policy_estimator.cpp
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 }