Skip to content

Eip 7916 progressive list - #68

Open
omerfirmak wants to merge 2 commits into
blockblaz:masterfrom
omerfirmak:eip-7916-progressive-list
Open

Eip 7916 progressive list#68
omerfirmak wants to merge 2 commits into
blockblaz:masterfrom
omerfirmak:eip-7916-progressive-list

Conversation

@omerfirmak

Copy link
Copy Markdown
Contributor

No description provided.

omerfirmak and others added 2 commits August 19, 2026 15:42
Add merkleizeProgressive() to lib.zig: a 0-terminated sequence of binary
subtrees with leaf counts 1, 4, 16, 64, ..., reusing merkleize() for each
fixed subtree.

Refactor List/Bitlist into ListImpl/BitlistImpl taking a `limit: ?usize`,
where null means progressive. List(T, N) and Bitlist(N) become thin
wrappers, so their behaviour is unchanged. New public types:
ProgressiveList(T), ProgressiveByteList and ProgressiveBitlist.

Serialization is byte-identical to the bounded variants. Differences are
confined to the capacity checks, which become no-ops, and merkleization:

 - maxInLength() returns error.NoMaxInLengthAvailable, since there is no
   static bound to check a payload against. This also changes
   Bitlist(N).maxInLength() from usize to !usize.
 - chunkCountLimit() is a @CompileError, as a progressive tree has no
   fixed depth and so cannot be wrapped in TreeHasher.
 - ProgressiveBitlist does not trim trailing zero bytes before hashing.
   Bitlist(N) can, because zero chunks are padding in a fixed-depth tree,
   but dropping a chunk shifts the progressive subtree layout.

Expected roots in the tests were generated by an independent Python
transcription of the EIP pseudocode, covering chunk counts that straddle
every subtree boundary plus deep cases at 1250 chunks and 20000 bits.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A struct opts in by declaring `pub const ssz_progressive_container = true`.
Serialization is untouched; hashTreeRoot becomes

  hash(merkleize_progressive(field_roots), pack_bits(active_fields))

Only the all-active form EIP-7688 mandates is supported: active_fields is
derived from the field count, so a field cannot be marked inactive.

Expected roots in the tests come from eth-remerkleable, the reference
implementation execution-specs uses. The ProgressiveList vectors added in
the previous commit were also cross-checked against it and all match.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@omerfirmak
omerfirmak requested a review from gballet as a code owner August 19, 2026 13:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant