Skip to content

Commit 0bac04b

Browse files
committed
Merge bitcoin/bitcoin#24407: fees: make the class FeeFilterRounder thread-safe
8173f16 style: rename variables to match coding style (Vasil Dimov) 8b4ad20 fees: make FeeFilterRounder::feeset const (Vasil Dimov) e7a5bf6 fees: make the class FeeFilterRounder thread-safe (Vasil Dimov) Pull request description: Make the class `FeeFilterRounder` thread-safe so that its methods can be called concurrently by different threads on the same object. Currently it has just one method (`round()`). The second commit is optional, but it improves readability, showing that the `feeset` member will never be changed, thus does not need protection from concurrent access. ACKs for top commit: jonatack: re-ACK 8173f16 laanwj: Code review ACK 8173f16 promag: Code review ACK 8173f16 Tree-SHA512: 94b809997c485c0d114fa702d0406b980be8eaaebcfefa56808ed670aa943959c2f16cfd0ef72b4752fe2a409a23af1b4b7f2f236e51212957759569e3bbbefd
2 parents 5ff3d1e + 8173f16 commit 0bac04b

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

src/policy/fees.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,20 +1011,36 @@ void CBlockPolicyEstimator::FlushUnconfirmed()
10111011
LogPrint(BCLog::ESTIMATEFEE, "Recorded %u unconfirmed txs from mempool in %gs\n", num_entries, Ticks<SecondsDouble>(endclear - startclear));
10121012
}
10131013

1014-
FeeFilterRounder::FeeFilterRounder(const CFeeRate& minIncrementalFee)
1014+
static std::set<double> MakeFeeSet(const CFeeRate& min_incremental_fee,
1015+
double max_filter_fee_rate,
1016+
double fee_filter_spacing)
10151017
{
1016-
CAmount minFeeLimit = std::max(CAmount(1), minIncrementalFee.GetFeePerK() / 2);
1017-
feeset.insert(0);
1018-
for (double bucketBoundary = minFeeLimit; bucketBoundary <= MAX_FILTER_FEERATE; bucketBoundary *= FEE_FILTER_SPACING) {
1019-
feeset.insert(bucketBoundary);
1018+
std::set<double> fee_set;
1019+
1020+
const CAmount min_fee_limit{std::max(CAmount(1), min_incremental_fee.GetFeePerK() / 2)};
1021+
fee_set.insert(0);
1022+
for (double bucket_boundary = min_fee_limit;
1023+
bucket_boundary <= max_filter_fee_rate;
1024+
bucket_boundary *= fee_filter_spacing) {
1025+
1026+
fee_set.insert(bucket_boundary);
10201027
}
1028+
1029+
return fee_set;
1030+
}
1031+
1032+
FeeFilterRounder::FeeFilterRounder(const CFeeRate& minIncrementalFee)
1033+
: m_fee_set{MakeFeeSet(minIncrementalFee, MAX_FILTER_FEERATE, FEE_FILTER_SPACING)}
1034+
{
10211035
}
10221036

10231037
CAmount FeeFilterRounder::round(CAmount currentMinFee)
10241038
{
1025-
std::set<double>::iterator it = feeset.lower_bound(currentMinFee);
1026-
if ((it != feeset.begin() && insecure_rand.rand32() % 3 != 0) || it == feeset.end()) {
1027-
it--;
1039+
std::set<double>::iterator it = m_fee_set.lower_bound(currentMinFee);
1040+
if (it == m_fee_set.end() ||
1041+
(it != m_fee_set.begin() &&
1042+
WITH_LOCK(m_insecure_rand_mutex, return insecure_rand.rand32()) % 3 != 0)) {
1043+
--it;
10281044
}
10291045
return static_cast<CAmount>(*it);
10301046
}

src/policy/fees.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -299,14 +299,15 @@ class FeeFilterRounder
299299

300300
public:
301301
/** Create new FeeFilterRounder */
302-
explicit FeeFilterRounder(const CFeeRate& minIncrementalFee);
302+
explicit FeeFilterRounder(const CFeeRate& min_incremental_fee);
303303

304-
/** Quantize a minimum fee for privacy purpose before broadcast. Not thread-safe due to use of FastRandomContext */
304+
/** Quantize a minimum fee for privacy purpose before broadcast. */
305305
CAmount round(CAmount currentMinFee);
306306

307307
private:
308-
std::set<double> feeset;
309-
FastRandomContext insecure_rand;
308+
const std::set<double> m_fee_set;
309+
Mutex m_insecure_rand_mutex;
310+
FastRandomContext insecure_rand GUARDED_BY(m_insecure_rand_mutex);
310311
};
311312

312313
#endif // BITCOIN_POLICY_FEES_H

0 commit comments

Comments
 (0)