Merge b0222bbb49 into merged_master (Bitcoin PR bitcoin/bitcoin#30239)

This commit is contained in:
ivanlele 2026-04-03 08:45:56 +00:00
commit 744c517dac
No known key found for this signature in database
22 changed files with 1236 additions and 10 deletions

View file

@ -34,6 +34,7 @@
#include <node/blockstorage.h>
#include <node/utxo_snapshot.h>
#include <pegins.h>
#include <policy/ephemeral_policy.h>
#include <policy/policy.h>
#include <policy/rbf.h>
#include <policy/settings.h>
@ -1134,6 +1135,13 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
fSpendsCoinbase, nSigOpsCost, lock_points.value(), setPeginsSpent));
ws.m_vsize = entry->GetTxSize();
// Enforces 0-fee for dust transactions, no incentive to be mined alone
if (m_pool.m_opts.require_standard) {
if (!CheckValidEphemeralTx(ptx, m_pool.m_opts.dust_relay_feerate, ws.m_base_fees, ws.m_modified_fees, state)) {
return false; // state filled in by CheckValidEphemeralTx
}
}
if (nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST)
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, "bad-txns-too-many-sigops",
strprintf("%d", nSigOpsCost));
@ -1667,6 +1675,16 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef
return MempoolAcceptResult::Failure(ws.m_state);
}
if (m_pool.m_opts.require_standard) {
if (const auto ephemeral_violation{CheckEphemeralSpends(/*package=*/{ptx}, m_pool.m_opts.dust_relay_feerate, m_pool)}) {
const Txid& txid = ephemeral_violation.value();
Assume(txid == ptx->GetHash());
ws.m_state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "missing-ephemeral-spends",
strprintf("tx %s did not spend parent's ephemeral dust", txid.ToString()));
return MempoolAcceptResult::Failure(ws.m_state);
}
}
if (m_subpackage.m_rbf && !ReplacementChecks(ws)) {
if (ws.m_state.GetResult() == TxValidationResult::TX_RECONSIDERABLE) {
// Failed for incentives-based fee reasons. Provide the effective feerate and which tx was included.
@ -1805,6 +1823,19 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
return PackageMempoolAcceptResult(package_state, std::move(results));
}
// Now that we've bounded the resulting possible ancestry count, check package for dust spends
if (m_pool.m_opts.require_standard) {
if (const auto ephemeral_violation{CheckEphemeralSpends(txns, m_pool.m_opts.dust_relay_feerate, m_pool)}) {
const Txid& child_txid = ephemeral_violation.value();
TxValidationState child_state;
child_state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "missing-ephemeral-spends",
strprintf("tx %s did not spend parent's ephemeral dust", child_txid.ToString()));
package_state.Invalid(PackageValidationResult::PCKG_TX, "unspent-dust");
results.emplace(child_txid, MempoolAcceptResult::Failure(child_state));
return PackageMempoolAcceptResult(package_state, std::move(results));
}
}
for (Workspace& ws : workspaces) {
ws.m_package_feerate = package_feerate;
if (!PolicyScriptChecks(args, ws)) {