From 66d4a29ab073fbfdd4fa34f15cf07b638bcdb967 Mon Sep 17 00:00:00 2001 From: ismaelsadeeq Date: Thu, 9 Jan 2025 14:41:53 -0500 Subject: [PATCH 01/22] fees: add `ForecastResult` class - This class represents the response returned by a fee rate forecaster. --- src/policy/fees/forecaster_util.h | 102 ++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/policy/fees/forecaster_util.h diff --git a/src/policy/fees/forecaster_util.h b/src/policy/fees/forecaster_util.h new file mode 100644 index 00000000000..a81057f664b --- /dev/null +++ b/src/policy/fees/forecaster_util.h @@ -0,0 +1,102 @@ +// Copyright (c) 2025 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_POLICY_FEES_FORECASTER_UTIL_H +#define BITCOIN_POLICY_FEES_FORECASTER_UTIL_H + +#include + +#include +#include + +/** + * @class ForecastResult + * Represents the response returned by a fee rate forecaster. + */ +class ForecastResult +{ +public: + /** + * @struct ForecastResponse + * Contains fee rate forecast metadata. + */ + struct ForecastResponse { + /** + * An estimated fee rate as a result of a forecast for economical transactions. + * This value is sufficient to confirm a package within the specified target. + */ + FeeFrac low_priority; + + /** + * An estimated fee rate as a result of forecast for high-priority transactions. + * This value is for users willing to pay more to increase the likelihood of + * confirmation within the specified target. + */ + FeeFrac high_priority; + + /** + * The chain tip at which the forecast was made. + */ + unsigned int current_block_height{0}; + }; + + /** + * Default ForecastResult constructor. + */ + ForecastResult() {} + + /** + * Constructs a ForecastResult object. + * @param response The forecast response data. + * @param error An optional error message (default: nullopt). + */ + ForecastResult(ForecastResponse response, std::optional error = std::nullopt) + : m_response(std::move(response)), m_error(std::move(error)) + { + } + + /** + * Checks if the forecast response is empty. + * @return true if both low and high priority forecast estimates are empty, false otherwise. + */ + bool Empty() const + { + return m_response.low_priority.IsEmpty() && m_response.high_priority.IsEmpty(); + } + + /** + * Overloaded less than operator which compares two ForecastResult objects based on + * their high priority estimates. + * @param other The other ForecastResult object to compare with. + * @return true if the current object's high priority estimate is less than the other, false otherwise. + */ + bool operator<(const ForecastResult& other) const + { + return m_response.high_priority << other.m_response.high_priority; + } + + /** + * Retrieves the forecast response. + * @return A reference to the forecast response metadata. + */ + const ForecastResponse& GetResponse() const + { + return m_response; + } + + /** + * Retrieves the error message, if any. + * @return An optional string containing the error message. + */ + const std::optional& GetError() const + { + return m_error; + } + +private: + ForecastResponse m_response; ///< The forecast response data. + std::optional m_error; ///< Optional error message. +}; + +#endif // BITCOIN_POLICY_FEES_FORECASTER_UTIL_H From a29c038e1afbf9ca4fcf168b1553785c2ba0e597 Mon Sep 17 00:00:00 2001 From: ismaelsadeeq Date: Thu, 9 Jan 2025 14:43:02 -0500 Subject: [PATCH 02/22] fees: add `ConfirmationTarget` struct - Defines the types of confirmation targets for fee rate forecasters. - This enable having a generic input for fee rate forecasters. --- src/policy/fees/forecaster_util.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/policy/fees/forecaster_util.h b/src/policy/fees/forecaster_util.h index a81057f664b..c641b622001 100644 --- a/src/policy/fees/forecaster_util.h +++ b/src/policy/fees/forecaster_util.h @@ -99,4 +99,21 @@ private: std::optional m_error; ///< Optional error message. }; +/** + * @enum ConfirmationTargetType + * Defines the types of confirmation targets for fee rate forecasters. + */ +enum class ConfirmationTargetType { + BLOCKS, /**< Forecasters providing estimates for a specific number of blocks use this type. */ +}; + +/** + * @struct ConfirmationTarget + * Represents the input for a parameter of fee rate forecaster. + */ +struct ConfirmationTarget { + unsigned int value; + ConfirmationTargetType type; +}; + #endif // BITCOIN_POLICY_FEES_FORECASTER_UTIL_H From 0de1842f1ba56395e522e5be1c58750c973fd14d Mon Sep 17 00:00:00 2001 From: ismaelsadeeq Date: Thu, 9 Jan 2025 14:55:59 -0500 Subject: [PATCH 03/22] fees: add Forecaster abstract class - This commit implements `Forecaster` abstract class as the base class of fee rate forecasters. - Derived classes must provide concrete implementation of the virtual methods. Co-authored-by: willcl-ark --- src/policy/fees/forecaster.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/policy/fees/forecaster.h diff --git a/src/policy/fees/forecaster.h b/src/policy/fees/forecaster.h new file mode 100644 index 00000000000..3fd7aeb0d81 --- /dev/null +++ b/src/policy/fees/forecaster.h @@ -0,0 +1,31 @@ +// Copyright (c) 2025 The Bitcoin Core developers +// Distributed under the MIT software license. See the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_POLICY_FEES_FORECASTER_H +#define BITCOIN_POLICY_FEES_FORECASTER_H + +#include + +/** \class Forecaster + * Abstract base class for fee rate forecasters. + */ +class Forecaster +{ +public: + Forecaster() = default; + + /** + * Forecast the fee rate required for package to confirm within + * a specified target. + * + * This pure virtual function must be overridden by derived classes. + * @param target The confirmation target for which to forecast the feerate for. + * @return ForecastResult containing the forecasted fee rate. + */ + virtual ForecastResult EstimateFee(ConfirmationTarget& target) = 0; + + virtual ~Forecaster() = default; +}; + +#endif // BITCOIN_POLICY_FEES_FORECASTER_H From 35a0576ee2b087b8a953ab9fae7ed9faf492f3b0 Mon Sep 17 00:00:00 2001 From: ismaelsadeeq Date: Thu, 9 Jan 2025 15:17:07 -0500 Subject: [PATCH 04/22] fees: add `ForecastType` enum - ForecastType will be used to identify forecasters. - Each time a new forecaster is added, a corresponding enum value should be added to ForecastType. - This allows users to identify which forecasting strategy was used to make a fee rate estimate. --- src/policy/fees/forecaster.h | 7 ++++++- src/policy/fees/forecaster_util.h | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/policy/fees/forecaster.h b/src/policy/fees/forecaster.h index 3fd7aeb0d81..6bcc37a4dd1 100644 --- a/src/policy/fees/forecaster.h +++ b/src/policy/fees/forecaster.h @@ -12,8 +12,13 @@ */ class Forecaster { +protected: + const ForecastType m_forecastType; + public: - Forecaster() = default; + Forecaster(ForecastType forecastType) : m_forecastType(forecastType) {} + + ForecastType GetForecastType() const { return m_forecastType; } /** * Forecast the fee rate required for package to confirm within diff --git a/src/policy/fees/forecaster_util.h b/src/policy/fees/forecaster_util.h index c641b622001..6485fc76b9b 100644 --- a/src/policy/fees/forecaster_util.h +++ b/src/policy/fees/forecaster_util.h @@ -10,6 +10,12 @@ #include #include +/** + * @enum ForecastType + * Identifier for fee rate forecasters. + */ +enum class ForecastType {}; + /** * @class ForecastResult * Represents the response returned by a fee rate forecaster. @@ -39,6 +45,8 @@ public: * The chain tip at which the forecast was made. */ unsigned int current_block_height{0}; + /* This identifies which forecaster is providing this feerate forecast */ + ForecastType forecaster; }; /** From 51347355a74f6be729d3749c6dd6a4ec3c253df0 Mon Sep 17 00:00:00 2001 From: ismaelsadeeq Date: Mon, 13 Jan 2025 17:02:27 -0500 Subject: [PATCH 05/22] fees: add `ForecasterMan` class - Its a module for managing and utilising multiple fee rate forecasters to provide fee rate forecast. - The ForecasterManager class allows for the registration of multiple fee rate forecasters. Co-authored-by: willcl-ark --- src/CMakeLists.txt | 1 + src/policy/fees/forecaster_man.cpp | 14 +++++++++++ src/policy/fees/forecaster_man.h | 37 ++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 src/policy/fees/forecaster_man.cpp create mode 100644 src/policy/fees/forecaster_man.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 89fdd855a45..e06f0dd0693 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -259,6 +259,7 @@ add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL policy/ephemeral_policy.cpp policy/fees.cpp policy/fees_args.cpp + policy/fees/forecaster_man.cpp policy/packages.cpp policy/rbf.cpp policy/settings.cpp diff --git a/src/policy/fees/forecaster_man.cpp b/src/policy/fees/forecaster_man.cpp new file mode 100644 index 00000000000..462fb2c8026 --- /dev/null +++ b/src/policy/fees/forecaster_man.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2025 The Bitcoin Core developers +// Distributed under the MIT software license. See the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include + +#include + +void FeeRateForecasterManager::RegisterForecaster(std::shared_ptr forecaster) +{ + forecasters.emplace(forecaster->GetForecastType(), forecaster); +} diff --git a/src/policy/fees/forecaster_man.h b/src/policy/fees/forecaster_man.h new file mode 100644 index 00000000000..13784e0e0a3 --- /dev/null +++ b/src/policy/fees/forecaster_man.h @@ -0,0 +1,37 @@ +// Copyright (c) 2025 The Bitcoin Core developers +// Distributed under the MIT software license. See the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_POLICY_FEES_FORECASTER_MAN_H +#define BITCOIN_POLICY_FEES_FORECASTER_MAN_H + +#include +#include + +class Forecaster; +class ForecastResult; + +enum class ForecastType; + +/** \class FeeRateForecasterManager + * Module for managing and utilising multiple fee rate forecasters to provide a forecast for a target. + * + * The FeeRateForecasterManager class allows for the registration of multiple fee rate + * forecasters. + */ +class FeeRateForecasterManager +{ +private: + //! Map of all registered forecasters to their shared pointers. + std::unordered_map> forecasters; + +public: + /** + * Register a forecaster to provide fee rate estimates. + * + * @param[in] forecaster shared pointer to a Forecaster instance. + */ + void RegisterForecaster(std::shared_ptr forecaster); +}; + +#endif // BITCOIN_POLICY_FEES_FORECASTER_MAN_H From 435f2424d1b0013a6ef58de7cb50e6e77e8d1659 Mon Sep 17 00:00:00 2001 From: ismaelsadeeq Date: Mon, 13 Jan 2025 09:58:23 -0500 Subject: [PATCH 06/22] fees: refactor: rename policy_fee_tests.cpp to feerounder_tests.cpp - Also remame the test suite name to match the new name. --- src/test/CMakeLists.txt | 2 +- src/test/{policy_fee_tests.cpp => feerounder_tests.cpp} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/test/{policy_fee_tests.cpp => feerounder_tests.cpp} (96%) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 859b9132067..09669dd3d85 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -62,6 +62,7 @@ add_executable(test_bitcoin descriptor_tests.cpp disconnected_transactions.cpp feefrac_tests.cpp + feerounder_tests.cpp flatfile_tests.cpp fs_tests.cpp getarg_tests.cpp @@ -89,7 +90,6 @@ add_executable(test_bitcoin orphanage_tests.cpp peerman_tests.cpp pmt_tests.cpp - policy_fee_tests.cpp policyestimator_tests.cpp pool_tests.cpp pow_tests.cpp diff --git a/src/test/policy_fee_tests.cpp b/src/test/feerounder_tests.cpp similarity index 96% rename from src/test/policy_fee_tests.cpp rename to src/test/feerounder_tests.cpp index 29d70cb5f85..400437e65ec 100644 --- a/src/test/policy_fee_tests.cpp +++ b/src/test/feerounder_tests.cpp @@ -9,7 +9,7 @@ #include -BOOST_AUTO_TEST_SUITE(policy_fee_tests) +BOOST_AUTO_TEST_SUITE(fee_rounder_tests) BOOST_AUTO_TEST_CASE(FeeRounder) { From 86d46e71b5db222c6268f6347e9ed8524597d95f Mon Sep 17 00:00:00 2001 From: ismaelsadeeq Date: Thu, 9 Jan 2025 17:31:05 -0500 Subject: [PATCH 07/22] fees: refactor: rename fees to block_policy_estimator - Also move it to policy/fees and update the includes - Note: the block_policy_estimator.h include in block_policy_estimator.cpp was done manually. --- src/CMakeLists.txt | 2 +- src/common/messages.cpp | 2 +- src/init.cpp | 3 ++- src/net_processing.cpp | 2 +- src/node/context.cpp | 2 +- src/node/interfaces.cpp | 3 ++- src/policy/{fees.cpp => fees/block_policy_estimator.cpp} | 2 +- src/policy/{fees.h => fees/block_policy_estimator.h} | 6 +++--- src/qt/sendcoinsdialog.cpp | 2 +- src/rpc/fees.cpp | 2 +- src/rpc/server_util.cpp | 3 ++- src/test/feerounder_tests.cpp | 2 +- src/test/fuzz/fees.cpp | 2 +- src/test/fuzz/kitchen_sink.cpp | 2 +- src/test/fuzz/policy_estimator.cpp | 2 +- src/test/fuzz/policy_estimator_io.cpp | 2 +- src/test/policyestimator_tests.cpp | 2 +- src/test/util/setup_common.cpp | 2 +- src/wallet/coincontrol.h | 2 +- src/wallet/feebumper.cpp | 2 +- src/wallet/interfaces.cpp | 2 +- src/wallet/spend.h | 2 +- src/wallet/test/spend_tests.cpp | 2 +- 23 files changed, 28 insertions(+), 25 deletions(-) rename src/policy/{fees.cpp => fees/block_policy_estimator.cpp} (99%) rename src/policy/{fees.h => fees/block_policy_estimator.h} (98%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e06f0dd0693..18fc303ed62 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -257,7 +257,7 @@ add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL node/warnings.cpp noui.cpp policy/ephemeral_policy.cpp - policy/fees.cpp + policy/fees/block_policy_estimator.cpp policy/fees_args.cpp policy/fees/forecaster_man.cpp policy/packages.cpp diff --git a/src/common/messages.cpp b/src/common/messages.cpp index 5fe3e9e4d86..c08889f125b 100644 --- a/src/common/messages.cpp +++ b/src/common/messages.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/init.cpp b/src/init.cpp index 1f597cb7cb2..52c71b56843 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -56,7 +56,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/src/net_processing.cpp b/src/net_processing.cpp index def758b9157..c8454816f01 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/node/context.cpp b/src/node/context.cpp index 75dfaee866d..bfec54bc0f5 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index fe88a6dad11..0edf01d4c92 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -40,7 +40,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/src/policy/fees.cpp b/src/policy/fees/block_policy_estimator.cpp similarity index 99% rename from src/policy/fees.cpp rename to src/policy/fees/block_policy_estimator.cpp index e85b2f2caaa..d23dae672cd 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees/block_policy_estimator.cpp @@ -3,7 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include +#include #include #include diff --git a/src/policy/fees.h b/src/policy/fees/block_policy_estimator.h similarity index 98% rename from src/policy/fees.h rename to src/policy/fees/block_policy_estimator.h index a95cc19dd45..394a1d7f885 100644 --- a/src/policy/fees.h +++ b/src/policy/fees/block_policy_estimator.h @@ -2,8 +2,8 @@ // Copyright (c) 2009-2022 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_POLICY_FEES_H -#define BITCOIN_POLICY_FEES_H +#ifndef BITCOIN_POLICY_FEES_BLOCK_POLICY_ESTIMATOR_H +#define BITCOIN_POLICY_FEES_BLOCK_POLICY_ESTIMATOR_H #include #include @@ -342,4 +342,4 @@ private: FastRandomContext& insecure_rand GUARDED_BY(m_insecure_rand_mutex); }; -#endif // BITCOIN_POLICY_FEES_H +#endif // BITCOIN_POLICY_FEES_BLOCK_POLICY_ESTIMATOR_H diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 0ee1b359fa9..d079cf76df2 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/rpc/fees.cpp b/src/rpc/fees.cpp index 10caa9ed2ec..f5dae48bd29 100644 --- a/src/rpc/fees.cpp +++ b/src/rpc/fees.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/rpc/server_util.cpp b/src/rpc/server_util.cpp index 0edd7527a95..4ad99499d46 100644 --- a/src/rpc/server_util.cpp +++ b/src/rpc/server_util.cpp @@ -9,7 +9,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/src/test/feerounder_tests.cpp b/src/test/feerounder_tests.cpp index 400437e65ec..3fbbec226d4 100644 --- a/src/test/feerounder_tests.cpp +++ b/src/test/feerounder_tests.cpp @@ -3,7 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include -#include +#include #include diff --git a/src/test/fuzz/fees.cpp b/src/test/fuzz/fees.cpp index 5c760be13d8..861168ff6ad 100644 --- a/src/test/fuzz/fees.cpp +++ b/src/test/fuzz/fees.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/test/fuzz/kitchen_sink.cpp b/src/test/fuzz/kitchen_sink.cpp index 62b49106cdd..2ff0841ac7c 100644 --- a/src/test/fuzz/kitchen_sink.cpp +++ b/src/test/fuzz/kitchen_sink.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/test/fuzz/policy_estimator.cpp b/src/test/fuzz/policy_estimator.cpp index 29427403952..699b72beeaf 100644 --- a/src/test/fuzz/policy_estimator.cpp +++ b/src/test/fuzz/policy_estimator.cpp @@ -3,7 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include -#include +#include #include #include #include diff --git a/src/test/fuzz/policy_estimator_io.cpp b/src/test/fuzz/policy_estimator_io.cpp index 3e7d0933439..2a50b6da8bb 100644 --- a/src/test/fuzz/policy_estimator_io.cpp +++ b/src/test/fuzz/policy_estimator_io.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include +#include #include #include #include diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index f767cd42871..945cc7519e2 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include +#include #include #include #include diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 970e1a917cb..a1f7355f43d 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/wallet/coincontrol.h b/src/wallet/coincontrol.h index d36314312ad..55eb792f4e4 100644 --- a/src/wallet/coincontrol.h +++ b/src/wallet/coincontrol.h @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include