Skip to content

Conversation

pablodeymo
Copy link
Contributor

@pablodeymo pablodeymo commented Jun 18, 2025

Account Info and Account Storage Snapshot Feature

Goal

Improve database read access performance for block execution, while keeping write access overhead in check.

MVP Requirements

  • Ability to build a snapshot from a point in time and keep it up-to-date.
  • Ability to handle re-orgs correctly.
  • Ability to read from the snapshot when its state corresponds to the one for the base block.

Missing for MVP

  • Check for re-orgs beyond start of log. It should discard the snapshot and start over.
  • Implementations for InMemoryDB and ReDB.
  • Unit or integration tests for edge cases.
  • Simplify by using smaller helpers inside the DB implementations. They need to take either the open transaction or the open cursor to operate on, to avoid adding commit overhead.

V2 Requirements

  • Unify tables with snap sync.
  • Fix the healing process of snap sync to produce a re-usable snapshot.
  • Implementation of log pruning, to limit the size of the snapshot.
  • Work directly on AccountUpdates for simplicity.

Later Work

  • The choice of using a log was made to enable a later change of index for tries, using their prefix rather than their hashes as key.
  • Under that implementation, the snapshot becomes one with the trie, as finding leaves is finding values and their prefix is the whole path in the trie.
  • There might be some extra improvement both in code size and storage size in saving the XOR of old and new values instead of the values themselves in the log entries. The storage should become about half, while the code for rewinding and replaying would change only in the direction of iteration, as XOR is a symmetric operation.

closes #1997

pablodeymo and others added 30 commits June 2, 2025 16:35
Co-authored-by: Juan Bono <[email protected]>
…ases (#3072)

**Motivation**

Original PR was missing ReDB and InMemory implementations.

**Description**

Merges the single-update method as a special case of the batch one.

Part of #3043

---------

Co-authored-by: Juan Bono <[email protected]>
Co-authored-by: Ivan Litteri <[email protected]>
@damiramirez damiramirez marked this pull request as ready for review July 4, 2025 15:03
@damiramirez damiramirez requested a review from a team as a code owner July 4, 2025 15:03
@damiramirez damiramirez requested a review from Copilot July 4, 2025 15:03
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Adds flat account info and storage snapshots with undo/replay support to improve read performance and handle chain re-orgs.

  • Introduce write‐log tables and processing functions in all StoreEngine backends (RedB, LMDBX, in‐memory).
  • Extend the StoreEngine API with undo/replay and genesis setup methods.
  • Hook snapshot reconstruction into sync and fork‐choice logic.

Reviewed Changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
crates/storage/store_db/redb.rs Added RDB tables, undo/replay methods and log processing hooks
crates/storage/store_db/libmdbx.rs Added LMDBX table definitions, undo/replay helpers and batch writes
crates/storage/store_db/in_memory.rs Added in‐memory snapshot state, undo/replay and log tracking
crates/storage/api.rs Extended StoreEngine trait with snapshot and genesis methods
crates/blockchain/fork_choice.rs Integrated reconstruct_snapshots_for_new_canonical_chain call
Comments suppressed due to low confidence (3)

crates/storage/api.rs:23

  • New snapshot undo/replay methods lack unit or integration tests. Add tests for undo_writes_until_canonical, replay_writes_until_head, and genesis setup to cover edge cases like deep re-orgs.
    async fn undo_writes_until_canonical(&self) -> Result<(), StoreError>;

crates/storage/api.rs:23

  • [nitpick] Public API methods undo_writes_until_canonical, replay_writes_until_head, and genesis setup lack doc comments explaining their semantics and requirements. Please add documentation to clarify expected behavior.
    async fn undo_writes_until_canonical(&self) -> Result<(), StoreError>;

crates/storage/store.rs:66

  • [nitpick] The field storage_log_updates parallels account_info_log_updates, but its name omits the account_ prefix. Consider renaming to account_storage_log_updates for consistency.
    pub storage_log_updates: Vec<AccountStorageLogEntry>,


// We update this here to ensure it's the previous block according
// to the logs found.
BlockNumHash(block_num, snapshot_hash) = parent_block;
Copy link
Preview

Copilot AI Jul 4, 2025

Choose a reason for hiding this comment

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

This line attempts to assign to block_num and snapshot_hash via a destructuring pattern but doesn’t actually update those variables. Replace it with let (block_num, snapshot_hash) = parent_block; and update current_snapshot accordingly.

Suggested change
BlockNumHash(block_num, snapshot_hash) = parent_block;
let (block_num, snapshot_hash) = parent_block;
current_snapshot = BlockNumHash(block_num, snapshot_hash);

Copilot uses AI. Check for mistakes.

Copy link
Contributor

Choose a reason for hiding this comment

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

Both variables are mutable

let mut block_num = current_snapshot.0;
let mut snapshot_hash = current_snapshot.1;

Copy link

github-actions bot commented Jul 4, 2025

No significant difference was registered for any benchmark run.

Detailed Results

Benchmark Results: BubbleSort

Command Mean [s] Min [s] Max [s] Relative
main_revm_BubbleSort 3.179 ± 0.033 3.140 3.237 1.00 ± 0.01
main_levm_BubbleSort 4.429 ± 0.022 4.400 4.473 1.39 ± 0.01
pr_revm_BubbleSort 3.178 ± 0.019 3.159 3.211 1.00
pr_levm_BubbleSort 4.470 ± 0.013 4.452 4.499 1.41 ± 0.01

Benchmark Results: ERC20Approval

Command Mean [s] Min [s] Max [s] Relative
main_revm_ERC20Approval 1.074 ± 0.013 1.050 1.091 1.02 ± 0.01
main_levm_ERC20Approval 1.547 ± 0.009 1.537 1.562 1.47 ± 0.01
pr_revm_ERC20Approval 1.056 ± 0.007 1.048 1.072 1.00
pr_levm_ERC20Approval 1.561 ± 0.010 1.545 1.582 1.48 ± 0.01

Benchmark Results: ERC20Mint

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Mint 139.7 ± 1.0 137.7 141.6 1.00
main_levm_ERC20Mint 255.3 ± 2.9 252.7 261.5 1.83 ± 0.03
pr_revm_ERC20Mint 141.1 ± 1.0 140.1 143.2 1.01 ± 0.01
pr_levm_ERC20Mint 266.3 ± 2.6 263.0 272.2 1.91 ± 0.02

Benchmark Results: ERC20Transfer

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Transfer 249.2 ± 0.7 248.1 250.6 1.01 ± 0.01
main_levm_ERC20Transfer 404.3 ± 3.3 401.5 412.8 1.64 ± 0.02
pr_revm_ERC20Transfer 245.9 ± 1.6 243.4 248.3 1.00
pr_levm_ERC20Transfer 409.1 ± 2.8 405.0 413.5 1.66 ± 0.02

Benchmark Results: Factorial

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Factorial 235.5 ± 1.7 233.8 238.3 1.00
main_levm_Factorial 434.1 ± 0.5 433.3 434.9 1.84 ± 0.01
pr_revm_Factorial 241.6 ± 6.9 238.8 261.3 1.03 ± 0.03
pr_levm_Factorial 459.6 ± 2.4 457.7 465.1 1.95 ± 0.02

Benchmark Results: FactorialRecursive

Command Mean [s] Min [s] Max [s] Relative
main_revm_FactorialRecursive 1.580 ± 0.078 1.372 1.638 1.00
main_levm_FactorialRecursive 2.729 ± 0.014 2.702 2.754 1.73 ± 0.09
pr_revm_FactorialRecursive 1.627 ± 0.029 1.571 1.678 1.03 ± 0.05
pr_levm_FactorialRecursive 2.880 ± 0.012 2.861 2.901 1.82 ± 0.09

Benchmark Results: Fibonacci

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Fibonacci 207.1 ± 1.2 204.7 209.2 1.00
main_levm_Fibonacci 440.4 ± 19.4 430.7 495.3 2.13 ± 0.09
pr_revm_Fibonacci 217.0 ± 0.3 216.5 217.5 1.05 ± 0.01
pr_levm_Fibonacci 453.4 ± 10.7 445.8 480.8 2.19 ± 0.05

Benchmark Results: FibonacciRecursive

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_FibonacciRecursive 851.4 ± 8.5 836.6 862.6 1.00
main_levm_FibonacciRecursive 1426.4 ± 8.4 1408.5 1436.4 1.68 ± 0.02
pr_revm_FibonacciRecursive 880.1 ± 14.3 849.7 901.2 1.03 ± 0.02
pr_levm_FibonacciRecursive 1519.4 ± 10.5 1503.7 1536.3 1.78 ± 0.02

Benchmark Results: ManyHashes

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ManyHashes 8.8 ± 0.1 8.7 9.0 1.02 ± 0.01
main_levm_ManyHashes 13.5 ± 0.5 13.2 14.9 1.55 ± 0.06
pr_revm_ManyHashes 8.7 ± 0.0 8.7 8.7 1.00
pr_levm_ManyHashes 14.5 ± 0.2 14.3 14.9 1.66 ± 0.02

Benchmark Results: MstoreBench

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_MstoreBench 271.5 ± 2.1 269.7 275.6 1.00
main_levm_MstoreBench 935.6 ± 3.2 930.7 940.0 3.45 ± 0.03
pr_revm_MstoreBench 273.5 ± 2.7 269.8 279.0 1.01 ± 0.01
pr_levm_MstoreBench 1026.5 ± 9.2 1018.7 1045.5 3.78 ± 0.04

Benchmark Results: Push

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Push 295.3 ± 1.3 293.9 297.8 1.01 ± 0.01
main_levm_Push 1062.0 ± 3.8 1057.0 1068.5 3.62 ± 0.02
pr_revm_Push 293.1 ± 1.4 291.5 296.2 1.00
pr_levm_Push 1076.6 ± 8.0 1055.5 1082.9 3.67 ± 0.03

Copy link

github-actions bot commented Jul 4, 2025

No significant difference was registered for any benchmark run.

Detailed Results

Benchmark Results: BubbleSort

Command Mean [s] Min [s] Max [s] Relative
main_revm_BubbleSort 3.192 ± 0.023 3.169 3.242 1.01 ± 0.01
main_levm_BubbleSort 4.492 ± 0.077 4.439 4.643 1.42 ± 0.03
pr_revm_BubbleSort 3.173 ± 0.017 3.152 3.207 1.00
pr_levm_BubbleSort 4.566 ± 0.070 4.513 4.750 1.44 ± 0.02

Benchmark Results: ERC20Approval

Command Mean [s] Min [s] Max [s] Relative
main_revm_ERC20Approval 1.039 ± 0.006 1.034 1.053 1.00
main_levm_ERC20Approval 1.552 ± 0.006 1.544 1.560 1.49 ± 0.01
pr_revm_ERC20Approval 1.059 ± 0.010 1.049 1.076 1.02 ± 0.01
pr_levm_ERC20Approval 1.570 ± 0.009 1.559 1.589 1.51 ± 0.01

Benchmark Results: ERC20Mint

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Mint 137.6 ± 1.6 136.4 141.9 1.00
main_levm_ERC20Mint 257.4 ± 1.9 255.2 260.4 1.87 ± 0.03
pr_revm_ERC20Mint 141.4 ± 0.6 140.7 142.4 1.03 ± 0.01
pr_levm_ERC20Mint 260.0 ± 2.1 257.4 264.6 1.89 ± 0.03

Benchmark Results: ERC20Transfer

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Transfer 243.8 ± 2.0 241.9 247.6 1.00
main_levm_ERC20Transfer 406.9 ± 1.5 405.5 409.7 1.67 ± 0.01
pr_revm_ERC20Transfer 245.8 ± 0.8 245.2 247.9 1.01 ± 0.01
pr_levm_ERC20Transfer 408.9 ± 3.6 404.7 417.3 1.68 ± 0.02

Benchmark Results: Factorial

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Factorial 235.6 ± 2.0 233.7 238.8 1.00
main_levm_Factorial 435.1 ± 5.3 431.4 449.6 1.85 ± 0.03
pr_revm_Factorial 243.9 ± 4.7 237.4 253.8 1.04 ± 0.02
pr_levm_Factorial 457.3 ± 1.5 456.0 460.0 1.94 ± 0.02

Benchmark Results: FactorialRecursive

Command Mean [s] Min [s] Max [s] Relative
main_revm_FactorialRecursive 1.606 ± 0.026 1.561 1.639 1.00
main_levm_FactorialRecursive 2.835 ± 0.025 2.805 2.881 1.76 ± 0.03
pr_revm_FactorialRecursive 1.618 ± 0.023 1.560 1.640 1.01 ± 0.02
pr_levm_FactorialRecursive 2.735 ± 0.042 2.710 2.852 1.70 ± 0.04

Benchmark Results: Fibonacci

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Fibonacci 228.5 ± 68.4 204.2 423.1 1.07 ± 0.32
main_levm_Fibonacci 430.5 ± 4.7 426.5 442.4 2.02 ± 0.02
pr_revm_Fibonacci 213.0 ± 0.6 211.9 213.9 1.00
pr_levm_Fibonacci 451.3 ± 5.2 447.3 463.4 2.12 ± 0.02

Benchmark Results: FibonacciRecursive

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_FibonacciRecursive 854.8 ± 8.0 842.3 863.9 1.00
main_levm_FibonacciRecursive 1485.3 ± 9.5 1469.1 1495.5 1.74 ± 0.02
pr_revm_FibonacciRecursive 871.3 ± 9.3 853.0 879.9 1.02 ± 0.01
pr_levm_FibonacciRecursive 1428.0 ± 8.5 1417.1 1444.7 1.67 ± 0.02

Benchmark Results: ManyHashes

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ManyHashes 8.9 ± 0.1 8.7 9.2 1.02 ± 0.02
main_levm_ManyHashes 14.0 ± 0.2 13.8 14.4 1.60 ± 0.02
pr_revm_ManyHashes 8.7 ± 0.0 8.7 8.8 1.00
pr_levm_ManyHashes 13.5 ± 0.1 13.3 13.6 1.54 ± 0.02

Benchmark Results: MstoreBench

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_MstoreBench 270.9 ± 1.1 269.3 272.8 1.00
main_levm_MstoreBench 934.9 ± 5.0 930.8 947.8 3.45 ± 0.02
pr_revm_MstoreBench 279.0 ± 19.8 270.2 334.5 1.03 ± 0.07
pr_levm_MstoreBench 951.3 ± 76.7 918.6 1167.2 3.51 ± 0.28

Benchmark Results: Push

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Push 295.7 ± 1.0 294.4 296.9 1.01 ± 0.02
main_levm_Push 1073.7 ± 11.3 1066.2 1105.1 3.67 ± 0.08
pr_revm_Push 292.9 ± 5.6 289.1 308.2 1.00
pr_levm_Push 1109.4 ± 33.2 1090.7 1199.9 3.79 ± 0.13

Copy link

github-actions bot commented Jul 4, 2025

No significant difference was registered for any benchmark run.

Detailed Results

Benchmark Results: BubbleSort

Command Mean [s] Min [s] Max [s] Relative
main_revm_BubbleSort 3.190 ± 0.025 3.164 3.254 1.00
main_levm_BubbleSort 4.414 ± 0.015 4.390 4.431 1.38 ± 0.01
pr_revm_BubbleSort 3.197 ± 0.015 3.180 3.230 1.00 ± 0.01
pr_levm_BubbleSort 4.548 ± 0.017 4.522 4.570 1.43 ± 0.01

Benchmark Results: ERC20Approval

Command Mean [s] Min [s] Max [s] Relative
main_revm_ERC20Approval 1.055 ± 0.021 1.044 1.114 1.01 ± 0.02
main_levm_ERC20Approval 1.513 ± 0.006 1.506 1.525 1.45 ± 0.02
pr_revm_ERC20Approval 1.044 ± 0.010 1.033 1.058 1.00
pr_levm_ERC20Approval 1.565 ± 0.010 1.552 1.583 1.50 ± 0.02

Benchmark Results: ERC20Mint

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Mint 140.4 ± 0.5 139.7 141.3 1.00
main_levm_ERC20Mint 251.9 ± 2.4 249.0 255.8 1.79 ± 0.02
pr_revm_ERC20Mint 140.8 ± 1.0 140.1 143.5 1.00 ± 0.01
pr_levm_ERC20Mint 264.7 ± 1.8 262.7 268.2 1.89 ± 0.01

Benchmark Results: ERC20Transfer

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Transfer 249.0 ± 6.8 245.1 267.7 1.02 ± 0.03
main_levm_ERC20Transfer 406.4 ± 25.1 395.9 477.5 1.66 ± 0.10
pr_revm_ERC20Transfer 245.2 ± 3.1 242.0 251.8 1.00
pr_levm_ERC20Transfer 409.6 ± 2.9 407.1 416.6 1.67 ± 0.02

Benchmark Results: Factorial

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Factorial 240.2 ± 2.1 237.8 244.1 1.01 ± 0.01
main_levm_Factorial 437.8 ± 6.0 433.3 452.4 1.85 ± 0.03
pr_revm_Factorial 236.9 ± 1.9 235.3 242.0 1.00
pr_levm_Factorial 457.7 ± 0.7 456.8 459.2 1.93 ± 0.02

Benchmark Results: FactorialRecursive

Command Mean [s] Min [s] Max [s] Relative
main_revm_FactorialRecursive 1.613 ± 0.020 1.589 1.651 1.00 ± 0.03
main_levm_FactorialRecursive 2.725 ± 0.022 2.701 2.773 1.70 ± 0.05
pr_revm_FactorialRecursive 1.607 ± 0.042 1.538 1.670 1.00
pr_levm_FactorialRecursive 2.813 ± 0.033 2.786 2.902 1.75 ± 0.05

Benchmark Results: Fibonacci

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Fibonacci 207.2 ± 0.6 206.4 208.3 1.00
main_levm_Fibonacci 438.6 ± 25.1 425.9 505.7 2.12 ± 0.12
pr_revm_Fibonacci 211.6 ± 2.5 209.6 216.9 1.02 ± 0.01
pr_levm_Fibonacci 464.1 ± 36.7 446.9 567.4 2.24 ± 0.18

Benchmark Results: FibonacciRecursive

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_FibonacciRecursive 866.1 ± 5.3 858.1 874.2 1.00
main_levm_FibonacciRecursive 1443.8 ± 15.3 1427.3 1480.7 1.67 ± 0.02
pr_revm_FibonacciRecursive 866.4 ± 11.5 844.7 882.2 1.00 ± 0.01
pr_levm_FibonacciRecursive 1496.4 ± 14.4 1481.4 1529.7 1.73 ± 0.02

Benchmark Results: ManyHashes

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ManyHashes 8.8 ± 0.0 8.8 8.8 1.00
main_levm_ManyHashes 13.0 ± 0.2 12.9 13.3 1.49 ± 0.02
pr_revm_ManyHashes 8.8 ± 0.1 8.7 8.9 1.00 ± 0.01
pr_levm_ManyHashes 14.2 ± 0.1 14.0 14.3 1.61 ± 0.01

Benchmark Results: MstoreBench

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_MstoreBench 272.0 ± 2.6 269.2 278.1 1.00
main_levm_MstoreBench 936.2 ± 9.0 931.1 961.2 3.44 ± 0.05
pr_revm_MstoreBench 272.0 ± 2.8 270.0 279.2 1.00 ± 0.01
pr_levm_MstoreBench 929.4 ± 6.2 917.6 940.6 3.42 ± 0.04

Benchmark Results: Push

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Push 296.5 ± 1.6 294.1 298.3 1.02 ± 0.01
main_levm_Push 1069.7 ± 3.8 1063.4 1078.3 3.69 ± 0.02
pr_revm_Push 290.2 ± 1.4 288.4 292.8 1.00
pr_levm_Push 1064.9 ± 4.0 1058.3 1071.0 3.67 ± 0.02

@github-actions github-actions bot added L1 Ethereum client L2 Rollup client performance labels Jul 8, 2025
@ilitteri ilitteri moved this to In Progress in ethrex_l2 Jul 8, 2025
@ilitteri ilitteri moved this from In Progress to In Review in ethrex_l2 Jul 8, 2025
@mpaulucci mpaulucci removed this from ethrex_l1 Jul 8, 2025
Copy link
Collaborator

@Arkenan Arkenan left a comment

Choose a reason for hiding this comment

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

LGTM, all of my comments can be addressed in a separate PR.

genesis_accounts: &[(Address, u64, U256, H256, bool)],
) -> Result<(), StoreError>;

/// Gets the block hash for the current snapshot
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: maybe clarify that the result is an option because there may be no current snapshot (if there is, there will always be an associated block hash).

Comment on lines +56 to +62

#[cfg(feature = "libmdbx")]
impl From<anyhow::Error> for StoreError {
fn from(err: anyhow::Error) -> Self {
StoreError::LibmdbxError(err)
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems convoluted and counterintuitive. anyhow:Error is very generic. How can we make sure it would always be a libmdbx error? why do we need this?

Comment on lines +35 to +48
#[cfg(feature = "redb")]
pub type AccountInfoLogEntryRLP = Rlp<AccountInfoLogEntry>;
#[cfg(feature = "redb")]
pub type AccountStorageLogEntryRLP = Rlp<AccountStorageLogEntry>;
#[cfg(feature = "redb")]
pub type BlockNumHashRLP = Rlp<BlockNumHash>;
#[cfg(feature = "redb")]
pub type AccountAddressRLP = Rlp<Address>;
#[cfg(feature = "redb")]
pub type AccountInfoRLP = Rlp<AccountInfo>;
#[cfg(feature = "redb")]
pub type AccountStorageKeyRLP = Rlp<H256>;
#[cfg(feature = "redb")]
pub type AccountStorageValueRLP = Rlp<U256>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

If this is redb specific, why do we need it in the storage rlp directory? Can we not have it in the redb file instead?

// the log for those blocks
// 4. Commit the transaction
//
// This function assumes that `new_canonical_blocks` is sorted by block number.
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is "new canonical blocks"?

Comment on lines +136 to +138
// TODO: build_account_info_logs and build_account_storage_logs became a bit
// redundant. Just pass the account_updates whole and process inside the
// apply_updates function.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This sounds very sensible. Let's add an issue for this.

let mut state_logs = state_log_cursor.seek_closest(to_snapshot)?;

let mut account_updates = vec![];
while let Some(((final_block, parent_block), log_entry)) = state_logs {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: I see we repeat this pattern quite a lot (seek closest + while). Shall we refactor it to an iterator se we can use it like this? self.get_logs(cursor, snapshot).map(...).

Not for this PR and also optional, might be more complex than it seems.

Copy link
Member

@jrchatruc jrchatruc left a comment

Choose a reason for hiding this comment

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

Blocking merge of this PR until we run the numbers along with pruning

@github-project-automation github-project-automation bot moved this from In Review to Requires Changes in ethrex_l2 Jul 10, 2025
Copy link

No significant difference was registered for any benchmark run.

Detailed Results

Benchmark Results: BubbleSort

Command Mean [s] Min [s] Max [s] Relative
main_revm_BubbleSort 3.190 ± 0.017 3.174 3.223 1.00 ± 0.01
main_levm_BubbleSort 4.450 ± 0.088 4.393 4.622 1.40 ± 0.03
pr_revm_BubbleSort 3.189 ± 0.026 3.143 3.237 1.00
pr_levm_BubbleSort 4.420 ± 0.028 4.385 4.487 1.39 ± 0.01

Benchmark Results: ERC20Approval

Command Mean [s] Min [s] Max [s] Relative
main_revm_ERC20Approval 1.046 ± 0.014 1.028 1.073 1.00 ± 0.02
main_levm_ERC20Approval 1.526 ± 0.014 1.512 1.556 1.46 ± 0.02
pr_revm_ERC20Approval 1.045 ± 0.008 1.034 1.062 1.00
pr_levm_ERC20Approval 1.531 ± 0.011 1.519 1.552 1.47 ± 0.02

Benchmark Results: ERC20Mint

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Mint 138.0 ± 1.7 136.1 141.2 1.00
main_levm_ERC20Mint 247.0 ± 3.6 244.0 254.6 1.79 ± 0.03
pr_revm_ERC20Mint 138.6 ± 1.6 137.0 142.4 1.00 ± 0.02
pr_levm_ERC20Mint 256.0 ± 3.3 253.0 263.0 1.86 ± 0.03

Benchmark Results: ERC20Transfer

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Transfer 244.2 ± 3.2 241.4 249.6 1.01 ± 0.02
main_levm_ERC20Transfer 393.4 ± 7.3 388.8 413.9 1.62 ± 0.04
pr_revm_ERC20Transfer 242.8 ± 3.5 240.3 252.1 1.00
pr_levm_ERC20Transfer 403.8 ± 5.7 398.3 418.7 1.66 ± 0.03

Benchmark Results: Factorial

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Factorial 232.9 ± 1.0 231.6 234.5 1.00
main_levm_Factorial 505.2 ± 27.6 474.8 533.6 2.17 ± 0.12
pr_revm_Factorial 233.4 ± 0.5 232.5 234.0 1.00 ± 0.00
pr_levm_Factorial 443.3 ± 1.0 442.3 445.4 1.90 ± 0.01

Benchmark Results: FactorialRecursive

Command Mean [s] Min [s] Max [s] Relative
main_revm_FactorialRecursive 1.610 ± 0.032 1.547 1.652 1.00
main_levm_FactorialRecursive 2.743 ± 0.065 2.699 2.868 1.70 ± 0.05
pr_revm_FactorialRecursive 1.639 ± 0.028 1.592 1.681 1.02 ± 0.03
pr_levm_FactorialRecursive 2.758 ± 0.020 2.736 2.786 1.71 ± 0.04

Benchmark Results: Fibonacci

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Fibonacci 207.9 ± 0.9 207.3 210.3 1.00 ± 0.00
main_levm_Fibonacci 463.8 ± 4.3 458.6 475.3 2.24 ± 0.02
pr_revm_Fibonacci 207.3 ± 0.4 206.9 208.1 1.00
pr_levm_Fibonacci 459.9 ± 45.8 440.9 588.0 2.22 ± 0.22

Benchmark Results: FibonacciRecursive

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_FibonacciRecursive 866.6 ± 17.0 825.5 885.1 1.00
main_levm_FibonacciRecursive 1446.9 ± 25.3 1424.1 1512.4 1.67 ± 0.04
pr_revm_FibonacciRecursive 877.4 ± 14.9 849.1 897.0 1.01 ± 0.03
pr_levm_FibonacciRecursive 1455.0 ± 23.7 1423.2 1494.8 1.68 ± 0.04

Benchmark Results: ManyHashes

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ManyHashes 8.8 ± 0.1 8.7 9.0 1.00 ± 0.01
main_levm_ManyHashes 13.2 ± 0.1 13.1 13.4 1.51 ± 0.02
pr_revm_ManyHashes 8.7 ± 0.1 8.6 9.0 1.00
pr_levm_ManyHashes 13.2 ± 0.2 12.9 13.6 1.51 ± 0.03

Benchmark Results: MstoreBench

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_MstoreBench 270.7 ± 4.5 266.8 280.8 1.01 ± 0.02
main_levm_MstoreBench 943.5 ± 5.9 937.1 956.4 3.51 ± 0.04
pr_revm_MstoreBench 268.4 ± 2.9 266.2 276.1 1.00
pr_levm_MstoreBench 898.9 ± 7.7 894.9 920.2 3.35 ± 0.05

Benchmark Results: Push

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Push 297.3 ± 1.1 296.0 299.4 1.00
main_levm_Push 1074.9 ± 8.2 1066.3 1095.6 3.62 ± 0.03
pr_revm_Push 302.5 ± 4.9 298.0 315.7 1.02 ± 0.02
pr_levm_Push 1002.3 ± 10.9 993.1 1031.1 3.37 ± 0.04

Copy link

Benchmark for d86adfa

Click to view benchmark
Test Base PR %
block payload building bench 0.2±0.00ns 0.3±0.00ns +50.00%

Copy link

Benchmark Block Execution Results Comparison Against Main

Command Mean [s] Min [s] Max [s] Relative
base 209.701 ± 2.777 207.066 217.251 1.02 ± 0.01
head 205.772 ± 0.821 204.714 206.818 1.00

@mpaulucci
Copy link
Collaborator

Moving to draft

@mpaulucci mpaulucci marked this pull request as draft August 20, 2025 13:08
@damiramirez
Copy link
Contributor

I think we can close this PR since it didn't give us the results we expected. What do you think, @Oppen?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
L1 Ethereum client L2 Rollup client performance
Projects
Status: Requires Changes
Status: Todo
Development

Successfully merging this pull request may close these issues.

perf: state snapshots
8 participants