@@ -290,6 +290,7 @@ void TxConfirmStats::removeTx(unsigned int entryHeight, unsigned int nBestSeenHe
290290// of no harm to try to remove them again.
291291bool CBlockPolicyEstimator::removeTx (uint256 hash)
292292{
293+ LOCK (cs_feeEstimator);
293294 std::map<uint256, TxStatsInfo>::iterator pos = mapMemPoolTxs.find (hash);
294295 if (pos != mapMemPoolTxs.end ()) {
295296 feeStats.removeTx (pos->second .blockHeight , nBestSeenHeight, pos->second .bucketIndex );
@@ -315,6 +316,7 @@ CBlockPolicyEstimator::CBlockPolicyEstimator()
315316
316317void CBlockPolicyEstimator::processTransaction (const CTxMemPoolEntry& entry, bool validFeeEstimate)
317318{
319+ LOCK (cs_feeEstimator);
318320 unsigned int txHeight = entry.GetHeight ();
319321 uint256 hash = entry.GetTx ().GetHash ();
320322 if (mapMemPoolTxs.count (hash)) {
@@ -374,6 +376,7 @@ bool CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxM
374376void CBlockPolicyEstimator::processBlock (unsigned int nBlockHeight,
375377 std::vector<const CTxMemPoolEntry*>& entries)
376378{
379+ LOCK (cs_feeEstimator);
377380 if (nBlockHeight <= nBestSeenHeight) {
378381 // Ignore side chains and re-orgs; assuming they are random
379382 // they don't affect the estimate.
@@ -410,6 +413,7 @@ void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight,
410413
411414CFeeRate CBlockPolicyEstimator::estimateFee (int confTarget)
412415{
416+ LOCK (cs_feeEstimator);
413417 // Return failure if trying to analyze a target we're not tracking
414418 // It's not possible to get reasonable estimates for confTarget of 1
415419 if (confTarget <= 1 || (unsigned int )confTarget > feeStats.GetMaxConfirms ())
@@ -427,18 +431,24 @@ CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, int *answerFoun
427431{
428432 if (answerFoundAtTarget)
429433 *answerFoundAtTarget = confTarget;
430- // Return failure if trying to analyze a target we're not tracking
431- if (confTarget <= 0 || (unsigned int )confTarget > feeStats.GetMaxConfirms ())
432- return CFeeRate (0 );
433-
434- // It's not possible to get reasonable estimates for confTarget of 1
435- if (confTarget == 1 )
436- confTarget = 2 ;
437434
438435 double median = -1 ;
439- while (median < 0 && (unsigned int )confTarget <= feeStats.GetMaxConfirms ()) {
440- median = feeStats.EstimateMedianVal (confTarget++, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true , nBestSeenHeight);
441- }
436+
437+ {
438+ LOCK (cs_feeEstimator);
439+
440+ // Return failure if trying to analyze a target we're not tracking
441+ if (confTarget <= 0 || (unsigned int )confTarget > feeStats.GetMaxConfirms ())
442+ return CFeeRate (0 );
443+
444+ // It's not possible to get reasonable estimates for confTarget of 1
445+ if (confTarget == 1 )
446+ confTarget = 2 ;
447+
448+ while (median < 0 && (unsigned int )confTarget <= feeStats.GetMaxConfirms ()) {
449+ median = feeStats.EstimateMedianVal (confTarget++, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true , nBestSeenHeight);
450+ }
451+ } // Must unlock cs_feeEstimator before taking mempool locks
442452
443453 if (answerFoundAtTarget)
444454 *answerFoundAtTarget = confTarget - 1 ;
@@ -456,12 +466,14 @@ CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, int *answerFoun
456466
457467void CBlockPolicyEstimator::Write (CAutoFile& fileout)
458468{
469+ LOCK (cs_feeEstimator);
459470 fileout << nBestSeenHeight;
460471 feeStats.Write (fileout);
461472}
462473
463474void CBlockPolicyEstimator::Read (CAutoFile& filein, int nFileVersion)
464475{
476+ LOCK (cs_feeEstimator);
465477 int nFileBestSeenHeight;
466478 filein >> nFileBestSeenHeight;
467479 feeStats.Read (filein);
0 commit comments