diff --git a/Cargo.lock b/Cargo.lock index 7e4095902a..06d06fc4ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3516,6 +3516,7 @@ dependencies = [ name = "revm-inspector" version = "1.0.0" dependencies = [ + "auto_impl", "revm", "revm-database", "serde", @@ -3548,6 +3549,7 @@ dependencies = [ "once_cell", "revm", "revm-database", + "revm-inspector", "revm-precompile", "rstest 0.23.0", "serde", diff --git a/bins/revme/src/cmd/evmrunner.rs b/bins/revme/src/cmd/evmrunner.rs index 89fbc40a16..53141b921c 100644 --- a/bins/revme/src/cmd/evmrunner.rs +++ b/bins/revme/src/cmd/evmrunner.rs @@ -1,10 +1,10 @@ use clap::Parser; use database::BenchmarkDB; -use inspector::inspectors::TracerEip3155; +use inspector::{inspectors::TracerEip3155, InspectEvm}; use revm::{ bytecode::{Bytecode, BytecodeDecodeError}, primitives::{address, hex, Address, TxKind}, - Context, Database, ExecuteEvm, InspectEvm, MainBuilder, MainContext, + Context, Database, ExecuteEvm, MainBuilder, MainContext, }; use std::io::Error as IoError; use std::path::PathBuf; diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index 04f2162e2c..96aefb4c7c 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -4,7 +4,7 @@ use super::{ }; use database::State; use indicatif::{ProgressBar, ProgressDrawTarget}; -use inspector::inspectors::TracerEip3155; +use inspector::{inspectors::TracerEip3155, InspectCommitEvm}; use revm::{ bytecode::Bytecode, context::{block::BlockEnv, cfg::CfgEnv, tx::TxEnv}, @@ -16,7 +16,7 @@ use revm::{ database_interface::EmptyDB, primitives::{keccak256, Bytes, TxKind, B256}, specification::{eip4844::TARGET_BLOB_GAS_PER_BLOCK_CANCUN, hardfork::SpecId}, - Context, ExecuteCommitEvm, InspectCommitEvm, MainBuilder, MainContext, + Context, ExecuteCommitEvm, MainBuilder, MainContext, }; use serde_json::json; use statetest_types::{SpecName, Test, TestSuite}; diff --git a/crates/context/src/evm.rs b/crates/context/src/evm.rs index 41ada34f2f..2b7cc3f0a7 100644 --- a/crates/context/src/evm.rs +++ b/crates/context/src/evm.rs @@ -3,7 +3,6 @@ use core::ops::{Deref, DerefMut}; pub struct Evm { pub data: EvmData, - pub enabled_inspection: bool, pub instruction: I, pub precompiles: P, } @@ -17,7 +16,6 @@ impl Evm { pub fn new(ctx: CTX) -> Self { Evm { data: EvmData { ctx, inspector: () }, - enabled_inspection: false, instruction: (), precompiles: (), } @@ -32,7 +30,6 @@ impl Evm { ctx: self.data.ctx, inspector, }, - enabled_inspection: self.enabled_inspection, instruction: self.instruction, precompiles: self.precompiles, } @@ -42,7 +39,6 @@ impl Evm { pub fn with_precompiles(self, precompiles: OP) -> Evm { Evm { data: self.data, - enabled_inspection: self.enabled_inspection, instruction: self.instruction, precompiles, } diff --git a/crates/handler/src/evm.rs b/crates/handler/src/evm.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/crates/handler/src/frame.rs b/crates/handler/src/frame.rs index 7226ab4e20..a05adc5960 100644 --- a/crates/handler/src/frame.rs +++ b/crates/handler/src/frame.rs @@ -30,33 +30,33 @@ use std::{boxed::Box, rc::Rc, sync::Arc}; /// Call frame trait pub trait Frame: Sized { - type Context; + type Evm; type FrameInit; type FrameResult; type Error; fn init_first( - context: &mut Self::Context, + evm: &mut Self::Evm, frame_input: Self::FrameInit, ) -> Result, Self::Error>; fn init( &self, - context: &mut Self::Context, + evm: &mut Self::Evm, frame_input: Self::FrameInit, ) -> Result, Self::Error>; - fn run(&mut self, context: &mut Self::Context) -> Result, Self::Error>; + fn run(&mut self, evm: &mut Self::Evm) -> Result, Self::Error>; fn return_result( &mut self, - context: &mut Self::Context, + evm: &mut Self::Evm, result: Self::FrameResult, ) -> Result<(), Self::Error>; } -pub struct EthFrame { - phantom: core::marker::PhantomData<(CTX, ERROR)>, +pub struct EthFrame { + phantom: core::marker::PhantomData<(EVM, ERROR)>, /// Data of the frame. data: FrameData, /// Input data for the frame. @@ -71,46 +71,46 @@ pub struct EthFrame { pub memory: Rc>, } -impl Frame for EthFrame> +impl Frame for EthFrame where EVM: EvmTrait< Precompiles: PrecompileProvider, Instructions: InstructionProvider< Context = EVM::Context, - InterpreterTypes = EthInterpreter<()>, + InterpreterTypes = EthInterpreter, Output = InterpreterAction, >, >, ERROR: From> + From, { - type Context = EVM; + type Evm = EVM; type FrameInit = FrameInput; type FrameResult = FrameResult; type Error = ERROR; fn init_first( - context: &mut Self::Context, + evm: &mut Self::Evm, frame_input: Self::FrameInit, ) -> Result, Self::Error> { - EthFrame::init_first(context, frame_input) + EthFrame::init_first(evm, frame_input) } fn init( &self, - context: &mut Self::Context, + evm: &mut Self::Evm, frame_input: Self::FrameInit, ) -> Result, Self::Error> { - self.init(context, frame_input) + self.init(evm, frame_input) } - fn run(&mut self, context: &mut Self::Context) -> Result, Self::Error> { + fn run(&mut self, context: &mut Self::Evm) -> Result, Self::Error> { let next_action = context.run_interpreter(&mut self.interpreter); - self.run_frame(context, next_action) + self.process_next_action(context, next_action) } fn return_result( &mut self, - context: &mut Self::Context, + context: &mut Self::Evm, result: Self::FrameResult, ) -> Result<(), Self::Error> { self.return_result(context, result) @@ -511,21 +511,21 @@ where } } -impl EthFrame> +impl EthFrame where - CTX: EvmTrait< + EVM: EvmTrait< Context: ContextTrait, - Precompiles: PrecompileProvider, + Precompiles: PrecompileProvider, Instructions: InstructionProvider< - Context = CTX::Context, - InterpreterTypes = EthInterpreter<()>, + Context = EVM::Context, + InterpreterTypes = EthInterpreter, Output = InterpreterAction, >, >, - ERROR: From> + From, + ERROR: From> + From, { pub fn init_first( - evm: &mut CTX, + evm: &mut EVM, frame_input: FrameInput, ) -> Result, ERROR> { let memory = Rc::new(RefCell::new(SharedMemory::new())); @@ -541,16 +541,16 @@ where fn init( &self, - context: &mut CTX, + evm: &mut EVM, frame_init: FrameInput, ) -> Result, ERROR> { self.memory.borrow_mut().new_context(); - Self::init_with_context(context, self.depth + 1, frame_init, self.memory.clone()) + Self::init_with_context(evm, self.depth + 1, frame_init, self.memory.clone()) } - pub fn run_frame( + pub fn process_next_action( &mut self, - evm: &mut CTX, + evm: &mut EVM, next_action: InterpreterAction, ) -> Result, ERROR> { let context = evm.ctx(); @@ -615,9 +615,9 @@ where Ok(result) } - fn return_result(&mut self, context: &mut CTX, result: FrameResult) -> Result<(), ERROR> { + fn return_result(&mut self, evm: &mut EVM, result: FrameResult) -> Result<(), ERROR> { self.memory.borrow_mut().free_context(); - core::mem::replace(context.ctx().error(), Ok(()))?; + core::mem::replace(evm.ctx().error(), Ok(()))?; // Insert result to the top frame. match result { diff --git a/crates/handler/src/handler.rs b/crates/handler/src/handler.rs index 760aec2239..8f8d6836bb 100644 --- a/crates/handler/src/handler.rs +++ b/crates/handler/src/handler.rs @@ -1,22 +1,16 @@ -use crate::inspector::JournalExt; use crate::{ - execution, inspector::Inspector, instructions::InstructionProvider, post_execution, - pre_execution, validation, Frame, FrameInitOrResult, FrameOrResult, FrameResult, ItemOrResult, + execution, instructions::InstructionProvider, post_execution, pre_execution, validation, Frame, + FrameInitOrResult, FrameOrResult, FrameResult, ItemOrResult, }; use auto_impl::auto_impl; -use context::{Evm, JournalEntry}; +use context::Evm; use context_interface::ContextTrait; use context_interface::{ result::{HaltReasonTrait, InvalidHeader, InvalidTransaction, ResultAndState}, Cfg, Database, Journal, Transaction, }; use core::mem; -use interpreter::table::InstructionTable; -use interpreter::InterpreterTypes; -use interpreter::{ - interpreter_types::{Jumps, LoopControl}, - FrameInput, Host, InitialAndFloorGas, InstructionResult, Interpreter, InterpreterAction, -}; +use interpreter::{FrameInput, Host, InitialAndFloorGas, Interpreter, InterpreterAction}; use precompile::PrecompileErrors; use primitives::Log; use state::EvmState; @@ -40,86 +34,12 @@ impl< { } -pub fn inspect_instructions( - context: &mut CTX, - interpreter: &mut Interpreter, - mut inspector: impl Inspector, - instructions: &InstructionTable, -) -> InterpreterAction -where - CTX: ContextTrait + Host, - IT: InterpreterTypes, -{ - interpreter.reset_control(); - - let mut log_num = context.journal().logs().len(); - // Main loop - while interpreter.control.instruction_result().is_continue() { - // Get current opcode. - let opcode = interpreter.bytecode.opcode(); - - // Call Inspector step. - inspector.step(interpreter, context); - if interpreter.control.instruction_result() != InstructionResult::Continue { - break; - } - - // SAFETY: In analysis we are doing padding of bytecode so that we are sure that last - // byte instruction is STOP so we are safe to just increment program_counter bcs on last instruction - // it will do noop and just stop execution of this contract - interpreter.bytecode.relative_jump(1); - - // Execute instruction. - instructions[opcode as usize](interpreter, context); - - // check if new log is added - let new_log = context.journal().logs().len(); - if log_num < new_log { - // as there is a change in log number this means new log is added - let log = context.journal().logs().last().unwrap().clone(); - inspector.log(interpreter, context, log); - log_num = new_log; - } - - // Call step_end. - inspector.step_end(interpreter, context); - } - - let next_action = interpreter.take_next_action(); - - // handle selfdestruct - if let InterpreterAction::Return { result } = &next_action { - if result.result == InstructionResult::SelfDestruct { - match context.journal().last_journal().last() { - Some(JournalEntry::AccountDestroyed { - address, - target, - had_balance, - .. - }) => { - inspector.selfdestruct(*address, *target, *had_balance); - } - Some(JournalEntry::BalanceTransfer { - from, to, balance, .. - }) => { - inspector.selfdestruct(*from, *to, *balance); - } - _ => {} - } - } - } - - next_action -} - impl EvmTrait for Evm where - CTX: ContextTrait + Host, - INSP: Inspector, + CTX: ContextTrait + Host, I: InstructionProvider, { type Context = CTX; - type Inspector = INSP; type Instructions = I; type Precompiles = P; @@ -132,24 +52,8 @@ where ) -> ::Output { let context = &mut self.data.ctx; let instructions = &mut self.instruction; - let inspector = &mut self.data.inspector; - if self.enabled_inspection { - inspect_instructions( - context, - interpreter, - inspector, - instructions.instruction_table(), - ) - } else { - interpreter.run_plain(instructions.instruction_table(), context) - } - } - - #[inline] - fn enable_inspection(&mut self, enable: bool) { - self.enabled_inspection = enable; + interpreter.run_plain(instructions.instruction_table(), context) } - #[inline] fn ctx(&mut self) -> &mut Self::Context { &mut self.data.ctx @@ -160,16 +64,6 @@ where &self.data.ctx } - #[inline] - fn inspector(&mut self) -> &mut Self::Inspector { - &mut self.data.inspector - } - - #[inline] - fn ctx_inspector(&mut self) -> (&mut Self::Context, &mut Self::Inspector) { - (&mut self.data.ctx, &mut self.data.inspector) - } - #[inline] fn ctx_instructions(&mut self) -> (&mut Self::Context, &mut Self::Instructions) { (&mut self.data.ctx, &mut self.instruction) @@ -184,7 +78,6 @@ where #[auto_impl(&mut, Box)] pub trait EvmTrait { type Context: ContextTrait; - type Inspector; type Instructions: InstructionProvider; type Precompiles; @@ -195,16 +88,10 @@ pub trait EvmTrait { >, ) -> ::Output; - fn enable_inspection(&mut self, enable: bool); - fn ctx(&mut self) -> &mut Self::Context; - fn inspector(&mut self) -> &mut Self::Inspector; - fn ctx_ref(&self) -> &Self::Context; - fn ctx_inspector(&mut self) -> (&mut Self::Context, &mut Self::Inspector); - fn ctx_instructions(&mut self) -> (&mut Self::Context, &mut Self::Instructions); fn ctx_precompiles(&mut self) -> (&mut Self::Context, &mut Self::Precompiles); @@ -216,7 +103,7 @@ pub trait EthHandler { // TODO `FrameResult` should be a generic trait. // TODO `FrameInit` should be a generic. type Frame: Frame< - Context = Self::Evm, + Evm = Self::Evm, Error = Self::Error, FrameResult = FrameResult, FrameInit = FrameInput, diff --git a/crates/handler/src/lib.rs b/crates/handler/src/lib.rs index 62914d92b9..587c915ed5 100644 --- a/crates/handler/src/lib.rs +++ b/crates/handler/src/lib.rs @@ -11,11 +11,9 @@ pub mod execution; mod frame; mod frame_data; pub mod handler; -pub mod inspector; pub mod instructions; mod item_or_result; mod mainnet_handler; -pub mod noop; pub mod post_execution; pub mod pre_execution; mod precompile_provider; @@ -24,9 +22,7 @@ pub mod validation; // Public exports pub use frame::{return_create, return_eofcreate, CtxTraitDbError, EthFrame, Frame}; pub use frame_data::{FrameData, FrameResult}; -pub use handler::{inspect_instructions, EthHandler, EthTraitError, EvmTrait}; -pub use inspector::{Inspector, JournalExt}; +pub use handler::{EthHandler, EthTraitError, EvmTrait}; pub use item_or_result::{FrameInitOrResult, FrameOrResult, ItemOrResult}; pub use mainnet_handler::MainnetHandler; -pub use noop::NoOpInspector; pub use precompile_provider::{EthPrecompiles, PrecompileProvider}; diff --git a/crates/handler/src/mainnet_handler.rs b/crates/handler/src/mainnet_handler.rs index 86153880c0..651f8ef04c 100644 --- a/crates/handler/src/mainnet_handler.rs +++ b/crates/handler/src/mainnet_handler.rs @@ -1,12 +1,7 @@ use super::{EthHandler, EthTraitError}; -use crate::{ - inspector::{EthInspectorHandler, Inspector, InspectorFrame}, - EvmTrait, Frame, FrameResult, -}; +use crate::{EvmTrait, Frame, FrameResult}; use context_interface::{result::HaltReason, ContextTrait, Journal}; - -use interpreter::{interpreter::EthInterpreter, FrameInput}; - +use interpreter::FrameInput; use primitives::Log; use state::EvmState; use std::vec::Vec; @@ -21,7 +16,7 @@ where ERROR: EthTraitError, // TODO `FrameResult` should be a generic trait. // TODO `FrameInit` should be a generic. - FRAME: Frame, + FRAME: Frame, { type Evm = EVM; type Error = ERROR; @@ -36,16 +31,3 @@ impl Default for MainnetHandler { } } } - -impl EthInspectorHandler for MainnetHandler -where - CTX: EvmTrait< - Context: ContextTrait)>>, - Inspector: Inspector<<::Evm as EvmTrait>::Context, EthInterpreter>, - >, - ERROR: EthTraitError, - FRAME: Frame - + InspectorFrame, -{ - type IT = EthInterpreter; -} diff --git a/crates/inspector/Cargo.toml b/crates/inspector/Cargo.toml index a4186c6c82..660258113b 100644 --- a/crates/inspector/Cargo.toml +++ b/crates/inspector/Cargo.toml @@ -24,6 +24,7 @@ all = "warn" [dependencies] # revm revm.workspace = true +auto_impl.workspace = true # Optional serde = { version = "1.0", default-features = false, features = [ diff --git a/crates/inspector/src/eip3155.rs b/crates/inspector/src/eip3155.rs index ab6b39b86e..23a2d77456 100644 --- a/crates/inspector/src/eip3155.rs +++ b/crates/inspector/src/eip3155.rs @@ -1,10 +1,10 @@ use crate::inspectors::GasInspector; +use crate::Inspector; use revm::interpreter::interpreter_types::{RuntimeFlag, SubRoutineStack}; use revm::{ bytecode::opcode::OpCode, context::Cfg, context_interface::{ContextTrait, Journal, Transaction}, - handler::inspector::Inspector, interpreter::{ interpreter_types::{Jumps, LoopControl, MemoryTrait, StackTrait}, CallInputs, CallOutcome, CreateInputs, CreateOutcome, Interpreter, InterpreterResult, diff --git a/crates/inspector/src/gas.rs b/crates/inspector/src/gas.rs index 84fadecd5d..af0da88d4c 100644 --- a/crates/inspector/src/gas.rs +++ b/crates/inspector/src/gas.rs @@ -68,20 +68,16 @@ impl GasInspector { #[cfg(test)] mod tests { use super::*; + use crate::{InspectEvm, Inspector}; use database::{BenchmarkDB, BENCH_CALLER, BENCH_TARGET}; use revm::{ bytecode::{opcode, Bytecode}, - handler::inspector::Inspector, interpreter::{ interpreter_types::{Jumps, LoopControl}, CallInputs, CreateInputs, Interpreter, InterpreterTypes, }, primitives::{Bytes, TxKind}, - Context, - InspectEvm, - MainBuilder, - MainContext, //Evm, - //EvmWiring, + Context, MainBuilder, MainContext, }; #[derive(Default, Debug)] diff --git a/crates/inspector/src/inspect.rs b/crates/inspector/src/inspect.rs new file mode 100644 index 0000000000..81301151a2 --- /dev/null +++ b/crates/inspector/src/inspect.rs @@ -0,0 +1,49 @@ +use revm::{context::setters::ContextSetters, ExecuteCommitEvm, ExecuteEvm}; + +pub trait InspectEvm: ExecuteEvm { + type Inspector; + + fn set_inspector(&mut self, inspector: Self::Inspector); + + fn inspect_previous(&mut self) -> Self::Output; + + fn inspect_previous_with_inspector(&mut self, inspector: Self::Inspector) -> Self::Output { + self.set_inspector(inspector); + self.inspect_previous() + } + + fn inspect_previous_with_tx(&mut self, tx: ::Tx) -> Self::Output { + self.set_tx(tx); + self.inspect_previous() + } + + fn inspect( + &mut self, + tx: ::Tx, + inspector: Self::Inspector, + ) -> Self::Output { + self.set_tx(tx); + self.inspect_previous_with_inspector(inspector) + } +} + +pub trait InspectCommitEvm: InspectEvm + ExecuteCommitEvm { + fn inspect_commit_previous(&mut self) -> Self::CommitOutput; + + fn inspect_commit_previous_with_inspector( + &mut self, + inspector: Self::Inspector, + ) -> Self::CommitOutput { + self.set_inspector(inspector); + self.inspect_commit_previous() + } + + fn inspect_commit( + &mut self, + tx: ::Tx, + inspector: Self::Inspector, + ) -> Self::CommitOutput { + self.set_tx(tx); + self.inspect_commit_previous_with_inspector(inspector) + } +} diff --git a/crates/handler/src/inspector.rs b/crates/inspector/src/inspector.rs similarity index 64% rename from crates/handler/src/inspector.rs rename to crates/inspector/src/inspector.rs index d68cfb4f68..397a84d64d 100644 --- a/crates/handler/src/inspector.rs +++ b/crates/inspector/src/inspector.rs @@ -1,17 +1,22 @@ -use crate::{ - execution, - handler::{EthHandler, EvmTrait}, - EthFrame, Frame, FrameOrResult, FrameResult, ItemOrResult, -}; +use crate::{InspectorEvmTrait, InspectorFrameTrait}; use auto_impl::auto_impl; -use context::{Cfg, JournalEntry, JournaledState}; -use context_interface::{result::ResultAndState, ContextTrait, Database, Transaction}; -use interpreter::{ - interpreter::EthInterpreter, CallInputs, CallOutcome, CreateInputs, CreateOutcome, - EOFCreateInputs, FrameInput, InitialAndFloorGas, Interpreter, InterpreterTypes, +use revm::{ + context::{Cfg, JournalEntry, JournaledState}, + context_interface::{result::ResultAndState, ContextTrait, Database, Transaction}, + handler::{ + execution, EthHandler, EvmTrait, Frame, FrameInitOrResult, FrameOrResult, FrameResult, + ItemOrResult, + }, + interpreter::{ + interpreter::EthInterpreter, + interpreter_types::{Jumps, LoopControl}, + table::InstructionTable, + CallInputs, CallOutcome, CreateInputs, CreateOutcome, EOFCreateInputs, FrameInput, Host, + InitialAndFloorGas, InstructionResult, Interpreter, InterpreterAction, InterpreterTypes, + }, + primitives::{Address, Log, U256}, + state::EvmState, }; -use primitives::{Address, Log, U256}; -use state::EvmState; use std::{vec, vec::Vec}; /// EVM [Interpreter] callbacks. @@ -19,7 +24,7 @@ use std::{vec, vec::Vec}; pub trait Inspector { /// Called before the interpreter is initialized. /// - /// If `interp.instruction_result` is set to anything other than [interpreter::InstructionResult::Continue] then the execution of the interpreter + /// If `interp.instruction_result` is set to anything other than [InstructionResult::Continue] then the execution of the interpreter /// is skipped. #[inline] fn initialize_interp(&mut self, interp: &mut Interpreter, context: &mut CTX) { @@ -43,7 +48,7 @@ pub trait Inspector { /// Called after `step` when the instruction has been executed. /// - /// Setting `interp.instruction_result` to anything other than [interpreter::InstructionResult::Continue] alters the execution + /// Setting `interp.instruction_result` to anything other than [InstructionResult::Continue] alters the execution /// of the interpreter. #[inline] fn step_end(&mut self, interp: &mut Interpreter, context: &mut CTX) { @@ -61,7 +66,7 @@ pub trait Inspector { /// Called whenever a call to a contract is about to start. /// - /// InstructionResulting anything other than [interpreter::InstructionResult::Continue] overrides the result of the call. + /// InstructionResulting anything other than [InstructionResult::Continue] overrides the result of the call. #[inline] fn call(&mut self, context: &mut CTX, inputs: &mut CallInputs) -> Option { let _ = context; @@ -176,36 +181,12 @@ impl JournalExt for JournaledState { } } -pub trait InspectorFrame { - type IT: InterpreterTypes; - type FrameInput; - - fn interpreter(&mut self) -> &mut Interpreter; - - fn frame_input(&self) -> &FrameInput; -} - -impl InspectorFrame for EthFrame -where - IT: InterpreterTypes, -{ - type IT = IT; - type FrameInput = FrameInput; - - fn interpreter(&mut self) -> &mut Interpreter { - &mut self.interpreter - } - - fn frame_input(&self) -> &FrameInput { - &self.input - } -} - pub trait EthInspectorHandler: EthHandler where - Self::Evm: - EvmTrait::Evm as EvmTrait>::Context, Self::IT>>, - Self::Frame: InspectorFrame, + Self::Evm: InspectorEvmTrait< + Inspector: Inspector<<::Evm as EvmTrait>::Context, Self::IT>, + >, + Self::Frame: InspectorFrameTrait, { type IT: InterpreterTypes; @@ -215,11 +196,7 @@ where ) -> Result, Self::Error> { let init_and_floor_gas = self.validate(evm)?; let eip7702_refund = self.pre_execution(evm)? as i64; - // enable instruction inspection - evm.enable_inspection(true); let exec_result = self.inspect_execution(evm, &init_and_floor_gas); - // disable instruction inspection - evm.enable_inspection(false); self.post_execution(evm, exec_result?, init_and_floor_gas, eip7702_refund) } @@ -276,6 +253,15 @@ where ret } + #[inline] + fn inspect_frame_call( + &mut self, + frame: &mut Self::Frame, + evm: &mut Self::Evm, + ) -> Result, Self::Error> { + frame.run_inspect(evm) + } + fn inspect_run_exec_loop( &mut self, evm: &mut Self::Evm, @@ -284,7 +270,7 @@ where let mut frame_stack: Vec = vec![frame]; loop { let frame = frame_stack.last_mut().unwrap(); - let call_or_result = self.frame_call(frame, evm)?; + let call_or_result = self.inspect_frame_call(frame, evm)?; let result = match call_or_result { ItemOrResult::Item(mut init) => { @@ -381,113 +367,74 @@ fn frame_end( } } -// INSTRUCTIONS FOR INSPECTOR - -// pub struct InspectorInstructionProvider { -// instruction_table: Rc<[InspectorInstruction; 256]>, -// } - -// impl Clone for InspectorInstructionProvider -// where -// WIRE: InterpreterTypes, -// { -// fn clone(&self) -> Self { -// Self { -// instruction_table: self.instruction_table.clone(), -// } -// } -// } - -// impl InspectorInstructionProvider -// where -// WIRE: InterpreterTypes, -// HOST: Host + JournalExtGetter + JournalGetter + InspectorCtx, -// { -// pub fn (base_table: InstructionTable) -> Self { -// let mut table: [MaybeUninit>; 256] = -// unsafe { MaybeUninit::uninit().assume_init() }; - -// for (i, element) in table.iter_mut().enumerate() { -// let function: InspectorInstruction = InspectorInstruction { -// instruction: base_table[i], -// }; -// *element = MaybeUninit::new(function); -// } - -// let mut table = unsafe { -// core::mem::transmute::< -// [MaybeUninit>; 256], -// [InspectorInstruction; 256], -// >(table) -// }; - -// // Inspector log wrapper -// fn inspector_log( -// interpreter: &mut Interpreter<::IT>, -// context: &mut CTX, -// prev: Instruction<::IT, CTX>, -// ) { -// prev(interpreter, context); - -// if interpreter.control.instruction_result() == InstructionResult::Continue { -// let last_log = context.journal_ext().logs().last().unwrap().clone(); -// context.inspector_log(interpreter, &last_log); -// } -// } - -// /* LOG and Selfdestruct instructions */ -// table[OpCode::LOG0.as_usize()] = InspectorInstruction { -// instruction: |interp, context| { -// inspector_log(interp, context, log::<0, HOST>); -// }, -// }; -// table[OpCode::LOG1.as_usize()] = InspectorInstruction { -// instruction: |interp, context| { -// inspector_log(interp, context, log::<1, HOST>); -// }, -// }; -// table[OpCode::LOG2.as_usize()] = InspectorInstruction { -// instruction: |interp, context| { -// inspector_log(interp, context, log::<2, HOST>); -// }, -// }; -// table[OpCode::LOG3.as_usize()] = InspectorInstruction { -// instruction: |interp, context| { -// inspector_log(interp, context, log::<3, HOST>); -// }, -// }; -// table[OpCode::LOG4.as_usize()] = InspectorInstruction { -// instruction: |interp, context| { -// inspector_log(interp, context, log::<4, HOST>); -// }, -// }; - -// table[OpCode::SELFDESTRUCT.as_usize()] = InspectorInstruction { -// instruction: |interp, context| { -// selfdestruct::(interp, context); -// if interp.control.instruction_result() == InstructionResult::SelfDestruct { -// match context.journal_ext().last_journal().last() { -// Some(JournalEntry::AccountDestroyed { -// address, -// target, -// had_balance, -// .. -// }) => { -// context.inspector_selfdestruct(*address, *target, *had_balance); -// } -// Some(JournalEntry::BalanceTransfer { -// from, to, balance, .. -// }) => { -// context.inspector_selfdestruct(*from, *to, *balance); -// } -// _ => {} -// } -// } -// }, -// }; - -// Self { -// instruction_table: Rc::new(table), -// } -// } -// } +pub fn inspect_instructions( + context: &mut CTX, + interpreter: &mut Interpreter, + mut inspector: impl Inspector, + instructions: &InstructionTable, +) -> InterpreterAction +where + CTX: ContextTrait + Host, + IT: InterpreterTypes, +{ + interpreter.reset_control(); + + let mut log_num = context.journal().logs().len(); + // Main loop + while interpreter.control.instruction_result().is_continue() { + // Get current opcode. + let opcode = interpreter.bytecode.opcode(); + + // Call Inspector step. + inspector.step(interpreter, context); + if interpreter.control.instruction_result() != InstructionResult::Continue { + break; + } + + // SAFETY: In analysis we are doing padding of bytecode so that we are sure that last + // byte instruction is STOP so we are safe to just increment program_counter bcs on last instruction + // it will do noop and just stop execution of this contract + interpreter.bytecode.relative_jump(1); + + // Execute instruction. + instructions[opcode as usize](interpreter, context); + + // check if new log is added + let new_log = context.journal().logs().len(); + if log_num < new_log { + // as there is a change in log number this means new log is added + let log = context.journal().logs().last().unwrap().clone(); + inspector.log(interpreter, context, log); + log_num = new_log; + } + + // Call step_end. + inspector.step_end(interpreter, context); + } + + let next_action = interpreter.take_next_action(); + + // handle selfdestruct + if let InterpreterAction::Return { result } = &next_action { + if result.result == InstructionResult::SelfDestruct { + match context.journal().last_journal().last() { + Some(JournalEntry::AccountDestroyed { + address, + target, + had_balance, + .. + }) => { + inspector.selfdestruct(*address, *target, *had_balance); + } + Some(JournalEntry::BalanceTransfer { + from, to, balance, .. + }) => { + inspector.selfdestruct(*from, *to, *balance); + } + _ => {} + } + } + } + + next_action +} diff --git a/crates/inspector/src/lib.rs b/crates/inspector/src/lib.rs index 3f8911b6ad..4a18d3c8f7 100644 --- a/crates/inspector/src/lib.rs +++ b/crates/inspector/src/lib.rs @@ -2,12 +2,17 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(not(feature = "std"), no_std)] -// #[cfg(not(feature = "std"))] -// extern crate alloc as std; +#[cfg(not(feature = "std"))] +extern crate alloc as std; #[cfg(all(feature = "std", feature = "serde-json"))] mod eip3155; mod gas; +mod inspect; +mod inspector; +mod mainnet_inspect; +mod noop; +mod traits; /// Inspector implementations. pub mod inspectors { @@ -15,3 +20,8 @@ pub mod inspectors { pub use super::eip3155::TracerEip3155; pub use super::gas::GasInspector; } + +pub use inspect::{InspectCommitEvm, InspectEvm}; +pub use inspector::*; +pub use noop::NoOpInspector; +pub use traits::*; diff --git a/crates/inspector/src/mainnet_inspect.rs b/crates/inspector/src/mainnet_inspect.rs new file mode 100644 index 0000000000..3e00d9f1c1 --- /dev/null +++ b/crates/inspector/src/mainnet_inspect.rs @@ -0,0 +1,73 @@ +use revm::{ + context::{setters::ContextSetters, Evm}, + context_interface::{ContextTrait, Journal}, + handler::{ + instructions::EthInstructions, EthFrame, EthHandler, EthTraitError, EvmTrait, Frame, + FrameResult, MainnetHandler, PrecompileProvider, + }, + interpreter::{interpreter::EthInterpreter, FrameInput, InterpreterResult}, + primitives::Log, + state::EvmState, + DatabaseCommit, +}; +use std::vec::Vec; + +use crate::{ + EthInspectorHandler, InspectCommitEvm, InspectEvm, Inspector, InspectorEvmTrait, + InspectorFrameTrait, JournalExt, +}; + +impl EthInspectorHandler for MainnetHandler +where + EVM: InspectorEvmTrait< + Context: ContextTrait)>>, + Inspector: Inspector<<::Evm as EvmTrait>::Context, EthInterpreter>, + >, + ERROR: EthTraitError, + FRAME: Frame + + InspectorFrameTrait, +{ + type IT = EthInterpreter; +} + +impl InspectEvm + for Evm, PRECOMPILES> +where + CTX: ContextSetters + + ContextTrait)> + JournalExt>, + INSP: Inspector, + PRECOMPILES: PrecompileProvider, +{ + type Inspector = INSP; + + fn set_inspector(&mut self, inspector: Self::Inspector) { + self.data.inspector = inspector; + } + + fn inspect_previous(&mut self) -> Self::Output { + let mut t = MainnetHandler::<_, _, EthFrame<_, _, _>> { + _phantom: core::marker::PhantomData, + }; + + t.inspect_run(self) + } +} + +impl InspectCommitEvm + for Evm, PRECOMPILES> +where + CTX: ContextSetters + + ContextTrait< + Journal: Journal)> + JournalExt, + Db: DatabaseCommit, + >, + INSP: Inspector, + PRECOMPILES: PrecompileProvider, +{ + fn inspect_commit_previous(&mut self) -> Self::CommitOutput { + self.inspect_previous().map(|r| { + self.ctx().db().commit(r.state); + r.result + }) + } +} diff --git a/crates/handler/src/noop.rs b/crates/inspector/src/noop.rs similarity index 86% rename from crates/handler/src/noop.rs rename to crates/inspector/src/noop.rs index 776dbe99f6..a8c0cbe8c4 100644 --- a/crates/handler/src/noop.rs +++ b/crates/inspector/src/noop.rs @@ -1,5 +1,5 @@ use crate::inspector::Inspector; -use interpreter::InterpreterTypes; +use revm::interpreter::InterpreterTypes; /// Dummy [Inspector], helpful as standalone replacement. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/crates/inspector/src/traits.rs b/crates/inspector/src/traits.rs new file mode 100644 index 0000000000..7650e555f5 --- /dev/null +++ b/crates/inspector/src/traits.rs @@ -0,0 +1,107 @@ +use revm::{ + context::{setters::ContextSetters, Evm}, + context_interface::ContextTrait, + handler::{ + instructions::InstructionProvider, CtxTraitDbError, EthFrame, EvmTrait, Frame, + FrameInitOrResult, PrecompileProvider, + }, + interpreter::{ + interpreter::EthInterpreter, FrameInput, Interpreter, InterpreterAction, InterpreterResult, + InterpreterTypes, + }, + precompile::PrecompileErrors, +}; + +use crate::{inspect_instructions, Inspector, JournalExt}; + +/// Inspector EVM trait. +pub trait InspectorEvmTrait: EvmTrait { + type Inspector; + + fn inspector(&mut self) -> &mut Self::Inspector; + + fn ctx_inspector(&mut self) -> (&mut Self::Context, &mut Self::Inspector); + + fn run_inspect_interpreter( + &mut self, + interpreter: &mut Interpreter< + ::InterpreterTypes, + >, + ) -> ::Output; +} + +impl InspectorEvmTrait for Evm +where + CTX: ContextTrait + ContextSetters, + I: InstructionProvider, + INSP: Inspector, +{ + type Inspector = INSP; + + fn inspector(&mut self) -> &mut Self::Inspector { + &mut self.data.inspector + } + + fn ctx_inspector(&mut self) -> (&mut Self::Context, &mut Self::Inspector) { + (&mut self.data.ctx, &mut self.data.inspector) + } + + fn run_inspect_interpreter( + &mut self, + interpreter: &mut Interpreter< + ::InterpreterTypes, + >, + ) -> ::Output { + let context = &mut self.data.ctx; + let instructions = &mut self.instruction; + let inspector = &mut self.data.inspector; + + inspect_instructions( + context, + interpreter, + inspector, + instructions.instruction_table(), + ) + } +} + +// TODO move InspectorFrame here +pub trait InspectorFrameTrait: Frame { + type IT: InterpreterTypes; + + fn run_inspect(&mut self, evm: &mut Self::Evm) -> Result, Self::Error>; + + fn interpreter(&mut self) -> &mut Interpreter; + + fn frame_input(&self) -> &FrameInput; +} + +impl InspectorFrameTrait for EthFrame +where + EVM: EvmTrait< + Context: ContextTrait, + Precompiles: PrecompileProvider, + Instructions: InstructionProvider< + Context = EVM::Context, + InterpreterTypes = EthInterpreter, + Output = InterpreterAction, + >, + > + InspectorEvmTrait, + ERROR: From> + From, +{ + type IT = EthInterpreter; + + fn run_inspect(&mut self, evm: &mut Self::Evm) -> Result, Self::Error> { + let interpreter = self.interpreter(); + let next_action = evm.run_inspect_interpreter(interpreter); + self.process_next_action(evm, next_action) + } + + fn interpreter(&mut self) -> &mut Interpreter { + &mut self.interpreter + } + + fn frame_input(&self) -> &FrameInput { + &self.input + } +} diff --git a/crates/optimism/Cargo.toml b/crates/optimism/Cargo.toml index 7666f6fc11..dfe07edf2a 100644 --- a/crates/optimism/Cargo.toml +++ b/crates/optimism/Cargo.toml @@ -25,6 +25,7 @@ all = "warn" # revm revm.workspace = true precompile = { workspace = true, features = ["secp256r1"] } +inspector.workspace = true auto_impl.workspace = true # static precompile sets. diff --git a/crates/optimism/src/api/builder.rs b/crates/optimism/src/api/builder.rs index b65e5f468f..29ca5ba3b6 100644 --- a/crates/optimism/src/api/builder.rs +++ b/crates/optimism/src/api/builder.rs @@ -3,7 +3,7 @@ use precompile::Log; use revm::{ context::{BlockEnv, Cfg, CfgEnv, TxEnv}, context_interface::{Block, Journal}, - handler::{instructions::EthInstructions, noop::NoOpInspector}, + handler::instructions::EthInstructions, interpreter::interpreter::EthInterpreter, state::EvmState, Context, Database, JournaledState, @@ -13,9 +13,7 @@ use std::vec::Vec; pub trait OpBuilder: Sized { type Context; - fn build_op( - self, - ) -> OpEvm>; + fn build_op(self) -> OpEvm>; fn build_op_with_inspector( self, @@ -33,10 +31,8 @@ where { type Context = Self; - fn build_op( - self, - ) -> OpEvm> { - OpEvm::new(self, NoOpInspector {}) + fn build_op(self) -> OpEvm> { + OpEvm::new(self, ()) } fn build_op_with_inspector( diff --git a/crates/optimism/src/api/default_ctx.rs b/crates/optimism/src/api/default_ctx.rs index 9d72999aa1..e01ce601af 100644 --- a/crates/optimism/src/api/default_ctx.rs +++ b/crates/optimism/src/api/default_ctx.rs @@ -38,13 +38,14 @@ impl DefaultOp mod test { use super::*; use crate::api::builder::OpBuilder; - use revm::{ExecuteEvm, InspectEvm}; + use inspector::{InspectEvm, NoOpInspector}; + use revm::ExecuteEvm; #[test] fn default_run_op() { let ctx = Context::op(); // convert to optimism context - let mut evm = ctx.build_op(); + let mut evm = ctx.build_op_with_inspector(NoOpInspector {}); // execute let _ = evm.transact_previous(); // inspect diff --git a/crates/optimism/src/api/exec.rs b/crates/optimism/src/api/exec.rs index 9d841e7397..da8489196b 100644 --- a/crates/optimism/src/api/exec.rs +++ b/crates/optimism/src/api/exec.rs @@ -2,21 +2,17 @@ use crate::{ evm::OpEvm, handler::OpHandler, transaction::OpTxTrait, L1BlockInfo, OpHaltReason, OpSpecId, OpTransactionError, }; +use inspector::{InspectCommitEvm, InspectEvm, Inspector, JournalExt}; use precompile::Log; use revm::{ context_interface::{ result::{EVMError, ExecutionResult, ResultAndState}, Block, Cfg, ContextTrait, Database, Journal, }, - handler::{ - handler::EvmTrait, - inspector::{Inspector, JournalExt}, - instructions::EthInstructions, - EthFrame, EthHandler, - }, + handler::{handler::EvmTrait, instructions::EthInstructions, EthFrame, EthHandler}, interpreter::interpreter::EthInterpreter, state::EvmState, - Context, DatabaseCommit, ExecuteCommitEvm, ExecuteEvm, InspectCommitEvm, InspectEvm, + Context, DatabaseCommit, ExecuteCommitEvm, ExecuteEvm, }; use std::vec::Vec; @@ -31,8 +27,7 @@ where TX: OpTxTrait, CFG: Cfg, DB: Database, - JOURNAL: Journal)> + JournalExt, - INSP: Inspector, EthInterpreter>, + JOURNAL: Journal)>, { type Output = Result, EVMError<::Error, OpTransactionError>>; @@ -55,7 +50,6 @@ where CFG: Cfg, DB: Database + DatabaseCommit, JOURNAL: Journal)> + JournalExt, - INSP: Inspector, EthInterpreter>, { type CommitOutput = Result< ExecutionResult, @@ -87,7 +81,7 @@ where type Inspector = INSP; fn set_inspector(&mut self, inspector: Self::Inspector) { - self.data.inspector = inspector; + self.0.data.inspector = inspector; } fn inspect_previous(&mut self) -> Self::Output { diff --git a/crates/optimism/src/evm.rs b/crates/optimism/src/evm.rs index 37ec9ad2c6..488af57f72 100644 --- a/crates/optimism/src/evm.rs +++ b/crates/optimism/src/evm.rs @@ -1,10 +1,8 @@ use revm::{ - context::{setters::ContextSetters, EvmData}, + context::{setters::ContextSetters, Evm, EvmData}, context_interface::ContextTrait, handler::{ handler::EvmTrait, - inspect_instructions, - inspector::{Inspector, JournalExt}, instructions::{EthInstructions, InstructionProvider}, }, interpreter::{interpreter::EthInterpreter, Host, Interpreter, InterpreterAction}, @@ -12,21 +10,19 @@ use revm::{ use crate::handler::precompiles::OpPrecompileProvider; -pub struct OpEvm { - pub data: EvmData, - pub enabled_inspection: bool, - pub instruction: I, - pub precompiles: OpPrecompileProvider, -} +pub struct OpEvm, P = OpPrecompileProvider>( + pub Evm, +); -impl OpEvm> { +impl + OpEvm, OpPrecompileProvider> +{ pub fn new(ctx: CTX, inspector: INSP) -> Self { - Self { + Self(Evm { data: EvmData { ctx, inspector }, - enabled_inspection: false, instruction: EthInstructions::new_mainnet(), precompiles: OpPrecompileProvider::default(), - } + }) } } @@ -35,24 +31,22 @@ impl ContextSetters for OpEvm { type Block = ::Block; fn set_tx(&mut self, tx: Self::Tx) { - self.data.ctx.set_tx(tx); + self.0.data.ctx.set_tx(tx); } fn set_block(&mut self, block: Self::Block) { - self.data.ctx.set_block(block); + self.0.data.ctx.set_block(block); } } -impl EvmTrait for OpEvm +impl EvmTrait for OpEvm where - CTX: ContextTrait, + CTX: ContextTrait, I: InstructionProvider, - INSP: Inspector, { type Context = CTX; - type Inspector = INSP; type Instructions = I; - type Precompiles = OpPrecompileProvider; + type Precompiles = P; fn run_interpreter( &mut self, @@ -60,46 +54,24 @@ where ::InterpreterTypes, >, ) -> ::Output { - let context = &mut self.data.ctx; - let instructions = &mut self.instruction; - let inspector = &mut self.data.inspector; - if self.enabled_inspection { - inspect_instructions( - context, - interpreter, - inspector, - instructions.instruction_table(), - ) - } else { - interpreter.run_plain(instructions.instruction_table(), context) - } - } - - fn enable_inspection(&mut self, enable: bool) { - self.enabled_inspection = enable; + let context = &mut self.0.data.ctx; + let instructions = &mut self.0.instruction; + interpreter.run_plain(instructions.instruction_table(), context) } fn ctx(&mut self) -> &mut Self::Context { - &mut self.data.ctx + &mut self.0.data.ctx } fn ctx_ref(&self) -> &Self::Context { - &self.data.ctx - } - - fn inspector(&mut self) -> &mut Self::Inspector { - &mut self.data.inspector - } - - fn ctx_inspector(&mut self) -> (&mut Self::Context, &mut Self::Inspector) { - (&mut self.data.ctx, &mut self.data.inspector) + &self.0.data.ctx } fn ctx_instructions(&mut self) -> (&mut Self::Context, &mut Self::Instructions) { - (&mut self.data.ctx, &mut self.instruction) + (&mut self.0.data.ctx, &mut self.0.instruction) } fn ctx_precompiles(&mut self) -> (&mut Self::Context, &mut Self::Precompiles) { - (&mut self.data.ctx, &mut self.precompiles) + (&mut self.0.data.ctx, &mut self.0.precompiles) } } diff --git a/crates/optimism/src/handler.rs b/crates/optimism/src/handler.rs index 87f04ce9ab..4fdc92166c 100644 --- a/crates/optimism/src/handler.rs +++ b/crates/optimism/src/handler.rs @@ -10,6 +10,7 @@ use crate::{ }, L1BlockInfo, OpHaltReason, OpSpecId, }; +use inspector::{EthInspectorHandler, Inspector, InspectorEvmTrait, InspectorFrameTrait}; use precompile::Log; use revm::{ context_interface::{ @@ -18,7 +19,6 @@ use revm::{ }, handler::{ handler::{EthTraitError, EvmTrait}, - inspector::{EthInspectorHandler, Inspector, InspectorFrame}, validation::validate_tx_against_account, EthHandler, Frame, FrameResult, MainnetHandler, }, @@ -73,7 +73,7 @@ where ERROR: EthTraitError + From + FromStringError + IsTxError, // TODO `FrameResult` should be a generic trait. // TODO `FrameInit` should be a generic. - FRAME: Frame, + FRAME: Frame, { type Evm = EVM; type Error = ERROR; @@ -470,7 +470,7 @@ where impl EthInspectorHandler for OpHandler where - EVM: EvmTrait< + EVM: InspectorEvmTrait< Context: ContextTrait< Journal: Journal)>, Tx: OpTxTrait, @@ -482,8 +482,13 @@ where ERROR: EthTraitError + From + FromStringError + IsTxError, // TODO `FrameResult` should be a generic trait. // TODO `FrameInit` should be a generic. - FRAME: Frame - + InspectorFrame, + FRAME: InspectorFrameTrait< + Evm = EVM, + Error = ERROR, + FrameResult = FrameResult, + FrameInit = FrameInput, + IT = EthInterpreter, + >, { type IT = EthInterpreter; } diff --git a/crates/revm/src/exec_inspect.rs b/crates/revm/src/exec_inspect.rs index bbc408f595..95025f7c5e 100644 --- a/crates/revm/src/exec_inspect.rs +++ b/crates/revm/src/exec_inspect.rs @@ -24,51 +24,3 @@ pub trait ExecuteCommitEvm: ExecuteEvm { self.transact_commit_previous() } } - -pub trait InspectEvm: ExecuteEvm { - type Inspector; - - fn set_inspector(&mut self, inspector: Self::Inspector); - - fn inspect_previous(&mut self) -> Self::Output; - - fn inspect_previous_with_inspector(&mut self, inspector: Self::Inspector) -> Self::Output { - self.set_inspector(inspector); - self.inspect_previous() - } - - fn inspect_previous_with_tx(&mut self, tx: ::Tx) -> Self::Output { - self.set_tx(tx); - self.inspect_previous() - } - - fn inspect( - &mut self, - tx: ::Tx, - inspector: Self::Inspector, - ) -> Self::Output { - self.set_tx(tx); - self.inspect_previous_with_inspector(inspector) - } -} - -pub trait InspectCommitEvm: InspectEvm + ExecuteCommitEvm { - fn inspect_commit_previous(&mut self) -> Self::CommitOutput; - - fn inspect_commit_previous_with_inspector( - &mut self, - inspector: Self::Inspector, - ) -> Self::CommitOutput { - self.set_inspector(inspector); - self.inspect_commit_previous() - } - - fn inspect_commit( - &mut self, - tx: ::Tx, - inspector: Self::Inspector, - ) -> Self::CommitOutput { - self.set_tx(tx); - self.inspect_commit_previous_with_inspector(inspector) - } -} diff --git a/crates/revm/src/lib.rs b/crates/revm/src/lib.rs index 46335ef25f..cadc161584 100644 --- a/crates/revm/src/lib.rs +++ b/crates/revm/src/lib.rs @@ -21,12 +21,12 @@ pub use state; mod exec_inspect; mod mainnet_builder; -mod mainnet_exec_inspect; +mod mainnet_exec; // Export items. pub use context::journaled_state::{JournalEntry, JournaledState}; pub use context::Context; pub use database_interface::{Database, DatabaseCommit, DatabaseRef}; -pub use exec_inspect::{ExecuteCommitEvm, ExecuteEvm, InspectCommitEvm, InspectEvm}; +pub use exec_inspect::{ExecuteCommitEvm, ExecuteEvm}; pub use mainnet_builder::{MainBuilder, MainContext, MainnetEvm}; diff --git a/crates/revm/src/mainnet_builder.rs b/crates/revm/src/mainnet_builder.rs index 56c6cdd1b8..ef0b6e2992 100644 --- a/crates/revm/src/mainnet_builder.rs +++ b/crates/revm/src/mainnet_builder.rs @@ -1,20 +1,20 @@ use context::{BlockEnv, Cfg, CfgEnv, Context, Evm, EvmData, JournaledState, TxEnv}; use context_interface::{Block, Database, Journal, Transaction}; use database_interface::EmptyDB; -use handler::{instructions::EthInstructions, noop::NoOpInspector, EthPrecompiles}; +use handler::{instructions::EthInstructions, EthPrecompiles}; use interpreter::interpreter::EthInterpreter; use primitives::Log; use specification::hardfork::SpecId; use state::EvmState; use std::vec::Vec; -pub type MainnetEvm = +pub type MainnetEvm = Evm, EthPrecompiles>; pub trait MainBuilder: Sized { type Context; - fn build_mainnet(self) -> MainnetEvm; + fn build_mainnet(self) -> MainnetEvm; fn build_mainnet_with_inspector(self, inspector: INSP) -> MainnetEvm; @@ -30,13 +30,12 @@ where { type Context = Self; - fn build_mainnet(self) -> MainnetEvm { + fn build_mainnet(self) -> MainnetEvm { Evm { data: EvmData { ctx: self, - inspector: NoOpInspector {}, + inspector: (), }, - enabled_inspection: false, instruction: EthInstructions::default(), precompiles: EthPrecompiles::default(), } @@ -51,7 +50,6 @@ where ctx: self, inspector, }, - enabled_inspection: true, instruction: EthInstructions::default(), precompiles: EthPrecompiles::default(), } diff --git a/crates/revm/src/mainnet_exec_inspect.rs b/crates/revm/src/mainnet_exec.rs similarity index 64% rename from crates/revm/src/mainnet_exec_inspect.rs rename to crates/revm/src/mainnet_exec.rs index 2dc12d4f7d..7f20065df2 100644 --- a/crates/revm/src/mainnet_exec_inspect.rs +++ b/crates/revm/src/mainnet_exec.rs @@ -1,5 +1,4 @@ use crate::{exec_inspect::ExecuteCommitEvm, ExecuteEvm}; -use crate::{InspectCommitEvm, InspectEvm}; use context::setters::ContextSetters; use context::Evm; use context_interface::{ @@ -7,11 +6,8 @@ use context_interface::{ ContextTrait, Database, Journal, }; use database_interface::DatabaseCommit; -use handler::inspector::JournalExt; -use handler::PrecompileProvider; -use handler::{handler::EvmTrait, inspector::EthInspectorHandler}; use handler::{ - inspector::Inspector, instructions::EthInstructions, EthFrame, EthHandler, MainnetHandler, + instructions::EthInstructions, EthFrame, EthHandler, MainnetHandler, PrecompileProvider, }; use interpreter::interpreter::EthInterpreter; @@ -23,9 +19,7 @@ use std::vec::Vec; impl ExecuteEvm for Evm, PRECOMPILES> where - CTX: ContextSetters - + ContextTrait)> + JournalExt>, - INSP: Inspector, + CTX: ContextSetters + ContextTrait)>>, PRECOMPILES: PrecompileProvider, { type Output = Result< @@ -43,11 +37,7 @@ impl ExecuteCommitEvm for Evm, PRECOMPILES> where CTX: ContextSetters - + ContextTrait< - Journal: Journal)> + JournalExt, - Db: DatabaseCommit, - >, - INSP: Inspector, + + ContextTrait)>, Db: DatabaseCommit>, PRECOMPILES: PrecompileProvider, { type CommitOutput = Result< @@ -63,48 +53,6 @@ where } } -impl InspectEvm - for Evm, PRECOMPILES> -where - CTX: ContextSetters - + ContextTrait)> + JournalExt>, - INSP: Inspector, - PRECOMPILES: PrecompileProvider, -{ - type Inspector = INSP; - - fn set_inspector(&mut self, inspector: Self::Inspector) { - self.data.inspector = inspector; - } - - fn inspect_previous(&mut self) -> Self::Output { - let mut t = MainnetHandler::<_, _, EthFrame<_, _, _>> { - _phantom: core::marker::PhantomData, - }; - - t.inspect_run(self) - } -} - -impl InspectCommitEvm - for Evm, PRECOMPILES> -where - CTX: ContextSetters - + ContextTrait< - Journal: Journal)> + JournalExt, - Db: DatabaseCommit, - >, - INSP: Inspector, - PRECOMPILES: PrecompileProvider, -{ - fn inspect_commit_previous(&mut self) -> Self::CommitOutput { - self.inspect_previous().map(|r| { - self.ctx().db().commit(r.state); - r.result - }) - } -} - #[cfg(test)] mod test { use super::*; diff --git a/examples/block_traces/src/main.rs b/examples/block_traces/src/main.rs index 02e1349b9d..e516bc212c 100644 --- a/examples/block_traces/src/main.rs +++ b/examples/block_traces/src/main.rs @@ -9,10 +9,9 @@ use alloy_provider::{ }; use database::{AlloyDB, CacheDB, StateBuilder}; use indicatif::ProgressBar; -use inspector::inspectors::TracerEip3155; +use inspector::{inspectors::TracerEip3155, InspectEvm}; use revm::{ - database_interface::WrapDatabaseAsync, primitives::TxKind, Context, InspectEvm, MainBuilder, - MainContext, + database_interface::WrapDatabaseAsync, primitives::TxKind, Context, MainBuilder, MainContext, }; use std::fs::OpenOptions; use std::io::BufWriter; diff --git a/examples/erc20_gas/src/exec.rs b/examples/erc20_gas/src/exec.rs index f809e484b9..b606f38f7b 100644 --- a/examples/erc20_gas/src/exec.rs +++ b/examples/erc20_gas/src/exec.rs @@ -23,7 +23,7 @@ where Precompiles: PrecompileProvider, Instructions: InstructionProvider< Context = EVM::Context, - InterpreterTypes = EthInterpreter<()>, + InterpreterTypes = EthInterpreter, Output = InterpreterAction, >, >, @@ -43,7 +43,7 @@ where Precompiles: PrecompileProvider, Instructions: InstructionProvider< Context = EVM::Context, - InterpreterTypes = EthInterpreter<()>, + InterpreterTypes = EthInterpreter, Output = InterpreterAction, >, >, diff --git a/examples/erc20_gas/src/handler.rs b/examples/erc20_gas/src/handler.rs index 8297fa6227..34b33909bb 100644 --- a/examples/erc20_gas/src/handler.rs +++ b/examples/erc20_gas/src/handler.rs @@ -35,7 +35,7 @@ impl Default for Erc20MainetHandler { impl EthHandler for Erc20MainetHandler where EVM: EvmTrait)>>>, - FRAME: Frame, + FRAME: Frame, ERROR: EthTraitError, { type Evm = EVM;