Skip to content

Commit 0b30bdd

Browse files
author
MarcoFalke
committed
Merge bitcoin/bitcoin#22014: refactor: Make m_cs_fee_estimator non-recursive
8c277b1 refactor: Make m_cs_fee_estimator non-recursive (Hennadii Stepanov) 5ee5b69 refactor: Add non-thread-safe CBlockPolicyEstimator::_removeTx helper (Hennadii Stepanov) 5c3033d Add thread safety annotations to CBlockPolicyEstimator public functions (Hennadii Stepanov) Pull request description: This PR eliminates the only place that `m_cs_fee_estimator` is recursively locked by refactoring out `_removeTx` member function. Related to #19303. ACKs for top commit: theStack: Code-review ACK 8c277b1 amadeuszpawlik: ACK 8c277b1 reviewed, built and ran tests Tree-SHA512: 65b0b59460d3d5fadf7e75e916b2898b0dcfafdf5b278ef8c3975660f67c9f88ae4b937944313bd36d7513a7a53e1e5859aaf4a6deb4a1aea089936b101635a1
2 parents bce58bb + 8c277b1 commit 0b30bdd

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

src/policy/fees.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,12 @@ void TxConfirmStats::removeTx(unsigned int entryHeight, unsigned int nBestSeenHe
493493
bool CBlockPolicyEstimator::removeTx(uint256 hash, bool inBlock)
494494
{
495495
LOCK(m_cs_fee_estimator);
496+
return _removeTx(hash, inBlock);
497+
}
498+
499+
bool CBlockPolicyEstimator::_removeTx(const uint256& hash, bool inBlock)
500+
{
501+
AssertLockHeld(m_cs_fee_estimator);
496502
std::map<uint256, TxStatsInfo>::iterator pos = mapMemPoolTxs.find(hash);
497503
if (pos != mapMemPoolTxs.end()) {
498504
feeStats->removeTx(pos->second.blockHeight, nBestSeenHeight, pos->second.bucketIndex, inBlock);
@@ -576,7 +582,8 @@ void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, boo
576582

577583
bool CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry* entry)
578584
{
579-
if (!removeTx(entry->GetTx().GetHash(), true)) {
585+
AssertLockHeld(m_cs_fee_estimator);
586+
if (!_removeTx(entry->GetTx().GetHash(), true)) {
580587
// This transaction wasn't being tracked for fee estimation
581588
return false;
582589
}
@@ -985,7 +992,7 @@ void CBlockPolicyEstimator::FlushUnconfirmed() {
985992
// Remove every entry in mapMemPoolTxs
986993
while (!mapMemPoolTxs.empty()) {
987994
auto mi = mapMemPoolTxs.begin();
988-
removeTx(mi->first, false); // this calls erase() on mapMemPoolTxs
995+
_removeTx(mi->first, false); // this calls erase() on mapMemPoolTxs
989996
}
990997
int64_t endclear = GetTimeMicros();
991998
LogPrint(BCLog::ESTIMATEFEE, "Recorded %u unconfirmed txs from mempool in %gs\n", num_entries, (endclear - startclear)*0.000001);

src/policy/fees.h

+28-12
Original file line numberDiff line numberDiff line change
@@ -186,47 +186,59 @@ class CBlockPolicyEstimator
186186

187187
/** Process all the transactions that have been included in a block */
188188
void processBlock(unsigned int nBlockHeight,
189-
std::vector<const CTxMemPoolEntry*>& entries);
189+
std::vector<const CTxMemPoolEntry*>& entries)
190+
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
190191

191192
/** Process a transaction accepted to the mempool*/
192-
void processTransaction(const CTxMemPoolEntry& entry, bool validFeeEstimate);
193+
void processTransaction(const CTxMemPoolEntry& entry, bool validFeeEstimate)
194+
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
193195

194196
/** Remove a transaction from the mempool tracking stats*/
195-
bool removeTx(uint256 hash, bool inBlock);
197+
bool removeTx(uint256 hash, bool inBlock)
198+
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
196199

197200
/** DEPRECATED. Return a feerate estimate */
198-
CFeeRate estimateFee(int confTarget) const;
201+
CFeeRate estimateFee(int confTarget) const
202+
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
199203

200204
/** Estimate feerate needed to get be included in a block within confTarget
201205
* blocks. If no answer can be given at confTarget, return an estimate at
202206
* the closest target where one can be given. 'conservative' estimates are
203207
* valid over longer time horizons also.
204208
*/
205-
CFeeRate estimateSmartFee(int confTarget, FeeCalculation *feeCalc, bool conservative) const;
209+
CFeeRate estimateSmartFee(int confTarget, FeeCalculation *feeCalc, bool conservative) const
210+
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
206211

207212
/** Return a specific fee estimate calculation with a given success
208213
* threshold and time horizon, and optionally return detailed data about
209214
* calculation
210215
*/
211-
CFeeRate estimateRawFee(int confTarget, double successThreshold, FeeEstimateHorizon horizon, EstimationResult *result = nullptr) const;
216+
CFeeRate estimateRawFee(int confTarget, double successThreshold, FeeEstimateHorizon horizon,
217+
EstimationResult* result = nullptr) const
218+
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
212219

213220
/** Write estimation data to a file */
214-
bool Write(CAutoFile& fileout) const;
221+
bool Write(CAutoFile& fileout) const
222+
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
215223

216224
/** Read estimation data from a file */
217-
bool Read(CAutoFile& filein);
225+
bool Read(CAutoFile& filein)
226+
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
218227

219228
/** Empty mempool transactions on shutdown to record failure to confirm for txs still in mempool */
220-
void FlushUnconfirmed();
229+
void FlushUnconfirmed()
230+
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
221231

222232
/** Calculation of highest target that estimates are tracked for */
223-
unsigned int HighestTargetTracked(FeeEstimateHorizon horizon) const;
233+
unsigned int HighestTargetTracked(FeeEstimateHorizon horizon) const
234+
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
224235

225236
/** Drop still unconfirmed transactions and record current estimations, if the fee estimation file is present. */
226-
void Flush();
237+
void Flush()
238+
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
227239

228240
private:
229-
mutable RecursiveMutex m_cs_fee_estimator;
241+
mutable Mutex m_cs_fee_estimator;
230242

231243
unsigned int nBestSeenHeight GUARDED_BY(m_cs_fee_estimator);
232244
unsigned int firstRecordedHeight GUARDED_BY(m_cs_fee_estimator);
@@ -267,6 +279,10 @@ class CBlockPolicyEstimator
267279
unsigned int HistoricalBlockSpan() const EXCLUSIVE_LOCKS_REQUIRED(m_cs_fee_estimator);
268280
/** Calculation of highest target that reasonable estimate can be provided for */
269281
unsigned int MaxUsableEstimate() const EXCLUSIVE_LOCKS_REQUIRED(m_cs_fee_estimator);
282+
283+
/** A non-thread-safe helper for the removeTx function */
284+
bool _removeTx(const uint256& hash, bool inBlock)
285+
EXCLUSIVE_LOCKS_REQUIRED(m_cs_fee_estimator);
270286
};
271287

272288
class FeeFilterRounder

0 commit comments

Comments
 (0)