diff options
author | Carl Dong <contact@carldong.me> | 2021-10-28 13:46:19 -0400 |
---|---|---|
committer | Carl Dong <contact@carldong.me> | 2022-06-28 15:36:18 -0400 |
commit | 82f00de7a6a60cbc9ad0c6e1d0ffb1bc70c49af5 (patch) | |
tree | 1a034d8f11035bf508c82a9cac2c8d935c648d03 | |
parent | f1941e8bfd2eecc478c7660434b1ebf6a64095a0 (diff) |
mempool: Pass in -maxmempool instead of referencing gArgs
- Store the mempool size limit (-maxmempool) in CTxMemPool as a member.
- Remove the requirement to explicitly specify a mempool size limit for
CTxMemPool::GetMinFee(...) and LimitMempoolSize(...), just use the
stored mempool size limit where possible.
- Remove all now-unnecessary instances of:
gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE_MB) * 1000000
The code change in CChainState::GetCoinsCacheSizeState() is correct
since the coinscache should not repurpose "extra" mempool memory
headroom for itself if the mempool doesn't even exist.
-rw-r--r-- | src/kernel/mempool_options.h | 6 | ||||
-rw-r--r-- | src/mempool_args.cpp | 2 | ||||
-rw-r--r-- | src/net_processing.cpp | 2 | ||||
-rw-r--r-- | src/node/interfaces.cpp | 2 | ||||
-rw-r--r-- | src/policy/policy.h | 2 | ||||
-rw-r--r-- | src/rpc/fees.cpp | 2 | ||||
-rw-r--r-- | src/rpc/mempool.cpp | 5 | ||||
-rw-r--r-- | src/txmempool.cpp | 3 | ||||
-rw-r--r-- | src/txmempool.h | 5 | ||||
-rw-r--r-- | src/validation.cpp | 12 |
10 files changed, 25 insertions, 16 deletions
diff --git a/src/kernel/mempool_options.h b/src/kernel/mempool_options.h index c3d54bf0f4..e8c129050e 100644 --- a/src/kernel/mempool_options.h +++ b/src/kernel/mempool_options.h @@ -4,8 +4,13 @@ #ifndef BITCOIN_KERNEL_MEMPOOL_OPTIONS_H #define BITCOIN_KERNEL_MEMPOOL_OPTIONS_H +#include <cstdint> + class CBlockPolicyEstimator; +/** Default for -maxmempool, maximum megabytes of mempool memory usage */ +static constexpr unsigned int DEFAULT_MAX_MEMPOOL_SIZE_MB{300}; + namespace kernel { /** * Options struct containing options for constructing a CTxMemPool. Default @@ -19,6 +24,7 @@ struct MemPoolOptions { CBlockPolicyEstimator* estimator{nullptr}; /* The ratio used to determine how often sanity checks will run. */ int check_ratio{0}; + int64_t max_size_bytes{DEFAULT_MAX_MEMPOOL_SIZE_MB * 1'000'000}; }; } // namespace kernel diff --git a/src/mempool_args.cpp b/src/mempool_args.cpp index 578463b81a..aef4e478f3 100644 --- a/src/mempool_args.cpp +++ b/src/mempool_args.cpp @@ -13,4 +13,6 @@ using kernel::MemPoolOptions; void ApplyArgsManOptions(const ArgsManager& argsman, MemPoolOptions& mempool_opts) { mempool_opts.check_ratio = argsman.GetIntArg("-checkmempool", mempool_opts.check_ratio); + + if (auto mb = argsman.GetIntArg("-maxmempool")) mempool_opts.max_size_bytes = *mb * 1'000'000; } diff --git a/src/net_processing.cpp b/src/net_processing.cpp index e958bef78f..14cc9c169d 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -4599,7 +4599,7 @@ void PeerManagerImpl::MaybeSendFeefilter(CNode& pto, Peer& peer, std::chrono::mi // transactions to us, regardless of feefilter state. if (pto.IsBlockOnlyConn()) return; - CAmount currentFilter = m_mempool.GetMinFee(gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE_MB) * 1000000).GetFeePerK(); + CAmount currentFilter = m_mempool.GetMinFee().GetFeePerK(); static FeeFilterRounder g_filter_rounder{CFeeRate{DEFAULT_MIN_RELAY_TX_FEE}}; if (m_chainman.ActiveChainstate().IsInitialBlockDownload()) { diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 12b40aa245..14eecdb950 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -685,7 +685,7 @@ public: CFeeRate mempoolMinFee() override { if (!m_node.mempool) return {}; - return m_node.mempool->GetMinFee(gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE_MB) * 1000000); + return m_node.mempool->GetMinFee(); } CFeeRate relayMinFee() override { return ::minRelayTxFee; } CFeeRate relayIncrementalFee() override { return ::incrementalRelayFee; } diff --git a/src/policy/policy.h b/src/policy/policy.h index 027b9c6a37..b3993b6a24 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -31,8 +31,6 @@ static constexpr unsigned int MIN_STANDARD_TX_NONWITNESS_SIZE{82}; static constexpr unsigned int MAX_P2SH_SIGOPS{15}; /** The maximum number of sigops we're willing to relay/mine in a single tx */ static constexpr unsigned int MAX_STANDARD_TX_SIGOPS_COST{MAX_BLOCK_SIGOPS_COST/5}; -/** Default for -maxmempool, maximum megabytes of mempool memory usage */ -static constexpr unsigned int DEFAULT_MAX_MEMPOOL_SIZE_MB{300}; /** Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or BIP 125 replacement **/ static constexpr unsigned int DEFAULT_INCREMENTAL_RELAY_FEE{1000}; /** Default for -bytespersigop */ diff --git a/src/rpc/fees.cpp b/src/rpc/fees.cpp index e6e8324c27..dd1a6441a0 100644 --- a/src/rpc/fees.cpp +++ b/src/rpc/fees.cpp @@ -89,7 +89,7 @@ static RPCHelpMan estimatesmartfee() FeeCalculation feeCalc; CFeeRate feeRate{fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative)}; if (feeRate != CFeeRate(0)) { - CFeeRate min_mempool_feerate{mempool.GetMinFee(gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE_MB) * 1000000)}; + CFeeRate min_mempool_feerate{mempool.GetMinFee()}; CFeeRate min_relay_feerate{::minRelayTxFee}; feeRate = std::max({feeRate, min_mempool_feerate, min_relay_feerate}); result.pushKV("feerate", ValueFromAmount(feeRate.GetFeePerK())); diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp index 07b12bc047..2cdde14144 100644 --- a/src/rpc/mempool.cpp +++ b/src/rpc/mempool.cpp @@ -657,9 +657,8 @@ UniValue MempoolInfoToJSON(const CTxMemPool& pool) ret.pushKV("bytes", (int64_t)pool.GetTotalTxSize()); ret.pushKV("usage", (int64_t)pool.DynamicMemoryUsage()); ret.pushKV("total_fee", ValueFromAmount(pool.GetTotalFee())); - int64_t maxmempool{gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE_MB) * 1000000}; - ret.pushKV("maxmempool", maxmempool); - ret.pushKV("mempoolminfee", ValueFromAmount(std::max(pool.GetMinFee(maxmempool), ::minRelayTxFee).GetFeePerK())); + ret.pushKV("maxmempool", pool.m_max_size_bytes); + ret.pushKV("mempoolminfee", ValueFromAmount(std::max(pool.GetMinFee(), ::minRelayTxFee).GetFeePerK())); ret.pushKV("minrelaytxfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())); ret.pushKV("unbroadcastcount", uint64_t{pool.GetUnbroadcastTxs().size()}); return ret; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 84088aead6..3e75f2db8d 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -453,7 +453,8 @@ void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee, CTxMemPool::CTxMemPool(const Options& opts) : m_check_ratio{opts.check_ratio}, - minerPolicyEstimator{opts.estimator} + minerPolicyEstimator{opts.estimator}, + m_max_size_bytes{opts.max_size_bytes} { _clear(); //lock free clear } diff --git a/src/txmempool.h b/src/txmempool.h index 32319ac181..d5d573b4f9 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -564,6 +564,8 @@ public: using Options = kernel::MemPoolOptions; + const int64_t m_max_size_bytes; + /** Create a new CTxMemPool. * Sanity checks will be off by default for performance, because otherwise * accepting transactions becomes O(N^2) where N is the number of transactions @@ -702,6 +704,9 @@ public: * takes the fee rate to go back down all the way to 0. When the feerate * would otherwise be half of this, it is set to 0 instead. */ + CFeeRate GetMinFee() const { + return GetMinFee(m_max_size_bytes); + } CFeeRate GetMinFee(size_t sizelimit) const; /** Remove transactions from the mempool until its dynamic size is <= sizelimit. diff --git a/src/validation.cpp b/src/validation.cpp index 4252914353..a14f82106f 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -255,7 +255,7 @@ bool CheckSequenceLocksAtTip(CBlockIndex* tip, // Returns the script flags which should be checked for a given block static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const ChainstateManager& chainman); -static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, size_t limit, std::chrono::seconds age) +static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, std::chrono::seconds age) EXCLUSIVE_LOCKS_REQUIRED(::cs_main, pool.cs) { AssertLockHeld(::cs_main); @@ -266,7 +266,7 @@ static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, siz } std::vector<COutPoint> vNoSpendsRemaining; - pool.TrimToSize(limit, &vNoSpendsRemaining); + pool.TrimToSize(pool.m_max_size_bytes, &vNoSpendsRemaining); for (const COutPoint& removed : vNoSpendsRemaining) coins_cache.Uncache(removed); } @@ -377,7 +377,6 @@ void CChainState::MaybeUpdateMempoolForReorg( LimitMempoolSize( *m_mempool, this->CoinsTip(), - gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE_MB) * 1000000, std::chrono::hours{gArgs.GetIntArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)}); } @@ -644,7 +643,7 @@ private: { AssertLockHeld(::cs_main); AssertLockHeld(m_pool.cs); - CAmount mempoolRejectFee = m_pool.GetMinFee(gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE_MB) * 1000000).GetFee(package_size); + CAmount mempoolRejectFee = m_pool.GetMinFee().GetFee(package_size); if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) { return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "mempool min fee not met", strprintf("%d < %d", package_fee, mempoolRejectFee)); } @@ -1082,7 +1081,7 @@ bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws) // in the package. LimitMempoolSize() should be called at the very end to make sure the mempool // is still within limits and package submission happens atomically. if (!args.m_package_submission && !bypass_limits) { - LimitMempoolSize(m_pool, m_active_chainstate.CoinsTip(), gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE_MB) * 1000000, std::chrono::hours{gArgs.GetIntArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)}); + LimitMempoolSize(m_pool, m_active_chainstate.CoinsTip(), std::chrono::hours{gArgs.GetIntArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)}); if (!m_pool.exists(GenTxid::Txid(hash))) return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "mempool full"); } @@ -1148,7 +1147,6 @@ bool MemPoolAccept::SubmitPackage(const ATMPArgs& args, std::vector<Workspace>& // It may or may not be the case that all the transactions made it into the mempool. Regardless, // make sure we haven't exceeded max mempool size. LimitMempoolSize(m_pool, m_active_chainstate.CoinsTip(), - gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE_MB) * 1000000, std::chrono::hours{gArgs.GetIntArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)}); // Find the wtxids of the transactions that made it into the mempool. Allow partial submission, @@ -2292,7 +2290,7 @@ CoinsCacheSizeState CChainState::GetCoinsCacheSizeState() AssertLockHeld(::cs_main); return this->GetCoinsCacheSizeState( m_coinstip_cache_size_bytes, - gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE_MB) * 1000000); + m_mempool ? m_mempool->m_max_size_bytes : 0); } CoinsCacheSizeState CChainState::GetCoinsCacheSizeState( |