fees: add FeeRateEstimatorManager class

Introduce FeeRateEstimatorManager to wrap CBlockPolicyEstimator and
act as the single point of contact for fee rate estimation in the node.

It inherits CValidationInterface so it can register directly with the
validation signals and receive mempool/block events.

Wire it into NodeContext (fee_estimator_man), init, shutdown, the RPC
server utility helpers (EnsureAnyFeeEstimatorMan), and the wallet-facing
interfaces::Chain API.

The Chain method estimateSmartFee is renamed to getFeeRateEstimate and
now returns util::Expected<FeeRateEstimation, FeeRateEstimationError>
instead of CFeeRate, so callers get the full estimation context without
needing FeeCalculation. estimateMaxBlocks is renamed to
maximumFeeEstimationTargetBlocks (still returns the max target).

CBlockPolicyEstimator no longer inherits CValidationInterface; the
manager now receives the mempool/block validation events and forwards
them to the CBlockPolicyEstimator.

Co-authored-by: willcl-ark <will@256k1.dev>
This commit is contained in:
ismaelsadeeq
2026-04-23 14:33:28 +01:00
parent 2cb6b831e0
commit ba6c61bbdd
20 changed files with 242 additions and 106 deletions

View File

@@ -46,7 +46,7 @@
#include <node/types.h>
#include <node/warnings.h>
#include <policy/feerate.h>
#include <policy/fees/block_policy_estimator.h>
#include <policy/fees/estimator_man.h>
#include <policy/policy.h>
#include <policy/rbf.h>
#include <primitives/block.h>
@@ -61,6 +61,8 @@
#include <univalue.h>
#include <util/btcsignals.h>
#include <util/check.h>
#include <util/expected.h>
#include <util/fees.h>
#include <util/result.h>
#include <util/signalinterrupt.h>
#include <util/string.h>
@@ -736,15 +738,15 @@ public:
}
return {};
}
CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc) override
util::Expected<FeeRateEstimation, FeeRateEstimationError> getFeeRateEstimate(int num_blocks, bool conservative) const override
{
if (!m_node.fee_estimator) return {};
return m_node.fee_estimator->estimateSmartFee(num_blocks, calc, conservative);
if (!m_node.fee_estimator_man) return EstimationError(FeeRateEstimatorType::NONE, /*returned_target=*/0, /*error=*/{});
return m_node.fee_estimator_man->GetFeeRateEstimate(num_blocks, conservative);
}
unsigned int estimateMaxBlocks() override
unsigned int maximumFeeEstimationTargetBlocks() const override
{
if (!m_node.fee_estimator) return 0;
return m_node.fee_estimator->MaximumTarget();
if (!m_node.fee_estimator_man) return 0;
return m_node.fee_estimator_man->MaximumTarget();
}
CFeeRate mempoolMinFee() override
{