test: move MockMempoolMinFee to util/txmempool
What changed, and why it matters
This is a harmless code cleanup in Bitcoin Core's test suite. A helper function used only by tests is being moved from one internal test file to another so it can be reused more easily. It does not change how the live Bitcoin network works and is not a security fix.
No action required. This is a non-security test refactor.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors MockMempoolMinFee, a test-only utility that artificially sets a mempool’s minimum feerate by staging a fake transaction and trimming the mempool. The function is moved from TestChain100Setup (src/test/util/setup_common.{cpp,h}) to the general mempool test utilities (src/test/util/txmempool.{cpp,h}). Callers are updated to pass the mempool explicitly. The implementation is essentially unchanged except for using a fixed deterministic uint256{123} instead of a random outpoint. This change is purely test infrastructure and does not touch consensus, networking, or production mempool policy.
Changed components
src/test/util/setup_common.cppsrc/test/util/setup_common.hsrc/test/util/txmempool.cppsrc/test/util/txmempool.hsrc/test/txpackage_tests.cppInspect captured patch +52 / −48
diff --git a/src/test/txpackage_tests.cpp b/src/test/txpackage_tests.cpp
index 1f167586..ded13c4c 100644
--- a/src/test/txpackage_tests.cpp
+++ b/src/test/txpackage_tests.cpp
@@ -357,7 +357,7 @@ BOOST_AUTO_TEST_CASE(package_submission_tests)
{
// Mine blocks to mature coinbases.
mineBlocks(3);
- MockMempoolMinFee(CFeeRate(5000));
+ MockMempoolMinFee(CFeeRate(5000), *m_node.mempool);
LOCK(cs_main);
unsigned int expected_pool_size = m_node.mempool->size();
CKey parent_key = GenerateRandomKey();
@@ -634,7 +634,7 @@ BOOST_AUTO_TEST_CASE(package_witness_swap_tests)
{
// Mine blocks to mature coinbases.
mineBlocks(5);
- MockMempoolMinFee(CFeeRate(5000));
+ MockMempoolMinFee(CFeeRate(5000), *m_node.mempool);
LOCK(cs_main);
// Transactions with a same-txid-different-witness transaction in the mempool should be ignored,
@@ -867,7 +867,7 @@ BOOST_AUTO_TEST_CASE(package_witness_swap_tests)
BOOST_AUTO_TEST_CASE(package_cpfp_tests)
{
mineBlocks(5);
- MockMempoolMinFee(CFeeRate(5000));
+ MockMempoolMinFee(CFeeRate(5000), *m_node.mempool);
LOCK(::cs_main);
size_t expected_pool_size = m_node.mempool->size();
CKey child_key = GenerateRandomKey();
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index 8ce0a0db..baedcf0b 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -571,40 +571,6 @@ std::vector<CTransactionRef> TestChain100Setup::PopulateMempool(FastRandomContex
return mempool_transactions;
}
-void TestChain100Setup::MockMempoolMinFee(const CFeeRate& target_feerate)
-{
- LOCK2(cs_main, m_node.mempool->cs);
- // Transactions in the mempool will affect the new minimum feerate.
- assert(m_node.mempool->size() == 0);
- // The target feerate cannot be too low...
- // ...otherwise the transaction's feerate will need to be negative.
- assert(target_feerate > m_node.mempool->m_opts.incremental_relay_feerate);
- // ...otherwise this is not meaningful. The feerate policy uses the maximum of both feerates.
- assert(target_feerate > m_node.mempool->m_opts.min_relay_feerate);
-
- // Manually create an invalid transaction. Manually set the fee in the CTxMemPoolEntry to
- // achieve the exact target feerate.
- CMutableTransaction mtx = CMutableTransaction();
- mtx.vin.emplace_back(COutPoint{Txid::FromUint256(m_rng.rand256()), 0});
- mtx.vout.emplace_back(1 * COIN, GetScriptForDestination(WitnessV0ScriptHash(CScript() << OP_TRUE)));
- // Set a large size so that the fee evaluated at target_feerate (which is usually in sats/kvB) is an integer.
- // Otherwise, GetMinFee() may end up slightly different from target_feerate.
- BulkTransaction(mtx, 4000);
- const auto tx{MakeTransactionRef(mtx)};
- LockPoints lp;
- // The new mempool min feerate is equal to the removed package's feerate + incremental feerate.
- const auto tx_fee = target_feerate.GetFee(GetVirtualTransactionSize(*tx)) -
- m_node.mempool->m_opts.incremental_relay_feerate.GetFee(GetVirtualTransactionSize(*tx));
- {
- auto changeset = m_node.mempool->GetChangeSet();
- changeset->StageAddition(tx, /*fee=*/tx_fee,
- /*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0,
- /*spends_coinbase=*/true, /*sigops_cost=*/1, lp);
- changeset->Apply();
- }
- m_node.mempool->TrimToSize(0);
- assert(m_node.mempool->GetMinFee() == target_feerate);
-}
/**
* @returns a real block (0000000000013b8ab2cd513b0261a14096412195a72a0c4827d229dcc7e0f7af)
* with 9 txs.
diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h
index 150f5065..fdb0951e 100644
--- a/src/test/util/setup_common.h
+++ b/src/test/util/setup_common.h
@@ -238,17 +238,6 @@ struct TestChain100Setup : public TestingSetup {
*/
std::vector<CTransactionRef> PopulateMempool(FastRandomContext& det_rand, size_t num_transactions, bool submit);
- /** Mock the mempool minimum feerate by adding a transaction and calling TrimToSize(0),
- * simulating the mempool "reaching capacity" and evicting by descendant feerate. Note that
- * this clears the mempool, and the new minimum feerate will depend on the maximum feerate of
- * transactions removed, so this must be called while the mempool is empty.
- *
- * @param target_feerate The new mempool minimum feerate after this function returns.
- * Must be above max(incremental feerate, min relay feerate),
- * or 1sat/vB with default settings.
- */
- void MockMempoolMinFee(const CFeeRate& target_feerate);
-
std::vector<CTransactionRef> m_coinbase_txns; // For convenience, coinbase transactions
CKey coinbaseKey; // private/public key needed to spend coinbase transactions
};
diff --git a/src/test/util/txmempool.cpp b/src/test/util/txmempool.cpp
index 5febb679..441cdbb2 100644
--- a/src/test/util/txmempool.cpp
+++ b/src/test/util/txmempool.cpp
@@ -10,6 +10,7 @@
#include <policy/rbf.h>
#include <policy/truc_policy.h>
#include <txmempool.h>
+#include <test/util/transaction_utils.h>
#include <util/check.h>
#include <util/time.h>
#include <util/translation.h>
@@ -218,3 +219,38 @@ void AddToMempool(CTxMemPool& tx_pool, const CTxMemPoolEntry& entry)
entry.GetSpendsCoinbase(), entry.GetSigOpCost(), entry.GetLockPoints());
changeset->Apply();
}
+
+void MockMempoolMinFee(const CFeeRate& target_feerate, CTxMemPool& mempool)
+{
+ LOCK2(cs_main, mempool.cs);
+ // Transactions in the mempool will affect the new minimum feerate.
+ assert(mempool.size() == 0);
+ // The target feerate cannot be too low...
+ // ...otherwise the transaction's feerate will need to be negative.
+ assert(target_feerate > mempool.m_opts.incremental_relay_feerate);
+ // ...otherwise this is not meaningful. The feerate policy uses the maximum of both feerates.
+ assert(target_feerate > mempool.m_opts.min_relay_feerate);
+
+ // Manually create an invalid transaction. Manually set the fee in the CTxMemPoolEntry to
+ // achieve the exact target feerate.
+ CMutableTransaction mtx{};
+ mtx.vin.emplace_back(COutPoint{Txid::FromUint256(uint256{123}), 0});
+ mtx.vout.emplace_back(1 * COIN, GetScriptForDestination(WitnessV0ScriptHash(CScript() << OP_TRUE)));
+ // Set a large size so that the fee evaluated at target_feerate (which is usually in sats/kvB) is an integer.
+ // Otherwise, GetMinFee() may end up slightly different from target_feerate.
+ BulkTransaction(mtx, 4000);
+ const auto tx{MakeTransactionRef(mtx)};
+ LockPoints lp;
+ // The new mempool min feerate is equal to the removed package's feerate + incremental feerate.
+ const auto tx_fee = target_feerate.GetFee(GetVirtualTransactionSize(*tx)) -
+ mempool.m_opts.incremental_relay_feerate.GetFee(GetVirtualTransactionSize(*tx));
+ {
+ auto changeset = mempool.GetChangeSet();
+ changeset->StageAddition(tx, /*fee=*/tx_fee,
+ /*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0,
+ /*spends_coinbase=*/true, /*sigops_cost=*/1, lp);
+ changeset->Apply();
+ }
+ mempool.TrimToSize(0);
+ assert(mempool.GetMinFee() == target_feerate);
+}
diff --git a/src/test/util/txmempool.h b/src/test/util/txmempool.h
index 36caad2a..731b46a3 100644
--- a/src/test/util/txmempool.h
+++ b/src/test/util/txmempool.h
@@ -67,4 +67,17 @@ void CheckMempoolTRUCInvariants(const CTxMemPool& tx_pool);
* and applying it. */
void AddToMempool(CTxMemPool& tx_pool, const CTxMemPoolEntry& entry);
+/** Mock the mempool minimum feerate by adding a transaction and calling TrimToSize(0),
+ * simulating the mempool "reaching capacity" and evicting by descendant feerate. Note that
+ * this clears the mempool, and the new minimum feerate will depend on the maximum feerate of
+ * transactions removed, so this must be called while the mempool is empty.
+ *
+ * @param target_feerate The new mempool minimum feerate after this function returns.
+ * Must be above max(incremental feerate, min relay feerate),
+ * or 1sat/vB with default settings.
+ * @param mempool The mempool to mock the minimum feerate for. Must be empty
+ * when called.
+ */
+void MockMempoolMinFee(const CFeeRate& target_feerate, CTxMemPool& mempool);
+
#endif // BITCOIN_TEST_UTIL_TXMEMPOOL_H
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.