policy_estimator.cpp
1 // Copyright (c) 2020-2022 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 { 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 const CTxMemPoolEntry& entry = ConsumeTxMemPoolEntry(fuzzed_data_provider, tx); 48 const auto tx_submitted_in_package = fuzzed_data_provider.ConsumeBool(); 49 const auto tx_has_mempool_parents = fuzzed_data_provider.ConsumeBool(); 50 const auto tx_info = NewMempoolTransactionInfo(entry.GetSharedTx(), entry.GetFee(), 51 entry.GetTxSize(), entry.GetHeight(), 52 /*mempool_limit_bypassed=*/false, 53 tx_submitted_in_package, 54 /*chainstate_is_current=*/true, 55 tx_has_mempool_parents); 56 block_policy_estimator.processTransaction(tx_info); 57 if (fuzzed_data_provider.ConsumeBool()) { 58 (void)block_policy_estimator.removeTx(tx.GetHash()); 59 } 60 }, 61 [&] { 62 std::list<CTxMemPoolEntry> mempool_entries; 63 LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) 64 { 65 const std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS); 66 if (!mtx) { 67 good_data = false; 68 break; 69 } 70 const CTransaction tx{*mtx}; 71 mempool_entries.emplace_back(CTxMemPoolEntry::ExplicitCopy, ConsumeTxMemPoolEntry(fuzzed_data_provider, tx)); 72 } 73 std::vector<RemovedMempoolTransactionInfo> txs; 74 txs.reserve(mempool_entries.size()); 75 for (const CTxMemPoolEntry& mempool_entry : mempool_entries) { 76 txs.emplace_back(mempool_entry); 77 } 78 block_policy_estimator.processBlock(txs, fuzzed_data_provider.ConsumeIntegral<unsigned int>()); 79 }, 80 [&] { 81 (void)block_policy_estimator.removeTx(ConsumeUInt256(fuzzed_data_provider)); 82 }, 83 [&] { 84 block_policy_estimator.FlushUnconfirmed(); 85 }); 86 (void)block_policy_estimator.estimateFee(fuzzed_data_provider.ConsumeIntegral<int>()); 87 EstimationResult result; 88 (void)block_policy_estimator.estimateRawFee(fuzzed_data_provider.ConsumeIntegral<int>(), fuzzed_data_provider.ConsumeFloatingPoint<double>(), fuzzed_data_provider.PickValueInArray(ALL_FEE_ESTIMATE_HORIZONS), fuzzed_data_provider.ConsumeBool() ? &result : nullptr); 89 FeeCalculation fee_calculation; 90 (void)block_policy_estimator.estimateSmartFee(fuzzed_data_provider.ConsumeIntegral<int>(), fuzzed_data_provider.ConsumeBool() ? &fee_calculation : nullptr, fuzzed_data_provider.ConsumeBool()); 91 (void)block_policy_estimator.HighestTargetTracked(fuzzed_data_provider.PickValueInArray(ALL_FEE_ESTIMATE_HORIZONS)); 92 } 93 { 94 FuzzedFileProvider fuzzed_file_provider{fuzzed_data_provider}; 95 AutoFile fuzzed_auto_file{fuzzed_file_provider.open()}; 96 block_policy_estimator.Write(fuzzed_auto_file); 97 block_policy_estimator.Read(fuzzed_auto_file); 98 } 99 }