Skip to content

Commit c81c252

Browse files
authored
feat: InspectEvm fn renames, inspector docs, book cleanup (#2275)
* feat: InspectEvm fn renames, inspector docs, book cleanup * nits, docs and typos * fix doc
1 parent bba246d commit c81c252

File tree

18 files changed

+522
-389
lines changed

18 files changed

+522
-389
lines changed

.github/workflows/book.yml

+5-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
- name: Run tests
3535
run: |
3636
cp README.md book/src/README.md
37-
sed -i -e 's|../../README.md|README.md|g' book/src/SUMMARY.md
37+
sed -i -e 's|../../README.md|./README.md|g' book/src/SUMMARY.md
3838
mdbook test
3939
4040
lint:
@@ -81,7 +81,10 @@ jobs:
8181
echo `pwd`/mdbook-template >> $GITHUB_PATH
8282
8383
- name: Build book
84-
run: mdbook build book
84+
run: |
85+
cp README.md book/src/README.md
86+
sed -i -e 's|../../README.md|./README.md|g' book/src/SUMMARY.md
87+
mdbook build book
8588
8689
- name: Build docs
8790
run: RUSTDOCFLAGS="--enable-index-page -Zunstable-options" cargo doc --all --no-deps

bins/revme/src/cmd/statetest/runner.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ pub fn execute_test_suite(
426426
);
427427

428428
let timer = Instant::now();
429-
let res = evm.inspect_commit_previous();
429+
let res = evm.inspect_replay_commit();
430430
*elapsed.lock().unwrap() += timer.elapsed();
431431

432432
let spec = cfg.spec();
@@ -498,7 +498,7 @@ pub fn execute_test_suite(
498498
TracerEip3155::buffered(stderr()).without_summary(),
499499
);
500500

501-
let _ = evm.inspect_commit_previous();
501+
let _ = evm.inspect_replay_commit();
502502

503503
println!("\nExecution result: {exec_result:#?}");
504504
println!("\nExpected exception: {:?}", test.expect_exception);

book/src/SUMMARY.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
- [Introduction](./../../README.md)
44
- [Awesome Revm](./awesome.md)
5-
- [Dev section](./dev.md)
65
- [Architecture](./architecture.md)
6+
- [Dev section](./dev.md)
77
- [Revme](./revme.md)
88
- [Release procedure](./release_procedure.md)
99
- [Contact](./contact.md)

book/src/architecture.md

+35-20
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Architecture
1+
# Architecture and API
22

33
REVM is a flexible implementation of the Ethereum Virtual Machine (EVM). It follows the rules of the Ethereum mainnet and stays up to date with changes through hardforks as defined in the official [Ethereum
44
execution specs](https://github.com/ethereum/execution-specs).
@@ -7,26 +7,45 @@ You can use REVM in two main ways:
77
1. Run regular Ethereum transactions using a Execution API
88
2. Create your own custom version of the EVM (for Layer 2 solutions or other chains) using EVM framework
99

10-
The main `revm` library combines all the different crates into one package and reexports them. You can see overview revm crates in [crates folder](https://github.com/bluealloy/revm/tree/main/crates) and overview of examples in [examples folder](https://github.com/bluealloy/revm/tree/main/examples).
10+
To see usage examples you can check the [examples folder](https://github.com/bluealloy/revm/tree/ main/examples). Other than documentation, examples are main resource to see and learn about Revm.
1111

12-
REVM works in no_std environments which means it can be used in zero-knowledge virtual machines (zkVMs). It also has very few external dependencies, which you can read more about in the [dev section](./dev.md).
12+
The main `revm` library combines all crates into one package and reexports them, standalone library are useful if there is need to import functionality with smaller scope. You can see overview of revm crates in [crates folder](https://github.com/bluealloy/revm/tree/main/crates).
13+
14+
REVM works in `no_std` environments which means it can be used in zero-knowledge virtual machines (zkVMs) and it is the standard library in that use case. It also has very few external dependencies.
1315

1416
# Execution API
1517

16-
REVM provides four ways to execute transactions through traits (interfaces).
18+
`Evm` the main structure for executing mainnet ethereum transaction is build with a `Context` and a builder, code for it looks like this:
19+
20+
```rust,ignore
21+
let mut evm = Context::mainnet().with_block(block).build_mainnet();
22+
let out = evm.transact(tx);
23+
```
24+
25+
`Evm` struct contains:
26+
* `Context` - Environment and evm state.
27+
* `Instructions` - EVM opcode implementations
28+
* `Precompiles` - Built-in contract implementations
29+
* `Inspector` - Used for tracing.
1730

18-
The State system builds on the `Database` trait and handles:
19-
- Getting data from external storage
20-
- Managing the EVM's output
21-
- Caching changes when running multiple transactions
31+
And `Context` contains data used in execution:
32+
* Environment data, the data that is known before execution starts are `Transaction`, `Block`, `Cfg`.
33+
* `Journal` is place where internal state is stored. Internal state is returned after execution ends.
34+
* And `Database` is a interface that allows fetching external data that is needed in runtime. That data are account, storage and bytecode. When loaded they are stored in `Journal`
2235

23-
You can implement one of three database interfaces depending on what you need:
36+
REVM provides four ways to execute transactions through traits (API):
2437

25-
- `Database`: Uses a mutable reference (`&mut self`). This is useful when you want to update a cache or track statistics while getting data. Enables basic transaction functions like `transact` and `inspect`.
38+
* `transact(tx)` and `replay()` are function of `ExecuteEvm` trait that allow execution transactions. They return the status of execution with reason, changed state and in of case of failed execution a error.
39+
* `transact_commit(tx)` and `replay_commit()` are part of `ExecuteCommitEvm` that internally commits the state diff to the database and returns status of execution. Database is requires to support `DatabaseCommit` trait.
40+
* `inspect()`, `inspect_replay(tx)` and few others are part of `InspectEvm` trait that allow execution with inspection. This is how tracers are called.
41+
* `inspect_commit()`,`inspect_replay_commit(tx)` that are part of `InspectCommitEvm` trait that extends `InspectEvm` to allow committing state diff after tracing.
2642

27-
- `DatabaseRef`: Uses a regular reference (`&self`). Good for when you only need to read data without making changes. Enables reference-based functions like `transact_ref`.
43+
For inspection API to be enabled `Evm` needs to be create with inspector.
2844

29-
- `Database + DatabaseCommit`: Adds the ability to save transaction changes directly. Enables commit functions like `transact_commit`.
45+
```rust,ignore
46+
let mut evm = Context::mainnet().with_block(block).build_mainnet().with_inspector(inspector);
47+
let _ = evm.inspect_with_tx(tx);
48+
```
3049

3150
# EVM Framework
3251

@@ -38,16 +57,12 @@ Each trait needed to build custom EVM has detailed documentation explaining how
3857

3958
In summary, REVM is built around several key traits that enable customizable EVM functionality. The core traits include:
4059

41-
* **EvmTr**: The core EVM trait that provides access to the main EVM components:
42-
- Context - Environment and state access
43-
- Instructions - EVM opcode implementations
44-
- Precompiles - Built-in contract implementations
45-
- Inspector - Used for tracing, only enabled with `InspectorEvmTr` trait.
46-
* **ContextTr**: Accessed through EvmTr, defines the execution environment including Tx/Block/Journal/Db:
60+
* **EvmTr**: The core EVM trait that provides access to `Context`, `Instruction`, `Precompiles`:
61+
* **ContextTr**: Accessed through EvmTr, defines the execution environment including Tx/Block/Journal/Db.
4762
* **Handler**: Implements the core execution logic, taking an EvmTr implementation. The default implementation follows Ethereum consensus.
4863

4964
And traits that provide support for inspection and tracing:
5065

51-
* **InspectorEvmTr**: Extends EvmTr to enable inspection mode execution with an associated Inspector type
52-
* **InspectorHandler**: Extends Handler with inspection-enabled execution paths that make Inspector callbacks
66+
* **InspectorEvmTr**: Extends EvmTr to enable inspection mode execution with an associated `Inspector` type
67+
* **InspectorHandler**: Extends Handler with inspection-enabled execution paths that make `Inspector` callbacks
5368
* **Inspector**: User-implementable trait for EVM inspection/tracing

book/src/awesome.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ A curated list of excellent Revm-related resources. Feel free to contribute to t
1717
- [**Reth:**](https://github.com/paradigmxyz/reth) A modular, contributor-friendly, and ultra-fast implementation of the Ethereum protocol.
1818
- [**Helios**](https://github.com/a16z/helios) is a trustless, efficient, and portable multichain light client written in Rust.
1919
- [**Trin**](https://github.com/ethereum/trin) is a Rust implementation of a Portal Network client.
20+
-
2021

2122
#### EVM Variants
2223
- [**Optimism**](https://github.com/bluealloy/revm/tree/main/crates/optimism) is a ethereum L2 network.

book/src/dev.md

+1-26
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,4 @@ cargo build --release
99

1010
**_Note:_** This project tends to use the newest rust version, so if you're encountering a build error try running rustup update first.
1111

12-
**_Note:_** `clang` is required for building revm with `c-kzg` or `secp256k1` feature flags as they depend on `C` libraries. If you don't have it installed, you can install it with `apt install clang`.
13-
14-
# External core dependencies
15-
16-
REVM relies on several key external dependencies to provide its core functionality:
17-
18-
* The `alloy-primitives` crate provides essential native types including:
19-
- `ruint` U256 big number type
20-
- Address, Bytes, and B256 types
21-
- `hashbrown` implementations of HashMap/HashSet with custom hashing algorithms
22-
* For broad compatibility, REVM is `no_std` compliant and uses the `alloc` crate for heap allocation needs.
23-
* Precompile functionality requires several cryptography and math libraries:
24-
- `c-kzg`: Implements Polynomial Commitments API for EIP-4844 (C implementation with Rust bindings)
25-
- `modexp`: Handles big integer modular exponentiation
26-
- `secp256k1`: Provides ECDSA public key recovery based on secp256k1 curves
27-
- `k256`: Serves as a no_std compatible fallback for secp256k1
28-
* Transaction environment AccessList and AuthorizationList come from:
29-
- `alloy-eip7702`
30-
- `alloy-eip2930`
31-
* Optional serialization support through feature-flagged:
32-
- `serde`
33-
- `serde-json`
34-
* Various utility crates enhance development:
35-
- `auto_impl`
36-
- `derive_more`
37-
- Specialized libraries like `nnum` for specific use cases
12+
**_Note:_** `clang` is required for building revm with `c-kzg` or `secp256k1` feature flags as they depend on `C` libraries. If you don't have it installed, you can install it with `apt install clang`.

book/src/testing.md

-1
This file was deleted.

crates/context/src/journaled_state/init.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::Journal;
22
use database_interface::EmptyDB;
33

4-
/// A clonable version of JournaledState that uses EmptyDB.
4+
/// A cloneable version of JournaledState that uses EmptyDB.
55
/// Used to clone the journaled state and for initialization of new journaled state.
66
pub type JournalInit = Journal<EmptyDB>;
77

crates/inspector/src/gas.rs

+10
Original file line numberDiff line numberDiff line change
@@ -16,38 +16,47 @@ impl Default for GasInspector {
1616
}
1717

1818
impl GasInspector {
19+
/// Returns the remaining gas.
20+
#[inline]
1921
pub fn gas_remaining(&self) -> u64 {
2022
self.gas_remaining
2123
}
2224

25+
/// Returns the last gas cost.
26+
#[inline]
2327
pub fn last_gas_cost(&self) -> u64 {
2428
self.last_gas_cost
2529
}
2630

31+
/// Create a new gas inspector.
2732
pub fn new() -> Self {
2833
Self {
2934
gas_remaining: 0,
3035
last_gas_cost: 0,
3136
}
3237
}
3338

39+
/// Sets remaining gas to gas limit.
3440
#[inline]
3541
pub fn initialize_interp(&mut self, gas: &Gas) {
3642
self.gas_remaining = gas.limit();
3743
}
3844

45+
/// Sets the remaining gas.
3946
#[inline]
4047
pub fn step(&mut self, gas: &Gas) {
4148
self.gas_remaining = gas.remaining();
4249
}
4350

51+
/// calculate last gas cost and remaining gas.
4452
#[inline]
4553
pub fn step_end(&mut self, gas: &mut Gas) {
4654
let remaining = gas.remaining();
4755
self.last_gas_cost = self.gas_remaining.saturating_sub(remaining);
4856
self.gas_remaining = remaining;
4957
}
5058

59+
/// Spend all gas if call failed.
5160
#[inline]
5261
pub fn call_end(&mut self, outcome: &mut CallOutcome) {
5362
if outcome.result.result.is_error() {
@@ -56,6 +65,7 @@ impl GasInspector {
5665
}
5766
}
5867

68+
/// Spend all gas if create failed.
5969
#[inline]
6070
pub fn create_end(&mut self, outcome: &mut CreateOutcome) {
6171
if outcome.result.result.is_error() {

0 commit comments

Comments
 (0)