BSHA3  0.17.99
P2P Blockchain, based on Bitcoin
fees.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <policy/fees.h>
7 #include <policy/policy.h>
8 
9 #include <clientversion.h>
10 #include <primitives/transaction.h>
11 #include <streams.h>
12 #include <txmempool.h>
13 #include <util.h>
14 
15 static constexpr double INF_FEERATE = 1e99;
16 
18  static const std::map<FeeEstimateHorizon, std::string> horizon_strings = {
22  };
23  auto horizon_string = horizon_strings.find(horizon);
24 
25  if (horizon_string == horizon_strings.end()) return "unknown";
26 
27  return horizon_string->second;
28 }
29 
30 std::string StringForFeeReason(FeeReason reason) {
31  static const std::map<FeeReason, std::string> fee_reason_strings = {
32  {FeeReason::NONE, "None"},
33  {FeeReason::HALF_ESTIMATE, "Half Target 60% Threshold"},
34  {FeeReason::FULL_ESTIMATE, "Target 85% Threshold"},
35  {FeeReason::DOUBLE_ESTIMATE, "Double Target 95% Threshold"},
36  {FeeReason::CONSERVATIVE, "Conservative Double Target longer horizon"},
37  {FeeReason::MEMPOOL_MIN, "Mempool Min Fee"},
38  {FeeReason::PAYTXFEE, "PayTxFee set"},
39  {FeeReason::FALLBACK, "Fallback fee"},
40  {FeeReason::REQUIRED, "Minimum Required Fee"},
41  {FeeReason::MAXTXFEE, "MaxTxFee limit"}
42  };
43  auto reason_string = fee_reason_strings.find(reason);
44 
45  if (reason_string == fee_reason_strings.end()) return "Unknown";
46 
47  return reason_string->second;
48 }
49 
50 bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode) {
51  static const std::map<std::string, FeeEstimateMode> fee_modes = {
52  {"UNSET", FeeEstimateMode::UNSET},
53  {"ECONOMICAL", FeeEstimateMode::ECONOMICAL},
54  {"CONSERVATIVE", FeeEstimateMode::CONSERVATIVE},
55  };
56  auto mode = fee_modes.find(mode_string);
57 
58  if (mode == fee_modes.end()) return false;
59 
60  fee_estimate_mode = mode->second;
61  return true;
62 }
63 
73 {
74 private:
75  //Define the buckets we will group transactions into
76  const std::vector<double>& buckets; // The upper-bound of the range for the bucket (inclusive)
77  const std::map<double, unsigned int>& bucketMap; // Map of bucket upper-bound to index into all vectors by bucket
78 
79  // For each bucket X:
80  // Count the total # of txs in each bucket
81  // Track the historical moving average of this total over blocks
82  std::vector<double> txCtAvg;
83 
84  // Count the total # of txs confirmed within Y blocks in each bucket
85  // Track the historical moving average of theses totals over blocks
86  std::vector<std::vector<double>> confAvg; // confAvg[Y][X]
87 
88  // Track moving avg of txs which have been evicted from the mempool
89  // after failing to be confirmed within Y blocks
90  std::vector<std::vector<double>> failAvg; // failAvg[Y][X]
91 
92  // Sum the total feerate of all tx's in each bucket
93  // Track the historical moving average of this total over blocks
94  std::vector<double> avg;
95 
96  // Combine the conf counts with tx counts to calculate the confirmation % for each Y,X
97  // Combine the total value with the tx counts to calculate the avg feerate per bucket
98 
99  double decay;
100 
101  // Resolution (# of blocks) with which confirmations are tracked
102  unsigned int scale;
103 
104  // Mempool counts of outstanding transactions
105  // For each bucket X, track the number of transactions in the mempool
106  // that are unconfirmed for each possible confirmation value Y
107  std::vector<std::vector<int> > unconfTxs; //unconfTxs[Y][X]
108  // transactions still unconfirmed after GetMaxConfirms for each bucket
109  std::vector<int> oldUnconfTxs;
110 
111  void resizeInMemoryCounters(size_t newbuckets);
112 
113 public:
121  TxConfirmStats(const std::vector<double>& defaultBuckets, const std::map<double, unsigned int>& defaultBucketMap,
122  unsigned int maxPeriods, double decay, unsigned int scale);
123 
125  void ClearCurrent(unsigned int nBlockHeight);
126 
133  void Record(int blocksToConfirm, double val);
134 
136  unsigned int NewTx(unsigned int nBlockHeight, double val);
137 
139  void removeTx(unsigned int entryHeight, unsigned int nBestSeenHeight,
140  unsigned int bucketIndex, bool inBlock);
141 
144  void UpdateMovingAverages();
145 
157  double EstimateMedianVal(int confTarget, double sufficientTxVal,
158  double minSuccess, bool requireGreater, unsigned int nBlockHeight,
159  EstimationResult *result = nullptr) const;
160 
162  unsigned int GetMaxConfirms() const { return scale * confAvg.size(); }
163 
165  void Write(CAutoFile& fileout) const;
166 
171  void Read(CAutoFile& filein, int nFileVersion, size_t numBuckets);
172 };
173 
174 
175 TxConfirmStats::TxConfirmStats(const std::vector<double>& defaultBuckets,
176  const std::map<double, unsigned int>& defaultBucketMap,
177  unsigned int maxPeriods, double _decay, unsigned int _scale)
178  : buckets(defaultBuckets), bucketMap(defaultBucketMap)
179 {
180  decay = _decay;
181  assert(_scale != 0 && "_scale must be non-zero");
182  scale = _scale;
183  confAvg.resize(maxPeriods);
184  for (unsigned int i = 0; i < maxPeriods; i++) {
185  confAvg[i].resize(buckets.size());
186  }
187  failAvg.resize(maxPeriods);
188  for (unsigned int i = 0; i < maxPeriods; i++) {
189  failAvg[i].resize(buckets.size());
190  }
191 
192  txCtAvg.resize(buckets.size());
193  avg.resize(buckets.size());
194 
196 }
197 
198 void TxConfirmStats::resizeInMemoryCounters(size_t newbuckets) {
199  // newbuckets must be passed in because the buckets referred to during Read have not been updated yet.
200  unconfTxs.resize(GetMaxConfirms());
201  for (unsigned int i = 0; i < unconfTxs.size(); i++) {
202  unconfTxs[i].resize(newbuckets);
203  }
204  oldUnconfTxs.resize(newbuckets);
205 }
206 
207 // Roll the unconfirmed txs circular buffer
208 void TxConfirmStats::ClearCurrent(unsigned int nBlockHeight)
209 {
210  for (unsigned int j = 0; j < buckets.size(); j++) {
211  oldUnconfTxs[j] += unconfTxs[nBlockHeight%unconfTxs.size()][j];
212  unconfTxs[nBlockHeight%unconfTxs.size()][j] = 0;
213  }
214 }
215 
216 
217 void TxConfirmStats::Record(int blocksToConfirm, double val)
218 {
219  // blocksToConfirm is 1-based
220  if (blocksToConfirm < 1)
221  return;
222  int periodsToConfirm = (blocksToConfirm + scale - 1)/scale;
223  unsigned int bucketindex = bucketMap.lower_bound(val)->second;
224  for (size_t i = periodsToConfirm; i <= confAvg.size(); i++) {
225  confAvg[i - 1][bucketindex]++;
226  }
227  txCtAvg[bucketindex]++;
228  avg[bucketindex] += val;
229 }
230 
232 {
233  for (unsigned int j = 0; j < buckets.size(); j++) {
234  for (unsigned int i = 0; i < confAvg.size(); i++)
235  confAvg[i][j] = confAvg[i][j] * decay;
236  for (unsigned int i = 0; i < failAvg.size(); i++)
237  failAvg[i][j] = failAvg[i][j] * decay;
238  avg[j] = avg[j] * decay;
239  txCtAvg[j] = txCtAvg[j] * decay;
240  }
241 }
242 
243 // returns -1 on error conditions
244 double TxConfirmStats::EstimateMedianVal(int confTarget, double sufficientTxVal,
245  double successBreakPoint, bool requireGreater,
246  unsigned int nBlockHeight, EstimationResult *result) const
247 {
248  // Counters for a bucket (or range of buckets)
249  double nConf = 0; // Number of tx's confirmed within the confTarget
250  double totalNum = 0; // Total number of tx's that were ever confirmed
251  int extraNum = 0; // Number of tx's still in mempool for confTarget or longer
252  double failNum = 0; // Number of tx's that were never confirmed but removed from the mempool after confTarget
253  int periodTarget = (confTarget + scale - 1)/scale;
254 
255  int maxbucketindex = buckets.size() - 1;
256 
257  // requireGreater means we are looking for the lowest feerate such that all higher
258  // values pass, so we start at maxbucketindex (highest feerate) and look at successively
259  // smaller buckets until we reach failure. Otherwise, we are looking for the highest
260  // feerate such that all lower values fail, and we go in the opposite direction.
261  unsigned int startbucket = requireGreater ? maxbucketindex : 0;
262  int step = requireGreater ? -1 : 1;
263 
264  // We'll combine buckets until we have enough samples.
265  // The near and far variables will define the range we've combined
266  // The best variables are the last range we saw which still had a high
267  // enough confirmation rate to count as success.
268  // The cur variables are the current range we're counting.
269  unsigned int curNearBucket = startbucket;
270  unsigned int bestNearBucket = startbucket;
271  unsigned int curFarBucket = startbucket;
272  unsigned int bestFarBucket = startbucket;
273 
274  bool foundAnswer = false;
275  unsigned int bins = unconfTxs.size();
276  bool newBucketRange = true;
277  bool passing = true;
278  EstimatorBucket passBucket;
279  EstimatorBucket failBucket;
280 
281  // Start counting from highest(default) or lowest feerate transactions
282  for (int bucket = startbucket; bucket >= 0 && bucket <= maxbucketindex; bucket += step) {
283  if (newBucketRange) {
284  curNearBucket = bucket;
285  newBucketRange = false;
286  }
287  curFarBucket = bucket;
288  nConf += confAvg[periodTarget - 1][bucket];
289  totalNum += txCtAvg[bucket];
290  failNum += failAvg[periodTarget - 1][bucket];
291  for (unsigned int confct = confTarget; confct < GetMaxConfirms(); confct++)
292  extraNum += unconfTxs[(nBlockHeight - confct)%bins][bucket];
293  extraNum += oldUnconfTxs[bucket];
294  // If we have enough transaction data points in this range of buckets,
295  // we can test for success
296  // (Only count the confirmed data points, so that each confirmation count
297  // will be looking at the same amount of data and same bucket breaks)
298  if (totalNum >= sufficientTxVal / (1 - decay)) {
299  double curPct = nConf / (totalNum + failNum + extraNum);
300 
301  // Check to see if we are no longer getting confirmed at the success rate
302  if ((requireGreater && curPct < successBreakPoint) || (!requireGreater && curPct > successBreakPoint)) {
303  if (passing == true) {
304  // First time we hit a failure record the failed bucket
305  unsigned int failMinBucket = std::min(curNearBucket, curFarBucket);
306  unsigned int failMaxBucket = std::max(curNearBucket, curFarBucket);
307  failBucket.start = failMinBucket ? buckets[failMinBucket - 1] : 0;
308  failBucket.end = buckets[failMaxBucket];
309  failBucket.withinTarget = nConf;
310  failBucket.totalConfirmed = totalNum;
311  failBucket.inMempool = extraNum;
312  failBucket.leftMempool = failNum;
313  passing = false;
314  }
315  continue;
316  }
317  // Otherwise update the cumulative stats, and the bucket variables
318  // and reset the counters
319  else {
320  failBucket = EstimatorBucket(); // Reset any failed bucket, currently passing
321  foundAnswer = true;
322  passing = true;
323  passBucket.withinTarget = nConf;
324  nConf = 0;
325  passBucket.totalConfirmed = totalNum;
326  totalNum = 0;
327  passBucket.inMempool = extraNum;
328  passBucket.leftMempool = failNum;
329  failNum = 0;
330  extraNum = 0;
331  bestNearBucket = curNearBucket;
332  bestFarBucket = curFarBucket;
333  newBucketRange = true;
334  }
335  }
336  }
337 
338  double median = -1;
339  double txSum = 0;
340 
341  // Calculate the "average" feerate of the best bucket range that met success conditions
342  // Find the bucket with the median transaction and then report the average feerate from that bucket
343  // This is a compromise between finding the median which we can't since we don't save all tx's
344  // and reporting the average which is less accurate
345  unsigned int minBucket = std::min(bestNearBucket, bestFarBucket);
346  unsigned int maxBucket = std::max(bestNearBucket, bestFarBucket);
347  for (unsigned int j = minBucket; j <= maxBucket; j++) {
348  txSum += txCtAvg[j];
349  }
350  if (foundAnswer && txSum != 0) {
351  txSum = txSum / 2;
352  for (unsigned int j = minBucket; j <= maxBucket; j++) {
353  if (txCtAvg[j] < txSum)
354  txSum -= txCtAvg[j];
355  else { // we're in the right bucket
356  median = avg[j] / txCtAvg[j];
357  break;
358  }
359  }
360 
361  passBucket.start = minBucket ? buckets[minBucket-1] : 0;
362  passBucket.end = buckets[maxBucket];
363  }
364 
365  // If we were passing until we reached last few buckets with insufficient data, then report those as failed
366  if (passing && !newBucketRange) {
367  unsigned int failMinBucket = std::min(curNearBucket, curFarBucket);
368  unsigned int failMaxBucket = std::max(curNearBucket, curFarBucket);
369  failBucket.start = failMinBucket ? buckets[failMinBucket - 1] : 0;
370  failBucket.end = buckets[failMaxBucket];
371  failBucket.withinTarget = nConf;
372  failBucket.totalConfirmed = totalNum;
373  failBucket.inMempool = extraNum;
374  failBucket.leftMempool = failNum;
375  }
376 
377  LogPrint(BCLog::ESTIMATEFEE, "FeeEst: %d %s%.0f%% decay %.5f: feerate: %g from (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out) Fail: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out)\n",
378  confTarget, requireGreater ? ">" : "<", 100.0 * successBreakPoint, decay,
379  median, passBucket.start, passBucket.end,
380  100 * passBucket.withinTarget / (passBucket.totalConfirmed + passBucket.inMempool + passBucket.leftMempool),
381  passBucket.withinTarget, passBucket.totalConfirmed, passBucket.inMempool, passBucket.leftMempool,
382  failBucket.start, failBucket.end,
383  100 * failBucket.withinTarget / (failBucket.totalConfirmed + failBucket.inMempool + failBucket.leftMempool),
384  failBucket.withinTarget, failBucket.totalConfirmed, failBucket.inMempool, failBucket.leftMempool);
385 
386 
387  if (result) {
388  result->pass = passBucket;
389  result->fail = failBucket;
390  result->decay = decay;
391  result->scale = scale;
392  }
393  return median;
394 }
395 
396 void TxConfirmStats::Write(CAutoFile& fileout) const
397 {
398  fileout << decay;
399  fileout << scale;
400  fileout << avg;
401  fileout << txCtAvg;
402  fileout << confAvg;
403  fileout << failAvg;
404 }
405 
406 void TxConfirmStats::Read(CAutoFile& filein, int nFileVersion, size_t numBuckets)
407 {
408  // Read data file and do some very basic sanity checking
409  // buckets and bucketMap are not updated yet, so don't access them
410  // If there is a read failure, we'll just discard this entire object anyway
411  size_t maxConfirms, maxPeriods;
412 
413  // The current version will store the decay with each individual TxConfirmStats and also keep a scale factor
414  filein >> decay;
415  if (decay <= 0 || decay >= 1) {
416  throw std::runtime_error("Corrupt estimates file. Decay must be between 0 and 1 (non-inclusive)");
417  }
418  filein >> scale;
419  if (scale == 0) {
420  throw std::runtime_error("Corrupt estimates file. Scale must be non-zero");
421  }
422 
423  filein >> avg;
424  if (avg.size() != numBuckets) {
425  throw std::runtime_error("Corrupt estimates file. Mismatch in feerate average bucket count");
426  }
427  filein >> txCtAvg;
428  if (txCtAvg.size() != numBuckets) {
429  throw std::runtime_error("Corrupt estimates file. Mismatch in tx count bucket count");
430  }
431  filein >> confAvg;
432  maxPeriods = confAvg.size();
433  maxConfirms = scale * maxPeriods;
434 
435  if (maxConfirms <= 0 || maxConfirms > 6 * 24 * 7) { // one week
436  throw std::runtime_error("Corrupt estimates file. Must maintain estimates for between 1 and 1008 (one week) confirms");
437  }
438  for (unsigned int i = 0; i < maxPeriods; i++) {
439  if (confAvg[i].size() != numBuckets) {
440  throw std::runtime_error("Corrupt estimates file. Mismatch in feerate conf average bucket count");
441  }
442  }
443 
444  filein >> failAvg;
445  if (maxPeriods != failAvg.size()) {
446  throw std::runtime_error("Corrupt estimates file. Mismatch in confirms tracked for failures");
447  }
448  for (unsigned int i = 0; i < maxPeriods; i++) {
449  if (failAvg[i].size() != numBuckets) {
450  throw std::runtime_error("Corrupt estimates file. Mismatch in one of failure average bucket counts");
451  }
452  }
453 
454  // Resize the current block variables which aren't stored in the data file
455  // to match the number of confirms and buckets
456  resizeInMemoryCounters(numBuckets);
457 
458  LogPrint(BCLog::ESTIMATEFEE, "Reading estimates: %u buckets counting confirms up to %u blocks\n",
459  numBuckets, maxConfirms);
460 }
461 
462 unsigned int TxConfirmStats::NewTx(unsigned int nBlockHeight, double val)
463 {
464  unsigned int bucketindex = bucketMap.lower_bound(val)->second;
465  unsigned int blockIndex = nBlockHeight % unconfTxs.size();
466  unconfTxs[blockIndex][bucketindex]++;
467  return bucketindex;
468 }
469 
470 void TxConfirmStats::removeTx(unsigned int entryHeight, unsigned int nBestSeenHeight, unsigned int bucketindex, bool inBlock)
471 {
472  //nBestSeenHeight is not updated yet for the new block
473  int blocksAgo = nBestSeenHeight - entryHeight;
474  if (nBestSeenHeight == 0) // the BlockPolicyEstimator hasn't seen any blocks yet
475  blocksAgo = 0;
476  if (blocksAgo < 0) {
477  LogPrint(BCLog::ESTIMATEFEE, "Blockpolicy error, blocks ago is negative for mempool tx\n");
478  return; //This can't happen because we call this with our best seen height, no entries can have higher
479  }
480 
481  if (blocksAgo >= (int)unconfTxs.size()) {
482  if (oldUnconfTxs[bucketindex] > 0) {
483  oldUnconfTxs[bucketindex]--;
484  } else {
485  LogPrint(BCLog::ESTIMATEFEE, "Blockpolicy error, mempool tx removed from >25 blocks,bucketIndex=%u already\n",
486  bucketindex);
487  }
488  }
489  else {
490  unsigned int blockIndex = entryHeight % unconfTxs.size();
491  if (unconfTxs[blockIndex][bucketindex] > 0) {
492  unconfTxs[blockIndex][bucketindex]--;
493  } else {
494  LogPrint(BCLog::ESTIMATEFEE, "Blockpolicy error, mempool tx removed from blockIndex=%u,bucketIndex=%u already\n",
495  blockIndex, bucketindex);
496  }
497  }
498  if (!inBlock && (unsigned int)blocksAgo >= scale) { // Only counts as a failure if not confirmed for entire period
499  assert(scale != 0);
500  unsigned int periodsAgo = blocksAgo / scale;
501  for (size_t i = 0; i < periodsAgo && i < failAvg.size(); i++) {
502  failAvg[i][bucketindex]++;
503  }
504  }
505 }
506 
507 // This function is called from CTxMemPool::removeUnchecked to ensure
508 // txs removed from the mempool for any reason are no longer
509 // tracked. Txs that were part of a block have already been removed in
510 // processBlockTx to ensure they are never double tracked, but it is
511 // of no harm to try to remove them again.
512 bool CBlockPolicyEstimator::removeTx(uint256 hash, bool inBlock)
513 {
515  std::map<uint256, TxStatsInfo>::iterator pos = mapMemPoolTxs.find(hash);
516  if (pos != mapMemPoolTxs.end()) {
517  feeStats->removeTx(pos->second.blockHeight, nBestSeenHeight, pos->second.bucketIndex, inBlock);
518  shortStats->removeTx(pos->second.blockHeight, nBestSeenHeight, pos->second.bucketIndex, inBlock);
519  longStats->removeTx(pos->second.blockHeight, nBestSeenHeight, pos->second.bucketIndex, inBlock);
520  mapMemPoolTxs.erase(hash);
521  return true;
522  } else {
523  return false;
524  }
525 }
526 
528  : nBestSeenHeight(0), firstRecordedHeight(0), historicalFirst(0), historicalBest(0), trackedTxs(0), untrackedTxs(0)
529 {
530  static_assert(MIN_BUCKET_FEERATE > 0, "Min feerate must be nonzero");
531  size_t bucketIndex = 0;
532  for (double bucketBoundary = MIN_BUCKET_FEERATE; bucketBoundary <= MAX_BUCKET_FEERATE; bucketBoundary *= FEE_SPACING, bucketIndex++) {
533  buckets.push_back(bucketBoundary);
534  bucketMap[bucketBoundary] = bucketIndex;
535  }
536  buckets.push_back(INF_FEERATE);
537  bucketMap[INF_FEERATE] = bucketIndex;
538  assert(bucketMap.size() == buckets.size());
539 
540  feeStats = std::unique_ptr<TxConfirmStats>(new TxConfirmStats(buckets, bucketMap, MED_BLOCK_PERIODS, MED_DECAY, MED_SCALE));
541  shortStats = std::unique_ptr<TxConfirmStats>(new TxConfirmStats(buckets, bucketMap, SHORT_BLOCK_PERIODS, SHORT_DECAY, SHORT_SCALE));
542  longStats = std::unique_ptr<TxConfirmStats>(new TxConfirmStats(buckets, bucketMap, LONG_BLOCK_PERIODS, LONG_DECAY, LONG_SCALE));
543 }
544 
546 {
547 }
548 
549 void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, bool validFeeEstimate)
550 {
552  unsigned int txHeight = entry.GetHeight();
553  uint256 hash = entry.GetTx().GetHash();
554  if (mapMemPoolTxs.count(hash)) {
555  LogPrint(BCLog::ESTIMATEFEE, "Blockpolicy error mempool tx %s already being tracked\n",
556  hash.ToString().c_str());
557  return;
558  }
559 
560  if (txHeight != nBestSeenHeight) {
561  // Ignore side chains and re-orgs; assuming they are random they don't
562  // affect the estimate. We'll potentially double count transactions in 1-block reorgs.
563  // Ignore txs if BlockPolicyEstimator is not in sync with chainActive.Tip().
564  // It will be synced next time a block is processed.
565  return;
566  }
567 
568  // Only want to be updating estimates when our blockchain is synced,
569  // otherwise we'll miscalculate how many blocks its taking to get included.
570  if (!validFeeEstimate) {
571  untrackedTxs++;
572  return;
573  }
574  trackedTxs++;
575 
576  // Feerates are stored and reported as BTC-per-kb:
577  CFeeRate feeRate(entry.GetFee(), entry.GetTxSize());
578 
579  mapMemPoolTxs[hash].blockHeight = txHeight;
580  unsigned int bucketIndex = feeStats->NewTx(txHeight, (double)feeRate.GetFeePerK());
581  mapMemPoolTxs[hash].bucketIndex = bucketIndex;
582  unsigned int bucketIndex2 = shortStats->NewTx(txHeight, (double)feeRate.GetFeePerK());
583  assert(bucketIndex == bucketIndex2);
584  unsigned int bucketIndex3 = longStats->NewTx(txHeight, (double)feeRate.GetFeePerK());
585  assert(bucketIndex == bucketIndex3);
586 }
587 
588 bool CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry* entry)
589 {
590  if (!removeTx(entry->GetTx().GetHash(), true)) {
591  // This transaction wasn't being tracked for fee estimation
592  return false;
593  }
594 
595  // How many blocks did it take for miners to include this transaction?
596  // blocksToConfirm is 1-based, so a transaction included in the earliest
597  // possible block has confirmation count of 1
598  int blocksToConfirm = nBlockHeight - entry->GetHeight();
599  if (blocksToConfirm <= 0) {
600  // This can't happen because we don't process transactions from a block with a height
601  // lower than our greatest seen height
602  LogPrint(BCLog::ESTIMATEFEE, "Blockpolicy error Transaction had negative blocksToConfirm\n");
603  return false;
604  }
605 
606  // Feerates are stored and reported as BTC-per-kb:
607  CFeeRate feeRate(entry->GetFee(), entry->GetTxSize());
608 
609  feeStats->Record(blocksToConfirm, (double)feeRate.GetFeePerK());
610  shortStats->Record(blocksToConfirm, (double)feeRate.GetFeePerK());
611  longStats->Record(blocksToConfirm, (double)feeRate.GetFeePerK());
612  return true;
613 }
614 
615 void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight,
616  std::vector<const CTxMemPoolEntry*>& entries)
617 {
619  if (nBlockHeight <= nBestSeenHeight) {
620  // Ignore side chains and re-orgs; assuming they are random
621  // they don't affect the estimate.
622  // And if an attacker can re-org the chain at will, then
623  // you've got much bigger problems than "attacker can influence
624  // transaction fees."
625  return;
626  }
627 
628  // Must update nBestSeenHeight in sync with ClearCurrent so that
629  // calls to removeTx (via processBlockTx) correctly calculate age
630  // of unconfirmed txs to remove from tracking.
631  nBestSeenHeight = nBlockHeight;
632 
633  // Update unconfirmed circular buffer
634  feeStats->ClearCurrent(nBlockHeight);
635  shortStats->ClearCurrent(nBlockHeight);
636  longStats->ClearCurrent(nBlockHeight);
637 
638  // Decay all exponential averages
639  feeStats->UpdateMovingAverages();
640  shortStats->UpdateMovingAverages();
641  longStats->UpdateMovingAverages();
642 
643  unsigned int countedTxs = 0;
644  // Update averages with data points from current block
645  for (const auto& entry : entries) {
646  if (processBlockTx(nBlockHeight, entry))
647  countedTxs++;
648  }
649 
650  if (firstRecordedHeight == 0 && countedTxs > 0) {
652  LogPrint(BCLog::ESTIMATEFEE, "Blockpolicy first recorded height %u\n", firstRecordedHeight);
653  }
654 
655 
656  LogPrint(BCLog::ESTIMATEFEE, "Blockpolicy estimates updated by %u of %u block txs, since last block %u of %u tracked, mempool map size %u, max target %u from %s\n",
657  countedTxs, entries.size(), trackedTxs, trackedTxs + untrackedTxs, mapMemPoolTxs.size(),
658  MaxUsableEstimate(), HistoricalBlockSpan() > BlockSpan() ? "historical" : "current");
659 
660  trackedTxs = 0;
661  untrackedTxs = 0;
662 }
663 
665 {
666  // It's not possible to get reasonable estimates for confTarget of 1
667  if (confTarget <= 1)
668  return CFeeRate(0);
669 
671 }
672 
673 CFeeRate CBlockPolicyEstimator::estimateRawFee(int confTarget, double successThreshold, FeeEstimateHorizon horizon, EstimationResult* result) const
674 {
675  TxConfirmStats* stats;
676  double sufficientTxs = SUFFICIENT_FEETXS;
677  switch (horizon) {
679  stats = shortStats.get();
680  sufficientTxs = SUFFICIENT_TXS_SHORT;
681  break;
682  }
684  stats = feeStats.get();
685  break;
686  }
688  stats = longStats.get();
689  break;
690  }
691  default: {
692  throw std::out_of_range("CBlockPolicyEstimator::estimateRawFee unknown FeeEstimateHorizon");
693  }
694  }
695 
697  // Return failure if trying to analyze a target we're not tracking
698  if (confTarget <= 0 || (unsigned int)confTarget > stats->GetMaxConfirms())
699  return CFeeRate(0);
700  if (successThreshold > 1)
701  return CFeeRate(0);
702 
703  double median = stats->EstimateMedianVal(confTarget, sufficientTxs, successThreshold, true, nBestSeenHeight, result);
704 
705  if (median < 0)
706  return CFeeRate(0);
707 
708  return CFeeRate(llround(median));
709 }
710 
712 {
713  switch (horizon) {
715  return shortStats->GetMaxConfirms();
716  }
718  return feeStats->GetMaxConfirms();
719  }
721  return longStats->GetMaxConfirms();
722  }
723  default: {
724  throw std::out_of_range("CBlockPolicyEstimator::HighestTargetTracked unknown FeeEstimateHorizon");
725  }
726  }
727 }
728 
730 {
731  if (firstRecordedHeight == 0) return 0;
733 
735 }
736 
738 {
739  if (historicalFirst == 0) return 0;
740  assert(historicalBest >= historicalFirst);
741 
743 
745 }
746 
748 {
749  // Block spans are divided by 2 to make sure there are enough potential failing data points for the estimate
750  return std::min(longStats->GetMaxConfirms(), std::max(BlockSpan(), HistoricalBlockSpan()) / 2);
751 }
752 
757 double CBlockPolicyEstimator::estimateCombinedFee(unsigned int confTarget, double successThreshold, bool checkShorterHorizon, EstimationResult *result) const
758 {
759  double estimate = -1;
760  if (confTarget >= 1 && confTarget <= longStats->GetMaxConfirms()) {
761  // Find estimate from shortest time horizon possible
762  if (confTarget <= shortStats->GetMaxConfirms()) { // short horizon
763  estimate = shortStats->EstimateMedianVal(confTarget, SUFFICIENT_TXS_SHORT, successThreshold, true, nBestSeenHeight, result);
764  }
765  else if (confTarget <= feeStats->GetMaxConfirms()) { // medium horizon
766  estimate = feeStats->EstimateMedianVal(confTarget, SUFFICIENT_FEETXS, successThreshold, true, nBestSeenHeight, result);
767  }
768  else { // long horizon
769  estimate = longStats->EstimateMedianVal(confTarget, SUFFICIENT_FEETXS, successThreshold, true, nBestSeenHeight, result);
770  }
771  if (checkShorterHorizon) {
772  EstimationResult tempResult;
773  // If a lower confTarget from a more recent horizon returns a lower answer use it.
774  if (confTarget > feeStats->GetMaxConfirms()) {
775  double medMax = feeStats->EstimateMedianVal(feeStats->GetMaxConfirms(), SUFFICIENT_FEETXS, successThreshold, true, nBestSeenHeight, &tempResult);
776  if (medMax > 0 && (estimate == -1 || medMax < estimate)) {
777  estimate = medMax;
778  if (result) *result = tempResult;
779  }
780  }
781  if (confTarget > shortStats->GetMaxConfirms()) {
782  double shortMax = shortStats->EstimateMedianVal(shortStats->GetMaxConfirms(), SUFFICIENT_TXS_SHORT, successThreshold, true, nBestSeenHeight, &tempResult);
783  if (shortMax > 0 && (estimate == -1 || shortMax < estimate)) {
784  estimate = shortMax;
785  if (result) *result = tempResult;
786  }
787  }
788  }
789  }
790  return estimate;
791 }
792 
796 double CBlockPolicyEstimator::estimateConservativeFee(unsigned int doubleTarget, EstimationResult *result) const
797 {
798  double estimate = -1;
799  EstimationResult tempResult;
800  if (doubleTarget <= shortStats->GetMaxConfirms()) {
801  estimate = feeStats->EstimateMedianVal(doubleTarget, SUFFICIENT_FEETXS, DOUBLE_SUCCESS_PCT, true, nBestSeenHeight, result);
802  }
803  if (doubleTarget <= feeStats->GetMaxConfirms()) {
804  double longEstimate = longStats->EstimateMedianVal(doubleTarget, SUFFICIENT_FEETXS, DOUBLE_SUCCESS_PCT, true, nBestSeenHeight, &tempResult);
805  if (longEstimate > estimate) {
806  estimate = longEstimate;
807  if (result) *result = tempResult;
808  }
809  }
810  return estimate;
811 }
812 
820 CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, FeeCalculation *feeCalc, bool conservative) const
821 {
823 
824  if (feeCalc) {
825  feeCalc->desiredTarget = confTarget;
826  feeCalc->returnedTarget = confTarget;
827  }
828 
829  double median = -1;
830  EstimationResult tempResult;
831 
832  // Return failure if trying to analyze a target we're not tracking
833  if (confTarget <= 0 || (unsigned int)confTarget > longStats->GetMaxConfirms()) {
834  return CFeeRate(0); // error condition
835  }
836 
837  // It's not possible to get reasonable estimates for confTarget of 1
838  if (confTarget == 1) confTarget = 2;
839 
840  unsigned int maxUsableEstimate = MaxUsableEstimate();
841  if ((unsigned int)confTarget > maxUsableEstimate) {
842  confTarget = maxUsableEstimate;
843  }
844  if (feeCalc) feeCalc->returnedTarget = confTarget;
845 
846  if (confTarget <= 1) return CFeeRate(0); // error condition
847 
848  assert(confTarget > 0); //estimateCombinedFee and estimateConservativeFee take unsigned ints
859  double halfEst = estimateCombinedFee(confTarget/2, HALF_SUCCESS_PCT, true, &tempResult);
860  if (feeCalc) {
861  feeCalc->est = tempResult;
862  feeCalc->reason = FeeReason::HALF_ESTIMATE;
863  }
864  median = halfEst;
865  double actualEst = estimateCombinedFee(confTarget, SUCCESS_PCT, true, &tempResult);
866  if (actualEst > median) {
867  median = actualEst;
868  if (feeCalc) {
869  feeCalc->est = tempResult;
870  feeCalc->reason = FeeReason::FULL_ESTIMATE;
871  }
872  }
873  double doubleEst = estimateCombinedFee(2 * confTarget, DOUBLE_SUCCESS_PCT, !conservative, &tempResult);
874  if (doubleEst > median) {
875  median = doubleEst;
876  if (feeCalc) {
877  feeCalc->est = tempResult;
879  }
880  }
881 
882  if (conservative || median == -1) {
883  double consEst = estimateConservativeFee(2 * confTarget, &tempResult);
884  if (consEst > median) {
885  median = consEst;
886  if (feeCalc) {
887  feeCalc->est = tempResult;
888  feeCalc->reason = FeeReason::CONSERVATIVE;
889  }
890  }
891  }
892 
893  if (median < 0) return CFeeRate(0); // error condition
894 
895  return CFeeRate(llround(median));
896 }
897 
898 
900 {
901  try {
903  fileout << 149900; // version required to read: 0.14.99 or later
904  fileout << CLIENT_VERSION; // version that wrote the file
905  fileout << nBestSeenHeight;
906  if (BlockSpan() > HistoricalBlockSpan()/2) {
907  fileout << firstRecordedHeight << nBestSeenHeight;
908  }
909  else {
910  fileout << historicalFirst << historicalBest;
911  }
912  fileout << buckets;
913  feeStats->Write(fileout);
914  shortStats->Write(fileout);
915  longStats->Write(fileout);
916  }
917  catch (const std::exception&) {
918  LogPrintf("CBlockPolicyEstimator::Write(): unable to write policy estimator data (non-fatal)\n");
919  return false;
920  }
921  return true;
922 }
923 
925 {
926  try {
928  int nVersionRequired, nVersionThatWrote;
929  filein >> nVersionRequired >> nVersionThatWrote;
930  if (nVersionRequired > CLIENT_VERSION)
931  return error("CBlockPolicyEstimator::Read(): up-version (%d) fee estimate file", nVersionRequired);
932 
933  // Read fee estimates file into temporary variables so existing data
934  // structures aren't corrupted if there is an exception.
935  unsigned int nFileBestSeenHeight;
936  filein >> nFileBestSeenHeight;
937 
938  if (nVersionRequired < 149900) {
939  LogPrintf("%s: incompatible old fee estimation data (non-fatal). Version: %d\n", __func__, nVersionRequired);
940  } else { // New format introduced in 149900
941  unsigned int nFileHistoricalFirst, nFileHistoricalBest;
942  filein >> nFileHistoricalFirst >> nFileHistoricalBest;
943  if (nFileHistoricalFirst > nFileHistoricalBest || nFileHistoricalBest > nFileBestSeenHeight) {
944  throw std::runtime_error("Corrupt estimates file. Historical block range for estimates is invalid");
945  }
946  std::vector<double> fileBuckets;
947  filein >> fileBuckets;
948  size_t numBuckets = fileBuckets.size();
949  if (numBuckets <= 1 || numBuckets > 1000)
950  throw std::runtime_error("Corrupt estimates file. Must have between 2 and 1000 feerate buckets");
951 
952  std::unique_ptr<TxConfirmStats> fileFeeStats(new TxConfirmStats(buckets, bucketMap, MED_BLOCK_PERIODS, MED_DECAY, MED_SCALE));
953  std::unique_ptr<TxConfirmStats> fileShortStats(new TxConfirmStats(buckets, bucketMap, SHORT_BLOCK_PERIODS, SHORT_DECAY, SHORT_SCALE));
954  std::unique_ptr<TxConfirmStats> fileLongStats(new TxConfirmStats(buckets, bucketMap, LONG_BLOCK_PERIODS, LONG_DECAY, LONG_SCALE));
955  fileFeeStats->Read(filein, nVersionThatWrote, numBuckets);
956  fileShortStats->Read(filein, nVersionThatWrote, numBuckets);
957  fileLongStats->Read(filein, nVersionThatWrote, numBuckets);
958 
959  // Fee estimates file parsed correctly
960  // Copy buckets from file and refresh our bucketmap
961  buckets = fileBuckets;
962  bucketMap.clear();
963  for (unsigned int i = 0; i < buckets.size(); i++) {
964  bucketMap[buckets[i]] = i;
965  }
966 
967  // Destroy old TxConfirmStats and point to new ones that already reference buckets and bucketMap
968  feeStats = std::move(fileFeeStats);
969  shortStats = std::move(fileShortStats);
970  longStats = std::move(fileLongStats);
971 
972  nBestSeenHeight = nFileBestSeenHeight;
973  historicalFirst = nFileHistoricalFirst;
974  historicalBest = nFileHistoricalBest;
975  }
976  }
977  catch (const std::exception& e) {
978  LogPrintf("CBlockPolicyEstimator::Read(): unable to read policy estimator data (non-fatal): %s\n",e.what());
979  return false;
980  }
981  return true;
982 }
983 
985  int64_t startclear = GetTimeMicros();
987  size_t num_entries = mapMemPoolTxs.size();
988  // Remove every entry in mapMemPoolTxs
989  while (!mapMemPoolTxs.empty()) {
990  auto mi = mapMemPoolTxs.begin();
991  removeTx(mi->first, false); // this calls erase() on mapMemPoolTxs
992  }
993  int64_t endclear = GetTimeMicros();
994  LogPrint(BCLog::ESTIMATEFEE, "Recorded %u unconfirmed txs from mempool in %gs\n", num_entries, (endclear - startclear)*0.000001);
995 }
996 
998 {
999  CAmount minFeeLimit = std::max(CAmount(1), minIncrementalFee.GetFeePerK() / 2);
1000  feeset.insert(0);
1001  for (double bucketBoundary = minFeeLimit; bucketBoundary <= MAX_FILTER_FEERATE; bucketBoundary *= FEE_FILTER_SPACING) {
1002  feeset.insert(bucketBoundary);
1003  }
1004 }
1005 
1007 {
1008  std::set<double>::iterator it = feeset.lower_bound(currentMinFee);
1009  if ((it != feeset.begin() && insecure_rand.rand32() % 3 != 0) || it == feeset.end()) {
1010  it--;
1011  }
1012  return static_cast<CAmount>(*it);
1013 }
static constexpr double MED_DECAY
Decay of .998 is a half-life of 144 blocks or about 1 day.
Definition: fees.h:154
EstimatorBucket pass
Definition: fees.h:74
std::vector< std::vector< double > > failAvg
Definition: fees.cpp:90
EstimationResult est
Definition: fees.h:82
bool FeeModeFromString(const std::string &mode_string, FeeEstimateMode &fee_estimate_mode)
Definition: fees.cpp:50
int returnedTarget
Definition: fees.h:85
CCriticalSection cs_feeEstimator
Definition: fees.h:257
static constexpr double MAX_BUCKET_FEERATE
Definition: fees.h:178
static constexpr double HALF_SUCCESS_PCT
Require greater than 60% of X feerate transactions to be confirmed within Y/2 blocks.
Definition: fees.h:159
size_t GetTxSize() const
Definition: txmempool.cpp:51
unsigned int firstRecordedHeight
Definition: fees.h:232
static constexpr unsigned int MED_BLOCK_PERIODS
Track confirm delays up to 48 blocks for medium horizon.
Definition: fees.h:143
double start
Definition: fees.h:63
bool removeTx(uint256 hash, bool inBlock)
Remove a transaction from the mempool tracking stats.
Definition: fees.cpp:512
CBlockPolicyEstimator()
Create new BlockPolicyEstimator and initialize stats tracking classes with default values...
Definition: fees.cpp:527
TxConfirmStats(const std::vector< double > &defaultBuckets, const std::map< double, unsigned int > &defaultBucketMap, unsigned int maxPeriods, double decay, unsigned int scale)
Create new TxConfirmStats.
Definition: fees.cpp:175
bool Write(CAutoFile &fileout) const
Write estimation data to a file.
Definition: fees.cpp:899
FeeEstimateMode
Definition: fees.h:52
void FlushUnconfirmed()
Empty mempool transactions on shutdown to record failure to confirm for txs still in mempool...
Definition: fees.cpp:984
std::vector< double > avg
Definition: fees.cpp:94
FeeReason reason
Definition: fees.h:83
static constexpr double MAX_FILTER_FEERATE
Definition: fees.h:277
We will instantiate an instance of this class to track transactions that were included in a block...
Definition: fees.cpp:72
std::map< double, unsigned int > bucketMap
Definition: fees.h:255
std::unique_ptr< TxConfirmStats > shortStats
Definition: fees.h:248
std::string StringForFeeReason(FeeReason reason)
Definition: fees.cpp:30
std::string StringForFeeEstimateHorizon(FeeEstimateHorizon horizon)
Definition: fees.cpp:17
std::unique_ptr< TxConfirmStats > longStats
Definition: fees.h:249
static constexpr double DOUBLE_SUCCESS_PCT
Require greater than 95% of X feerate transactions to be confirmed within 2 * Y blocks.
Definition: fees.h:163
static constexpr double FEE_SPACING
Spacing of FeeRate buckets We have to lump transactions into buckets based on feerate, but we want to be able to give accurate estimates over a large range of potential feerates Therefore it makes sense to exponentially space the buckets.
Definition: fees.h:185
int64_t GetTimeMicros()
Definition: utiltime.cpp:48
unsigned int nBestSeenHeight
Definition: fees.h:231
double decay
Definition: fees.cpp:99
void Record(int blocksToConfirm, double val)
Record a new transaction data point in the current block stats.
Definition: fees.cpp:217
static constexpr double MIN_BUCKET_FEERATE
Minimum and Maximum values for tracking feerates The MIN_BUCKET_FEERATE should just be set to the low...
Definition: fees.h:177
double withinTarget
Definition: fees.h:65
void resizeInMemoryCounters(size_t newbuckets)
Definition: fees.cpp:198
unsigned int MaxUsableEstimate() const
Calculation of highest target that reasonable estimate can be provided for.
Definition: fees.cpp:747
void ClearCurrent(unsigned int nBlockHeight)
Roll the circular buffer for unconfirmed txs.
Definition: fees.cpp:208
int desiredTarget
Definition: fees.h:84
static constexpr double SUFFICIENT_TXS_SHORT
Require an avg of 0.5 tx when using short decay since there are fewer blocks considered.
Definition: fees.h:168
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
Definition: txmempool.h:65
static constexpr double FEE_FILTER_SPACING
FEE_FILTER_SPACING is just used to provide some quantization of fee filter results.
Definition: fees.h:282
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
Force estimateSmartFee to use conservative estimates.
static constexpr double SUCCESS_PCT
Require greater than 85% of X feerate transactions to be confirmed within Y blocks.
Definition: fees.h:161
void Read(CAutoFile &filein, int nFileVersion, size_t numBuckets)
Read saved state of estimation data from a file and replace all internal data structures and variable...
Definition: fees.cpp:406
std::unique_ptr< TxConfirmStats > feeStats
Classes to track historical data on transaction confirmations.
Definition: fees.h:247
const std::map< double, unsigned int > & bucketMap
Definition: fees.cpp:77
static constexpr unsigned int SHORT_SCALE
Definition: fees.h:141
static constexpr double LONG_DECAY
Decay of .9995 is a half-life of 1008 blocks or about 1 week.
Definition: fees.h:156
std::vector< std::vector< double > > confAvg
Definition: fees.cpp:86
unsigned int NewTx(unsigned int nBlockHeight, double val)
Record a new transaction entering the mempool.
Definition: fees.cpp:462
unsigned int GetHeight() const
Definition: txmempool.h:104
unsigned int HistoricalBlockSpan() const
Number of blocks of recorded fee estimate data represented in saved data file.
Definition: fees.cpp:737
double end
Definition: fees.h:64
EstimatorBucket fail
Definition: fees.h:75
CFeeRate estimateRawFee(int confTarget, double successThreshold, FeeEstimateHorizon horizon, EstimationResult *result=nullptr) const
Return a specific fee estimate calculation with a given success threshold and time horizon...
Definition: fees.cpp:673
#define LOCK(cs)
Definition: sync.h:181
void removeTx(unsigned int entryHeight, unsigned int nBestSeenHeight, unsigned int bucketIndex, bool inBlock)
Remove a transaction from mempool tracking stats.
Definition: fees.cpp:470
const uint256 & GetHash() const
Definition: transaction.h:316
const CAmount & GetFee() const
Definition: txmempool.h:100
CFeeRate estimateSmartFee(int confTarget, FeeCalculation *feeCalc, bool conservative) const
Estimate feerate needed to get be included in a block within confTarget blocks.
Definition: fees.cpp:820
unsigned int scale
Definition: fees.cpp:102
unsigned int historicalFirst
Definition: fees.h:233
double estimateConservativeFee(unsigned int doubleTarget, EstimationResult *result) const
Helper for estimateSmartFee.
Definition: fees.cpp:796
unsigned int trackedTxs
Definition: fees.h:251
const std::vector< double > & buckets
Definition: fees.cpp:76
Use default settings based on other criteria.
double inMempool
Definition: fees.h:67
uint32_t rand32()
Generate a random 32-bit integer.
Definition: random.h:118
unsigned int BlockSpan() const
Number of blocks of data recorded while fee estimates have been running.
Definition: fees.cpp:729
FeeReason
Definition: fees.h:36
std::string ToString() const
Definition: uint256.cpp:62
FeeFilterRounder(const CFeeRate &minIncrementalFee)
Create new FeeFilterRounder.
Definition: fees.cpp:997
std::map< uint256, TxStatsInfo > mapMemPoolTxs
Definition: fees.h:244
FastRandomContext insecure_rand
Definition: fees.h:293
CFeeRate estimateFee(int confTarget) const
DEPRECATED.
Definition: fees.cpp:664
static constexpr unsigned int LONG_SCALE
Definition: fees.h:147
double estimateCombinedFee(unsigned int confTarget, double successThreshold, bool checkShorterHorizon, EstimationResult *result) const
Helper for estimateSmartFee.
Definition: fees.cpp:757
FeeEstimateHorizon
Definition: fees.h:27
std::vector< std::vector< int > > unconfTxs
Definition: fees.cpp:107
unsigned int HighestTargetTracked(FeeEstimateHorizon horizon) const
Calculation of highest target that estimates are tracked for.
Definition: fees.cpp:711
256-bit opaque blob.
Definition: uint256.h:122
static constexpr unsigned int MED_SCALE
Definition: fees.h:144
static const unsigned int OLDEST_ESTIMATE_HISTORY
Historical estimates that are older than this aren&#39;t valid.
Definition: fees.h:149
std::vector< int > oldUnconfTxs
Definition: fees.cpp:109
void processBlock(unsigned int nBlockHeight, std::vector< const CTxMemPoolEntry *> &entries)
Process all the transactions that have been included in a block.
Definition: fees.cpp:615
const CTransaction & GetTx() const
Definition: txmempool.h:98
bool Read(CAutoFile &filein)
Read estimation data from a file.
Definition: fees.cpp:924
unsigned int historicalBest
Definition: fees.h:234
double leftMempool
Definition: fees.h:68
unsigned int GetMaxConfirms() const
Return the max number of confirms we&#39;re tracking.
Definition: fees.cpp:162
static constexpr unsigned int LONG_BLOCK_PERIODS
Track confirm delays up to 1008 blocks for long horizon.
Definition: fees.h:146
Fee rate in satoshis per kilobyte: CAmount / kB.
Definition: feerate.h:19
bool error(const char *fmt, const Args &... args)
Definition: util.h:59
std::vector< double > buckets
Definition: fees.h:254
static constexpr unsigned int SHORT_BLOCK_PERIODS
Track confirm delays up to 12 blocks for short horizon.
Definition: fees.h:140
double totalConfirmed
Definition: fees.h:66
static constexpr double SUFFICIENT_FEETXS
Require an avg of 0.1 tx in the combined feerate bucket per block to have stat significance.
Definition: fees.h:166
bool processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry *entry)
Process a transaction confirmed in a block.
Definition: fees.cpp:588
Force estimateSmartFee to use non-conservative estimates.
CAmount round(CAmount currentMinFee)
Quantize a minimum fee for privacy purpose before broadcast.
Definition: fees.cpp:1006
static constexpr double SHORT_DECAY
Decay of .962 is a half-life of 18 blocks or about 3 hours.
Definition: fees.h:152
double EstimateMedianVal(int confTarget, double sufficientTxVal, double minSuccess, bool requireGreater, unsigned int nBlockHeight, EstimationResult *result=nullptr) const
Calculate a feerate estimate.
Definition: fees.cpp:244
void Write(CAutoFile &fileout) const
Write state of estimation data to a file.
Definition: fees.cpp:396
std::set< double > feeset
Definition: fees.h:292
std::vector< double > txCtAvg
Definition: fees.cpp:82
unsigned int untrackedTxs
Definition: fees.h:252
void UpdateMovingAverages()
Update our estimates by decaying our historical moving average and updating with the data gathered fr...
Definition: fees.cpp:231
unsigned int scale
Definition: fees.h:77
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
Definition: feerate.h:41
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:621
void processTransaction(const CTxMemPoolEntry &entry, bool validFeeEstimate)
Process a transaction accepted to the mempool.
Definition: fees.cpp:549
double decay
Definition: fees.h:76