Trait Handler

pub trait Handler {
    type Evm: EvmTr
       where <Self::Evm as EvmTr>::Context: ContextTr,
             <<Self::Evm as EvmTr>::Context as ContextTr>::Journal: JournalTr<State = HashMap<Address, Account, RandomState>>,
             <<Self::Evm as EvmTr>::Context as ContextTr>::Local: LocalContextTr,
             <Self::Evm as EvmTr>::Frame: FrameTr<FrameInit = FrameInit, FrameResult = FrameResult>;
    type Error: EvmTrError<Self::Evm>;
    type HaltReason: HaltReasonTr;

Show 21 methods // Provided methods fn run( &mut self, evm: &mut Self::Evm, ) -> Result<ExecutionResult<Self::HaltReason>, Self::Error> { ... } fn run_system_call( &mut self, evm: &mut Self::Evm, ) -> Result<ExecutionResult<Self::HaltReason>, Self::Error> { ... } fn run_without_catch_error( &mut self, evm: &mut Self::Evm, ) -> Result<ExecutionResult<Self::HaltReason>, Self::Error> { ... } fn validate( &self, evm: &mut Self::Evm, ) -> Result<InitialAndFloorGas, Self::Error> { ... } fn pre_execution(&self, evm: &mut Self::Evm) -> Result<u64, Self::Error> { ... } fn execution( &mut self, evm: &mut Self::Evm, init_and_floor_gas: &InitialAndFloorGas, ) -> Result<FrameResult, Self::Error> { ... } fn post_execution( &self, evm: &mut Self::Evm, exec_result: &mut FrameResult, init_and_floor_gas: InitialAndFloorGas, eip7702_gas_refund: i64, ) -> Result<(), Self::Error> { ... } fn validate_env(&self, evm: &mut Self::Evm) -> Result<(), Self::Error> { ... } fn validate_initial_tx_gas( &self, evm: &Self::Evm, ) -> Result<InitialAndFloorGas, Self::Error> { ... } fn load_accounts(&self, evm: &mut Self::Evm) -> Result<(), Self::Error> { ... } fn apply_eip7702_auth_list( &self, evm: &mut Self::Evm, ) -> Result<u64, Self::Error> { ... } fn validate_against_state_and_deduct_caller( &self, evm: &mut Self::Evm, ) -> Result<(), Self::Error> { ... } fn first_frame_input( &mut self, evm: &mut Self::Evm, gas_limit: u64, ) -> Result<FrameInit, Self::Error> { ... } fn last_frame_result( &mut self, evm: &mut Self::Evm, frame_result: &mut <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameResult, ) -> Result<(), Self::Error> { ... } fn run_exec_loop( &mut self, evm: &mut Self::Evm, first_frame_input: <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameInit, ) -> Result<FrameResult, Self::Error> { ... } fn eip7623_check_gas_floor( &self, _evm: &mut Self::Evm, exec_result: &mut <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameResult, init_and_floor_gas: InitialAndFloorGas, ) { ... } fn refund( &self, evm: &mut Self::Evm, exec_result: &mut <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameResult, eip7702_refund: i64, ) { ... } fn reimburse_caller( &self, evm: &mut Self::Evm, exec_result: &mut <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameResult, ) -> Result<(), Self::Error> { ... } fn reward_beneficiary( &self, evm: &mut Self::Evm, exec_result: &mut <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameResult, ) -> Result<(), Self::Error> { ... } fn execution_result( &mut self, evm: &mut Self::Evm, result: <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameResult, ) -> Result<ExecutionResult<Self::HaltReason>, Self::Error> { ... } fn catch_error( &self, evm: &mut Self::Evm, error: Self::Error, ) -> Result<ExecutionResult<Self::HaltReason>, Self::Error> { ... }
}
Expand description

The main implementation of Ethereum Mainnet transaction execution.

The Handler::run method serves as the entry point for execution and provides out-of-the-box support for executing Ethereum mainnet transactions.

This trait allows EVM variants to customize execution logic by implementing their own method implementations.

The handler logic consists of four phases:

  • Validation - Validates tx/block/config fields and loads caller account and validates initial gas requirements and balance checks.
  • Pre-execution - Loads and warms accounts, deducts initial gas
  • Execution - Executes the main frame loop, delegating to EvmTr for creating and running call frames.
  • Post-execution - Calculates final refunds, validates gas floor, reimburses caller, and rewards beneficiary

The Handler::catch_error method handles cleanup of intermediate state if an error occurs during execution.

§Returns

Returns execution status, error, gas spend and logs. State change is not returned and it is contained inside Context Journal. This setup allows multiple transactions to be chain executed.

To finalize the execution and obtain changed state, call JournalTr::finalize function.

Required Associated Types§

type Evm: EvmTr where <Self::Evm as EvmTr>::Context: ContextTr, <<Self::Evm as EvmTr>::Context as ContextTr>::Journal: JournalTr<State = HashMap<Address, Account, RandomState>>, <<Self::Evm as EvmTr>::Context as ContextTr>::Local: LocalContextTr, <Self::Evm as EvmTr>::Frame: FrameTr<FrameInit = FrameInit, FrameResult = FrameResult>

The EVM type containing Context, Instruction, and Precompiles implementations.

type Error: EvmTrError<Self::Evm>

The error type returned by this handler.

type HaltReason: HaltReasonTr

The halt reason type included in the output

Provided Methods§

fn run( &mut self, evm: &mut Self::Evm, ) -> Result<ExecutionResult<Self::HaltReason>, Self::Error>

The main entry point for transaction execution.

This method calls Handler::run_without_catch_error and if it returns an error, calls Handler::catch_error to handle the error and cleanup.

The Handler::catch_error method ensures intermediate state is properly cleared.

§Error handling

In case of error, the journal can be in an inconsistent state and should be cleared by calling JournalTr::discard_tx method or dropped.

§Returns

Returns execution result, error, gas spend and logs.

fn run_system_call( &mut self, evm: &mut Self::Evm, ) -> Result<ExecutionResult<Self::HaltReason>, Self::Error>

Runs the system call.

System call is a special transaction where caller is a crate::SYSTEM_ADDRESS

It is used to call a system contracts and it skips all the validation and pre-execution and most of post-execution phases. For example it will not deduct the caller or reward the beneficiary.

State changs can be obtained by calling JournalTr::finalize method from the EvmTr::Context.

§Error handling

By design system call should not fail and should always succeed. In case of an error (If fetching account/storage on rpc fails), the journal can be in an inconsistent state and should be cleared by calling JournalTr::discard_tx method or dropped.

fn run_without_catch_error( &mut self, evm: &mut Self::Evm, ) -> Result<ExecutionResult<Self::HaltReason>, Self::Error>

Called by Handler::run to execute the core handler logic.

Executes the four phases in sequence: Handler::validate, Handler::pre_execution, Handler::execution, Handler::post_execution.

Returns any errors without catching them or calling Handler::catch_error.

fn validate( &self, evm: &mut Self::Evm, ) -> Result<InitialAndFloorGas, Self::Error>

Validates the execution environment and transaction parameters.

Calculates initial and floor gas requirements and verifies they are covered by the gas limit.

Validation against state is done later in pre-execution phase in deduct_caller function.

fn pre_execution(&self, evm: &mut Self::Evm) -> Result<u64, Self::Error>

Prepares the EVM state for execution.

Loads the beneficiary account (EIP-3651: Warm COINBASE) and all accounts/storage from the access list (EIP-2929).

Deducts the maximum possible fee from the caller’s balance.

For EIP-7702 transactions, applies the authorization list and delegates successful authorizations. Returns the gas refund amount from EIP-7702. Authorizations are applied before execution begins.

fn execution( &mut self, evm: &mut Self::Evm, init_and_floor_gas: &InitialAndFloorGas, ) -> Result<FrameResult, Self::Error>

Creates and executes the initial frame, then processes the execution loop.

Always calls Handler::last_frame_result to handle returned gas from the call.

fn post_execution( &self, evm: &mut Self::Evm, exec_result: &mut FrameResult, init_and_floor_gas: InitialAndFloorGas, eip7702_gas_refund: i64, ) -> Result<(), Self::Error>

Handles the final steps of transaction execution.

Calculates final refunds and validates the gas floor (EIP-7623) to ensure minimum gas is spent. After EIP-7623, at least floor gas must be consumed.

Reimburses unused gas to the caller and rewards the beneficiary with transaction fees. The effective gas price determines rewards, with the base fee being burned.

Finally, finalizes output by returning the journal state and clearing internal state for the next execution.

fn validate_env(&self, evm: &mut Self::Evm) -> Result<(), Self::Error>

Validates block, transaction and configuration fields.

Performs all validation checks that can be done without loading state. For example, verifies transaction gas limit is below block gas limit.

fn validate_initial_tx_gas( &self, evm: &Self::Evm, ) -> Result<InitialAndFloorGas, Self::Error>

Calculates initial gas costs based on transaction type and input data.

Includes additional costs for access list and authorization list.

Verifies the initial cost does not exceed the transaction gas limit.

fn load_accounts(&self, evm: &mut Self::Evm) -> Result<(), Self::Error>

Loads access list and beneficiary account, marking them as warm in the context::Journal.

fn apply_eip7702_auth_list( &self, evm: &mut Self::Evm, ) -> Result<u64, Self::Error>

Processes the authorization list, validating authority signatures, nonces and chain IDs. Applies valid authorizations to accounts.

Returns the gas refund amount specified by EIP-7702.

fn validate_against_state_and_deduct_caller( &self, evm: &mut Self::Evm, ) -> Result<(), Self::Error>

Deducts maximum possible fee and transfer value from caller’s balance.

Unused fees are returned to caller after execution completes.

fn first_frame_input( &mut self, evm: &mut Self::Evm, gas_limit: u64, ) -> Result<FrameInit, Self::Error>

Creates initial frame input using transaction parameters, gas limit and configuration.

fn last_frame_result( &mut self, evm: &mut Self::Evm, frame_result: &mut <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameResult, ) -> Result<(), Self::Error>

Processes the result of the initial call and handles returned gas.

fn run_exec_loop( &mut self, evm: &mut Self::Evm, first_frame_input: <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameInit, ) -> Result<FrameResult, Self::Error>

Executes the main frame processing loop.

This loop manages the frame stack, processing each frame until execution completes. For each iteration:

  1. Calls the current frame
  2. Handles the returned frame input or result
  3. Creates new frames or propagates results as needed

fn eip7623_check_gas_floor( &self, _evm: &mut Self::Evm, exec_result: &mut <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameResult, init_and_floor_gas: InitialAndFloorGas, )

Validates that the minimum gas floor requirements are satisfied.

Ensures that at least the floor gas amount has been consumed during execution.

fn refund( &self, evm: &mut Self::Evm, exec_result: &mut <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameResult, eip7702_refund: i64, )

Calculates the final gas refund amount, including any EIP-7702 refunds.

fn reimburse_caller( &self, evm: &mut Self::Evm, exec_result: &mut <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameResult, ) -> Result<(), Self::Error>

Returns unused gas costs to the transaction sender’s account.

fn reward_beneficiary( &self, evm: &mut Self::Evm, exec_result: &mut <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameResult, ) -> Result<(), Self::Error>

Transfers transaction fees to the block beneficiary’s account.

fn execution_result( &mut self, evm: &mut Self::Evm, result: <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameResult, ) -> Result<ExecutionResult<Self::HaltReason>, Self::Error>

Processes the final execution output.

This method, retrieves the final state from the journal, converts internal results to the external output format. Internal state is cleared and EVM is prepared for the next transaction.

fn catch_error( &self, evm: &mut Self::Evm, error: Self::Error, ) -> Result<ExecutionResult<Self::HaltReason>, Self::Error>

Handles cleanup when an error occurs during execution.

Ensures the journal state is properly cleared before propagating the error. On happy path journal is cleared in Handler::execution_result method.

Implementations on Foreign Types§

Source§

impl<'db, I> Handler for FoundryHandler<'db, I>
where I: InspectorExt,

§

impl<EVM, ERROR, FRAME> Handler for OpHandler<EVM, ERROR, FRAME>
where EVM: EvmTr<Frame = FRAME>, <EVM as EvmTr>::Context: OpContextTr, ERROR: EvmTrError<EVM> + From<OpTransactionError> + FromStringError + IsTxError, FRAME: FrameTr<FrameResult = FrameResult, FrameInit = FrameInit>,

§

type Evm = EVM

§

type Error = ERROR

§

type HaltReason = OpHaltReason

§

fn validate_env( &self, evm: &mut <OpHandler<EVM, ERROR, FRAME> as Handler>::Evm, ) -> Result<(), <OpHandler<EVM, ERROR, FRAME> as Handler>::Error>

§

fn validate_against_state_and_deduct_caller( &self, evm: &mut <OpHandler<EVM, ERROR, FRAME> as Handler>::Evm, ) -> Result<(), <OpHandler<EVM, ERROR, FRAME> as Handler>::Error>

§

fn last_frame_result( &mut self, evm: &mut <OpHandler<EVM, ERROR, FRAME> as Handler>::Evm, frame_result: &mut <<<OpHandler<EVM, ERROR, FRAME> as Handler>::Evm as EvmTr>::Frame as FrameTr>::FrameResult, ) -> Result<(), <OpHandler<EVM, ERROR, FRAME> as Handler>::Error>

§

fn reimburse_caller( &self, evm: &mut <OpHandler<EVM, ERROR, FRAME> as Handler>::Evm, frame_result: &mut <<<OpHandler<EVM, ERROR, FRAME> as Handler>::Evm as EvmTr>::Frame as FrameTr>::FrameResult, ) -> Result<(), <OpHandler<EVM, ERROR, FRAME> as Handler>::Error>

§

fn refund( &self, evm: &mut <OpHandler<EVM, ERROR, FRAME> as Handler>::Evm, frame_result: &mut <<<OpHandler<EVM, ERROR, FRAME> as Handler>::Evm as EvmTr>::Frame as FrameTr>::FrameResult, eip7702_refund: i64, )

§

fn reward_beneficiary( &self, evm: &mut <OpHandler<EVM, ERROR, FRAME> as Handler>::Evm, frame_result: &mut <<<OpHandler<EVM, ERROR, FRAME> as Handler>::Evm as EvmTr>::Frame as FrameTr>::FrameResult, ) -> Result<(), <OpHandler<EVM, ERROR, FRAME> as Handler>::Error>

§

fn execution_result( &mut self, evm: &mut <OpHandler<EVM, ERROR, FRAME> as Handler>::Evm, frame_result: <<<OpHandler<EVM, ERROR, FRAME> as Handler>::Evm as EvmTr>::Frame as FrameTr>::FrameResult, ) -> Result<ExecutionResult<<OpHandler<EVM, ERROR, FRAME> as Handler>::HaltReason>, <OpHandler<EVM, ERROR, FRAME> as Handler>::Error>

§

fn catch_error( &self, evm: &mut <OpHandler<EVM, ERROR, FRAME> as Handler>::Evm, error: <OpHandler<EVM, ERROR, FRAME> as Handler>::Error, ) -> Result<ExecutionResult<<OpHandler<EVM, ERROR, FRAME> as Handler>::HaltReason>, <OpHandler<EVM, ERROR, FRAME> as Handler>::Error>

Implementors§

§

impl<EVM, ERROR, FRAME> Handler for MainnetHandler<EVM, ERROR, FRAME>
where <EVM as EvmTr>::Context: ContextTr, <<EVM as EvmTr>::Context as ContextTr>::Journal: JournalTr<State = HashMap<Address, Account, RandomState>>, ERROR: EvmTrError<EVM>, FRAME: FrameTr<FrameResult = FrameResult, FrameInit = FrameInit>, EVM: EvmTr<Frame = FRAME>,

§

type Evm = EVM

§

type Error = ERROR

§

type HaltReason = HaltReason