Skip to content

Commit 19604a8

Browse files
committed
mining: store mining args in NodeContext
Instead of parsing arguments like -blockmaxweight each time a block template is generated, do it once in ReadMiningArgs(). These arguments are stored in a new struct MiningArgs. The BlockAssembler::Options struct is removed in favor of passing both MiningArgs and BlockCreateOptions. This disentangles node configuration from client (or test) options.
1 parent 64ae0e3 commit 19604a8

File tree

13 files changed

+122
-57
lines changed

13 files changed

+122
-57
lines changed

src/init.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,8 @@ bool AppInitParameterInteraction(const ArgsManager& args)
10551055
return InitError(Untranslated("peertimeout must be a positive integer."));
10561056
}
10571057

1058-
auto mining_result{node::ReadMiningArgs(args)};
1058+
node::MiningArgs mining_args_dummy;
1059+
auto mining_result{node::ReadMiningArgs(args, mining_args_dummy)};
10591060
if (!mining_result) {
10601061
return InitError(util::ErrorString(mining_result));
10611062
}
@@ -1293,6 +1294,7 @@ static ChainstateLoadResult InitAndLoadChainstate(
12931294
if (!mempool_error.empty()) {
12941295
return {ChainstateLoadStatus::FAILURE_FATAL, mempool_error};
12951296
}
1297+
Assert(ReadMiningArgs(args, node.mining_args)); // no error can happen, already checked in AppInitParameterInteraction
12961298
LogInfo("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)",
12971299
cache_sizes.coins * (1.0 / 1024 / 1024),
12981300
mempool_opts.max_size_bytes * (1.0 / 1024 / 1024));

src/interfaces/mining.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ class Mining
152152
* @retval BlockTemplate a block template.
153153
* @retval std::nullptr if the node is shut down.
154154
*/
155-
virtual std::unique_ptr<BlockTemplate> createNewBlock(const node::BlockCreateOptions& options = {}) = 0;
155+
virtual std::unique_ptr<BlockTemplate> createNewBlock(node::BlockCreateOptions options = {}) = 0;
156156

157157
/**
158158
* Checks if a given block is valid.

src/node/context.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#ifndef BITCOIN_NODE_CONTEXT_H
66
#define BITCOIN_NODE_CONTEXT_H
77

8+
#include <node/mining_args.h>
9+
810
#include <atomic>
911
#include <cstdlib>
1012
#include <functional>
@@ -79,6 +81,7 @@ struct NodeContext {
7981
//! Reference to chain client that should used to load or create wallets
8082
//! opened by the gui.
8183
std::unique_ptr<interfaces::Mining> mining;
84+
MiningArgs mining_args;
8285
interfaces::WalletLoader* wallet_loader{nullptr};
8386
std::unique_ptr<CScheduler> scheduler;
8487
std::function<void()> rpc_interruption_point = [] {};

src/node/interfaces.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ using interfaces::Node;
8484
using interfaces::WalletLoader;
8585
using kernel::ChainstateRole;
8686
using node::BlockAssembler;
87+
using node::BlockCreateOptions;
88+
using node::MiningArgs;
8789
using node::BlockWaitOptions;
8890
using node::CoinbaseTx;
8991
using util::Join;
@@ -861,9 +863,9 @@ class ChainImpl : public Chain
861863
class BlockTemplateImpl : public BlockTemplate
862864
{
863865
public:
864-
explicit BlockTemplateImpl(BlockAssembler::Options assemble_options,
866+
explicit BlockTemplateImpl(BlockCreateOptions create_options,
865867
std::unique_ptr<CBlockTemplate> block_template,
866-
NodeContext& node) : m_assemble_options(std::move(assemble_options)),
868+
NodeContext& node) : m_create_options(std::move(create_options)),
867869
m_block_template(std::move(block_template)),
868870
m_node(node)
869871
{
@@ -923,8 +925,15 @@ class BlockTemplateImpl : public BlockTemplate
923925

924926
std::unique_ptr<BlockTemplate> waitNext(BlockWaitOptions options) override
925927
{
926-
auto new_template = WaitAndCreateNewBlock(chainman(), notifications(), m_node.mempool.get(), m_block_template, options, m_assemble_options, m_interrupt_wait);
927-
if (new_template) return std::make_unique<BlockTemplateImpl>(m_assemble_options, std::move(new_template), m_node);
928+
auto new_template = WaitAndCreateNewBlock(chainman(),
929+
notifications(),
930+
m_node.mempool.get(),
931+
m_block_template,
932+
options,
933+
m_mining_args,
934+
m_create_options,
935+
m_interrupt_wait);
936+
if (new_template) return std::make_unique<BlockTemplateImpl>(m_create_options, std::move(new_template), m_node);
928937
return nullptr;
929938
}
930939

@@ -933,7 +942,8 @@ class BlockTemplateImpl : public BlockTemplate
933942
InterruptWait(notifications(), m_interrupt_wait);
934943
}
935944

936-
const BlockAssembler::Options m_assemble_options;
945+
const MiningArgs m_mining_args;
946+
const BlockCreateOptions m_create_options;
937947

938948
const std::unique_ptr<CBlockTemplate> m_block_template;
939949

@@ -968,7 +978,7 @@ class MinerImpl : public Mining
968978
return WaitTipChanged(chainman(), notifications(), current_tip, timeout);
969979
}
970980

971-
std::unique_ptr<BlockTemplate> createNewBlock(const BlockCreateOptions& options) override
981+
std::unique_ptr<BlockTemplate> createNewBlock(BlockCreateOptions options) override
972982
{
973983
// Reject too-small values instead of clamping so callers don't silently
974984
// end up mining with different options than requested. This matches the
@@ -982,10 +992,15 @@ class MinerImpl : public Mining
982992

983993
// Ensure m_tip_block is set so consumers of BlockTemplate can rely on that.
984994
if (!waitTipChanged(uint256::ZERO, MillisecondsDouble::max())) return {};
985-
986-
BlockAssembler::Options assemble_options{options};
987-
ApplyArgsManOptions(*Assert(m_node.args), assemble_options);
988-
return std::make_unique<BlockTemplateImpl>(assemble_options, BlockAssembler{chainman().ActiveChainstate(), context()->mempool.get(), assemble_options}.CreateNewBlock(), m_node);
995+
ApplyMiningDefaults(m_node.mining_args, options);
996+
return std::make_unique<BlockTemplateImpl>(options,
997+
BlockAssembler{
998+
chainman().ActiveChainstate(),
999+
context()->mempool.get(),
1000+
context()->mining_args,
1001+
options,
1002+
}.CreateNewBlock(),
1003+
m_node);
9891004
}
9901005

9911006
bool checkBlock(const CBlock& block, const node::BlockCheckOptions& options, std::string& reason, std::string& debug) override

src/node/miner.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,11 @@ void RegenerateCommitments(CBlock& block, ChainstateManager& chainman)
7676
block.hashMerkleRoot = BlockMerkleRoot(block);
7777
}
7878

79-
static BlockAssembler::Options ClampOptions(BlockAssembler::Options options)
79+
static BlockCreateOptions ClampOptions(BlockCreateOptions options)
8080
{
81-
// Apply DEFAULT_BLOCK_RESERVED_WEIGHT and DEFAULT_BLOCK_MAX_WEIGHT when the caller left it unset.
81+
// Typically block_reserved_weight and block_max_weight are set by
82+
// ApplyMiningDefaults before the constructor calls this; value_or(DEFAULT_...)
83+
// only affects (test) call sites that don't go through the Mining interface.
8284
options.block_reserved_weight = std::clamp<size_t>(options.block_reserved_weight.value_or(DEFAULT_BLOCK_RESERVED_WEIGHT), MINIMUM_BLOCK_RESERVED_WEIGHT, MAX_BLOCK_WEIGHT);
8385
options.coinbase_output_max_additional_sigops = std::clamp<size_t>(options.coinbase_output_max_additional_sigops, 0, MAX_BLOCK_SIGOPS_COST);
8486
// Limit weight to between block_reserved_weight and MAX_BLOCK_WEIGHT for sanity:
@@ -87,26 +89,26 @@ static BlockAssembler::Options ClampOptions(BlockAssembler::Options options)
8789
return options;
8890
}
8991

90-
BlockAssembler::BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool, const Options& options)
92+
BlockAssembler::BlockAssembler(Chainstate& chainstate,
93+
const CTxMemPool* mempool,
94+
MiningArgs mining_args,
95+
BlockCreateOptions options)
9196
: chainparams{chainstate.m_chainman.GetParams()},
9297
m_mempool{options.use_mempool ? mempool : nullptr},
9398
m_chainstate{chainstate},
99+
m_mining_args{mining_args},
94100
m_options{ClampOptions(options)}
95101
{
96102
}
97103

98-
void ApplyArgsManOptions(const ArgsManager& args, BlockAssembler::Options& options)
104+
void ApplyMiningDefaults(const MiningArgs& args, BlockCreateOptions& options)
99105
{
100106
// Block resource limits
101107
if (!options.block_max_weight) {
102-
options.block_max_weight = args.GetIntArg("-blockmaxweight");
108+
options.block_max_weight = args.default_block_max_weight;
103109
}
104-
if (const auto blockmintxfee{args.GetArg("-blockmintxfee")}) {
105-
if (const auto parsed{ParseMoney(*blockmintxfee)}) options.blockMinFeeRate = CFeeRate{*parsed};
106-
}
107-
options.print_modified_fee = args.GetBoolArg("-printpriority", options.print_modified_fee);
108110
if (!options.block_reserved_weight) {
109-
options.block_reserved_weight = args.GetIntArg("-blockreservedweight");
111+
options.block_reserved_weight = args.default_block_reserved_weight;
110112
}
111113
}
112114

@@ -271,7 +273,7 @@ void BlockAssembler::AddToBlock(const CTxMemPoolEntry& entry)
271273
nBlockSigOpsCost += entry.GetSigOpCost();
272274
nFees += entry.GetFee();
273275

274-
if (m_options.print_modified_fee) {
276+
if (m_mining_args.print_modified_fee) {
275277
LogInfo("fee rate %s txid %s\n",
276278
CFeeRate(entry.GetModifiedFee(), entry.GetTxSize()).ToString(),
277279
entry.GetTx().GetHash().ToString());
@@ -297,7 +299,7 @@ void BlockAssembler::addChunks()
297299

298300
while (selected_transactions.size() > 0) {
299301
// Check to see if min fee rate is still respected.
300-
if (chunk_feerate_vsize << m_options.blockMinFeeRate.GetFeePerVSize()) {
302+
if (chunk_feerate_vsize << m_mining_args.blockMinFeeRate.GetFeePerVSize()) {
301303
// Everything else we might consider has a lower feerate
302304
return;
303305
}
@@ -365,7 +367,8 @@ std::unique_ptr<CBlockTemplate> WaitAndCreateNewBlock(ChainstateManager& chainma
365367
CTxMemPool* mempool,
366368
const std::unique_ptr<CBlockTemplate>& block_template,
367369
const BlockWaitOptions& options,
368-
const BlockAssembler::Options& assemble_options,
370+
const MiningArgs& mining_args,
371+
const BlockCreateOptions& assemble_options,
369372
bool& interrupt_wait)
370373
{
371374
// Delay calculating the current template fees, just in case a new block
@@ -426,8 +429,9 @@ std::unique_ptr<CBlockTemplate> WaitAndCreateNewBlock(ChainstateManager& chainma
426429
auto new_tmpl{BlockAssembler{
427430
chainman.ActiveChainstate(),
428431
mempool,
429-
assemble_options}
430-
.CreateNewBlock()};
432+
mining_args,
433+
assemble_options
434+
}.CreateNewBlock()};
431435

432436
// If the tip changed, return the new template regardless of its fees.
433437
if (tip_changed) return new_tmpl;

src/node/miner.h

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <interfaces/types.h>
1010
#include <node/types.h>
1111
#include <node/mining_types.h>
12+
#include <node/mining_args.h>
1213
#include <primitives/block.h>
1314
#include <txmempool.h>
1415
#include <util/feefrac.h>
@@ -23,7 +24,6 @@
2324
#include <boost/multi_index/tag.hpp>
2425
#include <boost/multi_index_container.hpp>
2526

26-
class ArgsManager;
2727
class CBlockIndex;
2828
class CChainParams;
2929
class CScript;
@@ -35,10 +35,9 @@ namespace Consensus { struct Params; };
3535
using interfaces::BlockRef;
3636

3737
namespace node {
38+
struct NodeContext;
3839
class KernelNotifications;
3940

40-
static const bool DEFAULT_PRINT_MODIFIED_FEE = false;
41-
4241
struct CBlockTemplate
4342
{
4443
CBlock block;
@@ -79,12 +78,10 @@ class BlockAssembler
7978
Chainstate& m_chainstate;
8079

8180
public:
82-
struct Options : BlockCreateOptions {
83-
CFeeRate blockMinFeeRate{DEFAULT_BLOCK_MIN_TX_FEE};
84-
bool print_modified_fee{DEFAULT_PRINT_MODIFIED_FEE};
85-
};
86-
87-
explicit BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool, const Options& options);
81+
explicit BlockAssembler(Chainstate& chainstate,
82+
const CTxMemPool* mempool,
83+
MiningArgs mining_args,
84+
BlockCreateOptions create_options);
8885

8986
/** Construct a new block template */
9087
std::unique_ptr<CBlockTemplate> CreateNewBlock();
@@ -95,7 +92,8 @@ class BlockAssembler
9592
inline static std::optional<int64_t> m_last_block_weight{};
9693

9794
private:
98-
const Options m_options;
95+
const MiningArgs m_mining_args;
96+
const BlockCreateOptions m_options;
9997

10098
// utility functions
10199
/** Clear the block's state and prepare for assembling a new block */
@@ -131,8 +129,8 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam
131129
/** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */
132130
void RegenerateCommitments(CBlock& block, ChainstateManager& chainman);
133131

134-
/** Apply -blockmintxfee and -blockmaxweight options from ArgsManager to BlockAssembler options. */
135-
void ApplyArgsManOptions(const ArgsManager& gArgs, BlockAssembler::Options& options);
132+
/** Apply -blockmaxweight and -blockreservedweight arguments from MiningArgs to BlockCreateOptions options. */
133+
void ApplyMiningDefaults(const MiningArgs& args, BlockCreateOptions& options);
136134

137135
/* Compute the block's merkle root, insert or replace the coinbase transaction and the merkle root into the block */
138136
void AddMerkleRootAndCoinbase(CBlock& block, CTransactionRef coinbase, uint32_t version, uint32_t timestamp, uint32_t nonce);
@@ -149,7 +147,8 @@ std::unique_ptr<CBlockTemplate> WaitAndCreateNewBlock(ChainstateManager& chainma
149147
CTxMemPool* mempool,
150148
const std::unique_ptr<CBlockTemplate>& block_template,
151149
const BlockWaitOptions& options,
152-
const BlockAssembler::Options& assemble_options,
150+
const MiningArgs& mining_args,
151+
const BlockCreateOptions& assemble_options,
153152
bool& interrupt_wait);
154153

155154
/* Locks cs_main and returns the block hash and block height of the active chain if it exists; otherwise, returns nullopt.*/

src/node/mining_args.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,30 @@ using common::AmountErrMsg;
1616

1717
namespace node {
1818

19-
util::Result<void> ReadMiningArgs(const ArgsManager& args)
19+
util::Result<void> ReadMiningArgs(const ArgsManager& args, MiningArgs& mining_args)
2020
{
2121
if (const auto arg{args.GetArg("-blockmintxfee")}) {
22-
if (!ParseMoney(*arg)) {
23-
return util::Error{AmountErrMsg("blockmintxfee", *arg)};
24-
}
22+
std::optional<CAmount> block_min_tx_fee{ParseMoney(*arg)};
23+
if (!block_min_tx_fee) return util::Error{AmountErrMsg("blockmintxfee", *arg)};
24+
mining_args.blockMinFeeRate = CFeeRate{*block_min_tx_fee};
2525
}
2626

27-
const auto max_block_weight = args.GetIntArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT);
27+
const size_t max_block_weight = args.GetIntArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT);
2828
if (max_block_weight > MAX_BLOCK_WEIGHT) {
2929
return util::Error{strprintf(_("Specified -blockmaxweight (%d) exceeds consensus maximum block weight (%d)"), max_block_weight, MAX_BLOCK_WEIGHT)};
3030
}
31+
mining_args.default_block_max_weight = max_block_weight;
3132

32-
const auto block_reserved_weight = args.GetIntArg("-blockreservedweight", DEFAULT_BLOCK_RESERVED_WEIGHT);
33+
const size_t block_reserved_weight = args.GetIntArg("-blockreservedweight", DEFAULT_BLOCK_RESERVED_WEIGHT);
3334
if (block_reserved_weight > MAX_BLOCK_WEIGHT) {
3435
return util::Error{strprintf(_("Specified -blockreservedweight (%d) exceeds consensus maximum block weight (%d)"), block_reserved_weight, MAX_BLOCK_WEIGHT)};
3536
}
3637
if (block_reserved_weight < MINIMUM_BLOCK_RESERVED_WEIGHT) {
3738
return util::Error{strprintf(_("Specified -blockreservedweight (%d) is lower than minimum safety value of (%d)"), block_reserved_weight, MINIMUM_BLOCK_RESERVED_WEIGHT)};
3839
}
40+
mining_args.default_block_reserved_weight = block_reserved_weight;
41+
42+
mining_args.print_modified_fee = args.GetBoolArg("-printpriority", mining_args.print_modified_fee);
3943

4044
return {};
4145
}

src/node/mining_args.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,41 @@
55
#ifndef BITCOIN_NODE_MINING_ARGS_H
66
#define BITCOIN_NODE_MINING_ARGS_H
77

8+
#include <policy/feerate.h>
9+
#include <policy/policy.h>
810
#include <util/result.h>
911

1012
class ArgsManager;
1113

1214
namespace node {
1315

14-
[[nodiscard]] util::Result<void> ReadMiningArgs(const ArgsManager& args);
16+
static const bool DEFAULT_PRINT_MODIFIED_FEE = false;
17+
18+
/**
19+
* Block template creation defaults and limits configured for the node.
20+
*/
21+
struct MiningArgs {
22+
CFeeRate blockMinFeeRate{DEFAULT_BLOCK_MIN_TX_FEE};
23+
bool print_modified_fee{DEFAULT_PRINT_MODIFIED_FEE};
24+
/**
25+
* The default maximum block weight.
26+
*/
27+
size_t default_block_max_weight{DEFAULT_BLOCK_MAX_WEIGHT};
28+
/**
29+
* The default reserved weight for the fixed-size block header,
30+
* transaction count and coinbase transaction.
31+
*/
32+
size_t default_block_reserved_weight{DEFAULT_BLOCK_RESERVED_WEIGHT};
33+
};
34+
35+
/**
36+
* Overlay the options set in \p args on top of corresponding members in
37+
* \p mining_args. Returns an error if one was encountered.
38+
*
39+
* @param[in] args The ArgsManager in which to check set options.
40+
* @param[in,out] mining_args The MiningArgs to modify according to \p args.
41+
*/
42+
[[nodiscard]] util::Result<void> ReadMiningArgs(const ArgsManager& args, MiningArgs& mining_args);
1543

1644
} // namespace node
1745

src/node/mining_types.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525

2626
namespace node {
2727

28+
/**
29+
* Block template creation options. These override node defaults, but can't
30+
* exceed node limits (e.g. block_reserved_weight can't exceed max block weight).
31+
*/
2832
struct BlockCreateOptions {
2933
/**
3034
* Set false to omit mempool transactions

src/rpc/mining.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -462,17 +462,15 @@ static RPCHelpMan getmininginfo()
462462
CBlockIndex& tip{*CHECK_NONFATAL(active_chain.Tip())};
463463

464464
UniValue obj(UniValue::VOBJ);
465-
obj.pushKV("blocks", active_chain.Height());
465+
obj.pushKV("blocks", active_chain.Height());
466466
if (BlockAssembler::m_last_block_weight) obj.pushKV("currentblockweight", *BlockAssembler::m_last_block_weight);
467467
if (BlockAssembler::m_last_block_num_txs) obj.pushKV("currentblocktx", *BlockAssembler::m_last_block_num_txs);
468468
obj.pushKV("bits", strprintf("%08x", tip.nBits));
469469
obj.pushKV("difficulty", GetDifficulty(tip));
470470
obj.pushKV("target", GetTarget(tip, chainman.GetConsensus().powLimit).GetHex());
471471
obj.pushKV("networkhashps", getnetworkhashps().HandleRequest(request));
472472
obj.pushKV("pooledtx", mempool.size());
473-
BlockAssembler::Options assembler_options;
474-
ApplyArgsManOptions(*node.args, assembler_options);
475-
obj.pushKV("blockmintxfee", ValueFromAmount(assembler_options.blockMinFeeRate.GetFeePerK()));
473+
obj.pushKV("blockmintxfee", ValueFromAmount(node.mining_args.blockMinFeeRate.GetFeePerK()));
476474
obj.pushKV("chain", chainman.GetParams().GetChainTypeString());
477475

478476
UniValue next(UniValue::VOBJ);

0 commit comments

Comments
 (0)