Merge bitcoin/bitcoin#30300: fuzz: have package_rbf always make small txns

4ccb3d6d0d576d32da8a1b9c6e70962cbd0f19fe fuzz: have package_rbf always make small txns (Greg Sanders)

Pull request description:

  hopefully resolves https://github.com/bitcoin/bitcoin/issues/30241

  The fuzz target is generating a large amount of
  transactions, but the core of the logic is
  ConsumeTxMemPoolEntry making the mempool
  entries for adding to the mempool. Since
  ConsumeTxMemPoolEntry generates its own transaction "vsize",
  we can improve efficiency of the target
  by explicitly creating very small transactions,
  reducing the hashing and memory burden.

ACKs for top commit:
  maflcko:
    lgtm ACK 4ccb3d6d0d576d32da8a1b9c6e70962cbd0f19fe
  hodlinator:
    ACK 4ccb3d6d0d576d32da8a1b9c6e70962cbd0f19fe
  glozow:
    ACK 4ccb3d6d0d576d32da8a1b9c6e70962cbd0f19fe

Tree-SHA512: 5d2e7e98460c6144dfe7deac554865e2e8e0e5f934dbdf5857dc4b4f471a64dc933297dc0dcf516f748a4348be6bd184808b7ece17ce073fdcc77f81b74c64de
This commit is contained in:
glozow 2024-06-19 12:36:30 +01:00
commit 2d21060af8
No known key found for this signature in database
GPG Key ID: BA03F4DBE0C63FB4

View File

@ -91,8 +91,10 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf)
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider));
std::optional<CMutableTransaction> child = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
if (!child) return;
// "Real" virtual size is not important for this test since ConsumeTxMemPoolEntry generates its own virtual size values
// so we construct small transactions for performance reasons. Child simply needs an input for later to perhaps connect to parent.
CMutableTransaction child;
child.vin.resize(1);
bilingual_str error;
CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node), error};
@ -113,15 +115,13 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf)
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), NUM_ITERS)
{
// Make sure txns only have one input, and that a unique input is given to avoid circular references
std::optional<CMutableTransaction> parent = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
if (!parent) {
return;
}
CMutableTransaction parent;
assert(iter <= g_outpoints.size());
parent->vin.resize(1);
parent->vin[0].prevout = g_outpoints[iter++];
parent.vin.resize(1);
parent.vin[0].prevout = g_outpoints[iter++];
parent.vout.emplace_back(0, CScript());
mempool_txs.emplace_back(*parent);
mempool_txs.emplace_back(parent);
const auto parent_entry = ConsumeTxMemPoolEntry(fuzzed_data_provider, mempool_txs.back());
running_vsize_total += parent_entry.GetTxSize();
if (running_vsize_total > std::numeric_limits<int32_t>::max()) {
@ -130,10 +130,10 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf)
break;
}
pool.addUnchecked(parent_entry);
if (fuzzed_data_provider.ConsumeBool() && !child->vin.empty()) {
child->vin[0].prevout = COutPoint{mempool_txs.back().GetHash(), 0};
if (fuzzed_data_provider.ConsumeBool()) {
child.vin[0].prevout = COutPoint{mempool_txs.back().GetHash(), 0};
}
mempool_txs.emplace_back(*child);
mempool_txs.emplace_back(child);
const auto child_entry = ConsumeTxMemPoolEntry(fuzzed_data_provider, mempool_txs.back());
running_vsize_total += child_entry.GetTxSize();
if (running_vsize_total > std::numeric_limits<int32_t>::max()) {