mining: store block create options in NodeContext

Read configured mining options once during startup instead of parsing
options like -blockmaxweight each time a block template is generated.

Store the parsed startup options as BlockCreateOptions. Members left unset
keep representing unset options; hardcoded defaults are applied by
FlattenMiningOptions() before the options are used. IPC overrides and node
defaults can then be merged with the same option type used by
BlockAssembler.

Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
This commit is contained in:
Sjors Provoost
2026-05-18 14:17:29 +02:00
parent 4637cd157d
commit 3bb6498fb0
7 changed files with 56 additions and 11 deletions

View File

@@ -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));

View File

@@ -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 = [] {};

View File

@@ -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(),

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;