@@ -896,40 +896,43 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
896896 strprintf (" %s: inputs missing/spent" , __func__));
897897 }
898898
899- // The mempool holds txs for the next block, so pass height+1 to CheckTxInputs
900- auto check_tx_inputs_res = m_view.AccessCoins (tx, [&tx, &state, &ws, this ](auto && coins) {
901- return Consensus::CheckTxInputs (tx, state, coins, m_active_chainstate.m_chain .Height () + 1 , ws.m_base_fees );
902- });
903- if (!check_tx_inputs_res) {
904- return false ; // state filled in by CheckTxInputs
905- }
899+ int64_t nSigOpsCost = 0 ;
900+ bool fSpendsCoinbase = false ;
901+ // Wrap access to required coins in their own scope to avoid coin lifetime extension issues
902+ auto res = m_view.AccessCoins (tx, [&, this ](auto && coins) {
903+ // The mempool holds txs for the next block, so pass height+1 to CheckTxInputs
904+ auto check_tx_inputs_res = Consensus::CheckTxInputs (tx, state, coins, m_active_chainstate.m_chain .Height () + 1 , ws.m_base_fees );
905+ if (!check_tx_inputs_res) {
906+ return false ; // state filled in by CheckTxInputs
907+ }
906908
907- if (m_pool.m_opts .require_standard ) {
908- state = ValidateInputsStandardness (tx, m_view);
909- if (state.IsInvalid ()) {
910- return false ;
909+ if (m_pool.m_opts .require_standard ) {
910+ state = ValidateInputsStandardness (tx, m_view);
911+ if (state.IsInvalid ()) {
912+ return false ;
913+ }
911914 }
912- }
913915
914- // Check for non-standard witnesses.
915- if (tx.HasWitness () && m_pool.m_opts .require_standard && !IsWitnessStandard (tx, m_view)) {
916- return state.Invalid (TxValidationResult::TX_WITNESS_MUTATED, " bad-witness-nonstandard" );
917- }
916+ // Check for non-standard witnesses.
917+ if (tx.HasWitness () && m_pool.m_opts .require_standard && !IsWitnessStandard (tx, m_view)) {
918+ return state.Invalid (TxValidationResult::TX_WITNESS_MUTATED, " bad-witness-nonstandard" );
919+ }
918920
919- int64_t nSigOpsCost = m_view.AccessCoins (tx, [&tx](auto && coins) {
920- return GetTransactionSigOpCost (tx, coins, STANDARD_SCRIPT_VERIFY_FLAGS);
921- });
921+ nSigOpsCost = GetTransactionSigOpCost (tx, coins, STANDARD_SCRIPT_VERIFY_FLAGS);
922922
923- // Keep track of transactions that spend a coinbase, which we re-scan
924- // during reorgs to ensure COINBASE_MATURITY is still met.
925- bool fSpendsCoinbase = false ;
926- for (const CTxIn &txin : tx.vin ) {
927- const Coin &coin = m_view.AccessCoin (txin.prevout );
928- if (coin.IsCoinBase ()) {
929- fSpendsCoinbase = true ;
930- break ;
923+ // Keep track of transactions that spend a coinbase, which we re-scan
924+ // during reorgs to ensure COINBASE_MATURITY is still met.
925+ for (const Coin& coin: coins) {
926+ if (coin.IsCoinBase ()) {
927+ fSpendsCoinbase = true ;
928+ break ;
929+ }
931930 }
932- }
931+
932+ return true ;
933+ });
934+
935+ if (!res) return res;
933936
934937 // Set entry_sequence to 0 when bypass_limits is used; this allows txs from a block
935938 // reorg to be marked earlier than any child txs that were already in the mempool.
0 commit comments