@@ -41,32 +41,39 @@ class TxConfirmStats;
41
41
* within your desired 5 blocks.
42
42
*
43
43
* 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.
62
66
*/
63
67
68
+ /* Identifier for each of the 3 different TxConfirmStats which will track
69
+ * history over different time horizons. */
64
70
enum FeeEstimateHorizon {
65
71
SHORT_HALFLIFE = 0 ,
66
72
MED_HALFLIFE = 1 ,
67
73
LONG_HALFLIFE = 2
68
74
};
69
75
76
+ /* Used to return detailed information about a feerate bucket */
70
77
struct EstimatorBucket
71
78
{
72
79
double start = -1 ;
@@ -77,6 +84,7 @@ struct EstimatorBucket
77
84
double leftMempool = 0 ;
78
85
};
79
86
87
+ /* Used to return detailed information about a fee estimate calculation */
80
88
struct EstimationResult
81
89
{
82
90
EstimatorBucket pass;
@@ -93,13 +101,13 @@ struct EstimationResult
93
101
class CBlockPolicyEstimator
94
102
{
95
103
private:
96
- /* * Track confirm delays up to 12 blocks medium decay */
104
+ /* * Track confirm delays up to 12 blocks for short horizon */
97
105
static constexpr unsigned int SHORT_BLOCK_PERIODS = 12 ;
98
106
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 */
100
108
static constexpr unsigned int MED_BLOCK_PERIODS = 24 ;
101
109
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 */
103
111
static constexpr unsigned int LONG_BLOCK_PERIODS = 42 ;
104
112
static constexpr unsigned int LONG_SCALE = 24 ;
105
113
/* * Historical estimates that are older than this aren't valid */
@@ -112,9 +120,11 @@ class CBlockPolicyEstimator
112
120
/* * Decay of .9995 is a half-life of 1008 blocks or about 1 week */
113
121
static constexpr double LONG_DECAY = .99931 ;
114
122
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*/
116
124
static constexpr double HALF_SUCCESS_PCT = .6 ;
125
+ /* * Require greater than 85% of X feerate transactions to be confirmed within Y blocks*/
117
126
static constexpr double SUCCESS_PCT = .85 ;
127
+ /* * Require greater than 95% of X feerate transactions to be confirmed within 2 * Y blocks*/
118
128
static constexpr double DOUBLE_SUCCESS_PCT = .95 ;
119
129
120
130
/* * Require an avg of 0.1 tx in the combined feerate bucket per block to have stat significance */
@@ -154,16 +164,19 @@ class CBlockPolicyEstimator
154
164
/* * Remove a transaction from the mempool tracking stats*/
155
165
bool removeTx (uint256 hash, bool inBlock);
156
166
157
- /* * Return a feerate estimate */
167
+ /* * DEPRECATED. Return a feerate estimate */
158
168
CFeeRate estimateFee (int confTarget) const ;
159
169
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.
163
174
*/
164
175
CFeeRate estimateSmartFee (int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool, bool conservative = true ) const ;
165
176
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
167
180
*/
168
181
CFeeRate estimateRawFee (int confTarget, double successThreshold, FeeEstimateHorizon horizon, EstimationResult *result = nullptr ) const ;
169
182
@@ -208,10 +221,15 @@ class CBlockPolicyEstimator
208
221
/* * Process a transaction confirmed in a block*/
209
222
bool processBlockTx (unsigned int nBlockHeight, const CTxMemPoolEntry* entry);
210
223
224
+ /* * Helper for estimateSmartFee */
211
225
double estimateCombinedFee (unsigned int confTarget, double successThreshold, bool checkShorterHorizon) const ;
226
+ /* * Helper for estimateSmartFee */
212
227
double estimateConservativeFee (unsigned int doubleTarget) const ;
228
+ /* * Number of blocks of data recorded while fee estimates have been running */
213
229
unsigned int BlockSpan () const ;
230
+ /* * Number of blocks of recorded fee estimate data represented in saved data file */
214
231
unsigned int HistoricalBlockSpan () const ;
232
+ /* * Calculation of highest target that reasonable estimate can be provided for */
215
233
unsigned int MaxUsableEstimate () const ;
216
234
};
217
235
0 commit comments