Skip to content

Commit

Permalink
fixup! [tx fees, policy]: create a mempool fee estimator
Browse files Browse the repository at this point in the history
* adds a shared mutex to permit multiple reads, but only a single
  update.
  • Loading branch information
willcl-ark committed Feb 20, 2024
1 parent 355ff73 commit bdc1a0c
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions src/policy/mempool_fees.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <chrono>
#include <map>
#include <optional>
#include <shared_mutex>
#include <string>

#include <logging.h>
Expand All @@ -21,22 +22,35 @@ class CTxMemPool;
// mempool condition might likely change.
static const unsigned int MAX_CONF_TARGET{3};

// Cache mempool-based feerate estimates to avoid repeatedly running the
// expensive block-building algorithm.
/**
* CachedMempoolEstimates holds a cache of recent mempool-based fee estimates.
* Running the block-building algorithm multiple times is undesriable due to
* locking.
*/
struct CachedMempoolEstimates {

private:
// shared_mutex allows for multiple concurrent reads, but only a single update
mutable std::shared_mutex cache_mutex;
static constexpr std::chrono::seconds cache_life{30};
std::map<uint64_t, CFeeRate> estimates;
std::chrono::steady_clock::time_point last_updated;

bool isStale() const
{
std::shared_lock<std::shared_mutex> lock(cache_mutex);
return (last_updated + cache_life) < std::chrono::steady_clock::now();
}

public:

CachedMempoolEstimates() : last_updated(std::chrono::steady_clock::now() - cache_life - std::chrono::seconds(1)) {}
CachedMempoolEstimates(const CachedMempoolEstimates&) = delete;
CachedMempoolEstimates& operator=(const CachedMempoolEstimates&) = delete;

std::optional<CFeeRate> get(uint64_t number_of_blocks) const
{
std::shared_lock<std::shared_mutex> lock(cache_mutex);
if (isStale()) return std::nullopt;
LogPrint(BCLog::MEMPOOL, "CachedMempoolEstimates : cache is not stale, using cached value\n");

Expand All @@ -47,8 +61,9 @@ struct CachedMempoolEstimates {
return std::nullopt;
}

void update(std::map<uint64_t, CFeeRate>& newEstimates)
void update(const std::map<uint64_t, CFeeRate>& newEstimates)
{
std::unique_lock<std::shared_mutex> lock(cache_mutex);
// Overwrite the entire map with the new data to avoid old
// estimates remaining.
estimates = newEstimates;
Expand Down

0 comments on commit bdc1a0c

Please sign in to comment.