mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-08 15:03:58 -05:00
- Fix parallel trie store_in_db_trie: was setting true when masks were present regardless of whether they were empty. Now correctly checks that at least one mask is non-empty. - Remove leftover TrieMasks struct usage in proof_v2 test
4.3 KiB
4.3 KiB
Prototype: Replace TrieMasks with Option<BranchNodeMasks> in ProofTrieNode
Summary
This prototype explores replacing TrieMasks with Option<BranchNodeMasks> in ProofTrieNode and related APIs, as suggested after PR #20664.
Current State
// TrieMasks - each field is independently optional
pub struct TrieMasks {
pub hash_mask: Option<TrieMask>, // 4 bytes
pub tree_mask: Option<TrieMask>, // 4 bytes
} // Total: 8 bytes
// BranchNodeMasks - both fields always present together
pub struct BranchNodeMasks {
pub hash_mask: TrieMask, // 2 bytes
pub tree_mask: TrieMask, // 2 bytes
} // Total: 4 bytes
// Option<BranchNodeMasks> = 6 bytes
Key Findings
1. Size Reduction
TrieMasks: 8 bytesOption<BranchNodeMasks>: 6 bytes- Savings: 25% reduction (2 bytes per instance)
2. Code Simplification
The prototype shows -27 net lines across 5 files:
| File | Insertions | Deletions | Net |
|---|---|---|---|
| common/src/trie.rs | +2 | -1 | +1 |
| sparse/src/provider.rs | +4 | -4 | 0 |
| sparse/src/state.rs | +16 | -23 | -7 |
| sparse/src/traits.rs | +3 | -3 | 0 |
| sparse/src/trie.rs | +18 | -33 | -15 |
| Total | +40 | -67 | -27 |
3. Semantic Correctness
Analysis confirms that both masks always come together:
- When read from database, both masks are fetched together
- Production code never sets one mask without the other
- Independent mask setting (
hash_mask: Some(..), tree_mask: None) only appears in tests
4. Simplification Examples
Before:
if masks.tree_mask.is_some() || masks.hash_mask.is_some() {
self.branch_node_masks.insert(
path,
BranchNodeMasks {
tree_mask: masks.tree_mask.unwrap_or_default(),
hash_mask: masks.hash_mask.unwrap_or_default(),
},
);
}
After:
if let Some(branch_masks) = masks {
self.branch_node_masks.insert(path, branch_masks);
}
Before:
store_in_db_trie: Some(
masks.hash_mask.is_some_and(|mask| !mask.is_empty()) ||
masks.tree_mask.is_some_and(|mask| !mask.is_empty()),
),
After:
store_in_db_trie: Some(masks.is_some_and(|m| {
!m.hash_mask.is_empty() || !m.tree_mask.is_empty()
})),
5. Full Scope of Changes
| Location | Count | Notes |
|---|---|---|
| sparse-parallel/src/trie.rs | 70 | Mostly tests |
| sparse/src/trie.rs | 16 | All tests after migration |
| proof_v2/mod.rs | 8 | Production code |
| proof_v2/node.rs | 5 | Production code |
| configured_sparse_trie.rs | 3 | Production code |
| common/src/trie.rs | 2 | Struct definition |
| common/src/lib.rs | 1 | Export |
6. Additional Changes Required
RevealedNodein provider.rs should also change from twoOption<TrieMask>fields to singleOption<BranchNodeMasks>(done in prototype)- Tests need updates to use
Some(BranchNodeMasks { .. })instead ofTrieMasks { hash_mask: Some(..), tree_mask: None } proof_v2module needs similar updates- Parallel sparse trie needs same changes as serial version
Recommendation
Proceed with this refactor because:
- Memory reduction: 25% smaller per instance
- Code simplification: -27 lines, cleaner patterns
- Semantic correctness: Reflects actual usage (masks come together)
- Type safety: Impossible to create invalid state with one mask missing
Test Migration Strategy
For tests that currently set masks independently:
// Before
TrieMasks { hash_mask: Some(TrieMask::new(0b01)), tree_mask: None }
// After - use default for the other mask
Some(BranchNodeMasks { hash_mask: TrieMask::new(0b01), tree_mask: TrieMask::default() })
Files Changed in Prototype
crates/trie/common/src/trie.rs (ProofTrieNode definition)
crates/trie/sparse/src/provider.rs (RevealedNode definition)
crates/trie/sparse/src/state.rs (State trie operations)
crates/trie/sparse/src/traits.rs (Trait signatures)
crates/trie/sparse/src/trie.rs (Serial sparse trie impl)
Outstanding Work
- Update tests in
sparse/src/trie.rs - Update
sparse-parallel/src/trie.rs(same changes) - Update
proof_v2module - Update
configured_sparse_trie.rs - Run full test suite and benchmarks
- Consider removing
TrieMasksstruct entirely if no longer needed