pub trait Handler {
type Evm: EvmTr<Context: ContextTr<Journal: JournalTr<FinalOutput = JournalOutput>>>;
type Error: EvmTrError<Self::Evm>;
type Frame: Frame<Evm = Self::Evm, Error = Self::Error, FrameResult = FrameResult, FrameInit = FrameInput>;
type HaltReason: HaltReasonTr;
Show 25 methods
// Provided methods
fn run(
&mut self,
evm: &mut Self::Evm,
) -> Result<ResultAndState<Self::HaltReason>, Self::Error> { ... }
fn run_without_catch_error(
&mut self,
evm: &mut Self::Evm,
) -> Result<ResultAndState<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: FrameResult,
init_and_floor_gas: InitialAndFloorGas,
eip7702_gas_refund: i64,
) -> Result<ResultAndState<Self::HaltReason>, 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 validate_tx_against_state(
&self,
evm: &mut Self::Evm,
) -> Result<(), 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 deduct_caller(&self, evm: &mut Self::Evm) -> Result<(), Self::Error> { ... }
fn first_frame_input(
&mut self,
evm: &mut Self::Evm,
gas_limit: u64,
) -> Result<FrameInput, Self::Error> { ... }
fn last_frame_result(
&self,
evm: &mut Self::Evm,
frame_result: &mut <Self::Frame as Frame>::FrameResult,
) -> Result<(), Self::Error> { ... }
fn first_frame_init(
&mut self,
evm: &mut Self::Evm,
frame_input: <Self::Frame as Frame>::FrameInit,
) -> Result<FrameOrResult<Self::Frame>, Self::Error> { ... }
fn frame_init(
&mut self,
frame: &Self::Frame,
evm: &mut Self::Evm,
frame_input: <Self::Frame as Frame>::FrameInit,
) -> Result<FrameOrResult<Self::Frame>, Self::Error> { ... }
fn frame_call(
&mut self,
frame: &mut Self::Frame,
evm: &mut Self::Evm,
) -> Result<FrameInitOrResult<Self::Frame>, Self::Error> { ... }
fn frame_return_result(
&mut self,
frame: &mut Self::Frame,
evm: &mut Self::Evm,
result: <Self::Frame as Frame>::FrameResult,
) -> Result<(), Self::Error> { ... }
fn run_exec_loop(
&mut self,
evm: &mut Self::Evm,
frame: Self::Frame,
) -> Result<FrameResult, Self::Error> { ... }
fn eip7623_check_gas_floor(
&self,
_evm: &mut Self::Evm,
exec_result: &mut <Self::Frame as Frame>::FrameResult,
init_and_floor_gas: InitialAndFloorGas,
) { ... }
fn refund(
&self,
evm: &mut Self::Evm,
exec_result: &mut <Self::Frame as Frame>::FrameResult,
eip7702_refund: i64,
) { ... }
fn reimburse_caller(
&self,
evm: &mut Self::Evm,
exec_result: &mut <Self::Frame as Frame>::FrameResult,
) -> Result<(), Self::Error> { ... }
fn reward_beneficiary(
&self,
evm: &mut Self::Evm,
exec_result: &mut <Self::Frame as Frame>::FrameResult,
) -> Result<(), Self::Error> { ... }
fn output(
&self,
evm: &mut Self::Evm,
result: <Self::Frame as Frame>::FrameResult,
) -> Result<ResultAndState<Self::HaltReason>, Self::Error> { ... }
fn catch_error(
&self,
evm: &mut Self::Evm,
error: Self::Error,
) -> Result<ResultAndState<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
Frame
for sub-calls - 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.
Required Associated Types§
Sourcetype Evm: EvmTr<Context: ContextTr<Journal: JournalTr<FinalOutput = JournalOutput>>>
type Evm: EvmTr<Context: ContextTr<Journal: JournalTr<FinalOutput = JournalOutput>>>
The EVM type containing Context, Instruction, and Precompiles implementations.
Sourcetype Error: EvmTrError<Self::Evm>
type Error: EvmTrError<Self::Evm>
The error type returned by this handler.
Sourcetype Frame: Frame<Evm = Self::Evm, Error = Self::Error, FrameResult = FrameResult, FrameInit = FrameInput>
type Frame: Frame<Evm = Self::Evm, Error = Self::Error, FrameResult = FrameResult, FrameInit = FrameInput>
The Frame type containing data for frame execution. Supports Call, Create and EofCreate frames.
Sourcetype HaltReason: HaltReasonTr
type HaltReason: HaltReasonTr
The halt reason type included in the output
Provided Methods§
Sourcefn run(
&mut self,
evm: &mut Self::Evm,
) -> Result<ResultAndState<Self::HaltReason>, Self::Error>
fn run( &mut self, evm: &mut Self::Evm, ) -> Result<ResultAndState<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.
Sourcefn run_without_catch_error(
&mut self,
evm: &mut Self::Evm,
) -> Result<ResultAndState<Self::HaltReason>, Self::Error>
fn run_without_catch_error( &mut self, evm: &mut Self::Evm, ) -> Result<ResultAndState<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
.
Sourcefn validate(
&self,
evm: &mut Self::Evm,
) -> Result<InitialAndFloorGas, Self::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.
Loads the caller account and validates transaction fields against state, including nonce checks and balance verification for maximum gas costs.
Sourcefn pre_execution(&self, evm: &mut Self::Evm) -> Result<u64, Self::Error>
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.
Sourcefn execution(
&mut self,
evm: &mut Self::Evm,
init_and_floor_gas: &InitialAndFloorGas,
) -> Result<FrameResult, Self::Error>
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.
Sourcefn post_execution(
&self,
evm: &mut Self::Evm,
exec_result: FrameResult,
init_and_floor_gas: InitialAndFloorGas,
eip7702_gas_refund: i64,
) -> Result<ResultAndState<Self::HaltReason>, Self::Error>
fn post_execution( &self, evm: &mut Self::Evm, exec_result: FrameResult, init_and_floor_gas: InitialAndFloorGas, eip7702_gas_refund: i64, ) -> Result<ResultAndState<Self::HaltReason>, 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.
Sourcefn validate_env(&self, evm: &mut Self::Evm) -> Result<(), Self::Error>
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.
Sourcefn validate_initial_tx_gas(
&self,
evm: &Self::Evm,
) -> Result<InitialAndFloorGas, Self::Error>
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.
Sourcefn validate_tx_against_state(
&self,
evm: &mut Self::Evm,
) -> Result<(), Self::Error>
fn validate_tx_against_state( &self, evm: &mut Self::Evm, ) -> Result<(), Self::Error>
Loads caller account to access nonce and balance.
Calculates maximum possible transaction fee and verifies caller has sufficient balance.
Sourcefn load_accounts(&self, evm: &mut Self::Evm) -> Result<(), Self::Error>
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
.
Sourcefn apply_eip7702_auth_list(
&self,
evm: &mut Self::Evm,
) -> Result<u64, Self::Error>
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.
Sourcefn deduct_caller(&self, evm: &mut Self::Evm) -> Result<(), Self::Error>
fn 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.
Sourcefn first_frame_input(
&mut self,
evm: &mut Self::Evm,
gas_limit: u64,
) -> Result<FrameInput, Self::Error>
fn first_frame_input( &mut self, evm: &mut Self::Evm, gas_limit: u64, ) -> Result<FrameInput, Self::Error>
Creates initial frame input using transaction parameters, gas limit and configuration.
Sourcefn last_frame_result(
&self,
evm: &mut Self::Evm,
frame_result: &mut <Self::Frame as Frame>::FrameResult,
) -> Result<(), Self::Error>
fn last_frame_result( &self, evm: &mut Self::Evm, frame_result: &mut <Self::Frame as Frame>::FrameResult, ) -> Result<(), Self::Error>
Processes the result of the initial call and handles returned gas.
Sourcefn first_frame_init(
&mut self,
evm: &mut Self::Evm,
frame_input: <Self::Frame as Frame>::FrameInit,
) -> Result<FrameOrResult<Self::Frame>, Self::Error>
fn first_frame_init( &mut self, evm: &mut Self::Evm, frame_input: <Self::Frame as Frame>::FrameInit, ) -> Result<FrameOrResult<Self::Frame>, Self::Error>
Initializes the first frame from the provided frame input.
Sourcefn frame_init(
&mut self,
frame: &Self::Frame,
evm: &mut Self::Evm,
frame_input: <Self::Frame as Frame>::FrameInit,
) -> Result<FrameOrResult<Self::Frame>, Self::Error>
fn frame_init( &mut self, frame: &Self::Frame, evm: &mut Self::Evm, frame_input: <Self::Frame as Frame>::FrameInit, ) -> Result<FrameOrResult<Self::Frame>, Self::Error>
Initializes a new frame from the provided frame input and previous frame.
The previous frame contains shared memory that is passed to the new frame.
Sourcefn frame_call(
&mut self,
frame: &mut Self::Frame,
evm: &mut Self::Evm,
) -> Result<FrameInitOrResult<Self::Frame>, Self::Error>
fn frame_call( &mut self, frame: &mut Self::Frame, evm: &mut Self::Evm, ) -> Result<FrameInitOrResult<Self::Frame>, Self::Error>
Executes a frame and returns either input for a new frame or the frame’s result.
When a result is returned, the frame is removed from the call stack. When frame input is returned, a new frame is created and pushed onto the call stack.
Sourcefn frame_return_result(
&mut self,
frame: &mut Self::Frame,
evm: &mut Self::Evm,
result: <Self::Frame as Frame>::FrameResult,
) -> Result<(), Self::Error>
fn frame_return_result( &mut self, frame: &mut Self::Frame, evm: &mut Self::Evm, result: <Self::Frame as Frame>::FrameResult, ) -> Result<(), Self::Error>
Processes a frame’s result by inserting it into the parent frame.
Sourcefn run_exec_loop(
&mut self,
evm: &mut Self::Evm,
frame: Self::Frame,
) -> Result<FrameResult, Self::Error>
fn run_exec_loop( &mut self, evm: &mut Self::Evm, frame: Self::Frame, ) -> 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:
- Calls the current frame
- Handles the returned frame input or result
- Creates new frames or propagates results as needed
Sourcefn eip7623_check_gas_floor(
&self,
_evm: &mut Self::Evm,
exec_result: &mut <Self::Frame as Frame>::FrameResult,
init_and_floor_gas: InitialAndFloorGas,
)
fn eip7623_check_gas_floor( &self, _evm: &mut Self::Evm, exec_result: &mut <Self::Frame as Frame>::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.
Sourcefn refund(
&self,
evm: &mut Self::Evm,
exec_result: &mut <Self::Frame as Frame>::FrameResult,
eip7702_refund: i64,
)
fn refund( &self, evm: &mut Self::Evm, exec_result: &mut <Self::Frame as Frame>::FrameResult, eip7702_refund: i64, )
Calculates the final gas refund amount, including any EIP-7702 refunds.
Sourcefn reimburse_caller(
&self,
evm: &mut Self::Evm,
exec_result: &mut <Self::Frame as Frame>::FrameResult,
) -> Result<(), Self::Error>
fn reimburse_caller( &self, evm: &mut Self::Evm, exec_result: &mut <Self::Frame as Frame>::FrameResult, ) -> Result<(), Self::Error>
Returns unused gas costs to the transaction sender’s account.
Sourcefn reward_beneficiary(
&self,
evm: &mut Self::Evm,
exec_result: &mut <Self::Frame as Frame>::FrameResult,
) -> Result<(), Self::Error>
fn reward_beneficiary( &self, evm: &mut Self::Evm, exec_result: &mut <Self::Frame as Frame>::FrameResult, ) -> Result<(), Self::Error>
Transfers transaction fees to the block beneficiary’s account.
Sourcefn output(
&self,
evm: &mut Self::Evm,
result: <Self::Frame as Frame>::FrameResult,
) -> Result<ResultAndState<Self::HaltReason>, Self::Error>
fn output( &self, evm: &mut Self::Evm, result: <Self::Frame as Frame>::FrameResult, ) -> Result<ResultAndState<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.
Sourcefn catch_error(
&self,
evm: &mut Self::Evm,
error: Self::Error,
) -> Result<ResultAndState<Self::HaltReason>, Self::Error>
fn catch_error( &self, evm: &mut Self::Evm, error: Self::Error, ) -> Result<ResultAndState<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::output
method.