/
githubmirror
/
bitcoin
Обзор
Документация
Войти
/
githubmirror
/
bitcoin
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/test/fuzz/mini_miner.cpp
124 строки
5 KB
MarcoFalke
fuzz: clang-format LIMITED_WHILE
14 июл 2026, 14:48
14 июл 2026, 14:48
fab8eee
Код
Авторство
О чём код?
// Copyright (c) The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <node/mini_miner.h> #include <consensus/amount.h> #include <kernel/cs_main.h> #include <policy/feerate.h> #include <primitives/transaction.h> #include <script/script.h> #include <sync.h> #include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/fuzz.h> #include <test/fuzz/util.h> #include <test/util/script.h> #include <test/util/random.h> #include <test/util/setup_common.h> #include <test/util/time.h> #include <test/util/txmempool.h> #include <txmempool.h> #include <uint256.h> #include <util/check.h> #include <util/translation.h> #include <algorithm> #include <cstddef> #include <cstdint> #include <deque> #include <functional> #include <map> #include <optional> #include <utility> #include <vector> namespace { std::deque<COutPoint> g_available_coins; void initialize_miner() { static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(); for (uint32_t i = 0; i < uint32_t{100}; ++i) { g_available_coins.emplace_back(Txid::FromUint256(uint256::ZERO), i); } } // Test that the MiniMiner can run with various outpoints and feerates. FUZZ_TARGET(mini_miner, .init = initialize_miner) { SeedRandomStateForTest(SeedRand::ZEROS); FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FakeNodeClock clock{ConsumeTime(fuzzed_data_provider)}; bilingual_str error; CTxMemPool pool{CTxMemPool::Options{}, error}; Assert(error.empty()); std::vector<COutPoint> outpoints; std::deque<COutPoint> available_coins = g_available_coins; LOCK2(::cs_main, pool.cs); // Cluster size cannot exceed 500 LIMITED_WHILE (!available_coins.empty(), 100) { CMutableTransaction mtx = CMutableTransaction(); const size_t num_inputs = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, available_coins.size()); const size_t num_outputs = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 50); for (size_t n{0}; n < num_inputs; ++n) { auto prevout = available_coins.front(); 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); TestMemPoolEntryHelper entry; const CAmount fee{ConsumeMoney(fuzzed_data_provider, /*max=*/MAX_MONEY/100000)}; assert(MoneyRange(fee)); TryAddToMempool(pool, entry.Fee(fee).FromTx(tx)); // All outputs are available to spend for (uint32_t n{0}; n < num_outputs; ++n) { if (fuzzed_data_provider.ConsumeBool()) { available_coins.emplace_back(tx->GetHash(), n); } } if (fuzzed_data_provider.ConsumeBool() && !tx->vout.empty()) { // Add outpoint from this tx (may or not be spent by a later tx) outpoints.emplace_back(tx->GetHash(), (uint32_t)fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, tx->vout.size())); } else { // Add some random outpoint (will be interpreted as confirmed or not yet submitted // to mempool). auto outpoint = ConsumeDeserializable<COutPoint>(fuzzed_data_provider); if (outpoint.has_value() && std::find(outpoints.begin(), outpoints.end(), *outpoint) == outpoints.end()) { outpoints.push_back(*outpoint); } } } const CFeeRate target_feerate{CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/MAX_MONEY/1000)}}; std::optional<CAmount> total_bumpfee; CAmount sum_fees = 0; { node::MiniMiner mini_miner{pool, outpoints}; assert(mini_miner.IsReadyToCalculate()); const auto bump_fees = mini_miner.CalculateBumpFees(target_feerate); for (const auto& outpoint : outpoints) { auto it = bump_fees.find(outpoint); assert(it != bump_fees.end()); assert(it->second >= 0); sum_fees += it->second; } assert(!mini_miner.IsReadyToCalculate()); } { node::MiniMiner mini_miner{pool, outpoints}; assert(mini_miner.IsReadyToCalculate()); total_bumpfee = mini_miner.CalculateTotalBumpFees(target_feerate); assert(total_bumpfee.has_value()); assert(!mini_miner.IsReadyToCalculate()); } // Overlapping ancestry across multiple outpoints can only reduce the total bump fee. assert (sum_fees >= *total_bumpfee); } } // namespace