diff --git a/interpreter/src/etable.rs b/interpreter/src/etable.rs index 73d095123..8d38ded60 100644 --- a/interpreter/src/etable.rs +++ b/interpreter/src/etable.rs @@ -5,20 +5,28 @@ use crate::{ use core::marker::PhantomData; use core::ops::{Deref, DerefMut}; -pub trait EtableSet { +pub trait EtableSet { + type State; + type Handle; + type Trap; + fn eval( &self, - machine: &mut Machine, - handle: &mut H, + machine: &mut Machine, + handle: &mut Self::Handle, opcode: Opcode, position: usize, - ) -> Control; + ) -> Control; } -impl EtableSet for Etable +impl EtableSet for Etable where F: Fn(&mut Machine, &mut H, Opcode, usize) -> Control, { + type State = S; + type Handle = H; + type Trap = Tr; + fn eval( &self, machine: &mut Machine, @@ -30,11 +38,15 @@ where } } -impl EtableSet for (Etable, Etable) +impl EtableSet for (Etable, Etable) where F1: Fn(&mut Machine, &mut H, Opcode, usize) -> Control, F2: Fn(&mut Machine, &mut H, Opcode, usize) -> Control, { + type State = S; + type Handle = H; + type Trap = Tr; + fn eval( &self, machine: &mut Machine, diff --git a/interpreter/src/interpreter/etable.rs b/interpreter/src/interpreter/etable.rs index 6430aa63b..34344c7cd 100644 --- a/interpreter/src/interpreter/etable.rs +++ b/interpreter/src/interpreter/etable.rs @@ -31,7 +31,7 @@ impl<'etable, S, H, Tr, ES> DerefMut for EtableInterpreter<'etable, S, H, Tr, ES impl<'etable, S, H, Tr, ES> EtableInterpreter<'etable, S, H, Tr, ES> where - ES: EtableSet, + ES: EtableSet, { /// Return a reference of the program counter. pub const fn position(&self) -> usize { @@ -87,11 +87,12 @@ where } } -impl<'etable, S, H, Tr, ES> Interpreter for EtableInterpreter<'etable, S, H, Tr, ES> +impl<'etable, S, H, Tr, ES> Interpreter for EtableInterpreter<'etable, S, H, Tr, ES> where - ES: EtableSet, + ES: EtableSet, { type State = S; + type Handle = H; type Trap = Tr; fn machine(&self) -> &Machine { @@ -124,9 +125,9 @@ where } } -impl<'etable, S, H, Tr, ES> StepInterpreter for EtableInterpreter<'etable, S, H, Tr, ES> +impl<'etable, S, H, Tr, ES> StepInterpreter for EtableInterpreter<'etable, S, H, Tr, ES> where - ES: EtableSet, + ES: EtableSet, { #[inline] fn step(&mut self, handle: &mut H) -> Result<(), Capture> { diff --git a/interpreter/src/interpreter/mod.rs b/interpreter/src/interpreter/mod.rs index be7666d0d..e019ce56d 100644 --- a/interpreter/src/interpreter/mod.rs +++ b/interpreter/src/interpreter/mod.rs @@ -5,22 +5,24 @@ pub use self::etable::EtableInterpreter; use crate::{Capture, ExitResult, Machine}; use alloc::vec::Vec; -pub type StateFor = >::State; -pub type TrapFor = >::Trap; -pub type DeconstructFor = (StateFor, Vec); +pub type StateFor = ::State; +pub type TrapFor = ::Trap; +pub type HandleFor = ::Handle; +pub type DeconstructFor = (StateFor, Vec); -pub trait Interpreter { +pub trait Interpreter { type State; + type Handle; type Trap; fn machine(&self) -> &Machine; fn machine_mut(&mut self) -> &mut Machine; fn deconstruct(self) -> (Self::State, Vec); - fn run(&mut self, handle: &mut H) -> Capture; + fn run(&mut self, handle: &mut Self::Handle) -> Capture; fn advance(&mut self); } -pub trait StepInterpreter: Interpreter { - fn step(&mut self, handle: &mut H) -> Result<(), Capture>; +pub trait StepInterpreter: Interpreter { + fn step(&mut self, handle: &mut Self::Handle) -> Result<(), Capture>; } diff --git a/interpreter/src/trap.rs b/interpreter/src/trap.rs index 7c6e80342..42fdef172 100644 --- a/interpreter/src/trap.rs +++ b/interpreter/src/trap.rs @@ -297,14 +297,14 @@ impl CallTrapData { } } - pub fn feedback( + pub fn feedback( self, reason: ExitResult, retbuf: Vec, interpreter: &mut I, ) -> Result<(), ExitError> where - I: Interpreter, + I: Interpreter, I::State: AsRef + AsMut, { let target_len = min(self.out_len, U256::from(retbuf.len())); @@ -465,14 +465,14 @@ impl CreateTrapData { }) } - pub fn feedback>( + pub fn feedback( self, reason: Result, retbuf: Vec, interpreter: &mut I, ) -> Result<(), ExitError> where - I: Interpreter, + I: Interpreter, I::State: AsRef + AsMut, { let ret = match reason { diff --git a/src/call_stack.rs b/src/call_stack.rs index 5e9c0b0c7..b9b5498e9 100644 --- a/src/call_stack.rs +++ b/src/call_stack.rs @@ -1,4 +1,4 @@ -use crate::interpreter::{Interpreter, StepInterpreter, TrapFor}; +use crate::interpreter::{HandleFor, Interpreter, StepInterpreter, TrapFor}; use crate::{Capture, ExitError, ExitFatal, ExitResult, Invoker, InvokerControl}; use alloc::vec::Vec; use core::convert::Infallible; @@ -21,23 +21,23 @@ enum LastSubstackStatus { // Note: this should not be exposed to public because it does not implement // Drop. -struct CallStack<'backend, 'invoker, H, I: Invoker> { +struct CallStack<'backend, 'invoker, I: Invoker> { stack: Vec>, #[allow(clippy::type_complexity)] - last: Option>>, + last: Option>>, initial_depth: usize, - backend: &'backend mut H, + backend: &'backend mut HandleFor, invoker: &'invoker I, } -impl<'backend, 'invoker, H, I> CallStack<'backend, 'invoker, H, I> +impl<'backend, 'invoker, I> CallStack<'backend, 'invoker, I> where - I: Invoker, + I: Invoker, { pub fn new( machine: I::Interpreter, initial_depth: usize, - backend: &'backend mut H, + backend: &'backend mut HandleFor, invoker: &'invoker I, ) -> Self { Self { @@ -81,7 +81,10 @@ where fs: FS, ) -> Result<(), Capture, I::Interrupt>> where - FS: Fn(&mut I::Interpreter, &mut H) -> LastSubstackStatus>, + FS: Fn( + &mut I::Interpreter, + &mut HandleFor, + ) -> LastSubstackStatus>, { let mut step_ret = None; @@ -205,10 +208,10 @@ where } } -impl<'backend, 'invoker, H, I> CallStack<'backend, 'invoker, H, I> +impl<'backend, 'invoker, I> CallStack<'backend, 'invoker, I> where - I: Invoker, - I::Interpreter: StepInterpreter, + I: Invoker, + I::Interpreter: StepInterpreter, { #[allow(clippy::type_complexity)] pub fn step( @@ -224,15 +227,15 @@ where } } -fn execute( +fn execute( mut machine: I::Interpreter, initial_depth: usize, heap_depth: Option, - backend: &mut H, + backend: &mut HandleFor, invoker: &I, ) -> Result<(ExitResult, I::Interpreter), ExitFatal> where - I: Invoker, + I: Invoker, { let mut result = machine.run(backend); @@ -294,14 +297,14 @@ where } } -enum HeapTransactState<'backend, 'invoker, H, I: Invoker> { +enum HeapTransactState<'backend, 'invoker, I: Invoker> { Created { args: I::TransactArgs, invoker: &'invoker I, - backend: &'backend mut H, + backend: &'backend mut HandleFor, }, Running { - call_stack: CallStack<'backend, 'invoker, H, I>, + call_stack: CallStack<'backend, 'invoker, I>, transact_invoke: I::TransactInvoke, }, } @@ -309,19 +312,19 @@ enum HeapTransactState<'backend, 'invoker, H, I: Invoker> { /// Heap-based call stack for a transaction. This is suitable for single /// stepping or debugging. The hybrid version [transact] uses a heap-based call /// stack internally after certain depth. -pub struct HeapTransact<'backend, 'invoker, H, I: Invoker>( - Option>, +pub struct HeapTransact<'backend, 'invoker, I: Invoker>( + Option>, ); -impl<'backend, 'invoker, H, I> HeapTransact<'backend, 'invoker, H, I> +impl<'backend, 'invoker, I> HeapTransact<'backend, 'invoker, I> where - I: Invoker, + I: Invoker, { /// Create a new heap-based call stack. pub fn new( args: I::TransactArgs, invoker: &'invoker I, - backend: &'backend mut H, + backend: &'backend mut HandleFor, ) -> Result { Ok(Self(Some(HeapTransactState::Created { args, @@ -337,7 +340,7 @@ where ) -> Result<(), Capture, I::Interrupt>> where FS: Fn( - &mut CallStack<'backend, 'invoker, H, I>, + &mut CallStack<'backend, 'invoker, I>, ) -> Result< (), Capture, I::Interrupt>, @@ -438,10 +441,10 @@ where } } -impl<'backend, 'invoker, H, I> HeapTransact<'backend, 'invoker, H, I> +impl<'backend, 'invoker, I> HeapTransact<'backend, 'invoker, I> where - I: Invoker, - I::Interpreter: StepInterpreter, + I: Invoker, + I::Interpreter: StepInterpreter, { /// Step the call stack, and step the interpreter inside. #[allow(clippy::type_complexity)] @@ -452,9 +455,9 @@ where } } -impl<'backend, 'invoker, H, I> Drop for HeapTransact<'backend, 'invoker, H, I> +impl<'backend, 'invoker, I> Drop for HeapTransact<'backend, 'invoker, I> where - I: Invoker, + I: Invoker, { fn drop(&mut self) { if let Some(HeapTransactState::Running { @@ -505,14 +508,14 @@ where /// /// Because a stack-based call stack cannot handle interrupts, the [Invoker] /// type must have its `Interrupt` type set to [Infallible]. -pub fn transact( +pub fn transact( args: I::TransactArgs, heap_depth: Option, - backend: &mut H, + backend: &mut HandleFor, invoker: &I, ) -> Result where - I: Invoker, + I: Invoker, { let (transact_invoke, control) = invoker.new_transact(args, backend)?; diff --git a/src/invoker.rs b/src/invoker.rs index ced31191f..16ecd0270 100644 --- a/src/invoker.rs +++ b/src/invoker.rs @@ -1,4 +1,4 @@ -use crate::interpreter::{DeconstructFor, Interpreter, TrapFor}; +use crate::interpreter::{DeconstructFor, HandleFor, Interpreter, TrapFor}; use crate::{Capture, ExitError, ExitResult}; /// Control for an invoker. @@ -10,8 +10,8 @@ pub enum InvokerControl { } /// An invoker, responsible for pushing/poping values in the call stack. -pub trait Invoker { - type Interpreter: Interpreter; +pub trait Invoker { + type Interpreter: Interpreter; /// Possible interrupt type that may be returned by the call stack. type Interrupt; @@ -31,11 +31,11 @@ pub trait Invoker { fn new_transact( &self, args: Self::TransactArgs, - handler: &mut H, + handler: &mut HandleFor, ) -> Result< ( Self::TransactInvoke, - InvokerControl)>, + InvokerControl)>, ), ExitError, >; @@ -45,26 +45,23 @@ pub trait Invoker { &self, invoke: &Self::TransactInvoke, exit: ExitResult, - machine: DeconstructFor, - handler: &mut H, + machine: DeconstructFor, + handler: &mut HandleFor, ) -> Result; /// Enter a sub-layer call stack. #[allow(clippy::type_complexity)] fn enter_substack( &self, - trap: TrapFor, + trap: TrapFor, machine: &mut Self::Interpreter, - handler: &mut H, + handler: &mut HandleFor, depth: usize, ) -> Capture< Result< ( Self::SubstackInvoke, - InvokerControl< - Self::Interpreter, - (ExitResult, DeconstructFor), - >, + InvokerControl)>, ), ExitError, >, @@ -75,9 +72,9 @@ pub trait Invoker { fn exit_substack( &self, result: ExitResult, - child: DeconstructFor, + child: DeconstructFor, trap_data: Self::SubstackInvoke, parent: &mut Self::Interpreter, - handler: &mut H, + handler: &mut HandleFor, ) -> Result<(), ExitError>; } diff --git a/src/standard/invoker/mod.rs b/src/standard/invoker/mod.rs index 8c9f6e40a..cb12941ec 100644 --- a/src/standard/invoker/mod.rs +++ b/src/standard/invoker/mod.rs @@ -6,7 +6,7 @@ pub use self::resolver::{EtableResolver, PrecompileSet, Resolver}; pub use self::state::InvokerState; use super::Config; -use crate::interpreter::{DeconstructFor, StateFor, TrapFor}; +use crate::interpreter::{DeconstructFor, HandleFor, StateFor, TrapFor}; use crate::trap::{CallCreateTrap, CallCreateTrapData, CallTrapData, CreateScheme, CreateTrapData}; use crate::{ interpreter::Interpreter, Capture, Context, ExitError, ExitException, ExitResult, ExitSucceed, @@ -18,7 +18,6 @@ use alloc::rc::Rc; use alloc::vec::Vec; use core::cmp::min; use core::convert::Infallible; -use core::marker::PhantomData; use primitive_types::{H160, H256, U256}; use sha3::{Digest, Keccak256}; @@ -143,32 +142,27 @@ impl TransactArgs { /// * `R`: Code resolver type, also handle precompiles. Usually /// [EtableResolver] but can be customized. /// * `Tr`: Trap type, usually [crate::Opcode] but can be customized. -pub struct Invoker<'config, 'resolver, H, R> { +pub struct Invoker<'config, 'resolver, R> { config: &'config Config, resolver: &'resolver R, - _marker: PhantomData, } -impl<'config, 'resolver, H, R> Invoker<'config, 'resolver, H, R> { +impl<'config, 'resolver, R> Invoker<'config, 'resolver, R> { /// Create a new standard invoker with the given config and resolver. pub fn new(config: &'config Config, resolver: &'resolver R) -> Self { - Self { - config, - resolver, - _marker: PhantomData, - } + Self { config, resolver } } } -impl<'config, 'resolver, H, R> InvokerT for Invoker<'config, 'resolver, H, R> +impl<'config, 'resolver, R> InvokerT for Invoker<'config, 'resolver, R> where - StateFor: InvokerState<'config> + AsRef + AsMut, - H: RuntimeEnvironment + RuntimeBackend + TransactionalBackend, - R: Resolver, - TrapFor: TrapConsume, + StateFor: InvokerState<'config> + AsRef + AsMut, + HandleFor: RuntimeEnvironment + RuntimeBackend + TransactionalBackend, + R: Resolver, + TrapFor: TrapConsume, { type Interpreter = R::Interpreter; - type Interrupt = as TrapConsume>::Rest; + type Interrupt = as TrapConsume>::Rest; type TransactArgs = TransactArgs; type TransactInvoke = TransactInvoke; type TransactValue = (ExitSucceed, Option); @@ -177,11 +171,11 @@ where fn new_transact( &self, args: Self::TransactArgs, - handler: &mut H, + handler: &mut HandleFor, ) -> Result< ( Self::TransactInvoke, - InvokerControl)>, + InvokerControl)>, ), ExitError, > { @@ -261,7 +255,7 @@ where } } - let state = >::new_transact_call( + let state = >::new_transact_call( RuntimeState { context, transaction_context: Rc::new(transaction_context), @@ -301,7 +295,7 @@ where access_list, .. } => { - let state = >::new_transact_create( + let state = >::new_transact_create( RuntimeState { context, transaction_context: Rc::new(transaction_context), @@ -341,8 +335,8 @@ where &self, invoke: &Self::TransactInvoke, result: ExitResult, - (mut substate, retval): DeconstructFor, - handler: &mut H, + (mut substate, retval): DeconstructFor, + handler: &mut HandleFor, ) -> Result { let left_gas = substate.effective_gas(); @@ -390,15 +384,15 @@ where fn enter_substack( &self, - trap: TrapFor, - machine: &mut Self::Interpreter, - handler: &mut H, + trap: TrapFor, + machine: &mut R::Interpreter, + handler: &mut HandleFor, depth: usize, ) -> Capture< Result< ( Self::SubstackInvoke, - InvokerControl)>, + InvokerControl)>, ), ExitError, >, @@ -509,10 +503,10 @@ where fn exit_substack( &self, result: ExitResult, - (mut substate, retval): DeconstructFor, + (mut substate, retval): DeconstructFor, trap_data: Self::SubstackInvoke, - parent: &mut Self::Interpreter, - handler: &mut H, + parent: &mut R::Interpreter, + handler: &mut HandleFor, ) -> Result<(), ExitError> { let strategy = match &result { Ok(_) => MergeStrategy::Commit, diff --git a/src/standard/invoker/resolver.rs b/src/standard/invoker/resolver.rs index eb7636fa4..8d86151d6 100644 --- a/src/standard/invoker/resolver.rs +++ b/src/standard/invoker/resolver.rs @@ -1,4 +1,4 @@ -use crate::interpreter::{DeconstructFor, EtableInterpreter, Interpreter}; +use crate::interpreter::{DeconstructFor, EtableInterpreter, HandleFor, Interpreter, StateFor}; use crate::{ standard::Config, EtableSet, ExitError, ExitResult, InvokerControl, Machine, RuntimeBackend, RuntimeState, @@ -13,8 +13,8 @@ use primitive_types::H160; /// (with the init code) is turned into a colored machine. The resolver can /// construct a machine, pushing the call stack, or directly exit, handling a /// precompile. -pub trait Resolver { - type Interpreter: Interpreter; +pub trait Resolver { + type Interpreter: Interpreter; /// Resolve a call (with the target code address). #[allow(clippy::type_complexity)] @@ -22,10 +22,10 @@ pub trait Resolver { &self, code_address: H160, input: Vec, - state: >::State, - handler: &mut H, + state: StateFor, + handler: &mut HandleFor, ) -> Result< - InvokerControl)>, + InvokerControl)>, ExitError, >; @@ -34,10 +34,10 @@ pub trait Resolver { fn resolve_create( &self, init_code: Vec, - state: >::State, - handler: &mut H, + state: StateFor, + handler: &mut HandleFor, ) -> Result< - InvokerControl)>, + InvokerControl)>, ExitError, >; } @@ -93,13 +93,13 @@ impl<'config, 'precompile, 'etable, S, H, Pre, Tr, ES> } } -impl<'config, 'precompile, 'etable, S, H, Pre, Tr, ES> Resolver +impl<'config, 'precompile, 'etable, S, H, Pre, Tr, ES> Resolver for EtableResolver<'config, 'precompile, 'etable, S, H, Pre, Tr, ES> where S: AsRef + AsMut, H: RuntimeBackend, Pre: PrecompileSet, - ES: EtableSet, + ES: EtableSet, { type Interpreter = EtableInterpreter<'etable, S, H, Tr, ES>; diff --git a/src/standard/invoker/routines.rs b/src/standard/invoker/routines.rs index 2729e9ee6..c14ddca09 100644 --- a/src/standard/invoker/routines.rs +++ b/src/standard/invoker/routines.rs @@ -1,30 +1,27 @@ use super::{CallTrapData, CreateTrapData, InvokerState, Resolver, SubstackInvoke}; -use crate::interpreter::{DeconstructFor, StateFor}; +use crate::interpreter::{DeconstructFor, HandleFor, StateFor}; use crate::standard::Config; use crate::{ ExitError, ExitException, ExitResult, InvokerControl, MergeStrategy, Opcode, RuntimeBackend, - RuntimeEnvironment, RuntimeState, TransactionalBackend, Transfer, + RuntimeBaseBackend, RuntimeEnvironment, RuntimeState, TransactionalBackend, Transfer, }; use alloc::vec::Vec; use primitive_types::{H160, U256}; #[allow(clippy::too_many_arguments, clippy::type_complexity)] -pub fn make_enter_call_machine( +pub fn make_enter_call_machine( _config: &Config, resolver: &R, code_address: H160, input: Vec, transfer: Option, - state: StateFor, - handler: &mut H, -) -> Result< - InvokerControl)>, - ExitError, -> + state: StateFor, + handler: &mut HandleFor, +) -> Result)>, ExitError> where - StateFor: AsRef, - H: RuntimeEnvironment + RuntimeBackend + TransactionalBackend, - R: Resolver, + StateFor: AsRef, + HandleFor: RuntimeEnvironment + RuntimeBackend + TransactionalBackend, + R: Resolver, { handler.mark_hot(state.as_ref().context.address, None); @@ -36,22 +33,19 @@ where } #[allow(clippy::type_complexity, clippy::too_many_arguments)] -pub fn make_enter_create_machine( +pub fn make_enter_create_machine( config: &Config, resolver: &R, caller: H160, init_code: Vec, transfer: Transfer, - state: StateFor, - handler: &mut H, -) -> Result< - InvokerControl)>, - ExitError, -> + state: StateFor, + handler: &mut HandleFor, +) -> Result)>, ExitError> where - StateFor: AsRef, - H: RuntimeEnvironment + RuntimeBackend + TransactionalBackend, - R: Resolver, + StateFor: AsRef, + HandleFor: RuntimeEnvironment + RuntimeBackend + TransactionalBackend, + R: Resolver, { if let Some(limit) = config.max_initcode_size { if init_code.len() > limit { @@ -80,24 +74,24 @@ where } #[allow(clippy::type_complexity, clippy::too_many_arguments)] -pub fn enter_call_substack( +pub fn enter_call_substack( config: &Config, resolver: &R, trap_data: CallTrapData, code_address: H160, - state: StateFor, - handler: &mut H, + state: StateFor, + handler: &mut HandleFor, ) -> Result< ( SubstackInvoke, - InvokerControl)>, + InvokerControl)>, ), ExitError, > where - StateFor: AsRef, - H: RuntimeEnvironment + RuntimeBackend + TransactionalBackend, - R: Resolver, + StateFor: AsRef, + HandleFor: RuntimeEnvironment + RuntimeBackend + TransactionalBackend, + R: Resolver, { handler.push_substate(); @@ -125,28 +119,28 @@ where } #[allow(clippy::type_complexity, clippy::too_many_arguments)] -pub fn enter_create_substack( +pub fn enter_create_substack( config: &Config, resolver: &R, code: Vec, trap_data: CreateTrapData, - state: StateFor, - handler: &mut H, + state: StateFor, + handler: &mut HandleFor, ) -> Result< ( SubstackInvoke, - InvokerControl)>, + InvokerControl)>, ), ExitError, > where - StateFor: AsRef, - H: RuntimeEnvironment + RuntimeBackend + TransactionalBackend, - R: Resolver, + StateFor: AsRef, + HandleFor: RuntimeEnvironment + RuntimeBackend + TransactionalBackend, + R: Resolver, { handler.push_substate(); - let work = || -> Result<(SubstackInvoke, InvokerControl)>), ExitError> { + let work = || -> Result<(SubstackInvoke, InvokerControl)>), ExitError> { let CreateTrapData { scheme, value,