aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAva Chow <github@achow101.com>2024-07-02 17:49:32 -0400
committerAva Chow <github@achow101.com>2024-07-02 17:49:32 -0400
commit3325a0afa45ee88c9e859f1002183f1bd61868da (patch)
tree9fd7c07e064f118ce45b476fb399629d23f83757
parent9251bc71110412ff248ee99fbb215d84b60c8c7c (diff)
parent926b8e39dcbc0a3a8a75ef0a29bdca2bf738d746 (diff)
downloadbitcoin-3325a0afa45ee88c9e859f1002183f1bd61868da.tar.xz
Merge bitcoin/bitcoin#30272: doc: use TRUC instead of v3 and add release note
926b8e39dcbc0a3a8a75ef0a29bdca2bf738d746 [doc] add release note for TRUC (glozow) 19a9b90617419f68d0f1c90ee115b5220be99a16 use version=3 instead of v3 in debug strings (glozow) 881fac8e609be17eb71bd9a54c0284b304e2e2e2 scripted-diff: change names from V3 to TRUC (glozow) a573dd261748d2a80560f73db08f7dca788c7fcf [doc] replace mentions of v3 with TRUC (glozow) 089b5757dff39a9a06cdb625aaced9beeb72958d rename mempool_accept_v3.py to mempool_truc.py (glozow) f543852a89d93441645250c40c3980aeb0c3b664 rename policy/v3_policy.* to policy/truc_policy.* (glozow) Pull request description: Adds a release note for TRUC policy which will be live in v28.0. For clarity, replaces mentions of "v3" with "TRUC" in most places. Suggested in - https://github.com/bitcoin/bitcoin/pull/29496#discussion_r1629749583 - https://github.com/bitcoin/bitcoin/pull/29496#discussion_r1624500904 I changed error strings from "v3-violation" to "TRUC-violation" but left v3 in the debug strings because I think it might be clearer for somebody who is debugging. Similarly, I left some variables unchanged because I think they're more descriptive this way, e.g. `tx_v3_from_v2_and_v3`. I'm happy to debate places that should or shouldn't be documented differently in this PR, whatever is clearest to everyone. ACKs for top commit: instagibbs: reACK https://github.com/bitcoin/bitcoin/pull/30272/commits/926b8e39dcbc0a3a8a75ef0a29bdca2bf738d746 achow101: ACK 926b8e39dcbc0a3a8a75ef0a29bdca2bf738d746 ismaelsadeeq: Code review ACK 926b8e39dcbc0a3a8a75ef0a29bdca2bf738d746 Tree-SHA512: 16c88add0a29dc6d1236c4d45f34a17b850f6727b231953cbd52eb9f7268d1d802563eadfc8b7928c94ed3d7a615275dd103e57e81439ebf3ba2b12efa1e42af
-rw-r--r--doc/release-notes-29496.md11
-rw-r--r--src/Makefile.am8
-rw-r--r--src/policy/truc_policy.cpp (renamed from src/policy/v3_policy.cpp)84
-rw-r--r--src/policy/truc_policy.h94
-rw-r--r--src/policy/v3_policy.h93
-rw-r--r--src/test/fuzz/package_eval.cpp6
-rw-r--r--src/test/fuzz/tx_pool.cpp6
-rw-r--r--src/test/txvalidation_tests.cpp100
-rw-r--r--src/test/util/txmempool.cpp22
-rw-r--r--src/test/util/txmempool.h14
-rw-r--r--src/validation.cpp30
-rwxr-xr-xtest/functional/mempool_truc.py (renamed from test/functional/mempool_accept_v3.py)138
-rwxr-xr-xtest/functional/test_runner.py2
-rwxr-xr-xtest/functional/wallet_create_tx.py8
14 files changed, 314 insertions, 302 deletions
diff --git a/doc/release-notes-29496.md b/doc/release-notes-29496.md
new file mode 100644
index 0000000000..799b2ca01d
--- /dev/null
+++ b/doc/release-notes-29496.md
@@ -0,0 +1,11 @@
+Mempool Policy Changes
+----------------------
+
+- Transactions with version number set to 3 are now treated as standard on all networks (#29496),
+ subject to Opt-in Topologically Restricted Until Confirmation (TRUC) Transactions policy as
+ described in [BIP 431](https://github.com/bitcoin/bips/blob/master/bip-0431.mediawiki). The
+ policy includes limits on spending unconfirmed outputs (#28948), eviction of a previous descendant
+ if a more incentive-compatible one is submitted (#29306), and a maximum transaction size of 10,000vB
+ (#29873). These restrictions simplify the assessment of incentive compatibility of accepting or
+ replacing TRUC transactions, thus ensuring any replacements are more profitable for the node and
+ making fee-bumping more reliable.
diff --git a/src/Makefile.am b/src/Makefile.am
index 52d4aae893..183d196a7b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -244,7 +244,6 @@ BITCOIN_CORE_H = \
node/warnings.h \
noui.h \
outputtype.h \
- policy/v3_policy.h \
policy/feerate.h \
policy/fees.h \
policy/fees_args.h \
@@ -252,6 +251,7 @@ BITCOIN_CORE_H = \
policy/policy.h \
policy/rbf.h \
policy/settings.h \
+ policy/truc_policy.h \
pow.h \
protocol.h \
psbt.h \
@@ -448,12 +448,12 @@ libbitcoin_node_a_SOURCES = \
node/validation_cache_args.cpp \
node/warnings.cpp \
noui.cpp \
- policy/v3_policy.cpp \
policy/fees.cpp \
policy/fees_args.cpp \
policy/packages.cpp \
policy/rbf.cpp \
policy/settings.cpp \
+ policy/truc_policy.cpp \
pow.cpp \
rest.cpp \
rpc/blockchain.cpp \
@@ -708,9 +708,9 @@ libbitcoin_common_a_SOURCES = \
netbase.cpp \
net_permissions.cpp \
outputtype.cpp \
- policy/v3_policy.cpp \
policy/feerate.cpp \
policy/policy.cpp \
+ policy/truc_policy.cpp \
protocol.cpp \
psbt.cpp \
rpc/external_signer.cpp \
@@ -955,12 +955,12 @@ libbitcoinkernel_la_SOURCES = \
node/blockstorage.cpp \
node/chainstate.cpp \
node/utxo_snapshot.cpp \
- policy/v3_policy.cpp \
policy/feerate.cpp \
policy/packages.cpp \
policy/policy.cpp \
policy/rbf.cpp \
policy/settings.cpp \
+ policy/truc_policy.cpp \
pow.cpp \
primitives/block.cpp \
primitives/transaction.cpp \
diff --git a/src/policy/v3_policy.cpp b/src/policy/truc_policy.cpp
index 6bd043b8e3..69e8d5ed1d 100644
--- a/src/policy/v3_policy.cpp
+++ b/src/policy/truc_policy.cpp
@@ -2,7 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <policy/v3_policy.h>
+#include <policy/truc_policy.h>
#include <coins.h>
#include <consensus/amount.h>
@@ -14,7 +14,7 @@
#include <numeric>
#include <vector>
-/** Helper for PackageV3Checks: Returns a vector containing the indices of transactions (within
+/** Helper for PackageTRUCChecks: Returns a vector containing the indices of transactions (within
* package) that are direct parents of ptx. */
std::vector<size_t> FindInPackageParents(const Package& package, const CTransactionRef& ptx)
{
@@ -37,13 +37,13 @@ std::vector<size_t> FindInPackageParents(const Package& package, const CTransact
return in_package_parents;
}
-/** Helper for PackageV3Checks, storing info for a mempool or package parent. */
+/** Helper for PackageTRUCChecks, storing info for a mempool or package parent. */
struct ParentInfo {
/** Txid used to identify this parent by prevout */
const Txid& m_txid;
/** Wtxid used for debug string */
const Wtxid& m_wtxid;
- /** version used to check inheritance of v3 and non-v3 */
+ /** version used to check inheritance of TRUC and non-TRUC */
decltype(CTransaction::version) m_version;
/** If parent is in mempool, whether it has any descendants in mempool. */
bool m_has_mempool_descendant;
@@ -55,36 +55,36 @@ struct ParentInfo {
{}
};
-std::optional<std::string> PackageV3Checks(const CTransactionRef& ptx, int64_t vsize,
+std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t vsize,
const Package& package,
const CTxMemPool::setEntries& mempool_ancestors)
{
// This function is specialized for these limits, and must be reimplemented if they ever change.
- static_assert(V3_ANCESTOR_LIMIT == 2);
- static_assert(V3_DESCENDANT_LIMIT == 2);
+ static_assert(TRUC_ANCESTOR_LIMIT == 2);
+ static_assert(TRUC_DESCENDANT_LIMIT == 2);
const auto in_package_parents{FindInPackageParents(package, ptx)};
- // Now we have all ancestors, so we can start checking v3 rules.
+ // Now we have all ancestors, so we can start checking TRUC rules.
if (ptx->version == TRUC_VERSION) {
- // SingleV3Checks should have checked this already.
- if (!Assume(vsize <= V3_MAX_VSIZE)) {
- return strprintf("v3 tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
- ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), vsize, V3_MAX_VSIZE);
+ // SingleTRUCChecks should have checked this already.
+ if (!Assume(vsize <= TRUC_MAX_VSIZE)) {
+ return strprintf("version=3 tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
+ ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), vsize, TRUC_MAX_VSIZE);
}
- if (mempool_ancestors.size() + in_package_parents.size() + 1 > V3_ANCESTOR_LIMIT) {
+ if (mempool_ancestors.size() + in_package_parents.size() + 1 > TRUC_ANCESTOR_LIMIT) {
return strprintf("tx %s (wtxid=%s) would have too many ancestors",
ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString());
}
const bool has_parent{mempool_ancestors.size() + in_package_parents.size() > 0};
if (has_parent) {
- // A v3 child cannot be too large.
- if (vsize > V3_CHILD_MAX_VSIZE) {
- return strprintf("v3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
+ // A TRUC child cannot be too large.
+ if (vsize > TRUC_CHILD_MAX_VSIZE) {
+ return strprintf("version=3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(),
- vsize, V3_CHILD_MAX_VSIZE);
+ vsize, TRUC_CHILD_MAX_VSIZE);
}
// Exactly 1 parent exists, either in mempool or package. Find it.
@@ -107,7 +107,7 @@ std::optional<std::string> PackageV3Checks(const CTransactionRef& ptx, int64_t v
// If there is a parent, it must have the right version.
if (parent_info.m_version != TRUC_VERSION) {
- return strprintf("v3 tx %s (wtxid=%s) cannot spend from non-v3 tx %s (wtxid=%s)",
+ return strprintf("version=3 tx %s (wtxid=%s) cannot spend from non-version=3 tx %s (wtxid=%s)",
ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(),
parent_info.m_txid.ToString(), parent_info.m_wtxid.ToString());
}
@@ -118,7 +118,7 @@ std::optional<std::string> PackageV3Checks(const CTransactionRef& ptx, int64_t v
for (auto& input : package_tx->vin) {
// Fail if we find another tx with the same parent. We don't check whether the
- // sibling is to-be-replaced (done in SingleV3Checks) because these transactions
+ // sibling is to-be-replaced (done in SingleTRUCChecks) because these transactions
// are within the same package.
if (input.prevout.hash == parent_info.m_txid) {
return strprintf("tx %s (wtxid=%s) would exceed descendant count limit",
@@ -140,17 +140,17 @@ std::optional<std::string> PackageV3Checks(const CTransactionRef& ptx, int64_t v
}
}
} else {
- // Non-v3 transactions cannot have v3 parents.
+ // Non-TRUC transactions cannot have TRUC parents.
for (auto it : mempool_ancestors) {
if (it->GetTx().version == TRUC_VERSION) {
- return strprintf("non-v3 tx %s (wtxid=%s) cannot spend from v3 tx %s (wtxid=%s)",
+ return strprintf("non-version=3 tx %s (wtxid=%s) cannot spend from version=3 tx %s (wtxid=%s)",
ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(),
it->GetSharedTx()->GetHash().ToString(), it->GetSharedTx()->GetWitnessHash().ToString());
}
}
for (const auto& index: in_package_parents) {
if (package.at(index)->version == TRUC_VERSION) {
- return strprintf("non-v3 tx %s (wtxid=%s) cannot spend from v3 tx %s (wtxid=%s)",
+ return strprintf("non-version=3 tx %s (wtxid=%s) cannot spend from version=3 tx %s (wtxid=%s)",
ptx->GetHash().ToString(),
ptx->GetWitnessHash().ToString(),
package.at(index)->GetHash().ToString(),
@@ -161,20 +161,20 @@ std::optional<std::string> PackageV3Checks(const CTransactionRef& ptx, int64_t v
return std::nullopt;
}
-std::optional<std::pair<std::string, CTransactionRef>> SingleV3Checks(const CTransactionRef& ptx,
+std::optional<std::pair<std::string, CTransactionRef>> SingleTRUCChecks(const CTransactionRef& ptx,
const CTxMemPool::setEntries& mempool_ancestors,
const std::set<Txid>& direct_conflicts,
int64_t vsize)
{
- // Check v3 and non-v3 inheritance.
+ // Check TRUC and non-TRUC inheritance.
for (const auto& entry : mempool_ancestors) {
if (ptx->version != TRUC_VERSION && entry->GetTx().version == TRUC_VERSION) {
- return std::make_pair(strprintf("non-v3 tx %s (wtxid=%s) cannot spend from v3 tx %s (wtxid=%s)",
+ return std::make_pair(strprintf("non-version=3 tx %s (wtxid=%s) cannot spend from version=3 tx %s (wtxid=%s)",
ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(),
entry->GetSharedTx()->GetHash().ToString(), entry->GetSharedTx()->GetWitnessHash().ToString()),
nullptr);
} else if (ptx->version == TRUC_VERSION && entry->GetTx().version != TRUC_VERSION) {
- return std::make_pair(strprintf("v3 tx %s (wtxid=%s) cannot spend from non-v3 tx %s (wtxid=%s)",
+ return std::make_pair(strprintf("version=3 tx %s (wtxid=%s) cannot spend from non-version=3 tx %s (wtxid=%s)",
ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(),
entry->GetSharedTx()->GetHash().ToString(), entry->GetSharedTx()->GetWitnessHash().ToString()),
nullptr);
@@ -182,20 +182,20 @@ std::optional<std::pair<std::string, CTransactionRef>> SingleV3Checks(const CTra
}
// This function is specialized for these limits, and must be reimplemented if they ever change.
- static_assert(V3_ANCESTOR_LIMIT == 2);
- static_assert(V3_DESCENDANT_LIMIT == 2);
+ static_assert(TRUC_ANCESTOR_LIMIT == 2);
+ static_assert(TRUC_DESCENDANT_LIMIT == 2);
// The rest of the rules only apply to transactions with version=3.
if (ptx->version != TRUC_VERSION) return std::nullopt;
- if (vsize > V3_MAX_VSIZE) {
- return std::make_pair(strprintf("v3 tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
- ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), vsize, V3_MAX_VSIZE),
+ if (vsize > TRUC_MAX_VSIZE) {
+ return std::make_pair(strprintf("version=3 tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
+ ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), vsize, TRUC_MAX_VSIZE),
nullptr);
}
- // Check that V3_ANCESTOR_LIMIT would not be violated.
- if (mempool_ancestors.size() + 1 > V3_ANCESTOR_LIMIT) {
+ // Check that TRUC_ANCESTOR_LIMIT would not be violated.
+ if (mempool_ancestors.size() + 1 > TRUC_ANCESTOR_LIMIT) {
return std::make_pair(strprintf("tx %s (wtxid=%s) would have too many ancestors",
ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString()),
nullptr);
@@ -203,10 +203,10 @@ std::optional<std::pair<std::string, CTransactionRef>> SingleV3Checks(const CTra
// Remaining checks only pertain to transactions with unconfirmed ancestors.
if (mempool_ancestors.size() > 0) {
- // If this transaction spends V3 parents, it cannot be too large.
- if (vsize > V3_CHILD_MAX_VSIZE) {
- return std::make_pair(strprintf("v3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
- ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), vsize, V3_CHILD_MAX_VSIZE),
+ // If this transaction spends TRUC parents, it cannot be too large.
+ if (vsize > TRUC_CHILD_MAX_VSIZE) {
+ return std::make_pair(strprintf("version=3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
+ ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), vsize, TRUC_CHILD_MAX_VSIZE),
nullptr);
}
@@ -217,14 +217,14 @@ std::optional<std::pair<std::string, CTransactionRef>> SingleV3Checks(const CTra
// possible through a reorg.
const auto& children = parent_entry->GetMemPoolChildrenConst();
// Don't double-count a transaction that is going to be replaced. This logic assumes that
- // any descendant of the V3 transaction is a direct child, which makes sense because a V3
- // transaction can only have 1 descendant.
+ // any descendant of the TRUC transaction is a direct child, which makes sense because a
+ // TRUC transaction can only have 1 descendant.
const bool child_will_be_replaced = !children.empty() &&
std::any_of(children.cbegin(), children.cend(),
[&direct_conflicts](const CTxMemPoolEntry& child){return direct_conflicts.count(child.GetTx().GetHash()) > 0;});
- if (parent_entry->GetCountWithDescendants() + 1 > V3_DESCENDANT_LIMIT && !child_will_be_replaced) {
- // Allow sibling eviction for v3 transaction: if another child already exists, even if
- // we don't conflict inputs with it, consider evicting it under RBF rules. We rely on v3 rules
+ if (parent_entry->GetCountWithDescendants() + 1 > TRUC_DESCENDANT_LIMIT && !child_will_be_replaced) {
+ // Allow sibling eviction for TRUC transaction: if another child already exists, even if
+ // we don't conflict inputs with it, consider evicting it under RBF rules. We rely on TRUC rules
// only permitting 1 descendant, as otherwise we would need to have logic for deciding
// which descendant to evict. Skip if this isn't true, e.g. if the transaction has
// multiple children or the sibling also has descendants due to a reorg.
diff --git a/src/policy/truc_policy.h b/src/policy/truc_policy.h
new file mode 100644
index 0000000000..dbc77696c6
--- /dev/null
+++ b/src/policy/truc_policy.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2022 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_POLICY_TRUC_POLICY_H
+#define BITCOIN_POLICY_TRUC_POLICY_H
+
+#include <consensus/amount.h>
+#include <policy/packages.h>
+#include <policy/policy.h>
+#include <primitives/transaction.h>
+#include <txmempool.h>
+#include <util/result.h>
+
+#include <set>
+#include <string>
+
+// This module enforces rules for BIP 431 TRUC transactions which help make
+// RBF abilities more robust. A transaction with version=3 is treated as TRUC.
+static constexpr decltype(CTransaction::version) TRUC_VERSION{3};
+
+// TRUC only allows 1 parent and 1 child when unconfirmed. This translates to a descendant set size
+// of 2 and ancestor set size of 2.
+/** Maximum number of transactions including an unconfirmed tx and its descendants. */
+static constexpr unsigned int TRUC_DESCENDANT_LIMIT{2};
+/** Maximum number of transactions including a TRUC tx and all its mempool ancestors. */
+static constexpr unsigned int TRUC_ANCESTOR_LIMIT{2};
+
+/** Maximum sigop-adjusted virtual size of all v3 transactions. */
+static constexpr int64_t TRUC_MAX_VSIZE{10000};
+/** Maximum sigop-adjusted virtual size of a tx which spends from an unconfirmed TRUC transaction. */
+static constexpr int64_t TRUC_CHILD_MAX_VSIZE{1000};
+// These limits are within the default ancestor/descendant limits.
+static_assert(TRUC_MAX_VSIZE + TRUC_CHILD_MAX_VSIZE <= DEFAULT_ANCESTOR_SIZE_LIMIT_KVB * 1000);
+static_assert(TRUC_MAX_VSIZE + TRUC_CHILD_MAX_VSIZE <= DEFAULT_DESCENDANT_SIZE_LIMIT_KVB * 1000);
+
+/** Must be called for every transaction, even if not TRUC. Not strictly necessary for transactions
+ * accepted through AcceptMultipleTransactions.
+ *
+ * Checks the following rules:
+ * 1. A TRUC tx must only have TRUC unconfirmed ancestors.
+ * 2. A non-TRUC tx must only have non-TRUC unconfirmed ancestors.
+ * 3. A TRUC's ancestor set, including itself, must be within TRUC_ANCESTOR_LIMIT.
+ * 4. A TRUC's descendant set, including itself, must be within TRUC_DESCENDANT_LIMIT.
+ * 5. If a TRUC tx has any unconfirmed ancestors, the tx's sigop-adjusted vsize must be within
+ * TRUC_CHILD_MAX_VSIZE.
+ * 6. A TRUC tx must be within TRUC_MAX_VSIZE.
+ *
+ *
+ * @param[in] mempool_ancestors The in-mempool ancestors of ptx.
+ * @param[in] direct_conflicts In-mempool transactions this tx conflicts with. These conflicts
+ * are used to more accurately calculate the resulting descendant
+ * count of in-mempool ancestors.
+ * @param[in] vsize The sigop-adjusted virtual size of ptx.
+ *
+ * @returns 3 possibilities:
+ * - std::nullopt if all TRUC checks were applied successfully
+ * - debug string + pointer to a mempool sibling if this transaction would be the second child in a
+ * 1-parent-1-child cluster; the caller may consider evicting the specified sibling or return an
+ * error with the debug string.
+ * - debug string + nullptr if this transaction violates some TRUC rule and sibling eviction is not
+ * applicable.
+ */
+std::optional<std::pair<std::string, CTransactionRef>> SingleTRUCChecks(const CTransactionRef& ptx,
+ const CTxMemPool::setEntries& mempool_ancestors,
+ const std::set<Txid>& direct_conflicts,
+ int64_t vsize);
+
+/** Must be called for every transaction that is submitted within a package, even if not TRUC.
+ *
+ * For each transaction in a package:
+ * If it's not a TRUC transaction, verify it has no direct TRUC parents in the mempool or the package.
+
+ * If it is a TRUC transaction, verify that any direct parents in the mempool or the package are TRUC.
+ * If such a parent exists, verify that parent has no other children in the package or the mempool,
+ * and that the transaction itself has no children in the package.
+ *
+ * If any TRUC violations in the package exist, this test will fail for one of them:
+ * - if a TRUC transaction T has a parent in the mempool and a child in the package, then PTRUCC(T) will fail
+ * - if a TRUC transaction T has a parent in the package and a child in the package, then PTRUCC(T) will fail
+ * - if a TRUC transaction T and a TRUC (sibling) transaction U have some parent in the mempool,
+ * then PTRUCC(T) and PTRUCC(U) will fail
+ * - if a TRUC transaction T and a TRUC (sibling) transaction U have some parent in the package,
+ * then PTRUCC(T) and PTRUCC(U) will fail
+ * - if a TRUC transaction T has a parent P and a grandparent G in the package, then
+ * PTRUCC(P) will fail (though PTRUCC(G) and PTRUCC(T) might succeed).
+ *
+ * @returns debug string if an error occurs, std::nullopt otherwise.
+ * */
+std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t vsize,
+ const Package& package,
+ const CTxMemPool::setEntries& mempool_ancestors);
+
+#endif // BITCOIN_POLICY_TRUC_POLICY_H
diff --git a/src/policy/v3_policy.h b/src/policy/v3_policy.h
deleted file mode 100644
index 90eaeda46f..0000000000
--- a/src/policy/v3_policy.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2022 The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef BITCOIN_POLICY_V3_POLICY_H
-#define BITCOIN_POLICY_V3_POLICY_H
-
-#include <consensus/amount.h>
-#include <policy/packages.h>
-#include <policy/policy.h>
-#include <primitives/transaction.h>
-#include <txmempool.h>
-#include <util/result.h>
-
-#include <set>
-#include <string>
-
-// This module enforces rules for BIP 431 TRUC transactions (with version=3) which help make
-// RBF abilities more robust.
-static constexpr decltype(CTransaction::version) TRUC_VERSION{3};
-
-// v3 only allows 1 parent and 1 child when unconfirmed.
-/** Maximum number of transactions including an unconfirmed tx and its descendants. */
-static constexpr unsigned int V3_DESCENDANT_LIMIT{2};
-/** Maximum number of transactions including a V3 tx and all its mempool ancestors. */
-static constexpr unsigned int V3_ANCESTOR_LIMIT{2};
-
-/** Maximum sigop-adjusted virtual size of all v3 transactions. */
-static constexpr int64_t V3_MAX_VSIZE{10000};
-/** Maximum sigop-adjusted virtual size of a tx which spends from an unconfirmed v3 transaction. */
-static constexpr int64_t V3_CHILD_MAX_VSIZE{1000};
-// These limits are within the default ancestor/descendant limits.
-static_assert(V3_MAX_VSIZE + V3_CHILD_MAX_VSIZE <= DEFAULT_ANCESTOR_SIZE_LIMIT_KVB * 1000);
-static_assert(V3_MAX_VSIZE + V3_CHILD_MAX_VSIZE <= DEFAULT_DESCENDANT_SIZE_LIMIT_KVB * 1000);
-
-/** Must be called for every transaction, even if not v3. Not strictly necessary for transactions
- * accepted through AcceptMultipleTransactions.
- *
- * Checks the following rules:
- * 1. A v3 tx must only have v3 unconfirmed ancestors.
- * 2. A non-v3 tx must only have non-v3 unconfirmed ancestors.
- * 3. A v3's ancestor set, including itself, must be within V3_ANCESTOR_LIMIT.
- * 4. A v3's descendant set, including itself, must be within V3_DESCENDANT_LIMIT.
- * 5. If a v3 tx has any unconfirmed ancestors, the tx's sigop-adjusted vsize must be within
- * V3_CHILD_MAX_VSIZE.
- * 6. A v3 tx must be within V3_MAX_VSIZE.
- *
- *
- * @param[in] mempool_ancestors The in-mempool ancestors of ptx.
- * @param[in] direct_conflicts In-mempool transactions this tx conflicts with. These conflicts
- * are used to more accurately calculate the resulting descendant
- * count of in-mempool ancestors.
- * @param[in] vsize The sigop-adjusted virtual size of ptx.
- *
- * @returns 3 possibilities:
- * - std::nullopt if all v3 checks were applied successfully
- * - debug string + pointer to a mempool sibling if this transaction would be the second child in a
- * 1-parent-1-child cluster; the caller may consider evicting the specified sibling or return an
- * error with the debug string.
- * - debug string + nullptr if this transaction violates some v3 rule and sibling eviction is not
- * applicable.
- */
-std::optional<std::pair<std::string, CTransactionRef>> SingleV3Checks(const CTransactionRef& ptx,
- const CTxMemPool::setEntries& mempool_ancestors,
- const std::set<Txid>& direct_conflicts,
- int64_t vsize);
-
-/** Must be called for every transaction that is submitted within a package, even if not v3.
- *
- * For each transaction in a package:
- * If it's not a v3 transaction, verify it has no direct v3 parents in the mempool or the package.
-
- * If it is a v3 transaction, verify that any direct parents in the mempool or the package are v3.
- * If such a parent exists, verify that parent has no other children in the package or the mempool,
- * and that the transaction itself has no children in the package.
- *
- * If any v3 violations in the package exist, this test will fail for one of them:
- * - if a v3 transaction T has a parent in the mempool and a child in the package, then PV3C(T) will fail
- * - if a v3 transaction T has a parent in the package and a child in the package, then PV3C(T) will fail
- * - if a v3 transaction T and a v3 (sibling) transaction U have some parent in the mempool,
- * then PV3C(T) and PV3C(U) will fail
- * - if a v3 transaction T and a v3 (sibling) transaction U have some parent in the package,
- * then PV3C(T) and PV3C(U) will fail
- * - if a v3 transaction T has a parent P and a grandparent G in the package, then
- * PV3C(P) will fail (though PV3C(G) and PV3C(T) might succeed).
- *
- * @returns debug string if an error occurs, std::nullopt otherwise.
- * */
-std::optional<std::string> PackageV3Checks(const CTransactionRef& ptx, int64_t vsize,
- const Package& package,
- const CTxMemPool::setEntries& mempool_ancestors);
-
-#endif // BITCOIN_POLICY_V3_POLICY_H
diff --git a/src/test/fuzz/package_eval.cpp b/src/test/fuzz/package_eval.cpp
index 53aedf23ea..652c7a7609 100644
--- a/src/test/fuzz/package_eval.cpp
+++ b/src/test/fuzz/package_eval.cpp
@@ -6,7 +6,7 @@
#include <node/context.h>
#include <node/mempool_args.h>
#include <node/miner.h>
-#include <policy/v3_policy.h>
+#include <policy/truc_policy.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
@@ -225,7 +225,7 @@ FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool)
tx_mut.vin.emplace_back();
}
- // Make a p2pk output to make sigops adjusted vsize to violate v3, potentially, which is never spent
+ // Make a p2pk output to make sigops adjusted vsize to violate TRUC rules, potentially, which is never spent
if (last_tx && amount_in > 1000 && fuzzed_data_provider.ConsumeBool()) {
tx_mut.vout.emplace_back(1000, CScript() << std::vector<unsigned char>(33, 0x02) << OP_CHECKSIG);
// Don't add any other outputs.
@@ -320,7 +320,7 @@ FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool)
Assert(result_package.m_tx_results.size() == txs.size() || result_package.m_tx_results.empty());
}
- CheckMempoolV3Invariants(tx_pool);
+ CheckMempoolTRUCInvariants(tx_pool);
}
node.validation_signals->UnregisterSharedValidationInterface(outpoints_updater);
diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp
index b6b91445f9..64861311db 100644
--- a/src/test/fuzz/tx_pool.cpp
+++ b/src/test/fuzz/tx_pool.cpp
@@ -6,7 +6,7 @@
#include <node/context.h>
#include <node/mempool_args.h>
#include <node/miner.h>
-#include <policy/v3_policy.h>
+#include <policy/truc_policy.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
@@ -320,7 +320,7 @@ FUZZ_TARGET(tx_pool_standard, .init = initialize_tx_pool)
if (accepted) {
Assert(added.size() == 1); // For now, no package acceptance
Assert(tx == *added.begin());
- CheckMempoolV3Invariants(tx_pool);
+ CheckMempoolTRUCInvariants(tx_pool);
} else {
// Do not consider rejected transaction removed
removed.erase(tx);
@@ -413,7 +413,7 @@ FUZZ_TARGET(tx_pool, .init = initialize_tx_pool)
const bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID;
if (accepted) {
txids.push_back(tx->GetHash());
- CheckMempoolV3Invariants(tx_pool);
+ CheckMempoolTRUCInvariants(tx_pool);
}
}
Finish(fuzzed_data_provider, tx_pool, chainstate);
diff --git a/src/test/txvalidation_tests.cpp b/src/test/txvalidation_tests.cpp
index f429f94a2f..97b27ef370 100644
--- a/src/test/txvalidation_tests.cpp
+++ b/src/test/txvalidation_tests.cpp
@@ -4,9 +4,9 @@
#include <consensus/validation.h>
#include <key_io.h>
-#include <policy/v3_policy.h>
#include <policy/packages.h>
#include <policy/policy.h>
+#include <policy/truc_policy.h>
#include <primitives/transaction.h>
#include <random.h>
#include <script/script.h>
@@ -91,7 +91,7 @@ static inline CTransactionRef make_tx(const std::vector<COutPoint>& inputs, int3
BOOST_FIXTURE_TEST_CASE(version3_tests, RegTestingSetup)
{
- // Test V3 policy helper functions
+ // Test TRUC policy helper functions
CTxMemPool& pool = *Assert(m_node.mempool);
LOCK2(cs_main, pool.cs);
TestMemPoolEntryHelper entry;
@@ -105,77 +105,77 @@ BOOST_FIXTURE_TEST_CASE(version3_tests, RegTestingSetup)
// Default values.
CTxMemPool::Limits m_limits{};
- // Cannot spend from an unconfirmed v3 transaction unless this tx is also v3.
+ // Cannot spend from an unconfirmed TRUC transaction unless this tx is also TRUC.
{
// mempool_tx_v3
// ^
// tx_v2_from_v3
auto tx_v2_from_v3 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}}, /*version=*/2);
auto ancestors_v2_from_v3{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v2_from_v3), m_limits)};
- const auto expected_error_str{strprintf("non-v3 tx %s (wtxid=%s) cannot spend from v3 tx %s (wtxid=%s)",
+ const auto expected_error_str{strprintf("non-version=3 tx %s (wtxid=%s) cannot spend from version=3 tx %s (wtxid=%s)",
tx_v2_from_v3->GetHash().ToString(), tx_v2_from_v3->GetWitnessHash().ToString(),
mempool_tx_v3->GetHash().ToString(), mempool_tx_v3->GetWitnessHash().ToString())};
- auto result_v2_from_v3{SingleV3Checks(tx_v2_from_v3, *ancestors_v2_from_v3, empty_conflicts_set, GetVirtualTransactionSize(*tx_v2_from_v3))};
+ auto result_v2_from_v3{SingleTRUCChecks(tx_v2_from_v3, *ancestors_v2_from_v3, empty_conflicts_set, GetVirtualTransactionSize(*tx_v2_from_v3))};
BOOST_CHECK_EQUAL(result_v2_from_v3->first, expected_error_str);
BOOST_CHECK_EQUAL(result_v2_from_v3->second, nullptr);
Package package_v3_v2{mempool_tx_v3, tx_v2_from_v3};
- BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v2_from_v3, GetVirtualTransactionSize(*tx_v2_from_v3), package_v3_v2, empty_ancestors), expected_error_str);
+ BOOST_CHECK_EQUAL(*PackageTRUCChecks(tx_v2_from_v3, GetVirtualTransactionSize(*tx_v2_from_v3), package_v3_v2, empty_ancestors), expected_error_str);
CTxMemPool::setEntries entries_mempool_v3{pool.GetIter(mempool_tx_v3->GetHash().ToUint256()).value()};
- BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v2_from_v3, GetVirtualTransactionSize(*tx_v2_from_v3), {tx_v2_from_v3}, entries_mempool_v3), expected_error_str);
+ BOOST_CHECK_EQUAL(*PackageTRUCChecks(tx_v2_from_v3, GetVirtualTransactionSize(*tx_v2_from_v3), {tx_v2_from_v3}, entries_mempool_v3), expected_error_str);
// mempool_tx_v3 mempool_tx_v2
// ^ ^
// tx_v2_from_v2_and_v3
auto tx_v2_from_v2_and_v3 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}, COutPoint{mempool_tx_v2->GetHash(), 0}}, /*version=*/2);
auto ancestors_v2_from_both{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v2_from_v2_and_v3), m_limits)};
- const auto expected_error_str_2{strprintf("non-v3 tx %s (wtxid=%s) cannot spend from v3 tx %s (wtxid=%s)",
+ const auto expected_error_str_2{strprintf("non-version=3 tx %s (wtxid=%s) cannot spend from version=3 tx %s (wtxid=%s)",
tx_v2_from_v2_and_v3->GetHash().ToString(), tx_v2_from_v2_and_v3->GetWitnessHash().ToString(),
mempool_tx_v3->GetHash().ToString(), mempool_tx_v3->GetWitnessHash().ToString())};
- auto result_v2_from_both{SingleV3Checks(tx_v2_from_v2_and_v3, *ancestors_v2_from_both, empty_conflicts_set, GetVirtualTransactionSize(*tx_v2_from_v2_and_v3))};
+ auto result_v2_from_both{SingleTRUCChecks(tx_v2_from_v2_and_v3, *ancestors_v2_from_both, empty_conflicts_set, GetVirtualTransactionSize(*tx_v2_from_v2_and_v3))};
BOOST_CHECK_EQUAL(result_v2_from_both->first, expected_error_str_2);
BOOST_CHECK_EQUAL(result_v2_from_both->second, nullptr);
Package package_v3_v2_v2{mempool_tx_v3, mempool_tx_v2, tx_v2_from_v2_and_v3};
- BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v2_from_v2_and_v3, GetVirtualTransactionSize(*tx_v2_from_v2_and_v3), package_v3_v2_v2, empty_ancestors), expected_error_str_2);
+ BOOST_CHECK_EQUAL(*PackageTRUCChecks(tx_v2_from_v2_and_v3, GetVirtualTransactionSize(*tx_v2_from_v2_and_v3), package_v3_v2_v2, empty_ancestors), expected_error_str_2);
}
- // V3 cannot spend from an unconfirmed non-v3 transaction.
+ // TRUC cannot spend from an unconfirmed non-TRUC transaction.
{
// mempool_tx_v2
// ^
// tx_v3_from_v2
auto tx_v3_from_v2 = make_tx({COutPoint{mempool_tx_v2->GetHash(), 0}}, /*version=*/3);
auto ancestors_v3_from_v2{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_from_v2), m_limits)};
- const auto expected_error_str{strprintf("v3 tx %s (wtxid=%s) cannot spend from non-v3 tx %s (wtxid=%s)",
+ const auto expected_error_str{strprintf("version=3 tx %s (wtxid=%s) cannot spend from non-version=3 tx %s (wtxid=%s)",
tx_v3_from_v2->GetHash().ToString(), tx_v3_from_v2->GetWitnessHash().ToString(),
mempool_tx_v2->GetHash().ToString(), mempool_tx_v2->GetWitnessHash().ToString())};
- auto result_v3_from_v2{SingleV3Checks(tx_v3_from_v2, *ancestors_v3_from_v2, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_from_v2))};
+ auto result_v3_from_v2{SingleTRUCChecks(tx_v3_from_v2, *ancestors_v3_from_v2, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_from_v2))};
BOOST_CHECK_EQUAL(result_v3_from_v2->first, expected_error_str);
BOOST_CHECK_EQUAL(result_v3_from_v2->second, nullptr);
Package package_v2_v3{mempool_tx_v2, tx_v3_from_v2};
- BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v3_from_v2, GetVirtualTransactionSize(*tx_v3_from_v2), package_v2_v3, empty_ancestors), expected_error_str);
+ BOOST_CHECK_EQUAL(*PackageTRUCChecks(tx_v3_from_v2, GetVirtualTransactionSize(*tx_v3_from_v2), package_v2_v3, empty_ancestors), expected_error_str);
CTxMemPool::setEntries entries_mempool_v2{pool.GetIter(mempool_tx_v2->GetHash().ToUint256()).value()};
- BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v3_from_v2, GetVirtualTransactionSize(*tx_v3_from_v2), {tx_v3_from_v2}, entries_mempool_v2), expected_error_str);
+ BOOST_CHECK_EQUAL(*PackageTRUCChecks(tx_v3_from_v2, GetVirtualTransactionSize(*tx_v3_from_v2), {tx_v3_from_v2}, entries_mempool_v2), expected_error_str);
// mempool_tx_v3 mempool_tx_v2
// ^ ^
// tx_v3_from_v2_and_v3
auto tx_v3_from_v2_and_v3 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}, COutPoint{mempool_tx_v2->GetHash(), 0}}, /*version=*/3);
auto ancestors_v3_from_both{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_from_v2_and_v3), m_limits)};
- const auto expected_error_str_2{strprintf("v3 tx %s (wtxid=%s) cannot spend from non-v3 tx %s (wtxid=%s)",
+ const auto expected_error_str_2{strprintf("version=3 tx %s (wtxid=%s) cannot spend from non-version=3 tx %s (wtxid=%s)",
tx_v3_from_v2_and_v3->GetHash().ToString(), tx_v3_from_v2_and_v3->GetWitnessHash().ToString(),
mempool_tx_v2->GetHash().ToString(), mempool_tx_v2->GetWitnessHash().ToString())};
- auto result_v3_from_both{SingleV3Checks(tx_v3_from_v2_and_v3, *ancestors_v3_from_both, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_from_v2_and_v3))};
+ auto result_v3_from_both{SingleTRUCChecks(tx_v3_from_v2_and_v3, *ancestors_v3_from_both, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_from_v2_and_v3))};
BOOST_CHECK_EQUAL(result_v3_from_both->first, expected_error_str_2);
BOOST_CHECK_EQUAL(result_v3_from_both->second, nullptr);
- // tx_v3_from_v2_and_v3 also violates V3_ANCESTOR_LIMIT.
+ // tx_v3_from_v2_and_v3 also violates TRUC_ANCESTOR_LIMIT.
const auto expected_error_str_3{strprintf("tx %s (wtxid=%s) would have too many ancestors",
tx_v3_from_v2_and_v3->GetHash().ToString(), tx_v3_from_v2_and_v3->GetWitnessHash().ToString())};
Package package_v3_v2_v3{mempool_tx_v3, mempool_tx_v2, tx_v3_from_v2_and_v3};
- BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v3_from_v2_and_v3, GetVirtualTransactionSize(*tx_v3_from_v2_and_v3), package_v3_v2_v3, empty_ancestors), expected_error_str_3);
+ BOOST_CHECK_EQUAL(*PackageTRUCChecks(tx_v3_from_v2_and_v3, GetVirtualTransactionSize(*tx_v3_from_v2_and_v3), package_v3_v2_v3, empty_ancestors), expected_error_str_3);
}
// V3 from V3 is ok, and non-V3 from non-V3 is ok.
{
@@ -184,25 +184,25 @@ BOOST_FIXTURE_TEST_CASE(version3_tests, RegTestingSetup)
// tx_v3_from_v3
auto tx_v3_from_v3 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}}, /*version=*/3);
auto ancestors_v3{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_from_v3), m_limits)};
- BOOST_CHECK(SingleV3Checks(tx_v3_from_v3, *ancestors_v3, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_from_v3))
+ BOOST_CHECK(SingleTRUCChecks(tx_v3_from_v3, *ancestors_v3, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_from_v3))
== std::nullopt);
Package package_v3_v3{mempool_tx_v3, tx_v3_from_v3};
- BOOST_CHECK(PackageV3Checks(tx_v3_from_v3, GetVirtualTransactionSize(*tx_v3_from_v3), package_v3_v3, empty_ancestors) == std::nullopt);
+ BOOST_CHECK(PackageTRUCChecks(tx_v3_from_v3, GetVirtualTransactionSize(*tx_v3_from_v3), package_v3_v3, empty_ancestors) == std::nullopt);
// mempool_tx_v2
// ^
// tx_v2_from_v2
auto tx_v2_from_v2 = make_tx({COutPoint{mempool_tx_v2->GetHash(), 0}}, /*version=*/2);
auto ancestors_v2{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v2_from_v2), m_limits)};
- BOOST_CHECK(SingleV3Checks(tx_v2_from_v2, *ancestors_v2, empty_conflicts_set, GetVirtualTransactionSize(*tx_v2_from_v2))
+ BOOST_CHECK(SingleTRUCChecks(tx_v2_from_v2, *ancestors_v2, empty_conflicts_set, GetVirtualTransactionSize(*tx_v2_from_v2))
== std::nullopt);
Package package_v2_v2{mempool_tx_v2, tx_v2_from_v2};
- BOOST_CHECK(PackageV3Checks(tx_v2_from_v2, GetVirtualTransactionSize(*tx_v2_from_v2), package_v2_v2, empty_ancestors) == std::nullopt);
+ BOOST_CHECK(PackageTRUCChecks(tx_v2_from_v2, GetVirtualTransactionSize(*tx_v2_from_v2), package_v2_v2, empty_ancestors) == std::nullopt);
}
- // Tx spending v3 cannot have too many mempool ancestors
+ // Tx spending TRUC cannot have too many mempool ancestors
// Configuration where the tx has multiple direct parents.
{
Package package_multi_parents;
@@ -221,11 +221,11 @@ BOOST_FIXTURE_TEST_CASE(version3_tests, RegTestingSetup)
BOOST_CHECK_EQUAL(ancestors->size(), 3);
const auto expected_error_str{strprintf("tx %s (wtxid=%s) would have too many ancestors",
tx_v3_multi_parent->GetHash().ToString(), tx_v3_multi_parent->GetWitnessHash().ToString())};
- auto result{SingleV3Checks(tx_v3_multi_parent, *ancestors, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_multi_parent))};
+ auto result{SingleTRUCChecks(tx_v3_multi_parent, *ancestors, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_multi_parent))};
BOOST_CHECK_EQUAL(result->first, expected_error_str);
BOOST_CHECK_EQUAL(result->second, nullptr);
- BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v3_multi_parent, GetVirtualTransactionSize(*tx_v3_multi_parent), package_multi_parents, empty_ancestors),
+ BOOST_CHECK_EQUAL(*PackageTRUCChecks(tx_v3_multi_parent, GetVirtualTransactionSize(*tx_v3_multi_parent), package_multi_parents, empty_ancestors),
expected_error_str);
}
@@ -246,34 +246,34 @@ BOOST_FIXTURE_TEST_CASE(version3_tests, RegTestingSetup)
auto ancestors{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_multi_gen), m_limits)};
const auto expected_error_str{strprintf("tx %s (wtxid=%s) would have too many ancestors",
tx_v3_multi_gen->GetHash().ToString(), tx_v3_multi_gen->GetWitnessHash().ToString())};
- auto result{SingleV3Checks(tx_v3_multi_gen, *ancestors, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_multi_gen))};
+ auto result{SingleTRUCChecks(tx_v3_multi_gen, *ancestors, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_multi_gen))};
BOOST_CHECK_EQUAL(result->first, expected_error_str);
BOOST_CHECK_EQUAL(result->second, nullptr);
// Middle tx is what triggers a failure for the grandchild:
- BOOST_CHECK_EQUAL(*PackageV3Checks(middle_tx, GetVirtualTransactionSize(*middle_tx), package_multi_gen, empty_ancestors), expected_error_str);
- BOOST_CHECK(PackageV3Checks(tx_v3_multi_gen, GetVirtualTransactionSize(*tx_v3_multi_gen), package_multi_gen, empty_ancestors) == std::nullopt);
+ BOOST_CHECK_EQUAL(*PackageTRUCChecks(middle_tx, GetVirtualTransactionSize(*middle_tx), package_multi_gen, empty_ancestors), expected_error_str);
+ BOOST_CHECK(PackageTRUCChecks(tx_v3_multi_gen, GetVirtualTransactionSize(*tx_v3_multi_gen), package_multi_gen, empty_ancestors) == std::nullopt);
}
- // Tx spending v3 cannot be too large in virtual size.
+ // Tx spending TRUC cannot be too large in virtual size.
auto many_inputs{random_outpoints(100)};
many_inputs.emplace_back(mempool_tx_v3->GetHash(), 0);
{
auto tx_v3_child_big = make_tx(many_inputs, /*version=*/3);
const auto vsize{GetVirtualTransactionSize(*tx_v3_child_big)};
auto ancestors{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_child_big), m_limits)};
- const auto expected_error_str{strprintf("v3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
- tx_v3_child_big->GetHash().ToString(), tx_v3_child_big->GetWitnessHash().ToString(), vsize, V3_CHILD_MAX_VSIZE)};
- auto result{SingleV3Checks(tx_v3_child_big, *ancestors, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_child_big))};
+ const auto expected_error_str{strprintf("version=3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
+ tx_v3_child_big->GetHash().ToString(), tx_v3_child_big->GetWitnessHash().ToString(), vsize, TRUC_CHILD_MAX_VSIZE)};
+ auto result{SingleTRUCChecks(tx_v3_child_big, *ancestors, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_child_big))};
BOOST_CHECK_EQUAL(result->first, expected_error_str);
BOOST_CHECK_EQUAL(result->second, nullptr);
Package package_child_big{mempool_tx_v3, tx_v3_child_big};
- BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v3_child_big, GetVirtualTransactionSize(*tx_v3_child_big), package_child_big, empty_ancestors),
+ BOOST_CHECK_EQUAL(*PackageTRUCChecks(tx_v3_child_big, GetVirtualTransactionSize(*tx_v3_child_big), package_child_big, empty_ancestors),
expected_error_str);
}
- // Tx spending v3 cannot have too many sigops.
+ // Tx spending TRUC cannot have too many sigops.
// This child has 10 P2WSH multisig inputs.
auto multisig_outpoints{random_outpoints(10)};
multisig_outpoints.emplace_back(mempool_tx_v3->GetHash(), 0);
@@ -302,34 +302,34 @@ BOOST_FIXTURE_TEST_CASE(version3_tests, RegTestingSetup)
BOOST_CHECK_EQUAL(total_sigops, tx_many_sigops->vin.size() * MAX_PUBKEYS_PER_MULTISIG);
const int64_t bip141_vsize{GetVirtualTransactionSize(*tx_many_sigops)};
// Weight limit is not reached...
- BOOST_CHECK(SingleV3Checks(tx_many_sigops, *ancestors, empty_conflicts_set, bip141_vsize) == std::nullopt);
+ BOOST_CHECK(SingleTRUCChecks(tx_many_sigops, *ancestors, empty_conflicts_set, bip141_vsize) == std::nullopt);
// ...but sigop limit is.
- const auto expected_error_str{strprintf("v3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
+ const auto expected_error_str{strprintf("version=3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
tx_many_sigops->GetHash().ToString(), tx_many_sigops->GetWitnessHash().ToString(),
- total_sigops * DEFAULT_BYTES_PER_SIGOP / WITNESS_SCALE_FACTOR, V3_CHILD_MAX_VSIZE)};
- auto result{SingleV3Checks(tx_many_sigops, *ancestors, empty_conflicts_set,
+ total_sigops * DEFAULT_BYTES_PER_SIGOP / WITNESS_SCALE_FACTOR, TRUC_CHILD_MAX_VSIZE)};
+ auto result{SingleTRUCChecks(tx_many_sigops, *ancestors, empty_conflicts_set,
GetVirtualTransactionSize(*tx_many_sigops, /*nSigOpCost=*/total_sigops, /*bytes_per_sigop=*/ DEFAULT_BYTES_PER_SIGOP))};
BOOST_CHECK_EQUAL(result->first, expected_error_str);
BOOST_CHECK_EQUAL(result->second, nullptr);
Package package_child_sigops{mempool_tx_v3, tx_many_sigops};
- BOOST_CHECK_EQUAL(*PackageV3Checks(tx_many_sigops, total_sigops * DEFAULT_BYTES_PER_SIGOP / WITNESS_SCALE_FACTOR, package_child_sigops, empty_ancestors),
+ BOOST_CHECK_EQUAL(*PackageTRUCChecks(tx_many_sigops, total_sigops * DEFAULT_BYTES_PER_SIGOP / WITNESS_SCALE_FACTOR, package_child_sigops, empty_ancestors),
expected_error_str);
}
- // Parent + child with v3 in the mempool. Child is allowed as long as it is under V3_CHILD_MAX_VSIZE.
+ // Parent + child with TRUC in the mempool. Child is allowed as long as it is under TRUC_CHILD_MAX_VSIZE.
auto tx_mempool_v3_child = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}}, /*version=*/3);
{
- BOOST_CHECK(GetTransactionWeight(*tx_mempool_v3_child) <= V3_CHILD_MAX_VSIZE * WITNESS_SCALE_FACTOR);
+ BOOST_CHECK(GetTransactionWeight(*tx_mempool_v3_child) <= TRUC_CHILD_MAX_VSIZE * WITNESS_SCALE_FACTOR);
auto ancestors{pool.CalculateMemPoolAncestors(entry.FromTx(tx_mempool_v3_child), m_limits)};
- BOOST_CHECK(SingleV3Checks(tx_mempool_v3_child, *ancestors, empty_conflicts_set, GetVirtualTransactionSize(*tx_mempool_v3_child)) == std::nullopt);
+ BOOST_CHECK(SingleTRUCChecks(tx_mempool_v3_child, *ancestors, empty_conflicts_set, GetVirtualTransactionSize(*tx_mempool_v3_child)) == std::nullopt);
pool.addUnchecked(entry.FromTx(tx_mempool_v3_child));
Package package_v3_1p1c{mempool_tx_v3, tx_mempool_v3_child};
- BOOST_CHECK(PackageV3Checks(tx_mempool_v3_child, GetVirtualTransactionSize(*tx_mempool_v3_child), package_v3_1p1c, empty_ancestors) == std::nullopt);
+ BOOST_CHECK(PackageTRUCChecks(tx_mempool_v3_child, GetVirtualTransactionSize(*tx_mempool_v3_child), package_v3_1p1c, empty_ancestors) == std::nullopt);
}
- // A v3 transaction cannot have more than 1 descendant. Sibling is returned when exactly 1 exists.
+ // A TRUC transaction cannot have more than 1 descendant. Sibling is returned when exactly 1 exists.
{
auto tx_v3_child2 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 1}}, /*version=*/3);
@@ -337,17 +337,17 @@ BOOST_FIXTURE_TEST_CASE(version3_tests, RegTestingSetup)
auto ancestors_1sibling{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_child2), m_limits)};
const auto expected_error_str{strprintf("tx %s (wtxid=%s) would exceed descendant count limit",
mempool_tx_v3->GetHash().ToString(), mempool_tx_v3->GetWitnessHash().ToString())};
- auto result_with_sibling_eviction{SingleV3Checks(tx_v3_child2, *ancestors_1sibling, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_child2))};
+ auto result_with_sibling_eviction{SingleTRUCChecks(tx_v3_child2, *ancestors_1sibling, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_child2))};
BOOST_CHECK_EQUAL(result_with_sibling_eviction->first, expected_error_str);
// The other mempool child is returned to allow for sibling eviction.
BOOST_CHECK_EQUAL(result_with_sibling_eviction->second, tx_mempool_v3_child);
// If directly replacing the child, make sure there is no double-counting.
- BOOST_CHECK(SingleV3Checks(tx_v3_child2, *ancestors_1sibling, {tx_mempool_v3_child->GetHash()}, GetVirtualTransactionSize(*tx_v3_child2))
+ BOOST_CHECK(SingleTRUCChecks(tx_v3_child2, *ancestors_1sibling, {tx_mempool_v3_child->GetHash()}, GetVirtualTransactionSize(*tx_v3_child2))
== std::nullopt);
Package package_v3_1p2c{mempool_tx_v3, tx_mempool_v3_child, tx_v3_child2};
- BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v3_child2, GetVirtualTransactionSize(*tx_v3_child2), package_v3_1p2c, empty_ancestors),
+ BOOST_CHECK_EQUAL(*PackageTRUCChecks(tx_v3_child2, GetVirtualTransactionSize(*tx_v3_child2), package_v3_1p2c, empty_ancestors),
expected_error_str);
// Configuration where parent already has 2 other children in mempool (no sibling eviction allowed). This may happen as the result of a reorg.
@@ -357,7 +357,7 @@ BOOST_FIXTURE_TEST_CASE(version3_tests, RegTestingSetup)
BOOST_CHECK_EQUAL(entry_mempool_parent->GetCountWithDescendants(), 3);
auto ancestors_2siblings{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_child3), m_limits)};
- auto result_2children{SingleV3Checks(tx_v3_child3, *ancestors_2siblings, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_child3))};
+ auto result_2children{SingleTRUCChecks(tx_v3_child3, *ancestors_2siblings, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_child3))};
BOOST_CHECK_EQUAL(result_2children->first, expected_error_str);
// The other mempool child is not returned because sibling eviction is not allowed.
BOOST_CHECK_EQUAL(result_2children->second, nullptr);
@@ -377,7 +377,7 @@ BOOST_FIXTURE_TEST_CASE(version3_tests, RegTestingSetup)
auto ancestors_3gen{pool.CalculateMemPoolAncestors(entry.FromTx(tx_to_submit), m_limits)};
const auto expected_error_str{strprintf("tx %s (wtxid=%s) would exceed descendant count limit",
tx_mempool_grandparent->GetHash().ToString(), tx_mempool_grandparent->GetWitnessHash().ToString())};
- auto result_3gen{SingleV3Checks(tx_to_submit, *ancestors_3gen, empty_conflicts_set, GetVirtualTransactionSize(*tx_to_submit))};
+ auto result_3gen{SingleTRUCChecks(tx_to_submit, *ancestors_3gen, empty_conflicts_set, GetVirtualTransactionSize(*tx_to_submit))};
BOOST_CHECK_EQUAL(result_3gen->first, expected_error_str);
// The other mempool child is not returned because sibling eviction is not allowed.
BOOST_CHECK_EQUAL(result_3gen->second, nullptr);
diff --git a/src/test/util/txmempool.cpp b/src/test/util/txmempool.cpp
index 94d50bba50..9d6b4810d0 100644
--- a/src/test/util/txmempool.cpp
+++ b/src/test/util/txmempool.cpp
@@ -8,7 +8,7 @@
#include <node/context.h>
#include <node/mempool_args.h>
#include <policy/rbf.h>
-#include <policy/v3_policy.h>
+#include <policy/truc_policy.h>
#include <txmempool.h>
#include <util/check.h>
#include <util/time.h>
@@ -141,30 +141,30 @@ std::optional<std::string> CheckPackageMempoolAcceptResult(const Package& txns,
return std::nullopt;
}
-void CheckMempoolV3Invariants(const CTxMemPool& tx_pool)
+void CheckMempoolTRUCInvariants(const CTxMemPool& tx_pool)
{
LOCK(tx_pool.cs);
for (const auto& tx_info : tx_pool.infoAll()) {
const auto& entry = *Assert(tx_pool.GetEntry(tx_info.tx->GetHash()));
if (tx_info.tx->version == TRUC_VERSION) {
// Check that special maximum virtual size is respected
- Assert(entry.GetTxSize() <= V3_MAX_VSIZE);
+ Assert(entry.GetTxSize() <= TRUC_MAX_VSIZE);
- // Check that special v3 ancestor/descendant limits and rules are always respected
- Assert(entry.GetCountWithDescendants() <= V3_DESCENDANT_LIMIT);
- Assert(entry.GetCountWithAncestors() <= V3_ANCESTOR_LIMIT);
- Assert(entry.GetSizeWithDescendants() <= V3_MAX_VSIZE + V3_CHILD_MAX_VSIZE);
- Assert(entry.GetSizeWithAncestors() <= V3_MAX_VSIZE + V3_CHILD_MAX_VSIZE);
+ // Check that special TRUC ancestor/descendant limits and rules are always respected
+ Assert(entry.GetCountWithDescendants() <= TRUC_DESCENDANT_LIMIT);
+ Assert(entry.GetCountWithAncestors() <= TRUC_ANCESTOR_LIMIT);
+ Assert(entry.GetSizeWithDescendants() <= TRUC_MAX_VSIZE + TRUC_CHILD_MAX_VSIZE);
+ Assert(entry.GetSizeWithAncestors() <= TRUC_MAX_VSIZE + TRUC_CHILD_MAX_VSIZE);
// If this transaction has at least 1 ancestor, it's a "child" and has restricted weight.
if (entry.GetCountWithAncestors() > 1) {
- Assert(entry.GetTxSize() <= V3_CHILD_MAX_VSIZE);
- // All v3 transactions must only have v3 unconfirmed parents.
+ Assert(entry.GetTxSize() <= TRUC_CHILD_MAX_VSIZE);
+ // All TRUC transactions must only have TRUC unconfirmed parents.
const auto& parents = entry.GetMemPoolParentsConst();
Assert(parents.begin()->get().GetSharedTx()->version == TRUC_VERSION);
}
} else if (entry.GetCountWithAncestors() > 1) {
- // All non-v3 transactions must only have non-v3 unconfirmed parents.
+ // All non-TRUC transactions must only have non-TRUC unconfirmed parents.
for (const auto& parent : entry.GetMemPoolParentsConst()) {
Assert(parent.get().GetSharedTx()->version != TRUC_VERSION);
}
diff --git a/src/test/util/txmempool.h b/src/test/util/txmempool.h
index b3022af7df..6d41fdf87f 100644
--- a/src/test/util/txmempool.h
+++ b/src/test/util/txmempool.h
@@ -47,13 +47,13 @@ std::optional<std::string> CheckPackageMempoolAcceptResult(const Package& txns,
bool expect_valid,
const CTxMemPool* mempool);
-/** For every transaction in tx_pool, check v3 invariants:
- * - a v3 tx's ancestor count must be within V3_ANCESTOR_LIMIT
- * - a v3 tx's descendant count must be within V3_DESCENDANT_LIMIT
- * - if a v3 tx has ancestors, its sigop-adjusted vsize must be within V3_CHILD_MAX_VSIZE
- * - any non-v3 tx must only have non-v3 parents
- * - any v3 tx must only have v3 parents
+/** For every transaction in tx_pool, check TRUC invariants:
+ * - a TRUC tx's ancestor count must be within TRUC_ANCESTOR_LIMIT
+ * - a TRUC tx's descendant count must be within TRUC_DESCENDANT_LIMIT
+ * - if a TRUC tx has ancestors, its sigop-adjusted vsize must be within TRUC_CHILD_MAX_VSIZE
+ * - any non-TRUC tx must only have non-TRUC parents
+ * - any TRUC tx must only have TRUC parents
* */
-void CheckMempoolV3Invariants(const CTxMemPool& tx_pool);
+void CheckMempoolTRUCInvariants(const CTxMemPool& tx_pool);
#endif // BITCOIN_TEST_UTIL_TXMEMPOOL_H
diff --git a/src/validation.cpp b/src/validation.cpp
index 4241d51d15..7b586c45b8 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -35,7 +35,7 @@
#include <policy/policy.h>
#include <policy/rbf.h>
#include <policy/settings.h>
-#include <policy/v3_policy.h>
+#include <policy/truc_policy.h>
#include <pow.h>
#include <primitives/block.h>
#include <primitives/transaction.h>
@@ -336,7 +336,7 @@ 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.
- // Note that v3 rules are not applied here, so reorgs may cause violations of v3 inheritance or
+ // Note that TRUC rules are not applied here, so reorgs may cause violations of TRUC inheritance or
// topology restrictions.
const auto filter_final_and_mature = [&](CTxMemPool::txiter it)
EXCLUSIVE_LOCKS_REQUIRED(m_mempool->cs, ::cs_main) {
@@ -829,7 +829,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// check all unconfirmed ancestors; otherwise an opt-in ancestor
// might be replaced, causing removal of this descendant.
//
- // All V3 transactions are considered replaceable.
+ // All TRUC transactions are considered replaceable.
//
// Replaceability signaling of the original transactions may be
// ignored due to node setting.
@@ -936,7 +936,7 @@ 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.
- // The only exception is v3 transactions.
+ // The only exception is TRUC transactions.
if (!bypass_limits && ws.m_ptx->version != TRUC_VERSION && ws.m_modified_fees < m_pool.m_opts.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.
@@ -1005,7 +1005,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// If the new transaction is relatively small (up to 40k weight)
// and has at most one ancestor (ie ancestor limit of 2, including
// the new transaction), allow it if its parent has exactly the
- // descendant limit descendants. The transaction also cannot be v3,
+ // descendant limit descendants. The transaction also cannot be TRUC,
// as its topology restrictions do not allow a second child.
//
// This allows protocols which rely on distrusting counterparties
@@ -1032,7 +1032,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// Even though just checking direct mempool parents for inheritance would be sufficient, we
// check using the full ancestor set here because it's more convenient to use what we have
// already calculated.
- if (const auto err{SingleV3Checks(ws.m_ptx, ws.m_ancestors, ws.m_conflicts, ws.m_vsize)}) {
+ if (const auto err{SingleTRUCChecks(ws.m_ptx, ws.m_ancestors, ws.m_conflicts, ws.m_vsize)}) {
// Single transaction contexts only.
if (args.m_allow_sibling_eviction && err->second != nullptr) {
// We should only be considering where replacement is considered valid as well.
@@ -1043,15 +1043,15 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
ws.m_conflicts.insert(err->second->GetHash());
// Adding the sibling to m_iters_conflicting here means that it doesn't count towards
// RBF Carve Out above. This is correct, since removing to-be-replaced transactions from
- // the descendant count is done separately in SingleV3Checks for v3 transactions.
+ // the descendant count is done separately in SingleTRUCChecks for TRUC transactions.
ws.m_iters_conflicting.insert(m_pool.GetIter(err->second->GetHash()).value());
ws.m_sibling_eviction = true;
// The sibling will be treated as part of the to-be-replaced set in ReplacementChecks.
- // Note that we are not checking whether it opts in to replaceability via BIP125 or v3
- // (which is normally done in PreChecks). However, the only way a v3 transaction can
- // have a non-v3 and non-BIP125 descendant is due to a reorg.
+ // Note that we are not checking whether it opts in to replaceability via BIP125 or TRUC
+ // (which is normally done in PreChecks). However, the only way a TRUC transaction can
+ // have a non-TRUC and non-BIP125 descendant is due to a reorg.
} else {
- return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "v3-rule-violation", err->first);
+ return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "TRUC-violation", err->first);
}
}
@@ -1103,7 +1103,7 @@ bool MemPoolAccept::ReplacementChecks(Workspace& ws)
}
// Enforce Rule #2.
if (const auto err_string{HasNoNewUnconfirmed(tx, m_pool, m_subpackage.m_all_conflicts)}) {
- // Sibling eviction is only done for v3 transactions, which cannot have multiple ancestors.
+ // Sibling eviction is only done for TRUC transactions, which cannot have multiple ancestors.
Assume(!ws.m_sibling_eviction);
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY,
strprintf("replacement-adds-unconfirmed%s", ws.m_sibling_eviction ? " (including sibling eviction)" : ""), *err_string);
@@ -1545,10 +1545,10 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
}
// At this point we have all in-mempool ancestors, and we know every transaction's vsize.
- // Run the v3 checks on the package.
+ // Run the TRUC 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());
+ if (auto err{PackageTRUCChecks(ws.m_ptx, ws.m_vsize, txns, ws.m_ancestors)}) {
+ package_state.Invalid(PackageValidationResult::PCKG_POLICY, "TRUC-violation", err.value());
return PackageMempoolAcceptResult(package_state, {});
}
}
diff --git a/test/functional/mempool_accept_v3.py b/test/functional/mempool_truc.py
index d4a33c232e..e1f3d77201 100755
--- a/test/functional/mempool_accept_v3.py
+++ b/test/functional/mempool_truc.py
@@ -22,7 +22,7 @@ from test_framework.wallet import (
)
MAX_REPLACEMENT_CANDIDATES = 100
-V3_MAX_VSIZE = 10000
+TRUC_MAX_VSIZE = 10000
def cleanup(extra_args=None):
def decorator(func):
@@ -39,7 +39,7 @@ def cleanup(extra_args=None):
return wrapper
return decorator
-class MempoolAcceptV3(BitcoinTestFramework):
+class MempoolTRUC(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
self.extra_args = [[]]
@@ -52,23 +52,23 @@ class MempoolAcceptV3(BitcoinTestFramework):
assert all([txid in txids for txid in mempool_contents])
@cleanup(extra_args=["-datacarriersize=20000"])
- def test_v3_max_vsize(self):
+ def test_truc_max_vsize(self):
node = self.nodes[0]
- self.log.info("Test v3-specific maximum transaction vsize")
- tx_v3_heavy = self.wallet.create_self_transfer(target_weight=(V3_MAX_VSIZE + 1) * WITNESS_SCALE_FACTOR, version=3)
- assert_greater_than_or_equal(tx_v3_heavy["tx"].get_vsize(), V3_MAX_VSIZE)
- expected_error_heavy = f"v3-rule-violation, v3 tx {tx_v3_heavy['txid']} (wtxid={tx_v3_heavy['wtxid']}) is too big"
+ self.log.info("Test TRUC-specific maximum transaction vsize")
+ tx_v3_heavy = self.wallet.create_self_transfer(target_weight=(TRUC_MAX_VSIZE + 1) * WITNESS_SCALE_FACTOR, version=3)
+ assert_greater_than_or_equal(tx_v3_heavy["tx"].get_vsize(), TRUC_MAX_VSIZE)
+ expected_error_heavy = f"TRUC-violation, version=3 tx {tx_v3_heavy['txid']} (wtxid={tx_v3_heavy['wtxid']}) is too big"
assert_raises_rpc_error(-26, expected_error_heavy, node.sendrawtransaction, tx_v3_heavy["hex"])
self.check_mempool([])
- # Ensure we are hitting the v3-specific limit and not something else
- tx_v2_heavy = self.wallet.send_self_transfer(from_node=node, target_weight=(V3_MAX_VSIZE + 1) * WITNESS_SCALE_FACTOR, version=2)
+ # Ensure we are hitting the TRUC-specific limit and not something else
+ tx_v2_heavy = self.wallet.send_self_transfer(from_node=node, target_weight=(TRUC_MAX_VSIZE + 1) * WITNESS_SCALE_FACTOR, version=2)
self.check_mempool([tx_v2_heavy["txid"]])
@cleanup(extra_args=["-datacarriersize=1000"])
- def test_v3_acceptance(self):
+ def test_truc_acceptance(self):
node = self.nodes[0]
- self.log.info("Test a child of a v3 transaction cannot be more than 1000vB")
+ self.log.info("Test a child of a TRUC transaction cannot be more than 1000vB")
tx_v3_parent_normal = self.wallet.send_self_transfer(from_node=node, version=3)
self.check_mempool([tx_v3_parent_normal["txid"]])
tx_v3_child_heavy = self.wallet.create_self_transfer(
@@ -77,13 +77,13 @@ class MempoolAcceptV3(BitcoinTestFramework):
version=3
)
assert_greater_than_or_equal(tx_v3_child_heavy["tx"].get_vsize(), 1000)
- expected_error_child_heavy = f"v3-rule-violation, v3 child tx {tx_v3_child_heavy['txid']} (wtxid={tx_v3_child_heavy['wtxid']}) is too big"
+ expected_error_child_heavy = f"TRUC-violation, version=3 child tx {tx_v3_child_heavy['txid']} (wtxid={tx_v3_child_heavy['wtxid']}) is too big"
assert_raises_rpc_error(-26, expected_error_child_heavy, node.sendrawtransaction, tx_v3_child_heavy["hex"])
self.check_mempool([tx_v3_parent_normal["txid"]])
# tx has no descendants
assert_equal(node.getmempoolentry(tx_v3_parent_normal["txid"])["descendantcount"], 1)
- self.log.info("Test that, during replacements, only the new transaction counts for v3 descendant limit")
+ self.log.info("Test that, during replacements, only the new transaction counts for TRUC descendant limit")
tx_v3_child_almost_heavy = self.wallet.send_self_transfer(
from_node=node,
fee_rate=DEFAULT_FEE,
@@ -106,9 +106,9 @@ class MempoolAcceptV3(BitcoinTestFramework):
assert_equal(node.getmempoolentry(tx_v3_parent_normal["txid"])["descendantcount"], 2)
@cleanup(extra_args=None)
- def test_v3_replacement(self):
+ def test_truc_replacement(self):
node = self.nodes[0]
- self.log.info("Test v3 transactions may be replaced by v3 transactions")
+ self.log.info("Test TRUC transactions may be replaced by TRUC transactions")
utxo_v3_bip125 = self.wallet.get_utxo()
tx_v3_bip125 = self.wallet.send_self_transfer(
from_node=node,
@@ -127,7 +127,7 @@ class MempoolAcceptV3(BitcoinTestFramework):
)
self.check_mempool([tx_v3_bip125_rbf["txid"]])
- self.log.info("Test v3 transactions may be replaced by V2 transactions")
+ self.log.info("Test TRUC transactions may be replaced by non-TRUC (BIP125) transactions")
tx_v3_bip125_rbf_v2 = self.wallet.send_self_transfer(
from_node=node,
fee_rate=DEFAULT_FEE * 3,
@@ -136,7 +136,7 @@ class MempoolAcceptV3(BitcoinTestFramework):
)
self.check_mempool([tx_v3_bip125_rbf_v2["txid"]])
- self.log.info("Test that replacements cannot cause violation of inherited v3")
+ self.log.info("Test that replacements cannot cause violation of inherited TRUC")
utxo_v3_parent = self.wallet.get_utxo()
tx_v3_parent = self.wallet.send_self_transfer(
from_node=node,
@@ -157,15 +157,15 @@ class MempoolAcceptV3(BitcoinTestFramework):
utxo_to_spend=tx_v3_parent["new_utxo"],
version=2
)
- expected_error_v2_v3 = f"v3-rule-violation, non-v3 tx {tx_v3_child_rbf_v2['txid']} (wtxid={tx_v3_child_rbf_v2['wtxid']}) cannot spend from v3 tx {tx_v3_parent['txid']} (wtxid={tx_v3_parent['wtxid']})"
+ expected_error_v2_v3 = f"TRUC-violation, non-version=3 tx {tx_v3_child_rbf_v2['txid']} (wtxid={tx_v3_child_rbf_v2['wtxid']}) cannot spend from version=3 tx {tx_v3_parent['txid']} (wtxid={tx_v3_parent['wtxid']})"
assert_raises_rpc_error(-26, expected_error_v2_v3, node.sendrawtransaction, tx_v3_child_rbf_v2["hex"])
self.check_mempool([tx_v3_bip125_rbf_v2["txid"], tx_v3_parent["txid"], tx_v3_child["txid"]])
@cleanup(extra_args=None)
- def test_v3_bip125(self):
+ def test_truc_bip125(self):
node = self.nodes[0]
- self.log.info("Test v3 transactions that don't signal BIP125 are replaceable")
+ self.log.info("Test TRUC transactions that don't signal BIP125 are replaceable")
assert_equal(node.getmempoolinfo()["fullrbf"], False)
utxo_v3_no_bip125 = self.wallet.get_utxo()
tx_v3_no_bip125 = self.wallet.send_self_transfer(
@@ -187,9 +187,9 @@ class MempoolAcceptV3(BitcoinTestFramework):
self.check_mempool([tx_v3_no_bip125_rbf["txid"]])
@cleanup(extra_args=["-datacarriersize=40000"])
- def test_v3_reorg(self):
+ def test_truc_reorg(self):
node = self.nodes[0]
- self.log.info("Test that, during a reorg, v3 rules are not enforced")
+ self.log.info("Test that, during a reorg, TRUC rules are not enforced")
tx_v2_block = self.wallet.send_self_transfer(from_node=node, version=2)
tx_v3_block = self.wallet.send_self_transfer(from_node=node, version=3)
tx_v3_block2 = self.wallet.send_self_transfer(from_node=node, version=3)
@@ -211,12 +211,12 @@ class MempoolAcceptV3(BitcoinTestFramework):
@cleanup(extra_args=["-limitdescendantsize=10", "-datacarriersize=40000"])
def test_nondefault_package_limits(self):
"""
- Max standard tx size + v3 rules imply the ancestor/descendant rules (at their default
+ Max standard tx size + TRUC rules imply the ancestor/descendant rules (at their default
values), but those checks must not be skipped. Ensure both sets of checks are done by
changing the ancestor/descendant limit configurations.
"""
node = self.nodes[0]
- self.log.info("Test that a decreased limitdescendantsize also applies to v3 child")
+ self.log.info("Test that a decreased limitdescendantsize also applies to TRUC child")
parent_target_weight = 9990 * WITNESS_SCALE_FACTOR
child_target_weight = 500 * WITNESS_SCALE_FACTOR
tx_v3_parent_large1 = self.wallet.send_self_transfer(
@@ -231,7 +231,7 @@ class MempoolAcceptV3(BitcoinTestFramework):
)
# Parent and child are within v3 limits, but parent's 10kvB descendant limit is exceeded
- assert_greater_than_or_equal(V3_MAX_VSIZE, tx_v3_parent_large1["tx"].get_vsize())
+ assert_greater_than_or_equal(TRUC_MAX_VSIZE, tx_v3_parent_large1["tx"].get_vsize())
assert_greater_than_or_equal(1000, tx_v3_child_large1["tx"].get_vsize())
assert_greater_than(tx_v3_parent_large1["tx"].get_vsize() + tx_v3_child_large1["tx"].get_vsize(), 10000)
@@ -253,8 +253,8 @@ class MempoolAcceptV3(BitcoinTestFramework):
version=3
)
- # Parent and child are within v3 limits
- assert_greater_than_or_equal(V3_MAX_VSIZE, tx_v3_parent_large2["tx"].get_vsize())
+ # Parent and child are within TRUC limits
+ assert_greater_than_or_equal(TRUC_MAX_VSIZE, tx_v3_parent_large2["tx"].get_vsize())
assert_greater_than_or_equal(1000, tx_v3_child_large2["tx"].get_vsize())
assert_greater_than(tx_v3_parent_large2["tx"].get_vsize() + tx_v3_child_large2["tx"].get_vsize(), 10000)
@@ -262,8 +262,8 @@ class MempoolAcceptV3(BitcoinTestFramework):
self.check_mempool([tx_v3_parent_large2["txid"]])
@cleanup(extra_args=["-datacarriersize=1000"])
- def test_v3_ancestors_package(self):
- self.log.info("Test that v3 ancestor limits are checked within the package")
+ def test_truc_ancestors_package(self):
+ self.log.info("Test that TRUC ancestor limits are checked within the package")
node = self.nodes[0]
tx_v3_parent_normal = self.wallet.create_self_transfer(
fee_rate=0,
@@ -289,34 +289,34 @@ class MempoolAcceptV3(BitcoinTestFramework):
self.check_mempool([])
result = node.submitpackage([tx_v3_parent_normal["hex"], tx_v3_parent_2_normal["hex"], tx_v3_child_multiparent["hex"]])
- assert_equal(result['package_msg'], f"v3-violation, tx {tx_v3_child_multiparent['txid']} (wtxid={tx_v3_child_multiparent['wtxid']}) would have too many ancestors")
+ assert_equal(result['package_msg'], f"TRUC-violation, tx {tx_v3_child_multiparent['txid']} (wtxid={tx_v3_child_multiparent['wtxid']}) would have too many ancestors")
self.check_mempool([])
self.check_mempool([])
result = node.submitpackage([tx_v3_parent_normal["hex"], tx_v3_child_heavy["hex"]])
# tx_v3_child_heavy is heavy based on weight, not sigops.
- assert_equal(result['package_msg'], f"v3-violation, v3 child tx {tx_v3_child_heavy['txid']} (wtxid={tx_v3_child_heavy['wtxid']}) is too big: {tx_v3_child_heavy['tx'].get_vsize()} > 1000 virtual bytes")
+ assert_equal(result['package_msg'], f"TRUC-violation, version=3 child tx {tx_v3_child_heavy['txid']} (wtxid={tx_v3_child_heavy['wtxid']}) is too big: {tx_v3_child_heavy['tx'].get_vsize()} > 1000 virtual bytes")
self.check_mempool([])
tx_v3_parent = self.wallet.create_self_transfer(version=3)
tx_v3_child = self.wallet.create_self_transfer(utxo_to_spend=tx_v3_parent["new_utxo"], version=3)
tx_v3_grandchild = self.wallet.create_self_transfer(utxo_to_spend=tx_v3_child["new_utxo"], version=3)
result = node.testmempoolaccept([tx_v3_parent["hex"], tx_v3_child["hex"], tx_v3_grandchild["hex"]])
- assert all([txresult["package-error"] == f"v3-violation, tx {tx_v3_grandchild['txid']} (wtxid={tx_v3_grandchild['wtxid']}) would have too many ancestors" for txresult in result])
+ assert all([txresult["package-error"] == f"TRUC-violation, tx {tx_v3_grandchild['txid']} (wtxid={tx_v3_grandchild['wtxid']}) would have too many ancestors" for txresult in result])
@cleanup(extra_args=None)
- def test_v3_ancestors_package_and_mempool(self):
+ def test_truc_ancestors_package_and_mempool(self):
"""
- A v3 transaction in a package cannot have 2 v3 parents.
+ A TRUC transaction in a package cannot have 2 TRUC parents.
Test that if we have a transaction graph A -> B -> C, where A, B, C are
- all v3 transactions, that we cannot use submitpackage to get the
+ all TRUC transactions, that we cannot use submitpackage to get the
transactions all into the mempool.
Verify, in particular, that if A is already in the mempool, then
submitpackage(B, C) will fail.
"""
node = self.nodes[0]
- self.log.info("Test that v3 ancestor limits include transactions within the package and all in-mempool ancestors")
+ self.log.info("Test that TRUC ancestor limits include transactions within the package and all in-mempool ancestors")
# This is our transaction "A":
tx_in_mempool = self.wallet.send_self_transfer(from_node=node, version=3)
@@ -331,7 +331,7 @@ class MempoolAcceptV3(BitcoinTestFramework):
# submitpackage(B, C) should fail
result = node.submitpackage([tx_0fee_parent["hex"], tx_child_violator["hex"]])
- assert_equal(result['package_msg'], f"v3-violation, tx {tx_child_violator['txid']} (wtxid={tx_child_violator['wtxid']}) would have too many ancestors")
+ assert_equal(result['package_msg'], f"TRUC-violation, tx {tx_child_violator['txid']} (wtxid={tx_child_violator['wtxid']}) would have too many ancestors")
self.check_mempool([tx_in_mempool["txid"]])
@cleanup(extra_args=None)
@@ -341,7 +341,7 @@ class MempoolAcceptV3(BitcoinTestFramework):
However, this option is only available in single transaction acceptance. It doesn't work in
a multi-testmempoolaccept (where RBF is disabled) or when doing package CPFP.
"""
- self.log.info("Test v3 sibling eviction in submitpackage and multi-testmempoolaccept")
+ self.log.info("Test TRUC sibling eviction in submitpackage and multi-testmempoolaccept")
node = self.nodes[0]
# Add a parent + child to mempool
tx_mempool_parent = self.wallet.send_self_transfer_multi(
@@ -384,17 +384,17 @@ class MempoolAcceptV3(BitcoinTestFramework):
# Fails with another non-related transaction via testmempoolaccept
tx_unrelated = self.wallet.create_self_transfer(version=3)
result_test_unrelated = node.testmempoolaccept([tx_sibling_1["hex"], tx_unrelated["hex"]])
- assert_equal(result_test_unrelated[0]["reject-reason"], "v3-rule-violation")
+ assert_equal(result_test_unrelated[0]["reject-reason"], "TRUC-violation")
# Fails in a package via testmempoolaccept
result_test_1p1c = node.testmempoolaccept([tx_sibling_1["hex"], tx_has_mempool_uncle["hex"]])
- assert_equal(result_test_1p1c[0]["reject-reason"], "v3-rule-violation")
+ assert_equal(result_test_1p1c[0]["reject-reason"], "TRUC-violation")
# Allowed when tx is submitted in a package and evaluated individually.
# Note that the child failed since it would be the 3rd generation.
result_package_indiv = node.submitpackage([tx_sibling_1["hex"], tx_has_mempool_uncle["hex"]])
self.check_mempool([tx_mempool_parent["txid"], tx_sibling_1["txid"]])
- expected_error_gen3 = f"v3-rule-violation, tx {tx_has_mempool_uncle['txid']} (wtxid={tx_has_mempool_uncle['wtxid']}) would have too many ancestors"
+ expected_error_gen3 = f"TRUC-violation, tx {tx_has_mempool_uncle['txid']} (wtxid={tx_has_mempool_uncle['wtxid']}) would have too many ancestors"
assert_equal(result_package_indiv["tx-results"][tx_has_mempool_uncle['wtxid']]['error'], expected_error_gen3)
@@ -402,17 +402,17 @@ class MempoolAcceptV3(BitcoinTestFramework):
node.submitpackage([tx_mempool_parent["hex"], tx_sibling_2["hex"]])
self.check_mempool([tx_mempool_parent["txid"], tx_sibling_2["txid"]])
- # Child cannot pay for sibling eviction for parent, as it violates v3 topology limits
+ # Child cannot pay for sibling eviction for parent, as it violates TRUC topology limits
result_package_cpfp = node.submitpackage([tx_sibling_3["hex"], tx_bumps_parent_with_sibling["hex"]])
self.check_mempool([tx_mempool_parent["txid"], tx_sibling_2["txid"]])
- expected_error_cpfp = f"v3-rule-violation, tx {tx_mempool_parent['txid']} (wtxid={tx_mempool_parent['wtxid']}) would exceed descendant count limit"
+ expected_error_cpfp = f"TRUC-violation, tx {tx_mempool_parent['txid']} (wtxid={tx_mempool_parent['wtxid']}) would exceed descendant count limit"
assert_equal(result_package_cpfp["tx-results"][tx_sibling_3['wtxid']]['error'], expected_error_cpfp)
@cleanup(extra_args=["-datacarriersize=1000"])
- def test_v3_package_inheritance(self):
- self.log.info("Test that v3 inheritance is checked within package")
+ def test_truc_package_inheritance(self):
+ self.log.info("Test that TRUC inheritance is checked within package")
node = self.nodes[0]
tx_v3_parent = self.wallet.create_self_transfer(
fee_rate=0,
@@ -426,14 +426,14 @@ class MempoolAcceptV3(BitcoinTestFramework):
)
self.check_mempool([])
result = node.submitpackage([tx_v3_parent["hex"], tx_v2_child["hex"]])
- assert_equal(result['package_msg'], f"v3-violation, non-v3 tx {tx_v2_child['txid']} (wtxid={tx_v2_child['wtxid']}) cannot spend from v3 tx {tx_v3_parent['txid']} (wtxid={tx_v3_parent['wtxid']})")
+ assert_equal(result['package_msg'], f"TRUC-violation, non-version=3 tx {tx_v2_child['txid']} (wtxid={tx_v2_child['wtxid']}) cannot spend from version=3 tx {tx_v3_parent['txid']} (wtxid={tx_v3_parent['wtxid']})")
self.check_mempool([])
@cleanup(extra_args=None)
- def test_v3_in_testmempoolaccept(self):
+ def test_truc_in_testmempoolaccept(self):
node = self.nodes[0]
- self.log.info("Test that v3 inheritance is accurately assessed in testmempoolaccept")
+ self.log.info("Test that TRUC inheritance is accurately assessed in testmempoolaccept")
tx_v2 = self.wallet.create_self_transfer(version=2)
tx_v2_from_v2 = self.wallet.create_self_transfer(utxo_to_spend=tx_v2["new_utxo"], version=2)
tx_v3_from_v2 = self.wallet.create_self_transfer(utxo_to_spend=tx_v2["new_utxo"], version=3)
@@ -447,11 +447,11 @@ class MempoolAcceptV3(BitcoinTestFramework):
assert all([result["allowed"] for result in test_accept_v2_and_v3])
test_accept_v3_from_v2 = node.testmempoolaccept([tx_v2["hex"], tx_v3_from_v2["hex"]])
- expected_error_v3_from_v2 = f"v3-violation, v3 tx {tx_v3_from_v2['txid']} (wtxid={tx_v3_from_v2['wtxid']}) cannot spend from non-v3 tx {tx_v2['txid']} (wtxid={tx_v2['wtxid']})"
+ expected_error_v3_from_v2 = f"TRUC-violation, version=3 tx {tx_v3_from_v2['txid']} (wtxid={tx_v3_from_v2['wtxid']}) cannot spend from non-version=3 tx {tx_v2['txid']} (wtxid={tx_v2['wtxid']})"
assert all([result["package-error"] == expected_error_v3_from_v2 for result in test_accept_v3_from_v2])
test_accept_v2_from_v3 = node.testmempoolaccept([tx_v3["hex"], tx_v2_from_v3["hex"]])
- expected_error_v2_from_v3 = f"v3-violation, non-v3 tx {tx_v2_from_v3['txid']} (wtxid={tx_v2_from_v3['wtxid']}) cannot spend from v3 tx {tx_v3['txid']} (wtxid={tx_v3['wtxid']})"
+ expected_error_v2_from_v3 = f"TRUC-violation, non-version=3 tx {tx_v2_from_v3['txid']} (wtxid={tx_v2_from_v3['wtxid']}) cannot spend from version=3 tx {tx_v3['txid']} (wtxid={tx_v3['wtxid']})"
assert all([result["package-error"] == expected_error_v2_from_v3 for result in test_accept_v2_from_v3])
test_accept_pairs = node.testmempoolaccept([tx_v2["hex"], tx_v3["hex"], tx_v2_from_v2["hex"], tx_v3_from_v3["hex"]])
@@ -463,16 +463,16 @@ class MempoolAcceptV3(BitcoinTestFramework):
tx_v3_child_1 = self.wallet.create_self_transfer(utxo_to_spend=tx_v3_parent["new_utxos"][0], version=3)
tx_v3_child_2 = self.wallet.create_self_transfer(utxo_to_spend=tx_v3_parent["new_utxos"][1], version=3)
test_accept_2children = node.testmempoolaccept([tx_v3_parent["hex"], tx_v3_child_1["hex"], tx_v3_child_2["hex"]])
- expected_error_2children = f"v3-violation, tx {tx_v3_parent['txid']} (wtxid={tx_v3_parent['wtxid']}) would exceed descendant count limit"
+ expected_error_2children = f"TRUC-violation, tx {tx_v3_parent['txid']} (wtxid={tx_v3_parent['wtxid']}) would exceed descendant count limit"
assert all([result["package-error"] == expected_error_2children for result in test_accept_2children])
- # Extra v3 transaction does not get incorrectly marked as extra descendant
+ # Extra TRUC transaction does not get incorrectly marked as extra descendant
test_accept_1child_with_exra = node.testmempoolaccept([tx_v3_parent["hex"], tx_v3_child_1["hex"], tx_v3_independent["hex"]])
assert all([result["allowed"] for result in test_accept_1child_with_exra])
- # Extra v3 transaction does not make us ignore the extra descendant
+ # Extra TRUC transaction does not make us ignore the extra descendant
test_accept_2children_with_exra = node.testmempoolaccept([tx_v3_parent["hex"], tx_v3_child_1["hex"], tx_v3_child_2["hex"], tx_v3_independent["hex"]])
- expected_error_extra = f"v3-violation, tx {tx_v3_parent['txid']} (wtxid={tx_v3_parent['wtxid']}) would exceed descendant count limit"
+ expected_error_extra = f"TRUC-violation, tx {tx_v3_parent['txid']} (wtxid={tx_v3_parent['wtxid']}) would exceed descendant count limit"
assert all([result["package-error"] == expected_error_extra for result in test_accept_2children_with_exra])
# Same result if the parent is already in mempool
node.sendrawtransaction(tx_v3_parent["hex"])
@@ -482,7 +482,7 @@ class MempoolAcceptV3(BitcoinTestFramework):
@cleanup(extra_args=None)
def test_reorg_2child_rbf(self):
node = self.nodes[0]
- self.log.info("Test that children of a v3 transaction can be replaced individually, even if there are multiple due to reorg")
+ self.log.info("Test that children of a TRUC transaction can be replaced individually, even if there are multiple due to reorg")
ancestor_tx = self.wallet.send_self_transfer_multi(from_node=node, num_outputs=2, version=3)
self.check_mempool([ancestor_tx["txid"]])
@@ -511,8 +511,8 @@ class MempoolAcceptV3(BitcoinTestFramework):
assert_equal(node.getmempoolentry(ancestor_tx["txid"])["descendantcount"], 3)
@cleanup(extra_args=None)
- def test_v3_sibling_eviction(self):
- self.log.info("Test sibling eviction for v3")
+ def test_truc_sibling_eviction(self):
+ self.log.info("Test sibling eviction for TRUC")
node = self.nodes[0]
tx_v3_parent = self.wallet.send_self_transfer_multi(from_node=node, num_outputs=2, version=3)
# This is the sibling to replace
@@ -609,7 +609,7 @@ class MempoolAcceptV3(BitcoinTestFramework):
utxo_to_spend=tx_with_multi_children["new_utxos"][2],
fee_rate=DEFAULT_FEE*50
)
- expected_error_2siblings = f"v3-rule-violation, tx {tx_with_multi_children['txid']} (wtxid={tx_with_multi_children['wtxid']}) would exceed descendant count limit"
+ expected_error_2siblings = f"TRUC-violation, tx {tx_with_multi_children['txid']} (wtxid={tx_with_multi_children['wtxid']}) would exceed descendant count limit"
assert_raises_rpc_error(-26, expected_error_2siblings, node.sendrawtransaction, tx_with_sibling3["hex"])
# However, an RBF (with conflicting inputs) is possible even if the resulting cluster size exceeds 2
@@ -627,21 +627,21 @@ class MempoolAcceptV3(BitcoinTestFramework):
node = self.nodes[0]
self.wallet = MiniWallet(node)
self.generate(self.wallet, 120)
- self.test_v3_max_vsize()
- self.test_v3_acceptance()
- self.test_v3_replacement()
- self.test_v3_bip125()
- self.test_v3_reorg()
+ self.test_truc_max_vsize()
+ self.test_truc_acceptance()
+ self.test_truc_replacement()
+ self.test_truc_bip125()
+ self.test_truc_reorg()
self.test_nondefault_package_limits()
- self.test_v3_ancestors_package()
- self.test_v3_ancestors_package_and_mempool()
+ self.test_truc_ancestors_package()
+ self.test_truc_ancestors_package_and_mempool()
self.test_sibling_eviction_package()
- self.test_v3_package_inheritance()
- self.test_v3_in_testmempoolaccept()
+ self.test_truc_package_inheritance()
+ self.test_truc_in_testmempoolaccept()
self.test_reorg_2child_rbf()
- self.test_v3_sibling_eviction()
+ self.test_truc_sibling_eviction()
self.test_reorg_sibling_eviction_1p2c()
if __name__ == "__main__":
- MempoolAcceptV3().main()
+ MempoolTRUC().main()
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 8475dc5faa..a55e45fa15 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -266,7 +266,7 @@ BASE_SCRIPTS = [
'p2p_v2_encrypted.py',
'p2p_v2_earlykeyresponse.py',
'example_test.py',
- 'mempool_accept_v3.py',
+ 'mempool_truc.py',
'wallet_txn_doublespend.py --legacy-wallet',
'wallet_multisig_descriptor_psbt.py --descriptors',
'wallet_txn_doublespend.py --descriptors',
diff --git a/test/functional/wallet_create_tx.py b/test/functional/wallet_create_tx.py
index fa3e920c25..41ddb2bc69 100755
--- a/test/functional/wallet_create_tx.py
+++ b/test/functional/wallet_create_tx.py
@@ -114,16 +114,16 @@ class CreateTxWalletTest(BitcoinTestFramework):
self.log.info('Check wallet does not create transactions with version=3 yet')
wallet_rpc = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
- self.nodes[0].createwallet("v3")
- wallet_v3 = self.nodes[0].get_wallet_rpc("v3")
+ self.nodes[0].createwallet("version3")
+ wallet_v3 = self.nodes[0].get_wallet_rpc("version3")
tx_data = wallet_rpc.send(outputs=[{wallet_v3.getnewaddress(): 25}], options={"change_position": 0})
wallet_tx_data = wallet_rpc.gettransaction(tx_data["txid"])
tx_current_version = tx_from_hex(wallet_tx_data["hex"])
- # While v3 transactions are standard, the CURRENT_VERSION is 2.
+ # While version=3 transactions are standard, the CURRENT_VERSION is 2.
# This test can be removed if CURRENT_VERSION is changed, and replaced with tests that the
- # wallet handles v3 rules properly.
+ # wallet handles TRUC rules properly.
assert_equal(tx_current_version.version, 2)
wallet_v3.unloadwallet()