//! EVM Handler related to Hl chain use super::{spec::HlSpecId, transaction::HlTxTr}; use revm::{ context::{ result::{ExecutionResult, HaltReason}, Cfg, ContextTr, JournalOutput, LocalContextTr, }, context_interface::{result::ResultAndState, JournalTr}, handler::{handler::EvmTrError, EvmTr, Frame, FrameResult, Handler, MainnetHandler}, inspector::{Inspector, InspectorEvmTr, InspectorFrame, InspectorHandler}, interpreter::{interpreter::EthInterpreter, FrameInput, SuccessOrHalt}, }; pub struct HlHandler { pub mainnet: MainnetHandler, } impl HlHandler { pub fn new() -> Self { Self { mainnet: MainnetHandler::default(), } } } impl Default for HlHandler { fn default() -> Self { Self::new() } } pub trait HlContextTr: ContextTr, Tx: HlTxTr, Cfg: Cfg> { } impl HlContextTr for T where T: ContextTr< Journal: JournalTr, Tx: HlTxTr, Cfg: Cfg, > { } impl Handler for HlHandler where EVM: EvmTr, ERROR: EvmTrError, FRAME: Frame, { type Evm = EVM; type Error = ERROR; type Frame = FRAME; type HaltReason = HaltReason; fn validate_initial_tx_gas( &self, evm: &Self::Evm, ) -> Result { self.mainnet.validate_initial_tx_gas(evm) } fn output( &self, evm: &mut Self::Evm, result: ::FrameResult, ) -> Result, Self::Error> { let ctx = evm.ctx(); ctx.error(); // used gas with refund calculated. let gas_refunded = result.gas().refunded() as u64; let final_gas_used = result.gas().spent() - gas_refunded; let output = result.output(); let instruction_result = result.into_interpreter_result(); // Reset journal and return present state. let JournalOutput { state, logs } = evm.ctx().journal().finalize(); let result = match SuccessOrHalt::from(instruction_result.result) { SuccessOrHalt::Success(reason) => ExecutionResult::Success { reason, gas_used: final_gas_used, gas_refunded, logs, output, }, SuccessOrHalt::Revert => ExecutionResult::Revert { gas_used: final_gas_used, output: output.into_data(), }, SuccessOrHalt::Halt(reason) => ExecutionResult::Halt { reason, gas_used: final_gas_used, }, // Only two internal return flags. flag @ (SuccessOrHalt::FatalExternalError | SuccessOrHalt::Internal(_)) => { panic!( "Encountered unexpected internal return flag: {flag:?} with instruction result: {instruction_result:?}" ) } }; // Clear local context evm.ctx().local().clear(); // Clear journal evm.ctx().journal().clear(); Ok(ResultAndState { result, state }) } } impl InspectorHandler for HlHandler where EVM: InspectorEvmTr< Context: HlContextTr, Inspector: Inspector<<::Evm as EvmTr>::Context, EthInterpreter>, >, ERROR: EvmTrError, FRAME: Frame + InspectorFrame, { type IT = EthInterpreter; }