fix(genesis): bound consensus params to uint16 - #326
Conversation
|
Reviewed at Verified
Nice catch that the description undersells: the field name#320 listed Why only this slot was vulnerableThis is the part I found most interesting, and it confirms the fix is at the right layer. // Slot 0: alpha | kRate | inverseElasticityMultiplier | padding
concat([toHex(0n, { size: 8 }), toHex(feeParams.inverseElasticityMultiplier, { size: 8 }), ...])viem's So slot 0 would have blown up loudly even without schema bounds. Slot 5 uses shift-OR into a single The corruption is subtler than #320 showsThe issue's repro reports lane 1 decoding as It's a bitwise OR, so the neighbour becomes The top lane fails differently, and worse — worth adding to the PR description
The lane reads back as 0 — and 0 is not a neutral value here. So an out-of-range
|
Summary
Fixes #320
This updates the genesis
ProtocolConfigschema soconsensusParamsvalues are validated against the uint16 range before they are packed into the genesis storage slot.The consensus params are packed as 8 x uint16 values in the
ProtocolConfigstorage slot. Previously, the schema accepted arbitrary bigint values for these fields, so values greater than 65535 could be accepted and then overflow into neighboring packed lanes.Changes
consensusParamsfields:timeoutProposeMstimeoutProposeDeltaMstimeoutPrevoteMstimeoutPrevoteDeltaMstimeoutPrecommitMstimeoutPrecommitDeltaMstimeoutRebroadcastMstargetBlockTimeMs6553565536for each packedconsensusParamsfieldWhy
A genesis config should not accept values that cannot be represented correctly in the packed on-chain layout.
Before this fix, a value like
65536ncould pass schema validation and then encode as0in the intended uint16 lane while spilling into the next lane. This could silently produce a different consensus configuration than the one supplied in genesis.Tests
Regression test before the fix:
Result before fix:
1 passing
1 failing
Failure:
AssertionError: timeoutProposeMs should reject 65536: expected [Function] to throw an error
After the fix:
Result:
2 passing
Formatting:
Result:
All matched files use Prettier code style!
Lint:
Result:
passed
Additional check attempted:
Result:
failed on pre-existing repository-wide TypeScript errors unrelated to this PR. No errors from the new test file were reported in that output.
Checklist
Risk & Impact
Low. The bound only rejects values that were already invalid for the packed uint16 layout — any genesis config using valid values (0–65535) is unaffected. Verified the regression test fails against the old schema and passes with the fix, confirming it exercises the actual overflow path.
Type: 🐛 Bug fix
Fixes: #320