void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, bool fCurrentEstimate) { unsigned int txHeight = entry.GetHeight(); uint256 hash = entry.GetTx().GetHash(); if (mapMemPoolTxs[hash].stats != NULL) { LogPrint("estimatefee", "Blockpolicy error mempool tx %s already being tracked\n", hash.ToString().c_str()); return; } if (txHeight < nBestSeenHeight) { // Ignore side chains and re-orgs; assuming they are random they don't // affect the estimate. We'll potentially double count transactions in 1-block reorgs. return; } // 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; if (!entry.WasClearAtEntry()) { // This transaction depends on other transactions in the mempool to // be included in a block before it will be able to be included, so // we shouldn't include it in our calculations return; } // Fees are stored and reported as XRE-per-kb: CFeeRate feeRate(entry.GetFee(), entry.GetTxSize()); // Want the priority of the tx at confirmation. However we don't know // what that will be and its too hard to continue updating it // so use starting priority as a proxy double curPri = entry.GetPriority(txHeight); mapMemPoolTxs[hash].blockHeight = txHeight; LogPrint("estimatefee", "Blockpolicy mempool tx %s ", hash.ToString().substr(0,10)); // Record this as a priority estimate if (entry.GetFee() == 0 || isPriDataPoint(feeRate, curPri)) { mapMemPoolTxs[hash].stats = &priStats; mapMemPoolTxs[hash].bucketIndex = priStats.NewTx(txHeight, curPri); } // Record this as a fee estimate else if (isFeeDataPoint(feeRate, curPri)) { mapMemPoolTxs[hash].stats = &feeStats; mapMemPoolTxs[hash].bucketIndex = feeStats.NewTx(txHeight, (double)feeRate.GetFeePerK()); } else { LogPrint("estimatefee", "not adding"); } LogPrint("estimatefee", "\n"); }
void CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry& entry) { if (!entry.WasClearAtEntry()) { // This transaction depended on other transactions in the mempool to // be included in a block before it was able to be included, so // we shouldn't include it in our calculations return; } // How many blocks did it take for miners to include this transaction? // blocksToConfirm is 1-based, so a transaction included in the earliest // possible block has confirmation count of 1 int blocksToConfirm = nBlockHeight - entry.GetHeight(); if (blocksToConfirm <= 0) { // This can't happen because we don't process transactions from a block with a height // lower than our greatest seen height LogPrint("estimatefee", "Blockpolicy error Transaction had negative blocksToConfirm\n"); return; } // Fees are stored and reported as XRE-per-kb: CFeeRate feeRate(entry.GetFee(), entry.GetTxSize()); // Want the priority of the tx at confirmation. The priority when it // entered the mempool could easily be very small and change quickly double curPri = entry.GetPriority(nBlockHeight); // Record this as a priority estimate if (entry.GetFee() == 0 || isPriDataPoint(feeRate, curPri)) { priStats.Record(blocksToConfirm, curPri); } // Record this as a fee estimate else if (isFeeDataPoint(feeRate, curPri)) { feeStats.Record(blocksToConfirm, (double)feeRate.GetFeePerK()); } }