Summary
The genesis ProtocolConfig schema accepts blockGasLimit: 0n, but the runtime contract API requires blockGasLimit to be greater than zero.
This creates an invariant mismatch between genesis configuration validation and later protocol config updates.
A chain can be initialized with a blockGasLimit value that would be rejected by the protocol config contract's mutative API.
Affected File
scripts/genesis/ProtocolConfig.ts
Observed Behavior
The genesis schema currently allows:
blockGasLimit: schemaBigInt.min(0n).max(maxUint64)
This means the following value is accepted:
blockGasLimit: 0n
However, the corresponding contract/API-side validation requires blockGasLimit to be greater than zero.
So genesis accepts a value that cannot be set through the normal runtime update path.
Expected Behavior
The genesis ProtocolConfig schema should enforce the same invariant as the runtime protocol config API.
blockGasLimit should be required to be at least 1:
blockGasLimit: schemaBigInt.min(1n).max(maxUint64)
Reproduction
I verified this against the current schema with a focused repro.
The repro calls schemaProtocolConfig.parse(...) with:
blockGasLimit: 0n
Observed result:
blockGasLimit=0 ACCEPTED
Expected result:
blockGasLimit=0 should be rejected
Why This Matters
Genesis configuration should not be able to bypass runtime validation invariants.
If blockGasLimit is zero at genesis, the resulting configuration may be unusable or inconsistent with the contract's own constraints. It also means the same value is treated differently depending on whether it is supplied at genesis or through the runtime update path.
Suggested Fix
Change the genesis schema bound for blockGasLimit from:
blockGasLimit: schemaBigInt.min(0n).max(maxUint64)
to:
blockGasLimit: schemaBigInt.min(1n).max(maxUint64)
Potential Regression Test
Add a ProtocolConfig schema test that verifies:
blockGasLimit: 1n is accepted
blockGasLimit: 0n is rejected
blockGasLimit above maxUint64 is rejected
Summary
The genesis
ProtocolConfigschema acceptsblockGasLimit: 0n, but the runtime contract API requiresblockGasLimitto be greater than zero.This creates an invariant mismatch between genesis configuration validation and later protocol config updates.
A chain can be initialized with a
blockGasLimitvalue that would be rejected by the protocol config contract's mutative API.Affected File
scripts/genesis/ProtocolConfig.tsObserved Behavior
The genesis schema currently allows:
blockGasLimit: schemaBigInt.min(0n).max(maxUint64)
This means the following value is accepted:
blockGasLimit: 0n
However, the corresponding contract/API-side validation requires
blockGasLimitto be greater than zero.So genesis accepts a value that cannot be set through the normal runtime update path.
Expected Behavior
The genesis
ProtocolConfigschema should enforce the same invariant as the runtime protocol config API.blockGasLimitshould be required to be at least 1:blockGasLimit: schemaBigInt.min(1n).max(maxUint64)
Reproduction
I verified this against the current schema with a focused repro.
The repro calls
schemaProtocolConfig.parse(...)with:blockGasLimit: 0n
Observed result:
blockGasLimit=0 ACCEPTED
Expected result:
blockGasLimit=0 should be rejected
Why This Matters
Genesis configuration should not be able to bypass runtime validation invariants.
If
blockGasLimitis zero at genesis, the resulting configuration may be unusable or inconsistent with the contract's own constraints. It also means the same value is treated differently depending on whether it is supplied at genesis or through the runtime update path.Suggested Fix
Change the genesis schema bound for
blockGasLimitfrom:blockGasLimit: schemaBigInt.min(0n).max(maxUint64)
to:
blockGasLimit: schemaBigInt.min(1n).max(maxUint64)
Potential Regression Test
Add a
ProtocolConfigschema test that verifies:blockGasLimit: 1nis acceptedblockGasLimit: 0nis rejectedblockGasLimitabovemaxUint64is rejected