Skip to content

Commit

Permalink
feat: introducing EvmWiring, a chain-specific configuration (#1672)
Browse files Browse the repository at this point in the history
* refactor: allow chain-specific configuration of Evm

* refactor: rename Transaction::transact_to and clarify docs

* refactor: remove trait bounds on Transaction super trait

* refactor: remove trait bounds from Block supertrait

* fix: clippy warnings

* fix: cargo doc

* refactor: limit trait bounds on HaltReason

* refactor: allow moving of kind

* refactor: rename Transaction::nonce to nonce_opt to signal that it's optional

* refactor: replace AccessList with alloy version

* refactor: rename gas_priority_fee to max_priority_fee_per_gas

* refactor: correct trait bound on ExecutionResult::clone

* Clone

* refactor: only allow optional nonce check via CfgEnv

* fix: revme

* refactor: derive DummyHost

* refactor: derive Clone for ExecutionResult

* refactor: remove EVMErrorForChain

* refactor: derive Clone for CfgEnvWithChainSpec

* refactor: use EVMResultGeneric

* refactor: add convenience EVMErrorForChain type alias

* feat: export OptimismBlock

* refactor: add handler constructor and Context to revm::ChainSpec

* refactor: generalise optimism implementation using traits

* fix: no-default-features

* fix: CI

* chore: Add default fn to Tx/Block traits

* Chore: rename ChainSpec to EvmWiring

* chore: clippy comments fix

* chore: rename EthEvmWiring to EthereumWiring

* chore: re add serde, restring HaltReasonTrait

* chore: move custom opcode to examples

* chore: remove op feature from test wiring

* nit use Self::EvmWiringT

* nit indents

* feat(Wiring): Add Database and EXT to EvmWiring

* some fixes

* temp

* feat: make builder compile. EnvWiring and Result Halt

* chore: cleanup rename

* nit

* fix: make string conversion complete

* fix compile

* compiles

* wip builder

* wip

* fix compile

* wip

* fix optimism test

* fix docs ci

* cleanup

* cleanup

* use core::error::Error

* cleanup

* use core error

* fix builer

* fix docs

* final doc fix

* rm alloy provider

---------

Co-authored-by: rakita <[email protected]>
  • Loading branch information
Wodann and rakita authored Sep 9, 2024
1 parent f68d3dc commit 077c2c3
Show file tree
Hide file tree
Showing 92 changed files with 3,965 additions and 2,553 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ jobs:
strategy:
fail-fast: false
matrix:
features: ["", "optimism,kzg-rs"]
features: ["", "kzg-rs"]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: riscv32imac-unknown-none-elf
- run: cargo check --target riscv32imac-unknown-none-elf --no-default-features --features=${{ matrix.features }}
- run: |
cargo check --target riscv32imac-unknown-none-elf --no-default-features --features=${{ matrix.features }}
cargo check --target riscv32imac-unknown-none-elf -p revm-optimism --no-default-features --features=${{ matrix.features }}
check:
name: check ${{ matrix.features }}
Expand Down
29 changes: 28 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = [
"crates/primitives",
"crates/interpreter",
"crates/precompile",
"crates/optimism",
]
resolver = "2"
default-members = ["crates/revm"]
Expand Down
6 changes: 3 additions & 3 deletions bins/revm-test/src/bin/analysis.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use revm::{
db::BenchmarkDB,
db::{BenchmarkDB, EthereumBenchmarkWiring},
interpreter::analysis::to_analysed,
primitives::{address, bytes, Bytecode, Bytes, TxKind},
Evm,
Expand All @@ -13,7 +13,7 @@ fn main() {
let bytecode_analysed = to_analysed(Bytecode::new_raw(contract_data));

// BenchmarkDB is dummy state that implements Database trait.
let mut evm = Evm::builder()
let mut evm = Evm::<EthereumBenchmarkWiring>::builder()
.modify_tx_env(|tx| {
// execution globals block hash/gas_limit/coinbase/timestamp..
tx.caller = address!("1000000000000000000000000000000000000000");
Expand All @@ -37,7 +37,7 @@ fn main() {

let mut evm = evm
.modify()
.reset_handler_with_db(BenchmarkDB::new_bytecode(bytecode_analysed))
.with_db(BenchmarkDB::new_bytecode(bytecode_analysed))
.build();

let timer = Instant::now();
Expand Down
8 changes: 5 additions & 3 deletions bins/revm-test/src/bin/burntpix/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use regex::bytes::Regex;
use revm::{
db::{CacheDB, EmptyDB},
primitives::{
address, hex, keccak256, AccountInfo, Address, Bytecode, Bytes, ExecutionResult, Output,
TxKind, B256, U256,
address, hex, keccak256, AccountInfo, Address, Bytecode, Bytes, EthereumWiring,
ExecutionResult, Output, TxKind, B256, U256,
},
Evm,
};
Expand All @@ -28,14 +28,16 @@ sol! {
}
}

type EthereumCacheDbWiring = EthereumWiring<CacheDB<EmptyDB>, ()>;

fn main() {
let (seed, iterations) = try_init_env_vars().expect("Failed to parse env vars");

let run_call_data = IBURNTPIX::runCall { seed, iterations }.abi_encode();

let db = init_db();

let mut evm = Evm::builder()
let mut evm = Evm::<EthereumCacheDbWiring>::builder()
.modify_tx_env(|tx| {
tx.caller = address!("1000000000000000000000000000000000000000");
tx.transact_to = TxKind::Call(BURNTPIX_MAIN_ADDRESS);
Expand Down
4 changes: 2 additions & 2 deletions bins/revm-test/src/bin/snailtracer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use revm::{
db::BenchmarkDB,
db::{BenchmarkDB, EthereumBenchmarkWiring},
interpreter::analysis::to_analysed,
primitives::{address, bytes, Bytecode, Bytes, TxKind},
Evm,
Expand All @@ -9,7 +9,7 @@ pub fn simple_example() {
let bytecode = to_analysed(Bytecode::new_raw(CONTRACT_DATA.clone()));

// BenchmarkDB is dummy state that implements Database trait.
let mut evm = Evm::builder()
let mut evm = Evm::<EthereumBenchmarkWiring>::builder()
.with_db(BenchmarkDB::new_bytecode(bytecode.clone()))
.modify_tx_env(|tx| {
// execution globals block hash/gas_limit/coinbase/timestamp..
Expand Down
5 changes: 2 additions & 3 deletions bins/revm-test/src/bin/transfer.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use revm::{
db::BenchmarkDB,
db::{BenchmarkDB, EthereumBenchmarkWiring},
primitives::{Bytecode, TxKind, U256},
Evm,
};

use std::time::Duration;

fn main() {
// BenchmarkDB is dummy state that implements Database trait.
let mut evm = Evm::builder()
let mut evm = Evm::<EthereumBenchmarkWiring>::builder()
.with_db(BenchmarkDB::new_bytecode(Bytecode::new()))
.modify_tx_env(|tx| {
// execution globals block hash/gas_limit/coinbase/timestamp..
Expand Down
26 changes: 14 additions & 12 deletions bins/revme/src/cmd/evmrunner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use revm::{
db::BenchmarkDB,
inspector_handle_register,
inspectors::TracerEip3155,
primitives::{Address, Bytecode, BytecodeDecodeError, TxKind},
Evm,
primitives::{address, Address, Bytecode, BytecodeDecodeError, EthereumWiring, TxKind},
Database, Evm,
};
use std::io::Error as IoError;
use std::path::PathBuf;
Expand Down Expand Up @@ -57,6 +57,8 @@ pub struct Cmd {
impl Cmd {
/// Run evm runner command.
pub fn run(&self) -> Result<(), Errors> {
const CALLER: Address = address!("0000000000000000000000000000000000000001");

let bytecode_str: Cow<'_, str> = if let Some(path) = &self.path {
// check if path exists.
if !path.exists() {
Expand All @@ -71,19 +73,21 @@ impl Cmd {
let input = hex::decode(self.input.trim())
.map_err(|_| Errors::InvalidInput)?
.into();

let mut db = BenchmarkDB::new_bytecode(Bytecode::new_raw_checked(bytecode.into())?);

let nonce = db.basic(CALLER).unwrap().map_or(0, |account| account.nonce);

// BenchmarkDB is dummy state that implements Database trait.
// the bytecode is deployed at zero address.
let mut evm = Evm::builder()
.with_db(BenchmarkDB::new_bytecode(Bytecode::new_raw_checked(
bytecode.into(),
)?))
let mut evm = Evm::<EthereumWiring<BenchmarkDB, TracerEip3155>>::builder()
.with_db(db)
.modify_tx_env(|tx| {
// execution globals block hash/gas_limit/coinbase/timestamp..
tx.caller = "0x0000000000000000000000000000000000000001"
.parse()
.unwrap();
tx.caller = CALLER;
tx.transact_to = TxKind::Call(Address::ZERO);
tx.data = input;
tx.nonce = nonce;
})
.build();

Expand All @@ -101,9 +105,7 @@ impl Cmd {
let out = if self.trace {
let mut evm = evm
.modify()
.reset_handler_with_external_context(TracerEip3155::new(
Box::new(std::io::stdout()),
))
.with_external_context(TracerEip3155::new(Box::new(std::io::stdout())))
.append_handler_register(inspector_handle_register)
.build();

Expand Down
51 changes: 28 additions & 23 deletions bins/revme/src/cmd/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ use super::{
};
use indicatif::{ProgressBar, ProgressDrawTarget};
use revm::{
db::EmptyDB,
db::{EmptyDB, State},
inspector_handle_register,
inspectors::TracerEip3155,
interpreter::analysis::to_analysed,
primitives::{
calc_excess_blob_gas, keccak256, Bytecode, Bytes, EVMResultGeneric, Env, ExecutionResult,
SpecId, TxKind, B256,
calc_excess_blob_gas, keccak256, Bytecode, Bytes, EVMResultGeneric, EnvWiring,
EthereumWiring, ExecutionResult, HaltReason, SpecId, TxKind, B256,
},
Evm, State,
Evm,
};
use serde_json::json;
use std::{
convert::Infallible,
fmt::Debug,
io::{stderr, stdout},
path::{Path, PathBuf},
sync::{
Expand All @@ -29,6 +29,9 @@ use std::{
use thiserror::Error;
use walkdir::{DirEntry, WalkDir};

type ExecEvmWiring<'a> = EthereumWiring<&'a mut State<EmptyDB>, ()>;
type TraceEvmWiring<'a> = EthereumWiring<&'a mut State<EmptyDB>, TracerEip3155>;

#[derive(Debug, Error)]
#[error("Test {name} failed: {kind}")]
pub struct TestError {
Expand Down Expand Up @@ -135,12 +138,15 @@ fn skip_test(path: &Path) -> bool {
)
}

fn check_evm_execution<EXT>(
fn check_evm_execution<EXT: Debug>(
test: &Test,
expected_output: Option<&Bytes>,
test_name: &str,
exec_result: &EVMResultGeneric<ExecutionResult, Infallible>,
evm: &Evm<'_, EXT, &mut State<EmptyDB>>,
exec_result: &EVMResultGeneric<
ExecutionResult<HaltReason>,
EthereumWiring<&mut State<EmptyDB>, EXT>,
>,
evm: &Evm<'_, EthereumWiring<&mut State<EmptyDB>, EXT>>,
print_json_outcome: bool,
) -> Result<(), TestError> {
let logs_root = log_rlp_hash(exec_result.as_ref().map(|r| r.logs()).unwrap_or_default());
Expand All @@ -164,7 +170,7 @@ fn check_evm_execution<EXT>(
Err(e) => e.to_string(),
},
"postLogsHash": logs_root,
"fork": evm.handler.cfg().spec_id,
"fork": evm.handler.spec_id(),
"test": test_name,
"d": test.indexes.data,
"g": test.indexes.gas,
Expand Down Expand Up @@ -277,7 +283,7 @@ pub fn execute_test_suite(
cache_state.insert_account_with_storage(address, acc_info, info.storage);
}

let mut env = Box::<Env>::default();
let mut env = Box::<EnvWiring<ExecEvmWiring>>::default();
// for mainnet
env.cfg.chain_id = 1;
// env.cfg.spec_id is set down the road
Expand Down Expand Up @@ -355,6 +361,8 @@ pub fn execute_test_suite(
.get(test.indexes.data)
.unwrap()
.clone();

env.tx.nonce = u64::try_from(unit.transaction.nonce).unwrap();
env.tx.value = unit.transaction.value[test.indexes.value];

env.tx.access_list = unit
Expand All @@ -376,16 +384,14 @@ pub fn execute_test_suite(
env.tx.transact_to = to;

let mut cache = cache_state.clone();
cache.set_state_clear_flag(SpecId::enabled(
spec_id,
revm::primitives::SpecId::SPURIOUS_DRAGON,
));
cache.set_state_clear_flag(SpecId::enabled(spec_id, SpecId::SPURIOUS_DRAGON));
let mut state = revm::db::State::builder()
.with_cached_prestate(cache)
.with_bundle_update()
.build();
let mut evm = Evm::builder()
let mut evm = Evm::<ExecEvmWiring>::builder()
.with_db(&mut state)
.with_default_ext_ctx()
.modify_env(|e| e.clone_from(&env))
.with_spec_id(spec_id)
.build();
Expand All @@ -394,7 +400,8 @@ pub fn execute_test_suite(
let (e, exec_result) = if trace {
let mut evm = evm
.modify()
.reset_handler_with_external_context(
.reset_handler_with_external_context::<EthereumWiring<_, TracerEip3155>>()
.with_external_context(
TracerEip3155::new(Box::new(stderr())).without_summary(),
)
.append_handler_register(inspector_handle_register)
Expand Down Expand Up @@ -445,21 +452,19 @@ pub fn execute_test_suite(

// re build to run with tracing
let mut cache = cache_state.clone();
cache.set_state_clear_flag(SpecId::enabled(
spec_id,
revm::primitives::SpecId::SPURIOUS_DRAGON,
));
let state = revm::db::State::builder()
cache.set_state_clear_flag(SpecId::enabled(spec_id, SpecId::SPURIOUS_DRAGON));
let mut state = revm::db::State::builder()
.with_cached_prestate(cache)
.with_bundle_update()
.build();

let path = path.display();
println!("\nTraces:");
let mut evm = Evm::builder()
let mut evm = Evm::<TraceEvmWiring>::builder()
.with_db(&mut state)
.with_spec_id(spec_id)
.with_db(state)
.with_env(env.clone())
.reset_handler_with_external_context::<EthereumWiring<_, TracerEip3155>>()
.with_external_context(TracerEip3155::new(Box::new(stdout())).without_summary())
.append_handler_register(inspector_handle_register)
.build();
Expand Down
11 changes: 1 addition & 10 deletions crates/interpreter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ all = "warn"
[dependencies]
revm-primitives = { path = "../primitives", version = "9.0.1", default-features = false }

derive-where = { version = "1.2.7", default-features = false }
paste = { version = "1.0", optional = true }
phf = { version = "0.11", default-features = false, optional = true, features = [
"macros",
Expand All @@ -50,16 +51,6 @@ asm-keccak = ["revm-primitives/asm-keccak"]
portable = ["revm-primitives/portable"]
parse = ["dep:paste", "dep:phf"]

optimism = ["revm-primitives/optimism"]
# Optimism default handler enabled Optimism handler register by default in EvmBuilder.
optimism-default-handler = [
"optimism",
"revm-primitives/optimism-default-handler",
]
negate-optimism-default-handler = [
"revm-primitives/negate-optimism-default-handler",
]

dev = [
"memory_limit",
"optional_balance_check",
Expand Down
Loading

0 comments on commit 077c2c3

Please sign in to comment.