@@ -513,6 +513,9 @@ class MemPoolAccept
513
513
const CTransactionRef& m_ptx;
514
514
const uint256& m_hash;
515
515
TxValidationState m_state;
516
+ /* * A temporary cache containing serialized transaction data for signature verification.
517
+ * Reused across PolicyScriptChecks and ConsensusScriptChecks. */
518
+ PrecomputedTransactionData m_precomputed_txdata;
516
519
};
517
520
518
521
// Run the policy checks on a given transaction, excluding any script checks.
@@ -523,13 +526,13 @@ class MemPoolAccept
523
526
524
527
// Run the script checks using our policy flags. As this can be slow, we should
525
528
// only invoke this on transactions that have otherwise passed policy checks.
526
- bool PolicyScriptChecks (const ATMPArgs& args, Workspace& ws, PrecomputedTransactionData& txdata ) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
529
+ bool PolicyScriptChecks (const ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
527
530
528
531
// Re-run the script checks, using consensus flags, and try to cache the
529
532
// result in the scriptcache. This should be done after
530
533
// PolicyScriptChecks(). This requires that all inputs either be in our
531
534
// utxo set or in the mempool.
532
- bool ConsensusScriptChecks (const ATMPArgs& args, Workspace& ws, PrecomputedTransactionData &txdata ) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
535
+ bool ConsensusScriptChecks (const ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
533
536
534
537
// Try to add the transaction to the mempool, removing any conflicts first.
535
538
// Returns true if the transaction is in the mempool after any size
@@ -842,7 +845,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
842
845
return true ;
843
846
}
844
847
845
- bool MemPoolAccept::PolicyScriptChecks (const ATMPArgs& args, Workspace& ws, PrecomputedTransactionData& txdata )
848
+ bool MemPoolAccept::PolicyScriptChecks (const ATMPArgs& args, Workspace& ws)
846
849
{
847
850
const CTransaction& tx = *ws.m_ptx ;
848
851
TxValidationState& state = ws.m_state ;
@@ -851,13 +854,13 @@ bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws, Prec
851
854
852
855
// Check input scripts and signatures.
853
856
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
854
- if (!CheckInputScripts (tx, state, m_view, scriptVerifyFlags, true , false , txdata )) {
857
+ if (!CheckInputScripts (tx, state, m_view, scriptVerifyFlags, true , false , ws. m_precomputed_txdata )) {
855
858
// SCRIPT_VERIFY_CLEANSTACK requires SCRIPT_VERIFY_WITNESS, so we
856
859
// need to turn both off, and compare against just turning off CLEANSTACK
857
860
// to see if the failure is specifically due to witness validation.
858
861
TxValidationState state_dummy; // Want reported failures to be from first CheckInputScripts
859
- if (!tx.HasWitness () && CheckInputScripts (tx, state_dummy, m_view, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true , false , txdata ) &&
860
- !CheckInputScripts (tx, state_dummy, m_view, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true , false , txdata )) {
862
+ if (!tx.HasWitness () && CheckInputScripts (tx, state_dummy, m_view, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true , false , ws. m_precomputed_txdata ) &&
863
+ !CheckInputScripts (tx, state_dummy, m_view, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true , false , ws. m_precomputed_txdata )) {
861
864
// Only the witness is missing, so the transaction itself may be fine.
862
865
state.Invalid (TxValidationResult::TX_WITNESS_STRIPPED,
863
866
state.GetRejectReason (), state.GetDebugMessage ());
@@ -868,7 +871,7 @@ bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws, Prec
868
871
return true ;
869
872
}
870
873
871
- bool MemPoolAccept::ConsensusScriptChecks (const ATMPArgs& args, Workspace& ws, PrecomputedTransactionData& txdata )
874
+ bool MemPoolAccept::ConsensusScriptChecks (const ATMPArgs& args, Workspace& ws)
872
875
{
873
876
const CTransaction& tx = *ws.m_ptx ;
874
877
const uint256& hash = ws.m_hash ;
@@ -891,7 +894,8 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws, P
891
894
// invalid blocks (using TestBlockValidity), however allowing such
892
895
// transactions into the mempool can be exploited as a DoS attack.
893
896
unsigned int currentBlockScriptVerifyFlags = GetBlockScriptFlags (m_active_chainstate.m_chain .Tip (), chainparams.GetConsensus ());
894
- if (!CheckInputsFromMempoolAndCache (tx, state, m_view, m_pool, currentBlockScriptVerifyFlags, txdata, m_active_chainstate.CoinsTip ())) {
897
+ if (!CheckInputsFromMempoolAndCache (tx, state, m_view, m_pool, currentBlockScriptVerifyFlags,
898
+ ws.m_precomputed_txdata , m_active_chainstate.CoinsTip ())) {
895
899
return error (" %s: BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s" ,
896
900
__func__, hash.ToString (), state.ToString ());
897
901
}
@@ -952,15 +956,11 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef
952
956
953
957
if (!PreChecks (args, ws)) return MempoolAcceptResult::Failure (ws.m_state );
954
958
955
- // Only compute the precomputed transaction data if we need to verify
956
- // scripts (ie, other policy checks pass). We perform the inexpensive
957
- // checks first and avoid hashing and signature verification unless those
958
- // checks pass, to mitigate CPU exhaustion denial-of-service attacks.
959
- PrecomputedTransactionData txdata;
959
+ // Perform the inexpensive checks first and avoid hashing and signature verification unless
960
+ // those checks pass, to mitigate CPU exhaustion denial-of-service attacks.
961
+ if (!PolicyScriptChecks (args, ws)) return MempoolAcceptResult::Failure (ws.m_state );
960
962
961
- if (!PolicyScriptChecks (args, ws, txdata)) return MempoolAcceptResult::Failure (ws.m_state );
962
-
963
- if (!ConsensusScriptChecks (args, ws, txdata)) return MempoolAcceptResult::Failure (ws.m_state );
963
+ if (!ConsensusScriptChecks (args, ws)) return MempoolAcceptResult::Failure (ws.m_state );
964
964
965
965
// Tx was accepted, but not added
966
966
if (args.m_test_accept ) {
@@ -1020,8 +1020,7 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
1020
1020
}
1021
1021
1022
1022
for (Workspace& ws : workspaces) {
1023
- PrecomputedTransactionData txdata;
1024
- if (!PolicyScriptChecks (args, ws, txdata)) {
1023
+ if (!PolicyScriptChecks (args, ws)) {
1025
1024
// Exit early to avoid doing pointless work. Update the failed tx result; the rest are unfinished.
1026
1025
package_state.Invalid (PackageValidationResult::PCKG_TX, " transaction failed" );
1027
1026
results.emplace (ws.m_ptx ->GetWitnessHash (), MempoolAcceptResult::Failure (ws.m_state ));
0 commit comments