Skip to content

Commit 3eaa0a3

Browse files
committed
miner: init: add -blockreservedweight startup option
- Prevent setting the value of `-blockreservedweight` below a safety value of 2000.
1 parent 777434a commit 3eaa0a3

File tree

5 files changed

+43
-0
lines changed

5 files changed

+43
-0
lines changed

src/init.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,7 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
649649

650650

651651
argsman.AddArg("-blockmaxweight=<n>", strprintf("Set maximum BIP141 block weight (default: %d)", DEFAULT_BLOCK_MAX_WEIGHT), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
652+
argsman.AddArg("-blockreservedweight=<n>", strprintf("Reserve space for the fixed-size block header plus the largest coinbase transaction the mining software may add to the block. (default: %d).", DEFAULT_BLOCK_RESERVED_WEIGHT), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
652653
argsman.AddArg("-blockmintxfee=<amt>", strprintf("Set lowest fee rate (in %s/kvB) for transactions to be included in block creation. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_BLOCK_MIN_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
653654
argsman.AddArg("-blockversion=<n>", "Override block version to test forking scenarios", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::BLOCK_CREATION);
654655

@@ -1023,6 +1024,16 @@ bool AppInitParameterInteraction(const ArgsManager& args)
10231024
}
10241025
}
10251026

1027+
if (args.IsArgSet("-blockreservedweight")) {
1028+
const auto block_reserved_weight = args.GetIntArg("-blockreservedweight", DEFAULT_BLOCK_RESERVED_WEIGHT);
1029+
if (block_reserved_weight > MAX_BLOCK_WEIGHT) {
1030+
return InitError(strprintf(_("Specified -blockreservedweight (%d) exceeds consensus maximum block weight (%d)"), block_reserved_weight, MAX_BLOCK_WEIGHT));
1031+
}
1032+
if (block_reserved_weight < MINIMUM_BLOCK_RESERVED_WEIGHT) {
1033+
return InitError(strprintf(_("Specified -blockreservedweight (%d) is lower than minimum safety value of (%d)"), block_reserved_weight, MINIMUM_BLOCK_RESERVED_WEIGHT));
1034+
}
1035+
}
1036+
10261037
nBytesPerSigOp = args.GetIntArg("-bytespersigop", nBytesPerSigOp);
10271038

10281039
if (!g_wallet_init_interface.ParameterInteraction()) return false;

src/node/miner.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ void RegenerateCommitments(CBlock& block, ChainstateManager& chainman)
6868
static BlockAssembler::Options ClampOptions(BlockAssembler::Options options)
6969
{
7070
Assert(options.block_reserved_weight <= MAX_BLOCK_WEIGHT);
71+
Assert(options.block_reserved_weight >= MINIMUM_BLOCK_RESERVED_WEIGHT);
7172
Assert(options.coinbase_output_max_additional_sigops <= MAX_BLOCK_SIGOPS_COST);
7273
// Limit weight to between block_reserved_weight and MAX_BLOCK_WEIGHT for sanity:
7374
// block_reserved_weight can safely exceed -blockmaxweight, but the rest of the block template will be empty.
@@ -91,6 +92,7 @@ void ApplyArgsManOptions(const ArgsManager& args, BlockAssembler::Options& optio
9192
if (const auto parsed{ParseMoney(*blockmintxfee)}) options.blockMinFeeRate = CFeeRate{*parsed};
9293
}
9394
options.print_modified_fee = args.GetBoolArg("-printpriority", options.print_modified_fee);
95+
options.block_reserved_weight = args.GetIntArg("-blockreservedweight", options.block_reserved_weight);
9496
}
9597

9698
void BlockAssembler::resetBlock()

src/policy/policy.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@ class CScript;
2121

2222
/** Default for -blockmaxweight, which controls the range of block weights the mining code will create **/
2323
static constexpr unsigned int DEFAULT_BLOCK_MAX_WEIGHT{MAX_BLOCK_WEIGHT};
24+
/** Default for -blockreservedweight **/
2425
static constexpr unsigned int DEFAULT_BLOCK_RESERVED_WEIGHT{8000};
26+
/** This accounts for the block header, var_int encoding of the transaction count and a minimally viable
27+
* coinbase transaction. It adds an additional safety margin, because even with a thorough understanding
28+
* of block serialization, it's easy to make a costly mistake when trying to squeeze every last byte.
29+
* Setting a lower value is prevented at startup. */
30+
static constexpr unsigned int MINIMUM_BLOCK_RESERVED_WEIGHT{2000};
2531
/** Default for -blockmintxfee, which sets the minimum feerate for a transaction in blocks created by mining code **/
2632
static constexpr unsigned int DEFAULT_BLOCK_MIN_TX_FEE{1000};
2733
/** The maximum weight for transactions we're willing to relay/mine */

test/functional/mining_basic.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
COIN,
2929
DEFAULT_BLOCK_RESERVED_WEIGHT,
3030
MAX_BLOCK_WEIGHT,
31+
MINIMUM_BLOCK_RESERVED_WEIGHT,
3132
ser_uint256,
3233
WITNESS_SCALE_FACTOR
3334
)
@@ -276,6 +277,28 @@ def test_block_max_weight(self):
276277
expected_weight=MAX_BLOCK_WEIGHT - DEFAULT_BLOCK_RESERVED_WEIGHT,
277278
)
278279

280+
self.log.info("Test -blockreservedweight startup option.")
281+
# Lowering the -blockreservedweight by 4000 will allow for two more transactions.
282+
self.restart_node(0, extra_args=[f"-datacarriersize={LARGE_VSIZE}", "-blockreservedweight=4000"])
283+
self.verify_block_template(
284+
expected_tx_count=12,
285+
expected_weight=MAX_BLOCK_WEIGHT - 4000,
286+
)
287+
288+
self.log.info("Test that node will fail to start when user provide invalid -blockreservedweight")
289+
self.stop_node(0)
290+
self.nodes[0].assert_start_raises_init_error(
291+
extra_args=[f"-blockreservedweight={MAX_BLOCK_WEIGHT + 1}"],
292+
expected_msg=f"Error: Specified -blockreservedweight ({MAX_BLOCK_WEIGHT + 1}) exceeds consensus maximum block weight ({MAX_BLOCK_WEIGHT})",
293+
)
294+
295+
self.log.info(f"Test that node will fail to start when user provide -blockreservedweight below {MINIMUM_BLOCK_RESERVED_WEIGHT}")
296+
self.stop_node(0)
297+
self.nodes[0].assert_start_raises_init_error(
298+
extra_args=[f"-blockreservedweight={MINIMUM_BLOCK_RESERVED_WEIGHT - 1}"],
299+
expected_msg=f"Error: Specified -blockreservedweight ({MINIMUM_BLOCK_RESERVED_WEIGHT - 1}) is lower than minimum safety value of ({MINIMUM_BLOCK_RESERVED_WEIGHT})",
300+
)
301+
279302
self.log.info("Test that node will fail to start when user provide invalid -blockmaxweight")
280303
self.stop_node(0)
281304
self.nodes[0].assert_start_raises_init_error(

test/functional/test_framework/messages.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
MAX_LOCATOR_SZ = 101
3535
MAX_BLOCK_WEIGHT = 4000000
3636
DEFAULT_BLOCK_RESERVED_WEIGHT = 8000
37+
MINIMUM_BLOCK_RESERVED_WEIGHT = 2000
3738
MAX_BLOOM_FILTER_SIZE = 36000
3839
MAX_BLOOM_HASH_FUNCS = 50
3940

0 commit comments

Comments
 (0)