From 0f61664cebe136b4a6981bad13f0fe85b7f16fef Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 27 Oct 2025 16:08:09 -0700 Subject: [PATCH] mempool+netsync: extend TxMempool interface for unified abstraction This commit extends the TxMempool interface to support both the legacy TxPool and new TxMempoolV2 implementations transparently. The interface now includes all methods required by the server, netsync, and mining subsystems, enabling a feature flag to toggle between implementations at runtime. The extended interface adds critical methods that were previously only available on the concrete TxPool type: RemoveOrphansByTag for peer cleanup, MiningDescs for block template generation, and several internal methods (RemoveDoubleSpends, RemoveOrphan, ProcessOrphans, MaybeAcceptTransaction) used by netsync for transaction relay. By abstracting these operations, we enable the server to use either implementation without subsystem-specific code changes. The netsync package now accepts the TxMempool interface rather than requiring the concrete TxPool type, allowing transparent switching. The MockTxMempool test implementation is updated to provide all new interface methods, ensuring tests continue to work with the expanded interface contract. --- mempool/interface.go | 31 +++++++++++++++++++++++ mempool/mocks.go | 59 ++++++++++++++++++++++++++++++++++++++++++++ netsync/interface.go | 2 +- netsync/manager.go | 2 +- 4 files changed, 92 insertions(+), 2 deletions(-) diff --git a/mempool/interface.go b/mempool/interface.go index f6fe1f05..5b3bb8db 100644 --- a/mempool/interface.go +++ b/mempool/interface.go @@ -6,6 +6,7 @@ import ( "github.com/btcsuite/btcd/btcjson" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/mining" "github.com/btcsuite/btcd/wire" ) @@ -68,4 +69,34 @@ type TxMempool interface { // a transaction in the mempool. If that's the case the spending // transaction will be returned, if not nil will be returned. CheckSpend(op wire.OutPoint) *btcutil.Tx + + // RemoveOrphansByTag removes all orphan transactions tagged with the + // provided identifier. Returns the number of orphans removed. + RemoveOrphansByTag(tag Tag) uint64 + + // MiningDescs returns a slice of mining descriptors for all the + // transactions in the source pool. + MiningDescs() []*mining.TxDesc + + // RemoveDoubleSpends removes all transactions that spend outputs spent + // by the passed transaction from the mempool. + RemoveDoubleSpends(tx *btcutil.Tx) + + // RemoveOrphan removes the passed orphan transaction from the orphan + // pool. + RemoveOrphan(tx *btcutil.Tx) + + // ProcessOrphans processes orphan transactions that now have a valid + // ancestor after the provided transaction was accepted. Returns a slice + // of transaction descriptors for any orphans that were accepted. + ProcessOrphans(acceptedTx *btcutil.Tx) []*TxDesc + + // MaybeAcceptTransaction validates and potentially accepts a + // transaction to the memory pool. It returns a slice of hashes for all + // transactions that were accepted, the transaction descriptor for the + // primary transaction (if accepted), and an error if the transaction + // was rejected. The isNew parameter indicates whether this is a new + // transaction or one being added from a reorganization. The rateLimit + // parameter indicates whether to apply rate limiting for relay. + MaybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit bool) ([]*chainhash.Hash, *TxDesc, error) } diff --git a/mempool/mocks.go b/mempool/mocks.go index e81309c5..124dac48 100644 --- a/mempool/mocks.go +++ b/mempool/mocks.go @@ -6,6 +6,7 @@ import ( "github.com/btcsuite/btcd/btcjson" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/mining" "github.com/btcsuite/btcd/wire" "github.com/stretchr/testify/mock" ) @@ -123,3 +124,61 @@ func (m *MockTxMempool) CheckSpend(op wire.OutPoint) *btcutil.Tx { return args.Get(0).(*btcutil.Tx) } + +// RemoveOrphansByTag removes all orphan transactions tagged with the provided +// identifier. +func (m *MockTxMempool) RemoveOrphansByTag(tag Tag) uint64 { + args := m.Called(tag) + return args.Get(0).(uint64) +} + +// MiningDescs returns a slice of mining descriptors for all the transactions +// in the source pool. +func (m *MockTxMempool) MiningDescs() []*mining.TxDesc { + args := m.Called() + if args.Get(0) == nil { + return nil + } + return args.Get(0).([]*mining.TxDesc) +} + +// RemoveDoubleSpends removes all transactions that spend outputs spent by the +// passed transaction from the mempool. +func (m *MockTxMempool) RemoveDoubleSpends(tx *btcutil.Tx) { + m.Called(tx) +} + +// RemoveOrphan removes the passed orphan transaction from the orphan pool. +func (m *MockTxMempool) RemoveOrphan(tx *btcutil.Tx) { + m.Called(tx) +} + +// ProcessOrphans processes orphan transactions that now have a valid ancestor +// after the provided transaction was accepted. +func (m *MockTxMempool) ProcessOrphans(acceptedTx *btcutil.Tx) []*TxDesc { + args := m.Called(acceptedTx) + if args.Get(0) == nil { + return nil + } + return args.Get(0).([]*TxDesc) +} + +// MaybeAcceptTransaction validates and potentially accepts a transaction to +// the memory pool. +func (m *MockTxMempool) MaybeAcceptTransaction(tx *btcutil.Tx, isNew, + rateLimit bool) ([]*chainhash.Hash, *TxDesc, error) { + + args := m.Called(tx, isNew, rateLimit) + + var hashes []*chainhash.Hash + if args.Get(0) != nil { + hashes = args.Get(0).([]*chainhash.Hash) + } + + var desc *TxDesc + if args.Get(1) != nil { + desc = args.Get(1).(*TxDesc) + } + + return hashes, desc, args.Error(2) +} diff --git a/netsync/interface.go b/netsync/interface.go index 6a873bd8..e8201769 100644 --- a/netsync/interface.go +++ b/netsync/interface.go @@ -31,7 +31,7 @@ type PeerNotifier interface { type Config struct { PeerNotifier PeerNotifier Chain *blockchain.BlockChain - TxMemPool *mempool.TxPool + TxMemPool mempool.TxMempool ChainParams *chaincfg.Params DisableCheckpoints bool diff --git a/netsync/manager.go b/netsync/manager.go index d10188d5..a2a50300 100644 --- a/netsync/manager.go +++ b/netsync/manager.go @@ -183,7 +183,7 @@ type SyncManager struct { started int32 shutdown int32 chain *blockchain.BlockChain - txMemPool *mempool.TxPool + txMemPool mempool.TxMempool chainParams *chaincfg.Params progressLogger *blockProgressLogger msgChan chan interface{}