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