diff --git a/app/protocol/flows/v5/transactionrelay/handle_relayed_transactions.go b/app/protocol/flows/v5/transactionrelay/handle_relayed_transactions.go index 21702986f..401ac46fd 100644 --- a/app/protocol/flows/v5/transactionrelay/handle_relayed_transactions.go +++ b/app/protocol/flows/v5/transactionrelay/handle_relayed_transactions.go @@ -102,7 +102,7 @@ func (flow *handleRelayedTransactionsFlow) requestInvTransactions( func (flow *handleRelayedTransactionsFlow) isKnownTransaction(txID *externalapi.DomainTransactionID) bool { // Ask the transaction memory pool if the transaction is known // to it in any form (main pool or orphan). - if _, ok := flow.Domain().MiningManager().GetTransaction(txID); ok { + if _, _, ok := flow.Domain().MiningManager().GetTransaction(txID, true, true); ok { return true } diff --git a/app/protocol/flows/v5/transactionrelay/handle_requested_transactions.go b/app/protocol/flows/v5/transactionrelay/handle_requested_transactions.go index 3dd8b294b..c40d86a9e 100644 --- a/app/protocol/flows/v5/transactionrelay/handle_requested_transactions.go +++ b/app/protocol/flows/v5/transactionrelay/handle_requested_transactions.go @@ -30,7 +30,11 @@ func (flow *handleRequestedTransactionsFlow) start() error { } for _, transactionID := range msgRequestTransactions.IDs { - tx, ok := flow.Domain().MiningManager().GetTransaction(transactionID) + //note: below ignores orphan txs that are requested + //find out if this is good or bad practice + //only reference i found to this, is that nodes don't do this in btc + //source: https://arxiv.org/abs/1912.11541 (2nd sentence in abstract) + tx, _, ok := flow.Domain().MiningManager().GetTransaction(transactionID, true, false) if !ok { msgTransactionNotFound := appmessage.NewMsgTransactionNotFound(transactionID) @@ -40,7 +44,6 @@ func (flow *handleRequestedTransactionsFlow) start() error { } continue } - err := flow.outgoingRoute.Enqueue(appmessage.DomainTransactionToMsgTx(tx)) if err != nil { return err diff --git a/app/rpc/rpchandlers/get_info.go b/app/rpc/rpchandlers/get_info.go index 2b72d7428..308e47615 100644 --- a/app/rpc/rpchandlers/get_info.go +++ b/app/rpc/rpchandlers/get_info.go @@ -16,7 +16,7 @@ func HandleGetInfo(context *rpccontext.Context, _ *router.Router, _ appmessage.M response := appmessage.NewGetInfoResponseMessage( context.NetAdapter.ID().String(), - uint64(context.Domain.MiningManager().TransactionCount()), + uint64(context.Domain.MiningManager().TransactionCount(true, false)), version.Version(), context.Config.UTXOIndex, context.ProtocolManager.Context().HasPeers() && isNearlySynced, diff --git a/app/rpc/rpchandlers/get_mempool_entries.go b/app/rpc/rpchandlers/get_mempool_entries.go index e37d84922..4f5ec8c81 100644 --- a/app/rpc/rpchandlers/get_mempool_entries.go +++ b/app/rpc/rpchandlers/get_mempool_entries.go @@ -12,58 +12,36 @@ func HandleGetMempoolEntries(context *rpccontext.Context, _ *router.Router, requ entries := make([]*appmessage.MempoolEntry, 0) + transactionPoolTransactions, orphanPoolTransactions := context.Domain.MiningManager().AllTransactions(!getMempoolEntriesRequest.FilterTransactionPool, getMempoolEntriesRequest.IncludeOrphanPool) + if !getMempoolEntriesRequest.FilterTransactionPool { - transactionPoolEntries, err := getTransactionPoolMempoolEntries(context) - if err != nil { - return nil, err + for _, transaction := range transactionPoolTransactions { + rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction) + err := context.PopulateTransactionWithVerboseData(rpcTransaction, nil) + if err != nil { + return nil, err + } + entries = append(entries, &appmessage.MempoolEntry{ + Fee: transaction.Fee, + Transaction: rpcTransaction, + IsOrphan: false, + }) } - - entries = append(entries, transactionPoolEntries...) } - if getMempoolEntriesRequest.IncludeOrphanPool { - orphanPoolEntries, err := getOrphanPoolMempoolEntries(context) - if err != nil { - return nil, err + for _, transaction := range orphanPoolTransactions { + rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction) + err := context.PopulateTransactionWithVerboseData(rpcTransaction, nil) + if err != nil { + return nil, err + } + entries = append(entries, &appmessage.MempoolEntry{ + Fee: transaction.Fee, + Transaction: rpcTransaction, + IsOrphan: true, + }) } - entries = append(entries, orphanPoolEntries...) } return appmessage.NewGetMempoolEntriesResponseMessage(entries), nil } - -func getTransactionPoolMempoolEntries(context *rpccontext.Context) ([]*appmessage.MempoolEntry, error) { - transactions := context.Domain.MiningManager().AllTransactions() - entries := make([]*appmessage.MempoolEntry, 0, len(transactions)) - for _, transaction := range transactions { - rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction) - err := context.PopulateTransactionWithVerboseData(rpcTransaction, nil) - if err != nil { - return nil, err - } - entries = append(entries, &appmessage.MempoolEntry{ - Fee: transaction.Fee, - Transaction: rpcTransaction, - IsOrphan: false, - }) - } - return entries, nil -} - -func getOrphanPoolMempoolEntries(context *rpccontext.Context) ([]*appmessage.MempoolEntry, error) { - orphanTransactions := context.Domain.MiningManager().AllOrphanTransactions() - entries := make([]*appmessage.MempoolEntry, 0, len(orphanTransactions)) - for _, orphanTransaction := range orphanTransactions { - rpcTransaction := appmessage.DomainTransactionToRPCTransaction(orphanTransaction) - err := context.PopulateTransactionWithVerboseData(rpcTransaction, nil) - if err != nil { - return nil, err - } - entries = append(entries, &appmessage.MempoolEntry{ - Fee: orphanTransaction.Fee, - Transaction: rpcTransaction, - IsOrphan: true, - }) - } - return entries, nil -} diff --git a/app/rpc/rpchandlers/get_mempool_entries_by_addresses.go b/app/rpc/rpchandlers/get_mempool_entries_by_addresses.go index 531c21bef..e7be7e97a 100644 --- a/app/rpc/rpchandlers/get_mempool_entries_by_addresses.go +++ b/app/rpc/rpchandlers/get_mempool_entries_by_addresses.go @@ -15,6 +15,11 @@ func HandleGetMempoolEntriesByAddresses(context *rpccontext.Context, _ *router.R mempoolEntriesByAddresses := make([]*appmessage.MempoolEntryByAddress, 0) + sendingInTransactionPool, receivingInTransactionPool, sendingInOrphanPool, receivingInOrphanPool, err := context.Domain.MiningManager().GetTransactionsByAddresses(!getMempoolEntriesByAddressesRequest.FilterTransactionPool, getMempoolEntriesByAddressesRequest.IncludeOrphanPool) + if err != nil { + return nil, err + } + for _, addressString := range getMempoolEntriesByAddressesRequest.Addresses { address, err := util.DecodeAddress(addressString, context.Config.NetParams().Prefix) @@ -29,12 +34,7 @@ func HandleGetMempoolEntriesByAddresses(context *rpccontext.Context, _ *router.R if !getMempoolEntriesByAddressesRequest.FilterTransactionPool { - sendingInMempool, receivingInMempool, err := context.Domain.MiningManager().GetTransactionsByAddresses() - if err != nil { - return nil, err - } - - if transaction, found := sendingInMempool[address.String()]; found { + if transaction, found := sendingInTransactionPool[address.String()]; found { rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction) err := context.PopulateTransactionWithVerboseData(rpcTransaction, nil) if err != nil { @@ -49,7 +49,7 @@ func HandleGetMempoolEntriesByAddresses(context *rpccontext.Context, _ *router.R ) } - if transaction, found := receivingInMempool[address.String()]; found { + if transaction, found := receivingInTransactionPool[address.String()]; found { rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction) err := context.PopulateTransactionWithVerboseData(rpcTransaction, nil) if err != nil { @@ -66,11 +66,6 @@ func HandleGetMempoolEntriesByAddresses(context *rpccontext.Context, _ *router.R } if getMempoolEntriesByAddressesRequest.IncludeOrphanPool { - sendingInOrphanPool, receivingInOrphanPool, err := context.Domain.MiningManager().GetOrphanTransactionsByAddresses() - if err != nil { - return nil, err - } - if transaction, found := sendingInOrphanPool[address.String()]; found { rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction) err := context.PopulateTransactionWithVerboseData(rpcTransaction, nil) diff --git a/app/rpc/rpchandlers/get_mempool_entry.go b/app/rpc/rpchandlers/get_mempool_entry.go index 5bc8938ef..a59b2f658 100644 --- a/app/rpc/rpchandlers/get_mempool_entry.go +++ b/app/rpc/rpchandlers/get_mempool_entry.go @@ -6,6 +6,7 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" "github.com/kaspanet/kaspad/domain/consensus/utils/transactionid" "github.com/kaspanet/kaspad/infrastructure/network/netadapter/router" + "github.com/pkg/errors" ) // HandleGetMempoolEntry handles the respectively named RPC command @@ -24,14 +25,7 @@ func HandleGetMempoolEntry(context *rpccontext.Context, _ *router.Router, reques return errorMessage, nil } - if !getMempoolEntryRequest.FilterTransactionPool { - transaction, found = context.Domain.MiningManager().GetTransaction(transactionID) - } - - if getMempoolEntryRequest.IncludeOrphanPool && !found { - transaction, found = context.Domain.MiningManager().GetOrphanTransaction(transactionID) - isOrphan = true - } + transactionPoolTransaction, orphanPoolTransaction, found := context.Domain.MiningManager().GetTransaction(transactionID, !getMempoolEntryRequest.FilterTransactionPool, getMempoolEntryRequest.IncludeOrphanPool) if !found { errorMessage := &appmessage.GetMempoolEntryResponseMessage{} @@ -39,6 +33,16 @@ func HandleGetMempoolEntry(context *rpccontext.Context, _ *router.Router, reques return errorMessage, nil } + if transactionPoolTransaction != nil && orphanPoolTransaction != nil { + return nil, errors.Errorf("Transaction %s is both an orphan, and not. This should never not happen", transactionID) + } else if transactionPoolTransaction != nil { + transaction = transactionPoolTransaction + isOrphan = false + } else if orphanPoolTransaction != nil { + transaction = orphanPoolTransaction + isOrphan = true + } + rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction) err = context.PopulateTransactionWithVerboseData(rpcTransaction, nil) if err != nil { diff --git a/domain/miningmanager/mempool/mempool.go b/domain/miningmanager/mempool/mempool.go index 5ecb81d86..96b6f7615 100644 --- a/domain/miningmanager/mempool/mempool.go +++ b/domain/miningmanager/mempool/mempool.go @@ -46,61 +46,87 @@ func (mp *mempool) ValidateAndInsertTransaction(transaction *externalapi.DomainT return mp.validateAndInsertTransaction(transaction, isHighPriority, allowOrphan, true) } -func (mp *mempool) GetTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) { +func (mp *mempool) GetTransaction(transactionID *externalapi.DomainTransactionID, + includeTransactionPool bool, + includeOrphanPool bool) ( + transactionPoolTransaction *externalapi.DomainTransaction, + orphanPoolTransaction *externalapi.DomainTransaction, + found bool) { + mp.mtx.RLock() defer mp.mtx.RUnlock() - return mp.transactionsPool.getTransaction(transactionID, true) + var transactionfound bool + var orphanTransactionFound bool + + if includeTransactionPool { + transactionPoolTransaction, transactionfound = mp.transactionsPool.getTransaction(transactionID, true) + } + if includeOrphanPool { + orphanPoolTransaction, orphanTransactionFound = mp.orphansPool.getOrphanTransaction(transactionID, true) + } + + return transactionPoolTransaction, orphanPoolTransaction, transactionfound || orphanTransactionFound } -func (mp *mempool) GetTransactionsByAddresses() ( - sending map[string]*externalapi.DomainTransaction, - receiving map[string]*externalapi.DomainTransaction, - err error, -) { +func (mp *mempool) GetTransactionsByAddresses(includeTransactionPool bool, includeOrphanPool bool) ( + sendingInTransactionPool map[string]*externalapi.DomainTransaction, + receivingInTransactionPool map[string]*externalapi.DomainTransaction, + sendingInOrphanPool map[string]*externalapi.DomainTransaction, + receivingInOrphanPool map[string]*externalapi.DomainTransaction, + err error) { mp.mtx.RLock() defer mp.mtx.RUnlock() - return mp.transactionsPool.getTransactionsByAddresses(true) + if includeTransactionPool { + sendingInTransactionPool, receivingInTransactionPool, err = mp.transactionsPool.getTransactionsByAddresses(true) + if err != nil { + return nil, nil, nil, nil, err + } + } + + if includeOrphanPool { + sendingInTransactionPool, receivingInOrphanPool, err = mp.orphansPool.getOrphanTransactionsByAddresses(true) + if err != nil { + return nil, nil, nil, nil, err + } + } + + return sendingInTransactionPool, receivingInTransactionPool, sendingInTransactionPool, receivingInOrphanPool, nil } -func (mp *mempool) AllTransactions() []*externalapi.DomainTransaction { +func (mp *mempool) AllTransactions(includeTransactionPool bool, includeOrphanPool bool) ( + transactionPoolTransactions []*externalapi.DomainTransaction, + orphanPoolTransactions []*externalapi.DomainTransaction) { + mp.mtx.RLock() defer mp.mtx.RUnlock() - return mp.transactionsPool.getAllTransactions(true) + if includeTransactionPool { + transactionPoolTransactions = mp.transactionsPool.getAllTransactions(true) + } + + if includeOrphanPool { + orphanPoolTransactions = mp.orphansPool.getAllOrphanTransactions(true) + } + + return transactionPoolTransactions, orphanPoolTransactions } -func (mp *mempool) GetOrphanTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) { +func (mp *mempool) TransactionCount(includeTransactionPool bool, includeOrphanPool bool) int { mp.mtx.RLock() defer mp.mtx.RUnlock() - return mp.orphansPool.getOrphanTransaction(transactionID, true) -} + transactionCount := 0 -func (mp *mempool) GetOrphanTransactionsByAddresses() ( - sending map[string]*externalapi.DomainTransaction, - receiving map[string]*externalapi.DomainTransaction, - err error, -) { - mp.mtx.RLock() - defer mp.mtx.RUnlock() + if includeOrphanPool { + transactionCount += mp.orphansPool.orphanTransactionCount() + } + if includeTransactionPool { + transactionCount += mp.transactionsPool.transactionCount() + } - return mp.orphansPool.getOrphanTransactionsByAddresses(true) -} - -func (mp *mempool) AllOrphanTransactions() []*externalapi.DomainTransaction { - mp.mtx.RLock() - defer mp.mtx.RUnlock() - - return mp.orphansPool.getAllOrphanTransactions(true) -} - -func (mp *mempool) TransactionCount() int { - mp.mtx.RLock() - defer mp.mtx.RUnlock() - - return mp.transactionsPool.transactionCount() + return transactionCount } func (mp *mempool) HandleNewBlockTransactions(transactions []*externalapi.DomainTransaction) ( diff --git a/domain/miningmanager/mempool/orphan_pool.go b/domain/miningmanager/mempool/orphan_pool.go index fe6cf8c7c..71af6402f 100644 --- a/domain/miningmanager/mempool/orphan_pool.go +++ b/domain/miningmanager/mempool/orphan_pool.go @@ -398,3 +398,7 @@ func (op *orphansPool) getAllOrphanTransactions(clone bool) []*externalapi.Domai } return allOrphanTransactions } + +func (op *orphansPool) orphanTransactionCount() int { + return len(op.allOrphans) +} diff --git a/domain/miningmanager/miningmanager.go b/domain/miningmanager/miningmanager.go index e1919bef8..635667b3d 100644 --- a/domain/miningmanager/miningmanager.go +++ b/domain/miningmanager/miningmanager.go @@ -15,19 +15,20 @@ type MiningManager interface { GetBlockTemplate(coinbaseData *externalapi.DomainCoinbaseData) (block *externalapi.DomainBlock, isNearlySynced bool, err error) ClearBlockTemplate() GetBlockTemplateBuilder() miningmanagermodel.BlockTemplateBuilder - GetTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) - GetTransactionsByAddresses() ( - sending map[string]*externalapi.DomainTransaction, - receiving map[string]*externalapi.DomainTransaction, + GetTransaction(transactionID *externalapi.DomainTransactionID, includeTransactionPool bool, includeOrphanPool bool) ( + transactionPoolTransaction *externalapi.DomainTransaction, + orphanPoolTransaction *externalapi.DomainTransaction, + found bool) + GetTransactionsByAddresses(includeTransactionPool bool, includeOrphanPool bool) ( + sendingInTransactionPool map[string]*externalapi.DomainTransaction, + receivingInTransactionPool map[string]*externalapi.DomainTransaction, + sendingInOrphanPool map[string]*externalapi.DomainTransaction, + receivingInOrphanPool map[string]*externalapi.DomainTransaction, err error) - AllTransactions() []*externalapi.DomainTransaction - GetOrphanTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) - GetOrphanTransactionsByAddresses() ( - sending map[string]*externalapi.DomainTransaction, - receiving map[string]*externalapi.DomainTransaction, - err error) - AllOrphanTransactions() []*externalapi.DomainTransaction - TransactionCount() int + AllTransactions(includeTransactionPool bool, includeOrphanPool bool) ( + transactionPoolTransactions []*externalapi.DomainTransaction, + orphanPoolTransactions []*externalapi.DomainTransaction) + TransactionCount(includeTransactionPool bool, includeOrphanPool bool) int HandleNewBlockTransactions(txs []*externalapi.DomainTransaction) ([]*externalapi.DomainTransaction, error) ValidateAndInsertTransaction(transaction *externalapi.DomainTransaction, isHighPriority bool, allowOrphan bool) ( acceptedTransactions []*externalapi.DomainTransaction, err error) @@ -117,42 +118,35 @@ func (mm *miningManager) ValidateAndInsertTransaction(transaction *externalapi.D } func (mm *miningManager) GetTransaction( - transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) { + transactionID *externalapi.DomainTransactionID, + includeTransactionPool bool, + includeOrphanPool bool) ( + transactionPoolTransaction *externalapi.DomainTransaction, + orphanPoolTransaction *externalapi.DomainTransaction, + found bool) { - return mm.mempool.GetTransaction(transactionID) + return mm.mempool.GetTransaction(transactionID, includeTransactionPool, includeOrphanPool) } -func (mm *miningManager) AllTransactions() []*externalapi.DomainTransaction { - return mm.mempool.AllTransactions() +func (mm *miningManager) AllTransactions(includeTransactionPool bool, includeOrphanPool bool) ( + transactionPoolTransactions []*externalapi.DomainTransaction, + orphanPoolTransactions []*externalapi.DomainTransaction) { + + return mm.mempool.AllTransactions(includeTransactionPool, includeOrphanPool) } -func (mm *miningManager) GetTransactionsByAddresses() ( - sending map[string]*externalapi.DomainTransaction, - receiving map[string]*externalapi.DomainTransaction, +func (mm *miningManager) GetTransactionsByAddresses(includeTransactionPool bool, includeOrphanPool bool) ( + sendingInTransactionPool map[string]*externalapi.DomainTransaction, + receivingInTransactionPool map[string]*externalapi.DomainTransaction, + sendingInOrphanPool map[string]*externalapi.DomainTransaction, + receivingInOrphanPool map[string]*externalapi.DomainTransaction, err error) { - return mm.mempool.GetTransactionsByAddresses() + + return mm.mempool.GetTransactionsByAddresses(includeTransactionPool, includeOrphanPool) } -func (mm *miningManager) GetOrphanTransaction( - transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) { - - return mm.mempool.GetOrphanTransaction(transactionID) -} - -func (mm *miningManager) GetOrphanTransactionsByAddresses() ( - sending map[string]*externalapi.DomainTransaction, - receiving map[string]*externalapi.DomainTransaction, - err error) { - return mm.mempool.GetTransactionsByAddresses() -} - -func (mm *miningManager) AllOrphanTransactions() []*externalapi.DomainTransaction { - - return mm.mempool.AllOrphanTransactions() -} - -func (mm *miningManager) TransactionCount() int { - return mm.mempool.TransactionCount() +func (mm *miningManager) TransactionCount(includeTransactionPool bool, includeOrphanPool bool) int { + return mm.mempool.TransactionCount(includeTransactionPool, includeOrphanPool) } func (mm *miningManager) RevalidateHighPriorityTransactions() ( diff --git a/domain/miningmanager/miningmanager_test.go b/domain/miningmanager/miningmanager_test.go index d8a31aeda..63277b6cc 100644 --- a/domain/miningmanager/miningmanager_test.go +++ b/domain/miningmanager/miningmanager_test.go @@ -52,7 +52,7 @@ func TestValidateAndInsertTransaction(t *testing.T) { } // The UTXOEntry was filled manually for those transactions, so the transactions won't be considered orphans. // Therefore, all the transactions expected to be contained in the mempool. - transactionsFromMempool := miningManager.AllTransactions() + transactionsFromMempool, _ := miningManager.AllTransactions(true, false) if len(transactionsToInsert) != len(transactionsFromMempool) { t.Fatalf("Wrong number of transactions in mempool: expected: %d, got: %d", len(transactionsToInsert), len(transactionsFromMempool)) } @@ -72,7 +72,7 @@ func TestValidateAndInsertTransaction(t *testing.T) { if err != nil { t.Fatalf("ValidateAndInsertTransaction: %v", err) } - transactionsFromMempool = miningManager.AllTransactions() + transactionsFromMempool, _ = miningManager.AllTransactions(true, false) if !contains(transactionNotAnOrphan, transactionsFromMempool) { t.Fatalf("Missing transaction %s in the mempool", consensushashing.TransactionID(transactionNotAnOrphan)) } @@ -99,7 +99,7 @@ func TestImmatureSpend(t *testing.T) { if !errors.As(err, txRuleError) || txRuleError.RejectCode != mempool.RejectImmatureSpend { t.Fatalf("Unexpected error %+v", err) } - transactionsFromMempool := miningManager.AllTransactions() + transactionsFromMempool, _ := miningManager.AllTransactions(true, false) if contains(tx, transactionsFromMempool) { t.Fatalf("Mempool contains a transaction with immature coinbase") } @@ -205,7 +205,7 @@ func TestHandleNewBlockTransactions(t *testing.T) { if err != nil { t.Fatalf("HandleNewBlockTransactions: %v", err) } - mempoolTransactions := miningManager.AllTransactions() + mempoolTransactions, _ := miningManager.AllTransactions(true, false) for _, removedTransaction := range blockWithFirstPartOfTheTransactions { if contains(removedTransaction, mempoolTransactions) { t.Fatalf("This transaction shouldnt be in mempool: %s", consensushashing.TransactionID(removedTransaction)) @@ -214,7 +214,7 @@ func TestHandleNewBlockTransactions(t *testing.T) { // There are no chained/double-spends transactions, and hence it is expected that all the other // transactions, will still be included in the mempool. - mempoolTransactions = miningManager.AllTransactions() + mempoolTransactions, _ = miningManager.AllTransactions(true, false) for _, transaction := range blockWithRestOfTheTransactions[transactionhelper.CoinbaseTransactionIndex+1:] { if !contains(transaction, mempoolTransactions) { t.Fatalf("This transaction %s should be in mempool.", consensushashing.TransactionID(transaction)) @@ -225,8 +225,10 @@ func TestHandleNewBlockTransactions(t *testing.T) { if err != nil { t.Fatalf("HandleNewBlockTransactions: %v", err) } - if len(miningManager.AllTransactions()) != 0 { - blockIDs := domainBlocksToBlockIds(miningManager.AllTransactions()) + mempoolTransactions, _ = miningManager.AllTransactions(true, false) + if len(mempoolTransactions) != 0 { + mempoolTransactions, _ = miningManager.AllTransactions(true, false) + blockIDs := domainBlocksToBlockIds(mempoolTransactions) t.Fatalf("The mempool contains unexpected transactions: %s", blockIDs) } }) @@ -269,7 +271,8 @@ func TestDoubleSpendWithBlock(t *testing.T) { if err != nil { t.Fatalf("HandleNewBlockTransactions: %v", err) } - if contains(transactionInTheMempool, miningManager.AllTransactions()) { + mempoolTransactions, _ := miningManager.AllTransactions(true, false) + if contains(transactionInTheMempool, mempoolTransactions) { t.Fatalf("The transaction %s, shouldn't be in the mempool, since at least one "+ "output was already spent.", consensushashing.TransactionID(transactionInTheMempool)) } @@ -303,7 +306,7 @@ func TestOrphanTransactions(t *testing.T) { t.Fatalf("ValidateAndInsertTransaction: %v", err) } } - transactionsMempool := miningManager.AllTransactions() + transactionsMempool, _ := miningManager.AllTransactions(true, false) for _, transaction := range transactionsMempool { if contains(transaction, childTransactions) { t.Fatalf("Error: an orphan transaction is exist in the mempool") @@ -345,7 +348,7 @@ func TestOrphanTransactions(t *testing.T) { if err != nil { t.Fatalf("HandleNewBlockTransactions: %+v", err) } - transactionsMempool = miningManager.AllTransactions() + transactionsMempool, _ = miningManager.AllTransactions(true, false) if len(transactionsMempool) != len(childTransactions) { t.Fatalf("Expected %d transactions in the mempool but got %d", len(childTransactions), len(transactionsMempool)) } @@ -553,8 +556,8 @@ func TestRevalidateHighPriorityTransactions(t *testing.T) { } // Make sure spendingTransaction is still in mempool - allTransactions := miningManager.AllTransactions() - if len(allTransactions) != 1 || !allTransactions[0].Equal(spendingTransaction) { + mempoolTransactions, _ := miningManager.AllTransactions(true, false) + if len(mempoolTransactions) != 1 || !mempoolTransactions[0].Equal(spendingTransaction) { t.Fatalf("Expected to have spendingTransaction as only validTransaction returned from "+ "RevalidateHighPriorityTransactions, but got %v instead", validTransactions) } @@ -568,9 +571,9 @@ func TestRevalidateHighPriorityTransactions(t *testing.T) { t.Fatalf("Expected to have empty validTransactions, but got %v instead", validTransactions) } // And also AllTransactions should be empty as well - allTransactions = miningManager.AllTransactions() - if len(allTransactions) != 0 { - t.Fatalf("Expected to have empty allTransactions, but got %v instead", allTransactions) + mempoolTransactions, _ = miningManager.AllTransactions(true, false) + if len(mempoolTransactions) != 0 { + t.Fatalf("Expected to have empty allTransactions, but got %v instead", mempoolTransactions) } }) } @@ -605,7 +608,7 @@ func TestModifyBlockTemplate(t *testing.T) { t.Fatalf("ValidateAndInsertTransaction: %v", err) } } - transactionsMempool := miningManager.AllTransactions() + transactionsMempool, _ := miningManager.AllTransactions(true, true) for _, transaction := range transactionsMempool { if contains(transaction, childTransactions) { t.Fatalf("Error: an orphan transaction is exist in the mempool") @@ -654,7 +657,7 @@ func TestModifyBlockTemplate(t *testing.T) { if err != nil { t.Fatalf("HandleNewBlockTransactions: %+v", err) } - transactionsMempool = miningManager.AllTransactions() + transactionsMempool, _ = miningManager.AllTransactions(true, true) if len(transactionsMempool) != len(childTransactions) { t.Fatalf("Expected %d transactions in the mempool but got %d", len(childTransactions), len(transactionsMempool)) } diff --git a/domain/miningmanager/model/interface_mempool.go b/domain/miningmanager/model/interface_mempool.go index 2796be181..4b1ec2e38 100644 --- a/domain/miningmanager/model/interface_mempool.go +++ b/domain/miningmanager/model/interface_mempool.go @@ -12,19 +12,31 @@ type Mempool interface { ValidateAndInsertTransaction(transaction *externalapi.DomainTransaction, isHighPriority bool, allowOrphan bool) ( acceptedTransactions []*externalapi.DomainTransaction, err error) RemoveTransactions(txs []*externalapi.DomainTransaction, removeRedeemers bool) error - GetTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) - GetTransactionsByAddresses() ( - sending map[string]*externalapi.DomainTransaction, - receiving map[string]*externalapi.DomainTransaction, + GetTransaction( + transactionID *externalapi.DomainTransactionID, + includeTransactionPool bool, + includeOrphanPool bool, + ) ( + transactionPoolTransaction *externalapi.DomainTransaction, + orphanPoolTransaction *externalapi.DomainTransaction, + found bool) + GetTransactionsByAddresses( + includeTransactionPool bool, + includeOrphanPool bool) ( + sendingInTransactionPool map[string]*externalapi.DomainTransaction, + receivingInTransactionPool map[string]*externalapi.DomainTransaction, + sendingInOrphanPool map[string]*externalapi.DomainTransaction, + receivingInOrphanPool map[string]*externalapi.DomainTransaction, err error) - AllTransactions() []*externalapi.DomainTransaction - GetOrphanTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) - GetOrphanTransactionsByAddresses() ( - sending map[string]*externalapi.DomainTransaction, - receiving map[string]*externalapi.DomainTransaction, - err error) - AllOrphanTransactions() []*externalapi.DomainTransaction - TransactionCount() int + AllTransactions( + includeTransactionPool bool, + includeOrphanPool bool, + ) ( + transactionPoolTransactions []*externalapi.DomainTransaction, + orphanPoolTransactions []*externalapi.DomainTransaction) + TransactionCount( + includeTransactionPool bool, + includeOrphanPool bool) int RevalidateHighPriorityTransactions() (validTransactions []*externalapi.DomainTransaction, err error) IsTransactionOutputDust(output *externalapi.DomainTransactionOutput) bool } diff --git a/testing/integration/tx_relay_test.go b/testing/integration/tx_relay_test.go index bfa1d4e14..3a664e694 100644 --- a/testing/integration/tx_relay_test.go +++ b/testing/integration/tx_relay_test.go @@ -105,7 +105,7 @@ func TestTxRelay(t *testing.T) { } //TO DO: find out if failing the below is a bug or not - /* for _, mempoolEntry := range mempoolEntryByAddress.Receiving { + for _, mempoolEntry := range mempoolEntryByAddress.Receiving { if mempoolEntry.IsOrphan { t.Fatalf("transaction %s is an orphan, although it shouldn't be", mempoolEntry.Transaction.VerboseData.TransactionID) } @@ -114,7 +114,7 @@ func TestTxRelay(t *testing.T) { if mempoolEntry.IsOrphan { t.Fatalf("transaction %s is an orphan, although it shouldn't be", mempoolEntry.Transaction.VerboseData.TransactionID) } - }*/ + } } close(txAddedToMempoolChan)