Skip to content

Conversation

@mpaulucci
Copy link
Collaborator

@mpaulucci mpaulucci commented Mar 25, 2025

Motivation
L2 code was accessing internal apis from the vm crate, specifically revm constructs. This is attempt to replace those with the public api, so that we can easily switch between revm and levm.

Description

  • Replaces references to ethrex_vm::backends:: from the prover backends.
  • Moved ExecutionDB to vm/db.rs. It is still somewhat coupled with revm but less than before. It should be totally decoupled.

@github-actions
Copy link

github-actions bot commented Mar 25, 2025

Lines of code report

Total lines added: 323
Total lines removed: 401
Total lines changed: 724

Detailed view
+----------------------------------------------------------+-------+------+
| File                                                     | Lines | Diff |
+----------------------------------------------------------+-------+------+
| ethrex/cmd/ef_tests/state/report.rs                      | 923   | +1   |
+----------------------------------------------------------+-------+------+
| ethrex/cmd/ef_tests/state/runner/levm_runner.rs          | 366   | -4   |
+----------------------------------------------------------+-------+------+
| ethrex/cmd/ef_tests/state/runner/mod.rs                  | 287   | +6   |
+----------------------------------------------------------+-------+------+
| ethrex/cmd/ef_tests/state/runner/revm_runner.rs          | 525   | -19  |
+----------------------------------------------------------+-------+------+
| ethrex/cmd/ef_tests/state/utils.rs                       | 80    | +3   |
+----------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/payload.rs                      | 544   | +1   |
+----------------------------------------------------------+-------+------+
| ethrex/crates/l2/prover/src/backends/exec.rs             | 60    | -1   |
+----------------------------------------------------------+-------+------+
| ethrex/crates/l2/prover/zkvm/interface/risc0/src/main.rs | 45    | -3   |
+----------------------------------------------------------+-------+------+
| ethrex/crates/l2/prover/zkvm/interface/sp1/src/main.rs   | 46    | -9   |
+----------------------------------------------------------+-------+------+
| ethrex/crates/l2/sequencer/prover_server.rs              | 542   | -1   |
+----------------------------------------------------------+-------+------+
| ethrex/crates/l2/utils/prover/save_state.rs              | 410   | -3   |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/backends/levm/db.rs                     | 130   | +65  |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/backends/levm/mod.rs                    | 481   | -87  |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/backends/mod.rs                         | 255   | -84  |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/backends/revm/db.rs                     | 361   | +41  |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/backends/revm/mod.rs                    | 615   | -1   |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/db.rs                                   | 142   | +90  |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/errors.rs                               | 119   | +2   |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/levm/bench/revm_comparison/src/lib.rs   | 172   | +87  |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/levm/src/db/error.rs                    | 6     | +6   |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/levm/src/db/mod.rs                      | 23    | -39  |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/levm/src/execution_handlers.rs          | 234   | -11  |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/levm/src/hooks/default_hook.rs          | 289   | -21  |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/levm/src/lib.rs                         | 18    | -1   |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/levm/src/opcode_handlers/block.rs       | 206   | -2   |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/levm/src/opcode_handlers/environment.rs | 343   | -16  |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/levm/src/opcode_handlers/system.rs      | 652   | -75  |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/levm/src/utils.rs                       | 534   | -20  |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/levm/src/vm.rs                          | 439   | +21  |
+----------------------------------------------------------+-------+------+
| ethrex/crates/vm/lib.rs                                  | 11    | -4   |
+----------------------------------------------------------+-------+------+

Base automatically changed from refactor-vm to main March 25, 2025 13:01
@github-actions
Copy link

github-actions bot commented Mar 27, 2025

Benchmark Results Comparison

PR Results

Benchmark Results: Factorial

Command Mean [ms] Min [ms] Max [ms] Relative
revm_Factorial 236.7 ± 5.3 232.8 251.1 1.00
levm_Factorial 797.9 ± 5.5 792.1 806.7 3.37 ± 0.08

Benchmark Results: Factorial - Recursive

Command Mean [s] Min [s] Max [s] Relative
revm_FactorialRecursive 1.422 ± 0.081 1.324 1.548 1.00
levm_FactorialRecursive 13.853 ± 0.204 13.686 14.123 9.74 ± 0.57

Benchmark Results: Fibonacci

Command Mean [ms] Min [ms] Max [ms] Relative
revm_Fibonacci 205.4 ± 1.8 204.0 209.9 1.00
levm_Fibonacci 787.7 ± 5.9 776.6 796.0 3.84 ± 0.04

Benchmark Results: ManyHashes

Command Mean [ms] Min [ms] Max [ms] Relative
revm_ManyHashes 8.7 ± 0.1 8.6 8.9 1.00
levm_ManyHashes 16.4 ± 0.3 16.1 17.0 1.89 ± 0.04

Benchmark Results: BubbleSort

Command Mean [s] Min [s] Max [s] Relative
revm_BubbleSort 3.208 ± 0.024 3.187 3.270 1.00
levm_BubbleSort 5.636 ± 0.044 5.565 5.696 1.76 ± 0.02

Benchmark Results: ERC20 - Transfer

Command Mean [ms] Min [ms] Max [ms] Relative
revm_ERC20Transfer 248.6 ± 2.4 246.1 252.9 1.00
levm_ERC20Transfer 482.9 ± 4.1 476.9 487.7 1.94 ± 0.02

Benchmark Results: ERC20 - Mint

Command Mean [ms] Min [ms] Max [ms] Relative
revm_ERC20Mint 141.3 ± 0.8 139.9 142.6 1.00
levm_ERC20Mint 314.8 ± 4.8 310.1 326.2 2.23 ± 0.04

Benchmark Results: ERC20 - Approval

Command Mean [s] Min [s] Max [s] Relative
revm_ERC20Approval 1.048 ± 0.011 1.037 1.069 1.00
levm_ERC20Approval 1.839 ± 0.018 1.813 1.864 1.76 ± 0.03

Main Results

Benchmark Results: Factorial

Command Mean [ms] Min [ms] Max [ms] Relative
revm_Factorial 241.0 ± 0.7 239.9 241.9 1.00
levm_Factorial 921.1 ± 10.3 913.3 948.0 3.82 ± 0.04

Benchmark Results: Factorial - Recursive

Command Mean [s] Min [s] Max [s] Relative
revm_FactorialRecursive 1.493 ± 0.080 1.396 1.595 1.00
levm_FactorialRecursive 15.797 ± 0.063 15.700 15.908 10.58 ± 0.57

Benchmark Results: Fibonacci

Command Mean [ms] Min [ms] Max [ms] Relative
revm_Fibonacci 216.5 ± 10.0 206.4 235.0 1.00
levm_Fibonacci 913.6 ± 8.8 906.7 934.7 4.22 ± 0.20

Benchmark Results: ManyHashes

Command Mean [ms] Min [ms] Max [ms] Relative
revm_ManyHashes 8.7 ± 0.1 8.6 8.9 1.00
levm_ManyHashes 18.4 ± 0.2 18.1 19.0 2.11 ± 0.03

Benchmark Results: BubbleSort

Command Mean [s] Min [s] Max [s] Relative
revm_BubbleSort 3.257 ± 0.088 3.192 3.483 1.00
levm_BubbleSort 6.191 ± 0.057 6.137 6.328 1.90 ± 0.05

Benchmark Results: ERC20 - Transfer

Command Mean [ms] Min [ms] Max [ms] Relative
revm_ERC20Transfer 247.8 ± 5.2 243.8 259.3 1.00
levm_ERC20Transfer 532.8 ± 5.8 526.7 545.2 2.15 ± 0.05

Benchmark Results: ERC20 - Mint

Command Mean [ms] Min [ms] Max [ms] Relative
revm_ERC20Mint 142.2 ± 5.6 139.4 158.1 1.00
levm_ERC20Mint 346.2 ± 2.3 343.0 350.6 2.44 ± 0.10

Benchmark Results: ERC20 - Approval

Command Mean [s] Min [s] Max [s] Relative
revm_ERC20Approval 1.024 ± 0.005 1.018 1.035 1.00
levm_ERC20Approval 2.015 ± 0.015 1.987 2.036 1.97 ± 0.02

Copy link
Contributor

@JereSalo JereSalo left a comment

Choose a reason for hiding this comment

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

I know it is still in draft but I reviewed all the code and left some comments :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Are we 100% sure that we want to delete these tests? I know we are not currently running them. The only case in which I consider them to be useful is for debugging purposes when modifying opcodes behavior (e.g. for improving performance) when the EF Tests are not descriptive enough.
It is not a big deal though.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The tests were useful to us before we integrated with the EF tests; now that we've done that there's not much point in keeping them, and considering they rely on a separate trait (Db) that's only used for them I think it's just better to delete them

}
}

pub fn from_execution_db(db: ExecutionDB) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we can send EvmEngine as parameter too when we call this so that both implementations for LEVM and REVM are available.

Copy link
Contributor

Choose a reason for hiding this comment

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

Of course this would mean having access to that variable within the provers and I don't know if we want that.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The idea is to transition to support just levm for the prover, as for L2 for example we won't be able to prove all we need to prove using revm anyway, and maintaining support for both vms on the prover just adds more work


pub fn from_execution_db(db: ExecutionDB) -> Self {
Evm::LEVM {
store_wrapper: Arc::new(db),
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we change the name store_wrapper for something else now that the DB can be either a StoreWrapper or ExecutionDB?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Check this PR first because things have changed over there #2371

#[test]
fn test_state_file_integration(
evm_engine: EvmEngine,
_evm_engine: EvmEngine,
Copy link
Contributor

Choose a reason for hiding this comment

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

We can use this evm_engine if when instantiating the Blockchain struct so that the test runs for both LEVM and REVM.
Instead of
let blockchain = Blockchain::default_with_store(store.clone());
We could do:
let blockchain = Blockchain::new(evm_engine, store.clone());

With the current implementation it would only run with REVM because it is the default engine.

Comment on lines 98 to 112
fn get_chain_config(&self) -> ethrex_common::types::ChainConfig {
self.get_chain_config()
}

fn get_account_info_by_hash(
&self,
_block_hash: ethrex_common::types::BlockHash,
_address: CoreAddress,
) -> Option<ethrex_common::types::AccountInfo> {
unreachable!()
}

fn get_account_code(&self, _code_hash: CoreH256) -> Option<bytes::Bytes> {
unreachable!()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I personally don't like the fact that we are adding methods to the trait LevmDatabase that aren't actually used inside the VM but I understand that it makes things way more simple.
If someday we want to make a crate out of LEVM, we'll need to refactor this.

Copy link
Collaborator

@jrchatruc jrchatruc Apr 1, 2025

Choose a reason for hiding this comment

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

I agree, but preferred to keep it for another refactor PR, since I'm not sure yet how we want to go about it (also just in case, these unreachable! calls were replaced by errors on this PR #2371)

jrchatruc and others added 3 commits April 1, 2025 15:49
**Motivation**

This PR refactors levm introducing a `GeneralizedDatabase` (the name is
not the best, suggestions are welcome), which is simply the combination
of the regular store (i.e. the on-disk database) and the cache (the in
memory structure we use to keep track of changes done to accounts as
execution happens).

More importantly, it makes levm (the `VM` struct) hold a mutable
reference to said database instead of a regular owned value. This is to
bring the levm api more in line to what we need it to be for ethrex; the
main problem we are solving is to be able to run multiple transactions
while keeping the underlying cache changes from those transactions. Once
we are done with execution (because we've finished executing or building
the block or group of blocks), calling `get_state_transitions` will
drain the cachedb for all the account updates and return them.

This change allowed, among other things, to implement for levm the
previously uninplemented function
`execute_block_without_clearing_state`, which is used for syncing.

Additionally, this PR introduces error handling for the levm `Database`
trait; previously its member functions did not return errors and we were
just unwrapping on some of their implementations.

**Description**

<!-- A clear and concise general description of the changes this PR
introduces -->

<!-- Link to issues: Resolves #111, Resolves #222 -->

Closes #issue_number

---------

Co-authored-by: Jeremías Salomón <48994069+JereSalo@users.noreply.github.com>
Co-authored-by: JereSalo <jeresalo17@gmail.com>
Co-authored-by: Martin Paulucci <martin.c.paulucci@gmail.com>
Co-authored-by: fmoletta <99273364+fmoletta@users.noreply.github.com>
@jrchatruc jrchatruc marked this pull request as ready for review April 3, 2025 15:09
@jrchatruc jrchatruc requested a review from a team as a code owner April 3, 2025 15:09
@jrchatruc jrchatruc enabled auto-merge April 3, 2025 15:12
@jrchatruc jrchatruc added this pull request to the merge queue Apr 3, 2025
Merged via the queue into main with commit 99c5440 Apr 3, 2025
48 checks passed
@jrchatruc jrchatruc deleted the fix-leak-zkvm branch April 3, 2025 15:42
pedrobergamini pushed a commit to pedrobergamini/ethrex that referenced this pull request Aug 24, 2025
**Motivation**
L2 code was accessing internal apis from the vm crate, specifically
`revm` constructs. This is attempt to replace those with the public api,
so that we can easily switch between revm and levm.

**Description**
- Replaces references to `ethrex_vm::backends::` from the prover
backends.
- Moved `ExecutionDB ` to `vm/db.rs`. It is still somewhat coupled with
revm but less than before. It should be totally decoupled.

---------

Co-authored-by: Javier Chatruc <jrchatruc@gmail.com>
Co-authored-by: Javier Rodríguez Chatruc <49622509+jrchatruc@users.noreply.github.com>
Co-authored-by: Jeremías Salomón <48994069+JereSalo@users.noreply.github.com>
Co-authored-by: JereSalo <jeresalo17@gmail.com>
Co-authored-by: fmoletta <99273364+fmoletta@users.noreply.github.com>
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.

4 participants