diff options
author | Antoine Poinsot <darosior@protonmail.com> | 2020-07-28 19:12:50 +0200 |
---|---|---|
committer | Antoine Poinsot <darosior@protonmail.com> | 2020-12-03 12:56:37 +0100 |
commit | 86ff2cf202bfb9d9b50800b8ffe3fead3f77f5fa (patch) | |
tree | 112793cb81c576520e0a4e7573556f239d95b87c | |
parent | 03bfeee957ab7e3b6aece82b9561774648094f54 (diff) |
Remove the remaining fee estimation globals
This moves the CBlockPolicyEstimator to the NodeContext, which get rids
of two globals and allows us to conditionally create the
CBlockPolicyEstimator (and to remove a circular dep).
Signed-off-by: Antoine Poinsot <darosior@protonmail.com>
-rw-r--r-- | src/init.cpp | 28 | ||||
-rw-r--r-- | src/node/context.cpp | 1 | ||||
-rw-r--r-- | src/node/context.h | 2 | ||||
-rw-r--r-- | src/node/interfaces.cpp | 6 | ||||
-rw-r--r-- | src/rpc/blockchain.cpp | 10 | ||||
-rw-r--r-- | src/rpc/blockchain.h | 2 | ||||
-rw-r--r-- | src/rpc/mining.cpp | 16 | ||||
-rw-r--r-- | src/test/util/setup_common.cpp | 4 | ||||
-rw-r--r-- | src/validation.cpp | 3 | ||||
-rw-r--r-- | src/validation.h | 2 | ||||
-rwxr-xr-x | test/lint/lint-circular-dependencies.sh | 1 |
11 files changed, 48 insertions, 27 deletions
diff --git a/src/init.cpp b/src/init.cpp index 9137050323..5c06b0459d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -85,7 +85,6 @@ #include <zmq/zmqrpc.h> #endif -static bool fFeeEstimatesInitialized = false; static const bool DEFAULT_PROXYRANDOMIZE = true; static const bool DEFAULT_REST_ENABLE = false; static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false; @@ -236,18 +235,18 @@ void Shutdown(NodeContext& node) DumpMempool(*node.mempool); } - if (fFeeEstimatesInitialized) - { - ::feeEstimator.FlushUnconfirmed(); + if (node.fee_estimator) { + node.fee_estimator->FlushUnconfirmed(); fs::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME; CAutoFile est_fileout(fsbridge::fopen(est_path, "wb"), SER_DISK, CLIENT_VERSION); - if (!est_fileout.IsNull()) - ::feeEstimator.Write(est_fileout); - else + if (!est_fileout.IsNull()) { + node.fee_estimator->Write(est_fileout); + } else { LogPrintf("%s: Failed to write fee estimates to %s\n", __func__, est_path.string()); - fFeeEstimatesInitialized = false; + } } + // FlushStateToDisk generates a ChainStateFlushed callback, which we should avoid missing if (node.chainman) { LOCK(cs_main); @@ -304,6 +303,7 @@ void Shutdown(NodeContext& node) globalVerifyHandle.reset(); ECC_Stop(); node.mempool.reset(); + node.fee_estimator.reset(); node.chainman = nullptr; node.scheduler.reset(); @@ -1389,9 +1389,12 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA assert(!node.connman); node.connman = MakeUnique<CConnman>(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max()), args.GetBoolArg("-networkactive", true)); + assert(!node.fee_estimator); + node.fee_estimator = std::make_unique<CBlockPolicyEstimator>(); + assert(!node.mempool); int check_ratio = std::min<int>(std::max<int>(args.GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); - node.mempool = MakeUnique<CTxMemPool>(&::feeEstimator, check_ratio); + node.mempool = std::make_unique<CTxMemPool>(node.fee_estimator.get(), check_ratio); assert(!node.chainman); node.chainman = &g_chainman; @@ -1788,10 +1791,9 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA fs::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME; CAutoFile est_filein(fsbridge::fopen(est_path, "rb"), SER_DISK, CLIENT_VERSION); // Allowed to fail as this file IS missing on first startup. - if (!est_filein.IsNull()) - ::feeEstimator.Read(est_filein); - fFeeEstimatesInitialized = true; - + if (node.fee_estimator && !est_filein.IsNull()) { + node.fee_estimator->Read(est_filein); + } // ********************************************************* Step 8: start indexers if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { g_txindex = MakeUnique<TxIndex>(nTxIndexCache, false, fReindex); diff --git a/src/node/context.cpp b/src/node/context.cpp index 49d0c37235..958221a913 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -8,6 +8,7 @@ #include <interfaces/chain.h> #include <net.h> #include <net_processing.h> +#include <policy/fees.h> #include <scheduler.h> #include <txmempool.h> diff --git a/src/node/context.h b/src/node/context.h index 3228831ed1..9b611bf8f5 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -12,6 +12,7 @@ class ArgsManager; class BanMan; +class CBlockPolicyEstimator; class CConnman; class CScheduler; class CTxMemPool; @@ -36,6 +37,7 @@ class WalletClient; struct NodeContext { std::unique_ptr<CConnman> connman; std::unique_ptr<CTxMemPool> mempool; + std::unique_ptr<CBlockPolicyEstimator> fee_estimator; std::unique_ptr<PeerManager> peerman; ChainstateManager* chainman{nullptr}; // Currently a raw pointer because the memory is not managed by this struct std::unique_ptr<BanMan> banman; diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 02c5cbc6b1..da3e759e38 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -592,11 +592,13 @@ public: } CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc) override { - return ::feeEstimator.estimateSmartFee(num_blocks, calc, conservative); + if (!m_node.fee_estimator) return {}; + return m_node.fee_estimator->estimateSmartFee(num_blocks, calc, conservative); } unsigned int estimateMaxBlocks() override { - return ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); + if (!m_node.fee_estimator) return 0; + return m_node.fee_estimator->HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); } CFeeRate mempoolMinFee() override { diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 392073d047..57327e6004 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -17,6 +17,7 @@ #include <node/coinstats.h> #include <node/context.h> #include <node/utxo_snapshot.h> +#include <policy/fees.h> #include <policy/feerate.h> #include <policy/policy.h> #include <policy/rbf.h> @@ -81,6 +82,15 @@ ChainstateManager& EnsureChainman(const util::Ref& context) return *node.chainman; } +CBlockPolicyEstimator& EnsureFeeEstimator(const util::Ref& context) +{ + NodeContext& node = EnsureNodeContext(context); + if (!node.fee_estimator) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Fee estimation disabled"); + } + return *node.fee_estimator; +} + /* Calculate the difficulty for a given block index. */ double GetDifficulty(const CBlockIndex* blockindex) diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h index 5b362bf211..91766aacc9 100644 --- a/src/rpc/blockchain.h +++ b/src/rpc/blockchain.h @@ -15,6 +15,7 @@ extern RecursiveMutex cs_main; class CBlock; class CBlockIndex; +class CBlockPolicyEstimator; class CTxMemPool; class ChainstateManager; class UniValue; @@ -54,5 +55,6 @@ void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], NodeContext& EnsureNodeContext(const util::Ref& context); CTxMemPool& EnsureMemPool(const util::Ref& context); ChainstateManager& EnsureChainman(const util::Ref& context); +CBlockPolicyEstimator& EnsureFeeEstimator(const util::Ref& context); #endif diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 7d45ad9434..798973850f 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -1059,7 +1059,10 @@ static RPCHelpMan estimatesmartfee() { RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VSTR}); RPCTypeCheckArgument(request.params[0], UniValue::VNUM); - unsigned int max_target = ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); + + CBlockPolicyEstimator& fee_estimator = EnsureFeeEstimator(request.context); + + unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target); bool conservative = true; if (!request.params[1].isNull()) { @@ -1073,7 +1076,7 @@ static RPCHelpMan estimatesmartfee() UniValue result(UniValue::VOBJ); UniValue errors(UniValue::VARR); FeeCalculation feeCalc; - CFeeRate feeRate = ::feeEstimator.estimateSmartFee(conf_target, &feeCalc, conservative); + CFeeRate feeRate = fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative); if (feeRate != CFeeRate(0)) { result.pushKV("feerate", ValueFromAmount(feeRate.GetFeePerK())); } else { @@ -1144,7 +1147,10 @@ static RPCHelpMan estimaterawfee() { RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM}, true); RPCTypeCheckArgument(request.params[0], UniValue::VNUM); - unsigned int max_target = ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); + + CBlockPolicyEstimator& fee_estimator = EnsureFeeEstimator(request.context); + + unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target); double threshold = 0.95; if (!request.params[1].isNull()) { @@ -1161,9 +1167,9 @@ static RPCHelpMan estimaterawfee() EstimationResult buckets; // Only output results for horizons which track the target - if (conf_target > ::feeEstimator.HighestTargetTracked(horizon)) continue; + if (conf_target > fee_estimator.HighestTargetTracked(horizon)) continue; - feeRate = ::feeEstimator.estimateRawFee(conf_target, threshold, horizon, &buckets); + feeRate = fee_estimator.estimateRawFee(conf_target, threshold, horizon, &buckets); UniValue horizon_result(UniValue::VOBJ); UniValue errors(UniValue::VARR); UniValue passbucket(UniValue::VOBJ); diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index adf5970206..fffa29a1d3 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -16,6 +16,7 @@ #include <net.h> #include <net_processing.h> #include <noui.h> +#include <policy/fees.h> #include <pow.h> #include <rpc/blockchain.h> #include <rpc/register.h> @@ -141,7 +142,8 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const pblocktree.reset(new CBlockTreeDB(1 << 20, true)); - m_node.mempool = MakeUnique<CTxMemPool>(&::feeEstimator, 1); + m_node.fee_estimator = std::make_unique<CBlockPolicyEstimator>(); + m_node.mempool = std::make_unique<CTxMemPool>(m_node.fee_estimator.get(), 1); m_node.chainman = &::g_chainman; m_node.chainman->InitializeChainstate(*m_node.mempool); diff --git a/src/validation.cpp b/src/validation.cpp index a774e76fa9..4c2bf79534 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -22,7 +22,6 @@ #include <logging/timer.h> #include <node/ui_interface.h> #include <optional.h> -#include <policy/fees.h> #include <policy/policy.h> #include <policy/settings.h> #include <pow.h> @@ -148,8 +147,6 @@ arith_uint256 nMinimumChainWork; CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); -CBlockPolicyEstimator feeEstimator; - // Internal stuff namespace { CBlockIndex* pindexBestInvalid = nullptr; diff --git a/src/validation.h b/src/validation.h index ffb038ad75..6d8c6d431a 100644 --- a/src/validation.h +++ b/src/validation.h @@ -42,7 +42,6 @@ class CChainParams; class CInv; class CConnman; class CScriptCheck; -class CBlockPolicyEstimator; class CTxMemPool; class ChainstateManager; class TxValidationState; @@ -110,7 +109,6 @@ enum class SynchronizationState { }; extern RecursiveMutex cs_main; -extern CBlockPolicyEstimator feeEstimator; typedef std::unordered_map<uint256, CBlockIndex*, BlockHasher> BlockMap; extern Mutex g_best_block_mutex; extern std::condition_variable g_best_block_cv; diff --git a/test/lint/lint-circular-dependencies.sh b/test/lint/lint-circular-dependencies.sh index 6bd02d45ac..c4ad00e954 100755 --- a/test/lint/lint-circular-dependencies.sh +++ b/test/lint/lint-circular-dependencies.sh @@ -20,7 +20,6 @@ EXPECTED_CIRCULAR_DEPENDENCIES=( "txmempool -> validation -> txmempool" "wallet/fees -> wallet/wallet -> wallet/fees" "wallet/wallet -> wallet/walletdb -> wallet/wallet" - "policy/fees -> txmempool -> validation -> policy/fees" ) EXIT_CODE=0 |