Skip to content

Commit 9a1fea5

Browse files
glozowsdaftuar
andcommitted
[policy/validation] allow v3 transactions with certain restrictions
Co-authored-by: Suhas Daftuar <[email protected]>
1 parent eb8d5a2 commit 9a1fea5

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

src/test/transaction_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
790790
t.nVersion = 0;
791791
CheckIsNotStandard(t, "version");
792792

793-
t.nVersion = 3;
793+
t.nVersion = TX_MAX_STANDARD_VERSION + 1;
794794
CheckIsNotStandard(t, "version");
795795

796796
// Allowed nVersion

src/validation.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <logging/timer.h>
3030
#include <node/blockstorage.h>
3131
#include <node/utxo_snapshot.h>
32+
#include <policy/v3_policy.h>
3233
#include <policy/policy.h>
3334
#include <policy/rbf.h>
3435
#include <policy/settings.h>
@@ -332,7 +333,9 @@ void Chainstate::MaybeUpdateMempoolForReorg(
332333
// Also updates valid entries' cached LockPoints if needed.
333334
// If false, the tx is still valid and its lockpoints are updated.
334335
// If true, the tx would be invalid in the next block; remove this entry and all of its descendants.
335-
const auto filter_final_and_mature = [this](CTxMemPool::txiter it)
336+
// Note that v3 rules are not applied here, so reorgs may cause violations of v3 inheritance or
337+
// topology restrictions.
338+
const auto filter_final_and_mature = [&](CTxMemPool::txiter it)
336339
EXCLUSIVE_LOCKS_REQUIRED(m_mempool->cs, ::cs_main) {
337340
AssertLockHeld(m_mempool->cs);
338341
AssertLockHeld(::cs_main);
@@ -760,9 +763,12 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
760763
// check all unconfirmed ancestors; otherwise an opt-in ancestor
761764
// might be replaced, causing removal of this descendant.
762765
//
763-
// If replaceability signaling is ignored due to node setting,
764-
// replacement is always allowed.
765-
if (!m_pool.m_full_rbf && !SignalsOptInRBF(*ptxConflicting)) {
766+
// All V3 transactions are considered replaceable.
767+
//
768+
// Replaceability signaling of the original transactions may be
769+
// ignored due to node setting.
770+
const bool allow_rbf{m_pool.m_full_rbf || SignalsOptInRBF(*ptxConflicting) || ptxConflicting->nVersion == 3};
771+
if (!allow_rbf) {
766772
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "txn-mempool-conflict");
767773
}
768774

@@ -864,7 +870,8 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
864870
// while a tx could be package CPFP'd when entering the mempool, we do not have a DoS-resistant
865871
// method of ensuring the tx remains bumped. For example, the fee-bumping child could disappear
866872
// due to a replacement.
867-
if (!bypass_limits && ws.m_modified_fees < m_pool.m_min_relay_feerate.GetFee(ws.m_vsize)) {
873+
// The only exception is v3 transactions.
874+
if (!bypass_limits && ws.m_ptx->nVersion != 3 && ws.m_modified_fees < m_pool.m_min_relay_feerate.GetFee(ws.m_vsize)) {
868875
// Even though this is a fee-related failure, this result is TX_MEMPOOL_POLICY, not
869876
// TX_RECONSIDERABLE, because it cannot be bypassed using package validation.
870877
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "min relay fee not met",
@@ -946,6 +953,9 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
946953
}
947954

948955
ws.m_ancestors = *ancestors;
956+
if (const auto err_string{SingleV3Checks(ws.m_ptx, ws.m_ancestors, ws.m_conflicts, ws.m_vsize)}) {
957+
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "v3-rule-violation", *err_string);
958+
}
949959

950960
// A transaction that spends outputs that would be replaced by it is invalid. Now
951961
// that we have the set of all ancestors we can detect this
@@ -1306,6 +1316,15 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
13061316
m_viewmempool.PackageAddTransaction(ws.m_ptx);
13071317
}
13081318

1319+
// At this point we have all in-mempool ancestors, and we know every transaction's vsize.
1320+
// Run the v3 checks on the package.
1321+
for (Workspace& ws : workspaces) {
1322+
if (auto err{PackageV3Checks(ws.m_ptx, ws.m_vsize, txns, ws.m_ancestors)}) {
1323+
package_state.Invalid(PackageValidationResult::PCKG_POLICY, "v3-violation", err.value());
1324+
return PackageMempoolAcceptResult(package_state, {});
1325+
}
1326+
}
1327+
13091328
// Transactions must meet two minimum feerates: the mempool minimum fee and min relay fee.
13101329
// For transactions consisting of exactly one child and its parents, it suffices to use the
13111330
// package feerate (total modified fees / total virtual size) to check this requirement.

0 commit comments

Comments
 (0)