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) 2022-present 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 <policy/fees/estimator_man.h>6#include <test/fuzz/FuzzedDataProvider.h>7#include <test/fuzz/fuzz.h>8#include <test/fuzz/util.h>9#include <test/util/setup_common.h>10#include <test/util/time.h>11#include <test/util/txmempool.h>12#include <util/expected.h>13#include <util/fees.h>14#include <validation.h>15#include <wallet/coincontrol.h>16#include <wallet/fees.h>17#include <wallet/test/util.h>18#include <wallet/wallet.h>20#include <optional>22namespace wallet {23namespace {25struct FeeEstimatorManTestingSetup : public TestingSetup {26FeeEstimatorManTestingSetup(const ChainType chain_type, TestOpts opts) : TestingSetup{chain_type, opts}27{28}30~FeeEstimatorManTestingSetup()31{32m_node.fee_estimator_man.reset();33}35void SetFeeEstimatorMan(std::unique_ptr<FeeRateEstimatorManager> fee_estimator_man)36{37m_node.fee_estimator_man = std::move(fee_estimator_man);38}39};41FeeEstimatorManTestingSetup* g_setup;43class FuzzedFeeEstimatorMan : public FeeRateEstimatorManager44{45FuzzedDataProvider& fuzzed_data_provider;47public:48FuzzedFeeEstimatorMan(FuzzedDataProvider& provider, const CTxMemPool& mempool, ChainstateManager& chainman)49: FeeRateEstimatorManager(fs::path{}, false, fs::path{}, mempool, chainman), fuzzed_data_provider(provider) {}51util::Expected<FeeRateEstimation, FeeRateEstimationError> GetFeeRateEstimate(int confTarget, bool conservative) const override52{53FeePerVSize feerate(ConsumeMoney(fuzzed_data_provider, /*max=*/1'000'000), fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(1000, 1000000));54return FeeRateEstimation{FeeRateEstimatorType::BLOCK_POLICY, feerate, fuzzed_data_provider.ConsumeIntegralInRange<int>(2, 1004)};55}56util::Expected<FeeRateEstimation, FeeRateEstimationError> GetFeeRateEstimate(FeeRateEstimatorType type, int confTarget, bool conservative) const override57{58auto res = GetFeeRateEstimate(confTarget, conservative);59if (res) res->feerate_estimator = type;60return res;61}62unsigned int MaximumTarget() const override63{64return fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(1, 1004);65}66};68void initialize_setup()69{70static const auto testing_setup = MakeNoLogFileContext<FeeEstimatorManTestingSetup>();71g_setup = testing_setup.get();72}74FUZZ_TARGET(wallet_fees, .init = initialize_setup)75{76SeedRandomStateForTest(SeedRand::ZEROS);77FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};78FakeNodeClock clock{ConsumeTime(fuzzed_data_provider)};79auto& node{g_setup->m_node};80Chainstate* chainstate = &node.chainman->ActiveChainstate();82bilingual_str error;83CTxMemPool::Options mempool_opts{84.incremental_relay_feerate = CFeeRate{ConsumeMoney(fuzzed_data_provider, 1'000'000)},85.min_relay_feerate = CFeeRate{ConsumeMoney(fuzzed_data_provider, 1'000'000)},86.dust_relay_feerate = CFeeRate{ConsumeMoney(fuzzed_data_provider, 1'000'000)}87};88node.mempool = std::make_unique<CTxMemPool>(mempool_opts, error);89std::unique_ptr<FeeRateEstimatorManager> fee_estimator_man = std::make_unique<FuzzedFeeEstimatorMan>(fuzzed_data_provider, *node.mempool, *node.chainman);90g_setup->SetFeeEstimatorMan(std::move(fee_estimator_man));91auto target_feerate{CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/1'000'000)}};92if (target_feerate > node.mempool->m_opts.incremental_relay_feerate &&93target_feerate > node.mempool->m_opts.min_relay_feerate) {94MockMempoolMinFee(target_feerate, *node.mempool);95}96std::unique_ptr<CWallet> wallet_ptr{std::make_unique<CWallet>(node.chain.get(), "", CreateMockableWalletDatabase())};97CWallet& wallet{*wallet_ptr};98{99LOCK(wallet.cs_wallet);100wallet.SetLastBlockProcessed(chainstate->m_chain.Height(), chainstate->m_chain.Tip()->GetBlockHash());101}103if (fuzzed_data_provider.ConsumeBool()) {104wallet.m_fallback_fee = CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/COIN)};105}107if (fuzzed_data_provider.ConsumeBool()) {108wallet.m_discard_rate = CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/COIN)};109}110(void)GetDiscardRate(wallet);112const auto tx_bytes{fuzzed_data_provider.ConsumeIntegralInRange(0, std::numeric_limits<int32_t>::max())};113if (fuzzed_data_provider.ConsumeBool()) {114wallet.m_min_fee = CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/COIN)};115}117(void)GetRequiredFee(wallet, tx_bytes);118(void)GetRequiredFeeRate(wallet);120CCoinControl coin_control;121if (fuzzed_data_provider.ConsumeBool()) {122coin_control.m_feerate = CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/COIN)};123}124if (fuzzed_data_provider.ConsumeBool()) {125coin_control.m_confirm_target = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, 999'000);126}127if (fuzzed_data_provider.ConsumeBool()) {128coin_control.m_fee_mode = fuzzed_data_provider.ConsumeBool() ? FeeEstimateMode::CONSERVATIVE : FeeEstimateMode::ECONOMICAL;129}130FeeReason fee_reason{FeeReason::FEE_RATE_ESTIMATOR};131if (fuzzed_data_provider.ConsumeBool()) {132fee_reason = fuzzed_data_provider.PickValueInArray({FeeReason::FEE_RATE_ESTIMATOR, FeeReason::MEMPOOL_MIN, FeeReason::USER_SPECIFIED, FeeReason::FALLBACK, FeeReason::REQUIRED});133}134std::optional<int> returned_target;135if (fuzzed_data_provider.ConsumeBool()) {136returned_target = fuzzed_data_provider.ConsumeIntegralInRange<int>(1, 999'000);137}138MinimumFeeRateResult min_fee_rate{139CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/COIN)},140fee_reason,141returned_target};142(void)GetMinimumFeeRate(wallet, coin_control);143(void)GetMinimumFee(min_fee_rate, tx_bytes);144}145} // namespace146} // namespace wallet
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.