mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-06-29 10:19:26 +02:00
MOVEONLY: mempool checks to their own functions
No change in behavior, because package transactions would not be going through the rbf logic in PreChecks anyway (BIP125 is currently disabled for package acceptance, see ATMPArgs). We draw the line here because each individual transaction in package validation still goes through all PreChecks. For example, checking that one's own conflicts and dependencies are disjoint (a consensus check) and individual transaction mempool ancestor/descendant limits.
This commit is contained in:
@ -541,6 +541,14 @@ private:
|
||||
// only tests that are fast should be done here (to avoid CPU DoS).
|
||||
bool PreChecks(ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
|
||||
|
||||
// Run checks for mempool replace-by-fee.
|
||||
bool ReplacementChecks(Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
|
||||
|
||||
// Enforce package mempool ancestor/descendant limits (distinct from individual
|
||||
// ancestor/descendant limits done in PreChecks).
|
||||
bool PackageMempoolChecks(const std::vector<CTransactionRef>& txns,
|
||||
PackageValidationState& package_state) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
|
||||
|
||||
// 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(const ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
|
||||
@ -823,7 +831,18 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
||||
}
|
||||
|
||||
m_rbf = !ws.m_conflicts.empty();
|
||||
if (m_rbf) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemPoolAccept::ReplacementChecks(Workspace& ws)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
AssertLockHeld(m_pool.cs);
|
||||
|
||||
const CTransaction& tx = *ws.m_ptx;
|
||||
const uint256& hash = ws.m_hash;
|
||||
TxValidationState& state = ws.m_state;
|
||||
|
||||
CFeeRate newFeeRate(ws.m_modified_fees, ws.m_vsize);
|
||||
// It's possible that the replacement pays more fees than its direct conflicts but not more
|
||||
// than all conflicts (i.e. the direct conflicts have high-fee descendants). However, if the
|
||||
@ -845,7 +864,6 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
||||
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY,
|
||||
"replacement-adds-unconfirmed", *err_string);
|
||||
}
|
||||
|
||||
// Check if it's economically rational to mine this transaction rather than the ones it
|
||||
// replaces and pays for its own relay fees. Enforce BIP125 Rules #3 and #4.
|
||||
for (CTxMemPool::txiter it : ws.m_all_conflicting) {
|
||||
@ -856,6 +874,20 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
||||
::incrementalRelayFee, hash)}) {
|
||||
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "insufficient fee", *err_string);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemPoolAccept::PackageMempoolChecks(const std::vector<CTransactionRef>& txns,
|
||||
PackageValidationState& package_state)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
AssertLockHeld(m_pool.cs);
|
||||
|
||||
std::string err_string;
|
||||
if (!m_pool.CheckPackageLimits(txns, m_limit_ancestors, m_limit_ancestor_size, m_limit_descendants,
|
||||
m_limit_descendant_size, err_string)) {
|
||||
// This is a package-wide error, separate from an individual transaction error.
|
||||
return package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package-mempool-limits", err_string);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -966,6 +998,8 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef
|
||||
|
||||
if (!PreChecks(args, ws)) return MempoolAcceptResult::Failure(ws.m_state);
|
||||
|
||||
if (m_rbf && !ReplacementChecks(ws)) return MempoolAcceptResult::Failure(ws.m_state);
|
||||
|
||||
// Perform the inexpensive checks first and avoid hashing and signature verification unless
|
||||
// those checks pass, to mitigate CPU exhaustion denial-of-service attacks.
|
||||
if (!PolicyScriptChecks(args, ws)) return MempoolAcceptResult::Failure(ws.m_state);
|
||||
@ -1020,12 +1054,7 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
|
||||
// because it's unnecessary. Also, CPFP carve out can increase the limit for individual
|
||||
// transactions, but this exemption is not extended to packages in CheckPackageLimits().
|
||||
std::string err_string;
|
||||
if (txns.size() > 1 &&
|
||||
!m_pool.CheckPackageLimits(txns, m_limit_ancestors, m_limit_ancestor_size, m_limit_descendants,
|
||||
m_limit_descendant_size, err_string)) {
|
||||
// All transactions must have individually passed mempool ancestor and descendant limits
|
||||
// inside of PreChecks(), so this is separate from an individual transaction error.
|
||||
package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package-mempool-limits", err_string);
|
||||
if (txns.size() > 1 && !PackageMempoolChecks(txns, package_state)) {
|
||||
return PackageMempoolAcceptResult(package_state, std::move(results));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user