miner: clamp options instead of asserting
What changed, and why it matters
This change replaces internal sanity checks (assertions) in Bitcoin Core's block-building code with clamping. Instead of crashing the program if a miner passes an out-of-range value, the code now silently adjusts the value to the nearest allowed limit. This is a robustness improvement that prevents a misconfiguration or unusual input from terminating the node, but it also means invalid settings are no longer loudly rejected.
Review whether callers of ClampOptions rely on the previous assertion failures to detect misconfiguration. Ensure that clamped values still produce valid and expected block templates, and consider logging warnings when clamping occurs so operators are aware of out-of-range settings.
Security signals we found
Removal of Assert() guards on miner configuration bounds
Silent clamping of user-supplied or default miner options
Potential for unintended block template behavior if out-of-range values are supplied
No explicit security framing in commit message or diff
Evidence from the diff
The commit modifies ClampOptions() in src/node/miner.cpp. Previously it used Assert() to enforce that block_reserved_weight was within [MINIMUM_BLOCK_RESERVED_WEIGHT, MAX_BLOCK_WEIGHT] and that coinbase_output_max_additional_sigops was within [0, MAX_BLOCK_SIGOPS_COST]. These assertions are replaced with std::clamp calls that silently bound the values to the allowed ranges. The existing clamp on nBlockMaxWeight remains. This converts a fail-stop behavior into a clamp-and-continue behavior.
Changed components
src/node/miner.cppBlockAssembler::Options clamping logicBlock template generationInspect captured patch +2 / −3
diff --git a/src/node/miner.cpp b/src/node/miner.cpp
index 02a76841..a08c70e2 100644
--- a/src/node/miner.cpp
+++ b/src/node/miner.cpp
@@ -77,9 +77,8 @@ void RegenerateCommitments(CBlock& block, ChainstateManager& chainman)
static BlockAssembler::Options ClampOptions(BlockAssembler::Options options)
{
- Assert(options.block_reserved_weight <= MAX_BLOCK_WEIGHT);
- Assert(options.block_reserved_weight >= MINIMUM_BLOCK_RESERVED_WEIGHT);
- Assert(options.coinbase_output_max_additional_sigops <= MAX_BLOCK_SIGOPS_COST);
+ options.block_reserved_weight = std::clamp<size_t>(options.block_reserved_weight, MINIMUM_BLOCK_RESERVED_WEIGHT, MAX_BLOCK_WEIGHT);
+ options.coinbase_output_max_additional_sigops = std::clamp<size_t>(options.coinbase_output_max_additional_sigops, 0, MAX_BLOCK_SIGOPS_COST);
// Limit weight to between block_reserved_weight and MAX_BLOCK_WEIGHT for sanity:
// block_reserved_weight can safely exceed -blockmaxweight, but the rest of the block template will be empty.
options.nBlockMaxWeight = std::clamp<size_t>(options.nBlockMaxWeight, options.block_reserved_weight, MAX_BLOCK_WEIGHT);
Why this scored 32/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.