mempool: Return type TxDesc instead of type btcutil.Tx

This will provide callers more information on the accepted transaction.
This commit is contained in:
David Hill 2016-10-28 14:23:51 -04:00
parent 1a69eb0617
commit 2615fa0849
4 changed files with 61 additions and 57 deletions

View file

@ -1185,7 +1185,7 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
// Reinsert all of the transactions (except the coinbase) into // Reinsert all of the transactions (except the coinbase) into
// the transaction pool. // the transaction pool.
for _, tx := range block.Transactions()[1:] { for _, tx := range block.Transactions()[1:] {
_, err := b.server.txMemPool.MaybeAcceptTransaction(tx, _, _, err := b.server.txMemPool.MaybeAcceptTransaction(tx,
false, false) false, false)
if err != nil { if err != nil {
// Remove the transaction and all transactions // Remove the transaction and all transactions

View file

@ -481,10 +481,10 @@ func (mp *TxPool) RemoveDoubleSpends(tx *btcutil.Tx) {
// helper for maybeAcceptTransaction. // helper for maybeAcceptTransaction.
// //
// This function MUST be called with the mempool lock held (for writes). // This function MUST be called with the mempool lock held (for writes).
func (mp *TxPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil.Tx, height int32, fee int64) { func (mp *TxPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil.Tx, height int32, fee int64) *TxDesc {
// Add the transaction to the pool and mark the referenced outpoints // Add the transaction to the pool and mark the referenced outpoints
// as spent by the pool. // as spent by the pool.
mp.pool[*tx.Hash()] = &TxDesc{ txD := &TxDesc{
TxDesc: mining.TxDesc{ TxDesc: mining.TxDesc{
Tx: tx, Tx: tx,
Added: time.Now(), Added: time.Now(),
@ -493,6 +493,8 @@ func (mp *TxPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil
}, },
StartingPriority: mining.CalcPriority(tx.MsgTx(), utxoView, height), StartingPriority: mining.CalcPriority(tx.MsgTx(), utxoView, height),
} }
mp.pool[*tx.Hash()] = txD
for _, txIn := range tx.MsgTx().TxIn { for _, txIn := range tx.MsgTx().TxIn {
mp.outpoints[txIn.PreviousOutPoint] = tx mp.outpoints[txIn.PreviousOutPoint] = tx
} }
@ -503,6 +505,8 @@ func (mp *TxPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil
if mp.cfg.AddrIndex != nil { if mp.cfg.AddrIndex != nil {
mp.cfg.AddrIndex.AddUnconfirmedTx(tx, utxoView) mp.cfg.AddrIndex.AddUnconfirmedTx(tx, utxoView)
} }
return txD
} }
// checkPoolDoubleSpend checks whether or not the passed transaction is // checkPoolDoubleSpend checks whether or not the passed transaction is
@ -572,7 +576,7 @@ func (mp *TxPool) FetchTransaction(txHash *chainhash.Hash) (*btcutil.Tx, error)
// more details. // more details.
// //
// This function MUST be called with the mempool lock held (for writes). // This function MUST be called with the mempool lock held (for writes).
func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejectDupOrphans bool) ([]*chainhash.Hash, error) { func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejectDupOrphans bool) ([]*chainhash.Hash, *TxDesc, error) {
txHash := tx.Hash() txHash := tx.Hash()
// Don't accept the transaction if it already exists in the pool. This // Don't accept the transaction if it already exists in the pool. This
@ -583,7 +587,7 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
mp.isOrphanInPool(txHash)) { mp.isOrphanInPool(txHash)) {
str := fmt.Sprintf("already have transaction %v", txHash) str := fmt.Sprintf("already have transaction %v", txHash)
return nil, txRuleError(wire.RejectDuplicate, str) return nil, nil, txRuleError(wire.RejectDuplicate, str)
} }
// Perform preliminary sanity checks on the transaction. This makes // Perform preliminary sanity checks on the transaction. This makes
@ -592,16 +596,16 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
err := blockchain.CheckTransactionSanity(tx) err := blockchain.CheckTransactionSanity(tx)
if err != nil { if err != nil {
if cerr, ok := err.(blockchain.RuleError); ok { if cerr, ok := err.(blockchain.RuleError); ok {
return nil, chainRuleError(cerr) return nil, nil, chainRuleError(cerr)
} }
return nil, err return nil, nil, err
} }
// A standalone transaction must not be a coinbase transaction. // A standalone transaction must not be a coinbase transaction.
if blockchain.IsCoinBase(tx) { if blockchain.IsCoinBase(tx) {
str := fmt.Sprintf("transaction %v is an individual coinbase", str := fmt.Sprintf("transaction %v is an individual coinbase",
txHash) txHash)
return nil, txRuleError(wire.RejectInvalid, str) return nil, nil, txRuleError(wire.RejectInvalid, str)
} }
// Don't accept transactions with a lock time after the maximum int32 // Don't accept transactions with a lock time after the maximum int32
@ -611,7 +615,7 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
if tx.MsgTx().LockTime > math.MaxInt32 { if tx.MsgTx().LockTime > math.MaxInt32 {
str := fmt.Sprintf("transaction %v has a lock time after "+ str := fmt.Sprintf("transaction %v has a lock time after "+
"2038 which is not accepted yet", txHash) "2038 which is not accepted yet", txHash)
return nil, txRuleError(wire.RejectNonstandard, str) return nil, nil, txRuleError(wire.RejectNonstandard, str)
} }
// Get the current height of the main chain. A standalone transaction // Get the current height of the main chain. A standalone transaction
@ -638,7 +642,7 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
} }
str := fmt.Sprintf("transaction %v is not standard: %v", str := fmt.Sprintf("transaction %v is not standard: %v",
txHash, err) txHash, err)
return nil, txRuleError(rejectCode, str) return nil, nil, txRuleError(rejectCode, str)
} }
} }
@ -652,7 +656,7 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
// which examines the actual spend data and prevents double spends. // which examines the actual spend data and prevents double spends.
err = mp.checkPoolDoubleSpend(tx) err = mp.checkPoolDoubleSpend(tx)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
// Fetch all of the unspent transaction outputs referenced by the inputs // Fetch all of the unspent transaction outputs referenced by the inputs
@ -662,16 +666,16 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
utxoView, err := mp.fetchInputUtxos(tx) utxoView, err := mp.fetchInputUtxos(tx)
if err != nil { if err != nil {
if cerr, ok := err.(blockchain.RuleError); ok { if cerr, ok := err.(blockchain.RuleError); ok {
return nil, chainRuleError(cerr) return nil, nil, chainRuleError(cerr)
} }
return nil, err return nil, nil, err
} }
// Don't allow the transaction if it exists in the main chain and is not // Don't allow the transaction if it exists in the main chain and is not
// not already fully spent. // not already fully spent.
txEntry := utxoView.LookupEntry(txHash) txEntry := utxoView.LookupEntry(txHash)
if txEntry != nil && !txEntry.IsFullySpent() { if txEntry != nil && !txEntry.IsFullySpent() {
return nil, txRuleError(wire.RejectDuplicate, return nil, nil, txRuleError(wire.RejectDuplicate,
"transaction already exists") "transaction already exists")
} }
delete(utxoView.Entries(), *txHash) delete(utxoView.Entries(), *txHash)
@ -692,7 +696,7 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
} }
} }
if len(missingParents) > 0 { if len(missingParents) > 0 {
return missingParents, nil return missingParents, nil, nil
} }
// Don't allow the transaction into the mempool unless its sequence // Don't allow the transaction into the mempool unless its sequence
@ -701,13 +705,13 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
sequenceLock, err := mp.cfg.CalcSequenceLock(tx, utxoView) sequenceLock, err := mp.cfg.CalcSequenceLock(tx, utxoView)
if err != nil { if err != nil {
if cerr, ok := err.(blockchain.RuleError); ok { if cerr, ok := err.(blockchain.RuleError); ok {
return nil, chainRuleError(cerr) return nil, nil, chainRuleError(cerr)
} }
return nil, err return nil, nil, err
} }
if !blockchain.SequenceLockActive(sequenceLock, nextBlockHeight, if !blockchain.SequenceLockActive(sequenceLock, nextBlockHeight,
medianTimePast) { medianTimePast) {
return nil, txRuleError(wire.RejectNonstandard, return nil, nil, txRuleError(wire.RejectNonstandard,
"transaction's sequence locks on inputs not met") "transaction's sequence locks on inputs not met")
} }
@ -719,9 +723,9 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
utxoView, mp.cfg.ChainParams) utxoView, mp.cfg.ChainParams)
if err != nil { if err != nil {
if cerr, ok := err.(blockchain.RuleError); ok { if cerr, ok := err.(blockchain.RuleError); ok {
return nil, chainRuleError(cerr) return nil, nil, chainRuleError(cerr)
} }
return nil, err return nil, nil, err
} }
// Don't allow transactions with non-standard inputs if the network // Don't allow transactions with non-standard inputs if the network
@ -738,7 +742,7 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
} }
str := fmt.Sprintf("transaction %v has a non-standard "+ str := fmt.Sprintf("transaction %v has a non-standard "+
"input: %v", txHash, err) "input: %v", txHash, err)
return nil, txRuleError(rejectCode, str) return nil, nil, txRuleError(rejectCode, str)
} }
} }
@ -754,15 +758,15 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
numSigOps, err := blockchain.CountP2SHSigOps(tx, false, utxoView) numSigOps, err := blockchain.CountP2SHSigOps(tx, false, utxoView)
if err != nil { if err != nil {
if cerr, ok := err.(blockchain.RuleError); ok { if cerr, ok := err.(blockchain.RuleError); ok {
return nil, chainRuleError(cerr) return nil, nil, chainRuleError(cerr)
} }
return nil, err return nil, nil, err
} }
numSigOps += blockchain.CountSigOps(tx) numSigOps += blockchain.CountSigOps(tx)
if numSigOps > mp.cfg.Policy.MaxSigOpsPerTx { if numSigOps > mp.cfg.Policy.MaxSigOpsPerTx {
str := fmt.Sprintf("transaction %v has too many sigops: %d > %d", str := fmt.Sprintf("transaction %v has too many sigops: %d > %d",
txHash, numSigOps, mp.cfg.Policy.MaxSigOpsPerTx) txHash, numSigOps, mp.cfg.Policy.MaxSigOpsPerTx)
return nil, txRuleError(wire.RejectNonstandard, str) return nil, nil, txRuleError(wire.RejectNonstandard, str)
} }
// Don't allow transactions with fees too low to get into a mined block. // Don't allow transactions with fees too low to get into a mined block.
@ -783,7 +787,7 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
str := fmt.Sprintf("transaction %v has %d fees which is under "+ str := fmt.Sprintf("transaction %v has %d fees which is under "+
"the required amount of %d", txHash, txFee, "the required amount of %d", txHash, txFee,
minFee) minFee)
return nil, txRuleError(wire.RejectInsufficientFee, str) return nil, nil, txRuleError(wire.RejectInsufficientFee, str)
} }
// Require that free transactions have sufficient priority to be mined // Require that free transactions have sufficient priority to be mined
@ -797,7 +801,7 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
str := fmt.Sprintf("transaction %v has insufficient "+ str := fmt.Sprintf("transaction %v has insufficient "+
"priority (%g <= %g)", txHash, "priority (%g <= %g)", txHash,
currentPriority, mining.MinHighPriority) currentPriority, mining.MinHighPriority)
return nil, txRuleError(wire.RejectInsufficientFee, str) return nil, nil, txRuleError(wire.RejectInsufficientFee, str)
} }
} }
@ -815,7 +819,7 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
if mp.pennyTotal >= mp.cfg.Policy.FreeTxRelayLimit*10*1000 { if mp.pennyTotal >= mp.cfg.Policy.FreeTxRelayLimit*10*1000 {
str := fmt.Sprintf("transaction %v has been rejected "+ str := fmt.Sprintf("transaction %v has been rejected "+
"by the rate limiter due to low fees", txHash) "by the rate limiter due to low fees", txHash)
return nil, txRuleError(wire.RejectInsufficientFee, str) return nil, nil, txRuleError(wire.RejectInsufficientFee, str)
} }
oldTotal := mp.pennyTotal oldTotal := mp.pennyTotal
@ -831,18 +835,18 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
txscript.StandardVerifyFlags, mp.cfg.SigCache) txscript.StandardVerifyFlags, mp.cfg.SigCache)
if err != nil { if err != nil {
if cerr, ok := err.(blockchain.RuleError); ok { if cerr, ok := err.(blockchain.RuleError); ok {
return nil, chainRuleError(cerr) return nil, nil, chainRuleError(cerr)
} }
return nil, err return nil, nil, err
} }
// Add to transaction pool. // Add to transaction pool.
mp.addTransaction(utxoView, tx, bestHeight, txFee) txD := mp.addTransaction(utxoView, tx, bestHeight, txFee)
log.Debugf("Accepted transaction %v (pool size: %v)", txHash, log.Debugf("Accepted transaction %v (pool size: %v)", txHash,
len(mp.pool)) len(mp.pool))
return nil, nil return nil, txD, nil
} }
// MaybeAcceptTransaction is the main workhorse for handling insertion of new // MaybeAcceptTransaction is the main workhorse for handling insertion of new
@ -856,21 +860,21 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec
// be added to the orphan pool. // be added to the orphan pool.
// //
// This function is safe for concurrent access. // This function is safe for concurrent access.
func (mp *TxPool) MaybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit bool) ([]*chainhash.Hash, error) { func (mp *TxPool) MaybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit bool) ([]*chainhash.Hash, *TxDesc, error) {
// Protect concurrent access. // Protect concurrent access.
mp.mtx.Lock() mp.mtx.Lock()
hashes, err := mp.maybeAcceptTransaction(tx, isNew, rateLimit, true) hashes, txD, err := mp.maybeAcceptTransaction(tx, isNew, rateLimit, true)
mp.mtx.Unlock() mp.mtx.Unlock()
return hashes, err return hashes, txD, err
} }
// processOrphans is the internal function which implements the public // processOrphans is the internal function which implements the public
// ProcessOrphans. See the comment for ProcessOrphans for more details. // ProcessOrphans. See the comment for ProcessOrphans for more details.
// //
// This function MUST be called with the mempool lock held (for writes). // This function MUST be called with the mempool lock held (for writes).
func (mp *TxPool) processOrphans(acceptedTx *btcutil.Tx) []*btcutil.Tx { func (mp *TxPool) processOrphans(acceptedTx *btcutil.Tx) []*TxDesc {
var acceptedTxns []*btcutil.Tx var acceptedTxns []*TxDesc
// Start with processing at least the passed transaction. // Start with processing at least the passed transaction.
processList := list.New() processList := list.New()
@ -901,7 +905,7 @@ func (mp *TxPool) processOrphans(acceptedTx *btcutil.Tx) []*btcutil.Tx {
// Potentially accept an orphan into the tx pool. // Potentially accept an orphan into the tx pool.
for _, tx := range orphans { for _, tx := range orphans {
missing, err := mp.maybeAcceptTransaction( missing, txD, err := mp.maybeAcceptTransaction(
tx, true, true, false) tx, true, true, false)
if err != nil { if err != nil {
// The orphan is now invalid, so there // The orphan is now invalid, so there
@ -925,7 +929,7 @@ func (mp *TxPool) processOrphans(acceptedTx *btcutil.Tx) []*btcutil.Tx {
// the orphan pool, and add it to the list of // the orphan pool, and add it to the list of
// transactions to process so any orphans that // transactions to process so any orphans that
// depend on it are handled too. // depend on it are handled too.
acceptedTxns = append(acceptedTxns, tx) acceptedTxns = append(acceptedTxns, txD)
mp.removeOrphan(tx, false) mp.removeOrphan(tx, false)
processList.PushBack(tx) processList.PushBack(tx)
@ -941,8 +945,8 @@ func (mp *TxPool) processOrphans(acceptedTx *btcutil.Tx) []*btcutil.Tx {
// by the accepted transactions since those are now definitive double // by the accepted transactions since those are now definitive double
// spends. // spends.
mp.removeOrphanDoubleSpends(acceptedTx) mp.removeOrphanDoubleSpends(acceptedTx)
for _, tx := range acceptedTxns { for _, txD := range acceptedTxns {
mp.removeOrphanDoubleSpends(tx) mp.removeOrphanDoubleSpends(txD.Tx)
} }
return acceptedTxns return acceptedTxns
@ -958,7 +962,7 @@ func (mp *TxPool) processOrphans(acceptedTx *btcutil.Tx) []*btcutil.Tx {
// no transactions were moved from the orphan pool to the mempool. // no transactions were moved from the orphan pool to the mempool.
// //
// This function is safe for concurrent access. // This function is safe for concurrent access.
func (mp *TxPool) ProcessOrphans(acceptedTx *btcutil.Tx) []*btcutil.Tx { func (mp *TxPool) ProcessOrphans(acceptedTx *btcutil.Tx) []*TxDesc {
mp.mtx.Lock() mp.mtx.Lock()
acceptedTxns := mp.processOrphans(acceptedTx) acceptedTxns := mp.processOrphans(acceptedTx)
mp.mtx.Unlock() mp.mtx.Unlock()
@ -977,7 +981,7 @@ func (mp *TxPool) ProcessOrphans(acceptedTx *btcutil.Tx) []*btcutil.Tx {
// the passed one being accepted. // the passed one being accepted.
// //
// This function is safe for concurrent access. // This function is safe for concurrent access.
func (mp *TxPool) ProcessTransaction(tx *btcutil.Tx, allowOrphan, rateLimit bool) ([]*btcutil.Tx, error) { func (mp *TxPool) ProcessTransaction(tx *btcutil.Tx, allowOrphan, rateLimit bool) ([]*TxDesc, error) {
log.Tracef("Processing transaction %v", tx.Hash()) log.Tracef("Processing transaction %v", tx.Hash())
// Protect concurrent access. // Protect concurrent access.
@ -985,7 +989,7 @@ func (mp *TxPool) ProcessTransaction(tx *btcutil.Tx, allowOrphan, rateLimit bool
defer mp.mtx.Unlock() defer mp.mtx.Unlock()
// Potentially accept the transaction to the memory pool. // Potentially accept the transaction to the memory pool.
missingParents, err := mp.maybeAcceptTransaction(tx, true, rateLimit, missingParents, txD, err := mp.maybeAcceptTransaction(tx, true, rateLimit,
true) true)
if err != nil { if err != nil {
return nil, err return nil, err
@ -997,11 +1001,11 @@ func (mp *TxPool) ProcessTransaction(tx *btcutil.Tx, allowOrphan, rateLimit bool
// are now available) and repeat for those accepted // are now available) and repeat for those accepted
// transactions until there are no more. // transactions until there are no more.
newTxs := mp.processOrphans(tx) newTxs := mp.processOrphans(tx)
acceptedTxs := make([]*btcutil.Tx, len(newTxs)+1) acceptedTxs := make([]*TxDesc, len(newTxs)+1)
// Add the parent transaction first so remote nodes // Add the parent transaction first so remote nodes
// do not add orphans. // do not add orphans.
acceptedTxs[0] = tx acceptedTxs[0] = txD
copy(acceptedTxs[1:], newTxs) copy(acceptedTxs[1:], newTxs)
return acceptedTxs, nil return acceptedTxs, nil

View file

@ -442,10 +442,10 @@ func TestSimpleOrphanChain(t *testing.T) {
"length does not match expected -- got %d, want %d", "length does not match expected -- got %d, want %d",
len(acceptedTxns), len(chainedTxns)) len(acceptedTxns), len(chainedTxns))
} }
for _, tx := range acceptedTxns { for _, txD := range acceptedTxns {
// Ensure the transaction is no longer in the orphan pool, is // Ensure the transaction is no longer in the orphan pool, is
// now in the transaction pool, and is reported as available. // now in the transaction pool, and is reported as available.
testPoolMembership(tc, tx, false, true) testPoolMembership(tc, txD.Tx, false, true)
} }
} }
@ -784,10 +784,10 @@ func TestMultiInputOrphanDoubleSpend(t *testing.T) {
"length does not match expected -- got %d, want %d", "length does not match expected -- got %d, want %d",
len(acceptedTxns), maxOrphans) len(acceptedTxns), maxOrphans)
} }
for _, tx := range acceptedTxns { for _, txD := range acceptedTxns {
// Ensure the transaction is no longer in the orphan pool, is // Ensure the transaction is no longer in the orphan pool, is
// in the transaction pool, and is reported as available. // in the transaction pool, and is reported as available.
testPoolMembership(tc, tx, false, true) testPoolMembership(tc, txD.Tx, false, true)
} }
// Ensure the double spending orphan is no longer in the orphan pool and // Ensure the double spending orphan is no longer in the orphan pool and

View file

@ -972,18 +972,18 @@ func (s *server) RemoveRebroadcastInventory(iv *wire.InvVect) {
// both websocket and getblocktemplate long poll clients of the passed // both websocket and getblocktemplate long poll clients of the passed
// transactions. This function should be called whenever new transactions // transactions. This function should be called whenever new transactions
// are added to the mempool. // are added to the mempool.
func (s *server) AnnounceNewTransactions(newTxs []*btcutil.Tx) { func (s *server) AnnounceNewTransactions(newTxs []*mempool.TxDesc) {
// Generate and relay inventory vectors for all newly accepted // Generate and relay inventory vectors for all newly accepted
// transactions into the memory pool due to the original being // transactions into the memory pool due to the original being
// accepted. // accepted.
for _, tx := range newTxs { for _, txD := range newTxs {
// Generate the inventory vector and relay it. // Generate the inventory vector and relay it.
iv := wire.NewInvVect(wire.InvTypeTx, tx.Hash()) iv := wire.NewInvVect(wire.InvTypeTx, txD.Tx.Hash())
s.RelayInventory(iv, tx) s.RelayInventory(iv, txD)
if s.rpcServer != nil { if s.rpcServer != nil {
// Notify websocket clients about mempool transactions. // Notify websocket clients about mempool transactions.
s.rpcServer.ntfnMgr.NotifyMempoolTx(tx, true) s.rpcServer.ntfnMgr.NotifyMempoolTx(txD.Tx, true)
// Potentially notify any getblocktemplate long poll clients // Potentially notify any getblocktemplate long poll clients
// about stale block templates due to the new transaction. // about stale block templates due to the new transaction.
@ -1319,14 +1319,14 @@ func (s *server) handleRelayInvMsg(state *peerState, msg relayMsg) {
// Don't relay the transaction if there is a bloom // Don't relay the transaction if there is a bloom
// filter loaded and the transaction doesn't match it. // filter loaded and the transaction doesn't match it.
if sp.filter.IsLoaded() { if sp.filter.IsLoaded() {
tx, ok := msg.data.(*btcutil.Tx) txD, ok := msg.data.(*mempool.TxDesc)
if !ok { if !ok {
peerLog.Warnf("Underlying data for tx" + peerLog.Warnf("Underlying data for tx" +
" inv relay is not a transaction") " inv relay is not a *mempool.TxDesc")
return return
} }
if !sp.filter.MatchTxAndUpdate(tx) { if !sp.filter.MatchTxAndUpdate(txD.Tx) {
return return
} }
} }