From 880fd26ca13093810afc7f6d2e1e9617b44c0ecb Mon Sep 17 00:00:00 2001 From: clabby Date: Sat, 18 Nov 2023 11:55:50 -0500 Subject: [PATCH 1/2] chore: Upgrade `revm` --- Cargo.lock | 8 +- Cargo.toml | 4 +- .../revm/revm-inspectors/src/access_list.rs | 4 +- .../revm-inspectors/src/stack/maybe_owned.rs | 81 ++++++----- crates/revm/revm-inspectors/src/stack/mod.rs | 104 ++++++++------ .../revm-inspectors/src/tracing/fourbyte.rs | 19 ++- .../revm-inspectors/src/tracing/js/mod.rs | 131 ++++++++++++------ .../revm/revm-inspectors/src/tracing/mod.rs | 124 +++++++++-------- .../revm-inspectors/src/tracing/opcount.rs | 4 +- crates/rpc/rpc/src/eth/revm_utils.rs | 10 +- 10 files changed, 286 insertions(+), 203 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 89e2cd91e499..97d5f75d3696 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6635,7 +6635,7 @@ dependencies = [ [[package]] name = "revm" version = "3.5.0" -source = "git+https://github.com/bluealloy/revm?rev=1609e07c68048909ad1682c98cf2b9baa76310b5#1609e07c68048909ad1682c98cf2b9baa76310b5" +source = "git+https://github.com/clabby/revm?branch=cl/canyon-hardfork#2731282f33d06c35fcba15450b5014ba18cef586" dependencies = [ "auto_impl", "revm-interpreter", @@ -6645,7 +6645,7 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "1.3.0" -source = "git+https://github.com/bluealloy/revm?rev=1609e07c68048909ad1682c98cf2b9baa76310b5#1609e07c68048909ad1682c98cf2b9baa76310b5" +source = "git+https://github.com/clabby/revm?branch=cl/canyon-hardfork#2731282f33d06c35fcba15450b5014ba18cef586" dependencies = [ "revm-primitives", ] @@ -6653,7 +6653,7 @@ dependencies = [ [[package]] name = "revm-precompile" version = "2.2.0" -source = "git+https://github.com/bluealloy/revm?rev=1609e07c68048909ad1682c98cf2b9baa76310b5#1609e07c68048909ad1682c98cf2b9baa76310b5" +source = "git+https://github.com/clabby/revm?branch=cl/canyon-hardfork#2731282f33d06c35fcba15450b5014ba18cef586" dependencies = [ "aurora-engine-modexp", "c-kzg", @@ -6669,7 +6669,7 @@ dependencies = [ [[package]] name = "revm-primitives" version = "1.3.0" -source = "git+https://github.com/bluealloy/revm?rev=1609e07c68048909ad1682c98cf2b9baa76310b5#1609e07c68048909ad1682c98cf2b9baa76310b5" +source = "git+https://github.com/clabby/revm?branch=cl/canyon-hardfork#2731282f33d06c35fcba15450b5014ba18cef586" dependencies = [ "alloy-primitives", "alloy-rlp", diff --git a/Cargo.toml b/Cargo.toml index d0bbf106e879..373b0609a627 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -135,8 +135,8 @@ reth-transaction-pool = { path = "crates/transaction-pool" } reth-trie = { path = "crates/trie" } # revm -revm = { git = "https://github.com/bluealloy/revm", rev = "1609e07c68048909ad1682c98cf2b9baa76310b5" } -revm-primitives = { git = "https://github.com/bluealloy/revm", rev = "1609e07c68048909ad1682c98cf2b9baa76310b5" } +revm = { git = "https://github.com/clabby/revm", branch = "cl/canyon-hardfork" } +revm-primitives = { git = "https://github.com/clabby/revm", branch = "cl/canyon-hardfork" } # eth alloy-primitives = "0.4" diff --git a/crates/revm/revm-inspectors/src/access_list.rs b/crates/revm/revm-inspectors/src/access_list.rs index 6eb0c0b3fa3e..660b75bb4c8b 100644 --- a/crates/revm/revm-inspectors/src/access_list.rs +++ b/crates/revm/revm-inspectors/src/access_list.rs @@ -1,7 +1,7 @@ use reth_primitives::{AccessList, AccessListItem, Address, B256}; use revm::{ interpreter::{opcode, Interpreter}, - Database, EVMData, Inspector, + Database, EvmContext, Inspector, }; use std::collections::{BTreeSet, HashMap, HashSet}; @@ -61,7 +61,7 @@ impl Inspector for AccessListInspector where DB: Database, { - fn step(&mut self, interpreter: &mut Interpreter<'_>, _data: &mut EVMData<'_, DB>) { + fn step(&mut self, interpreter: &mut Interpreter, _context: &mut EvmContext<'_, DB>) { match interpreter.current_opcode() { opcode::SLOAD | opcode::SSTORE => { if let Ok(slot) = interpreter.stack().peek(0) { diff --git a/crates/revm/revm-inspectors/src/stack/maybe_owned.rs b/crates/revm/revm-inspectors/src/stack/maybe_owned.rs index f29b44090a0d..4d6eeb592c38 100644 --- a/crates/revm/revm-inspectors/src/stack/maybe_owned.rs +++ b/crates/revm/revm-inspectors/src/stack/maybe_owned.rs @@ -1,11 +1,14 @@ use reth_primitives::U256; use revm::{ - interpreter::{CallInputs, CreateInputs, Gas, InstructionResult, Interpreter}, + interpreter::{ + CallInputs, CreateInputs, Gas, InstructionResult, Interpreter, InterpreterResult, + }, primitives::{db::Database, Address, Bytes, B256}, - EVMData, Inspector, + EvmContext, Inspector, }; use std::{ cell::{Ref, RefCell}, + ops::Range, rc::Rc, }; @@ -69,14 +72,16 @@ where DB: Database, INSP: Inspector, { - fn initialize_interp(&mut self, interp: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { + fn initialize_interp(&mut self, interp: &mut Interpreter, context: &mut EvmContext<'_, DB>) { match self { - MaybeOwnedInspector::Owned(insp) => insp.borrow_mut().initialize_interp(interp, data), + MaybeOwnedInspector::Owned(insp) => { + insp.borrow_mut().initialize_interp(interp, context) + } MaybeOwnedInspector::Stacked(_) => {} } } - fn step(&mut self, interp: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { + fn step(&mut self, interp: &mut Interpreter, data: &mut EvmContext<'_, DB>) { match self { MaybeOwnedInspector::Owned(insp) => insp.borrow_mut().step(interp, data), MaybeOwnedInspector::Stacked(_) => {} @@ -85,86 +90,92 @@ where fn log( &mut self, - evm_data: &mut EVMData<'_, DB>, + context: &mut EvmContext<'_, DB>, address: &Address, topics: &[B256], data: &Bytes, ) { match self { MaybeOwnedInspector::Owned(insp) => { - return insp.borrow_mut().log(evm_data, address, topics, data) + return insp.borrow_mut().log(context, address, topics, data) } MaybeOwnedInspector::Stacked(_) => {} } } - fn step_end(&mut self, interp: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { + fn step_end(&mut self, interp: &mut Interpreter, context: &mut EvmContext<'_, DB>) { match self { - MaybeOwnedInspector::Owned(insp) => insp.borrow_mut().step_end(interp, data), + MaybeOwnedInspector::Owned(insp) => insp.borrow_mut().step_end(interp, context), MaybeOwnedInspector::Stacked(_) => {} } } fn call( &mut self, - data: &mut EVMData<'_, DB>, + context: &mut EvmContext<'_, DB>, inputs: &mut CallInputs, - ) -> (InstructionResult, Gas, Bytes) { + ) -> Option<(InterpreterResult, Range)> { match self { - MaybeOwnedInspector::Owned(insp) => return insp.borrow_mut().call(data, inputs), + MaybeOwnedInspector::Owned(insp) => return insp.borrow_mut().call(context, inputs), MaybeOwnedInspector::Stacked(_) => {} } - (InstructionResult::Continue, Gas::new(0), Bytes::new()) + Some(( + InterpreterResult { + result: InstructionResult::Continue, + gas: Gas::new(0), + output: Bytes::new(), + }, + 0..0, + )) } fn call_end( &mut self, - data: &mut EVMData<'_, DB>, - inputs: &CallInputs, - remaining_gas: Gas, - ret: InstructionResult, - out: Bytes, - ) -> (InstructionResult, Gas, Bytes) { + context: &mut EvmContext<'_, DB>, + result: InterpreterResult, + ) -> InterpreterResult { match self { - MaybeOwnedInspector::Owned(insp) => { - return insp.borrow_mut().call_end(data, inputs, remaining_gas, ret, out) - } + MaybeOwnedInspector::Owned(insp) => return insp.borrow_mut().call_end(context, result), MaybeOwnedInspector::Stacked(_) => {} } - (ret, remaining_gas, out) + result } fn create( &mut self, - data: &mut EVMData<'_, DB>, + context: &mut EvmContext<'_, DB>, inputs: &mut CreateInputs, - ) -> (InstructionResult, Option
, Gas, Bytes) { + ) -> Option<(InterpreterResult, Option
)> { match self { - MaybeOwnedInspector::Owned(insp) => return insp.borrow_mut().create(data, inputs), + MaybeOwnedInspector::Owned(insp) => return insp.borrow_mut().create(context, inputs), MaybeOwnedInspector::Stacked(_) => {} } - (InstructionResult::Continue, None, Gas::new(0), Bytes::default()) + Some(( + InterpreterResult { + result: InstructionResult::Continue, + gas: Gas::new(0), + output: Bytes::new(), + }, + None, + )) } fn create_end( &mut self, - data: &mut EVMData<'_, DB>, - inputs: &CreateInputs, - ret: InstructionResult, + context: &mut EvmContext<'_, DB>, + result: InterpreterResult, address: Option
, - remaining_gas: Gas, - out: Bytes, - ) -> (InstructionResult, Option
, Gas, Bytes) { + ) -> (InterpreterResult, Option
) { match self { MaybeOwnedInspector::Owned(insp) => { - return insp.borrow_mut().create_end(data, inputs, ret, address, remaining_gas, out) + return insp.borrow_mut().create_end(context, result, address) } MaybeOwnedInspector::Stacked(_) => {} } - (ret, address, remaining_gas, out) + (result, address) } fn selfdestruct(&mut self, contract: Address, target: Address, value: U256) { diff --git a/crates/revm/revm-inspectors/src/stack/mod.rs b/crates/revm/revm-inspectors/src/stack/mod.rs index 603fe1d692c0..ee896e50331a 100644 --- a/crates/revm/revm-inspectors/src/stack/mod.rs +++ b/crates/revm/revm-inspectors/src/stack/mod.rs @@ -1,11 +1,13 @@ use reth_primitives::{Address, Bytes, TxHash, B256, U256}; use revm::{ inspectors::CustomPrintTracer, - interpreter::{CallInputs, CreateInputs, Gas, InstructionResult, Interpreter}, + interpreter::{ + CallInputs, CreateInputs, Gas, InstructionResult, Interpreter, InterpreterResult, + }, primitives::Env, - Database, EVMData, Inspector, + Database, EvmContext, Inspector, }; -use std::fmt::Debug; +use std::{fmt::Debug, ops::Range}; /// A wrapped [Inspector] that can be reused in the stack mod maybe_owned; @@ -100,13 +102,13 @@ impl Inspector for InspectorStack where DB: Database, { - fn initialize_interp(&mut self, interpreter: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { + fn initialize_interp(&mut self, interpreter: &mut Interpreter, data: &mut EvmContext<'_, DB>) { call_inspectors!(inspector, [&mut self.custom_print_tracer], { inspector.initialize_interp(interpreter, data); }); } - fn step(&mut self, interpreter: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { + fn step(&mut self, interpreter: &mut Interpreter, data: &mut EvmContext<'_, DB>) { call_inspectors!(inspector, [&mut self.custom_print_tracer], { inspector.step(interpreter, data); }); @@ -114,17 +116,17 @@ where fn log( &mut self, - evm_data: &mut EVMData<'_, DB>, + context: &mut EvmContext<'_, DB>, address: &Address, topics: &[B256], data: &Bytes, ) { call_inspectors!(inspector, [&mut self.custom_print_tracer], { - inspector.log(evm_data, address, topics, data); + inspector.log(context, address, topics, data); }); } - fn step_end(&mut self, interpreter: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { + fn step_end(&mut self, interpreter: &mut Interpreter, data: &mut EvmContext<'_, DB>) { call_inspectors!(inspector, [&mut self.custom_print_tracer], { inspector.step_end(interpreter, data); }); @@ -132,79 +134,89 @@ where fn call( &mut self, - data: &mut EVMData<'_, DB>, + context: &mut EvmContext<'_, DB>, inputs: &mut CallInputs, - ) -> (InstructionResult, Gas, Bytes) { + ) -> Option<(InterpreterResult, Range)> { call_inspectors!(inspector, [&mut self.custom_print_tracer], { - let (status, gas, retdata) = inspector.call(data, inputs); - - // Allow inspectors to exit early - if status != InstructionResult::Continue { - return (status, gas, retdata) + if let Some((interp_result, range)) = inspector.call(context, inputs) { + // Allow inspectors to exit early + if interp_result.result != InstructionResult::Continue { + return Some((interp_result, range)); + } } }); - (InstructionResult::Continue, Gas::new(inputs.gas_limit), Bytes::new()) + Some(( + InterpreterResult { + result: InstructionResult::Continue, + gas: Gas::new(inputs.gas_limit), + output: Bytes::new(), + }, + 0..0, + )) } fn call_end( &mut self, - data: &mut EVMData<'_, DB>, - inputs: &CallInputs, - remaining_gas: Gas, - ret: InstructionResult, - out: Bytes, - ) -> (InstructionResult, Gas, Bytes) { + context: &mut EvmContext<'_, DB>, + result: InterpreterResult, + ) -> InterpreterResult { call_inspectors!(inspector, [&mut self.custom_print_tracer], { - let (new_ret, new_gas, new_out) = - inspector.call_end(data, inputs, remaining_gas, ret, out.clone()); + let new_result = inspector.call_end(context, result.clone()); // If the inspector returns a different ret or a revert with a non-empty message, // we assume it wants to tell us something - if new_ret != ret || (new_ret == InstructionResult::Revert && new_out != out) { - return (new_ret, new_gas, new_out) + if new_result.result != result.result + || (new_result.result == InstructionResult::Revert + && new_result.output != result.output) + { + return new_result; } }); - (ret, remaining_gas, out) + result } fn create( &mut self, - data: &mut EVMData<'_, DB>, + context: &mut EvmContext<'_, DB>, inputs: &mut CreateInputs, - ) -> (InstructionResult, Option
, Gas, Bytes) { + ) -> Option<(InterpreterResult, Option
)> { call_inspectors!(inspector, [&mut self.custom_print_tracer], { - let (status, addr, gas, retdata) = inspector.create(data, inputs); - - // Allow inspectors to exit early - if status != InstructionResult::Continue { - return (status, addr, gas, retdata) + // let (status, addr, gas, retdata) = inspector.create(data, inputs); + if let Some((interp_result, range)) = inspector.create(context, inputs) { + // Allow inspectors to exit early + if interp_result.result != InstructionResult::Continue { + return Some((interp_result, range)); + } } }); - (InstructionResult::Continue, None, Gas::new(inputs.gas_limit), Bytes::new()) + Some(( + InterpreterResult { + result: InstructionResult::Continue, + gas: Gas::new(inputs.gas_limit), + output: Bytes::new(), + }, + None, + )) } fn create_end( &mut self, - data: &mut EVMData<'_, DB>, - inputs: &CreateInputs, - ret: InstructionResult, + context: &mut EvmContext<'_, DB>, + result: InterpreterResult, address: Option
, - remaining_gas: Gas, - out: Bytes, - ) -> (InstructionResult, Option
, Gas, Bytes) { + ) -> (InterpreterResult, Option
) { call_inspectors!(inspector, [&mut self.custom_print_tracer], { - let (new_ret, new_address, new_gas, new_retdata) = - inspector.create_end(data, inputs, ret, address, remaining_gas, out.clone()); + let (new_result, new_address) = inspector.create_end(context, result.clone(), address); - if new_ret != ret { - return (new_ret, new_address, new_gas, new_retdata) + if new_result.result != result.result { + return (new_result, new_address); } }); - (ret, address, remaining_gas, out) + (result, address) } fn selfdestruct(&mut self, contract: Address, target: Address, value: U256) { diff --git a/crates/revm/revm-inspectors/src/tracing/fourbyte.rs b/crates/revm/revm-inspectors/src/tracing/fourbyte.rs index 8d116b8d4fb9..3c14caf9927b 100644 --- a/crates/revm/revm-inspectors/src/tracing/fourbyte.rs +++ b/crates/revm/revm-inspectors/src/tracing/fourbyte.rs @@ -24,10 +24,10 @@ use reth_primitives::{hex, Bytes, Selector}; use reth_rpc_types::trace::geth::FourByteFrame; use revm::{ - interpreter::{CallInputs, Gas, InstructionResult}, - Database, EVMData, Inspector, + interpreter::{CallInputs, Gas, InstructionResult, InterpreterResult}, + Database, EvmContext, Inspector, }; -use std::collections::HashMap; +use std::{collections::HashMap, ops::Range}; /// Fourbyte tracing inspector that records all function selectors and their calldata sizes. #[derive(Debug, Clone, Default)] @@ -49,16 +49,23 @@ where { fn call( &mut self, - _data: &mut EVMData<'_, DB>, + _context: &mut EvmContext<'_, DB>, call: &mut CallInputs, - ) -> (InstructionResult, Gas, Bytes) { + ) -> Option<(InterpreterResult, Range)> { if call.input.len() >= 4 { let selector = Selector::try_from(&call.input[..4]).expect("input is at least 4 bytes"); let calldata_size = call.input[4..].len(); *self.inner.entry((selector, calldata_size)).or_default() += 1; } - (InstructionResult::Continue, Gas::new(0), Bytes::new()) + Some(( + InterpreterResult { + result: InstructionResult::Continue, + gas: Gas::new(0), + output: Bytes::new(), + }, + 0..0, + )) } } diff --git a/crates/revm/revm-inspectors/src/tracing/js/mod.rs b/crates/revm/revm-inspectors/src/tracing/js/mod.rs index 94adf1d44162..1b925e090c8c 100644 --- a/crates/revm/revm-inspectors/src/tracing/js/mod.rs +++ b/crates/revm/revm-inspectors/src/tracing/js/mod.rs @@ -15,11 +15,13 @@ use reth_primitives::{Account, Address, Bytes, B256, U256}; use revm::{ interpreter::{ return_revert, CallInputs, CallScheme, CreateInputs, Gas, InstructionResult, Interpreter, + InterpreterResult, }, precompile::Precompiles, primitives::{Env, ExecutionResult, Output, ResultAndState, TransactTo}, - Database, EVMData, Inspector, + Database, EvmContext as RevmEvmContext, Inspector, }; +use std::ops::Range; use tokio::sync::mpsc; pub(crate) mod bindings; @@ -92,7 +94,7 @@ impl JsInspector { .cloned() .ok_or(JsInspectorError::ResultFunctionMissing)?; if !result_fn.is_callable() { - return Err(JsInspectorError::ResultFunctionMissing) + return Err(JsInspectorError::ResultFunctionMissing); } let fault_fn = obj @@ -101,7 +103,7 @@ impl JsInspector { .cloned() .ok_or(JsInspectorError::ResultFunctionMissing)?; if !result_fn.is_callable() { - return Err(JsInspectorError::ResultFunctionMissing) + return Err(JsInspectorError::ResultFunctionMissing); } let enter_fn = obj.get("enter", &mut ctx)?.as_object().cloned().filter(|o| o.is_callable()); @@ -113,7 +115,7 @@ impl JsInspector { if let Some(setup_fn) = obj.get("setup", &mut ctx)?.as_object() { if !setup_fn.is_callable() { - return Err(JsInspectorError::SetupFunctionNotCallable) + return Err(JsInspectorError::SetupFunctionNotCallable); } // call setup() @@ -272,9 +274,9 @@ impl JsInspector { /// Registers the precompiles in the JS context fn register_precompiles(&mut self, precompiles: &Precompiles) { if !self.precompiles_registered { - return + return; } - let precompiles = PrecompileList(precompiles.addresses().into_iter().copied().collect()); + let precompiles = PrecompileList(precompiles.addresses().copied().collect()); let _ = precompiles.register_callable(&mut self.ctx); @@ -286,16 +288,16 @@ impl Inspector for JsInspector where DB: Database, { - fn step(&mut self, interp: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { + fn step(&mut self, interp: &mut Interpreter, data: &mut RevmEvmContext<'_, DB>) { if self.step_fn.is_none() { - return + return; } let (db, _db_guard) = EvmDbRef::new(&data.journaled_state.state, self.to_db_service.clone()); let (stack, _stack_guard) = StackRef::new(&interp.stack); - let (memory, _memory_guard) = MemoryRef::new(interp.shared_memory); + let (memory, _memory_guard) = MemoryRef::new(&interp.shared_memory); let step = StepLog { stack, op: interp.current_opcode().into(), @@ -316,16 +318,16 @@ where fn log( &mut self, - _evm_data: &mut EVMData<'_, DB>, + _evm_data: &mut RevmEvmContext<'_, DB>, _address: &Address, _topics: &[B256], _data: &Bytes, ) { } - fn step_end(&mut self, interp: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { + fn step_end(&mut self, interp: &mut Interpreter, data: &mut RevmEvmContext<'_, DB>) { if self.step_fn.is_none() { - return + return; } if matches!(interp.instruction_result, return_revert!()) { @@ -333,7 +335,7 @@ where EvmDbRef::new(&data.journaled_state.state, self.to_db_service.clone()); let (stack, _stack_guard) = StackRef::new(&interp.stack); - let (memory, _memory_guard) = MemoryRef::new(interp.shared_memory); + let (memory, _memory_guard) = MemoryRef::new(&interp.shared_memory); let step = StepLog { stack, op: interp.current_opcode().into(), @@ -353,10 +355,10 @@ where fn call( &mut self, - data: &mut EVMData<'_, DB>, + context: &mut RevmEvmContext<'_, DB>, inputs: &mut CallInputs, - ) -> (InstructionResult, Gas, Bytes) { - self.register_precompiles(&data.precompiles); + ) -> Option<(InterpreterResult, Range)> { + self.register_precompiles(&context.precompiles); // determine correct `from` and `to` based on the call scheme let (from, to) = match inputs.context.scheme { @@ -384,43 +386,61 @@ where gas: inputs.gas_limit, }; if let Err(err) = self.try_enter(frame) { - return (InstructionResult::Revert, Gas::new(0), err.to_string().into()) + return Some(( + InterpreterResult { + result: InstructionResult::Revert, + output: err.to_string().into(), + gas: Gas::new(0), + }, + 0..0, + )); } } - (InstructionResult::Continue, Gas::new(0), Bytes::new()) + Some(( + InterpreterResult { + result: InstructionResult::Continue, + gas: Gas::new(0), + output: Bytes::new(), + }, + 0..0, + )) } fn call_end( &mut self, - _data: &mut EVMData<'_, DB>, - _inputs: &CallInputs, - remaining_gas: Gas, - ret: InstructionResult, - out: Bytes, - ) -> (InstructionResult, Gas, Bytes) { + _context: &mut RevmEvmContext<'_, DB>, + result: InterpreterResult, + ) -> InterpreterResult { if self.exit_fn.is_some() { - let frame_result = - FrameResult { gas_used: remaining_gas.spend(), output: out.clone(), error: None }; + let frame_result = FrameResult { + gas_used: result.gas.spend(), + output: result.output.clone(), + error: None, + }; if let Err(err) = self.try_exit(frame_result) { - return (InstructionResult::Revert, Gas::new(0), err.to_string().into()) + return InterpreterResult { + result: InstructionResult::Revert, + output: err.to_string().into(), + gas: Gas::new(0), + }; } } self.pop_call(); - (ret, remaining_gas, out) + result } fn create( &mut self, - data: &mut EVMData<'_, DB>, + context: &mut RevmEvmContext<'_, DB>, inputs: &mut CreateInputs, - ) -> (InstructionResult, Option
, Gas, Bytes) { - self.register_precompiles(&data.precompiles); + ) -> Option<(InterpreterResult, Option
)> { + self.register_precompiles(&context.precompiles); - let _ = data.journaled_state.load_account(inputs.caller, data.db); - let nonce = data.journaled_state.account(inputs.caller).info.nonce; + let _ = context.journaled_state.load_account(inputs.caller, context.db); + let nonce = context.journaled_state.account(inputs.caller).info.nonce; let address = get_create_address(inputs, nonce); self.push_call( address, @@ -436,33 +456,54 @@ where let frame = CallFrame { contract: call.contract.clone(), kind: call.kind, gas: call.gas_limit }; if let Err(err) = self.try_enter(frame) { - return (InstructionResult::Revert, None, Gas::new(0), err.to_string().into()) + return Some(( + InterpreterResult { + result: InstructionResult::Revert, + gas: Gas::new(0), + output: err.to_string().into(), + }, + None, + )); } } - (InstructionResult::Continue, None, Gas::new(inputs.gas_limit), Bytes::default()) + Some(( + InterpreterResult { + result: InstructionResult::Continue, + gas: Gas::new(inputs.gas_limit), + output: Bytes::default(), + }, + None, + )) } fn create_end( &mut self, - _data: &mut EVMData<'_, DB>, - _inputs: &CreateInputs, - ret: InstructionResult, + _context: &mut RevmEvmContext<'_, DB>, + result: InterpreterResult, address: Option
, - remaining_gas: Gas, - out: Bytes, - ) -> (InstructionResult, Option
, Gas, Bytes) { + ) -> (InterpreterResult, Option
) { if self.exit_fn.is_some() { - let frame_result = - FrameResult { gas_used: remaining_gas.spend(), output: out.clone(), error: None }; + let frame_result = FrameResult { + gas_used: result.gas.spend(), + output: result.output.clone(), + error: None, + }; if let Err(err) = self.try_exit(frame_result) { - return (InstructionResult::Revert, None, Gas::new(0), err.to_string().into()) + return ( + InterpreterResult { + result: InstructionResult::Revert, + gas: Gas::new(0), + output: err.to_string().into(), + }, + None, + ); } } self.pop_call(); - (ret, address, remaining_gas, out) + (result, address) } fn selfdestruct(&mut self, _contract: Address, _target: Address, _value: U256) { diff --git a/crates/revm/revm-inspectors/src/tracing/mod.rs b/crates/revm/revm-inspectors/src/tracing/mod.rs index a947c42538c4..1b6ba87c9394 100644 --- a/crates/revm/revm-inspectors/src/tracing/mod.rs +++ b/crates/revm/revm-inspectors/src/tracing/mod.rs @@ -8,11 +8,12 @@ use revm::{ inspectors::GasInspector, interpreter::{ opcode, return_ok, CallInputs, CallScheme, CreateInputs, Gas, InstructionResult, - Interpreter, OpCode, + Interpreter, InterpreterResult, OpCode, }, primitives::SpecId, - Database, EVMData, Inspector, JournalEntry, + Database, EvmContext, Inspector, JournalEntry, }; +use std::ops::Range; use types::{CallTrace, CallTraceStep}; mod arena; @@ -127,13 +128,13 @@ impl TracingInspector { #[inline] fn is_precompile_call( &self, - data: &EVMData<'_, DB>, + data: &EvmContext<'_, DB>, to: &Address, value: U256, ) -> bool { if data.precompiles.contains(to) { // only if this is _not_ the root call - return self.is_deep() && value == U256::ZERO + return self.is_deep() && value == U256::ZERO; } false } @@ -177,7 +178,7 @@ impl TracingInspector { #[allow(clippy::too_many_arguments)] fn start_trace_on_call( &mut self, - data: &EVMData<'_, DB>, + data: &EvmContext<'_, DB>, address: Address, input_data: Bytes, value: U256, @@ -234,10 +235,8 @@ impl TracingInspector { /// This expects an existing trace [Self::start_trace_on_call] fn fill_trace_on_call_end( &mut self, - data: &EVMData<'_, DB>, - status: InstructionResult, - gas: &Gas, - output: Bytes, + context: &EvmContext<'_, DB>, + result: InterpreterResult, created_address: Option
, ) { let trace_idx = self.pop_trace_idx(); @@ -246,16 +245,17 @@ impl TracingInspector { if trace_idx == 0 { // this is the root call which should get the gas used of the transaction // refunds are applied after execution, which is when the root call ends - trace.gas_used = gas_used(data.env.cfg.spec_id, gas.spend(), gas.refunded() as u64); + trace.gas_used = + gas_used(context.env.cfg.spec_id, result.gas.spend(), result.gas.refunded() as u64); } else { - trace.gas_used = gas.spend(); + trace.gas_used = result.gas.spend(); } - trace.status = status; - trace.success = matches!(status, return_ok!()); - trace.output = output.clone(); + trace.status = result.result; + trace.success = matches!(result.result, return_ok!()); + trace.output = result.output.clone(); - self.last_call_return_data = Some(output); + self.last_call_return_data = Some(result.output); if let Some(address) = created_address { // A new contract was created via CREATE @@ -271,7 +271,7 @@ impl TracingInspector { /// /// This expects an existing [CallTrace], in other words, this panics if not within the context /// of a call. - fn start_step(&mut self, interp: &Interpreter<'_>, data: &EVMData<'_, DB>) { + fn start_step(&mut self, interp: &Interpreter, data: &EvmContext<'_, DB>) { let trace_idx = self.last_trace_idx(); let trace = &mut self.traces.arena[trace_idx]; @@ -319,8 +319,8 @@ impl TracingInspector { /// Invoked on [Inspector::step_end]. fn fill_step_on_step_end( &mut self, - interp: &Interpreter<'_>, - data: &EVMData<'_, DB>, + interp: &Interpreter, + data: &EvmContext<'_, DB>, ) { let StackStep { trace_idx, step_idx } = self.step_stack.pop().expect("can't fill step without starting a step first"); @@ -381,11 +381,11 @@ impl Inspector for TracingInspector where DB: Database, { - fn initialize_interp(&mut self, interp: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { + fn initialize_interp(&mut self, interp: &mut Interpreter, data: &mut EvmContext<'_, DB>) { self.gas_inspector.initialize_interp(interp, data) } - fn step(&mut self, interp: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { + fn step(&mut self, interp: &mut Interpreter, data: &mut EvmContext<'_, DB>) { if self.config.record_steps { self.gas_inspector.step(interp, data); self.start_step(interp, data); @@ -394,12 +394,12 @@ where fn log( &mut self, - evm_data: &mut EVMData<'_, DB>, + context: &mut EvmContext<'_, DB>, address: &Address, topics: &[B256], data: &Bytes, ) { - self.gas_inspector.log(evm_data, address, topics, data); + self.gas_inspector.log(context, address, topics, data); let trace_idx = self.last_trace_idx(); let trace = &mut self.traces.arena[trace_idx]; @@ -410,7 +410,7 @@ where } } - fn step_end(&mut self, interp: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { + fn step_end(&mut self, interp: &mut Interpreter, data: &mut EvmContext<'_, DB>) { if self.config.record_steps { self.gas_inspector.step_end(interp, data); self.fill_step_on_step_end(interp, data); @@ -419,10 +419,10 @@ where fn call( &mut self, - data: &mut EVMData<'_, DB>, + context: &mut EvmContext<'_, DB>, inputs: &mut CallInputs, - ) -> (InstructionResult, Gas, Bytes) { - self.gas_inspector.call(data, inputs); + ) -> Option<(InterpreterResult, Range)> { + self.gas_inspector.call(context, inputs); // determine correct `from` and `to` based on the call scheme let (from, to) = match inputs.context.scheme { @@ -444,11 +444,13 @@ where }; // if calls to precompiles should be excluded, check whether this is a call to a precompile - let maybe_precompile = - self.config.exclude_precompile_calls.then(|| self.is_precompile_call(data, &to, value)); + let maybe_precompile = self + .config + .exclude_precompile_calls + .then(|| self.is_precompile_call(context, &to, value)); self.start_trace_on_call( - data, + context, to, inputs.input.clone(), value, @@ -458,35 +460,39 @@ where maybe_precompile, ); - (InstructionResult::Continue, Gas::new(0), Bytes::new()) + Some(( + InterpreterResult { + result: InstructionResult::Continue, + gas: Gas::new(0), + output: Bytes::new(), + }, + 0..0, + )) } fn call_end( &mut self, - data: &mut EVMData<'_, DB>, - inputs: &CallInputs, - gas: Gas, - ret: InstructionResult, - out: Bytes, - ) -> (InstructionResult, Gas, Bytes) { - self.gas_inspector.call_end(data, inputs, gas, ret, out.clone()); + context: &mut EvmContext<'_, DB>, + result: InterpreterResult, + ) -> InterpreterResult { + self.gas_inspector.call_end(context, result.clone()); - self.fill_trace_on_call_end(data, ret, &gas, out.clone(), None); + self.fill_trace_on_call_end(context, result.clone(), None); - (ret, gas, out) + result } fn create( &mut self, - data: &mut EVMData<'_, DB>, + context: &mut EvmContext<'_, DB>, inputs: &mut CreateInputs, - ) -> (InstructionResult, Option
, Gas, Bytes) { - self.gas_inspector.create(data, inputs); + ) -> Option<(InterpreterResult, Option
)> { + self.gas_inspector.create(context, inputs); - let _ = data.journaled_state.load_account(inputs.caller, data.db); - let nonce = data.journaled_state.account(inputs.caller).info.nonce; + let _ = context.journaled_state.load_account(inputs.caller, context.db); + let nonce = context.journaled_state.account(inputs.caller).info.nonce; self.start_trace_on_call( - data, + context, get_create_address(inputs, nonce), inputs.init_code.clone(), inputs.value, @@ -496,7 +502,14 @@ where Some(false), ); - (InstructionResult::Continue, None, Gas::new(inputs.gas_limit), Bytes::default()) + Some(( + InterpreterResult { + result: InstructionResult::Continue, + gas: Gas::new(inputs.gas_limit), + output: Bytes::new(), + }, + None, + )) } /// Called when a contract has been created. @@ -505,19 +518,17 @@ where /// remaining_gas, address, out)`) will alter the result of the create. fn create_end( &mut self, - data: &mut EVMData<'_, DB>, - inputs: &CreateInputs, - status: InstructionResult, + context: &mut EvmContext<'_, DB>, + mut result: InterpreterResult, address: Option
, - gas: Gas, - retdata: Bytes, - ) -> (InstructionResult, Option
, Gas, Bytes) { - self.gas_inspector.create_end(data, inputs, status, address, gas, retdata.clone()); + ) -> (InterpreterResult, Option
) { + self.gas_inspector.create_end(context, result.clone(), address); // get the code of the created contract let code = address .and_then(|address| { - data.journaled_state + context + .journaled_state .account(address) .info .code @@ -525,10 +536,11 @@ where .map(|code| code.bytes()[..code.len()].to_vec()) }) .unwrap_or_default(); + result.output = code.into(); - self.fill_trace_on_call_end(data, status, &gas, code.into(), address); + self.fill_trace_on_call_end(context, result.clone(), address); - (status, address, gas, retdata) + (result, address) } fn selfdestruct(&mut self, _contract: Address, target: Address, _value: U256) { diff --git a/crates/revm/revm-inspectors/src/tracing/opcount.rs b/crates/revm/revm-inspectors/src/tracing/opcount.rs index 2088f2165299..98b332c672b4 100644 --- a/crates/revm/revm-inspectors/src/tracing/opcount.rs +++ b/crates/revm/revm-inspectors/src/tracing/opcount.rs @@ -2,7 +2,7 @@ //! //! See also -use revm::{interpreter::Interpreter, Database, EVMData, Inspector}; +use revm::{interpreter::Interpreter, Database, EvmContext, Inspector}; /// An inspector that counts all opcodes. #[derive(Debug, Clone, Copy, Default)] @@ -23,7 +23,7 @@ impl Inspector for OpcodeCountInspector where DB: Database, { - fn step(&mut self, _interp: &mut Interpreter<'_>, _data: &mut EVMData<'_, DB>) { + fn step(&mut self, _interp: &mut Interpreter, _data: &mut EvmContext<'_, DB>) { self.count += 1; } } diff --git a/crates/rpc/rpc/src/eth/revm_utils.rs b/crates/rpc/rpc/src/eth/revm_utils.rs index bbfb3b2d1753..20b202db9e76 100644 --- a/crates/rpc/rpc/src/eth/revm_utils.rs +++ b/crates/rpc/rpc/src/eth/revm_utils.rs @@ -111,7 +111,7 @@ impl FillableTransaction for TransactionSigned { #[inline] pub(crate) fn get_precompiles(spec_id: SpecId) -> impl IntoIterator { let spec = PrecompilesSpecId::from_spec_id(spec_id); - Precompiles::new(spec).addresses().into_iter().copied().map(Address::from) + Precompiles::new(spec).addresses().copied().map(Address::from) } /// Executes the [Env] against the given [Database] without committing state changes. @@ -185,7 +185,7 @@ where for tx in transactions.into_iter() { if tx.hash() == target_tx_hash { // reached the target transaction - break + break; } tx.try_fill_tx_env(&mut evm.env.tx)?; @@ -281,7 +281,7 @@ pub(crate) fn build_call_evm_env( pub(crate) fn create_txn_env(block_env: &BlockEnv, request: CallRequest) -> EthResult { // Ensure that if versioned hashes are set, they're not empty if request.has_empty_blob_hashes() { - return Err(RpcInvalidTransactionError::BlobTransactionMissingBlobHashes.into()) + return Err(RpcInvalidTransactionError::BlobTransactionMissingBlobHashes.into()); } let CallRequest { @@ -429,7 +429,7 @@ impl CallFees { return Err( // `max_priority_fee_per_gas` is greater than the `max_fee_per_gas` RpcInvalidTransactionError::TipAboveFeeCap.into(), - ) + ); } } Ok(()) @@ -466,7 +466,7 @@ impl CallFees { // Ensure blob_hashes are present if !has_blob_hashes { // Blob transaction but no blob hashes - return Err(RpcInvalidTransactionError::BlobTransactionMissingBlobHashes.into()) + return Err(RpcInvalidTransactionError::BlobTransactionMissingBlobHashes.into()); } Ok(CallFees { From 14aba2a4192a3eeafd2dcea5c494f2ea108a7469 Mon Sep 17 00:00:00 2001 From: clabby Date: Sat, 18 Nov 2023 12:25:54 -0500 Subject: [PATCH 2/2] lint --- crates/revm/revm-inspectors/src/stack/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/revm/revm-inspectors/src/stack/mod.rs b/crates/revm/revm-inspectors/src/stack/mod.rs index ee896e50331a..9306080e7298 100644 --- a/crates/revm/revm-inspectors/src/stack/mod.rs +++ b/crates/revm/revm-inspectors/src/stack/mod.rs @@ -166,9 +166,9 @@ where // If the inspector returns a different ret or a revert with a non-empty message, // we assume it wants to tell us something - if new_result.result != result.result - || (new_result.result == InstructionResult::Revert - && new_result.output != result.output) + if new_result.result != result.result || + (new_result.result == InstructionResult::Revert && + new_result.output != result.output) { return new_result; }