reth_evm/system_calls/
eip7002.rs1use crate::ConfigureEvm;
3use alloc::{boxed::Box, format};
4use alloy_eips::eip7002::WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS;
5use alloy_primitives::Bytes;
6use reth_execution_errors::{BlockExecutionError, BlockValidationError};
7use revm::{interpreter::Host, Database, Evm};
8use revm_primitives::{ExecutionResult, ResultAndState};
9
10#[inline]
16pub(crate) fn transact_withdrawal_requests_contract_call<EvmConfig, EXT, DB>(
17 evm_config: &EvmConfig,
18 evm: &mut Evm<'_, EXT, DB>,
19) -> Result<ResultAndState, BlockExecutionError>
20where
21 DB: Database,
22 DB::Error: core::fmt::Display,
23 EvmConfig: ConfigureEvm,
24{
25 let previous_env = Box::new(evm.context.env().clone());
27
28 evm_config.fill_tx_env_system_contract_call(
37 &mut evm.context.evm.env,
38 alloy_eips::eip7002::SYSTEM_ADDRESS,
39 WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS,
40 Bytes::new(),
41 );
42
43 let mut res = match evm.transact() {
44 Ok(res) => res,
45 Err(e) => {
46 evm.context.evm.env = previous_env;
47 return Err(BlockValidationError::WithdrawalRequestsContractCall {
48 message: format!("execution failed: {e}"),
49 }
50 .into())
51 }
52 };
53
54 res.state.remove(&alloy_eips::eip7002::SYSTEM_ADDRESS);
56 res.state.remove(&evm.block().coinbase);
57
58 evm.context.evm.env = previous_env;
60
61 Ok(res)
62}
63
64#[inline]
67pub(crate) fn post_commit(result: ExecutionResult) -> Result<Bytes, BlockExecutionError> {
68 match result {
69 ExecutionResult::Success { output, .. } => Ok(output.into_data()),
70 ExecutionResult::Revert { output, .. } => {
71 Err(BlockValidationError::WithdrawalRequestsContractCall {
72 message: format!("execution reverted: {output}"),
73 }
74 .into())
75 }
76 ExecutionResult::Halt { reason, .. } => {
77 Err(BlockValidationError::WithdrawalRequestsContractCall {
78 message: format!("execution halted: {reason:?}"),
79 }
80 .into())
81 }
82 }
83}