[policy/validation] allow v3 transactions with certain restrictions

Co-authored-by: Suhas Daftuar <sdaftuar@gmail.com>
This commit is contained in:
glozow 2023-12-15 12:17:44 +00:00
parent eb8d5a2e7d
commit 9a1fea55b2
2 changed files with 25 additions and 6 deletions

View File

@ -790,7 +790,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
t.nVersion = 0;
CheckIsNotStandard(t, "version");
t.nVersion = 3;
t.nVersion = TX_MAX_STANDARD_VERSION + 1;
CheckIsNotStandard(t, "version");
// Allowed nVersion

View File

@ -29,6 +29,7 @@
#include <logging/timer.h>
#include <node/blockstorage.h>
#include <node/utxo_snapshot.h>
#include <policy/v3_policy.h>
#include <policy/policy.h>
#include <policy/rbf.h>
#include <policy/settings.h>
@ -332,7 +333,9 @@ void Chainstate::MaybeUpdateMempoolForReorg(
// Also updates valid entries' cached LockPoints if needed.
// If false, the tx is still valid and its lockpoints are updated.
// If true, the tx would be invalid in the next block; remove this entry and all of its descendants.
const auto filter_final_and_mature = [this](CTxMemPool::txiter it)
// Note that v3 rules are not applied here, so reorgs may cause violations of v3 inheritance or
// topology restrictions.
const auto filter_final_and_mature = [&](CTxMemPool::txiter it)
EXCLUSIVE_LOCKS_REQUIRED(m_mempool->cs, ::cs_main) {
AssertLockHeld(m_mempool->cs);
AssertLockHeld(::cs_main);
@ -760,9 +763,12 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// check all unconfirmed ancestors; otherwise an opt-in ancestor
// might be replaced, causing removal of this descendant.
//
// If replaceability signaling is ignored due to node setting,
// replacement is always allowed.
if (!m_pool.m_full_rbf && !SignalsOptInRBF(*ptxConflicting)) {
// All V3 transactions are considered replaceable.
//
// Replaceability signaling of the original transactions may be
// ignored due to node setting.
const bool allow_rbf{m_pool.m_full_rbf || SignalsOptInRBF(*ptxConflicting) || ptxConflicting->nVersion == 3};
if (!allow_rbf) {
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "txn-mempool-conflict");
}
@ -864,7 +870,8 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// while a tx could be package CPFP'd when entering the mempool, we do not have a DoS-resistant
// method of ensuring the tx remains bumped. For example, the fee-bumping child could disappear
// due to a replacement.
if (!bypass_limits && ws.m_modified_fees < m_pool.m_min_relay_feerate.GetFee(ws.m_vsize)) {
// The only exception is v3 transactions.
if (!bypass_limits && ws.m_ptx->nVersion != 3 && ws.m_modified_fees < m_pool.m_min_relay_feerate.GetFee(ws.m_vsize)) {
// Even though this is a fee-related failure, this result is TX_MEMPOOL_POLICY, not
// TX_RECONSIDERABLE, because it cannot be bypassed using package validation.
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "min relay fee not met",
@ -946,6 +953,9 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
}
ws.m_ancestors = *ancestors;
if (const auto err_string{SingleV3Checks(ws.m_ptx, ws.m_ancestors, ws.m_conflicts, ws.m_vsize)}) {
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "v3-rule-violation", *err_string);
}
// A transaction that spends outputs that would be replaced by it is invalid. Now
// that we have the set of all ancestors we can detect this
@ -1306,6 +1316,15 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
m_viewmempool.PackageAddTransaction(ws.m_ptx);
}
// At this point we have all in-mempool ancestors, and we know every transaction's vsize.
// Run the v3 checks on the package.
for (Workspace& ws : workspaces) {
if (auto err{PackageV3Checks(ws.m_ptx, ws.m_vsize, txns, ws.m_ancestors)}) {
package_state.Invalid(PackageValidationResult::PCKG_POLICY, "v3-violation", err.value());
return PackageMempoolAcceptResult(package_state, {});
}
}
// Transactions must meet two minimum feerates: the mempool minimum fee and min relay fee.
// For transactions consisting of exactly one child and its parents, it suffices to use the
// package feerate (total modified fees / total virtual size) to check this requirement.