fuzz: remove comparison between mini_miner block construction and miner
After cluster mempool, the mini_miner will no longer match the miner's block construction. Eventually mini_miner should be reworked to directly use linearizations done in the mempool.
This commit is contained in:
1 parent
6c2bceb200
commit
dec138d1dd
1 file changed
-91
@@ -116,95 +116,4 @@ FUZZ_TARGET(mini_miner, .init = initialize_miner)
|
|||||||
// Overlapping ancestry across multiple outpoints can only reduce the total bump fee.
|
// Overlapping ancestry across multiple outpoints can only reduce the total bump fee.
|
||||||
assert (sum_fees >= *total_bumpfee);
|
assert (sum_fees >= *total_bumpfee);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that MiniMiner and BlockAssembler build the same block given the same transactions and constraints.
|
|
||||||
FUZZ_TARGET(mini_miner_selection, .init = initialize_miner)
|
|
||||||
{
|
|
||||||
SeedRandomStateForTest(SeedRand::ZEROS);
|
|
||||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
|
||||||
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
|
||||||
bilingual_str error;
|
|
||||||
CTxMemPool pool{CTxMemPool::Options{}, error};
|
|
||||||
Assert(error.empty());
|
|
||||||
// Make a copy to preserve determinism.
|
|
||||||
std::deque<COutPoint> available_coins = g_available_coins;
|
|
||||||
std::vector<CTransactionRef> transactions;
|
|
||||||
|
|
||||||
LOCK2(::cs_main, pool.cs);
|
|
||||||
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 100)
|
|
||||||
{
|
|
||||||
CMutableTransaction mtx = CMutableTransaction();
|
|
||||||
assert(!available_coins.empty());
|
|
||||||
const size_t num_inputs = std::min(size_t{2}, available_coins.size());
|
|
||||||
const size_t num_outputs = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(2, 5);
|
|
||||||
for (size_t n{0}; n < num_inputs; ++n) {
|
|
||||||
auto prevout = available_coins.at(0);
|
|
||||||
mtx.vin.emplace_back(prevout, CScript());
|
|
||||||
available_coins.pop_front();
|
|
||||||
}
|
|
||||||
for (uint32_t n{0}; n < num_outputs; ++n) {
|
|
||||||
mtx.vout.emplace_back(100, P2WSH_OP_TRUE);
|
|
||||||
}
|
|
||||||
CTransactionRef tx = MakeTransactionRef(mtx);
|
|
||||||
|
|
||||||
// First 2 outputs are available to spend. The rest are added to outpoints to calculate bumpfees.
|
|
||||||
// There is no overlap between spendable coins and outpoints passed to MiniMiner because the
|
|
||||||
// MiniMiner interprets spent coins as to-be-replaced and excludes them.
|
|
||||||
for (uint32_t n{0}; n < num_outputs - 1; ++n) {
|
|
||||||
if (fuzzed_data_provider.ConsumeBool()) {
|
|
||||||
available_coins.emplace_front(tx->GetHash(), n);
|
|
||||||
} else {
|
|
||||||
available_coins.emplace_back(tx->GetHash(), n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto block_adjusted_max_weight = MAX_BLOCK_WEIGHT - DEFAULT_BLOCK_RESERVED_WEIGHT;
|
|
||||||
// Stop if pool reaches block_adjusted_max_weight because BlockAssembler will stop when the
|
|
||||||
// block template reaches that, but the MiniMiner will keep going.
|
|
||||||
if (pool.GetTotalTxSize() + GetVirtualTransactionSize(*tx) >= block_adjusted_max_weight) break;
|
|
||||||
TestMemPoolEntryHelper entry;
|
|
||||||
const CAmount fee{ConsumeMoney(fuzzed_data_provider, /*max=*/MAX_MONEY/100000)};
|
|
||||||
assert(MoneyRange(fee));
|
|
||||||
AddToMempool(pool, entry.Fee(fee).FromTx(tx));
|
|
||||||
transactions.push_back(tx);
|
|
||||||
}
|
|
||||||
std::vector<COutPoint> outpoints;
|
|
||||||
for (const auto& coin : g_available_coins) {
|
|
||||||
if (!pool.GetConflictTx(coin)) outpoints.push_back(coin);
|
|
||||||
}
|
|
||||||
for (const auto& tx : transactions) {
|
|
||||||
assert(pool.exists(tx->GetHash()));
|
|
||||||
for (uint32_t n{0}; n < tx->vout.size(); ++n) {
|
|
||||||
COutPoint coin{tx->GetHash(), n};
|
|
||||||
if (!pool.GetConflictTx(coin)) outpoints.push_back(coin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const CFeeRate target_feerate{ConsumeMoney(fuzzed_data_provider, /*max=*/MAX_MONEY/100000)};
|
|
||||||
|
|
||||||
node::BlockAssembler::Options miner_options;
|
|
||||||
miner_options.blockMinFeeRate = target_feerate;
|
|
||||||
miner_options.nBlockMaxWeight = MAX_BLOCK_WEIGHT;
|
|
||||||
miner_options.test_block_validity = false;
|
|
||||||
miner_options.coinbase_output_script = CScript() << OP_0;
|
|
||||||
|
|
||||||
node::BlockAssembler miner{g_setup->m_node.chainman->ActiveChainstate(), &pool, miner_options};
|
|
||||||
node::MiniMiner mini_miner{pool, outpoints};
|
|
||||||
assert(mini_miner.IsReadyToCalculate());
|
|
||||||
|
|
||||||
// Use BlockAssembler as oracle. BlockAssembler and MiniMiner should select the same
|
|
||||||
// transactions, stopping once packages do not meet target_feerate.
|
|
||||||
const auto blocktemplate{miner.CreateNewBlock()};
|
|
||||||
mini_miner.BuildMockTemplate(target_feerate);
|
|
||||||
assert(!mini_miner.IsReadyToCalculate());
|
|
||||||
auto mock_template_txids = mini_miner.GetMockTemplateTxids();
|
|
||||||
// MiniMiner doesn't add a coinbase tx.
|
|
||||||
assert(mock_template_txids.count(blocktemplate->block.vtx[0]->GetHash()) == 0);
|
|
||||||
auto [iter, new_entry] = mock_template_txids.emplace(blocktemplate->block.vtx[0]->GetHash());
|
|
||||||
assert(new_entry);
|
|
||||||
|
|
||||||
assert(mock_template_txids.size() == blocktemplate->block.vtx.size());
|
|
||||||
for (const auto& tx : blocktemplate->block.vtx) {
|
|
||||||
assert(mock_template_txids.count(tx->GetHash()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace
|
} // namespace
|
||||||
Reference in new issue
Block a user