You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fees.cpp 43KB

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