LCOV - code coverage report
Current view: top level - src/policy - fees.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 466 495 94.1 %
Date: 2020-09-26 01:30:44 Functions: 38 38 100.0 %

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

Generated by: LCOV version 1.15