aboutsummaryrefslogtreecommitdiff
path: root/src/validation.cpp
diff options
context:
space:
mode:
authorgzhao408 <gzhao408@berkeley.edu>2021-01-19 09:32:20 -0800
committergzhao408 <gzhao408@berkeley.edu>2021-02-09 07:01:52 -0800
commit174cb5330af4b09f3a66974d3bae783ea43b190e (patch)
tree36832da190d5b9b80cd7fec82728d075fa2461c4 /src/validation.cpp
parentf82baf0762f60c2ca5ffc339b095f9271d7c2f33 (diff)
downloadbitcoin-174cb5330af4b09f3a66974d3bae783ea43b190e.tar.xz
[refactor] const ATMPArgs and non-const Workspace
ATMPArgs should contain const arguments for validation. The Workspace should contain state that may change throughout validation.
Diffstat (limited to 'src/validation.cpp')
-rw-r--r--src/validation.cpp54
1 files changed, 24 insertions, 30 deletions
diff --git a/src/validation.cpp b/src/validation.cpp
index a1e57752d3..fc6edbf440 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -461,9 +461,7 @@ public:
// around easier.
struct ATMPArgs {
const CChainParams& m_chainparams;
- TxValidationState &m_state;
const int64_t m_accept_time;
- std::list<CTransactionRef> m_replaced_transactions;
const bool m_bypass_limits;
/*
* Return any outpoints which were not previously present in the coins
@@ -474,7 +472,6 @@ public:
*/
std::vector<COutPoint>& m_coins_to_uncache;
const bool m_test_accept;
- CAmount m_fee_out;
};
// Single transaction acceptance
@@ -489,14 +486,17 @@ private:
CTxMemPool::setEntries m_all_conflicting;
CTxMemPool::setEntries m_ancestors;
std::unique_ptr<CTxMemPoolEntry> m_entry;
+ std::list<CTransactionRef> m_replaced_transactions;
bool m_replacement_transaction;
+ CAmount m_fee_out;
CAmount m_modified_fees;
CAmount m_conflicting_fees;
size_t m_conflicting_size;
const CTransactionRef& m_ptx;
const uint256& m_hash;
+ TxValidationState m_state;
};
// Run the policy checks on a given transaction, excluding any script checks.
@@ -507,18 +507,18 @@ private:
// Run the script checks using our policy flags. As this can be slow, we should
// only invoke this on transactions that have otherwise passed policy checks.
- bool PolicyScriptChecks(ATMPArgs& args, const Workspace& ws, PrecomputedTransactionData& txdata) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
+ bool PolicyScriptChecks(const ATMPArgs& args, Workspace& ws, PrecomputedTransactionData& txdata) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
// Re-run the script checks, using consensus flags, and try to cache the
// result in the scriptcache. This should be done after
// PolicyScriptChecks(). This requires that all inputs either be in our
// utxo set or in the mempool.
- bool ConsensusScriptChecks(ATMPArgs& args, const Workspace& ws, PrecomputedTransactionData &txdata) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
+ bool ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws, PrecomputedTransactionData &txdata) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
// Try to add the transaction to the mempool, removing any conflicts first.
// Returns true if the transaction is in the mempool after any size
// limiting is performed, false otherwise.
- bool Finalize(ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
+ bool Finalize(const ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
// Compare a package's feerate against minimum allowed.
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)
const uint256& hash = ws.m_hash;
// Copy/alias what we need out of args
- TxValidationState &state = args.m_state;
const int64_t nAcceptTime = args.m_accept_time;
const bool bypass_limits = args.m_bypass_limits;
std::vector<COutPoint>& coins_to_uncache = args.m_coins_to_uncache;
// Alias what we need out of ws
+ TxValidationState &state = ws.m_state;
std::set<uint256>& setConflicts = ws.m_conflicts;
CTxMemPool::setEntries& allConflicting = ws.m_all_conflicting;
CTxMemPool::setEntries& setAncestors = ws.m_ancestors;
@@ -681,13 +681,10 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
if (!CheckSequenceLocks(m_pool, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-BIP68-final");
- CAmount nFees = 0;
- if (!Consensus::CheckTxInputs(tx, state, m_view, g_chainman.m_blockman.GetSpendHeight(m_view), nFees)) {
+ if (!Consensus::CheckTxInputs(tx, state, m_view, g_chainman.m_blockman.GetSpendHeight(m_view), ws.m_fee_out)) {
return false; // state filled in by CheckTxInputs
}
- args.m_fee_out = nFees;
-
// Check for non-standard pay-to-script-hash in inputs
const auto& params = args.m_chainparams.GetConsensus();
auto taproot_state = VersionBitsState(::ChainActive().Tip(), params, Consensus::DEPLOYMENT_TAPROOT, versionbitscache);
@@ -702,7 +699,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
int64_t nSigOpsCost = GetTransactionSigOpCost(tx, m_view, STANDARD_SCRIPT_VERIFY_FLAGS);
// nModifiedFees includes any fee deltas from PrioritiseTransaction
- nModifiedFees = nFees;
+ nModifiedFees = ws.m_fee_out;
m_pool.ApplyDelta(hash, nModifiedFees);
// Keep track of transactions that spend a coinbase, which we re-scan
@@ -716,7 +713,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
}
}
- entry.reset(new CTxMemPoolEntry(ptx, nFees, nAcceptTime, ::ChainActive().Height(),
+ entry.reset(new CTxMemPoolEntry(ptx, ws.m_fee_out, nAcceptTime, ::ChainActive().Height(),
fSpendsCoinbase, nSigOpsCost, lp));
unsigned int nSize = entry->GetTxSize();
@@ -920,11 +917,10 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
return true;
}
-bool MemPoolAccept::PolicyScriptChecks(ATMPArgs& args, const Workspace& ws, PrecomputedTransactionData& txdata)
+bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws, PrecomputedTransactionData& txdata)
{
const CTransaction& tx = *ws.m_ptx;
-
- TxValidationState &state = args.m_state;
+ TxValidationState &state = ws.m_state;
constexpr unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS;
@@ -947,12 +943,11 @@ bool MemPoolAccept::PolicyScriptChecks(ATMPArgs& args, const Workspace& ws, Prec
return true;
}
-bool MemPoolAccept::ConsensusScriptChecks(ATMPArgs& args, const Workspace& ws, PrecomputedTransactionData& txdata)
+bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws, PrecomputedTransactionData& txdata)
{
const CTransaction& tx = *ws.m_ptx;
const uint256& hash = ws.m_hash;
-
- TxValidationState &state = args.m_state;
+ TxValidationState &state = ws.m_state;
const CChainParams& chainparams = args.m_chainparams;
// Check again against the current block tip's script verification
@@ -979,11 +974,11 @@ bool MemPoolAccept::ConsensusScriptChecks(ATMPArgs& args, const Workspace& ws, P
return true;
}
-bool MemPoolAccept::Finalize(ATMPArgs& args, Workspace& ws)
+bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws)
{
const CTransaction& tx = *ws.m_ptx;
const uint256& hash = ws.m_hash;
- TxValidationState &state = args.m_state;
+ TxValidationState &state = ws.m_state;
const bool bypass_limits = args.m_bypass_limits;
CTxMemPool::setEntries& allConflicting = ws.m_all_conflicting;
@@ -1002,7 +997,7 @@ bool MemPoolAccept::Finalize(ATMPArgs& args, Workspace& ws)
hash.ToString(),
FormatMoney(nModifiedFees - nConflictingFees),
(int)entry->GetTxSize() - (int)nConflictingSize);
- args.m_replaced_transactions.push_back(it->GetSharedTx());
+ ws.m_replaced_transactions.push_back(it->GetSharedTx());
}
m_pool.RemoveStaged(allConflicting, false, MemPoolRemovalReason::REPLACED);
@@ -1032,7 +1027,7 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef
Workspace workspace(ptx);
- if (!PreChecks(args, workspace)) return MempoolAcceptResult(args.m_state);
+ if (!PreChecks(args, workspace)) return MempoolAcceptResult(workspace.m_state);
// Only compute the precomputed transaction data if we need to verify
// scripts (ie, other policy checks pass). We perform the inexpensive
@@ -1040,20 +1035,20 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef
// checks pass, to mitigate CPU exhaustion denial-of-service attacks.
PrecomputedTransactionData txdata;
- if (!PolicyScriptChecks(args, workspace, txdata)) return MempoolAcceptResult(args.m_state);
+ if (!PolicyScriptChecks(args, workspace, txdata)) return MempoolAcceptResult(workspace.m_state);
- if (!ConsensusScriptChecks(args, workspace, txdata)) return MempoolAcceptResult(args.m_state);
+ if (!ConsensusScriptChecks(args, workspace, txdata)) return MempoolAcceptResult(workspace.m_state);
// Tx was accepted, but not added
if (args.m_test_accept) {
- return MempoolAcceptResult(std::move(args.m_replaced_transactions), args.m_fee_out);
+ return MempoolAcceptResult(std::move(workspace.m_replaced_transactions), workspace.m_fee_out);
}
- if (!Finalize(args, workspace)) return MempoolAcceptResult(args.m_state);
+ if (!Finalize(args, workspace)) return MempoolAcceptResult(workspace.m_state);
GetMainSignals().TransactionAddedToMempool(ptx, m_pool.GetAndIncrementSequence());
- return MempoolAcceptResult(std::move(args.m_replaced_transactions), args.m_fee_out);
+ return MempoolAcceptResult(std::move(workspace.m_replaced_transactions), workspace.m_fee_out);
}
} // anon namespace
@@ -1064,9 +1059,8 @@ static MempoolAcceptResult AcceptToMemoryPoolWithTime(const CChainParams& chainp
bool bypass_limits, bool test_accept)
EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
- TxValidationState state;
std::vector<COutPoint> coins_to_uncache;
- MemPoolAccept::ATMPArgs args { chainparams, state, nAcceptTime, {}, bypass_limits, coins_to_uncache, test_accept, {} };
+ MemPoolAccept::ATMPArgs args { chainparams, nAcceptTime, bypass_limits, coins_to_uncache, test_accept };
const MempoolAcceptResult result = MemPoolAccept(pool).AcceptSingleTransaction(tx, args);
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {