Skip to content

Commit 2d2e170

Browse files
committed
Comments and improved documentation
1 parent ef589f8 commit 2d2e170

File tree

3 files changed

+56
-28
lines changed

3 files changed

+56
-28
lines changed

src/policy/fees.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,9 @@ double CBlockPolicyEstimator::estimateCombinedFee(unsigned int confTarget, doubl
729729
return estimate;
730730
}
731731

732+
/** Ensure that for a conservative estimate, the DOUBLE_SUCCESS_PCT is also met
733+
* at 2 * target for any longer time horizons.
734+
*/
732735
double CBlockPolicyEstimator::estimateConservativeFee(unsigned int doubleTarget) const
733736
{
734737
double estimate = -1;
@@ -744,6 +747,13 @@ double CBlockPolicyEstimator::estimateConservativeFee(unsigned int doubleTarget)
744747
return estimate;
745748
}
746749

750+
/** estimateSmartFee returns the max of the feerates calculated with a 60%
751+
* threshold required at target / 2, an 85% threshold required at target and a
752+
* 95% threshold required at 2 * target. Each calculation is performed at the
753+
* shortest time horizon which tracks the required target. Conservative
754+
* estimates, however, required the 95% threshold at 2 * target be met for any
755+
* longer time horizons also.
756+
*/
747757
CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool, bool conservative) const
748758
{
749759
if (answerFoundAtTarget)

src/policy/fees.h

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -41,32 +41,39 @@ class TxConfirmStats;
4141
* within your desired 5 blocks.
4242
*
4343
* Here is a brief description of the implementation:
44-
* When a transaction enters the mempool, we
45-
* track the height of the block chain at entry. Whenever a block comes in,
46-
* we count the number of transactions in each bucket and the total amount of feerate
47-
* paid in each bucket. Then we calculate how many blocks Y it took each
48-
* transaction to be mined and we track an array of counters in each bucket
49-
* for how long it to took transactions to get confirmed from 1 to a max of 25
50-
* and we increment all the counters from Y up to 25. This is because for any
51-
* number Z>=Y the transaction was successfully mined within Z blocks. We
52-
* want to save a history of this information, so at any time we have a
53-
* counter of the total number of transactions that happened in a given feerate
54-
* bucket and the total number that were confirmed in each number 1-25 blocks
55-
* or less for any bucket. We save this history by keeping an exponentially
56-
* decaying moving average of each one of these stats. Furthermore we also
57-
* keep track of the number unmined (in mempool) transactions in each bucket
58-
* and for how many blocks they have been outstanding and use that to increase
59-
* the number of transactions we've seen in that feerate bucket when calculating
60-
* an estimate for any number of confirmations below the number of blocks
61-
* they've been outstanding.
44+
* When a transaction enters the mempool, we track the height of the block chain
45+
* at entry. All further calculations are conducted only on this set of "seen"
46+
* transactions. Whenever a block comes in, we count the number of transactions
47+
* in each bucket and the total amount of feerate paid in each bucket. Then we
48+
* calculate how many blocks Y it took each transaction to be mined. We convert
49+
* from a number of blocks to a number of periods Y' each encompassing "scale"
50+
* blocks. This is is tracked in 3 different data sets each up to a maximum
51+
* number of periods. Within each data set we have an array of counters in each
52+
* feerate bucket and we increment all the counters from Y' up to max periods
53+
* representing that a tx was successfullly confirmed in less than or equal to
54+
* that many periods. We want to save a history of this information, so at any
55+
* time we have a counter of the total number of transactions that happened in a
56+
* given feerate bucket and the total number that were confirmed in each of the
57+
* periods or less for any bucket. We save this history by keeping an
58+
* exponentially decaying moving average of each one of these stats. This is
59+
* done for a different decay in each of the 3 data sets to keep relevant data
60+
* from different time horizons. Furthermore we also keep track of the number
61+
* unmined (in mempool or left mempool without being included in a block)
62+
* transactions in each bucket and for how many blocks they have been
63+
* outstanding and use both of these numbers to increase the number of transactions
64+
* we've seen in that feerate bucket when calculating an estimate for any number
65+
* of confirmations below the number of blocks they've been outstanding.
6266
*/
6367

68+
/* Identifier for each of the 3 different TxConfirmStats which will track
69+
* history over different time horizons. */
6470
enum FeeEstimateHorizon {
6571
SHORT_HALFLIFE = 0,
6672
MED_HALFLIFE = 1,
6773
LONG_HALFLIFE = 2
6874
};
6975

76+
/* Used to return detailed information about a feerate bucket */
7077
struct EstimatorBucket
7178
{
7279
double start = -1;
@@ -77,6 +84,7 @@ struct EstimatorBucket
7784
double leftMempool = 0;
7885
};
7986

87+
/* Used to return detailed information about a fee estimate calculation */
8088
struct EstimationResult
8189
{
8290
EstimatorBucket pass;
@@ -93,13 +101,13 @@ struct EstimationResult
93101
class CBlockPolicyEstimator
94102
{
95103
private:
96-
/** Track confirm delays up to 12 blocks medium decay */
104+
/** Track confirm delays up to 12 blocks for short horizon */
97105
static constexpr unsigned int SHORT_BLOCK_PERIODS = 12;
98106
static constexpr unsigned int SHORT_SCALE = 1;
99-
/** Track confirm delays up to 48 blocks medium decay */
107+
/** Track confirm delays up to 48 blocks for medium horizon */
100108
static constexpr unsigned int MED_BLOCK_PERIODS = 24;
101109
static constexpr unsigned int MED_SCALE = 2;
102-
/** Track confirm delays up to 1008 blocks for longer decay */
110+
/** Track confirm delays up to 1008 blocks for long horizon */
103111
static constexpr unsigned int LONG_BLOCK_PERIODS = 42;
104112
static constexpr unsigned int LONG_SCALE = 24;
105113
/** Historical estimates that are older than this aren't valid */
@@ -112,9 +120,11 @@ class CBlockPolicyEstimator
112120
/** Decay of .9995 is a half-life of 1008 blocks or about 1 week */
113121
static constexpr double LONG_DECAY = .99931;
114122

115-
/** Require greater than 95% of X feerate transactions to be confirmed within Y blocks for X to be big enough */
123+
/** Require greater than 60% of X feerate transactions to be confirmed within Y/2 blocks*/
116124
static constexpr double HALF_SUCCESS_PCT = .6;
125+
/** Require greater than 85% of X feerate transactions to be confirmed within Y blocks*/
117126
static constexpr double SUCCESS_PCT = .85;
127+
/** Require greater than 95% of X feerate transactions to be confirmed within 2 * Y blocks*/
118128
static constexpr double DOUBLE_SUCCESS_PCT = .95;
119129

120130
/** Require an avg of 0.1 tx in the combined feerate bucket per block to have stat significance */
@@ -154,16 +164,19 @@ class CBlockPolicyEstimator
154164
/** Remove a transaction from the mempool tracking stats*/
155165
bool removeTx(uint256 hash, bool inBlock);
156166

157-
/** Return a feerate estimate */
167+
/** DEPRECATED. Return a feerate estimate */
158168
CFeeRate estimateFee(int confTarget) const;
159169

160-
/** Estimate feerate needed to get be included in a block within
161-
* confTarget blocks. If no answer can be given at confTarget, return an
162-
* estimate at the lowest target where one can be given.
170+
/** Estimate feerate needed to get be included in a block within confTarget
171+
* blocks. If no answer can be given at confTarget, return an estimate at
172+
* the closest target where one can be given. 'conservative' estimates are
173+
* valid over longer time horizons also.
163174
*/
164175
CFeeRate estimateSmartFee(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool, bool conservative = true) const;
165176

166-
/** Return a specific fee estimate calculation with a given success threshold and time horizon.
177+
/** Return a specific fee estimate calculation with a given success
178+
* threshold and time horizon, and optionally return detailed data about
179+
* calculation
167180
*/
168181
CFeeRate estimateRawFee(int confTarget, double successThreshold, FeeEstimateHorizon horizon, EstimationResult *result = nullptr) const;
169182

@@ -208,10 +221,15 @@ class CBlockPolicyEstimator
208221
/** Process a transaction confirmed in a block*/
209222
bool processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry* entry);
210223

224+
/** Helper for estimateSmartFee */
211225
double estimateCombinedFee(unsigned int confTarget, double successThreshold, bool checkShorterHorizon) const;
226+
/** Helper for estimateSmartFee */
212227
double estimateConservativeFee(unsigned int doubleTarget) const;
228+
/** Number of blocks of data recorded while fee estimates have been running */
213229
unsigned int BlockSpan() const;
230+
/** Number of blocks of recorded fee estimate data represented in saved data file */
214231
unsigned int HistoricalBlockSpan() const;
232+
/** Calculation of highest target that reasonable estimate can be provided for */
215233
unsigned int MaxUsableEstimate() const;
216234
};
217235

src/rpc/mining.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,7 @@ UniValue estimatefee(const JSONRPCRequest& request)
797797
if (request.fHelp || request.params.size() != 1)
798798
throw std::runtime_error(
799799
"estimatefee nblocks\n"
800+
"\nDEPRECATED. Please use estimatesmartfee for more intelligent estimates."
800801
"\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n"
801802
"confirmation within nblocks blocks. Uses virtual transaction size of transaction\n"
802803
"as defined in BIP 141 (witness data is discounted).\n"
@@ -831,7 +832,6 @@ UniValue estimatesmartfee(const JSONRPCRequest& request)
831832
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
832833
throw std::runtime_error(
833834
"estimatesmartfee nblocks (conservative)\n"
834-
"\nWARNING: This interface is unstable and may disappear or change!\n"
835835
"\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n"
836836
"confirmation within nblocks blocks if possible and return the number of blocks\n"
837837
"for which the estimate is valid. Uses virtual transaction size as defined\n"

0 commit comments

Comments
 (0)