Skip to content

Commit 60c7b2d

Browse files
committed
validation: Consolidate AccessCoins calls in PreChecks
This should introduce no behaviour change, but avoids a few extra vector allocations and coins lookups
1 parent 34cde8f commit 60c7b2d

1 file changed

Lines changed: 31 additions & 28 deletions

File tree

src/validation.cpp

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)