Skip to content

Commit 174cb53

Browse files
committed
[refactor] const ATMPArgs and non-const Workspace
ATMPArgs should contain const arguments for validation. The Workspace should contain state that may change throughout validation.
1 parent f82baf0 commit 174cb53

File tree

1 file changed

+24
-30
lines changed

1 file changed

+24
-30
lines changed

src/validation.cpp

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,7 @@ class MemPoolAccept
461461
// around easier.
462462
struct ATMPArgs {
463463
const CChainParams& m_chainparams;
464-
TxValidationState &m_state;
465464
const int64_t m_accept_time;
466-
std::list<CTransactionRef> m_replaced_transactions;
467465
const bool m_bypass_limits;
468466
/*
469467
* Return any outpoints which were not previously present in the coins
@@ -474,7 +472,6 @@ class MemPoolAccept
474472
*/
475473
std::vector<COutPoint>& m_coins_to_uncache;
476474
const bool m_test_accept;
477-
CAmount m_fee_out;
478475
};
479476

480477
// Single transaction acceptance
@@ -489,14 +486,17 @@ class MemPoolAccept
489486
CTxMemPool::setEntries m_all_conflicting;
490487
CTxMemPool::setEntries m_ancestors;
491488
std::unique_ptr<CTxMemPoolEntry> m_entry;
489+
std::list<CTransactionRef> m_replaced_transactions;
492490

493491
bool m_replacement_transaction;
492+
CAmount m_fee_out;
494493
CAmount m_modified_fees;
495494
CAmount m_conflicting_fees;
496495
size_t m_conflicting_size;
497496

498497
const CTransactionRef& m_ptx;
499498
const uint256& m_hash;
499+
TxValidationState m_state;
500500
};
501501

502502
// Run the policy checks on a given transaction, excluding any script checks.
@@ -507,18 +507,18 @@ class MemPoolAccept
507507

508508
// Run the script checks using our policy flags. As this can be slow, we should
509509
// only invoke this on transactions that have otherwise passed policy checks.
510-
bool PolicyScriptChecks(ATMPArgs& args, const Workspace& ws, PrecomputedTransactionData& txdata) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
510+
bool PolicyScriptChecks(const ATMPArgs& args, Workspace& ws, PrecomputedTransactionData& txdata) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
511511

512512
// Re-run the script checks, using consensus flags, and try to cache the
513513
// result in the scriptcache. This should be done after
514514
// PolicyScriptChecks(). This requires that all inputs either be in our
515515
// utxo set or in the mempool.
516-
bool ConsensusScriptChecks(ATMPArgs& args, const Workspace& ws, PrecomputedTransactionData &txdata) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
516+
bool ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws, PrecomputedTransactionData &txdata) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
517517

518518
// Try to add the transaction to the mempool, removing any conflicts first.
519519
// Returns true if the transaction is in the mempool after any size
520520
// limiting is performed, false otherwise.
521-
bool Finalize(ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
521+
bool Finalize(const ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
522522

523523
// Compare a package's feerate against minimum allowed.
524524
bool CheckFeeRate(size_t package_size, CAmount package_fee, TxValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs)
@@ -556,12 +556,12 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
556556
const uint256& hash = ws.m_hash;
557557

558558
// Copy/alias what we need out of args
559-
TxValidationState &state = args.m_state;
560559
const int64_t nAcceptTime = args.m_accept_time;
561560
const bool bypass_limits = args.m_bypass_limits;
562561
std::vector<COutPoint>& coins_to_uncache = args.m_coins_to_uncache;
563562

564563
// Alias what we need out of ws
564+
TxValidationState &state = ws.m_state;
565565
std::set<uint256>& setConflicts = ws.m_conflicts;
566566
CTxMemPool::setEntries& allConflicting = ws.m_all_conflicting;
567567
CTxMemPool::setEntries& setAncestors = ws.m_ancestors;
@@ -681,13 +681,10 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
681681
if (!CheckSequenceLocks(m_pool, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
682682
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-BIP68-final");
683683

684-
CAmount nFees = 0;
685-
if (!Consensus::CheckTxInputs(tx, state, m_view, g_chainman.m_blockman.GetSpendHeight(m_view), nFees)) {
684+
if (!Consensus::CheckTxInputs(tx, state, m_view, g_chainman.m_blockman.GetSpendHeight(m_view), ws.m_fee_out)) {
686685
return false; // state filled in by CheckTxInputs
687686
}
688687

689-
args.m_fee_out = nFees;
690-
691688
// Check for non-standard pay-to-script-hash in inputs
692689
const auto& params = args.m_chainparams.GetConsensus();
693690
auto taproot_state = VersionBitsState(::ChainActive().Tip(), params, Consensus::DEPLOYMENT_TAPROOT, versionbitscache);
@@ -702,7 +699,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
702699
int64_t nSigOpsCost = GetTransactionSigOpCost(tx, m_view, STANDARD_SCRIPT_VERIFY_FLAGS);
703700

704701
// nModifiedFees includes any fee deltas from PrioritiseTransaction
705-
nModifiedFees = nFees;
702+
nModifiedFees = ws.m_fee_out;
706703
m_pool.ApplyDelta(hash, nModifiedFees);
707704

708705
// Keep track of transactions that spend a coinbase, which we re-scan
@@ -716,7 +713,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
716713
}
717714
}
718715

719-
entry.reset(new CTxMemPoolEntry(ptx, nFees, nAcceptTime, ::ChainActive().Height(),
716+
entry.reset(new CTxMemPoolEntry(ptx, ws.m_fee_out, nAcceptTime, ::ChainActive().Height(),
720717
fSpendsCoinbase, nSigOpsCost, lp));
721718
unsigned int nSize = entry->GetTxSize();
722719

@@ -920,11 +917,10 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
920917
return true;
921918
}
922919

923-
bool MemPoolAccept::PolicyScriptChecks(ATMPArgs& args, const Workspace& ws, PrecomputedTransactionData& txdata)
920+
bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws, PrecomputedTransactionData& txdata)
924921
{
925922
const CTransaction& tx = *ws.m_ptx;
926-
927-
TxValidationState &state = args.m_state;
923+
TxValidationState &state = ws.m_state;
928924

929925
constexpr unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS;
930926

@@ -947,12 +943,11 @@ bool MemPoolAccept::PolicyScriptChecks(ATMPArgs& args, const Workspace& ws, Prec
947943
return true;
948944
}
949945

950-
bool MemPoolAccept::ConsensusScriptChecks(ATMPArgs& args, const Workspace& ws, PrecomputedTransactionData& txdata)
946+
bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws, PrecomputedTransactionData& txdata)
951947
{
952948
const CTransaction& tx = *ws.m_ptx;
953949
const uint256& hash = ws.m_hash;
954-
955-
TxValidationState &state = args.m_state;
950+
TxValidationState &state = ws.m_state;
956951
const CChainParams& chainparams = args.m_chainparams;
957952

958953
// Check again against the current block tip's script verification
@@ -979,11 +974,11 @@ bool MemPoolAccept::ConsensusScriptChecks(ATMPArgs& args, const Workspace& ws, P
979974
return true;
980975
}
981976

982-
bool MemPoolAccept::Finalize(ATMPArgs& args, Workspace& ws)
977+
bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws)
983978
{
984979
const CTransaction& tx = *ws.m_ptx;
985980
const uint256& hash = ws.m_hash;
986-
TxValidationState &state = args.m_state;
981+
TxValidationState &state = ws.m_state;
987982
const bool bypass_limits = args.m_bypass_limits;
988983

989984
CTxMemPool::setEntries& allConflicting = ws.m_all_conflicting;
@@ -1002,7 +997,7 @@ bool MemPoolAccept::Finalize(ATMPArgs& args, Workspace& ws)
1002997
hash.ToString(),
1003998
FormatMoney(nModifiedFees - nConflictingFees),
1004999
(int)entry->GetTxSize() - (int)nConflictingSize);
1005-
args.m_replaced_transactions.push_back(it->GetSharedTx());
1000+
ws.m_replaced_transactions.push_back(it->GetSharedTx());
10061001
}
10071002
m_pool.RemoveStaged(allConflicting, false, MemPoolRemovalReason::REPLACED);
10081003

@@ -1032,28 +1027,28 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef
10321027

10331028
Workspace workspace(ptx);
10341029

1035-
if (!PreChecks(args, workspace)) return MempoolAcceptResult(args.m_state);
1030+
if (!PreChecks(args, workspace)) return MempoolAcceptResult(workspace.m_state);
10361031

10371032
// Only compute the precomputed transaction data if we need to verify
10381033
// scripts (ie, other policy checks pass). We perform the inexpensive
10391034
// checks first and avoid hashing and signature verification unless those
10401035
// checks pass, to mitigate CPU exhaustion denial-of-service attacks.
10411036
PrecomputedTransactionData txdata;
10421037

1043-
if (!PolicyScriptChecks(args, workspace, txdata)) return MempoolAcceptResult(args.m_state);
1038+
if (!PolicyScriptChecks(args, workspace, txdata)) return MempoolAcceptResult(workspace.m_state);
10441039

1045-
if (!ConsensusScriptChecks(args, workspace, txdata)) return MempoolAcceptResult(args.m_state);
1040+
if (!ConsensusScriptChecks(args, workspace, txdata)) return MempoolAcceptResult(workspace.m_state);
10461041

10471042
// Tx was accepted, but not added
10481043
if (args.m_test_accept) {
1049-
return MempoolAcceptResult(std::move(args.m_replaced_transactions), args.m_fee_out);
1044+
return MempoolAcceptResult(std::move(workspace.m_replaced_transactions), workspace.m_fee_out);
10501045
}
10511046

1052-
if (!Finalize(args, workspace)) return MempoolAcceptResult(args.m_state);
1047+
if (!Finalize(args, workspace)) return MempoolAcceptResult(workspace.m_state);
10531048

10541049
GetMainSignals().TransactionAddedToMempool(ptx, m_pool.GetAndIncrementSequence());
10551050

1056-
return MempoolAcceptResult(std::move(args.m_replaced_transactions), args.m_fee_out);
1051+
return MempoolAcceptResult(std::move(workspace.m_replaced_transactions), workspace.m_fee_out);
10571052
}
10581053

10591054
} // anon namespace
@@ -1064,9 +1059,8 @@ static MempoolAcceptResult AcceptToMemoryPoolWithTime(const CChainParams& chainp
10641059
bool bypass_limits, bool test_accept)
10651060
EXCLUSIVE_LOCKS_REQUIRED(cs_main)
10661061
{
1067-
TxValidationState state;
10681062
std::vector<COutPoint> coins_to_uncache;
1069-
MemPoolAccept::ATMPArgs args { chainparams, state, nAcceptTime, {}, bypass_limits, coins_to_uncache, test_accept, {} };
1063+
MemPoolAccept::ATMPArgs args { chainparams, nAcceptTime, bypass_limits, coins_to_uncache, test_accept };
10701064

10711065
const MempoolAcceptResult result = MemPoolAccept(pool).AcceptSingleTransaction(tx, args);
10721066
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {

0 commit comments

Comments
 (0)