From 35e5fd7fb5018f2ed62246db65e7c4609e1275ff Mon Sep 17 00:00:00 2001 From: "aurelien.foucault@lambda-coins.com" Date: Mon, 8 Dec 2025 12:33:06 +0100 Subject: [PATCH] Etherlink/Kernel: Change etherlink inspector to not used an enum and use trait-based instead --- .../revm/src/inspectors/call_tracer.rs | 11 + .../kernel_latest/revm/src/inspectors/mod.rs | 260 ++---------------- .../kernel_latest/revm/src/inspectors/noop.rs | 14 + .../revm/src/inspectors/struct_logger.rs | 11 + etherlink/kernel_latest/revm/src/lib.rs | 38 +-- 5 files changed, 86 insertions(+), 248 deletions(-) diff --git a/etherlink/kernel_latest/revm/src/inspectors/call_tracer.rs b/etherlink/kernel_latest/revm/src/inspectors/call_tracer.rs index 6f7aaa80320e..75c8df632a94 100644 --- a/etherlink/kernel_latest/revm/src/inspectors/call_tracer.rs +++ b/etherlink/kernel_latest/revm/src/inspectors/call_tracer.rs @@ -9,6 +9,7 @@ use crate::{ append_address, append_option_address, append_option_canonical, append_option_u64_le, append_u16_le, append_u256_le, append_u64_le, }, + inspectors::EtherlinkInspector, precompiles::provider::EtherlinkPrecompiles, }; @@ -118,6 +119,16 @@ impl Encodable for CallTrace { } } +impl<'a, Host: Runtime + 'a> EtherlinkInspector<'a, Host> for CallTracer { + fn is_struct_logger(&self) -> bool { + false + } + + fn get_transaction_hash(&self) -> Option { + self.transaction_hash + } +} + impl CallTrace { pub fn new_minimal_trace( type_: Vec, diff --git a/etherlink/kernel_latest/revm/src/inspectors/mod.rs b/etherlink/kernel_latest/revm/src/inspectors/mod.rs index 335e58c72ad7..1c76ebd9594c 100644 --- a/etherlink/kernel_latest/revm/src/inspectors/mod.rs +++ b/etherlink/kernel_latest/revm/src/inspectors/mod.rs @@ -2,12 +2,8 @@ // // SPDX-License-Identifier: MIT -use crate::{ - database::EtherlinkVMDB, precompiles::provider::EtherlinkPrecompiles, - EVMInnerContext, Error, -}; -use call_tracer::{CallTracer, CallTracerInput}; -use noop::NoInspector; +use crate::{precompiles::provider::EtherlinkPrecompiles, EVMInnerContext, Error}; +use call_tracer::CallTracerInput; use revm::{ context::{ result::{EVMError, ExecutionResult, HaltReason}, @@ -18,18 +14,12 @@ use revm::{ Handler, }, inspector::InspectorHandler, - interpreter::{ - interpreter::{EthInterpreter, ReturnDataImpl}, - interpreter_action::FrameInit, - interpreter_types::StackTr, - CallInputs, CallOutcome, CreateInputs, CreateOutcome, Interpreter, - InterpreterTypes, Stack, - }, + interpreter::{interpreter::EthInterpreter, interpreter_action::FrameInit, Stack}, primitives::B256, state::EvmState, ExecuteCommitEvm, ExecuteEvm, InspectEvm, Inspector, }; -use struct_logger::{StructLogger, StructLoggerInput}; +use struct_logger::StructLoggerInput; use tezos_evm_runtime::runtime::Runtime; pub mod call_tracer; @@ -39,19 +29,21 @@ pub mod struct_logger; pub const CALL_TRACER_CONFIG_PREFIX: u8 = 0x01; -pub type EvmInspection<'a, Host> = Evm< +pub type EvmInspection<'a, Host, INSP> = Evm< EVMInnerContext<'a, Host>, - EtherlinkInspector, + INSP, EthInstructions>, EtherlinkPrecompiles, EthFrame, >; -pub struct EtherlinkEvmInspector<'a, Host: Runtime> { - inner: EvmInspection<'a, Host>, +pub struct EtherlinkEvmInspector<'a, Host: Runtime, INSP: EtherlinkInspector<'a, Host>> { + inner: EvmInspection<'a, Host, INSP>, } -impl<'a, Host: Runtime> ExecuteEvm for EtherlinkEvmInspector<'a, Host> { +impl<'a, Host: Runtime, INSP: EtherlinkInspector<'a, Host>> ExecuteEvm + for EtherlinkEvmInspector<'a, Host, INSP> +{ type ExecutionResult = ExecutionResult; type State = EvmState; type Error = EVMError; @@ -83,7 +75,9 @@ impl<'a, Host: Runtime> ExecuteEvm for EtherlinkEvmInspector<'a, Host> { } } -impl<'a, Host: Runtime> ExecuteCommitEvm for EtherlinkEvmInspector<'a, Host> { +impl<'a, Host: Runtime, INSP: EtherlinkInspector<'a, Host>> ExecuteCommitEvm + for EtherlinkEvmInspector<'a, Host, INSP> +{ fn commit(&mut self, state: Self::State) { self.inner.commit(state); } @@ -126,8 +120,10 @@ where type IT = EthInterpreter; } -impl InspectEvm for EtherlinkEvmInspector<'_, Host> { - type Inspector = EtherlinkInspector; +impl<'a, Host: Runtime, INSP: EtherlinkInspector<'a, Host>> InspectEvm + for EtherlinkEvmInspector<'a, Host, INSP> +{ + type Inspector = INSP; fn set_inspector(&mut self, inspector: Self::Inspector) { self.inner.inspector = inspector; @@ -159,31 +155,22 @@ impl TracerInput { } } -pub enum EtherlinkInspector { - NoOp(NoInspector), - CallTracer(Box), - StructLogger(Box), +pub trait EtherlinkInspector<'a, Host: Runtime + 'a>: + Inspector> +{ + fn is_struct_logger(&self) -> bool; + fn get_transaction_hash(&self) -> Option; } -impl EtherlinkInspector { - pub fn is_struct_logger(&self) -> bool { - matches!(self, EtherlinkInspector::StructLogger(_)) - } - - pub fn get_transaction_hash(&self) -> Option { - match self { - EtherlinkInspector::NoOp(_) => None, - EtherlinkInspector::CallTracer(call_tracer) => call_tracer.transaction_hash, - EtherlinkInspector::StructLogger(struct_logger) => { - struct_logger.transaction_hash - } - } +impl<'a, Host: Runtime + 'a> EtherlinkInspector<'a, Host> + for Box> +{ + fn is_struct_logger(&self) -> bool { + self.as_ref().is_struct_logger() } -} -impl Default for EtherlinkInspector { - fn default() -> Self { - Self::NoOp(NoInspector) + fn get_transaction_hash(&self) -> Option { + self.as_ref().get_transaction_hash() } } @@ -202,193 +189,6 @@ impl StructStack for Stack { } } -impl<'a, Host, CTX, INTR> Inspector for EtherlinkInspector -where - Host: Runtime + 'a, - CTX: ContextTr>, - INTR: InterpreterTypes, -{ - fn call( - &mut self, - context: &mut CTX, - inputs: &mut CallInputs, - ) -> Option { - match self { - Self::NoOp(no_inspector) => { - >::call(no_inspector, context, inputs) - } - Self::CallTracer(call_tracer) => { - >::call(call_tracer, context, inputs) - } - Self::StructLogger(struct_logger) => { - >::call( - struct_logger, - context, - inputs, - ) - } - } - } - - fn call_end( - &mut self, - context: &mut CTX, - inputs: &CallInputs, - outcome: &mut CallOutcome, - ) { - match self { - Self::NoOp(no_inspector) => >::call_end( - no_inspector, - context, - inputs, - outcome, - ), - Self::CallTracer(call_tracer) => { - >::call_end( - call_tracer, - context, - inputs, - outcome, - ) - } - Self::StructLogger(struct_logger) => { - >::call_end( - struct_logger, - context, - inputs, - outcome, - ) - } - } - } - - fn create( - &mut self, - context: &mut CTX, - inputs: &mut CreateInputs, - ) -> Option { - match self { - Self::NoOp(no_inspector) => >::create( - no_inspector, - context, - inputs, - ), - Self::CallTracer(call_tracer) => { - >::create(call_tracer, context, inputs) - } - Self::StructLogger(struct_logger) => { - >::create( - struct_logger, - context, - inputs, - ) - } - } - } - - fn create_end( - &mut self, - context: &mut CTX, - inputs: &CreateInputs, - outcome: &mut CreateOutcome, - ) { - match self { - Self::NoOp(no_inspector) => { - >::create_end( - no_inspector, - context, - inputs, - outcome, - ) - } - Self::CallTracer(call_tracer) => { - >::create_end( - call_tracer, - context, - inputs, - outcome, - ) - } - Self::StructLogger(struct_logger) => { - >::create_end( - struct_logger, - context, - inputs, - outcome, - ) - } - } - } - - fn initialize_interp(&mut self, interp: &mut Interpreter, context: &mut CTX) { - match self { - Self::NoOp(no_inspector) => { - >::initialize_interp( - no_inspector, - interp, - context, - ) - } - Self::CallTracer(call_tracer) => { - >::initialize_interp( - call_tracer, - interp, - context, - ) - } - Self::StructLogger(struct_logger) => { - >::initialize_interp( - struct_logger, - interp, - context, - ) - } - } - } - - fn step(&mut self, interp: &mut Interpreter, context: &mut CTX) { - match self { - Self::NoOp(no_inspector) => { - >::step(no_inspector, interp, context) - } - Self::CallTracer(call_tracer) => { - >::step(call_tracer, interp, context) - } - Self::StructLogger(struct_logger) => { - >::step( - struct_logger, - interp, - context, - ) - } - } - } - - fn step_end(&mut self, interp: &mut Interpreter, context: &mut CTX) { - match self { - Self::NoOp(no_inspector) => >::step_end( - no_inspector, - interp, - context, - ), - Self::CallTracer(call_tracer) => { - >::step_end( - call_tracer, - interp, - context, - ) - } - Self::StructLogger(struct_logger) => { - >::step_end( - struct_logger, - interp, - context, - ) - } - } - } -} - pub fn get_tracer_configuration( tx_hash_target: B256, tracer_input: Option, diff --git a/etherlink/kernel_latest/revm/src/inspectors/noop.rs b/etherlink/kernel_latest/revm/src/inspectors/noop.rs index 89f31d3dbfcc..9e9b929127ad 100644 --- a/etherlink/kernel_latest/revm/src/inspectors/noop.rs +++ b/etherlink/kernel_latest/revm/src/inspectors/noop.rs @@ -5,8 +5,12 @@ use revm::{ context::ContextTr, interpreter::{interpreter_types::StackTr, InterpreterTypes}, + primitives::B256, Inspector, }; +use tezos_evm_runtime::runtime::Runtime; + +use crate::inspectors::EtherlinkInspector; pub struct NoInspector; @@ -16,3 +20,13 @@ where INTR: InterpreterTypes, { } + +impl<'a, Host: Runtime + 'a> EtherlinkInspector<'a, Host> for NoInspector { + fn is_struct_logger(&self) -> bool { + false + } + + fn get_transaction_hash(&self) -> Option { + None + } +} diff --git a/etherlink/kernel_latest/revm/src/inspectors/struct_logger.rs b/etherlink/kernel_latest/revm/src/inspectors/struct_logger.rs index 248f4281b778..f29d8018892c 100644 --- a/etherlink/kernel_latest/revm/src/inspectors/struct_logger.rs +++ b/etherlink/kernel_latest/revm/src/inspectors/struct_logger.rs @@ -5,6 +5,7 @@ use crate::{ database::EtherlinkVMDB, helpers::rlp::{append_option_canonical, append_u16_le, append_u64_le}, + inspectors::EtherlinkInspector, Error, }; @@ -205,6 +206,16 @@ impl StructLogger { } } +impl<'a, Host: Runtime + 'a> EtherlinkInspector<'a, Host> for StructLogger { + fn is_struct_logger(&self) -> bool { + true + } + + fn get_transaction_hash(&self) -> Option { + self.transaction_hash + } +} + impl<'a, Host, CTX, INTR> Inspector for StructLogger where Host: Runtime + 'a, diff --git a/etherlink/kernel_latest/revm/src/lib.rs b/etherlink/kernel_latest/revm/src/lib.rs index 2215cea000ff..f258ae28834a 100644 --- a/etherlink/kernel_latest/revm/src/lib.rs +++ b/etherlink/kernel_latest/revm/src/lib.rs @@ -4,7 +4,8 @@ // SPDX-License-Identifier: MIT use crate::{ - journal::Journal, precompiles::send_outbox_message::Withdrawal, + inspectors::EtherlinkInspector, journal::Journal, + precompiles::send_outbox_message::Withdrawal, storage::world_state_handler::StorageAccount, }; use database::EtherlinkVMDB; @@ -13,7 +14,7 @@ use inspectors::{ call_tracer::{CallTracer, CallTracerInput}, noop::NoInspector, struct_logger::{StructLogger, StructLoggerInput}, - EtherlinkInspector, EvmInspection, TracerInput, + EvmInspection, TracerInput, }; use precompiles::provider::EtherlinkPrecompiles; use revm::{ @@ -198,35 +199,35 @@ fn tx_env( } #[instrument(skip_all)] -fn get_inspector_from( +fn get_inspector_from<'a, Host: Runtime + 'a>( tracer_input: TracerInput, precompiles: EtherlinkPrecompiles, spec_id: SpecId, -) -> EtherlinkInspector { +) -> Box> { match tracer_input { TracerInput::CallTracer(CallTracerInput { config, transaction_hash, - }) => EtherlinkInspector::CallTracer(Box::new(CallTracer::new( + }) => Box::new(CallTracer::new( config, precompiles, spec_id, transaction_hash, - ))), + )) as Box>, TracerInput::StructLogger(StructLoggerInput { config, transaction_hash, - }) => EtherlinkInspector::StructLogger(Box::new(StructLogger::new( - config, - transaction_hash, - ))), - TracerInput::NoOp => EtherlinkInspector::NoOp(NoInspector), + }) => Box::new(StructLogger::new(config, transaction_hash)) + as Box>, + TracerInput::NoOp => { + Box::new(NoInspector) as Box> + } } } #[instrument(skip_all)] #[allow(clippy::too_many_arguments)] -fn evm_inspect<'a, Host: Runtime>( +fn evm_inspect<'a, Host: Runtime, INSP: EtherlinkInspector<'a, Host>>( db: EtherlinkVMDB<'a, Host>, block: &'a BlockEnv, tx: &'a TxEnv, @@ -234,9 +235,9 @@ fn evm_inspect<'a, Host: Runtime>( precompiles: EtherlinkPrecompiles, chain_id: u64, spec_id: SpecId, - inspector: EtherlinkInspector, + inspector: INSP, is_simulation: bool, -) -> EvmInspection<'a, Host> { +) -> EvmInspection<'a, Host, INSP> { let mut cfg = CfgEnv::new().with_chain_id(chain_id).with_spec(spec_id); cfg.disable_eip3607 = is_simulation; cfg.tx_gas_limit_cap = Some(maximum_gas_per_transaction); @@ -344,9 +345,6 @@ pub fn run_transaction<'a, Host: Runtime>( let db = EtherlinkVMDB::new(host, block_constants)?; if let Some(tracer_input) = tracer_input { - let inspector = - get_inspector_from(tracer_input, EtherlinkPrecompiles::new(), spec_id); - let mut evm = evm_inspect( db, &block_env, @@ -355,7 +353,11 @@ pub fn run_transaction<'a, Host: Runtime>( EtherlinkPrecompiles::new(), block_constants.chain_id.as_u64(), spec_id, - inspector, + get_inspector_from::( + tracer_input, + EtherlinkPrecompiles::new(), + spec_id, + ), is_simulation, ); -- GitLab