From 40f923e64646c300909d79a49a3e5c2540ee6219 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 20 Sep 2024 11:41:29 +0200 Subject: [PATCH 01/20] feat: add SystemCaller helper type --- crates/evm/src/system_calls/mod.rs | 76 ++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 50d5c4c857ff..ec91779e7c71 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -1,7 +1,9 @@ //! System contract call functions. mod eip2935; + pub use eip2935::*; +use revm_primitives::ResultAndState; mod eip4788; pub use eip4788::*; @@ -11,3 +13,77 @@ pub use eip7002::*; mod eip7251; pub use eip7251::*; +use reth_execution_errors::BlockExecutionError; + +/// A hook that is called after each state change. +// TODO impl for &mut +pub trait OnStateHook { + /// Invoked with the result and state after each system call. + fn on_state(&mut self, state: &ResultAndState); +} + +impl OnStateHook for F +where + F: FnMut(&ResultAndState), +{ + fn on_state(&mut self, state: &ResultAndState) { + self(state) + } +} + +/// An [`OnStateHook`] that does nothing. +#[derive(Default, Debug, Clone)] +#[non_exhaustive] +pub struct NoopHook; + +impl OnStateHook for NoopHook { + fn on_state(&mut self, _state: &ResultAndState) {} +} + +/// An ephemeral helper type for executing system calls. +/// +/// This can be used to chain system transaction calls. +#[derive(Debug)] +pub struct SystemCaller { + evm_config: EvmConfig, + db: DB, + chain_spec: Chainspec, + /// Optional hook to be called after each state change. + // TODO do we want this optional? + hook: Option, +} + +impl SystemCaller { + /// Create a new system caller with the given EVM config, database, and chain spec. + pub fn new(evm_config: EvmConfig, db: DB, chain_spec: Chainspec) -> Self { + Self { evm_config, db, chain_spec, hook: None } + } +} + +impl SystemCaller { + /// Installs a custom hook to be called after each state change. + pub fn with_state_hook( + self, + hook: H, + ) -> SystemCaller { + let Self { evm_config, db, chain_spec, .. } = self; + SystemCaller { evm_config, db, chain_spec, hook: Some(hook) } + } + /// Convenience type to consume the type and drop borrowed fields + pub fn finish(self) {} +} + +impl SystemCaller { + // TODO add apply functions that are chainable + + /// Applies the pre-block call to the EIP-2935 blockhashes contract. + pub fn pre_block_blockhashes_contract_call(self) -> Result { + // TODO: + // transact + // apply hook + // commit + todo!() + } + + // TODO add other system calls +} From 4ed37c9b39f1d2c409cb91d3c0ea69924f490f63 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Fri, 27 Sep 2024 12:21:13 +0200 Subject: [PATCH 02/20] complete EIP-2935 system call --- crates/evm/src/system_calls/mod.rs | 68 ++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index ec91779e7c71..957079e95e00 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -1,9 +1,15 @@ //! System contract call functions. -mod eip2935; +use crate::ConfigureEvm; +use core::fmt::Display; +use reth_chainspec::ChainSpec; +use reth_execution_errors::BlockExecutionError; +use reth_primitives::Header; +use revm::{Database, DatabaseCommit, Evm}; +use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState, B256}; +mod eip2935; pub use eip2935::*; -use revm_primitives::ResultAndState; mod eip4788; pub use eip4788::*; @@ -13,7 +19,6 @@ pub use eip7002::*; mod eip7251; pub use eip7251::*; -use reth_execution_errors::BlockExecutionError; /// A hook that is called after each state change. // TODO impl for &mut @@ -55,7 +60,7 @@ pub struct SystemCaller { impl SystemCaller { /// Create a new system caller with the given EVM config, database, and chain spec. - pub fn new(evm_config: EvmConfig, db: DB, chain_spec: Chainspec) -> Self { + pub const fn new(evm_config: EvmConfig, db: DB, chain_spec: Chainspec) -> Self { Self { evm_config, db, chain_spec, hook: None } } } @@ -74,15 +79,54 @@ impl SystemCaller SystemCaller { - // TODO add apply functions that are chainable - /// Applies the pre-block call to the EIP-2935 blockhashes contract. - pub fn pre_block_blockhashes_contract_call(self) -> Result { - // TODO: - // transact - // apply hook - // commit - todo!() + pub fn pre_block_blockhashes_contract_call( + mut self, + initialized_cfg: &CfgEnvWithHandlerCfg, + initialized_block_env: &BlockEnv, + parent_block_hash: B256, + ) -> Result + where + DB: Database + DatabaseCommit + Clone, + DB::Error: Display, + EvmConfig: ConfigureEvm
, + Chainspec: AsRef, + Hook: OnStateHook, + { + let mut evm = Evm::builder() + .with_db(self.db.clone()) + .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( + initialized_cfg.clone(), + initialized_block_env.clone(), + Default::default(), + )) + .build(); + + let result_and_state = eip2935::transact_blockhashes_contract_call( + &self.evm_config, + self.chain_spec.as_ref(), + initialized_block_env.timestamp.to(), + initialized_block_env.number.to(), + parent_block_hash, + &mut evm, + )?; + + if let Some(ref mut hook) = self.hook { + if let Some(res) = result_and_state { + hook.on_state(&res); + } + } + + eip2935::apply_blockhashes_contract_call( + &self.evm_config, + self.chain_spec.as_ref(), + initialized_block_env.timestamp.to(), + initialized_block_env.number.to(), + parent_block_hash, + &mut evm, + )?; + + Ok(self) } // TODO add other system calls From 6d25641c9f8ee048977192d673e8e817193fb327 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Fri, 27 Sep 2024 13:15:39 +0200 Subject: [PATCH 03/20] commit after successful tracnsact --- crates/evm/src/system_calls/mod.rs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 957079e95e00..569056b5d15a 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -111,21 +111,13 @@ impl SystemCaller Date: Fri, 27 Sep 2024 14:36:23 +0200 Subject: [PATCH 04/20] add evm field --- crates/evm/src/system_calls/mod.rs | 50 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 569056b5d15a..6b8e00c4b71e 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -6,7 +6,7 @@ use reth_chainspec::ChainSpec; use reth_execution_errors::BlockExecutionError; use reth_primitives::Header; use revm::{Database, DatabaseCommit, Evm}; -use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState, B256}; +use revm_primitives::{BlockEnv, ResultAndState, B256}; mod eip2935; pub use eip2935::*; @@ -48,8 +48,9 @@ impl OnStateHook for NoopHook { /// An ephemeral helper type for executing system calls. /// /// This can be used to chain system transaction calls. -#[derive(Debug)] -pub struct SystemCaller { +#[allow(missing_debug_implementations)] +pub struct SystemCaller<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook = NoopHook> { + evm: Evm<'a, Ext, DB>, evm_config: EvmConfig, db: DB, chain_spec: Chainspec, @@ -58,31 +59,39 @@ pub struct SystemCaller { hook: Option, } -impl SystemCaller { +impl<'a, EvmConfig, Ext, DB: Database, Chainspec> SystemCaller<'a, EvmConfig, Ext, DB, Chainspec> { /// Create a new system caller with the given EVM config, database, and chain spec. - pub const fn new(evm_config: EvmConfig, db: DB, chain_spec: Chainspec) -> Self { - Self { evm_config, db, chain_spec, hook: None } + pub const fn new( + evm_config: EvmConfig, + db: DB, + chain_spec: Chainspec, + evm: Evm<'a, Ext, DB>, + ) -> Self { + Self { evm_config, db, chain_spec, evm, hook: None } } } -impl SystemCaller { +impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> + SystemCaller<'a, EvmConfig, Ext, DB, Chainspec, Hook> +{ /// Installs a custom hook to be called after each state change. pub fn with_state_hook( self, hook: H, - ) -> SystemCaller { - let Self { evm_config, db, chain_spec, .. } = self; - SystemCaller { evm_config, db, chain_spec, hook: Some(hook) } + ) -> SystemCaller<'a, EvmConfig, Ext, DB, Chainspec, H> { + let Self { evm_config, db, chain_spec, evm, .. } = self; + SystemCaller { evm_config, db, chain_spec, evm, hook: Some(hook) } } - /// Convenience type to consume the type and drop borrowed fields + /// Convenience method to consume the type and drop borrowed fields pub fn finish(self) {} } -impl SystemCaller { +impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> + SystemCaller<'a, EvmConfig, Ext, DB, Chainspec, Hook> +{ /// Applies the pre-block call to the EIP-2935 blockhashes contract. - pub fn pre_block_blockhashes_contract_call( + pub fn pre_block_blockhashes_contract_call( mut self, - initialized_cfg: &CfgEnvWithHandlerCfg, initialized_block_env: &BlockEnv, parent_block_hash: B256, ) -> Result @@ -93,29 +102,20 @@ impl SystemCaller, Hook: OnStateHook, { - let mut evm = Evm::builder() - .with_db(self.db.clone()) - .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( - initialized_cfg.clone(), - initialized_block_env.clone(), - Default::default(), - )) - .build(); - let result_and_state = eip2935::transact_blockhashes_contract_call( &self.evm_config, self.chain_spec.as_ref(), initialized_block_env.timestamp.to(), initialized_block_env.number.to(), parent_block_hash, - &mut evm, + &mut self.evm, )?; if let Some(res) = result_and_state { if let Some(ref mut hook) = self.hook { hook.on_state(&res); } - evm.context.evm.db.commit(res.state); + self.evm.context.evm.db.commit(res.state); } Ok(self) From 4e557628a3c22f644979a597be091f1dc8187294 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Fri, 27 Sep 2024 17:14:09 +0200 Subject: [PATCH 05/20] implement all eip system call methods --- crates/evm/src/system_calls/mod.rs | 300 +++++++++++++++++++++++++++-- 1 file changed, 280 insertions(+), 20 deletions(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 6b8e00c4b71e..41fc3d804cac 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -1,12 +1,17 @@ //! System contract call functions. use crate::ConfigureEvm; +use alloc::{format, string::ToString, vec::Vec}; +use alloy_eips::{eip7002::WithdrawalRequest, eip7251::ConsolidationRequest}; +use alloy_primitives::{Address, FixedBytes}; use core::fmt::Display; use reth_chainspec::ChainSpec; -use reth_execution_errors::BlockExecutionError; -use reth_primitives::Header; +use reth_execution_errors::{BlockExecutionError, BlockValidationError}; +use reth_primitives::{Buf, Header, Request}; use revm::{Database, DatabaseCommit, Evm}; -use revm_primitives::{BlockEnv, ResultAndState, B256}; +use revm_primitives::{ + BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, ResultAndState, B256, +}; mod eip2935; pub use eip2935::*; @@ -49,52 +54,88 @@ impl OnStateHook for NoopHook { /// /// This can be used to chain system transaction calls. #[allow(missing_debug_implementations)] -pub struct SystemCaller<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook = NoopHook> { - evm: Evm<'a, Ext, DB>, +pub struct SystemCaller<'a, EvmConfig, DB: Database, Chainspec, Hook = NoopHook> { + evm: Evm<'a, (), DB>, evm_config: EvmConfig, - db: DB, chain_spec: Chainspec, /// Optional hook to be called after each state change. // TODO do we want this optional? hook: Option, } -impl<'a, EvmConfig, Ext, DB: Database, Chainspec> SystemCaller<'a, EvmConfig, Ext, DB, Chainspec> { - /// Create a new system caller with the given EVM config, database, and chain spec. - pub const fn new( +impl<'a, EvmConfig, DB: Database, Chainspec> SystemCaller<'a, EvmConfig, DB, Chainspec> { + /// Create a new system caller with the given EVM, EVM config, database, and chain spec. + pub const fn new_with_evm( + evm_config: EvmConfig, + chain_spec: Chainspec, + evm: Evm<'a, (), DB>, + ) -> Self { + Self { evm_config, chain_spec, evm, hook: None } + } + /// Create a new system caller with the given EVM config, database, and chain spec, and creates + /// the EVM with the given initialized config and block environment. + pub fn new_with_initialized_config_and_block_env( evm_config: EvmConfig, db: DB, chain_spec: Chainspec, - evm: Evm<'a, Ext, DB>, + initialized_cfg: &CfgEnvWithHandlerCfg, + initialized_block_env: &BlockEnv, ) -> Self { - Self { evm_config, db, chain_spec, evm, hook: None } + let evm = Evm::builder() + .with_db(db) + .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( + initialized_cfg.clone(), + initialized_block_env.clone(), + Default::default(), + )) + .build(); + + Self { evm_config, chain_spec, evm, hook: None } } } -impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> - SystemCaller<'a, EvmConfig, Ext, DB, Chainspec, Hook> +impl<'a, EvmConfig, DB: Database, Chainspec, Hook> + SystemCaller<'a, EvmConfig, DB, Chainspec, Hook> { /// Installs a custom hook to be called after each state change. pub fn with_state_hook( self, hook: H, - ) -> SystemCaller<'a, EvmConfig, Ext, DB, Chainspec, H> { - let Self { evm_config, db, chain_spec, evm, .. } = self; - SystemCaller { evm_config, db, chain_spec, evm, hook: Some(hook) } + ) -> SystemCaller<'a, EvmConfig, DB, Chainspec, H> { + let Self { evm_config, chain_spec, evm, .. } = self; + SystemCaller { evm_config, chain_spec, evm, hook: Some(hook) } } /// Convenience method to consume the type and drop borrowed fields pub fn finish(self) {} } -impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> - SystemCaller<'a, EvmConfig, Ext, DB, Chainspec, Hook> +impl<'a, EvmConfig, DB: Database, Chainspec, Hook> + SystemCaller<'a, EvmConfig, DB, Chainspec, Hook> { /// Applies the pre-block call to the EIP-2935 blockhashes contract. - pub fn pre_block_blockhashes_contract_call( + pub fn pre_block_blockhashes_contract_call( mut self, initialized_block_env: &BlockEnv, parent_block_hash: B256, ) -> Result + where + DB: Database + DatabaseCommit + Clone, + DB::Error: Display, + EvmConfig: ConfigureEvm
, + Chainspec: AsRef, + Hook: OnStateHook, + { + self.apply_blockhashes_contract_call(initialized_block_env, parent_block_hash)?; + + Ok(self) + } + + /// Applies the pre-block call to the EIP-2935 blockhashes contract. + pub fn apply_blockhashes_contract_call( + &mut self, + initialized_block_env: &BlockEnv, + parent_block_hash: B256, + ) -> Result<(), BlockExecutionError> where DB: Database + DatabaseCommit + Clone, DB::Error: Display, @@ -118,8 +159,227 @@ impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> self.evm.context.evm.db.commit(res.state); } + Ok(()) + } + + /// Applies the pre-block call to the EIP-4788 beacon root contract. + pub fn pre_block_beacon_root_contract_call( + mut self, + initialized_block_env: &BlockEnv, + parent_block_hash: Option, + ) -> Result + where + DB: Database + DatabaseCommit + Clone, + DB::Error: Display, + EvmConfig: ConfigureEvm
, + Chainspec: AsRef, + Hook: OnStateHook, + { + self.apply_beacon_root_contract_call(initialized_block_env, parent_block_hash)?; + Ok(self) } - // TODO add other system calls + /// Applies the pre-block call to the EIP-4788 beacon root contract. + pub fn apply_beacon_root_contract_call( + &mut self, + initialized_block_env: &BlockEnv, + parent_block_hash: Option, + ) -> Result<(), BlockExecutionError> + where + DB: Database + DatabaseCommit + Clone, + DB::Error: Display, + EvmConfig: ConfigureEvm
, + Chainspec: AsRef, + Hook: OnStateHook, + { + let result_and_state = eip4788::transact_beacon_root_contract_call( + &self.evm_config, + self.chain_spec.as_ref(), + initialized_block_env.timestamp.to(), + initialized_block_env.number.to(), + parent_block_hash, + &mut self.evm, + )?; + + if let Some(res) = result_and_state { + if let Some(ref mut hook) = self.hook { + hook.on_state(&res); + } + self.evm.context.evm.db.commit(res.state); + } + + Ok(()) + } + + /// Applies the post-block call to the EIP-7002 withdrawal request contract. + pub fn post_block_withdrawal_request_contract_call( + self, + ) -> Result, BlockExecutionError> + where + DB: Database + DatabaseCommit + Clone, + DB::Error: Display, + EvmConfig: ConfigureEvm
, + Chainspec: AsRef, + Hook: OnStateHook, + { + let result = self.apply_withdrawal_request_contract_call()?; + + Ok(result) + } + + /// Applies the post-block call to the EIP-7002 withdrawal request contract. + pub fn apply_withdrawal_request_contract_call( + mut self, + ) -> Result, BlockExecutionError> + where + DB: Database + DatabaseCommit + Clone, + DB::Error: Display, + EvmConfig: ConfigureEvm
, + Chainspec: AsRef, + Hook: OnStateHook, + { + let result_and_state = + eip7002::transact_withdrawal_requests_contract_call(&self.evm_config, &mut self.evm)?; + + if let Some(ref mut hook) = self.hook { + hook.on_state(&result_and_state); + } + self.evm.context.evm.db.commit(result_and_state.state); + + let mut data = match result_and_state.result { + ExecutionResult::Success { output, .. } => Ok(output.into_data()), + ExecutionResult::Revert { output, .. } => { + Err(BlockValidationError::WithdrawalRequestsContractCall { + message: format!("execution reverted: {output}"), + }) + } + ExecutionResult::Halt { reason, .. } => { + Err(BlockValidationError::WithdrawalRequestsContractCall { + message: format!("execution halted: {reason:?}"), + }) + } + }?; + + // Withdrawals are encoded as a series of withdrawal requests, each with the following + // format: + // + // +------+--------+--------+ + // | addr | pubkey | amount | + // +------+--------+--------+ + // 20 48 8 + + const WITHDRAWAL_REQUEST_SIZE: usize = 20 + 48 + 8; + let mut withdrawal_requests = Vec::with_capacity(data.len() / WITHDRAWAL_REQUEST_SIZE); + while data.has_remaining() { + if data.remaining() < WITHDRAWAL_REQUEST_SIZE { + return Err(BlockValidationError::WithdrawalRequestsContractCall { + message: "invalid withdrawal request length".to_string(), + } + .into()) + } + + let mut source_address = Address::ZERO; + data.copy_to_slice(source_address.as_mut_slice()); + + let mut validator_pubkey = FixedBytes::<48>::ZERO; + data.copy_to_slice(validator_pubkey.as_mut_slice()); + + let amount = data.get_u64(); + + withdrawal_requests + .push(WithdrawalRequest { source_address, validator_pubkey, amount }.into()); + } + + Ok(withdrawal_requests) + } + + /// Applies the post-block call to the EIP-7251 consolidation requests contract. + pub fn post_block_consolidation_requests_contract_call( + self, + ) -> Result, BlockExecutionError> + where + DB: Database + DatabaseCommit + Clone, + DB::Error: Display, + EvmConfig: ConfigureEvm
, + Chainspec: AsRef, + Hook: OnStateHook, + { + let res = self.apply_consolidation_requests_contract_call()?; + + Ok(res) + } + + /// Applies the post-block call to the EIP-7251 consolidation requests contract. + pub fn apply_consolidation_requests_contract_call( + mut self, + ) -> Result, BlockExecutionError> + where + DB: Database + DatabaseCommit + Clone, + DB::Error: Display, + EvmConfig: ConfigureEvm
, + Chainspec: AsRef, + Hook: OnStateHook, + { + let result_and_state = eip7251::transact_consolidation_requests_contract_call( + &self.evm_config, + &mut self.evm, + )?; + + if let Some(ref mut hook) = self.hook { + hook.on_state(&result_and_state); + } + self.evm.context.evm.db.commit(result_and_state.state); + + let mut data = match result_and_state.result { + ExecutionResult::Success { output, .. } => Ok(output.into_data()), + ExecutionResult::Revert { output, .. } => { + Err(BlockValidationError::ConsolidationRequestsContractCall { + message: format!("execution reverted: {output}"), + }) + } + ExecutionResult::Halt { reason, .. } => { + Err(BlockValidationError::ConsolidationRequestsContractCall { + message: format!("execution halted: {reason:?}"), + }) + } + }?; + + // Consolidations are encoded as a series of consolidation requests, each with the following + // format: + // + // +------+--------+---------------+ + // | addr | pubkey | target pubkey | + // +------+--------+---------------+ + // 20 48 48 + + const CONSOLIDATION_REQUEST_SIZE: usize = 20 + 48 + 48; + let mut consolidation_requests = + Vec::with_capacity(data.len() / CONSOLIDATION_REQUEST_SIZE); + while data.has_remaining() { + if data.remaining() < CONSOLIDATION_REQUEST_SIZE { + return Err(BlockValidationError::ConsolidationRequestsContractCall { + message: "invalid consolidation request length".to_string(), + } + .into()) + } + + let mut source_address = Address::ZERO; + data.copy_to_slice(source_address.as_mut_slice()); + + let mut source_pubkey = FixedBytes::<48>::ZERO; + data.copy_to_slice(source_pubkey.as_mut_slice()); + + let mut target_pubkey = FixedBytes::<48>::ZERO; + data.copy_to_slice(target_pubkey.as_mut_slice()); + + consolidation_requests.push(Request::ConsolidationRequest(ConsolidationRequest { + source_address, + source_pubkey, + target_pubkey, + })); + } + + Ok(consolidation_requests) + } } From be5058533139752d2f2b041a8574d01c794b06f5 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Fri, 27 Sep 2024 19:27:35 +0200 Subject: [PATCH 06/20] generic Ext for Evm and updated apply params --- crates/evm/src/system_calls/mod.rs | 68 ++++++++++++++++++------------ 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 41fc3d804cac..9e22916ce046 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -54,8 +54,8 @@ impl OnStateHook for NoopHook { /// /// This can be used to chain system transaction calls. #[allow(missing_debug_implementations)] -pub struct SystemCaller<'a, EvmConfig, DB: Database, Chainspec, Hook = NoopHook> { - evm: Evm<'a, (), DB>, +pub struct SystemCaller<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook = NoopHook> { + evm: Evm<'a, Ext, DB>, evm_config: EvmConfig, chain_spec: Chainspec, /// Optional hook to be called after each state change. @@ -63,12 +63,12 @@ pub struct SystemCaller<'a, EvmConfig, DB: Database, Chainspec, Hook = NoopHook> hook: Option, } -impl<'a, EvmConfig, DB: Database, Chainspec> SystemCaller<'a, EvmConfig, DB, Chainspec> { +impl<'a, EvmConfig, Ext, DB: Database, Chainspec> SystemCaller<'a, EvmConfig, Ext, DB, Chainspec> { /// Create a new system caller with the given EVM, EVM config, database, and chain spec. pub const fn new_with_evm( evm_config: EvmConfig, chain_spec: Chainspec, - evm: Evm<'a, (), DB>, + evm: Evm<'a, Ext, DB>, ) -> Self { Self { evm_config, chain_spec, evm, hook: None } } @@ -80,9 +80,11 @@ impl<'a, EvmConfig, DB: Database, Chainspec> SystemCaller<'a, EvmConfig, DB, Cha chain_spec: Chainspec, initialized_cfg: &CfgEnvWithHandlerCfg, initialized_block_env: &BlockEnv, + external_context: Ext, ) -> Self { let evm = Evm::builder() .with_db(db) + .with_external_context(external_context) .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( initialized_cfg.clone(), initialized_block_env.clone(), @@ -94,14 +96,14 @@ impl<'a, EvmConfig, DB: Database, Chainspec> SystemCaller<'a, EvmConfig, DB, Cha } } -impl<'a, EvmConfig, DB: Database, Chainspec, Hook> - SystemCaller<'a, EvmConfig, DB, Chainspec, Hook> +impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> + SystemCaller<'a, EvmConfig, Ext, DB, Chainspec, Hook> { /// Installs a custom hook to be called after each state change. pub fn with_state_hook( self, hook: H, - ) -> SystemCaller<'a, EvmConfig, DB, Chainspec, H> { + ) -> SystemCaller<'a, EvmConfig, Ext, DB, Chainspec, H> { let Self { evm_config, chain_spec, evm, .. } = self; SystemCaller { evm_config, chain_spec, evm, hook: Some(hook) } } @@ -109,8 +111,8 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> pub fn finish(self) {} } -impl<'a, EvmConfig, DB: Database, Chainspec, Hook> - SystemCaller<'a, EvmConfig, DB, Chainspec, Hook> +impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> + SystemCaller<'a, EvmConfig, Ext, DB, Chainspec, Hook> { /// Applies the pre-block call to the EIP-2935 blockhashes contract. pub fn pre_block_blockhashes_contract_call( @@ -119,13 +121,17 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> parent_block_hash: B256, ) -> Result where - DB: Database + DatabaseCommit + Clone, + DB: Database + DatabaseCommit, DB::Error: Display, EvmConfig: ConfigureEvm
, Chainspec: AsRef, Hook: OnStateHook, { - self.apply_blockhashes_contract_call(initialized_block_env, parent_block_hash)?; + self.apply_blockhashes_contract_call( + initialized_block_env.timestamp.to(), + initialized_block_env.number.to(), + parent_block_hash, + )?; Ok(self) } @@ -133,11 +139,12 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> /// Applies the pre-block call to the EIP-2935 blockhashes contract. pub fn apply_blockhashes_contract_call( &mut self, - initialized_block_env: &BlockEnv, + timestamp: u64, + block_number: u64, parent_block_hash: B256, ) -> Result<(), BlockExecutionError> where - DB: Database + DatabaseCommit + Clone, + DB: Database + DatabaseCommit, DB::Error: Display, EvmConfig: ConfigureEvm
, Chainspec: AsRef, @@ -146,8 +153,8 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> let result_and_state = eip2935::transact_blockhashes_contract_call( &self.evm_config, self.chain_spec.as_ref(), - initialized_block_env.timestamp.to(), - initialized_block_env.number.to(), + timestamp, + block_number, parent_block_hash, &mut self.evm, )?; @@ -169,13 +176,17 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> parent_block_hash: Option, ) -> Result where - DB: Database + DatabaseCommit + Clone, + DB: Database + DatabaseCommit, DB::Error: Display, EvmConfig: ConfigureEvm
, Chainspec: AsRef, Hook: OnStateHook, { - self.apply_beacon_root_contract_call(initialized_block_env, parent_block_hash)?; + self.apply_beacon_root_contract_call( + initialized_block_env.timestamp.to(), + initialized_block_env.number.to(), + parent_block_hash, + )?; Ok(self) } @@ -183,11 +194,12 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> /// Applies the pre-block call to the EIP-4788 beacon root contract. pub fn apply_beacon_root_contract_call( &mut self, - initialized_block_env: &BlockEnv, + timestamp: u64, + block_number: u64, parent_block_hash: Option, ) -> Result<(), BlockExecutionError> where - DB: Database + DatabaseCommit + Clone, + DB: Database + DatabaseCommit, DB::Error: Display, EvmConfig: ConfigureEvm
, Chainspec: AsRef, @@ -196,8 +208,8 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> let result_and_state = eip4788::transact_beacon_root_contract_call( &self.evm_config, self.chain_spec.as_ref(), - initialized_block_env.timestamp.to(), - initialized_block_env.number.to(), + timestamp, + block_number, parent_block_hash, &mut self.evm, )?; @@ -213,27 +225,27 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> } /// Applies the post-block call to the EIP-7002 withdrawal request contract. - pub fn post_block_withdrawal_request_contract_call( + pub fn post_block_withdrawal_requests_contract_call( self, ) -> Result, BlockExecutionError> where - DB: Database + DatabaseCommit + Clone, + DB: Database + DatabaseCommit, DB::Error: Display, EvmConfig: ConfigureEvm
, Chainspec: AsRef, Hook: OnStateHook, { - let result = self.apply_withdrawal_request_contract_call()?; + let result = self.apply_withdrawal_requests_contract_call()?; Ok(result) } /// Applies the post-block call to the EIP-7002 withdrawal request contract. - pub fn apply_withdrawal_request_contract_call( + pub fn apply_withdrawal_requests_contract_call( mut self, ) -> Result, BlockExecutionError> where - DB: Database + DatabaseCommit + Clone, + DB: Database + DatabaseCommit, DB::Error: Display, EvmConfig: ConfigureEvm
, Chainspec: AsRef, @@ -299,7 +311,7 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> self, ) -> Result, BlockExecutionError> where - DB: Database + DatabaseCommit + Clone, + DB: Database + DatabaseCommit, DB::Error: Display, EvmConfig: ConfigureEvm
, Chainspec: AsRef, @@ -315,7 +327,7 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> mut self, ) -> Result, BlockExecutionError> where - DB: Database + DatabaseCommit + Clone, + DB: Database + DatabaseCommit, DB::Error: Display, EvmConfig: ConfigureEvm
, Chainspec: AsRef, From 7f4d1d3ba01efe5dddb2e2d3b7c9bb3a5bd23f8e Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Fri, 27 Sep 2024 20:00:21 +0200 Subject: [PATCH 07/20] do not consume self --- crates/evm/src/system_calls/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 9e22916ce046..56eec9168e3c 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -226,7 +226,7 @@ impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> /// Applies the post-block call to the EIP-7002 withdrawal request contract. pub fn post_block_withdrawal_requests_contract_call( - self, + &mut self, ) -> Result, BlockExecutionError> where DB: Database + DatabaseCommit, @@ -242,7 +242,7 @@ impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> /// Applies the post-block call to the EIP-7002 withdrawal request contract. pub fn apply_withdrawal_requests_contract_call( - mut self, + &mut self, ) -> Result, BlockExecutionError> where DB: Database + DatabaseCommit, @@ -308,7 +308,7 @@ impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> /// Applies the post-block call to the EIP-7251 consolidation requests contract. pub fn post_block_consolidation_requests_contract_call( - self, + &mut self, ) -> Result, BlockExecutionError> where DB: Database + DatabaseCommit, @@ -324,7 +324,7 @@ impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> /// Applies the post-block call to the EIP-7251 consolidation requests contract. pub fn apply_consolidation_requests_contract_call( - mut self, + &mut self, ) -> Result, BlockExecutionError> where DB: Database + DatabaseCommit, From 90928dcef099ec7987aaea37b85a5fe60efafb87 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Fri, 27 Sep 2024 21:30:49 +0200 Subject: [PATCH 08/20] single constructor, always create local evm --- crates/evm/src/system_calls/mod.rs | 34 +++++++++++------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 56eec9168e3c..e29b1074142a 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -54,8 +54,8 @@ impl OnStateHook for NoopHook { /// /// This can be used to chain system transaction calls. #[allow(missing_debug_implementations)] -pub struct SystemCaller<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook = NoopHook> { - evm: Evm<'a, Ext, DB>, +pub struct SystemCaller<'a, EvmConfig, DB: Database, Chainspec, Hook = NoopHook> { + evm: Evm<'a, (), DB>, evm_config: EvmConfig, chain_spec: Chainspec, /// Optional hook to be called after each state change. @@ -63,28 +63,18 @@ pub struct SystemCaller<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook = Noop hook: Option, } -impl<'a, EvmConfig, Ext, DB: Database, Chainspec> SystemCaller<'a, EvmConfig, Ext, DB, Chainspec> { - /// Create a new system caller with the given EVM, EVM config, database, and chain spec. - pub const fn new_with_evm( - evm_config: EvmConfig, - chain_spec: Chainspec, - evm: Evm<'a, Ext, DB>, - ) -> Self { - Self { evm_config, chain_spec, evm, hook: None } - } +impl<'a, EvmConfig, DB: Database, Chainspec> SystemCaller<'a, EvmConfig, DB, Chainspec> { /// Create a new system caller with the given EVM config, database, and chain spec, and creates /// the EVM with the given initialized config and block environment. - pub fn new_with_initialized_config_and_block_env( + pub fn new( evm_config: EvmConfig, db: DB, chain_spec: Chainspec, initialized_cfg: &CfgEnvWithHandlerCfg, initialized_block_env: &BlockEnv, - external_context: Ext, ) -> Self { let evm = Evm::builder() .with_db(db) - .with_external_context(external_context) .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( initialized_cfg.clone(), initialized_block_env.clone(), @@ -96,14 +86,14 @@ impl<'a, EvmConfig, Ext, DB: Database, Chainspec> SystemCaller<'a, EvmConfig, Ex } } -impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> - SystemCaller<'a, EvmConfig, Ext, DB, Chainspec, Hook> +impl<'a, EvmConfig, DB: Database, Chainspec, Hook> + SystemCaller<'a, EvmConfig, DB, Chainspec, Hook> { /// Installs a custom hook to be called after each state change. pub fn with_state_hook( self, hook: H, - ) -> SystemCaller<'a, EvmConfig, Ext, DB, Chainspec, H> { + ) -> SystemCaller<'a, EvmConfig, DB, Chainspec, H> { let Self { evm_config, chain_spec, evm, .. } = self; SystemCaller { evm_config, chain_spec, evm, hook: Some(hook) } } @@ -111,15 +101,15 @@ impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> pub fn finish(self) {} } -impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> - SystemCaller<'a, EvmConfig, Ext, DB, Chainspec, Hook> +impl<'a, EvmConfig, DB: Database, Chainspec, Hook> + SystemCaller<'a, EvmConfig, DB, Chainspec, Hook> { /// Applies the pre-block call to the EIP-2935 blockhashes contract. pub fn pre_block_blockhashes_contract_call( - mut self, + &mut self, initialized_block_env: &BlockEnv, parent_block_hash: B256, - ) -> Result + ) -> Result<(), BlockExecutionError> where DB: Database + DatabaseCommit, DB::Error: Display, @@ -133,7 +123,7 @@ impl<'a, EvmConfig, Ext, DB: Database, Chainspec, Hook> parent_block_hash, )?; - Ok(self) + Ok(()) } /// Applies the pre-block call to the EIP-2935 blockhashes contract. From 75bf4feb97aa185af18283c1d017fd7412719254 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Sat, 28 Sep 2024 12:45:13 +0200 Subject: [PATCH 09/20] do not wrap evm --- crates/evm/src/system_calls/mod.rs | 127 ++++++++++++++++------------- 1 file changed, 72 insertions(+), 55 deletions(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index e29b1074142a..4082987f80a4 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -54,8 +54,7 @@ impl OnStateHook for NoopHook { /// /// This can be used to chain system transaction calls. #[allow(missing_debug_implementations)] -pub struct SystemCaller<'a, EvmConfig, DB: Database, Chainspec, Hook = NoopHook> { - evm: Evm<'a, (), DB>, +pub struct SystemCaller { evm_config: EvmConfig, chain_spec: Chainspec, /// Optional hook to be called after each state change. @@ -63,50 +62,49 @@ pub struct SystemCaller<'a, EvmConfig, DB: Database, Chainspec, Hook = NoopHook> hook: Option, } -impl<'a, EvmConfig, DB: Database, Chainspec> SystemCaller<'a, EvmConfig, DB, Chainspec> { +impl SystemCaller { /// Create a new system caller with the given EVM config, database, and chain spec, and creates /// the EVM with the given initialized config and block environment. - pub fn new( - evm_config: EvmConfig, - db: DB, - chain_spec: Chainspec, - initialized_cfg: &CfgEnvWithHandlerCfg, - initialized_block_env: &BlockEnv, - ) -> Self { - let evm = Evm::builder() - .with_db(db) - .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( - initialized_cfg.clone(), - initialized_block_env.clone(), - Default::default(), - )) - .build(); - - Self { evm_config, chain_spec, evm, hook: None } + pub fn new(evm_config: EvmConfig, chain_spec: Chainspec) -> Self { + Self { evm_config, chain_spec, hook: None } } } -impl<'a, EvmConfig, DB: Database, Chainspec, Hook> - SystemCaller<'a, EvmConfig, DB, Chainspec, Hook> -{ +impl SystemCaller { /// Installs a custom hook to be called after each state change. - pub fn with_state_hook( - self, - hook: H, - ) -> SystemCaller<'a, EvmConfig, DB, Chainspec, H> { - let Self { evm_config, chain_spec, evm, .. } = self; - SystemCaller { evm_config, chain_spec, evm, hook: Some(hook) } + pub fn with_state_hook(self, hook: H) -> SystemCaller { + let Self { evm_config, chain_spec, .. } = self; + SystemCaller { evm_config, chain_spec, hook: Some(hook) } } /// Convenience method to consume the type and drop borrowed fields pub fn finish(self) {} } -impl<'a, EvmConfig, DB: Database, Chainspec, Hook> - SystemCaller<'a, EvmConfig, DB, Chainspec, Hook> +fn initialize_evm<'a, DB>( + db: &'a mut DB, + initialized_cfg: &'a CfgEnvWithHandlerCfg, + initialized_block_env: &'a BlockEnv, +) -> Evm<'a, (), &'a mut DB> +where + DB: Database + DatabaseCommit, + DB::Error: Display, { + Evm::builder() + .with_db(db) + .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( + initialized_cfg.clone(), + initialized_block_env.clone(), + Default::default(), + )) + .build() +} + +impl SystemCaller { /// Applies the pre-block call to the EIP-2935 blockhashes contract. - pub fn pre_block_blockhashes_contract_call( + pub fn pre_block_blockhashes_contract_call( &mut self, + db: &mut DB, + initialized_cfg: &CfgEnvWithHandlerCfg, initialized_block_env: &BlockEnv, parent_block_hash: B256, ) -> Result<(), BlockExecutionError> @@ -117,21 +115,24 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> Chainspec: AsRef, Hook: OnStateHook, { + let mut evm = initialize_evm(db, initialized_cfg, initialized_block_env); self.apply_blockhashes_contract_call( initialized_block_env.timestamp.to(), initialized_block_env.number.to(), parent_block_hash, + &mut evm, )?; Ok(()) } /// Applies the pre-block call to the EIP-2935 blockhashes contract. - pub fn apply_blockhashes_contract_call( + pub fn apply_blockhashes_contract_call( &mut self, timestamp: u64, block_number: u64, parent_block_hash: B256, + evm: &mut Evm<'_, Ext, DB>, ) -> Result<(), BlockExecutionError> where DB: Database + DatabaseCommit, @@ -146,25 +147,27 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> timestamp, block_number, parent_block_hash, - &mut self.evm, + evm, )?; if let Some(res) = result_and_state { if let Some(ref mut hook) = self.hook { hook.on_state(&res); } - self.evm.context.evm.db.commit(res.state); + evm.context.evm.db.commit(res.state); } Ok(()) } /// Applies the pre-block call to the EIP-4788 beacon root contract. - pub fn pre_block_beacon_root_contract_call( - mut self, + pub fn pre_block_beacon_root_contract_call( + &mut self, + db: &mut DB, + initialized_cfg: &CfgEnvWithHandlerCfg, initialized_block_env: &BlockEnv, parent_block_hash: Option, - ) -> Result + ) -> Result<(), BlockExecutionError> where DB: Database + DatabaseCommit, DB::Error: Display, @@ -172,21 +175,25 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> Chainspec: AsRef, Hook: OnStateHook, { + let mut evm = initialize_evm(db, initialized_cfg, initialized_block_env); + self.apply_beacon_root_contract_call( initialized_block_env.timestamp.to(), initialized_block_env.number.to(), parent_block_hash, + &mut evm, )?; - Ok(self) + Ok(()) } /// Applies the pre-block call to the EIP-4788 beacon root contract. - pub fn apply_beacon_root_contract_call( + pub fn apply_beacon_root_contract_call( &mut self, timestamp: u64, block_number: u64, parent_block_hash: Option, + evm: &mut Evm<'_, Ext, DB>, ) -> Result<(), BlockExecutionError> where DB: Database + DatabaseCommit, @@ -201,22 +208,25 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> timestamp, block_number, parent_block_hash, - &mut self.evm, + evm, )?; if let Some(res) = result_and_state { if let Some(ref mut hook) = self.hook { hook.on_state(&res); } - self.evm.context.evm.db.commit(res.state); + evm.context.evm.db.commit(res.state); } Ok(()) } /// Applies the post-block call to the EIP-7002 withdrawal request contract. - pub fn post_block_withdrawal_requests_contract_call( + pub fn post_block_withdrawal_requests_contract_call( &mut self, + db: &mut DB, + initialized_cfg: &CfgEnvWithHandlerCfg, + initialized_block_env: &BlockEnv, ) -> Result, BlockExecutionError> where DB: Database + DatabaseCommit, @@ -225,14 +235,17 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> Chainspec: AsRef, Hook: OnStateHook, { - let result = self.apply_withdrawal_requests_contract_call()?; + let mut evm = initialize_evm(db, initialized_cfg, initialized_block_env); + + let result = self.apply_withdrawal_requests_contract_call(&mut evm)?; Ok(result) } /// Applies the post-block call to the EIP-7002 withdrawal request contract. - pub fn apply_withdrawal_requests_contract_call( + pub fn apply_withdrawal_requests_contract_call( &mut self, + evm: &mut Evm<'_, Ext, DB>, ) -> Result, BlockExecutionError> where DB: Database + DatabaseCommit, @@ -242,12 +255,12 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> Hook: OnStateHook, { let result_and_state = - eip7002::transact_withdrawal_requests_contract_call(&self.evm_config, &mut self.evm)?; + eip7002::transact_withdrawal_requests_contract_call(&self.evm_config, evm)?; if let Some(ref mut hook) = self.hook { hook.on_state(&result_and_state); } - self.evm.context.evm.db.commit(result_and_state.state); + evm.context.evm.db.commit(result_and_state.state); let mut data = match result_and_state.result { ExecutionResult::Success { output, .. } => Ok(output.into_data()), @@ -297,8 +310,11 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> } /// Applies the post-block call to the EIP-7251 consolidation requests contract. - pub fn post_block_consolidation_requests_contract_call( + pub fn post_block_consolidation_requests_contract_call( &mut self, + db: &mut DB, + initialized_cfg: &CfgEnvWithHandlerCfg, + initialized_block_env: &BlockEnv, ) -> Result, BlockExecutionError> where DB: Database + DatabaseCommit, @@ -307,14 +323,17 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> Chainspec: AsRef, Hook: OnStateHook, { - let res = self.apply_consolidation_requests_contract_call()?; + let mut evm = initialize_evm(db, initialized_cfg, initialized_block_env); + + let res = self.apply_consolidation_requests_contract_call(&mut evm)?; Ok(res) } /// Applies the post-block call to the EIP-7251 consolidation requests contract. - pub fn apply_consolidation_requests_contract_call( + pub fn apply_consolidation_requests_contract_call( &mut self, + evm: &mut Evm<'_, Ext, DB>, ) -> Result, BlockExecutionError> where DB: Database + DatabaseCommit, @@ -323,15 +342,13 @@ impl<'a, EvmConfig, DB: Database, Chainspec, Hook> Chainspec: AsRef, Hook: OnStateHook, { - let result_and_state = eip7251::transact_consolidation_requests_contract_call( - &self.evm_config, - &mut self.evm, - )?; + let result_and_state = + eip7251::transact_consolidation_requests_contract_call(&self.evm_config, evm)?; if let Some(ref mut hook) = self.hook { hook.on_state(&result_and_state); } - self.evm.context.evm.db.commit(result_and_state.state); + evm.context.evm.db.commit(result_and_state.state); let mut data = match result_and_state.result { ExecutionResult::Success { output, .. } => Ok(output.into_data()), From 80434ad7a775db498ff9d920488d3a7e19c9fe6d Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Sat, 28 Sep 2024 12:58:15 +0200 Subject: [PATCH 10/20] refactor where clauses --- crates/evm/src/system_calls/mod.rs | 31 ++++++------------------------ 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 4082987f80a4..5d924afd7f33 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -99,7 +99,12 @@ where .build() } -impl SystemCaller { +impl SystemCaller +where + EvmConfig: ConfigureEvm
, + Chainspec: AsRef, + Hook: OnStateHook, +{ /// Applies the pre-block call to the EIP-2935 blockhashes contract. pub fn pre_block_blockhashes_contract_call( &mut self, @@ -111,9 +116,6 @@ impl SystemCaller { where DB: Database + DatabaseCommit, DB::Error: Display, - EvmConfig: ConfigureEvm
, - Chainspec: AsRef, - Hook: OnStateHook, { let mut evm = initialize_evm(db, initialized_cfg, initialized_block_env); self.apply_blockhashes_contract_call( @@ -137,9 +139,6 @@ impl SystemCaller { where DB: Database + DatabaseCommit, DB::Error: Display, - EvmConfig: ConfigureEvm
, - Chainspec: AsRef, - Hook: OnStateHook, { let result_and_state = eip2935::transact_blockhashes_contract_call( &self.evm_config, @@ -171,9 +170,6 @@ impl SystemCaller { where DB: Database + DatabaseCommit, DB::Error: Display, - EvmConfig: ConfigureEvm
, - Chainspec: AsRef, - Hook: OnStateHook, { let mut evm = initialize_evm(db, initialized_cfg, initialized_block_env); @@ -198,9 +194,6 @@ impl SystemCaller { where DB: Database + DatabaseCommit, DB::Error: Display, - EvmConfig: ConfigureEvm
, - Chainspec: AsRef, - Hook: OnStateHook, { let result_and_state = eip4788::transact_beacon_root_contract_call( &self.evm_config, @@ -231,9 +224,6 @@ impl SystemCaller { where DB: Database + DatabaseCommit, DB::Error: Display, - EvmConfig: ConfigureEvm
, - Chainspec: AsRef, - Hook: OnStateHook, { let mut evm = initialize_evm(db, initialized_cfg, initialized_block_env); @@ -250,9 +240,6 @@ impl SystemCaller { where DB: Database + DatabaseCommit, DB::Error: Display, - EvmConfig: ConfigureEvm
, - Chainspec: AsRef, - Hook: OnStateHook, { let result_and_state = eip7002::transact_withdrawal_requests_contract_call(&self.evm_config, evm)?; @@ -319,9 +306,6 @@ impl SystemCaller { where DB: Database + DatabaseCommit, DB::Error: Display, - EvmConfig: ConfigureEvm
, - Chainspec: AsRef, - Hook: OnStateHook, { let mut evm = initialize_evm(db, initialized_cfg, initialized_block_env); @@ -338,9 +322,6 @@ impl SystemCaller { where DB: Database + DatabaseCommit, DB::Error: Display, - EvmConfig: ConfigureEvm
, - Chainspec: AsRef, - Hook: OnStateHook, { let result_and_state = eip7251::transact_consolidation_requests_contract_call(&self.evm_config, evm)?; From c917cdc54a9a6c17b360e83856013732bd607be8 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Sat, 28 Sep 2024 13:05:53 +0200 Subject: [PATCH 11/20] remove uneeded trait bounds --- crates/evm/src/system_calls/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 5d924afd7f33..145ce6cfe1c9 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -86,8 +86,7 @@ fn initialize_evm<'a, DB>( initialized_block_env: &'a BlockEnv, ) -> Evm<'a, (), &'a mut DB> where - DB: Database + DatabaseCommit, - DB::Error: Display, + DB: Database, { Evm::builder() .with_db(db) From 16a7eadfd61f21476a842103f7d22872d8384281 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Sat, 28 Sep 2024 13:37:17 +0200 Subject: [PATCH 12/20] const fn --- crates/evm/src/system_calls/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 145ce6cfe1c9..7e6720a8d4ce 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -65,7 +65,7 @@ pub struct SystemCaller { impl SystemCaller { /// Create a new system caller with the given EVM config, database, and chain spec, and creates /// the EVM with the given initialized config and block environment. - pub fn new(evm_config: EvmConfig, chain_spec: Chainspec) -> Self { + pub const fn new(evm_config: EvmConfig, chain_spec: Chainspec) -> Self { Self { evm_config, chain_spec, hook: None } } } From 7c2c3f9a96feab7966b820cf7e5c7d1d0ac156c0 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Sat, 28 Sep 2024 14:04:24 +0200 Subject: [PATCH 13/20] take references of evm config and chainspec --- crates/evm/src/system_calls/mod.rs | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 7e6720a8d4ce..d19594537e52 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -54,25 +54,28 @@ impl OnStateHook for NoopHook { /// /// This can be used to chain system transaction calls. #[allow(missing_debug_implementations)] -pub struct SystemCaller { - evm_config: EvmConfig, - chain_spec: Chainspec, +pub struct SystemCaller<'a, EvmConfig, Chainspec, Hook = NoopHook> { + evm_config: &'a EvmConfig, + chain_spec: &'a Chainspec, /// Optional hook to be called after each state change. // TODO do we want this optional? hook: Option, } -impl SystemCaller { +impl<'a, EvmConfig, Chainspec> SystemCaller<'a, EvmConfig, Chainspec> { /// Create a new system caller with the given EVM config, database, and chain spec, and creates /// the EVM with the given initialized config and block environment. - pub const fn new(evm_config: EvmConfig, chain_spec: Chainspec) -> Self { + pub const fn new(evm_config: &'a EvmConfig, chain_spec: &'a Chainspec) -> Self { Self { evm_config, chain_spec, hook: None } } } -impl SystemCaller { +impl<'a, EvmConfig, Chainspec, Hook> SystemCaller<'a, EvmConfig, Chainspec, Hook> { /// Installs a custom hook to be called after each state change. - pub fn with_state_hook(self, hook: H) -> SystemCaller { + pub fn with_state_hook( + self, + hook: H, + ) -> SystemCaller<'a, EvmConfig, Chainspec, H> { let Self { evm_config, chain_spec, .. } = self; SystemCaller { evm_config, chain_spec, hook: Some(hook) } } @@ -98,7 +101,7 @@ where .build() } -impl SystemCaller +impl<'a, EvmConfig, Chainspec, Hook> SystemCaller<'a, EvmConfig, Chainspec, Hook> where EvmConfig: ConfigureEvm
, Chainspec: AsRef, @@ -140,7 +143,7 @@ where DB::Error: Display, { let result_and_state = eip2935::transact_blockhashes_contract_call( - &self.evm_config, + &self.evm_config.clone(), self.chain_spec.as_ref(), timestamp, block_number, @@ -195,7 +198,7 @@ where DB::Error: Display, { let result_and_state = eip4788::transact_beacon_root_contract_call( - &self.evm_config, + &self.evm_config.clone(), self.chain_spec.as_ref(), timestamp, block_number, @@ -241,7 +244,7 @@ where DB::Error: Display, { let result_and_state = - eip7002::transact_withdrawal_requests_contract_call(&self.evm_config, evm)?; + eip7002::transact_withdrawal_requests_contract_call(&self.evm_config.clone(), evm)?; if let Some(ref mut hook) = self.hook { hook.on_state(&result_and_state); @@ -323,7 +326,7 @@ where DB::Error: Display, { let result_and_state = - eip7251::transact_consolidation_requests_contract_call(&self.evm_config, evm)?; + eip7251::transact_consolidation_requests_contract_call(&self.evm_config.clone(), evm)?; if let Some(ref mut hook) = self.hook { hook.on_state(&result_and_state); From 4d553cc1dcc882074790ca015a83786e130cbd0d Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Sun, 29 Sep 2024 10:14:27 +0200 Subject: [PATCH 14/20] single entry point to apply pre block execution changes --- crates/evm/src/system_calls/eip2935.rs | 24 ++++++++++++++++++- crates/evm/src/system_calls/eip4788.rs | 24 ++++++++++++++++++- crates/evm/src/system_calls/mod.rs | 33 +++++++++++++++++++++++--- 3 files changed, 76 insertions(+), 5 deletions(-) diff --git a/crates/evm/src/system_calls/eip2935.rs b/crates/evm/src/system_calls/eip2935.rs index 7b09a4813079..4a5433c57c21 100644 --- a/crates/evm/src/system_calls/eip2935.rs +++ b/crates/evm/src/system_calls/eip2935.rs @@ -8,7 +8,7 @@ use alloy_primitives::B256; use core::fmt::Display; use reth_chainspec::EthereumHardforks; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; -use reth_primitives::Header; +use reth_primitives::{Block, Header}; use revm::{interpreter::Host, Database, DatabaseCommit, Evm}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState}; @@ -116,6 +116,28 @@ where Ok(Some(res)) } +#[inline] +pub(crate) fn transact( + evm_config: &EvmConfig, + chain_spec: impl EthereumHardforks, + block: &Block, + evm: &mut Evm<'_, EXT, DB>, +) -> Result, BlockExecutionError> +where + DB: Database + DatabaseCommit, + DB::Error: core::fmt::Display, + EvmConfig: ConfigureEvm
, +{ + transact_blockhashes_contract_call( + evm_config, + chain_spec, + block.timestamp, + block.number, + block.parent_hash, + evm, + ) +} + /// Applies the pre-block call to the [EIP-2935] blockhashes contract, using the given block, /// chain specification, and EVM and commits the relevant state changes. /// diff --git a/crates/evm/src/system_calls/eip4788.rs b/crates/evm/src/system_calls/eip4788.rs index a1f97bf5e908..604cf1a6b168 100644 --- a/crates/evm/src/system_calls/eip4788.rs +++ b/crates/evm/src/system_calls/eip4788.rs @@ -6,7 +6,7 @@ use alloy_eips::eip4788::BEACON_ROOTS_ADDRESS; use alloy_primitives::B256; use reth_chainspec::EthereumHardforks; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; -use reth_primitives::Header; +use reth_primitives::{Block, Header}; use revm::{interpreter::Host, Database, DatabaseCommit, Evm}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState}; @@ -126,6 +126,28 @@ where Ok(Some(res)) } +#[inline] +pub(crate) fn transact( + evm_config: &EvmConfig, + chain_spec: impl EthereumHardforks, + block: &Block, + evm: &mut Evm<'_, EXT, DB>, +) -> Result, BlockExecutionError> +where + DB: Database + DatabaseCommit, + DB::Error: core::fmt::Display, + EvmConfig: ConfigureEvm
, +{ + transact_beacon_root_contract_call( + evm_config, + &chain_spec, + block.timestamp, + block.number, + block.parent_beacon_block_root, + evm, + ) +} + /// Applies the pre-block call to the [EIP-4788] beacon block root contract, using the given block, /// chain spec, EVM. /// diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index d19594537e52..b8ad644cae20 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -7,7 +7,7 @@ use alloy_primitives::{Address, FixedBytes}; use core::fmt::Display; use reth_chainspec::ChainSpec; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; -use reth_primitives::{Buf, Header, Request}; +use reth_primitives::{Block, Buf, Header, Request}; use revm::{Database, DatabaseCommit, Evm}; use revm_primitives::{ BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, ResultAndState, B256, @@ -107,6 +107,33 @@ where Chainspec: AsRef, Hook: OnStateHook, { + /// Apply pre execution changes. + pub fn apply_pre_execution_changes( + &mut self, + block: &Block, + evm: &mut Evm<'_, Ext, DB>, + ) -> Result<(), BlockExecutionError> + where + DB: Database + DatabaseCommit, + DB::Error: Display, + { + let transacts = vec![eip2935::transact, eip4788::transact]; + + for tx in transacts { + let result_and_state = + tx(&self.evm_config.clone(), self.chain_spec.as_ref(), block, evm)?; + + if let Some(res) = result_and_state { + if let Some(ref mut hook) = self.hook { + hook.on_state(&res); + } + evm.context.evm.db.commit(res.state); + } + } + + Ok(()) + } + /// Applies the pre-block call to the EIP-2935 blockhashes contract. pub fn pre_block_blockhashes_contract_call( &mut self, @@ -167,7 +194,7 @@ where db: &mut DB, initialized_cfg: &CfgEnvWithHandlerCfg, initialized_block_env: &BlockEnv, - parent_block_hash: Option, + parent_beacon_block_root: Option, ) -> Result<(), BlockExecutionError> where DB: Database + DatabaseCommit, @@ -178,7 +205,7 @@ where self.apply_beacon_root_contract_call( initialized_block_env.timestamp.to(), initialized_block_env.number.to(), - parent_block_hash, + parent_beacon_block_root, &mut evm, )?; From 19330d3b030342bbd7f377ef37674f7d2fd862d4 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Sun, 29 Sep 2024 10:29:25 +0200 Subject: [PATCH 15/20] single entry point to apply post block excution changes --- crates/evm/src/system_calls/mod.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index b8ad644cae20..8be3f537eb3f 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -134,6 +134,23 @@ where Ok(()) } + /// Apply post execution changes. + pub fn apply_post_execution_changes( + &mut self, + evm: &mut Evm<'_, Ext, DB>, + ) -> Result, BlockExecutionError> + where + DB: Database + DatabaseCommit, + DB::Error: Display, + { + // Collect all EIP-7685 requests + let withdrawal_requests = self.apply_withdrawal_requests_contract_call(evm)?; + + // Collect all EIP-7251 requests + let consolidation_requests = self.apply_consolidation_requests_contract_call(evm)?; + Ok([withdrawal_requests, consolidation_requests].concat()) + } + /// Applies the pre-block call to the EIP-2935 blockhashes contract. pub fn pre_block_blockhashes_contract_call( &mut self, From 9c6238a10e0bc8ba0c2d8b493df65f04d090c7a7 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Sun, 29 Sep 2024 10:39:49 +0200 Subject: [PATCH 16/20] clippy --- crates/evm/src/system_calls/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 8be3f537eb3f..d191f3529923 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -1,7 +1,7 @@ //! System contract call functions. use crate::ConfigureEvm; -use alloc::{format, string::ToString, vec::Vec}; +use alloc::{format, string::ToString, vec, vec::Vec}; use alloy_eips::{eip7002::WithdrawalRequest, eip7251::ConsolidationRequest}; use alloy_primitives::{Address, FixedBytes}; use core::fmt::Display; From d5898add1a239727b35ee73c6892ee4dbd63bf2c Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Sun, 29 Sep 2024 11:17:41 +0200 Subject: [PATCH 17/20] refactor --- crates/evm/src/system_calls/eip2935.rs | 22 ---- crates/evm/src/system_calls/eip4788.rs | 22 ---- crates/evm/src/system_calls/eip7002.rs | 5 + crates/evm/src/system_calls/eip7251.rs | 5 + crates/evm/src/system_calls/mod.rs | 134 ++++--------------------- 5 files changed, 28 insertions(+), 160 deletions(-) diff --git a/crates/evm/src/system_calls/eip2935.rs b/crates/evm/src/system_calls/eip2935.rs index 4a5433c57c21..3b3e6aa4bba7 100644 --- a/crates/evm/src/system_calls/eip2935.rs +++ b/crates/evm/src/system_calls/eip2935.rs @@ -116,28 +116,6 @@ where Ok(Some(res)) } -#[inline] -pub(crate) fn transact( - evm_config: &EvmConfig, - chain_spec: impl EthereumHardforks, - block: &Block, - evm: &mut Evm<'_, EXT, DB>, -) -> Result, BlockExecutionError> -where - DB: Database + DatabaseCommit, - DB::Error: core::fmt::Display, - EvmConfig: ConfigureEvm
, -{ - transact_blockhashes_contract_call( - evm_config, - chain_spec, - block.timestamp, - block.number, - block.parent_hash, - evm, - ) -} - /// Applies the pre-block call to the [EIP-2935] blockhashes contract, using the given block, /// chain specification, and EVM and commits the relevant state changes. /// diff --git a/crates/evm/src/system_calls/eip4788.rs b/crates/evm/src/system_calls/eip4788.rs index 604cf1a6b168..af30aa2c5562 100644 --- a/crates/evm/src/system_calls/eip4788.rs +++ b/crates/evm/src/system_calls/eip4788.rs @@ -126,28 +126,6 @@ where Ok(Some(res)) } -#[inline] -pub(crate) fn transact( - evm_config: &EvmConfig, - chain_spec: impl EthereumHardforks, - block: &Block, - evm: &mut Evm<'_, EXT, DB>, -) -> Result, BlockExecutionError> -where - DB: Database + DatabaseCommit, - DB::Error: core::fmt::Display, - EvmConfig: ConfigureEvm
, -{ - transact_beacon_root_contract_call( - evm_config, - &chain_spec, - block.timestamp, - block.number, - block.parent_beacon_block_root, - evm, - ) -} - /// Applies the pre-block call to the [EIP-4788] beacon block root contract, using the given block, /// chain spec, EVM. /// diff --git a/crates/evm/src/system_calls/eip7002.rs b/crates/evm/src/system_calls/eip7002.rs index d03268254f43..5bfe562d2ec2 100644 --- a/crates/evm/src/system_calls/eip7002.rs +++ b/crates/evm/src/system_calls/eip7002.rs @@ -118,6 +118,11 @@ where // commit the state evm.context.evm.db.commit(state); + post_commit(result) +} + +#[inline] +pub(crate) fn post_commit(result: ExecutionResult) -> Result, BlockExecutionError> { let mut data = match result { ExecutionResult::Success { output, .. } => Ok(output.into_data()), ExecutionResult::Revert { output, .. } => { diff --git a/crates/evm/src/system_calls/eip7251.rs b/crates/evm/src/system_calls/eip7251.rs index 8247f06b1841..42cf680ecbe3 100644 --- a/crates/evm/src/system_calls/eip7251.rs +++ b/crates/evm/src/system_calls/eip7251.rs @@ -120,6 +120,11 @@ where // commit the state evm.context.evm.db.commit(state); + post_commit(result) +} + +#[inline] +pub(crate) fn post_commit(result: ExecutionResult) -> Result, BlockExecutionError> { let mut data = match result { ExecutionResult::Success { output, .. } => Ok(output.into_data()), ExecutionResult::Revert { output, .. } => { diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index d191f3529923..d178a91ad49c 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -1,17 +1,13 @@ //! System contract call functions. use crate::ConfigureEvm; -use alloc::{format, string::ToString, vec, vec::Vec}; -use alloy_eips::{eip7002::WithdrawalRequest, eip7251::ConsolidationRequest}; -use alloy_primitives::{Address, FixedBytes}; +use alloc::{vec, vec::Vec}; use core::fmt::Display; use reth_chainspec::ChainSpec; -use reth_execution_errors::{BlockExecutionError, BlockValidationError}; -use reth_primitives::{Block, Buf, Header, Request}; +use reth_execution_errors::BlockExecutionError; +use reth_primitives::{Block, Header, Request}; use revm::{Database, DatabaseCommit, Evm}; -use revm_primitives::{ - BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, ResultAndState, B256, -}; +use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState, B256}; mod eip2935; pub use eip2935::*; @@ -117,19 +113,18 @@ where DB: Database + DatabaseCommit, DB::Error: Display, { - let transacts = vec![eip2935::transact, eip4788::transact]; - - for tx in transacts { - let result_and_state = - tx(&self.evm_config.clone(), self.chain_spec.as_ref(), block, evm)?; - - if let Some(res) = result_and_state { - if let Some(ref mut hook) = self.hook { - hook.on_state(&res); - } - evm.context.evm.db.commit(res.state); - } - } + self.apply_blockhashes_contract_call( + block.timestamp, + block.number, + block.parent_hash, + evm, + )?; + self.apply_beacon_root_contract_call( + block.timestamp, + block.number, + block.parent_beacon_block_root, + evm, + )?; Ok(()) } @@ -295,51 +290,7 @@ where } evm.context.evm.db.commit(result_and_state.state); - let mut data = match result_and_state.result { - ExecutionResult::Success { output, .. } => Ok(output.into_data()), - ExecutionResult::Revert { output, .. } => { - Err(BlockValidationError::WithdrawalRequestsContractCall { - message: format!("execution reverted: {output}"), - }) - } - ExecutionResult::Halt { reason, .. } => { - Err(BlockValidationError::WithdrawalRequestsContractCall { - message: format!("execution halted: {reason:?}"), - }) - } - }?; - - // Withdrawals are encoded as a series of withdrawal requests, each with the following - // format: - // - // +------+--------+--------+ - // | addr | pubkey | amount | - // +------+--------+--------+ - // 20 48 8 - - const WITHDRAWAL_REQUEST_SIZE: usize = 20 + 48 + 8; - let mut withdrawal_requests = Vec::with_capacity(data.len() / WITHDRAWAL_REQUEST_SIZE); - while data.has_remaining() { - if data.remaining() < WITHDRAWAL_REQUEST_SIZE { - return Err(BlockValidationError::WithdrawalRequestsContractCall { - message: "invalid withdrawal request length".to_string(), - } - .into()) - } - - let mut source_address = Address::ZERO; - data.copy_to_slice(source_address.as_mut_slice()); - - let mut validator_pubkey = FixedBytes::<48>::ZERO; - data.copy_to_slice(validator_pubkey.as_mut_slice()); - - let amount = data.get_u64(); - - withdrawal_requests - .push(WithdrawalRequest { source_address, validator_pubkey, amount }.into()); - } - - Ok(withdrawal_requests) + eip7002::post_commit(result_and_state.result) } /// Applies the post-block call to the EIP-7251 consolidation requests contract. @@ -377,55 +328,6 @@ where } evm.context.evm.db.commit(result_and_state.state); - let mut data = match result_and_state.result { - ExecutionResult::Success { output, .. } => Ok(output.into_data()), - ExecutionResult::Revert { output, .. } => { - Err(BlockValidationError::ConsolidationRequestsContractCall { - message: format!("execution reverted: {output}"), - }) - } - ExecutionResult::Halt { reason, .. } => { - Err(BlockValidationError::ConsolidationRequestsContractCall { - message: format!("execution halted: {reason:?}"), - }) - } - }?; - - // Consolidations are encoded as a series of consolidation requests, each with the following - // format: - // - // +------+--------+---------------+ - // | addr | pubkey | target pubkey | - // +------+--------+---------------+ - // 20 48 48 - - const CONSOLIDATION_REQUEST_SIZE: usize = 20 + 48 + 48; - let mut consolidation_requests = - Vec::with_capacity(data.len() / CONSOLIDATION_REQUEST_SIZE); - while data.has_remaining() { - if data.remaining() < CONSOLIDATION_REQUEST_SIZE { - return Err(BlockValidationError::ConsolidationRequestsContractCall { - message: "invalid consolidation request length".to_string(), - } - .into()) - } - - let mut source_address = Address::ZERO; - data.copy_to_slice(source_address.as_mut_slice()); - - let mut source_pubkey = FixedBytes::<48>::ZERO; - data.copy_to_slice(source_pubkey.as_mut_slice()); - - let mut target_pubkey = FixedBytes::<48>::ZERO; - data.copy_to_slice(target_pubkey.as_mut_slice()); - - consolidation_requests.push(Request::ConsolidationRequest(ConsolidationRequest { - source_address, - source_pubkey, - target_pubkey, - })); - } - - Ok(consolidation_requests) + eip7251::post_commit(result_and_state.result) } } From 6e7e878cceb268238c9ee49d3d180d00fc867c4d Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Sun, 29 Sep 2024 11:21:31 +0200 Subject: [PATCH 18/20] clippy --- crates/evm/src/system_calls/eip2935.rs | 2 +- crates/evm/src/system_calls/eip4788.rs | 2 +- crates/evm/src/system_calls/mod.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/evm/src/system_calls/eip2935.rs b/crates/evm/src/system_calls/eip2935.rs index 3b3e6aa4bba7..7b09a4813079 100644 --- a/crates/evm/src/system_calls/eip2935.rs +++ b/crates/evm/src/system_calls/eip2935.rs @@ -8,7 +8,7 @@ use alloy_primitives::B256; use core::fmt::Display; use reth_chainspec::EthereumHardforks; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; -use reth_primitives::{Block, Header}; +use reth_primitives::Header; use revm::{interpreter::Host, Database, DatabaseCommit, Evm}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState}; diff --git a/crates/evm/src/system_calls/eip4788.rs b/crates/evm/src/system_calls/eip4788.rs index af30aa2c5562..a1f97bf5e908 100644 --- a/crates/evm/src/system_calls/eip4788.rs +++ b/crates/evm/src/system_calls/eip4788.rs @@ -6,7 +6,7 @@ use alloy_eips::eip4788::BEACON_ROOTS_ADDRESS; use alloy_primitives::B256; use reth_chainspec::EthereumHardforks; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; -use reth_primitives::{Block, Header}; +use reth_primitives::Header; use revm::{interpreter::Host, Database, DatabaseCommit, Evm}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState}; diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index d178a91ad49c..487da92fa3b6 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -1,7 +1,7 @@ //! System contract call functions. use crate::ConfigureEvm; -use alloc::{vec, vec::Vec}; +use alloc::vec::Vec; use core::fmt::Display; use reth_chainspec::ChainSpec; use reth_execution_errors::BlockExecutionError; From dce01aeaf38313ef3d2477c3c1b47a35a1c5f205 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Sun, 29 Sep 2024 12:56:30 +0200 Subject: [PATCH 19/20] Arc for chain_spec --- crates/evm/src/system_calls/mod.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 487da92fa3b6..65e2ceb05967 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -3,11 +3,12 @@ use crate::ConfigureEvm; use alloc::vec::Vec; use core::fmt::Display; -use reth_chainspec::ChainSpec; +use reth_chainspec::EthereumHardforks; use reth_execution_errors::BlockExecutionError; use reth_primitives::{Block, Header, Request}; use revm::{Database, DatabaseCommit, Evm}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState, B256}; +use std::sync::Arc; mod eip2935; pub use eip2935::*; @@ -52,7 +53,7 @@ impl OnStateHook for NoopHook { #[allow(missing_debug_implementations)] pub struct SystemCaller<'a, EvmConfig, Chainspec, Hook = NoopHook> { evm_config: &'a EvmConfig, - chain_spec: &'a Chainspec, + chain_spec: Arc, /// Optional hook to be called after each state change. // TODO do we want this optional? hook: Option, @@ -61,7 +62,7 @@ pub struct SystemCaller<'a, EvmConfig, Chainspec, Hook = NoopHook> { impl<'a, EvmConfig, Chainspec> SystemCaller<'a, EvmConfig, Chainspec> { /// Create a new system caller with the given EVM config, database, and chain spec, and creates /// the EVM with the given initialized config and block environment. - pub const fn new(evm_config: &'a EvmConfig, chain_spec: &'a Chainspec) -> Self { + pub const fn new(evm_config: &'a EvmConfig, chain_spec: Arc) -> Self { Self { evm_config, chain_spec, hook: None } } } @@ -100,7 +101,7 @@ where impl<'a, EvmConfig, Chainspec, Hook> SystemCaller<'a, EvmConfig, Chainspec, Hook> where EvmConfig: ConfigureEvm
, - Chainspec: AsRef, + Chainspec: EthereumHardforks, Hook: OnStateHook, { /// Apply pre execution changes. From 3ee8cb928c8ece46541b68a918853b7b113934e8 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Sun, 29 Sep 2024 13:50:10 +0200 Subject: [PATCH 20/20] clippy --- crates/evm/src/system_calls/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 65e2ceb05967..d9a2da90e1f3 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -1,14 +1,13 @@ //! System contract call functions. use crate::ConfigureEvm; -use alloc::vec::Vec; +use alloc::{sync::Arc, vec::Vec}; use core::fmt::Display; use reth_chainspec::EthereumHardforks; use reth_execution_errors::BlockExecutionError; use reth_primitives::{Block, Header, Request}; use revm::{Database, DatabaseCommit, Evm}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState, B256}; -use std::sync::Arc; mod eip2935; pub use eip2935::*;