23#include <validation.h>
31#include <system_error>
37struct MinedBlockStatsFormatter {
38 template <
typename Stream>
43 template <
typename Stream>
53 return block.m_height >= stats.m_height;
58 "%s: connected block height=%s discards tracked mined-block stats "
59 "from height=%s to height=%s; stale_stats=%s",
69 "%s: clearing mined-block stats after height gap; tracked_stats=%s "
70 "expected_height=%s received_height=%s",
91 if (!
tip)
return std::nullopt;
122std::optional<MemPoolFeeRateEstimatorCache::FeeRateEstimate>
153 return "Not enough recent block data for fee rate estimation";
155 return "Mempool is unreliable for fee rate estimation";
166 : m_mempool(mempool),
167 m_chainman(chainman),
195 LogWarning(
"%s: file version not supported; continuing anyway",
200 std::vector<MinedBlockStats>
blocks;
205 LogWarning(
"%s: Number of previously mined blocks read exceeds the maximum of %s; ignoring file",
210 for (
size_t i = 1; i <
blocks.size(); ++i) {
213 LogWarning(
"%s: Non-consecutive block heights read, expected height %s but found %s; ignoring file",
223 LogWarning(
"%s: Mined-block stats read end at height %s block %s, but there is no active chain tip; ignoring file",
229 LogWarning(
"%s: Mined-block stats read end at height %s block %s, but the active chain tip is height %s block %s; ignoring file",
240 }
catch (
const std::exception&) {
241 LogWarning(
"%s: Unable to read mined-block stats from stream (non-fatal)",
255 }
catch (
const std::exception&) {
264 std::error_code error;
267 LogWarning(
"%s: failed to create mempool policy estimator directory %s: %s. Continuing anyway",
275 LogWarning(
"%s: unable to open %s for writing. Continuing anyway",
281 LogWarning(
"%s: Unable to write mined-block stats to %s (non-fatal)",
285 if (file.fclose() != 0) {
286 LogWarning(
"Failed to close mempool policy estimator file %s: %s. Continuing anyway.",
306 unsigned int block_height)
309 Assert(!block->vtx.empty());
317 return acc + get_tx_weight(tx);
322 return acc + get_tx_weight(tx.info.m_tx);
359 "%s: mempool health check %s; removed_weight=%s total_block_weight=%s "
360 "coverage=%.2f required_coverage=%.2f",
407 const FeePerVSize floor{std::max(m_mempool.m_opts.min_relay_feerate, m_mempool.GetMinFee()).GetFeePerVSize()};
#define Assert(val)
Identity function.
#define Assume(val)
Assume is the identity function.
Non-refcounted RAII wrapper for FILE*.
Wrapper around FeeFrac & derived types, which adds a feerate-based ordering which treats equal-feerat...
The block chain is a tree shaped structure starting with the genesis block at the root,...
int nHeight
height of the entry in the chain. The genesis block has height 0
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Fee rate in satoshis per virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
bool GetLoadTried() const
CChain m_chain
The current chain of blockheaders we consult and build on.
Interface for managing multiple Chainstate objects, where each chainstate is associated with chainsta...
CBlockIndex * ActiveTip() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
SnapshotCompletionResult MaybeValidateSnapshot(Chainstate &validated_cs, Chainstate &unvalidated_cs) EXCLUSIVE_LOCKS_REQUIRED(Chainstate & CurrentChainstate() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Try to validate an assumeutxo snapshot by using a validated historical chainstate targeted at the sna...
std::optional< FeeRateEstimate > GetCachedEstimate(const uint256 &tip_hash) const
Returns cached estimates if not stale and computed on tip_hash, nullopt otherwise.
NodeClock::time_point m_last_updated
void Clear()
Clear cached fee rate estimates.
bool IsStale() const
Returns true if the cache is empty or older than CACHE_LIFE.
std::optional< FeeRateEstimate > m_fee_rate_estimation
void Update(FeePerVSize conservative, FeePerVSize economical, const uint256 &tip_hash)
Update the cache with new estimates computed on tip_hash.
void ReadFromDisk() EXCLUSIVE_LOCKS_REQUIRED(!cs)
bool Write(AutoFile &file) const EXCLUSIVE_LOCKS_REQUIRED(!cs)
Serialize mined-block stats without taking ownership of file.
MempoolHealth GetMempoolHealth() const EXCLUSIVE_LOCKS_REQUIRED(!cs)
const CTxMemPool & m_mempool
ChainstateManager & m_chainman
void MempoolTxsRemovedForBlock(const std::shared_ptr< const CBlock > &block, const std::vector< RemovedMempoolTransactionInfo > &txs_removed_for_block, unsigned int block_height) EXCLUSIVE_LOCKS_REQUIRED(!cs)
void FlushMinedBlockStats() EXCLUSIVE_LOCKS_REQUIRED(!cs)
static Percentiles CalculateMaxWeightPercentiles(std::span< const FeePerVSize > chunk_feerates)
Calculate the 50th and 75th percentile fee rates from block template chunks, sorted in descending min...
const fs::path m_mempool_estimator_file_path
bool Read(AutoFile &file) EXCLUSIVE_LOCKS_REQUIRED(!cs)
Deserialize mined-block stats without taking ownership of file.
util::Expected< FeeRateEstimation, FeeRateEstimationError > EstimateFeeRate(bool conservative) const EXCLUSIVE_LOCKS_REQUIRED(!cs)
MemPoolFeeRateEstimator(fs::path mempool_estimator_file_path, const CTxMemPool &mempool, ChainstateManager &chainman)
MempoolHealth
Health of the recent mined-block window for fee rate estimation.
@ LOW_COVERAGE
Recent blocks include too few mempool transactions to estimate a fee rate.
@ HEALTHY
Recent blocks represent the mempool well enough to estimate a fee rate.
@ INSUFFICIENT_DATA
Too few recent mined blocks to estimate a fee rate.
void MempoolLoadFailed() EXCLUSIVE_LOCKS_REQUIRED(!cs)
Generate a new block, without valid proof-of-work.
The util::Expected class provides a standard way for low-level functions to return either error value...
The util::Unexpected class represents an unexpected value stored in util::Expected.
static int32_t GetTransactionWeight(const CTransaction &tx)
constexpr int WITNESS_SCALE_FACTOR
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
const std::string CURRENCY_ATOM
static std::string PathToString(const path &path)
Convert path object to a byte string.
#define LogDebug(category,...)
constexpr int CURRENT_MEMPOOL_ESTIMATOR_VERSION
static constexpr uint64_t MIN_REPRESENTATIVE_WINDOW_WEIGHT
static std::optional< std::string_view > MempoolHealthError(MemPoolFeeRateEstimator::MempoolHealth health)
static util::Unexpected< FeeRateEstimationError > EstimationError(std::string error)
Build the error result for a failed mempool fee rate estimation.
constexpr int MEMPOOL_FEE_ESTIMATOR_MAX_TARGET
constexpr std::chrono::seconds CACHE_LIFE
constexpr double MEMPOOL_REPRESENTATION_THRESHOLD
constexpr size_t MEMPOOL_HEALTH_WINDOW_BLOCKS
FILE * fopen(const fs::path &p, const char *mode)
T SaturatingAdd(const T i, const T j) noexcept
constexpr unsigned int DEFAULT_BLOCK_MAX_WEIGHT
Default for -blockmaxweight, which controls the range of block weights the mining code will create.
std::shared_ptr< const CTransaction > CTransactionRef
bool IsEmpty() const noexcept
Check if this is empty (size and fee are 0).
A successful fee rate estimate returned by a fee rate estimator.
Weight statistics for a recently mined block, used to assess mempool coverage.
uint64_t m_block_weight
Total non-coinbase transaction weight in the block.
uint64_t m_height
Block height.
uint64_t m_removed_block_txs_weight
Weight of mempool transactions removed for this block (excluding coinbase).
static time_point now() noexcept
Return current system time or mocked time, if set.
Block template creation options.
bool test_block_validity
Whether to call TestBlockValidity() at the end of CreateNewBlock().
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
std::string SysErrorString(int err)
Return system error string from errno value.
std::string_view FeeRateEstimatorTypeToString(FeeRateEstimatorType feerate_estimator_type)
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.