policy_estimator.cpp raw
1 // Copyright (c) 2020-2022 The Limenka 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 {
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 LIMITED_WHILE(good_data && fuzzed_data_provider.ConsumeBool(), 10'000)
37 {
38 CallOneOf(
39 fuzzed_data_provider,
40 [&] {
41 const std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
42 if (!mtx) {
43 good_data = false;
44 return;
45 }
46 const CTransaction tx{*mtx};
47 if (!SanityCheckForConsumeTxMemPoolEntry(tx)) return;
48 const CTxMemPoolEntry& entry = ConsumeTxMemPoolEntry(fuzzed_data_provider, tx);
49 const auto tx_submitted_in_package = fuzzed_data_provider.ConsumeBool();
50 const auto tx_has_mempool_parents = fuzzed_data_provider.ConsumeBool();
51 const auto tx_info = NewMempoolTransactionInfo(entry.GetSharedTx(), entry.GetFee(),
52 entry.GetTxSize(), entry.GetHeight(),
53 empty_ignore_rejects,
54 tx_submitted_in_package,
55 /*chainstate_is_current=*/true,
56 tx_has_mempool_parents);
57 block_policy_estimator.processTransaction(tx_info);
58 if (fuzzed_data_provider.ConsumeBool()) {
59 (void)block_policy_estimator.removeTx(tx.GetHash());
60 }
61 },
62 [&] {
63 std::list<CTxMemPoolEntry> mempool_entries;
64 LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000)
65 {
66 const std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
67 if (!mtx) {
68 good_data = false;
69 break;
70 }
71 const CTransaction tx{*mtx};
72 if (!SanityCheckForConsumeTxMemPoolEntry(tx)) return;
73 mempool_entries.emplace_back(CTxMemPoolEntry::ExplicitCopy, ConsumeTxMemPoolEntry(fuzzed_data_provider, tx));
74 }
75 std::vector<RemovedMempoolTransactionInfo> txs;
76 txs.reserve(mempool_entries.size());
77 for (const CTxMemPoolEntry& mempool_entry : mempool_entries) {
78 txs.emplace_back(mempool_entry);
79 }
80 block_policy_estimator.processBlock(txs, fuzzed_data_provider.ConsumeIntegral<unsigned int>());
81 },
82 [&] {
83 (void)block_policy_estimator.removeTx(ConsumeUInt256(fuzzed_data_provider));
84 },
85 [&] {
86 block_policy_estimator.FlushUnconfirmed();
87 });
88 (void)block_policy_estimator.estimateFee(fuzzed_data_provider.ConsumeIntegral<int>());
89 EstimationResult result;
90 auto conf_target = fuzzed_data_provider.ConsumeIntegral<int>();
91 auto success_threshold = fuzzed_data_provider.ConsumeFloatingPoint<double>();
92 auto horizon = fuzzed_data_provider.PickValueInArray(ALL_FEE_ESTIMATE_HORIZONS);
93 auto* result_ptr = fuzzed_data_provider.ConsumeBool() ? &result : nullptr;
94 (void)block_policy_estimator.estimateRawFee(conf_target, success_threshold, horizon, result_ptr);
95
96 FeeCalculation fee_calculation;
97 conf_target = fuzzed_data_provider.ConsumeIntegral<int>();
98 auto* fee_calc_ptr = fuzzed_data_provider.ConsumeBool() ? &fee_calculation : nullptr;
99 auto conservative = fuzzed_data_provider.ConsumeBool();
100 (void)block_policy_estimator.estimateSmartFee(conf_target, fee_calc_ptr, conservative);
101
102 (void)block_policy_estimator.HighestTargetTracked(fuzzed_data_provider.PickValueInArray(ALL_FEE_ESTIMATE_HORIZONS));
103 }
104 {
105 FuzzedFileProvider fuzzed_file_provider{fuzzed_data_provider};
106 AutoFile fuzzed_auto_file{fuzzed_file_provider.open()};
107 block_policy_estimator.Write(fuzzed_auto_file);
108 block_policy_estimator.Read(fuzzed_auto_file);
109 (void)fuzzed_auto_file.fclose();
110 }
111 }
112