Coverage Report

Created: 2026-09-14 20:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/tmp/bitcoin/src/policy/fees/estimator_man.cpp
Line
Count
Source
1
// Copyright (c) The Bitcoin Core developers
2
// Distributed under the MIT software license. See the accompanying
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5
#include <policy/fees/estimator_man.h>
6
7
#include <logging.h>
8
#include <policy/feerate.h>
9
#include <policy/fees/block_policy_estimator.h>
10
#include <policy/fees/mempool_estimator.h>
11
#include <util/fees.h>
12
13
1.07k
FeeRateEstimatorManager::~FeeRateEstimatorManager() = default;
14
15
FeeRateEstimatorManager::FeeRateEstimatorManager(const fs::path& block_policy_path,
16
                                                 bool read_stale_estimates,
17
                                                 const fs::path& mempool_estimator_path,
18
                                                 const CTxMemPool& mempool,
19
                                                 ChainstateManager& chainman)
20
1.07k
    : m_block_policy_estimator(std::make_unique<CBlockPolicyEstimator>(block_policy_path, read_stale_estimates)),
21
1.07k
      m_mempool_estimator(std::make_unique<MemPoolFeeRateEstimator>(mempool_estimator_path, mempool, chainman))
22
1.07k
{
23
1.07k
}
24
25
util::Expected<FeeRateEstimation, FeeRateEstimationError> FeeRateEstimatorManager::GetFeeRateEstimate(int target, bool conservative) const
26
6.71k
{
27
6.71k
    auto block_policy_estimate = m_block_policy_estimator->EstimateFeeRate(target, conservative);
28
6.71k
    if (!block_policy_estimate) {
29
3.60k
        LogDebug(BCLog::ESTIMATEFEE, "%s", block_policy_estimate.error().reason);
30
3.60k
        return block_policy_estimate;
31
3.60k
    }
32
3.10k
    auto mempool_estimate = m_mempool_estimator->EstimateFeeRate(conservative);
33
3.10k
    if (!mempool_estimate) {
34
        // A failed mempool estimate is surfaced as a warning rather than silently returning the
35
        // block policy estimate, which callers can still request explicitly.
36
1
        LogDebug(BCLog::ESTIMATEFEE, "%s", mempool_estimate.error().reason);
37
1
        return mempool_estimate;
38
1
    }
39
3.10k
    auto selected_estimate = std::min(*block_policy_estimate, *mempool_estimate);
40
3.10k
    LogDebug(BCLog::ESTIMATEFEE, "Fee rate estimated using %s: target=%s feerate=%s %s/kvB.",
41
3.10k
             FeeRateEstimatorTypeToString(selected_estimate.feerate_estimator),
42
3.10k
             selected_estimate.returned_target, CFeeRate(selected_estimate.feerate).GetFeePerK(), CURRENCY_ATOM);
43
3.10k
    return selected_estimate;
44
3.10k
}
45
46
util::Expected<FeeRateEstimation, FeeRateEstimationError> FeeRateEstimatorManager::GetFeeRateEstimate(FeeRateEstimatorType type, int target, bool conservative) const
47
187
{
48
187
    switch (type) {
49
13
    case FeeRateEstimatorType::NONE:
50
13
        return GetFeeRateEstimate(target, conservative);
51
172
    case FeeRateEstimatorType::BLOCK_POLICY:
52
172
        return m_block_policy_estimator->EstimateFeeRate(target, conservative);
53
2
    case FeeRateEstimatorType::MEMPOOL_POLICY:
54
2
        return m_mempool_estimator->EstimateFeeRate(conservative);
55
187
    } // no default case, so the compiler can warn about missing cases
56
187
    assert(false);
57
0
}
58
59
void FeeRateEstimatorManager::IntervalFlush()
60
4
{
61
4
    m_block_policy_estimator->FlushFeeEstimates();
62
4
    m_mempool_estimator->FlushMinedBlockStats();
63
4
}
64
65
void FeeRateEstimatorManager::ShutdownFlush()
66
1.07k
{
67
1.07k
    m_block_policy_estimator->Flush();
68
1.07k
    m_mempool_estimator->FlushMinedBlockStats();
69
1.07k
}
70
71
std::vector<MinedBlockStats> FeeRateEstimatorManager::MempoolPolicyEstimatorBlocksStats() const
72
3
{
73
3
    return m_mempool_estimator->GetPrevBlockData();
74
3
}
75
76
void FeeRateEstimatorManager::TransactionAddedToMempool(const NewMempoolTransactionInfo& tx, uint64_t /*unused*/)
77
26.7k
{
78
26.7k
    m_block_policy_estimator->processTransaction(tx);
79
26.7k
}
80
81
void FeeRateEstimatorManager::TransactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason /*unused*/, uint64_t /*unused*/)
82
2.01k
{
83
2.01k
    m_block_policy_estimator->removeTx(tx->GetHash());
84
2.01k
}
85
86
void FeeRateEstimatorManager::MempoolTransactionsRemovedForBlock(const std::shared_ptr<const CBlock>& block, const std::vector<RemovedMempoolTransactionInfo>& txs_removed_for_block, unsigned int block_height)
87
79.2k
{
88
79.2k
    m_block_policy_estimator->processBlock(txs_removed_for_block, block_height);
89
79.2k
    m_mempool_estimator->MempoolTxsRemovedForBlock(block, txs_removed_for_block, block_height);
90
79.2k
}
91
92
CFeeRate FeeRateEstimatorManager::BlockPolicyEstimateRawFee(unsigned int target, double threshold, FeeEstimateHorizon horizon, EstimationResult* buckets) const
93
319
{
94
319
    return m_block_policy_estimator->estimateRawFee(target, threshold, horizon, buckets);
95
319
}
96
97
unsigned int FeeRateEstimatorManager::BlockPolicyHighestTargetTracked(FeeEstimateHorizon horizon) const
98
384
{
99
384
    return m_block_policy_estimator->HighestTargetTracked(horizon);
100
384
}
101
102
unsigned int FeeRateEstimatorManager::MaximumTarget() const
103
4.12k
{
104
4.12k
    return std::max(m_block_policy_estimator->MaximumTarget(), m_mempool_estimator->MaximumTarget());
105
4.12k
}