Doc: Specify preconf validation to be stricter than derivation #764
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
Currently, Shasta derivation performs validation at the proposal level. During derivation, raw proposal data is transformed into L2 blocks, and both the proposal and resulting blocks undergo validation—a process that may modify or filter them out.
This per-proposal validation creates an issue for preconfirmations, which operate on individual blocks rather than complete proposals. The validation logic used during proposal submission cannot be directly applied at preconfirmation time. This mismatch enables the following scenario:
A malicious or careless preconfer can exploit this to cause reorgs by making step 2 produce blocks that differ from step 1.
Note that we cannot slash for this behavior. Preconfirmations commit to
rawTxList + metadatarather than block hashes, i.e., the inputs needed to derive blocks, not the blocks themselves. From a slashing perspective, the preconfer technically delivered what they promised; the issue is that derivation produced different outputs at different times.Solution
To avoid such reorgs, the property we want is the following: The validation of preconf blocks must be strictly stricter than the validation in the derivation. This gives us the property where “if block is accepted at proposal time, it is accepted at preconf time”.
Implementation
Gas limit: Uses the same logic as derivation. Validates that gas limit is within 0.999990x to 1.000010x of the effective parent gas limit (parent gas - 250K).
Timestamp: Validates timestamp is within bounds: lower_bound = max(parent_timestamp + 1, now() - MAX_TIMESTAMP_DRIFT), upper_bound = min(submissionWindowEnd, now() + MAX_TIMESTAMP_DRIFT). Ensures timestamps are monotonic and don't drift too far from current time or exceed the submission window.
Anchor block number: Validates anchor block number is within acceptable drift from the last seen L1 head, ensuring it's not too far in the past or future. For the first block of a proposal, additionally requires that the anchor block number increments by at least one from the parent.
Sufficient bond: Verifies that the proposer has sufficient bond funds by calling hasSufficientBond(proposer) before accepting the preconfirmation.