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.
This commit is contained in:
Olaoluwa Osuntokun 2025-10-27 16:08:09 -07:00
parent dec3e41354
commit 0f61664ceb
4 changed files with 92 additions and 2 deletions

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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

View file

@ -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{}