Coverage Report

Created: 2025-09-19 18:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/bitcoin/src/test/fuzz/policy_estimator.cpp
Line
Count
Source
1
// Copyright (c) 2020-present The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5
#include <kernel/mempool_entry.h>
6
#include <policy/fees.h>
7
#include <policy/fees_args.h>
8
#include <primitives/transaction.h>
9
#include <streams.h>
10
#include <test/fuzz/FuzzedDataProvider.h>
11
#include <test/fuzz/fuzz.h>
12
#include <test/fuzz/util.h>
13
#include <test/fuzz/util/mempool.h>
14
#include <test/util/setup_common.h>
15
16
#include <memory>
17
#include <optional>
18
#include <vector>
19
20
namespace {
21
const BasicTestingSetup* g_setup;
22
} // namespace
23
24
void initialize_policy_estimator()
25
0
{
26
0
    static const auto testing_setup = MakeNoLogFileContext<>();
27
0
    g_setup = testing_setup.get();
28
0
}
29
30
FUZZ_TARGET(policy_estimator, .init = initialize_policy_estimator)
31
0
{
32
0
    FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
33
0
    bool good_data{true};
34
35
0
    CBlockPolicyEstimator block_policy_estimator{FeeestPath(*g_setup->m_node.args), DEFAULT_ACCEPT_STALE_FEE_ESTIMATES};
36
37
0
    uint32_t current_height{0};
38
0
    const auto advance_height{
39
0
        [&] { current_height = fuzzed_data_provider.ConsumeIntegralInRange<decltype(current_height)>(current_height, 1 << 30); },
40
0
    };
41
0
    advance_height();
42
0
    LIMITED_WHILE(good_data && fuzzed_data_provider.ConsumeBool(), 10'000)
43
0
    {
44
0
        CallOneOf(
45
0
            fuzzed_data_provider,
46
0
            [&] {
47
0
                const std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
48
0
                if (!mtx) {
49
0
                    good_data = false;
50
0
                    return;
51
0
                }
52
0
                const CTransaction tx{*mtx};
53
0
                const auto entry{ConsumeTxMemPoolEntry(fuzzed_data_provider, tx, current_height)};
54
0
                const auto tx_submitted_in_package = fuzzed_data_provider.ConsumeBool();
55
0
                const auto tx_has_mempool_parents = fuzzed_data_provider.ConsumeBool();
56
0
                const auto tx_info = NewMempoolTransactionInfo(entry.GetSharedTx(), entry.GetFee(),
57
0
                                                               entry.GetTxSize(), entry.GetHeight(),
58
0
                                                               /*mempool_limit_bypassed=*/false,
59
0
                                                               tx_submitted_in_package,
60
0
                                                               /*chainstate_is_current=*/true,
61
0
                                                               tx_has_mempool_parents);
62
0
                block_policy_estimator.processTransaction(tx_info);
63
0
                if (fuzzed_data_provider.ConsumeBool()) {
64
0
                    (void)block_policy_estimator.removeTx(tx.GetHash());
65
0
                }
66
0
            },
67
0
            [&] {
68
0
                std::list<CTxMemPoolEntry> mempool_entries;
69
0
                LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000)
70
0
                {
71
0
                    const std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
72
0
                    if (!mtx) {
73
0
                        good_data = false;
74
0
                        break;
75
0
                    }
76
0
                    const CTransaction tx{*mtx};
77
0
                    mempool_entries.emplace_back(CTxMemPoolEntry::ExplicitCopy, ConsumeTxMemPoolEntry(fuzzed_data_provider, tx, current_height));
78
0
                }
79
0
                std::vector<RemovedMempoolTransactionInfo> txs;
80
0
                txs.reserve(mempool_entries.size());
81
0
                for (const CTxMemPoolEntry& mempool_entry : mempool_entries) {
82
0
                    txs.emplace_back(mempool_entry);
83
0
                }
84
0
                advance_height();
85
0
                block_policy_estimator.processBlock(txs, current_height);
86
0
            },
87
0
            [&] {
88
0
                (void)block_policy_estimator.removeTx(Txid::FromUint256(ConsumeUInt256(fuzzed_data_provider)));
89
0
            },
90
0
            [&] {
91
0
                block_policy_estimator.FlushUnconfirmed();
92
0
            });
93
0
        (void)block_policy_estimator.estimateFee(fuzzed_data_provider.ConsumeIntegral<int>());
94
0
        EstimationResult result;
95
0
        auto conf_target = fuzzed_data_provider.ConsumeIntegral<int>();
96
0
        auto success_threshold = fuzzed_data_provider.ConsumeFloatingPoint<double>();
97
0
        auto horizon = fuzzed_data_provider.PickValueInArray(ALL_FEE_ESTIMATE_HORIZONS);
98
0
        auto* result_ptr = fuzzed_data_provider.ConsumeBool() ? &result : nullptr;
99
0
        (void)block_policy_estimator.estimateRawFee(conf_target, success_threshold, horizon, result_ptr);
100
101
0
        FeeCalculation fee_calculation;
102
0
        conf_target = fuzzed_data_provider.ConsumeIntegral<int>();
103
0
        auto* fee_calc_ptr = fuzzed_data_provider.ConsumeBool() ? &fee_calculation : nullptr;
104
0
        auto conservative = fuzzed_data_provider.ConsumeBool();
105
0
        (void)block_policy_estimator.estimateSmartFee(conf_target, fee_calc_ptr, conservative);
106
107
0
        (void)block_policy_estimator.HighestTargetTracked(fuzzed_data_provider.PickValueInArray(ALL_FEE_ESTIMATE_HORIZONS));
108
0
    }
109
0
    {
110
0
        FuzzedFileProvider fuzzed_file_provider{fuzzed_data_provider};
111
0
        AutoFile fuzzed_auto_file{fuzzed_file_provider.open()};
112
0
        block_policy_estimator.Write(fuzzed_auto_file);
113
0
        block_policy_estimator.Read(fuzzed_auto_file);
114
0
        (void)fuzzed_auto_file.fclose();
115
0
    }
116
0
}