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