fix(ssz): correct JustificationValidators LIMIT formula in rule doc#728
Merged
tcoratger merged 1 commit intoMay 18, 2026
Merged
Conversation
The SSZ-patterns rule doc showed `LIMIT = HISTORICAL_ROOTS_LIMIT * HISTORICAL_ROOTS_LIMIT` for the JustificationValidators example, but the type stores one bit per (tracked root, registered validator) pair. The second factor must be the validator registry limit. The numerical impact is large: the doc value is 64x the correct value. Because BaseBitlist.LIMIT controls the merkleization depth, a second-client implementer following the rule doc would compute a different hash_tree_root for the same state field and fork off silently the first time they tried to talk to a node built from this code. Changes: - ssz-patterns.md: fix the formula in the example, add an inline rationale, and define VALIDATOR_REGISTRY_LIMIT alongside HISTORICAL_ROOTS_LIMIT so the math is self-contained. - ssz-patterns.md: update the frontmatter path glob and the architecture diagram to reflect that containers moved to forks/<fork>/containers/ in the recent refactor. - state/types.py: expand the one-line docstring on JustificationValidators to document the layout and the consensus-critical nature of the LIMIT product. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
The SSZ-patterns rule doc showed
LIMIT = HISTORICAL_ROOTS_LIMIT * HISTORICAL_ROOTS_LIMITfor theJustificationValidatorsexample, butthe type stores one bit per (tracked root, registered validator)
pair. The second factor must be the validator registry limit. The
code (
state/types.py:167) already uses the correct product — onlythe rule doc was wrong.
Why it matters
BaseBitlist.LIMITdirectly controls merkleization depth:2^18 * 2^122^302^222^18 * 2^182^362^28A second-client implementer treating
.claude/rules/ssz-patterns.mdas canonical would compute a different
hash_tree_rootfor the samestate field. Different state roots → different block roots → silent
consensus divergence on the first network exchange. Exactly the kind
of doc/code drift this rule file is meant to prevent.
Changes
.claude/rules/ssz-patterns.md— fix the formula in the exampleand add an inline rationale block explaining why the product matters
(consensus-critical merkle depth). Also define
VALIDATOR_REGISTRY_LIMITalongside
HISTORICAL_ROOTS_LIMITso the math is self-contained..claude/rules/ssz-patterns.md— update the frontmatter pathglob and the architecture diagram to reflect that containers moved
to
forks/<fork>/containers/in the recent refactor.state/types.py— expand the one-line docstring onJustificationValidatorsto document the layout and theconsensus-critical nature of the
LIMITproduct. One sentence perline per the documentation rules.
Test plan
ruff check,ruff format --check,ty checkpasstests/lean_spec/forks/lstar/stateandtests/lean_spec/forks/lstar/forkchoicepassthe doc was wrong
🤖 Generated with Claude Code