Skip to content
Snippets Groups Projects
Unverified Commit bcbcf50c authored by Wolfgang Welz's avatar Wolfgang Welz Committed by GitHub
Browse files

Improve tangle tests (#126)

parent 384b317f
No related branches found
No related tags found
No related merge requests found
package tangle
import (
"sync"
"io/ioutil"
stdlog "log"
"os"
"sync/atomic"
"testing"
"time"
"github.com/iotaledger/goshimmer/packages/database"
"github.com/iotaledger/goshimmer/packages/gossip"
"github.com/iotaledger/goshimmer/packages/model/meta_transaction"
"github.com/iotaledger/goshimmer/packages/model/value_transaction"
......@@ -15,68 +20,121 @@ import (
"github.com/stretchr/testify/require"
)
// use much lower min weight magnitude for the tests
const testMWM = 8
func init() {
if err := parameter.LoadDefaultConfig(false); err != nil {
log.Fatalf("Failed to initialize config: %s", err)
stdlog.Fatalf("Failed to initialize config: %s", err)
}
if err := logger.InitGlobalLogger(parameter.NodeConfig); err != nil {
log.Fatalf("Failed to initialize config: %s", err)
stdlog.Fatalf("Failed to initialize config: %s", err)
}
}
func TestSolidifier(t *testing.T) {
func TestTangle(t *testing.T) {
dir, err := ioutil.TempDir("", "example")
require.NoError(t, err)
defer os.Remove(dir)
// use the tempdir for the database
parameter.NodeConfig.Set(database.CFG_DIRECTORY, dir)
// start a test node
node.Start(node.Plugins(PLUGIN))
defer node.Shutdown()
// create transactions and chain them together
transaction1 := value_transaction.New()
transaction1.SetValue(1)
require.NoError(t, transaction1.DoProofOfWork(meta_transaction.MIN_WEIGHT_MAGNITUDE))
transaction2 := value_transaction.New()
transaction2.SetValue(2)
transaction2.SetBranchTransactionHash(transaction1.GetHash())
require.NoError(t, transaction2.DoProofOfWork(meta_transaction.MIN_WEIGHT_MAGNITUDE))
transaction3 := value_transaction.New()
transaction3.SetValue(3)
transaction3.SetBranchTransactionHash(transaction2.GetHash())
require.NoError(t, transaction3.DoProofOfWork(meta_transaction.MIN_WEIGHT_MAGNITUDE))
transaction4 := value_transaction.New()
transaction4.SetValue(4)
transaction4.SetBranchTransactionHash(transaction3.GetHash())
transaction4.SetAddress("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
require.NoError(t, transaction4.DoProofOfWork(meta_transaction.MIN_WEIGHT_MAGNITUDE))
// setup event handlers
var wg sync.WaitGroup
Events.TransactionSolid.Attach(events.NewClosure(func(transaction *value_transaction.ValueTransaction) {
wg.Done()
}))
// only transaction3 should be requested
SetRequester(RequesterFunc(func(hash trinary.Hash) {
require.Equal(t, transaction3.GetHash(), hash)
// return the transaction data
gossip.Events.TransactionReceived.Trigger(&gossip.TransactionReceivedEvent{Data: transaction3.GetBytes()})
}))
// issue transactions
wg.Add(4)
gossip.Events.TransactionReceived.Trigger(&gossip.TransactionReceivedEvent{Data: transaction1.GetBytes()})
gossip.Events.TransactionReceived.Trigger(&gossip.TransactionReceivedEvent{Data: transaction2.GetBytes()})
// gossip.Events.TransactionReceived.Trigger(&gossip.TransactionReceivedEvent{Data: transaction3.GetBytes()})
gossip.Events.TransactionReceived.Trigger(&gossip.TransactionReceivedEvent{Data: transaction4.GetBytes()})
// wait until all are solid
wg.Wait()
txAddr, err := ReadTransactionHashesForAddressFromDatabase(transaction4.GetAddress())
require.NoError(t, err)
require.Equal(t, transaction4.GetHash(), txAddr[0])
t.Run("ReadTransactionHashesForAddressFromDatabase", func(t *testing.T) {
tx1 := value_transaction.New()
tx1.SetAddress("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
tx1.SetTimestamp(uint(time.Now().UnixNano()))
require.NoError(t, tx1.DoProofOfWork(testMWM))
tx2 := value_transaction.New()
tx2.SetTimestamp(uint(time.Now().UnixNano()))
require.NoError(t, tx2.DoProofOfWork(testMWM))
transactionReceived(&gossip.TransactionReceivedEvent{Data: tx1.GetBytes()})
txAddr, err := ReadTransactionHashesForAddressFromDatabase(tx1.GetAddress())
require.NoError(t, err)
require.ElementsMatch(t, []trinary.Hash{tx1.GetHash()}, txAddr)
})
t.Run("ProofOfWork", func(t *testing.T) {
tx1 := value_transaction.New()
tx1.SetTimestamp(uint(time.Now().UnixNano()))
require.NoError(t, tx1.DoProofOfWork(1))
tx2 := value_transaction.New()
tx2.SetTimestamp(uint(time.Now().UnixNano()))
require.NoError(t, tx2.DoProofOfWork(testMWM))
var counter int32
closure := events.NewClosure(func(transaction *value_transaction.ValueTransaction) {
atomic.AddInt32(&counter, 1)
})
Events.TransactionSolid.Attach(closure)
defer Events.TransactionSolid.Detach(closure)
transactionReceived(&gossip.TransactionReceivedEvent{Data: tx1.GetBytes()})
transactionReceived(&gossip.TransactionReceivedEvent{Data: tx2.GetBytes()})
// shutdown test node
node.Shutdown()
time.Sleep(100 * time.Millisecond)
require.EqualValues(t, 1, counter)
})
t.Run("Solidifier", func(t *testing.T) {
transaction1 := value_transaction.New()
transaction1.SetTimestamp(uint(time.Now().UnixNano()))
require.NoError(t, transaction1.DoProofOfWork(testMWM))
transaction2 := value_transaction.New()
transaction2.SetTimestamp(uint(time.Now().UnixNano()))
transaction2.SetBranchTransactionHash(transaction1.GetHash())
require.NoError(t, transaction2.DoProofOfWork(testMWM))
transaction3 := value_transaction.New()
transaction3.SetTimestamp(uint(time.Now().UnixNano()))
transaction3.SetBranchTransactionHash(transaction2.GetHash())
require.NoError(t, transaction3.DoProofOfWork(testMWM))
transaction4 := value_transaction.New()
transaction4.SetTimestamp(uint(time.Now().UnixNano()))
transaction4.SetBranchTransactionHash(transaction3.GetHash())
require.NoError(t, transaction4.DoProofOfWork(testMWM))
var counter int32
closure := events.NewClosure(func(tx *value_transaction.ValueTransaction) {
atomic.AddInt32(&counter, 1)
log.Infof("Transaction solid: hash=%s", tx.GetHash())
})
Events.TransactionSolid.Attach(closure)
defer Events.TransactionSolid.Detach(closure)
// only transaction3 should be requested
SetRequester(RequesterFunc(func(hash trinary.Hash) {
if transaction3.GetHash() == hash {
// return the transaction data
transactionReceived(&gossip.TransactionReceivedEvent{Data: transaction3.GetBytes()})
}
}))
transactionReceived(&gossip.TransactionReceivedEvent{Data: transaction1.GetBytes()})
transactionReceived(&gossip.TransactionReceivedEvent{Data: transaction2.GetBytes()})
// transactionReceived(&gossip.TransactionReceivedEvent{Data: transaction3.GetBytes()})
transactionReceived(&gossip.TransactionReceivedEvent{Data: transaction4.GetBytes()})
time.Sleep(100 * time.Millisecond)
require.EqualValues(t, 4, counter)
})
}
// transactionReceived mocks the TransactionReceived event by allowing lower mwm
func transactionReceived(ev *gossip.TransactionReceivedEvent) {
metaTx := meta_transaction.FromBytes(ev.Data)
if metaTx.GetWeightMagnitude() < testMWM {
log.Warnf("invalid weight magnitude: %d / %d", metaTx.GetWeightMagnitude(), testMWM)
return
}
processMetaTransaction(metaTx)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment