LCOV - code coverage report
Current view: top level - src/policy - fees.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 255 275 92.7 %
Date: 2015-10-12 22:39:14 Functions: 20 22 90.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2015 The Bitcoin 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 "amount.h"
       9             : #include "primitives/transaction.h"
      10             : #include "streams.h"
      11             : #include "txmempool.h"
      12             : #include "util.h"
      13             : 
      14         198 : void TxConfirmStats::Initialize(std::vector<double>& defaultBuckets,
      15             :                                 unsigned int maxConfirms, double _decay, std::string _dataTypeString)
      16             : {
      17         198 :     decay = _decay;
      18         198 :     dataTypeString = _dataTypeString;
      19       22470 :     for (unsigned int i = 0; i < defaultBuckets.size(); i++) {
      20       22074 :         buckets.push_back(defaultBuckets[i]);
      21       22074 :         bucketMap[defaultBuckets[i]] = i;
      22             :     }
      23         396 :     confAvg.resize(maxConfirms);
      24         396 :     curBlockConf.resize(maxConfirms);
      25         396 :     unconfTxs.resize(maxConfirms);
      26        5148 :     for (unsigned int i = 0; i < maxConfirms; i++) {
      27       14850 :         confAvg[i].resize(buckets.size());
      28       14850 :         curBlockConf[i].resize(buckets.size());
      29       14850 :         unconfTxs[i].resize(buckets.size());
      30             :     }
      31             : 
      32         396 :     oldUnconfTxs.resize(buckets.size());
      33         396 :     curBlockTxCt.resize(buckets.size());
      34         396 :     txCtAvg.resize(buckets.size());
      35         396 :     curBlockVal.resize(buckets.size());
      36         396 :     avg.resize(buckets.size());
      37         198 : }
      38             : 
      39             : // Zero out the data for the current block
      40       10120 : void TxConfirmStats::ClearCurrent(unsigned int nBlockHeight)
      41             : {
      42     1145850 :     for (unsigned int j = 0; j < buckets.size(); j++) {
      43     2814025 :         oldUnconfTxs[j] += unconfTxs[nBlockHeight%unconfTxs.size()][j];
      44      562805 :         unconfTxs[nBlockHeight%unconfTxs.size()][j] = 0;
      45    29265860 :         for (unsigned int i = 0; i < curBlockConf.size(); i++)
      46    42210375 :             curBlockConf[i][j] = 0;
      47     1125610 :         curBlockTxCt[j] = 0;
      48     1125610 :         curBlockVal[j] = 0;
      49             :     }
      50       10120 : }
      51             : 
      52             : 
      53       15112 : void TxConfirmStats::Record(int blocksToConfirm, double val)
      54             : {
      55             :     // blocksToConfirm is 1-based
      56       15112 :     if (blocksToConfirm < 1)
      57       15112 :         return;
      58       45336 :     unsigned int bucketindex = bucketMap.lower_bound(val)->second;
      59      752804 :     for (size_t i = blocksToConfirm; i <= curBlockConf.size(); i++) {
      60     1083870 :         curBlockConf[i - 1][bucketindex]++;
      61             :     }
      62       30224 :     curBlockTxCt[bucketindex]++;
      63       30224 :     curBlockVal[bucketindex] += val;
      64             : }
      65             : 
      66       10120 : void TxConfirmStats::UpdateMovingAverages()
      67             : {
      68     1145850 :     for (unsigned int j = 0; j < buckets.size(); j++) {
      69    28703055 :         for (unsigned int i = 0; i < confAvg.size(); i++)
      70    70350625 :             confAvg[i][j] = confAvg[i][j] * decay + curBlockConf[i][j];
      71     1688415 :         avg[j] = avg[j] * decay + curBlockVal[j];
      72     1688415 :         txCtAvg[j] = txCtAvg[j] * decay + curBlockTxCt[j];
      73             :     }
      74       10120 : }
      75             : 
      76             : // returns -1 on error conditions
      77       20666 : double TxConfirmStats::EstimateMedianVal(int confTarget, double sufficientTxVal,
      78             :                                          double successBreakPoint, bool requireGreater,
      79             :                                          unsigned int nBlockHeight)
      80             : {
      81             :     // Counters for a bucket (or range of buckets)
      82       20666 :     double nConf = 0; // Number of tx's confirmed within the confTarget
      83       20666 :     double totalNum = 0; // Total number of tx's that were ever confirmed
      84       20666 :     int extraNum = 0;  // Number of tx's still in mempool for confTarget or longer
      85             : 
      86       41332 :     int maxbucketindex = buckets.size() - 1;
      87             : 
      88             :     // requireGreater means we are looking for the lowest fee/priority such that all higher
      89             :     // values pass, so we start at maxbucketindex (highest fee) and look at succesively
      90             :     // smaller buckets until we reach failure.  Otherwise, we are looking for the highest
      91             :     // fee/priority such that all lower values fail, and we go in the opposite direction.
      92       20666 :     unsigned int startbucket = requireGreater ? maxbucketindex : 0;
      93       20666 :     int step = requireGreater ? -1 : 1;
      94             : 
      95             :     // We'll combine buckets until we have enough samples.
      96             :     // The near and far variables will define the range we've combined
      97             :     // The best variables are the last range we saw which still had a high
      98             :     // enough confirmation rate to count as success.
      99             :     // The cur variables are the current range we're counting.
     100       20666 :     unsigned int curNearBucket = startbucket;
     101       20666 :     unsigned int bestNearBucket = startbucket;
     102       20666 :     unsigned int curFarBucket = startbucket;
     103       20666 :     unsigned int bestFarBucket = startbucket;
     104             : 
     105       20666 :     bool foundAnswer = false;
     106       41332 :     unsigned int bins = unconfTxs.size();
     107             : 
     108             :     // Start counting from highest(default) or lowest fee/pri transactions
     109     1120927 :     for (int bucket = startbucket; bucket >= 0 && bucket <= maxbucketindex; bucket += step) {
     110     1101758 :         curFarBucket = bucket;
     111     3305274 :         nConf += confAvg[confTarget - 1][bucket];
     112     2203516 :         totalNum += txCtAvg[bucket];
     113    44376386 :         for (unsigned int confct = confTarget; confct < GetMaxConfirms(); confct++)
     114    63259305 :             extraNum += unconfTxs[(nBlockHeight - confct)%bins][bucket];
     115     2203516 :         extraNum += oldUnconfTxs[bucket];
     116             :         // If we have enough transaction data points in this range of buckets,
     117             :         // we can test for success
     118             :         // (Only count the confirmed data points, so that each confirmation count
     119             :         // will be looking at the same amount of data and same bucket breaks)
     120     1101758 :         if (totalNum >= sufficientTxVal / (1 - decay)) {
     121        3867 :             double curPct = nConf / (totalNum + extraNum);
     122             : 
     123             :             // Check to see if we are no longer getting confirmed at the success rate
     124        3867 :             if (requireGreater && curPct < successBreakPoint)
     125             :                 break;
     126        3073 :             if (!requireGreater && curPct > successBreakPoint)
     127             :                 break;
     128             : 
     129             :             // Otherwise update the cumulative stats, and the bucket variables
     130             :             // and reset the counters
     131             :             else {
     132        2370 :                 foundAnswer = true;
     133        2370 :                 nConf = 0;
     134        2370 :                 totalNum = 0;
     135        2370 :                 extraNum = 0;
     136        2370 :                 bestNearBucket = curNearBucket;
     137        2370 :                 bestFarBucket = curFarBucket;
     138        2370 :                 curNearBucket = bucket + step;
     139             :             }
     140             :         }
     141             :     }
     142             : 
     143       20666 :     double median = -1;
     144       20666 :     double txSum = 0;
     145             : 
     146             :     // Calculate the "average" fee of the best bucket range that met success conditions
     147             :     // Find the bucket with the median transaction and then report the average fee from that bucket
     148             :     // This is a compromise between finding the median which we can't since we don't save all tx's
     149             :     // and reporting the average which is less accurate
     150       20666 :     unsigned int minBucket = bestNearBucket < bestFarBucket ? bestNearBucket : bestFarBucket;
     151       20666 :     unsigned int maxBucket = bestNearBucket > bestFarBucket ? bestNearBucket : bestFarBucket;
     152       48305 :     for (unsigned int j = minBucket; j <= maxBucket; j++) {
     153       55278 :         txSum += txCtAvg[j];
     154             :     }
     155       20666 :     if (foundAnswer && txSum != 0) {
     156         789 :         txSum = txSum / 2;
     157        2020 :         for (unsigned int j = minBucket; j <= maxBucket; j++) {
     158        2020 :             if (txCtAvg[j] < txSum)
     159         221 :                 txSum -= txCtAvg[j];
     160             :             else { // we're in the right bucket
     161        1578 :                 median = avg[j] / txCtAvg[j];
     162         789 :                 break;
     163             :             }
     164             :         }
     165             :     }
     166             : 
     167             :     LogPrint("estimatefee", "%3d: For conf success %s %4.2f need %s %s: %12.5g from buckets %8g - %8g  Cur Bucket stats %6.2f%%  %8.1f/(%.1f+%d mempool)\n",
     168             :              confTarget, requireGreater ? ">" : "<", successBreakPoint, dataTypeString,
     169       41332 :              requireGreater ? ">" : "<", median, buckets[minBucket], buckets[maxBucket],
     170       41332 :              100 * nConf / (totalNum + extraNum), nConf, totalNum, extraNum);
     171             : 
     172       20666 :     return median;
     173             : }
     174             : 
     175         188 : void TxConfirmStats::Write(CAutoFile& fileout)
     176             : {
     177         188 :     fileout << decay;
     178         188 :     fileout << buckets;
     179         188 :     fileout << avg;
     180         188 :     fileout << txCtAvg;
     181         188 :     fileout << confAvg;
     182         188 : }
     183             : 
     184          56 : void TxConfirmStats::Read(CAutoFile& filein)
     185             : {
     186             :     // Read data file into temporary variables and do some very basic sanity checking
     187             :     std::vector<double> fileBuckets;
     188             :     std::vector<double> fileAvg;
     189          56 :     std::vector<std::vector<double> > fileConfAvg;
     190             :     std::vector<double> fileTxCtAvg;
     191             :     double fileDecay;
     192             :     size_t maxConfirms;
     193             :     size_t numBuckets;
     194             : 
     195          56 :     filein >> fileDecay;
     196          56 :     if (fileDecay <= 0 || fileDecay >= 1)
     197           0 :         throw std::runtime_error("Corrupt estimates file. Decay must be between 0 and 1 (non-inclusive)");
     198          56 :     filein >> fileBuckets;
     199         112 :     numBuckets = fileBuckets.size();
     200          56 :     if (numBuckets <= 1 || numBuckets > 1000)
     201           0 :         throw std::runtime_error("Corrupt estimates file. Must have between 2 and 1000 fee/pri buckets");
     202          56 :     filein >> fileAvg;
     203         112 :     if (fileAvg.size() != numBuckets)
     204           0 :         throw std::runtime_error("Corrupt estimates file. Mismatch in fee/pri average bucket count");
     205          56 :     filein >> fileTxCtAvg;
     206         112 :     if (fileTxCtAvg.size() != numBuckets)
     207           0 :         throw std::runtime_error("Corrupt estimates file. Mismatch in tx count bucket count");
     208          56 :     filein >> fileConfAvg;
     209         112 :     maxConfirms = fileConfAvg.size();
     210          56 :     if (maxConfirms <= 0 || maxConfirms > 6 * 24 * 7) // one week
     211           0 :         throw std::runtime_error("Corrupt estimates file.  Must maintain estimates for between 1 and 1008 (one week) confirms");
     212        1400 :     for (unsigned int i = 0; i < maxConfirms; i++) {
     213        2800 :         if (fileConfAvg[i].size() != numBuckets)
     214           0 :             throw std::runtime_error("Corrupt estimates file. Mismatch in fee/pri conf average bucket count");
     215             :     }
     216             :     // Now that we've processed the entire fee estimate data file and not
     217             :     // thrown any errors, we can copy it to our data structures
     218          56 :     decay = fileDecay;
     219          56 :     buckets = fileBuckets;
     220          56 :     avg = fileAvg;
     221          56 :     confAvg = fileConfAvg;
     222          56 :     txCtAvg = fileTxCtAvg;
     223          56 :     bucketMap.clear();
     224             : 
     225             :     // Resize the current block variables which aren't stored in the data file
     226             :     // to match the number of confirms and buckets
     227         112 :     curBlockConf.resize(maxConfirms);
     228        1456 :     for (unsigned int i = 0; i < maxConfirms; i++) {
     229        4200 :         curBlockConf[i].resize(buckets.size());
     230             :     }
     231         112 :     curBlockTxCt.resize(buckets.size());
     232         112 :     curBlockVal.resize(buckets.size());
     233             : 
     234         112 :     unconfTxs.resize(maxConfirms);
     235        1456 :     for (unsigned int i = 0; i < maxConfirms; i++) {
     236        4200 :         unconfTxs[i].resize(buckets.size());
     237             :     }
     238         112 :     oldUnconfTxs.resize(buckets.size());
     239             : 
     240        6216 :     for (unsigned int i = 0; i < buckets.size(); i++)
     241        6160 :         bucketMap[buckets[i]] = i;
     242             : 
     243             :     LogPrint("estimatefee", "Reading estimates: %u %s buckets counting confirms up to %u blocks\n",
     244          56 :              numBuckets, dataTypeString, maxConfirms);
     245          56 : }
     246             : 
     247       15933 : unsigned int TxConfirmStats::NewTx(unsigned int nBlockHeight, double val)
     248             : {
     249       47799 :     unsigned int bucketindex = bucketMap.lower_bound(val)->second;
     250       31866 :     unsigned int blockIndex = nBlockHeight % unconfTxs.size();
     251       47799 :     unconfTxs[blockIndex][bucketindex]++;
     252       15933 :     LogPrint("estimatefee", "adding to %s", dataTypeString);
     253       15933 :     return bucketindex;
     254             : }
     255             : 
     256       15918 : void TxConfirmStats::removeTx(unsigned int entryHeight, unsigned int nBestSeenHeight, unsigned int bucketindex)
     257             : {
     258             :     //nBestSeenHeight is not updated yet for the new block
     259       15918 :     int blocksAgo = nBestSeenHeight - entryHeight;
     260       15918 :     if (nBestSeenHeight == 0)  // the BlockPolicyEstimator hasn't seen any blocks yet
     261           6 :         blocksAgo = 0;
     262       15918 :     if (blocksAgo < 0) {
     263           0 :         LogPrint("estimatefee", "Blockpolicy error, blocks ago is negative for mempool tx\n");
     264       15918 :         return;  //This can't happen because we call this with our best seen height, no entries can have higher
     265             :     }
     266             : 
     267       31836 :     if (blocksAgo >= (int)unconfTxs.size()) {
     268           0 :         if (oldUnconfTxs[bucketindex] > 0)
     269           0 :             oldUnconfTxs[bucketindex]--;
     270             :         else
     271             :             LogPrint("estimatefee", "Blockpolicy error, mempool tx removed from >25 blocks,bucketIndex=%u already\n",
     272           0 :                      bucketindex);
     273             :     }
     274             :     else {
     275       15918 :         unsigned int blockIndex = entryHeight % unconfTxs.size();
     276       47754 :         if (unconfTxs[blockIndex][bucketindex] > 0)
     277       15918 :             unconfTxs[blockIndex][bucketindex]--;
     278             :         else
     279             :             LogPrint("estimatefee", "Blockpolicy error, mempool tx removed from blockIndex=%u,bucketIndex=%u already\n",
     280           0 :                      blockIndex, bucketindex);
     281             :     }
     282             : }
     283             : 
     284       16273 : void CBlockPolicyEstimator::removeTx(uint256 hash)
     285             : {
     286       32546 :     std::map<uint256, TxStatsInfo>::iterator pos = mapMemPoolTxs.find(hash);
     287       32546 :     if (pos == mapMemPoolTxs.end()) {
     288             :         LogPrint("estimatefee", "Blockpolicy error mempool tx %s not found for removeTx\n",
     289           0 :                  hash.ToString().c_str());
     290       16273 :         return;
     291             :     }
     292       16273 :     TxConfirmStats *stats = pos->second.stats;
     293       16273 :     unsigned int entryHeight = pos->second.blockHeight;
     294       16273 :     unsigned int bucketIndex = pos->second.bucketIndex;
     295             : 
     296       16273 :     if (stats != NULL)
     297       15918 :         stats->removeTx(entryHeight, nBestSeenHeight, bucketIndex);
     298       16273 :     mapMemPoolTxs.erase(hash);
     299             : }
     300             : 
     301          99 : CBlockPolicyEstimator::CBlockPolicyEstimator(const CFeeRate& _minRelayFee)
     302         396 :     : nBestSeenHeight(0)
     303             : {
     304         198 :     minTrackedFee = _minRelayFee < CFeeRate(MIN_FEERATE) ? CFeeRate(MIN_FEERATE) : _minRelayFee;
     305             :     std::vector<double> vfeelist;
     306        8265 :     for (double bucketBoundary = minTrackedFee.GetFeePerK(); bucketBoundary <= MAX_FEERATE; bucketBoundary *= FEE_SPACING) {
     307        8067 :         vfeelist.push_back(bucketBoundary);
     308             :     }
     309          99 :     vfeelist.push_back(INF_FEERATE);
     310         297 :     feeStats.Initialize(vfeelist, MAX_BLOCK_CONFIRMS, DEFAULT_DECAY, "FeeRate");
     311             : 
     312          99 :     minTrackedPriority = AllowFreeThreshold() < MIN_PRIORITY ? MIN_PRIORITY : AllowFreeThreshold();
     313             :     std::vector<double> vprilist;
     314        2871 :     for (double bucketBoundary = minTrackedPriority; bucketBoundary <= MAX_PRIORITY; bucketBoundary *= PRI_SPACING) {
     315        2772 :         vprilist.push_back(bucketBoundary);
     316             :     }
     317          99 :     vprilist.push_back(INF_PRIORITY);
     318         297 :     priStats.Initialize(vprilist, MAX_BLOCK_CONFIRMS, DEFAULT_DECAY, "Priority");
     319             : 
     320          99 :     feeUnlikely = CFeeRate(0);
     321          99 :     feeLikely = CFeeRate(INF_FEERATE);
     322          99 :     priUnlikely = 0;
     323          99 :     priLikely = INF_PRIORITY;
     324          99 : }
     325             : 
     326           0 : bool CBlockPolicyEstimator::isFeeDataPoint(const CFeeRate &fee, double pri)
     327             : {
     328       76320 :     if ((pri < minTrackedPriority && fee >= minTrackedFee) ||
     329         576 :         (pri < priUnlikely && fee > feeLikely)) {
     330             :         return true;
     331             :     }
     332           0 :     return false;
     333             : }
     334             : 
     335           0 : bool CBlockPolicyEstimator::isPriDataPoint(const CFeeRate &fee, double pri)
     336             : {
     337      101760 :     if ((fee < minTrackedFee && pri >= minTrackedPriority) ||
     338       25440 :         (fee < feeUnlikely && pri > priLikely)) {
     339             :         return true;
     340             :     }
     341           0 :     return false;
     342             : }
     343             : 
     344       17437 : void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, bool fCurrentEstimate)
     345             : {
     346       17437 :     unsigned int txHeight = entry.GetHeight();
     347       17437 :     uint256 hash = entry.GetTx().GetHash();
     348       17437 :     if (mapMemPoolTxs[hash].stats != NULL) {
     349             :         LogPrint("estimatefee", "Blockpolicy error mempool tx %s already being tracked\n",
     350           0 :                  hash.ToString().c_str());
     351        1238 :         return;
     352             :     }
     353             : 
     354       17437 :     if (txHeight < nBestSeenHeight) {
     355             :         // Ignore side chains and re-orgs; assuming they are random they don't
     356             :         // affect the estimate.  We'll potentially double count transactions in 1-block reorgs.
     357             :         return;
     358             :     }
     359             : 
     360             :     // Only want to be updating estimates when our blockchain is synced,
     361             :     // otherwise we'll miscalculate how many blocks its taking to get included.
     362       16286 :     if (!fCurrentEstimate)
     363             :         return;
     364             : 
     365       16257 :     if (!entry.WasClearAtEntry()) {
     366             :         // This transaction depends on other transactions in the mempool to
     367             :         // be included in a block before it will be able to be included, so
     368             :         // we shouldn't include it in our calculations
     369             :         return;
     370             :     }
     371             : 
     372             :     // Fees are stored and reported as BTC-per-kb:
     373       16199 :     CFeeRate feeRate(entry.GetFee(), entry.GetTxSize());
     374             : 
     375             :     // Want the priority of the tx at confirmation. However we don't know
     376             :     // what that will be and its too hard to continue updating it
     377             :     // so use starting priority as a proxy
     378       16199 :     double curPri = entry.GetPriority(txHeight);
     379       16199 :     mapMemPoolTxs[hash].blockHeight = txHeight;
     380             : 
     381       48597 :     LogPrint("estimatefee", "Blockpolicy mempool tx %s ", hash.ToString().substr(0,10));
     382             :     // Record this as a priority estimate
     383       29229 :     if (entry.GetFee() == 0 || isPriDataPoint(feeRate, curPri)) {
     384        3169 :         mapMemPoolTxs[hash].stats = &priStats;
     385        3169 :         mapMemPoolTxs[hash].bucketIndex =  priStats.NewTx(txHeight, curPri);
     386             :     }
     387             :     // Record this as a fee estimate
     388       13030 :     else if (isFeeDataPoint(feeRate, curPri)) {
     389       12764 :         mapMemPoolTxs[hash].stats = &feeStats;
     390       25528 :         mapMemPoolTxs[hash].bucketIndex = feeStats.NewTx(txHeight, (double)feeRate.GetFeePerK());
     391             :     }
     392             :     else {
     393         266 :         LogPrint("estimatefee", "not adding");
     394             :     }
     395       16199 :     LogPrint("estimatefee", "\n");
     396             : }
     397             : 
     398       15470 : void CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry& entry)
     399             : {
     400       15470 :     if (!entry.WasClearAtEntry()) {
     401             :         // This transaction depended on other transactions in the mempool to
     402             :         // be included in a block before it was able to be included, so
     403             :         // we shouldn't include it in our calculations
     404          48 :         return;
     405             :     }
     406             : 
     407             :     // How many blocks did it take for miners to include this transaction?
     408             :     // blocksToConfirm is 1-based, so a transaction included in the earliest
     409             :     // possible block has confirmation count of 1
     410       15422 :     int blocksToConfirm = nBlockHeight - entry.GetHeight();
     411       15422 :     if (blocksToConfirm <= 0) {
     412             :         // This can't happen because we don't process transactions from a block with a height
     413             :         // lower than our greatest seen height
     414           0 :         LogPrint("estimatefee", "Blockpolicy error Transaction had negative blocksToConfirm\n");
     415             :         return;
     416             :     }
     417             : 
     418             :     // Fees are stored and reported as BTC-per-kb:
     419       15422 :     CFeeRate feeRate(entry.GetFee(), entry.GetTxSize());
     420             : 
     421             :     // Want the priority of the tx at confirmation.  The priority when it
     422             :     // entered the mempool could easily be very small and change quickly
     423       15422 :     double curPri = entry.GetPriority(nBlockHeight);
     424             : 
     425             :     // Record this as a priority estimate
     426       27832 :     if (entry.GetFee() == 0 || isPriDataPoint(feeRate, curPri)) {
     427        3012 :         priStats.Record(blocksToConfirm, curPri);
     428             :     }
     429             :     // Record this as a fee estimate
     430       12410 :     else if (isFeeDataPoint(feeRate, curPri)) {
     431       12100 :         feeStats.Record(blocksToConfirm, (double)feeRate.GetFeePerK());
     432             :     }
     433             : }
     434             : 
     435        5868 : void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight,
     436             :                                          std::vector<CTxMemPoolEntry>& entries, bool fCurrentEstimate)
     437             : {
     438        5868 :     if (nBlockHeight <= nBestSeenHeight) {
     439             :         // Ignore side chains and re-orgs; assuming they are random
     440             :         // they don't affect the estimate.
     441             :         // And if an attacker can re-org the chain at will, then
     442             :         // you've got much bigger problems than "attacker can influence
     443             :         // transaction fees."
     444             :         return;
     445             :     }
     446        5234 :     nBestSeenHeight = nBlockHeight;
     447             : 
     448             :     // Only want to be updating estimates when our blockchain is synced,
     449             :     // otherwise we'll miscalculate how many blocks its taking to get included.
     450        5234 :     if (!fCurrentEstimate)
     451             :         return;
     452             : 
     453             :     // Update the dynamic cutoffs
     454             :     // a fee/priority is "likely" the reason your tx was included in a block if >85% of such tx's
     455             :     // were confirmed in 2 blocks and is "unlikely" if <50% were confirmed in 10 blocks
     456        5060 :     LogPrint("estimatefee", "Blockpolicy recalculating dynamic cutoffs:\n");
     457        5060 :     priLikely = priStats.EstimateMedianVal(2, SUFFICIENT_PRITXS, MIN_SUCCESS_PCT, true, nBlockHeight);
     458        5060 :     if (priLikely == -1)
     459        4718 :         priLikely = INF_PRIORITY;
     460             : 
     461        5060 :     double feeLikelyEst = feeStats.EstimateMedianVal(2, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBlockHeight);
     462        5060 :     if (feeLikelyEst == -1)
     463        4721 :         feeLikely = CFeeRate(INF_FEERATE);
     464             :     else
     465         339 :         feeLikely = CFeeRate(feeLikelyEst);
     466             : 
     467        5060 :     priUnlikely = priStats.EstimateMedianVal(10, SUFFICIENT_PRITXS, UNLIKELY_PCT, false, nBlockHeight);
     468        5060 :     if (priUnlikely == -1)
     469        5060 :         priUnlikely = 0;
     470             : 
     471        5060 :     double feeUnlikelyEst = feeStats.EstimateMedianVal(10, SUFFICIENT_FEETXS, UNLIKELY_PCT, false, nBlockHeight);
     472        5060 :     if (feeUnlikelyEst == -1)
     473        5060 :         feeUnlikely = CFeeRate(0);
     474             :     else
     475           0 :         feeUnlikely = CFeeRate(feeUnlikelyEst);
     476             : 
     477             :     // Clear the current block states
     478        5060 :     feeStats.ClearCurrent(nBlockHeight);
     479        5060 :     priStats.ClearCurrent(nBlockHeight);
     480             : 
     481             :     // Repopulate the current block states
     482       41060 :     for (unsigned int i = 0; i < entries.size(); i++)
     483       30940 :         processBlockTx(nBlockHeight, entries[i]);
     484             : 
     485             :     // Update all exponential averages with the current block states
     486        5060 :     feeStats.UpdateMovingAverages();
     487        5060 :     priStats.UpdateMovingAverages();
     488             : 
     489             :     LogPrint("estimatefee", "Blockpolicy after updating estimates for %u confirmed entries, new mempool map size %u\n",
     490       15180 :              entries.size(), mapMemPoolTxs.size());
     491             : }
     492             : 
     493         373 : CFeeRate CBlockPolicyEstimator::estimateFee(int confTarget)
     494             : {
     495             :     // Return failure if trying to analyze a target we're not tracking
     496         746 :     if (confTarget <= 0 || (unsigned int)confTarget > feeStats.GetMaxConfirms())
     497           0 :         return CFeeRate(0);
     498             : 
     499         373 :     double median = feeStats.EstimateMedianVal(confTarget, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBestSeenHeight);
     500             : 
     501         373 :     if (median < 0)
     502         318 :         return CFeeRate(0);
     503             : 
     504          55 :     return CFeeRate(median);
     505             : }
     506             : 
     507          53 : double CBlockPolicyEstimator::estimatePriority(int confTarget)
     508             : {
     509             :     // Return failure if trying to analyze a target we're not tracking
     510         106 :     if (confTarget <= 0 || (unsigned int)confTarget > priStats.GetMaxConfirms())
     511             :         return -1;
     512             : 
     513          53 :     return priStats.EstimateMedianVal(confTarget, SUFFICIENT_PRITXS, MIN_SUCCESS_PCT, true, nBestSeenHeight);
     514             : }
     515             : 
     516          94 : void CBlockPolicyEstimator::Write(CAutoFile& fileout)
     517             : {
     518          94 :     fileout << nBestSeenHeight;
     519          94 :     feeStats.Write(fileout);
     520          94 :     priStats.Write(fileout);
     521          94 : }
     522             : 
     523          28 : void CBlockPolicyEstimator::Read(CAutoFile& filein)
     524             : {
     525             :     int nFileBestSeenHeight;
     526          28 :     filein >> nFileBestSeenHeight;
     527          28 :     feeStats.Read(filein);
     528          28 :     priStats.Read(filein);
     529          28 :     nBestSeenHeight = nFileBestSeenHeight;
     530         316 : }

Generated by: LCOV version 1.11