mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-06-02 15:32:34 +02:00
[refactor] const ATMPArgs and non-const Workspace
ATMPArgs should contain const arguments for validation. The Workspace should contain state that may change throughout validation.
This commit is contained in:
parent
f82baf0762
commit
174cb5330a
@ -461,9 +461,7 @@ public:
|
|||||||
// around easier.
|
// around easier.
|
||||||
struct ATMPArgs {
|
struct ATMPArgs {
|
||||||
const CChainParams& m_chainparams;
|
const CChainParams& m_chainparams;
|
||||||
TxValidationState &m_state;
|
|
||||||
const int64_t m_accept_time;
|
const int64_t m_accept_time;
|
||||||
std::list<CTransactionRef> m_replaced_transactions;
|
|
||||||
const bool m_bypass_limits;
|
const bool m_bypass_limits;
|
||||||
/*
|
/*
|
||||||
* Return any outpoints which were not previously present in the coins
|
* Return any outpoints which were not previously present in the coins
|
||||||
@ -474,7 +472,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
std::vector<COutPoint>& m_coins_to_uncache;
|
std::vector<COutPoint>& m_coins_to_uncache;
|
||||||
const bool m_test_accept;
|
const bool m_test_accept;
|
||||||
CAmount m_fee_out;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Single transaction acceptance
|
// Single transaction acceptance
|
||||||
@ -489,14 +486,17 @@ private:
|
|||||||
CTxMemPool::setEntries m_all_conflicting;
|
CTxMemPool::setEntries m_all_conflicting;
|
||||||
CTxMemPool::setEntries m_ancestors;
|
CTxMemPool::setEntries m_ancestors;
|
||||||
std::unique_ptr<CTxMemPoolEntry> m_entry;
|
std::unique_ptr<CTxMemPoolEntry> m_entry;
|
||||||
|
std::list<CTransactionRef> m_replaced_transactions;
|
||||||
|
|
||||||
bool m_replacement_transaction;
|
bool m_replacement_transaction;
|
||||||
|
CAmount m_fee_out;
|
||||||
CAmount m_modified_fees;
|
CAmount m_modified_fees;
|
||||||
CAmount m_conflicting_fees;
|
CAmount m_conflicting_fees;
|
||||||
size_t m_conflicting_size;
|
size_t m_conflicting_size;
|
||||||
|
|
||||||
const CTransactionRef& m_ptx;
|
const CTransactionRef& m_ptx;
|
||||||
const uint256& m_hash;
|
const uint256& m_hash;
|
||||||
|
TxValidationState m_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Run the policy checks on a given transaction, excluding any script checks.
|
// 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
|
// 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.
|
// 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
|
// Re-run the script checks, using consensus flags, and try to cache the
|
||||||
// result in the scriptcache. This should be done after
|
// result in the scriptcache. This should be done after
|
||||||
// PolicyScriptChecks(). This requires that all inputs either be in our
|
// PolicyScriptChecks(). This requires that all inputs either be in our
|
||||||
// utxo set or in the mempool.
|
// 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.
|
// Try to add the transaction to the mempool, removing any conflicts first.
|
||||||
// Returns true if the transaction is in the mempool after any size
|
// Returns true if the transaction is in the mempool after any size
|
||||||
// limiting is performed, false otherwise.
|
// 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.
|
// 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)
|
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;
|
const uint256& hash = ws.m_hash;
|
||||||
|
|
||||||
// Copy/alias what we need out of args
|
// Copy/alias what we need out of args
|
||||||
TxValidationState &state = args.m_state;
|
|
||||||
const int64_t nAcceptTime = args.m_accept_time;
|
const int64_t nAcceptTime = args.m_accept_time;
|
||||||
const bool bypass_limits = args.m_bypass_limits;
|
const bool bypass_limits = args.m_bypass_limits;
|
||||||
std::vector<COutPoint>& coins_to_uncache = args.m_coins_to_uncache;
|
std::vector<COutPoint>& coins_to_uncache = args.m_coins_to_uncache;
|
||||||
|
|
||||||
// Alias what we need out of ws
|
// Alias what we need out of ws
|
||||||
|
TxValidationState &state = ws.m_state;
|
||||||
std::set<uint256>& setConflicts = ws.m_conflicts;
|
std::set<uint256>& setConflicts = ws.m_conflicts;
|
||||||
CTxMemPool::setEntries& allConflicting = ws.m_all_conflicting;
|
CTxMemPool::setEntries& allConflicting = ws.m_all_conflicting;
|
||||||
CTxMemPool::setEntries& setAncestors = ws.m_ancestors;
|
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))
|
if (!CheckSequenceLocks(m_pool, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
|
||||||
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-BIP68-final");
|
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), ws.m_fee_out)) {
|
||||||
if (!Consensus::CheckTxInputs(tx, state, m_view, g_chainman.m_blockman.GetSpendHeight(m_view), nFees)) {
|
|
||||||
return false; // state filled in by CheckTxInputs
|
return false; // state filled in by CheckTxInputs
|
||||||
}
|
}
|
||||||
|
|
||||||
args.m_fee_out = nFees;
|
|
||||||
|
|
||||||
// Check for non-standard pay-to-script-hash in inputs
|
// Check for non-standard pay-to-script-hash in inputs
|
||||||
const auto& params = args.m_chainparams.GetConsensus();
|
const auto& params = args.m_chainparams.GetConsensus();
|
||||||
auto taproot_state = VersionBitsState(::ChainActive().Tip(), params, Consensus::DEPLOYMENT_TAPROOT, versionbitscache);
|
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);
|
int64_t nSigOpsCost = GetTransactionSigOpCost(tx, m_view, STANDARD_SCRIPT_VERIFY_FLAGS);
|
||||||
|
|
||||||
// nModifiedFees includes any fee deltas from PrioritiseTransaction
|
// nModifiedFees includes any fee deltas from PrioritiseTransaction
|
||||||
nModifiedFees = nFees;
|
nModifiedFees = ws.m_fee_out;
|
||||||
m_pool.ApplyDelta(hash, nModifiedFees);
|
m_pool.ApplyDelta(hash, nModifiedFees);
|
||||||
|
|
||||||
// Keep track of transactions that spend a coinbase, which we re-scan
|
// 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));
|
fSpendsCoinbase, nSigOpsCost, lp));
|
||||||
unsigned int nSize = entry->GetTxSize();
|
unsigned int nSize = entry->GetTxSize();
|
||||||
|
|
||||||
@ -920,11 +917,10 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||||||
return true;
|
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;
|
const CTransaction& tx = *ws.m_ptx;
|
||||||
|
TxValidationState &state = ws.m_state;
|
||||||
TxValidationState &state = args.m_state;
|
|
||||||
|
|
||||||
constexpr unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS;
|
constexpr unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS;
|
||||||
|
|
||||||
@ -947,12 +943,11 @@ bool MemPoolAccept::PolicyScriptChecks(ATMPArgs& args, const Workspace& ws, Prec
|
|||||||
return true;
|
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 CTransaction& tx = *ws.m_ptx;
|
||||||
const uint256& hash = ws.m_hash;
|
const uint256& hash = ws.m_hash;
|
||||||
|
TxValidationState &state = ws.m_state;
|
||||||
TxValidationState &state = args.m_state;
|
|
||||||
const CChainParams& chainparams = args.m_chainparams;
|
const CChainParams& chainparams = args.m_chainparams;
|
||||||
|
|
||||||
// Check again against the current block tip's script verification
|
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemPoolAccept::Finalize(ATMPArgs& args, Workspace& ws)
|
bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws)
|
||||||
{
|
{
|
||||||
const CTransaction& tx = *ws.m_ptx;
|
const CTransaction& tx = *ws.m_ptx;
|
||||||
const uint256& hash = ws.m_hash;
|
const uint256& hash = ws.m_hash;
|
||||||
TxValidationState &state = args.m_state;
|
TxValidationState &state = ws.m_state;
|
||||||
const bool bypass_limits = args.m_bypass_limits;
|
const bool bypass_limits = args.m_bypass_limits;
|
||||||
|
|
||||||
CTxMemPool::setEntries& allConflicting = ws.m_all_conflicting;
|
CTxMemPool::setEntries& allConflicting = ws.m_all_conflicting;
|
||||||
@ -1002,7 +997,7 @@ bool MemPoolAccept::Finalize(ATMPArgs& args, Workspace& ws)
|
|||||||
hash.ToString(),
|
hash.ToString(),
|
||||||
FormatMoney(nModifiedFees - nConflictingFees),
|
FormatMoney(nModifiedFees - nConflictingFees),
|
||||||
(int)entry->GetTxSize() - (int)nConflictingSize);
|
(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);
|
m_pool.RemoveStaged(allConflicting, false, MemPoolRemovalReason::REPLACED);
|
||||||
|
|
||||||
@ -1032,7 +1027,7 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef
|
|||||||
|
|
||||||
Workspace workspace(ptx);
|
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
|
// Only compute the precomputed transaction data if we need to verify
|
||||||
// scripts (ie, other policy checks pass). We perform the inexpensive
|
// 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.
|
// checks pass, to mitigate CPU exhaustion denial-of-service attacks.
|
||||||
PrecomputedTransactionData txdata;
|
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
|
// Tx was accepted, but not added
|
||||||
if (args.m_test_accept) {
|
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());
|
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
|
} // anon namespace
|
||||||
@ -1064,9 +1059,8 @@ static MempoolAcceptResult AcceptToMemoryPoolWithTime(const CChainParams& chainp
|
|||||||
bool bypass_limits, bool test_accept)
|
bool bypass_limits, bool test_accept)
|
||||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||||
{
|
{
|
||||||
TxValidationState state;
|
|
||||||
std::vector<COutPoint> coins_to_uncache;
|
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);
|
const MempoolAcceptResult result = MemPoolAccept(pool).AcceptSingleTransaction(tx, args);
|
||||||
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
|
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
|
||||||
|
Loading…
Reference in New Issue
Block a user