Skip to content

Conversation

@michaelsproul
Copy link
Member

@michaelsproul michaelsproul commented Dec 10, 2025

This PR contains all of the tree_hash changes required to support EIP-7916 and EIP-8016:

  • ProgressiveMerkleHasher: an analog of MerkleHasher, it has a lazy API where it can ingest bytes and hash them incrementally. It uses a MerkleHasher under the hood to do the hashing of the binary subtrees.
  • TreeHash implementation for Bitfield<Progressive> from ethereum_ssz.
  • Derive macro support for struct_behaviour = "progressive_container". This generates code that uses a ProgressiveMerkleHasher for the fields. It comes with a new attribute active_fields({0,1},+) which is used to insert zero hashes for inactivated fields. The derive macro also generates a 32-byte array representing the active fields as a bitfield (at compile time), and generates code to mix this bitfield into the root, following the spec.
  • Derive macro support for enum_behaviour = "compatible_union". Compatible unions behave quite similarly to the existing (and now deprecated) union type, with the difference being that their g-indices and merkle tree structure is stable across all enum variants. For now the macro does not verify that enum variants are compatible, because this verification is not mandatory (it is safe if the only compatible unions happen to be compatible, which the spec should ensure). Verification is left for a follow-up PR: Compatible union validation ethereum_ssz#72.
  • As part of compatible union support, we add a new variant attribute tree_hash(selector = "1") which can set the selector for compatible unions only. To avoid duplication with ethereum_ssz this selector is read from the ssz attribute, or the tree_hash attribute (they must be consistent if both are set). See discussion: Progressive data structures and tests EIP-7916, EIP-8016 lighthouse#8505 (comment).

Depends on:

Copy link
Member

@macladson macladson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to work on flipping the tree structure to the new spec

Some(Hash256::from_slice(&root))
}

pub fn mix_in_active_fields(root: Hash256, active_fields: [u8; BYTES_PER_CHUNK]) -> Hash256 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any utility to this function outside of the derive? I'm wondering if we should mark this with a #[doc(hidden)]? (Same applies to mix_in_selector)

@codecov
Copy link

codecov bot commented Feb 3, 2026

Codecov Report

❌ Patch coverage is 86.36364% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.42%. Comparing base (dbf20c3) to head (ab57ec3).

Files with missing lines Patch % Lines
tree_hash/src/impls.rs 0.00% 7 Missing ⚠️
tree_hash/src/progressive_merkle_hasher.rs 95.83% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #43      +/-   ##
==========================================
+ Coverage   87.75%   88.42%   +0.67%     
==========================================
  Files           6        7       +1     
  Lines         294      432     +138     
==========================================
+ Hits          258      382     +124     
- Misses         36       50      +14     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

3 participants