Give CBlockPolicyEstimator it's own lock

This commit is contained in:
Alex Morcos 2017-02-15 09:24:11 -05:00
parent f6187d6e39
commit dbb9e3699b
3 changed files with 25 additions and 14 deletions

View File

@ -290,6 +290,7 @@ void TxConfirmStats::removeTx(unsigned int entryHeight, unsigned int nBestSeenHe
// of no harm to try to remove them again. // of no harm to try to remove them again.
bool CBlockPolicyEstimator::removeTx(uint256 hash) bool CBlockPolicyEstimator::removeTx(uint256 hash)
{ {
LOCK(cs_feeEstimator);
std::map<uint256, TxStatsInfo>::iterator pos = mapMemPoolTxs.find(hash); std::map<uint256, TxStatsInfo>::iterator pos = mapMemPoolTxs.find(hash);
if (pos != mapMemPoolTxs.end()) { if (pos != mapMemPoolTxs.end()) {
feeStats.removeTx(pos->second.blockHeight, nBestSeenHeight, pos->second.bucketIndex); feeStats.removeTx(pos->second.blockHeight, nBestSeenHeight, pos->second.bucketIndex);
@ -315,6 +316,7 @@ CBlockPolicyEstimator::CBlockPolicyEstimator()
void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, bool validFeeEstimate) void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, bool validFeeEstimate)
{ {
LOCK(cs_feeEstimator);
unsigned int txHeight = entry.GetHeight(); unsigned int txHeight = entry.GetHeight();
uint256 hash = entry.GetTx().GetHash(); uint256 hash = entry.GetTx().GetHash();
if (mapMemPoolTxs.count(hash)) { if (mapMemPoolTxs.count(hash)) {
@ -374,6 +376,7 @@ bool CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxM
void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight, void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight,
std::vector<const CTxMemPoolEntry*>& entries) std::vector<const CTxMemPoolEntry*>& entries)
{ {
LOCK(cs_feeEstimator);
if (nBlockHeight <= nBestSeenHeight) { if (nBlockHeight <= nBestSeenHeight) {
// Ignore side chains and re-orgs; assuming they are random // Ignore side chains and re-orgs; assuming they are random
// they don't affect the estimate. // they don't affect the estimate.
@ -410,6 +413,7 @@ void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight,
CFeeRate CBlockPolicyEstimator::estimateFee(int confTarget) CFeeRate CBlockPolicyEstimator::estimateFee(int confTarget)
{ {
LOCK(cs_feeEstimator);
// Return failure if trying to analyze a target we're not tracking // Return failure if trying to analyze a target we're not tracking
// It's not possible to get reasonable estimates for confTarget of 1 // It's not possible to get reasonable estimates for confTarget of 1
if (confTarget <= 1 || (unsigned int)confTarget > feeStats.GetMaxConfirms()) if (confTarget <= 1 || (unsigned int)confTarget > feeStats.GetMaxConfirms())
@ -427,18 +431,24 @@ CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, int *answerFoun
{ {
if (answerFoundAtTarget) if (answerFoundAtTarget)
*answerFoundAtTarget = confTarget; *answerFoundAtTarget = confTarget;
// Return failure if trying to analyze a target we're not tracking
if (confTarget <= 0 || (unsigned int)confTarget > feeStats.GetMaxConfirms())
return CFeeRate(0);
// It's not possible to get reasonable estimates for confTarget of 1
if (confTarget == 1)
confTarget = 2;
double median = -1; double median = -1;
while (median < 0 && (unsigned int)confTarget <= feeStats.GetMaxConfirms()) {
median = feeStats.EstimateMedianVal(confTarget++, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBestSeenHeight); {
} LOCK(cs_feeEstimator);
// Return failure if trying to analyze a target we're not tracking
if (confTarget <= 0 || (unsigned int)confTarget > feeStats.GetMaxConfirms())
return CFeeRate(0);
// It's not possible to get reasonable estimates for confTarget of 1
if (confTarget == 1)
confTarget = 2;
while (median < 0 && (unsigned int)confTarget <= feeStats.GetMaxConfirms()) {
median = feeStats.EstimateMedianVal(confTarget++, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBestSeenHeight);
}
} // Must unlock cs_feeEstimator before taking mempool locks
if (answerFoundAtTarget) if (answerFoundAtTarget)
*answerFoundAtTarget = confTarget - 1; *answerFoundAtTarget = confTarget - 1;
@ -456,12 +466,14 @@ CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, int *answerFoun
void CBlockPolicyEstimator::Write(CAutoFile& fileout) void CBlockPolicyEstimator::Write(CAutoFile& fileout)
{ {
LOCK(cs_feeEstimator);
fileout << nBestSeenHeight; fileout << nBestSeenHeight;
feeStats.Write(fileout); feeStats.Write(fileout);
} }
void CBlockPolicyEstimator::Read(CAutoFile& filein, int nFileVersion) void CBlockPolicyEstimator::Read(CAutoFile& filein, int nFileVersion)
{ {
LOCK(cs_feeEstimator);
int nFileBestSeenHeight; int nFileBestSeenHeight;
filein >> nFileBestSeenHeight; filein >> nFileBestSeenHeight;
feeStats.Read(filein); feeStats.Read(filein);

View File

@ -8,6 +8,7 @@
#include "amount.h" #include "amount.h"
#include "uint256.h" #include "uint256.h"
#include "random.h" #include "random.h"
#include "sync.h"
#include <map> #include <map>
#include <string> #include <string>
@ -249,6 +250,8 @@ private:
unsigned int trackedTxs; unsigned int trackedTxs;
unsigned int untrackedTxs; unsigned int untrackedTxs;
mutable CCriticalSection cs_feeEstimator;
/** Process a transaction confirmed in a block*/ /** Process a transaction confirmed in a block*/
bool processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry* entry); bool processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry* entry);

View File

@ -845,12 +845,10 @@ TxMempoolInfo CTxMemPool::info(const uint256& hash) const
CFeeRate CTxMemPool::estimateFee(int nBlocks) const CFeeRate CTxMemPool::estimateFee(int nBlocks) const
{ {
LOCK(cs);
return minerPolicyEstimator->estimateFee(nBlocks); return minerPolicyEstimator->estimateFee(nBlocks);
} }
CFeeRate CTxMemPool::estimateSmartFee(int nBlocks, int *answerFoundAtBlocks) const CFeeRate CTxMemPool::estimateSmartFee(int nBlocks, int *answerFoundAtBlocks) const
{ {
LOCK(cs);
return minerPolicyEstimator->estimateSmartFee(nBlocks, answerFoundAtBlocks, *this); return minerPolicyEstimator->estimateSmartFee(nBlocks, answerFoundAtBlocks, *this);
} }
@ -858,7 +856,6 @@ bool
CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const
{ {
try { try {
LOCK(cs);
fileout << 139900; // version required to read: 0.13.99 or later fileout << 139900; // version required to read: 0.13.99 or later
fileout << CLIENT_VERSION; // version that wrote the file fileout << CLIENT_VERSION; // version that wrote the file
minerPolicyEstimator->Write(fileout); minerPolicyEstimator->Write(fileout);
@ -878,7 +875,6 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein)
filein >> nVersionRequired >> nVersionThatWrote; filein >> nVersionRequired >> nVersionThatWrote;
if (nVersionRequired > CLIENT_VERSION) if (nVersionRequired > CLIENT_VERSION)
return error("CTxMemPool::ReadFeeEstimates(): up-version (%d) fee estimate file", nVersionRequired); return error("CTxMemPool::ReadFeeEstimates(): up-version (%d) fee estimate file", nVersionRequired);
LOCK(cs);
minerPolicyEstimator->Read(filein, nVersionThatWrote); minerPolicyEstimator->Read(filein, nVersionThatWrote);
} }
catch (const std::exception&) { catch (const std::exception&) {