policy_estimator.cpp raw
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/block_policy_estimator.h>
7 #include <policy/fees/block_policy_estimator_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 {
26 static const auto testing_setup = MakeNoLogFileContext<>();
27 g_setup = testing_setup.get();
28 }
29
30 FUZZ_TARGET(policy_estimator, .init = initialize_policy_estimator)
31 {
32 FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
33 bool good_data{true};
34
35 CBlockPolicyEstimator block_policy_estimator{FeeestPath(*g_setup->m_node.args), DEFAULT_ACCEPT_STALE_FEE_ESTIMATES};
36
37 uint32_t current_height{0};
38 const auto advance_height{
39 [&] { current_height = fuzzed_data_provider.ConsumeIntegralInRange<decltype(current_height)>(current_height, 1 << 30); },
40 };
41 advance_height();
42 LIMITED_WHILE(good_data && fuzzed_data_provider.ConsumeBool(), 10'000)
43 {
44 CallOneOf(
45 fuzzed_data_provider,
46 [&] {
47 const std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
48 if (!mtx) {
49 good_data = false;
50 return;
51 }
52 const CTransaction tx{*mtx};
53 const auto entry{ConsumeTxMemPoolEntry(fuzzed_data_provider, tx, current_height)};
54 const auto tx_submitted_in_package = fuzzed_data_provider.ConsumeBool();
55 const auto tx_has_mempool_parents = fuzzed_data_provider.ConsumeBool();
56 const auto tx_info = NewMempoolTransactionInfo(entry.GetSharedTx(), entry.GetFee(),
57 entry.GetTxSize(), entry.GetHeight(),
58 /*mempool_limit_bypassed=*/false,
59 tx_submitted_in_package,
60 /*chainstate_is_current=*/true,
61 tx_has_mempool_parents);
62 block_policy_estimator.processTransaction(tx_info);
63 if (fuzzed_data_provider.ConsumeBool()) {
64 (void)block_policy_estimator.removeTx(tx.GetHash());
65 }
66 },
67 [&] {
68 std::list<CTxMemPoolEntry> mempool_entries;
69 LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000)
70 {
71 const std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
72 if (!mtx) {
73 good_data = false;
74 break;
75 }
76 const CTransaction tx{*mtx};
77 mempool_entries.push_back(ConsumeTxMemPoolEntry(fuzzed_data_provider, tx, current_height));
78 }
79 std::vector<RemovedMempoolTransactionInfo> txs;
80 txs.reserve(mempool_entries.size());
81 for (const CTxMemPoolEntry& mempool_entry : mempool_entries) {
82 txs.emplace_back(mempool_entry);
83 }
84 advance_height();
85 block_policy_estimator.processBlock(txs, current_height);
86 },
87 [&] {
88 (void)block_policy_estimator.removeTx(Txid::FromUint256(ConsumeUInt256(fuzzed_data_provider)));
89 },
90 [&] {
91 block_policy_estimator.FlushUnconfirmed();
92 });
93 (void)block_policy_estimator.estimateFee(fuzzed_data_provider.ConsumeIntegral<int>());
94 EstimationResult result;
95 auto conf_target = fuzzed_data_provider.ConsumeIntegral<int>();
96 auto success_threshold = fuzzed_data_provider.ConsumeFloatingPoint<double>();
97 auto horizon = fuzzed_data_provider.PickValueInArray(ALL_FEE_ESTIMATE_HORIZONS);
98 auto* result_ptr = fuzzed_data_provider.ConsumeBool() ? &result : nullptr;
99 (void)block_policy_estimator.estimateRawFee(conf_target, success_threshold, horizon, result_ptr);
100
101 FeeCalculation fee_calculation;
102 conf_target = fuzzed_data_provider.ConsumeIntegral<int>();
103 auto* fee_calc_ptr = fuzzed_data_provider.ConsumeBool() ? &fee_calculation : nullptr;
104 auto conservative = fuzzed_data_provider.ConsumeBool();
105 (void)block_policy_estimator.estimateSmartFee(conf_target, fee_calc_ptr, conservative);
106
107 (void)block_policy_estimator.HighestTargetTracked(fuzzed_data_provider.PickValueInArray(ALL_FEE_ESTIMATE_HORIZONS));
108 }
109 {
110 FuzzedFileProvider fuzzed_file_provider{fuzzed_data_provider};
111 AutoFile fuzzed_auto_file{fuzzed_file_provider.open()};
112 block_policy_estimator.Write(fuzzed_auto_file);
113 block_policy_estimator.Read(fuzzed_auto_file);
114 (void)fuzzed_auto_file.fclose();
115 }
116 }
117