Skip to content

Commit b466b32

Browse files
committed
mining: move minimum block_reserved_weight check to miner
And also enforce maximum. Currently the exception can only be triggered by IPC (and test) code, because for the RPC path the minimum -blockreservedweight is enforced during node startup. If in the future RPC methods like getblocktemplate allow a custom value per request, they would trigger this exception and the RPC call would return an error - consistent with IPC behavior.
1 parent bfa6e3f commit b466b32

File tree

3 files changed

+26
-12
lines changed

3 files changed

+26
-12
lines changed

src/node/interfaces.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
#include <any>
6868
#include <memory>
6969
#include <optional>
70-
#include <stdexcept>
7170
#include <utility>
7271

7372
#include <boost/signals2/signal.hpp>
@@ -980,16 +979,6 @@ class MinerImpl : public Mining
980979

981980
std::unique_ptr<BlockTemplate> createNewBlock(BlockCreateOptions options) override
982981
{
983-
// Reject too-small values instead of clamping so callers don't silently
984-
// end up mining with different options than requested. This matches the
985-
// behavior of the `-blockreservedweight` startup option, which rejects
986-
// values below MINIMUM_BLOCK_RESERVED_WEIGHT.
987-
if (options.block_reserved_weight && options.block_reserved_weight < MINIMUM_BLOCK_RESERVED_WEIGHT) {
988-
throw std::runtime_error(strprintf("block_reserved_weight (%zu) must be at least %u weight units",
989-
*options.block_reserved_weight,
990-
MINIMUM_BLOCK_RESERVED_WEIGHT));
991-
}
992-
993982
// Ensure m_tip_block is set so consumers of BlockTemplate can rely on that.
994983
if (!waitTipChanged(uint256::ZERO, MillisecondsDouble::max())) return {};
995984
ApplyMiningDefaults(m_node.mining_args, options);

src/node/miner.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <algorithm>
3131
#include <utility>
3232
#include <numeric>
33+
#include <stdexcept>
3334

3435
namespace node {
3536

@@ -81,7 +82,21 @@ static BlockCreateOptions ClampOptions(BlockCreateOptions options)
8182
// Typically block_reserved_weight and block_max_weight are set by
8283
// ApplyMiningDefaults before the constructor calls this; value_or(DEFAULT_...)
8384
// only affects (test) call sites that don't go through the Mining interface.
84-
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);
85+
const size_t reserved_weight{options.block_reserved_weight.value_or(DEFAULT_BLOCK_RESERVED_WEIGHT)};
86+
// Reject too-small values instead of clamping so callers don't silently
87+
// end up mining with different options than requested.
88+
if (reserved_weight < MINIMUM_BLOCK_RESERVED_WEIGHT) {
89+
throw std::runtime_error(strprintf("block_reserved_weight (%zu) must be at least %u weight units",
90+
reserved_weight,
91+
MINIMUM_BLOCK_RESERVED_WEIGHT));
92+
}
93+
// Reject too-large values too.
94+
if (reserved_weight > MAX_BLOCK_WEIGHT) {
95+
throw std::runtime_error(strprintf("block_reserved_weight (%zu) exceeds consensus maximum block weight (%u)",
96+
reserved_weight,
97+
MAX_BLOCK_WEIGHT));
98+
}
99+
options.block_reserved_weight = reserved_weight;
85100
options.coinbase_output_max_additional_sigops = std::clamp<size_t>(options.coinbase_output_max_additional_sigops, 0, MAX_BLOCK_SIGOPS_COST);
86101
// Limit weight to between block_reserved_weight and MAX_BLOCK_WEIGHT for sanity:
87102
// block_reserved_weight can safely exceed -blockmaxweight, but the rest of the block template will be empty.

test/functional/interface_ipc_mining.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,16 @@ async def async_routine():
267267
assert_equal(e.description, "remote exception: std::exception: block_reserved_weight (0) must be at least 2000 weight units")
268268
assert_equal(e.type, "FAILED")
269269

270+
self.log.debug("Enforce maximum reserved weight for IPC clients too")
271+
opts.blockReservedWeight = MAX_BLOCK_WEIGHT + 1
272+
try:
273+
await mining.createNewBlock(opts)
274+
raise AssertionError("createNewBlock unexpectedly succeeded")
275+
except capnp.lib.capnp.KjException as e:
276+
assert_equal(e.description, f"remote exception: std::exception: block_reserved_weight ({MAX_BLOCK_WEIGHT + 1}) exceeds consensus maximum block weight ({MAX_BLOCK_WEIGHT})")
277+
assert_equal(e.type, "FAILED")
278+
279+
270280
asyncio.run(capnp.run(async_routine()))
271281

272282
def run_coinbase_and_submission_test(self):

0 commit comments

Comments
 (0)