Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@mediocregopher
Copy link
Collaborator

Hello! I noted the following open bug in reth and decided to use the opportunity to get a better understanding for the codebase and related libraries:

paradigmxyz/reth#12129 (related PR which provided a test case: paradigmxyz/reth#12080)

Most of my understanding of the problem and solution is based on my reading of the reth and alloy codebases and other materials, so I could well have made some wrong assumptions or misunderstood some fundamental point. Sorry if that's the case, but please let me know!


As I dug into the issue I found that the source of the problem was in the HashBuilder here in the trie library. As described in the original bug/pr, in certain cases the tree_mask would get a bit set on it even though the corresponding child wouldn't appear in the set of updated branch nodes. This was due to the bit getting incorrectly set for extension nodes which pointed to intermediate branch nodes.

For example, the following is a simplified reproduction case based on the one in the above PR. Given these leafs:

0xb000000000000000000000000000000000000000000000000000000000000000
0xb650000000000000000000000000000000000000000000000000000000000000
0xb652000000000000000000000000000000000000000000000000000000000000
0xb652c00000000000000000000000000000000000000000000000000000000000

The node 0xb6 is an extension node with short key 5 leading to the branch node 0xb65, which does appear in the updated branch nodes result. The branch node at 0xb was incorrectly getting the bit for child 6 set in its tree_masks, due to this code in the update_masks method:

if !self.tree_masks[current.len() - 1].is_empty() {
self.tree_masks[len_from - 1] |= flag;
}

Unfortunately it was not enough to simply remove the offending line, as the tree_masks is getting used to determine if an updated branch node should be created at all, and so would cause the 0xb65 branch node to not be included in the updated branch nodes set.

let store_in_db_trie = !self.tree_masks[len].is_empty() || !self.hash_masks[len].is_empty();

My solution is to simply do a bitwise AND between the hash_mask and the tree_mask when creating the BranchNodeCompact. If I'm not mistaken the hash mask will be correctly set with a bit only for child branch nodes, regardless of if the node is an intermediate node, and so is always a superset of the desired tree_mask. If this isn't correct then another solution will need to be found.

I've included a bunch of extra tracing which I found helpful during debugging, as well as some test cases which check the solution. If any of these aren't up to coding guidelines or what-have-you I can of course change them.

@codspeed-hq
Copy link

codspeed-hq bot commented Jun 13, 2025

CodSpeed Performance Report

Merging #103 will not alter performance

Comparing mediocregopher:reth-issue-12129-invalid-trie-masks (e202160) with main (3401e6e)

Summary

✅ 4 untouched benchmarks

@jenpaff jenpaff added this to Alloy Jun 17, 2025
@jenpaff jenpaff moved this to In Progress in Alloy Jun 17, 2025
@mediocregopher mediocregopher force-pushed the reth-issue-12129-invalid-trie-masks branch from 530b2e0 to da11f37 Compare June 18, 2025 08:26
As reported in:
paradigmxyz/reth#12080
paradigmxyz/reth#12129

the tree_mask would sometimes get a bit set on it even though the
corresponding child wouldn't appear in the set of updated branch nodes.
This was due to the bit getting incorrectly set for extension nodes
which pointed to updated branch nodes. The solution is a bit of a hack.
@mediocregopher mediocregopher force-pushed the reth-issue-12129-invalid-trie-masks branch from da11f37 to 451cd09 Compare August 26, 2025 08:50
@mediocregopher mediocregopher force-pushed the reth-issue-12129-invalid-trie-masks branch from 451cd09 to e202160 Compare September 2, 2025 10:06
@mediocregopher
Copy link
Collaborator Author

My work being done here is going beyond the tree_mask bug, I'm honestly not even sure that is a bug at this point, just a misunderstanding in the code documentation about tree mask is (vs how we use it).

@github-project-automation github-project-automation bot moved this from In Progress to Done in Alloy Sep 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant