Skip to content

Commit

Permalink
feat: EthHandler trait (#2001)
Browse files Browse the repository at this point in the history
* feat: EthHandler trait

* work work

* frame contexts

* inspector compiled

* transact_main and transact_main_commit

* Generalize InterpreterTypes

* big cleanup, rm all partial handlers

* compile

* Some cleanup

* some cleanup

* Erc20 example, need to fix logic

* fix erc20 example

* cleanup and testing

* fix eip7702 order, pass all devnet tests

* fix compilation

* docs
  • Loading branch information
rakita authored Jan 21, 2025
1 parent 25512fd commit 34bc873
Show file tree
Hide file tree
Showing 73 changed files with 1,848 additions and 2,544 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

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

8 changes: 3 additions & 5 deletions bins/revme/src/cmd/bench/analysis.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use database::BenchmarkDB;
use revm::{
bytecode::Bytecode,
handler::EthHandler,
primitives::{address, bytes, hex, Bytes, TxKind},
Context, MainEvm,
transact_main, Context,
};

const BYTES: &str = include_str!("analysis.hex");
Expand All @@ -12,7 +11,7 @@ pub fn run() {
let bytecode = Bytecode::new_raw(Bytes::from(hex::decode(BYTES).unwrap()));

// BenchmarkDB is dummy state that implements Database trait.
let context = Context::builder()
let mut context = Context::builder()
.with_db(BenchmarkDB::new_bytecode(bytecode))
.modify_tx_chained(|tx| {
// Execution globals block hash/gas_limit/coinbase/timestamp..
Expand All @@ -21,6 +20,5 @@ pub fn run() {
//evm.env.tx.data = Bytes::from(hex::decode("30627b7c").unwrap());
tx.data = bytes!("8035F0CE");
});
let mut evm = MainEvm::new(context, EthHandler::default());
let _ = evm.transact().unwrap();
let _ = transact_main(&mut context);
}
8 changes: 3 additions & 5 deletions bins/revme/src/cmd/bench/burntpix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ use database::CacheDB;
use revm::{
context_interface::result::{ExecutionResult, Output},
database_interface::EmptyDB,
handler::EthHandler,
primitives::{address, hex, keccak256, Address, Bytes, TxKind, B256, U256},
state::{AccountInfo, Bytecode},
Context, MainEvm,
transact_main, Context,
};

use std::fs::File;
Expand All @@ -37,16 +36,15 @@ pub fn run() {

let db = init_db();

let context = Context::builder().with_db(db).modify_tx_chained(|tx| {
let mut context = Context::builder().with_db(db).modify_tx_chained(|tx| {
tx.caller = address!("1000000000000000000000000000000000000000");
tx.kind = TxKind::Call(BURNTPIX_MAIN_ADDRESS);
tx.data = run_call_data.clone().into();
tx.gas_limit = u64::MAX;
});
let mut evm = MainEvm::new(context, EthHandler::default());

let started = Instant::now();
let tx_result = evm.transact().unwrap().result;
let tx_result = transact_main(&mut context).unwrap().result;
let return_data = match tx_result {
ExecutionResult::Success {
output, gas_used, ..
Expand Down
8 changes: 3 additions & 5 deletions bins/revme/src/cmd/bench/snailtracer.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use database::BenchmarkDB;
use revm::{
bytecode::Bytecode,
handler::EthHandler,
primitives::{address, bytes, hex, Bytes, TxKind},
Context, MainEvm,
transact_main, Context,
};

pub fn simple_example(bytecode: Bytecode) {
let context = Context::builder()
let mut context = Context::builder()
.with_db(BenchmarkDB::new_bytecode(bytecode.clone()))
.modify_tx_chained(|tx| {
// Execution globals block hash/gas_limit/coinbase/timestamp..
Expand All @@ -16,8 +15,7 @@ pub fn simple_example(bytecode: Bytecode) {
tx.data = bytes!("30627b7c");
tx.gas_limit = 1_000_000_000;
});
let mut evm = MainEvm::new(context, EthHandler::default());
let _ = evm.transact().unwrap();
let _ = transact_main(&mut context).unwrap();
}

pub fn run() {
Expand Down
9 changes: 3 additions & 6 deletions bins/revme/src/cmd/bench/transfer.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use database::BenchmarkDB;
use revm::{
bytecode::Bytecode,
handler::EthHandler,
primitives::{TxKind, U256},
Context, MainEvm,
transact_main, Context,
};

pub fn run() {
let context = Context::builder()
let mut context = Context::builder()
.with_db(BenchmarkDB::new_bytecode(Bytecode::new()))
.modify_tx_chained(|tx| {
// Execution globals block hash/gas_limit/coinbase/timestamp..
Expand All @@ -21,7 +20,5 @@ pub fn run() {
.unwrap(),
);
});
let mut evm = MainEvm::new(context, EthHandler::default());

let _ = evm.transact().unwrap();
let _ = transact_main(&mut context);
}
38 changes: 15 additions & 23 deletions bins/revme/src/cmd/evmrunner.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
use clap::Parser;
use database::BenchmarkDB;
use inspector::{
inspector_context::InspectorContext, inspector_handler, inspectors::TracerEip3155,
InspectorMainEvm,
};
use inspector::{inspect_main, inspector_context::InspectorContext, inspectors::TracerEip3155};
use revm::{
bytecode::{Bytecode, BytecodeDecodeError},
handler::EthHandler,
primitives::{address, hex, Address, TxKind},
Context, Database, EvmExec, MainEvm,
transact_main, Context, Database,
};
use std::io::Error as IoError;
use std::path::PathBuf;
Expand Down Expand Up @@ -86,36 +82,32 @@ impl Cmd {

// BenchmarkDB is dummy state that implements Database trait.
// The bytecode is deployed at zero address.
let mut evm = MainEvm::new(
Context::builder().with_db(db).modify_tx_chained(|tx| {
tx.caller = CALLER;
tx.kind = TxKind::Call(Address::ZERO);
tx.data = input;
tx.nonce = nonce;
}),
EthHandler::default(),
);
let mut ctx = Context::builder().with_db(db).modify_tx_chained(|tx| {
tx.caller = CALLER;
tx.kind = TxKind::Call(Address::ZERO);
tx.data = input;
tx.nonce = nonce;
});

if self.bench {
// Microbenchmark
let bench_options = microbench::Options::default().time(Duration::from_secs(3));

microbench::bench(&bench_options, "Run bytecode", || {
let _ = evm.transact().unwrap();
let _ = transact_main(&mut ctx).unwrap();
});

return Ok(());
}

let out = if self.trace {
let mut evm = InspectorMainEvm::new(
InspectorContext::new(evm.context, TracerEip3155::new(Box::new(std::io::stdout()))),
inspector_handler(),
);

evm.exec().map_err(|_| Errors::EVMError)?
inspect_main(&mut InspectorContext::new(
&mut ctx,
TracerEip3155::new(Box::new(std::io::stdout())),
))
.map_err(|_| Errors::EVMError)?
} else {
let out = evm.transact().map_err(|_| Errors::EVMError)?;
let out = transact_main(&mut ctx).map_err(|_| Errors::EVMError)?;
println!("Result: {:#?}", out.result);
out
};
Expand Down
70 changes: 27 additions & 43 deletions bins/revme/src/cmd/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ use super::{
use database::State;
use indicatif::{ProgressBar, ProgressDrawTarget};
use inspector::{
inspector_context::InspectorContext, inspector_handler, inspectors::TracerEip3155,
InspectorMainEvm,
inspect_main_commit, inspector_context::InspectorContext, inspectors::TracerEip3155,
};
use revm::{
bytecode::Bytecode,
Expand All @@ -17,10 +16,9 @@ use revm::{
Cfg,
},
database_interface::EmptyDB,
handler::EthHandler,
primitives::{keccak256, Bytes, TxKind, B256},
specification::{eip4844::TARGET_BLOB_GAS_PER_BLOCK_CANCUN, hardfork::SpecId},
Context, DatabaseCommit, EvmCommit, MainEvm,
transact_main_commit, Context,
};
use serde_json::json;
use statetest_types::{SpecName, Test, TestSuite};
Expand Down Expand Up @@ -361,7 +359,6 @@ pub fn execute_test_suite(
}

for (index, test) in tests.into_iter().enumerate() {
// TODO : TX TYPE needs to be set
let Some(tx_type) = unit.transaction.tx_type(test.indexes.data) else {
if test.expect_exception.is_some() {
continue;
Expand Down Expand Up @@ -416,35 +413,29 @@ pub fn execute_test_suite(
.with_cached_prestate(cache)
.with_bundle_update()
.build();
let mut evm = MainEvm::new(
Context::builder()
.with_block(&block)
.with_tx(&tx)
.with_cfg(&cfg)
.with_db(&mut state),
EthHandler::default(),
);
let mut ctx = Context::builder()
.with_block(&block)
.with_tx(&tx)
.with_cfg(&cfg)
.with_db(&mut state);

// Do the deed
let (e, exec_result) = if trace {
let mut evm = InspectorMainEvm::new(
InspectorContext::new(
Context::builder()
.with_block(&block)
.with_tx(&tx)
.with_cfg(&cfg)
.with_db(&mut state),
TracerEip3155::new(Box::new(stderr())).without_summary(),
),
inspector_handler(),
let mut ctx = &mut InspectorContext::new(
Context::builder()
.with_block(&block)
.with_tx(&tx)
.with_cfg(&cfg)
.with_db(&mut state),
TracerEip3155::new(Box::new(stderr())).without_summary(),
);

let timer = Instant::now();
let res = evm.exec_commit();
let res = inspect_main_commit(&mut ctx);
*elapsed.lock().unwrap() += timer.elapsed();

let spec = cfg.spec();
let db = evm.context.inner.journaled_state.database;
let db = &mut ctx.inner.journaled_state.database;
// Dump state and traces if test failed
let output = check_evm_execution(
&test,
Expand All @@ -461,11 +452,11 @@ pub fn execute_test_suite(
(e, res)
} else {
let timer = Instant::now();
let res = evm.exec_commit();
let res = transact_main_commit(&mut ctx);
*elapsed.lock().unwrap() += timer.elapsed();

let spec = cfg.spec();
let db = evm.context.journaled_state.database;
let db = ctx.journaled_state.database;
// Dump state and traces if test failed
let output = check_evm_execution(
&test,
Expand Down Expand Up @@ -503,30 +494,23 @@ pub fn execute_test_suite(

println!("\nTraces:");

let mut evm = InspectorMainEvm::new(
InspectorContext::new(
Context::builder()
.with_db(&mut state)
.with_block(&block)
.with_tx(&tx)
.with_cfg(&cfg),
TracerEip3155::new(Box::new(stderr())).without_summary(),
),
inspector_handler(),
let mut ctx = InspectorContext::new(
Context::builder()
.with_db(&mut state)
.with_block(&block)
.with_tx(&tx)
.with_cfg(&cfg),
TracerEip3155::new(Box::new(stderr())).without_summary(),
);

let res = evm.transact();
let _ = res.map(|r| {
evm.context.inner.journaled_state.database.commit(r.state);
r.result
});
let _ = inspect_main_commit(&mut ctx);

println!("\nExecution result: {exec_result:#?}");
println!("\nExpected exception: {:?}", test.expect_exception);
println!("\nState before: {cache_state:#?}");
println!(
"\nState after: {:#?}",
evm.context.inner.journaled_state.database.cache
ctx.inner.journaled_state.database.cache
);
println!("\nSpecification: {:?}", cfg.spec);
println!("\nTx: {tx:#?}");
Expand Down
2 changes: 1 addition & 1 deletion crates/bytecode/src/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ mod tests {
assert_eq!(
opcode.map(|opcode| opcode.terminating).unwrap_or_default(),
opcodes[i],
"Opcode {:?} terminating chack failed.",
"Opcode {:?} terminating check failed.",
opcode
);
}
Expand Down
3 changes: 3 additions & 0 deletions crates/context/interface/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use auto_impl::auto_impl;

/// Some actions on top of context with just Getter traits would require borrowing the context
/// with a both mutable and immutable reference.
///
/// To allow doing this action more efficiently, we introduce a new trait that does this directly.
///
/// Used for loading access list and applying EIP-7702 authorization list.
#[auto_impl(&mut,Box)]
pub trait PerformantContextAccess {
type Error;

Expand Down
1 change: 0 additions & 1 deletion crates/context/interface/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use auto_impl::auto_impl;
use primitives::{Address, Bytes, Log, B256, U256};

/// EVM context host.
// TODO : Move to context-interface
#[auto_impl(&mut, Box)]
pub trait Host: TransactionGetter + BlockGetter + CfgGetter {
/// Load an account code.
Expand Down
Loading

0 comments on commit 34bc873

Please sign in to comment.