mining: store block create options in NodeContext
What changed, and why it matters
This commit is a straightforward internal code cleanup: it reads mining-related command-line options once when the program starts and stores them in a shared node structure, instead of re-reading and re-parsing them every time a block template is created or an RPC mining-info call is answered. There is no user-visible behavior change, no bug fix, and no security relevance in the diff itself.
No security action required. Treat as normal code-quality/maintenance review.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change moves parsing of mining options (e.g., -blockmaxweight) from hot paths such as interfaces.cpp’s createBlockTemplate() and rpc/mining.cpp’s getmininginfo() into initialization code in init.cpp and the test setup. A new BlockCreateOptions member, mining_args, is added to NodeContext. Call sites now use node.mining_args rather than calling node::ReadMiningArgs() repeatedly. The diff is purely refactor: option merging/flattening logic is unchanged, defaults are still applied by FlattenMiningOptions(), and no validation rules or consensus behavior are modified.
Changed components
src/init.cppsrc/node/context.hsrc/node/interfaces.cppsrc/node/mining_args.cppsrc/rpc/mining.cppsrc/test/miner_tests.cppsrc/test/util/setup_common.cppInspect captured patch +56 / −11
diff --git a/src/init.cpp b/src/init.cpp
index adf94665..aab7a52e 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1310,6 +1310,9 @@ static ChainstateLoadResult InitAndLoadChainstate(
if (!mempool_error.empty()) {
return {ChainstateLoadStatus::FAILURE_FATAL, mempool_error};
}
+ auto mining_args{node::ReadMiningArgs(args)};
+ Assert(mining_args); // no error can happen, already checked in AppInitParameterInteraction
+ node.mining_args = std::move(*mining_args);
LogInfo("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)",
cache_sizes.coins / double(1_MiB),
mempool_opts.max_size_bytes / double(1_MiB));
diff --git a/src/node/context.h b/src/node/context.h
index 848c872f..b8b3274f 100644
--- a/src/node/context.h
+++ b/src/node/context.h
@@ -5,6 +5,8 @@
#ifndef BITCOIN_NODE_CONTEXT_H
#define BITCOIN_NODE_CONTEXT_H
+#include <node/mining_types.h>
+
#include <atomic>
#include <cstdlib>
#include <functional>
@@ -81,6 +83,11 @@ struct NodeContext {
//! Reference to chain client that should used to load or create wallets
//! opened by the gui.
std::unique_ptr<interfaces::Mining> mining;
+ //! Mining options used to create block templates. This value member is an
+ //! exception to the dependency guidance above because BlockCreateOptions is
+ //! a minimal dependency. It could be moved to the BlockTemplateCache
+ //! proposed in bitcoin/bitcoin#33421.
+ BlockCreateOptions mining_args;
interfaces::WalletLoader* wallet_loader{nullptr};
std::unique_ptr<CScheduler> scheduler;
std::function<void()> rpc_interruption_point = [] {};
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index 5317af9f..5aa6e271 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -988,8 +988,7 @@ public:
// Also wait during the final catch-up moments after IBD.
if (!CooldownIfHeadersAhead(chainman(), notifications(), *maybe_tip, m_interrupt_mining)) return {};
}
- const auto args_options{*Assert(ReadMiningArgs(*Assert(m_node.args)))};
- const BlockCreateOptions create_options{MergeMiningOptions(options, args_options)};
+ const BlockCreateOptions create_options{MergeMiningOptions(options, m_node.mining_args)};
return std::make_unique<BlockTemplateImpl>(create_options,
BlockAssembler{
chainman().ActiveChainstate(),
diff --git a/src/node/mining_args.cpp b/src/node/mining_args.cpp
index 33e623a1..ec173464 100644
--- a/src/node/mining_args.cpp
+++ b/src/node/mining_args.cpp
@@ -13,10 +13,12 @@
#include <policy/policy.h>
#include <tinyformat.h>
#include <util/moneystr.h>
+#include <util/result.h>
#include <util/translation.h>
#include <cstdint>
#include <optional>
+#include <string>
#include <utility>
using common::AmountErrMsg;
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 62e64a54..e89a0e61 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -5,48 +5,77 @@
#include <bitcoin-build-config.h> // IWYU pragma: keep
+#include <interfaces/mining.h>
+
+#include <addresstype.h>
+#include <arith_uint256.h>
#include <chain.h>
#include <chainparams.h>
#include <chainparamsbase.h>
-#include <common/system.h>
#include <consensus/amount.h>
#include <consensus/consensus.h>
#include <consensus/merkle.h>
#include <consensus/params.h>
#include <consensus/validation.h>
#include <core_io.h>
-#include <deploymentinfo.h>
-#include <deploymentstatus.h>
-#include <interfaces/mining.h>
+#include <crypto/hex_base.h>
+#include <interfaces/types.h>
#include <key_io.h>
#include <net.h>
+#include <netbase.h>
+#include <node/blockstorage.h>
#include <node/context.h>
#include <node/miner.h>
#include <node/mining_args.h>
#include <node/mining_types.h>
#include <node/warnings.h>
-#include <policy/ephemeral_policy.h>
+#include <policy/feerate.h>
+#include <policy/policy.h>
#include <pow.h>
+#include <primitives/block.h>
+#include <primitives/transaction.h>
#include <rpc/blockchain.h>
#include <rpc/mining.h>
+#include <rpc/protocol.h>
+#include <rpc/request.h>
#include <rpc/server.h>
#include <rpc/server_util.h>
#include <rpc/util.h>
#include <script/descriptor.h>
#include <script/script.h>
#include <script/signingprovider.h>
+#include <serialize.h>
+#include <streams.h>
+#include <sync.h>
+#include <tinyformat.h>
#include <txmempool.h>
+#include <uint256.h>
#include <univalue.h>
+#include <util/chaintype.h>
+#include <util/check.h>
#include <util/signalinterrupt.h>
#include <util/strencodings.h>
#include <util/string.h>
#include <util/time.h>
-#include <util/translation.h>
#include <validation.h>
#include <validationinterface.h>
+#include <versionbits.h>
+#include <algorithm>
+#include <cstddef>
#include <cstdint>
+#include <functional>
+#include <initializer_list>
+#include <limits>
+#include <map>
#include <memory>
+#include <optional>
+#include <set>
+#include <span>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
using interfaces::BlockRef;
using interfaces::BlockTemplate;
@@ -473,8 +502,8 @@ static RPCMethod getmininginfo()
obj.pushKV("target", GetTarget(tip, chainman.GetConsensus().powLimit).GetHex());
obj.pushKV("networkhashps", getnetworkhashps().HandleRequest(request));
obj.pushKV("pooledtx", mempool.size());
- const auto options{node::FlattenMiningOptions(*Assert(node::ReadMiningArgs(*node.args)))};
- obj.pushKV("blockmintxfee", ValueFromAmount(CHECK_NONFATAL(options.block_min_fee_rate)->GetFeePerK()));
+ const auto mining_options{node::FlattenMiningOptions(node.mining_args)};
+ obj.pushKV("blockmintxfee", ValueFromAmount(CHECK_NONFATAL(mining_options.block_min_fee_rate)->GetFeePerK()));
obj.pushKV("chain", chainman.GetParams().GetChainTypeString());
UniValue next(UniValue::VOBJ);
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index be2b5e60..4d1c3053 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -181,7 +181,7 @@ void MinerTestingSetup::TestPackageSelection(const CScript& scriptPubKey, const
const auto block_package_feerates = BlockAssembler{
m_node.chainman->ActiveChainstate(),
&tx_mempool,
- BlockCreateOptions{},
+ m_node.mining_args,
}.CreateNewBlock()->m_package_feerates;
BOOST_CHECK(block_package_feerates.size() == 2);
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index 09b6c9c7..25d71f38 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -26,6 +26,7 @@
#include <node/kernel_notifications.h>
#include <node/mempool_args.h>
#include <node/miner.h>
+#include <node/mining_args.h>
#include <node/peerman_args.h>
#include <node/warnings.h>
#include <noui.h>
@@ -65,6 +66,7 @@
#include <future>
#include <functional>
#include <stdexcept>
+#include <utility>
using namespace util::hex_literals;
using node::ApplyArgsManOptions;
@@ -364,6 +366,9 @@ TestingSetup::TestingSetup(
m_node.args->GetIntArg("-checkaddrman", 0));
m_node.banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME);
m_node.connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params()); // Deterministic randomness for tests.
+ auto mining_args{node::ReadMiningArgs(*m_node.args)};
+ Assert(mining_args);
+ m_node.mining_args = std::move(*mining_args);
PeerManager::Options peerman_opts;
ApplyArgsManOptions(*m_node.args, peerman_opts);
peerman_opts.deterministic_rng = true;
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.