@@ -458,11 +458,13 @@ namespace {
458458class MemPoolAccept
459459{
460460public:
461- explicit MemPoolAccept (CTxMemPool& mempool) : m_pool(mempool), m_view(&m_dummy), m_viewmempool(&::ChainstateActive() .CoinsTip(), m_pool),
461+ explicit MemPoolAccept (CTxMemPool& mempool, CChainState& active_chainstate ) : m_pool(mempool), m_view(&m_dummy), m_viewmempool(&active_chainstate .CoinsTip(), m_pool), m_active_chainstate(active_chainstate ),
462462 m_limit_ancestors(gArgs .GetArg(" -limitancestorcount" , DEFAULT_ANCESTOR_LIMIT)),
463463 m_limit_ancestor_size(gArgs .GetArg(" -limitancestorsize" , DEFAULT_ANCESTOR_SIZE_LIMIT)*1000),
464464 m_limit_descendants(gArgs .GetArg(" -limitdescendantcount" , DEFAULT_DESCENDANT_LIMIT)),
465- m_limit_descendant_size(gArgs .GetArg(" -limitdescendantsize" , DEFAULT_DESCENDANT_SIZE_LIMIT)*1000) {}
465+ m_limit_descendant_size(gArgs .GetArg(" -limitdescendantsize" , DEFAULT_DESCENDANT_SIZE_LIMIT)*1000) {
466+ assert (std::addressof (::ChainstateActive ()) == std::addressof (m_active_chainstate));
467+ }
466468
467469 // We put the arguments we're handed into a struct, so we can pass them
468470 // around easier.
@@ -547,6 +549,8 @@ class MemPoolAccept
547549 CCoinsViewMemPool m_viewmempool;
548550 CCoinsView m_dummy;
549551
552+ CChainState& m_active_chainstate;
553+
550554 // The package limits in effect at the time of invocation.
551555 const size_t m_limit_ancestors;
552556 const size_t m_limit_ancestor_size;
@@ -601,7 +605,8 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
601605 // Only accept nLockTime-using transactions that can be mined in the next
602606 // block; we don't want our mempool filled up with transactions that can't
603607 // be mined yet.
604- if (!CheckFinalTx (::ChainActive ().Tip (), tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
608+ assert (std::addressof (::ChainActive ()) == std::addressof (m_active_chainstate.m_chain ));
609+ if (!CheckFinalTx (m_active_chainstate.m_chain .Tip (), tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
605610 return state.Invalid (TxValidationResult::TX_PREMATURE_SPEND, " non-final" );
606611
607612 // is it already in the memory pool?
@@ -649,7 +654,8 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
649654 LockPoints lp;
650655 m_view.SetBackend (m_viewmempool);
651656
652- const CCoinsViewCache& coins_cache = ::ChainstateActive ().CoinsTip ();
657+ assert (std::addressof (::ChainstateActive ().CoinsTip ()) == std::addressof (m_active_chainstate.CoinsTip ()));
658+ const CCoinsViewCache& coins_cache = m_active_chainstate.CoinsTip ();
653659 // do all inputs exist?
654660 for (const CTxIn& txin : tx.vin ) {
655661 if (!coins_cache.HaveCoinInCache (txin.prevout )) {
@@ -685,16 +691,19 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
685691 // be mined yet.
686692 // Must keep pool.cs for this unless we change CheckSequenceLocks to take a
687693 // CoinsViewCache instead of create its own
688- if (!CheckSequenceLocks (::ChainstateActive (), m_pool, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
694+ assert (std::addressof (::ChainstateActive ()) == std::addressof (m_active_chainstate));
695+ if (!CheckSequenceLocks (m_active_chainstate, m_pool, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
689696 return state.Invalid (TxValidationResult::TX_PREMATURE_SPEND, " non-BIP68-final" );
690697
691- if (!Consensus::CheckTxInputs (tx, state, m_view, g_chainman.m_blockman .GetSpendHeight (m_view), ws.m_base_fees )) {
698+ assert (std::addressof (g_chainman.m_blockman ) == std::addressof (m_active_chainstate.m_blockman ));
699+ if (!Consensus::CheckTxInputs (tx, state, m_view, m_active_chainstate.m_blockman .GetSpendHeight (m_view), ws.m_base_fees )) {
692700 return false ; // state filled in by CheckTxInputs
693701 }
694702
695703 // Check for non-standard pay-to-script-hash in inputs
696704 const auto & params = args.m_chainparams .GetConsensus ();
697- auto taproot_state = VersionBitsState (::ChainActive ().Tip (), params, Consensus::DEPLOYMENT_TAPROOT, versionbitscache);
705+ assert (std::addressof (::ChainActive ()) == std::addressof (m_active_chainstate.m_chain ));
706+ auto taproot_state = VersionBitsState (m_active_chainstate.m_chain .Tip (), params, Consensus::DEPLOYMENT_TAPROOT, versionbitscache);
698707 if (fRequireStandard && !AreInputsStandard (tx, m_view, taproot_state == ThresholdState::ACTIVE)) {
699708 return state.Invalid (TxValidationResult::TX_INPUTS_NOT_STANDARD, " bad-txns-nonstandard-inputs" );
700709 }
@@ -720,7 +729,8 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
720729 }
721730 }
722731
723- entry.reset (new CTxMemPoolEntry (ptx, ws.m_base_fees , nAcceptTime, ::ChainActive ().Height (),
732+ assert (std::addressof (::ChainActive ()) == std::addressof (m_active_chainstate.m_chain ));
733+ entry.reset (new CTxMemPoolEntry (ptx, ws.m_base_fees , nAcceptTime, m_active_chainstate.m_chain .Height (),
724734 fSpendsCoinbase , nSigOpsCost, lp));
725735 unsigned int nSize = entry->GetTxSize ();
726736
@@ -972,8 +982,10 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws, P
972982 // There is a similar check in CreateNewBlock() to prevent creating
973983 // invalid blocks (using TestBlockValidity), however allowing such
974984 // transactions into the mempool can be exploited as a DoS attack.
975- unsigned int currentBlockScriptVerifyFlags = GetBlockScriptFlags (::ChainActive ().Tip (), chainparams.GetConsensus ());
976- if (!CheckInputsFromMempoolAndCache (tx, state, m_view, m_pool, currentBlockScriptVerifyFlags, txdata, ::ChainstateActive ().CoinsTip ())) {
985+ assert (std::addressof (::ChainActive ()) == std::addressof (m_active_chainstate.m_chain ));
986+ unsigned int currentBlockScriptVerifyFlags = GetBlockScriptFlags (m_active_chainstate.m_chain .Tip (), chainparams.GetConsensus ());
987+ assert (std::addressof (::ChainstateActive ().CoinsTip ()) == std::addressof (m_active_chainstate.CoinsTip ()));
988+ if (!CheckInputsFromMempoolAndCache (tx, state, m_view, m_pool, currentBlockScriptVerifyFlags, txdata, m_active_chainstate.CoinsTip ())) {
977989 return error (" %s: BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s" ,
978990 __func__, hash.ToString (), state.ToString ());
979991 }
@@ -1013,14 +1025,16 @@ bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws)
10131025 // - it's not being re-added during a reorg which bypasses typical mempool fee limits
10141026 // - the node is not behind
10151027 // - the transaction is not dependent on any other transactions in the mempool
1016- bool validForFeeEstimation = !fReplacementTransaction && !bypass_limits && IsCurrentForFeeEstimation (::ChainstateActive ()) && m_pool.HasNoInputsOf (tx);
1028+ assert (std::addressof (::ChainstateActive ()) == std::addressof (m_active_chainstate));
1029+ bool validForFeeEstimation = !fReplacementTransaction && !bypass_limits && IsCurrentForFeeEstimation (m_active_chainstate) && m_pool.HasNoInputsOf (tx);
10171030
10181031 // Store transaction in memory
10191032 m_pool.addUnchecked (*entry, setAncestors, validForFeeEstimation);
10201033
10211034 // trim mempool and check if tx was trimmed
10221035 if (!bypass_limits) {
1023- LimitMempoolSize (m_pool, ::ChainstateActive ().CoinsTip (), gArgs .GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 , std::chrono::hours{gArgs .GetArg (" -mempoolexpiry" , DEFAULT_MEMPOOL_EXPIRY)});
1036+ assert (std::addressof (::ChainstateActive ().CoinsTip ()) == std::addressof (m_active_chainstate.CoinsTip ()));
1037+ LimitMempoolSize (m_pool, m_active_chainstate.CoinsTip (), gArgs .GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 , std::chrono::hours{gArgs .GetArg (" -mempoolexpiry" , DEFAULT_MEMPOOL_EXPIRY)});
10241038 if (!m_pool.exists (hash))
10251039 return state.Invalid (TxValidationResult::TX_MEMPOOL_POLICY, " mempool full" );
10261040 }
@@ -1069,7 +1083,7 @@ static MempoolAcceptResult AcceptToMemoryPoolWithTime(const CChainParams& chainp
10691083 std::vector<COutPoint> coins_to_uncache;
10701084 MemPoolAccept::ATMPArgs args { chainparams, nAcceptTime, bypass_limits, coins_to_uncache, test_accept };
10711085
1072- const MempoolAcceptResult result = MemPoolAccept (pool).AcceptSingleTransaction (tx, args);
1086+ const MempoolAcceptResult result = MemPoolAccept (pool, :: ChainstateActive () ).AcceptSingleTransaction (tx, args);
10731087 if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
10741088 // Remove coins that were not present in the coins cache before calling ATMPW;
10751089 // this is to prevent memory DoS in case we receive a large number of
0 commit comments