Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2009-2010 Satoshi Nakamoto2// Copyright (c) 2009-present The Bitcoin Core developers3// Distributed under the MIT software license, see the accompanying4// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#ifndef BITCOIN_POLICY_FEES_BLOCK_POLICY_ESTIMATOR_H6#define BITCOIN_POLICY_FEES_BLOCK_POLICY_ESTIMATOR_H8#include <consensus/amount.h>9#include <policy/feerate.h>10#include <primitives/transaction_identifier.h>11#include <random.h>12#include <sync.h>13#include <uint256.h>14#include <util/expected.h>15#include <util/fees.h>16#include <util/fs.h>18#include <array>19#include <chrono>20#include <map>21#include <memory>22#include <set>23#include <string>24#include <vector>27/** Block policy estimate files that are more than 60 hours (2.5 days) old will not be read,28* as fee estimates are based on historical data and may be inaccurate if29* network activity has changed.30*/31inline constexpr std::chrono::hours MAX_FILE_AGE{60};33// Whether we allow importing a fee_estimates file older than MAX_FILE_AGE.34inline constexpr bool DEFAULT_ACCEPT_STALE_FEE_ESTIMATES{false};36class AutoFile;37class TxConfirmStats;38struct RemovedMempoolTransactionInfo;39struct NewMempoolTransactionInfo;41/* Identifier for each of the 3 different TxConfirmStats which will track42* history over different time horizons. */43enum class FeeEstimateHorizon {44SHORT_HALFLIFE,45MED_HALFLIFE,46LONG_HALFLIFE,47};49inline constexpr auto ALL_FEE_ESTIMATE_HORIZONS = std::array{50FeeEstimateHorizon::SHORT_HALFLIFE,51FeeEstimateHorizon::MED_HALFLIFE,52FeeEstimateHorizon::LONG_HALFLIFE,53};55std::string StringForFeeEstimateHorizon(FeeEstimateHorizon horizon);57/* Enumeration of reason for returned fee estimate */58enum class BlockPolicyEstimateReason {59NONE,60HALF_ESTIMATE,61FULL_ESTIMATE,62DOUBLE_ESTIMATE,63CONSERVATIVE,64};66std::string StringForBlockPolicyEstimateReason(BlockPolicyEstimateReason reason);68/* Used to return detailed information about a feerate bucket */69struct EstimatorBucket70{71double start = -1;72double end = -1;73double withinTarget = 0;74double totalConfirmed = 0;75double inMempool = 0;76double leftMempool = 0;77};79/* Used to return detailed information about a fee estimate calculation */80struct EstimationResult81{82EstimatorBucket pass;83EstimatorBucket fail;84double decay = 0;85unsigned int scale = 0;86};88struct FeeCalculation89{90EstimationResult est;91BlockPolicyEstimateReason reason = BlockPolicyEstimateReason::NONE;92int desiredTarget = 0;93int returnedTarget = 0;94unsigned int best_height{0};95};97/** \class CBlockPolicyEstimator98* The BlockPolicyEstimator is used for estimating the feerate needed99* for a transaction to be included in a block within a certain number of100* blocks.101*102* At a high level the algorithm works by grouping transactions into buckets103* based on having similar feerates and then tracking how long it104* takes transactions in the various buckets to be mined. It operates under105* the assumption that in general transactions of higher feerate will be106* included in blocks before transactions of lower feerate. So for107* example if you wanted to know what feerate you should put on a transaction to108* be included in a block within the next 5 blocks, you would start by looking109* at the bucket with the highest feerate transactions and verifying that a110* sufficiently high percentage of them were confirmed within 5 blocks and111* then you would look at the next highest feerate bucket, and so on, stopping at112* the last bucket to pass the test. The average feerate of transactions in this113* bucket will give you an indication of the lowest feerate you can put on a114* transaction and still have a sufficiently high chance of being confirmed115* within your desired 5 blocks.116*117* Here is a brief description of the implementation:118* When a transaction enters the mempool, we track the height of the block chain119* at entry. All further calculations are conducted only on this set of "seen"120* transactions. Whenever a block comes in, we count the number of transactions121* in each bucket and the total amount of feerate paid in each bucket. Then we122* calculate how many blocks Y it took each transaction to be mined. We convert123* from a number of blocks to a number of periods Y' each encompassing "scale"124* blocks. This is tracked in 3 different data sets each up to a maximum125* number of periods. Within each data set we have an array of counters in each126* feerate bucket and we increment all the counters from Y' up to max periods127* representing that a tx was successfully confirmed in less than or equal to128* that many periods. We want to save a history of this information, so at any129* time we have a counter of the total number of transactions that happened in a130* given feerate bucket and the total number that were confirmed in each of the131* periods or less for any bucket. We save this history by keeping an132* exponentially decaying moving average of each one of these stats. This is133* done for a different decay in each of the 3 data sets to keep relevant data134* from different time horizons. Furthermore we also keep track of the number135* unmined (in mempool or left mempool without being included in a block)136* transactions in each bucket and for how many blocks they have been137* outstanding and use both of these numbers to increase the number of transactions138* we've seen in that feerate bucket when calculating an estimate for any number139* of confirmations below the number of blocks they've been outstanding.140*141* We want to be able to estimate feerates that are needed on tx's to be included in142* a certain number of blocks. Every time a block is added to the best chain, this class records143* stats on the transactions included in that block144*/145class CBlockPolicyEstimator146{147private:148/** Track confirm delays up to 12 blocks for short horizon */149static constexpr unsigned int SHORT_BLOCK_PERIODS = 12;150static constexpr unsigned int SHORT_SCALE = 1;151/** Track confirm delays up to 48 blocks for medium horizon */152static constexpr unsigned int MED_BLOCK_PERIODS = 24;153static constexpr unsigned int MED_SCALE = 2;154/** Track confirm delays up to 1008 blocks for long horizon */155static constexpr unsigned int LONG_BLOCK_PERIODS = 42;156static constexpr unsigned int LONG_SCALE = 24;157/** Historical estimates that are older than this aren't valid */158static constexpr unsigned int OLDEST_ESTIMATE_HISTORY{6 * 1008};160/** Decay of .962 is a half-life of 18 blocks or about 3 hours */161static constexpr double SHORT_DECAY = .962;162/** Decay of .9952 is a half-life of 144 blocks or about 1 day */163static constexpr double MED_DECAY = .9952;164/** Decay of .99931 is a half-life of 1008 blocks or about 1 week */165static constexpr double LONG_DECAY = .99931;167/** Require greater than 60% of X feerate transactions to be confirmed within Y/2 blocks*/168static constexpr double HALF_SUCCESS_PCT = .6;169/** Require greater than 85% of X feerate transactions to be confirmed within Y blocks*/170static constexpr double SUCCESS_PCT = .85;171/** Require greater than 95% of X feerate transactions to be confirmed within 2 * Y blocks*/172static constexpr double DOUBLE_SUCCESS_PCT = .95;174/** Require an avg of 0.1 tx in the combined feerate bucket per block to have stat significance */175static constexpr double SUFFICIENT_FEETXS = 0.1;176/** Require an avg of 0.5 tx when using short decay since there are fewer blocks considered*/177static constexpr double SUFFICIENT_TXS_SHORT = 0.5;179/** Minimum and Maximum values for tracking feerates180* The MIN_BUCKET_FEERATE should just be set to the lowest reasonable feerate.181* MIN_BUCKET_FEERATE has historically inherited DEFAULT_MIN_RELAY_TX_FEE.182* It is hardcoded because changing it is disruptive, as it invalidates existing fee183* estimate files.184*185* Whenever DEFAULT_MIN_RELAY_TX_FEE changes, this value should be updated186* accordingly. At the same time CURRENT_FEES_FILE_VERSION should be bumped.187*/188static constexpr double MIN_BUCKET_FEERATE = 100;189static constexpr double MAX_BUCKET_FEERATE = 1e7;191/** Spacing of FeeRate buckets192* We have to lump transactions into buckets based on feerate, but we want to be able193* to give accurate estimates over a large range of potential feerates194* Therefore it makes sense to exponentially space the buckets195*/196static constexpr double FEE_SPACING = 1.05;198const fs::path m_estimation_filepath;199public:200/** Create new BlockPolicyEstimator and initialize stats tracking classes with default values */201CBlockPolicyEstimator(const fs::path& estimation_filepath, bool read_stale_estimates);202virtual ~CBlockPolicyEstimator();204/** Process all the transactions that have been included in a block */205void processBlock(const std::vector<RemovedMempoolTransactionInfo>& txs_removed_for_block,206unsigned int nBlockHeight)207EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);209/** Process a transaction accepted to the mempool*/210void processTransaction(const NewMempoolTransactionInfo& tx)211EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);213/** Remove a transaction from the mempool tracking stats for non BLOCK removal reasons*/214bool removeTx(Txid hash)215EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);217/** DEPRECATED. Return a feerate estimate */218CFeeRate estimateFee(int confTarget) const219EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);221/** Estimate feerate needed to get be included in a block within confTarget222* blocks. If no answer can be given at confTarget, return an estimate at223* the closest target where one can be given. 'conservative' estimates are224* valid over longer time horizons also.225*/226virtual CFeeRate estimateSmartFee(int confTarget, FeeCalculation *feeCalc, bool conservative) const227EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);229/** Return a specific fee estimate calculation with a given success230* threshold and time horizon, and optionally return detailed data about231* calculation232*/233CFeeRate estimateRawFee(int confTarget, double successThreshold, FeeEstimateHorizon horizon,234EstimationResult* result = nullptr) const235EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);237/** Write estimation data to a file */238bool Write(AutoFile& fileout) const239EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);241/** Read estimation data from a file */242bool Read(AutoFile& filein)243EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);245/** Empty mempool transactions on shutdown to record failure to confirm for txs still in mempool */246void FlushUnconfirmed()247EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);249/** Calculation of highest target that estimates are tracked for */250virtual unsigned int HighestTargetTracked(FeeEstimateHorizon horizon) const
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.