From 7ae0229f2d4e7559f35a1d4c9d3d16f192b3cad2 Mon Sep 17 00:00:00 2001 From: karim1king Date: Wed, 11 Nov 2020 18:51:36 +0200 Subject: [PATCH] [NOD-1429] Add additional test --- domain/miningmanager/miningmanager_test.go | 137 ++++++++++++++++++--- 1 file changed, 119 insertions(+), 18 deletions(-) diff --git a/domain/miningmanager/miningmanager_test.go b/domain/miningmanager/miningmanager_test.go index 90316e678..58c26fbcd 100644 --- a/domain/miningmanager/miningmanager_test.go +++ b/domain/miningmanager/miningmanager_test.go @@ -1,19 +1,21 @@ package miningmanager_test import ( + "bytes" "github.com/kaspanet/kaspad/app/appmessage" "github.com/kaspanet/kaspad/domain/consensus" "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" + "github.com/kaspanet/kaspad/domain/consensus/utils/coinbase" "github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization" "github.com/kaspanet/kaspad/domain/consensus/utils/constants" + "github.com/kaspanet/kaspad/domain/consensus/utils/hashes" "github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks" + "github.com/kaspanet/kaspad/domain/consensus/utils/txscript" "github.com/kaspanet/kaspad/domain/dagconfig" "github.com/kaspanet/kaspad/domain/miningmanager" - "github.com/kaspanet/kaspad/domain/txscript" infrastructuredatabase "github.com/kaspanet/kaspad/infrastructure/db/database" "github.com/kaspanet/kaspad/infrastructure/db/database/ldb" "github.com/kaspanet/kaspad/util" - "github.com/kaspanet/kaspad/util/daghash" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb/opt" "io/ioutil" @@ -50,24 +52,46 @@ func setupDBForTest(dbName string) (infrastructuredatabase.Database, func(), err return db, teardown, err } -func createCoinbaseTransaction(scriptPublicKey []byte, value uint64) *externalapi.DomainTransaction { +func createCoinbaseTransaction(t *testing.T, scriptPublicKey []byte, value uint64) *externalapi.DomainTransaction { dummyTxOut := externalapi.DomainTransactionOutput{ Value: value, ScriptPublicKey: scriptPublicKey, } - payload := make([]byte, 8) - payloadHash := externalapi.DomainHash(*daghash.DoubleHashP(payload)) + payload, err := coinbase.SerializeCoinbasePayload(1, &externalapi.DomainCoinbaseData{ + ScriptPublicKey:scriptPublicKey, + }) + if err != nil { + t.Fatalf("SerializeCoinbasePayload: %v", err) + } + + payloadHash := hashes.HashData(payload) transaction := &externalapi.DomainTransaction{ - Version: appmessage.TxVersion, - Inputs: nil, + Version: constants.TransactionVersion, + Inputs: []*externalapi.DomainTransactionInput{}, Outputs: []*externalapi.DomainTransactionOutput{&dummyTxOut}, + LockTime: 0, SubnetworkID: subnetworks.SubnetworkIDCoinbase, Gas: 0, - PayloadHash: payloadHash, + PayloadHash: *payloadHash, Payload: payload, + } + + return transaction +} + +func createTransaction(inputs []*externalapi.DomainTransactionInput, scriptPublicKey []byte, value uint64) *externalapi.DomainTransaction { + dummyTxOut := externalapi.DomainTransactionOutput{ + Value: value, + ScriptPublicKey: scriptPublicKey, + } + + transaction := &externalapi.DomainTransaction{ + Version: constants.TransactionVersion, + Inputs: inputs, + Outputs: []*externalapi.DomainTransactionOutput{&dummyTxOut}, LockTime: 0, - Fee: 1500, - Mass: 1500, + SubnetworkID: subnetworks.SubnetworkIDNative, + Gas: 0, } return transaction @@ -93,15 +117,14 @@ func TestMiningManager(t *testing.T) { t.Run("Spending all transactions", func(t *testing.T) { consensusInstance, err := consensusFactory.NewConsensus(dagParams, db) if err != nil { - if err != nil { - t.Fatalf("NewConsensus: %v", err) - } + t.Fatalf("NewConsensus: %v", err) } + // Insert 10 transactions miningManager := miningManagerFactory.NewMiningManager(consensusInstance, constants.MaxMassAcceptedByBlock) transactions := make([]*externalapi.DomainTransaction, 10) for i := range transactions { - transaction := createCoinbaseTransaction(scriptPublicKey, uint64(100000000+i)) + transaction := createCoinbaseTransaction(t, scriptPublicKey, uint64(100000000+i)) transactions[i] = transaction err = miningManager.ValidateAndInsertTransaction(transaction, true) if err != nil { @@ -109,6 +132,7 @@ func TestMiningManager(t *testing.T) { } } + // Spending 10 transactions miningManager.HandleNewBlockTransactions(transactions) block := miningManager.GetBlockTemplate(&externalapi.DomainCoinbaseData{ ScriptPublicKey: scriptPublicKey, @@ -117,6 +141,7 @@ func TestMiningManager(t *testing.T) { t.Fatalf("GetBlockTemplate: failed building block") } + // Check 10 transactions are not exist for _, tx2 := range transactions { for _, tx1 := range block.Transactions { if consensusserialization.TransactionID(tx1) == consensusserialization.TransactionID(tx2) { @@ -129,15 +154,14 @@ func TestMiningManager(t *testing.T) { t.Run("Spending some transactions", func(t *testing.T) { consensusInstance, err := consensusFactory.NewConsensus(dagParams, db) if err != nil { - if err != nil { - t.Fatalf("NewConsensus: %v", err) - } + t.Fatalf("NewConsensus: %v", err) } + // Insert 10 transactions miningManager := miningManagerFactory.NewMiningManager(consensusInstance, constants.MaxMassAcceptedByBlock) transactions := make([]*externalapi.DomainTransaction, 10) for i := range transactions { - transaction := createCoinbaseTransaction(scriptPublicKey, uint64(100000000+i)) + transaction := createCoinbaseTransaction(t, scriptPublicKey, uint64(100000000+i)) transactions[i] = transaction err = miningManager.ValidateAndInsertTransaction(transaction, true) if err != nil { @@ -145,6 +169,7 @@ func TestMiningManager(t *testing.T) { } } + // Spending first 5 transactions miningManager.HandleNewBlockTransactions(transactions[0:5]) block := miningManager.GetBlockTemplate(&externalapi.DomainCoinbaseData{ ScriptPublicKey: scriptPublicKey, @@ -153,6 +178,7 @@ func TestMiningManager(t *testing.T) { t.Fatalf("GetBlockTemplate: failed building block") } + // Check first 5 transactions are not exist for _, tx2 := range transactions[0:5] { for _, tx1 := range block.Transactions { if consensusserialization.TransactionID(tx1) == consensusserialization.TransactionID(tx2) { @@ -161,4 +187,79 @@ func TestMiningManager(t *testing.T) { } } }) + + t.Run("Spending transactions with unknown parents", func(t *testing.T) { + consensusInstance, err := consensusFactory.NewConsensus(dagParams, db) + if err != nil { + t.Fatalf("NewConsensus: %v", err) + } + + miningManager := miningManagerFactory.NewMiningManager(consensusInstance, constants.MaxMassAcceptedByBlock) + transactions := make([]*externalapi.DomainTransaction, 10) + parentTransactions := make([]*externalapi.DomainTransaction, len(transactions)) + for i := range parentTransactions { + parentTransaction := createCoinbaseTransaction(t, scriptPublicKey, uint64(100000000+i)) + parentTransactions[i] = parentTransaction + } + + // Insert transactions with unknown parents + for i := range transactions { + parentTransaction := parentTransactions[i] + txIn := externalapi.DomainTransactionInput{ + PreviousOutpoint: externalapi.DomainOutpoint{TransactionID: *consensusserialization.TransactionID(parentTransaction), Index: 1}, + SignatureScript: bytes.Repeat([]byte{0x00}, 65), + Sequence: appmessage.MaxTxInSequenceNum, + } + transaction := createTransaction([]*externalapi.DomainTransactionInput{&txIn}, scriptPublicKey, uint64(10+i)) + transactions[i] = transaction + err = miningManager.ValidateAndInsertTransaction(transaction, true) + if err != nil { + t.Fatalf("ValidateAndInsertTransaction: unexpected error: %v", err) + } + } + + // Check transactions with unknown parents + block := miningManager.GetBlockTemplate(&externalapi.DomainCoinbaseData{ + ScriptPublicKey: scriptPublicKey, + }) + if block == nil { + t.Fatalf("GetBlockTemplate: failed building block") + } + + for _, tx1 := range transactions { + for _, tx2 := range block.Transactions { + if consensusserialization.TransactionID(tx1) == consensusserialization.TransactionID(tx2) { + t.Fatalf("Tranasaction with unknown parents is exisit") + } + } + } + + // Add the missing parents + for _, parentTransaction := range parentTransactions { + err = miningManager.ValidateAndInsertTransaction(parentTransaction, true) + if err != nil { + t.Fatalf("ValidateAndInsertTransaction: unexpected error: %v", err) + } + } + block = miningManager.GetBlockTemplate(&externalapi.DomainCoinbaseData{ + ScriptPublicKey: scriptPublicKey, + }) + if block == nil { + t.Fatalf("GetBlockTemplate: failed building block") + } + + numberOfFoundTransactions := 0 + for _, tx1 := range transactions { + for _, tx2 := range block.Transactions { + if consensusserialization.TransactionID(tx1) == consensusserialization.TransactionID(tx2) { + numberOfFoundTransactions++ + break + } + } + } + + if len(transactions) != numberOfFoundTransactions{ + t.Fatalf("Not all transactions are exist, expected %v, but got %v", len(transactions), numberOfFoundTransactions) + } + }) }