From 7976eb1ae77af2c88e1e61e85d4a61390b34b986 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 4 Feb 2025 15:03:25 -0500 Subject: [PATCH] Avoid violating mempool policy limits in tests Changes AddToMempool() helper to only apply changes if the mempool limits are respected. Fix package_rbf fuzz target to handle mempool policy violations --- src/test/fuzz/rbf.cpp | 24 +++++++++++++++++++----- src/test/util/txmempool.cpp | 2 +- src/test/util/txmempool.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/test/fuzz/rbf.cpp b/src/test/fuzz/rbf.cpp index 2ca57341533..02ec3cb0e8a 100644 --- a/src/test/fuzz/rbf.cpp +++ b/src/test/fuzz/rbf.cpp @@ -120,8 +120,8 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf) replacement_tx->vin[0].prevout = g_outpoints.at(iter++); CTransaction replacement_tx_final{*replacement_tx}; auto replacement_entry = ConsumeTxMemPoolEntry(fuzzed_data_provider, replacement_tx_final); - int32_t replacement_vsize = replacement_entry.GetTxSize(); - int64_t running_vsize_total{replacement_vsize}; + int32_t replacement_weight = replacement_entry.GetAdjustedWeight(); + int64_t running_vsize_total{replacement_entry.GetTxSize()}; LOCK2(cs_main, pool.cs); @@ -144,6 +144,14 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf) } assert(!pool.GetIter(parent_entry.GetTx().GetHash())); AddToMempool(pool, parent_entry); + + // It's possible that adding this to the mempool failed due to cluster + // size limits; if so bail out. + if(!pool.GetIter(parent_entry.GetTx().GetHash())) { + mempool_txs.pop_back(); + continue; + } + child.vin[0].prevout = COutPoint{mempool_txs.back().GetHash(), 0}; mempool_txs.emplace_back(child); const auto child_entry = ConsumeTxMemPoolEntry(fuzzed_data_provider, mempool_txs.back()); @@ -155,6 +163,12 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf) } if (!pool.GetIter(child_entry.GetTx().GetHash())) { AddToMempool(pool, child_entry); + // Adding this transaction to the mempool may fail due to cluster + // size limits; if so bail out. + if(!pool.GetIter(child_entry.GetTx().GetHash())) { + mempool_txs.pop_back(); + continue; + } } if (fuzzed_data_provider.ConsumeBool()) { @@ -165,7 +179,7 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf) // Pick some transactions at random to be the direct conflicts CTxMemPool::setEntries direct_conflicts; for (auto& tx : mempool_txs) { - if (fuzzed_data_provider.ConsumeBool()) { + if (fuzzed_data_provider.ConsumeBool() && pool.GetIter(tx.GetHash())) { direct_conflicts.insert(*pool.GetIter(tx.GetHash())); } } @@ -206,11 +220,11 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf) FeeFrac replaced; for (auto txiter : all_conflicts) { replaced.fee += txiter->GetModifiedFee(); - replaced.size += txiter->GetTxSize(); + replaced.size += txiter->GetAdjustedWeight(); } // The total fee & size of the new diagram minus replaced fee & size should be the total // fee & size of the old diagram minus replacement fee & size. - assert((first_sum - replaced) == (second_sum - FeeFrac{replacement_fees, replacement_vsize})); + assert((first_sum - replaced) == (second_sum - FeeFrac{replacement_fees, replacement_weight})); } // If internals report error, wrapper should too diff --git a/src/test/util/txmempool.cpp b/src/test/util/txmempool.cpp index e85c496d01b..980621dee03 100644 --- a/src/test/util/txmempool.cpp +++ b/src/test/util/txmempool.cpp @@ -218,5 +218,5 @@ void AddToMempool(CTxMemPool& tx_pool, const CTxMemPoolEntry& entry) changeset->StageAddition(entry.GetSharedTx(), entry.GetFee(), entry.GetTime().count(), entry.GetHeight(), entry.GetSequence(), entry.GetSpendsCoinbase(), entry.GetSigOpCost(), entry.GetLockPoints()); - changeset->Apply(); + if (changeset->CheckMemPoolPolicyLimits()) changeset->Apply(); } diff --git a/src/test/util/txmempool.h b/src/test/util/txmempool.h index 36caad2ae1a..2ed498a9ec5 100644 --- a/src/test/util/txmempool.h +++ b/src/test/util/txmempool.h @@ -64,7 +64,7 @@ void CheckMempoolEphemeralInvariants(const CTxMemPool& tx_pool); void CheckMempoolTRUCInvariants(const CTxMemPool& tx_pool); /** One-line wrapper for creating a mempool changeset with a single transaction - * and applying it. */ + * and applying it if the policy limits are respected. */ void AddToMempool(CTxMemPool& tx_pool, const CTxMemPoolEntry& entry); #endif // BITCOIN_TEST_UTIL_TXMEMPOOL_H