bench: rewrite ComplexMemPool to not create oversized clusters
What changed, and why it matters
This commit changes only a benchmark test file used to measure mempool performance. It rewrites how fake transactions are generated so the test creates many small independent groups instead of one huge interconnected cluster. There is no change to the actual Bitcoin network code that users run, so this cannot affect real funds, nodes, or network security.
No security action needed. Treat as a normal test-maintenance change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch modifies src/bench/mempool_stress.cpp. It renames CreateOrderedCoins to CreateCoinCluster, reduces the number of base transactions from 100 to 10, explicitly assigns a random previous output to each base transaction so clusters no longer share inputs, lowers childTxs from 800 to 50, and restructures ComplexMemPool to create 1000 separate clusters, add them to the mempool, then benchmark removeForBlock plus re-acceptance. This is purely a test/benchmark adjustment; no consensus, mempool policy, P2P, or wallet code is touched.
Changed components
src/bench/mempool_stress.cppInspect captured patch +33 / −7
diff --git a/src/bench/mempool_stress.cpp b/src/bench/mempool_stress.cpp
index 5095438c..49ff17c1 100644
--- a/src/bench/mempool_stress.cpp
+++ b/src/bench/mempool_stress.cpp
@@ -39,15 +39,17 @@ struct Available {
Available(CTransactionRef& ref, size_t tx_count) : ref(ref), tx_count(tx_count){}
};
-static std::vector<CTransactionRef> CreateOrderedCoins(FastRandomContext& det_rand, int childTxs, int min_ancestors)
+// Create a cluster of transactions, randomly.
+static std::vector<CTransactionRef> CreateCoinCluster(FastRandomContext& det_rand, int childTxs, int min_ancestors)
{
std::vector<Available> available_coins;
std::vector<CTransactionRef> ordered_coins;
// Create some base transactions
size_t tx_counter = 1;
- for (auto x = 0; x < 100; ++x) {
+ for (auto x = 0; x < 10; ++x) {
CMutableTransaction tx = CMutableTransaction();
tx.vin.resize(1);
+ tx.vin[0].prevout = COutPoint(Txid::FromUint256(GetRandHash()), 1);
tx.vin[0].scriptSig = CScript() << CScriptNum(tx_counter);
tx.vin[0].scriptWitness.stack.push_back(CScriptNum(x).getvch());
tx.vout.resize(det_rand.randrange(10)+2);
@@ -94,20 +96,44 @@ static std::vector<CTransactionRef> CreateOrderedCoins(FastRandomContext& det_ra
static void ComplexMemPool(benchmark::Bench& bench)
{
FastRandomContext det_rand{true};
- int childTxs = 800;
+ int childTxs = 50;
if (bench.complexityN() > 1) {
childTxs = static_cast<int>(bench.complexityN());
}
- std::vector<CTransactionRef> ordered_coins = CreateOrderedCoins(det_rand, childTxs, /*min_ancestors=*/1);
const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(ChainType::MAIN);
CTxMemPool& pool = *testing_setup.get()->m_node.mempool;
+
+ std::vector<CTransactionRef> tx_remove_for_block;
+ std::vector<Txid> hashes_remove_for_block;
+
LOCK2(cs_main, pool.cs);
+
+ for (int i=0; i<1000; i++) {
+ std::vector<CTransactionRef> transactions = CreateCoinCluster(det_rand, childTxs, /*min_ancestors=*/1);
+
+ // Add all transactions to the mempool.
+ // Also store the first 10 transactions from each cluster as the
+ // transactions we'll "mine" in the the benchmark.
+ int tx_count = 0;
+ for (auto& tx : transactions) {
+ if (tx_count < 10) {
+ tx_remove_for_block.push_back(tx);
+ ++tx_count;
+ hashes_remove_for_block.emplace_back(tx->GetHash());
+ }
+ AddTx(tx, pool);
+ }
+ }
+
+ // Since the benchmark will be run repeatedly, we have to leave the mempool
+ // in the same state at the end of the function, so we benchmark both
+ // mining a block and reorging the block's contents back into the mempool.
bench.run([&]() NO_THREAD_SAFETY_ANALYSIS {
- for (auto& tx : ordered_coins) {
+ pool.removeForBlock(tx_remove_for_block, /*nBlockHeight*/100);
+ for (auto& tx: tx_remove_for_block) {
AddTx(tx, pool);
}
- pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4);
- pool.TrimToSize(GetVirtualTransactionSize(*ordered_coins.front()));
+ pool.UpdateTransactionsFromBlock(hashes_remove_for_block);
});
}
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.