Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <node/mini_miner.h>7#include <consensus/amount.h>8#include <kernel/cs_main.h>9#include <policy/feerate.h>10#include <primitives/transaction.h>11#include <script/script.h>12#include <sync.h>13#include <test/fuzz/FuzzedDataProvider.h>14#include <test/fuzz/fuzz.h>15#include <test/fuzz/util.h>16#include <test/util/script.h>17#include <test/util/random.h>18#include <test/util/setup_common.h>19#include <test/util/time.h>20#include <test/util/txmempool.h>21#include <txmempool.h>22#include <uint256.h>23#include <util/check.h>24#include <util/translation.h>26#include <algorithm>27#include <cstddef>28#include <cstdint>29#include <deque>30#include <functional>31#include <map>32#include <optional>33#include <utility>34#include <vector>36namespace {38std::deque<COutPoint> g_available_coins;39void initialize_miner()40{41static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();42for (uint32_t i = 0; i < uint32_t{100}; ++i) {43g_available_coins.emplace_back(Txid::FromUint256(uint256::ZERO), i);44}45}47// Test that the MiniMiner can run with various outpoints and feerates.48FUZZ_TARGET(mini_miner, .init = initialize_miner)49{50SeedRandomStateForTest(SeedRand::ZEROS);51FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};52FakeNodeClock clock{ConsumeTime(fuzzed_data_provider)};53bilingual_str error;54CTxMemPool pool{CTxMemPool::Options{}, error};55Assert(error.empty());56std::vector<COutPoint> outpoints;57std::deque<COutPoint> available_coins = g_available_coins;58LOCK2(::cs_main, pool.cs);59// Cluster size cannot exceed 50060LIMITED_WHILE (!available_coins.empty(), 100) {61CMutableTransaction mtx = CMutableTransaction();62const size_t num_inputs = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, available_coins.size());63const size_t num_outputs = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 50);64for (size_t n{0}; n < num_inputs; ++n) {65auto prevout = available_coins.front();66mtx.vin.emplace_back(prevout, CScript());67available_coins.pop_front();68}69for (uint32_t n{0}; n < num_outputs; ++n) {70mtx.vout.emplace_back(100, P2WSH_OP_TRUE);71}72CTransactionRef tx = MakeTransactionRef(mtx);73TestMemPoolEntryHelper entry;74const CAmount fee{ConsumeMoney(fuzzed_data_provider, /*max=*/MAX_MONEY/100000)};75assert(MoneyRange(fee));76TryAddToMempool(pool, entry.Fee(fee).FromTx(tx));78// All outputs are available to spend79for (uint32_t n{0}; n < num_outputs; ++n) {80if (fuzzed_data_provider.ConsumeBool()) {81available_coins.emplace_back(tx->GetHash(), n);82}83}85if (fuzzed_data_provider.ConsumeBool() && !tx->vout.empty()) {86// Add outpoint from this tx (may or not be spent by a later tx)87outpoints.emplace_back(tx->GetHash(),88(uint32_t)fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, tx->vout.size()));89} else {90// Add some random outpoint (will be interpreted as confirmed or not yet submitted91// to mempool).92auto outpoint = ConsumeDeserializable<COutPoint>(fuzzed_data_provider);93if (outpoint.has_value() && std::find(outpoints.begin(), outpoints.end(), *outpoint) == outpoints.end()) {94outpoints.push_back(*outpoint);95}96}97}99const CFeeRate target_feerate{CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/MAX_MONEY/1000)}};100std::optional<CAmount> total_bumpfee;101CAmount sum_fees = 0;102{103node::MiniMiner mini_miner{pool, outpoints};104assert(mini_miner.IsReadyToCalculate());105const auto bump_fees = mini_miner.CalculateBumpFees(target_feerate);106for (const auto& outpoint : outpoints) {107auto it = bump_fees.find(outpoint);108assert(it != bump_fees.end());109assert(it->second >= 0);110sum_fees += it->second;111}112assert(!mini_miner.IsReadyToCalculate());113}114{115node::MiniMiner mini_miner{pool, outpoints};116assert(mini_miner.IsReadyToCalculate());117total_bumpfee = mini_miner.CalculateTotalBumpFees(target_feerate);118assert(total_bumpfee.has_value());119assert(!mini_miner.IsReadyToCalculate());120}121// Overlapping ancestry across multiple outpoints can only reduce the total bump fee.122assert (sum_fees >= *total_bumpfee);123}124} // namespace
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.