void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight, std::vector<CTxMemPoolEntry>& entries, bool fCurrentEstimate) { if (nBlockHeight <= nBestSeenHeight) { // Ignore side chains and re-orgs; assuming they are random // they don't affect the estimate. // And if an attacker can re-org the chain at will, then // you've got much bigger problems than "attacker can influence // transaction fees." return; } nBestSeenHeight = nBlockHeight; // Only want to be updating estimates when our blockchain is synced, // otherwise we'll miscalculate how many blocks its taking to get included. if (!fCurrentEstimate) return; // Update the dynamic cutoffs // a fee/priority is "likely" the reason your tx was included in a block if >85% of such tx's // were confirmed in 2 blocks and is "unlikely" if <50% were confirmed in 10 blocks LogPrint("estimatefee", "Blockpolicy recalculating dynamic cutoffs:\n"); priLikely = priStats.EstimateMedianVal(2, SUFFICIENT_PRITXS, MIN_SUCCESS_PCT, true, nBlockHeight); if (priLikely == -1) priLikely = INF_PRIORITY; double feeLikelyEst = feeStats.EstimateMedianVal(2, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBlockHeight); if (feeLikelyEst == -1) feeLikely = CFeeRate(INF_FEERATE); else feeLikely = CFeeRate(feeLikelyEst); priUnlikely = priStats.EstimateMedianVal(10, SUFFICIENT_PRITXS, UNLIKELY_PCT, false, nBlockHeight); if (priUnlikely == -1) priUnlikely = 0; double feeUnlikelyEst = feeStats.EstimateMedianVal(10, SUFFICIENT_FEETXS, UNLIKELY_PCT, false, nBlockHeight); if (feeUnlikelyEst == -1) feeUnlikely = CFeeRate(0); else feeUnlikely = CFeeRate(feeUnlikelyEst); // Clear the current block states feeStats.ClearCurrent(nBlockHeight); priStats.ClearCurrent(nBlockHeight); // Repopulate the current block states for (unsigned int i = 0; i < entries.size(); i++) processBlockTx(nBlockHeight, entries[i]); // Update all exponential averages with the current block states feeStats.UpdateMovingAverages(); priStats.UpdateMovingAverages(); LogPrint("estimatefee", "Blockpolicy after updating estimates for %u confirmed entries, new mempool map size %u\n", entries.size(), mapMemPoolTxs.size()); }
void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight, std::vector<const CTxMemPoolEntry*>& entries) { LOCK(cs_feeEstimator); if (nBlockHeight <= nBestSeenHeight) { // Ignore side chains and re-orgs; assuming they are random // they don't affect the estimate. // And if an attacker can re-org the chain at will, then // you've got much bigger problems than "attacker can influence // transaction fees." return; } // Must update nBestSeenHeight in sync with ClearCurrent so that // calls to removeTx (via processBlockTx) correctly calculate age // of unconfirmed txs to remove from tracking. nBestSeenHeight = nBlockHeight; // Update unconfirmed circular buffer feeStats->ClearCurrent(nBlockHeight); shortStats->ClearCurrent(nBlockHeight); longStats->ClearCurrent(nBlockHeight); // Decay all exponential averages feeStats->UpdateMovingAverages(); shortStats->UpdateMovingAverages(); longStats->UpdateMovingAverages(); unsigned int countedTxs = 0; // Update averages with data points from current block for (const auto& entry : entries) { if (processBlockTx(nBlockHeight, entry)) countedTxs++; } if (firstRecordedHeight == 0 && countedTxs > 0) { firstRecordedHeight = nBestSeenHeight; LogPrint(BCLog::ESTIMATEFEE, "Blockpolicy first recorded height %u\n", firstRecordedHeight); } 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", countedTxs, entries.size(), trackedTxs, trackedTxs + untrackedTxs, mapMemPoolTxs.size(), MaxUsableEstimate(), HistoricalBlockSpan() > BlockSpan() ? "historical" : "current"); trackedTxs = 0; untrackedTxs = 0; }
void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight, std::vector<const CTxMemPoolEntry*>& entries) { LOCK(cs_feeEstimator); if (nBlockHeight <= nBestSeenHeight) { // Ignore side chains and re-orgs; assuming they are random // they don't affect the estimate. // And if an attacker can re-org the chain at will, then // you've got much bigger problems than "attacker can influence // transaction fees." return; } // Must update nBestSeenHeight in sync with ClearCurrent so that // calls to removeTx (via processBlockTx) correctly calculate age // of unconfirmed txs to remove from tracking. nBestSeenHeight = nBlockHeight; // Clear the current block state and update unconfirmed circular buffer feeStats->ClearCurrent(nBlockHeight); unsigned int countedTxs = 0; // Repopulate the current block states for (unsigned int i = 0; i < entries.size(); i++) { if (processBlockTx(nBlockHeight, entries[i])) countedTxs++; } // Update all exponential averages with the current block state feeStats->UpdateMovingAverages(); LogPrint(BCLog::ESTIMATEFEE, "Blockpolicy after updating estimates for %u of %u txs in block, since last block %u of %u tracked, new mempool map size %u\n", countedTxs, entries.size(), trackedTxs, trackedTxs + untrackedTxs, mapMemPoolTxs.size()); trackedTxs = 0; untrackedTxs = 0; }