Skip to content

Conversation

@iovoid
Copy link
Contributor

@iovoid iovoid commented Oct 15, 2025

Motivation

We want to have a way to query values directly without going through the trie (several reads).

To do this, we have a flattened key=>value mapping, which we call FlatKeyValue. This is sometimes known as "snapshots".

Description

A process is launched to generate this mapping in the background. We ensure apply_updates and this process don't conflict, and that block execution can only make use of the calculated snapshots.

Closes #1997, closes #2409, closes #2410

@github-actions
Copy link

Benchmark for f8a1eff

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 34.5±1.18ms 32.1±1.70ms -6.96%
Trie/cita-trie insert 1k 2.8±0.01ms 2.8±0.12ms 0.00%
Trie/ethrex-trie insert 10k 66.8±1.47ms 67.2±1.44ms +0.60%
Trie/ethrex-trie insert 1k 7.3±0.02ms 7.6±0.14ms +4.11%

@iovoid iovoid marked this pull request as ready for review October 17, 2025 19:42
@iovoid iovoid requested a review from a team as a code owner October 17, 2025 19:42
@ethrex-project-sync ethrex-project-sync bot moved this to In Review in ethrex_l1 Oct 17, 2025
@github-actions
Copy link

Benchmark for 7462ef0

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 38.0±2.05ms 34.7±0.98ms -8.68%
Trie/cita-trie insert 1k 3.5±0.01ms 3.5±0.02ms 0.00%
Trie/ethrex-trie insert 10k 62.8±1.16ms 65.7±0.73ms +4.62%
Trie/ethrex-trie insert 1k 8.0±0.24ms 8.5±0.44ms +6.25%

@github-actions
Copy link

Benchmark for cc00a65

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 35.0±0.43ms 35.3±0.46ms +0.86%
Trie/cita-trie insert 1k 3.5±0.02ms 3.6±0.16ms +2.86%
Trie/ethrex-trie insert 10k 63.2±1.22ms 66.2±1.42ms +4.75%
Trie/ethrex-trie insert 1k 8.0±0.04ms 8.3±0.02ms +3.75%

@github-actions
Copy link

Benchmark for 483cbaf

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 37.4±1.20ms 38.7±1.83ms +3.48%
Trie/cita-trie insert 1k 3.6±0.02ms 3.5±0.02ms -2.78%
Trie/ethrex-trie insert 10k 65.7±1.92ms 68.7±2.99ms +4.57%
Trie/ethrex-trie insert 1k 8.1±0.19ms 8.2±0.29ms +1.23%

@github-actions
Copy link

Benchmark for fe41120

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 35.8±1.20ms 35.1±0.38ms -1.96%
Trie/cita-trie insert 1k 3.5±0.01ms 3.6±0.01ms +2.86%
Trie/ethrex-trie insert 10k 62.3±1.18ms 66.3±1.60ms +6.42%
Trie/ethrex-trie insert 1k 7.9±0.14ms 8.4±0.20ms +6.33%

Copy link
Contributor

@Oppen Oppen left a comment

Choose a reason for hiding this comment

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

There are a few minor comments. I'll make an issue with them. Otherwise it should be good to go.

Comment on lines +154 to +156
if path.len() == 32 {
self.pending_removal.insert(Nibbles::from_bytes(path));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not true for all tries (receipts, transactions and withdrawals use their index encoded as RLP as key), but also at this level Trie is just key-value. This should be unconditional.

pub fn get(&self, pathrlp: &PathRLP) -> Result<Option<ValueRLP>, TrieError> {
let path = Nibbles::from_bytes(pathrlp);

if pathrlp.len() == 32
Copy link
Contributor

Choose a reason for hiding this comment

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

Similarly, we shouldn't have to check length here.

Comment on lines +112 to +114
pub const CF_FLATKEYVALUE: &str = "flatkeyvalue";

pub const CF_MISC_VALUES: &str = "misc_values";
Copy link
Contributor

Choose a reason for hiding this comment

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

No need for pub.

};
let account_state = AccountState::decode(&node.value)?;
let account_hash = H256::from_slice(&path.to_bytes());
batch.put_cf(&cf_misc, "last_written", path.as_ref());
Copy link
Contributor

Choose a reason for hiding this comment

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

We may save some memory and some overhead by miving the last_written updates to inside the if ctr > 10_000 cases.

Comment on lines +749 to +751
let ret = db
.write(batch)
.map_err(|e| StoreError::Custom(format!("RocksDB batch write error: {}", e)));
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing comment explaining we need to unconditionally run the lines below, and that they are order sensitive.

Comment on lines +73 to +75
if let Node::Leaf(leaf) = node.as_ref() {
acc.push((path.concat(&leaf.partial), leaf.value.clone()));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

We should have a comment here.

@github-actions
Copy link

Benchmark for e84c87a

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 36.3±1.29ms 42.7±2.44ms +17.63%
Trie/cita-trie insert 1k 3.7±0.03ms 3.5±0.07ms -5.41%
Trie/ethrex-trie insert 10k 68.2±1.41ms 68.2±4.55ms 0.00%
Trie/ethrex-trie insert 1k 8.2±0.07ms 8.3±0.36ms +1.22%

@github-actions
Copy link

Benchmark for a155d2e

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 38.0±1.36ms 38.8±1.99ms +2.11%
Trie/cita-trie insert 1k 3.5±0.02ms 3.6±0.01ms +2.86%
Trie/ethrex-trie insert 10k 64.2±1.44ms 67.4±2.79ms +4.98%
Trie/ethrex-trie insert 1k 8.0±0.02ms 8.4±0.03ms +5.00%

@github-actions
Copy link

Benchmark for 9731dac

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 35.9±1.79ms 35.7±1.39ms -0.56%
Trie/cita-trie insert 1k 3.6±0.02ms 3.6±0.17ms 0.00%
Trie/ethrex-trie insert 10k 62.7±1.01ms 65.5±1.03ms +4.47%
Trie/ethrex-trie insert 1k 8.1±0.04ms 8.4±0.23ms +3.70%

@ManuelBilbao ManuelBilbao added this pull request to the merge queue Oct 18, 2025
Merged via the queue into main with commit e5b1c81 Oct 18, 2025
33 checks passed
@ManuelBilbao ManuelBilbao deleted the pathbased_regen_versioning branch October 18, 2025 22:13
@github-project-automation github-project-automation bot moved this from In Review to Done in ethrex_l1 Oct 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

L1 Ethereum client

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Account storage by address and location snapshot Account state by address snapshot. perf: state snapshots

10 participants