diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index 4b37744f8b..f4a1f11dc4 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -397,8 +397,7 @@ pub fn execute_test_suite( .map(|item| (item.address, item.storage_keys.clone())) .collect::>() }) - .unwrap_or_default() - .into(); + .unwrap_or_default(); tx.authorization_list = unit .transaction diff --git a/crates/context/interface/src/context.rs b/crates/context/interface/src/context.rs new file mode 100644 index 0000000000..3378775607 --- /dev/null +++ b/crates/context/interface/src/context.rs @@ -0,0 +1,12 @@ +/// Some actions on top of context with just Getter traits would require borrowing the context +/// with a both mutable and immutable reference. +/// +/// To allow doing this action more efficiently, we introduce a new trait that does this directly. +/// +/// Used for loading access list and applying EIP-7702 authorization list. +pub trait PerformantContextAccess { + type Error; + + /// Load access list + fn load_access_list(&mut self) -> Result<(), Self::Error>; +} diff --git a/crates/context/interface/src/lib.rs b/crates/context/interface/src/lib.rs index 8176798392..c03aba433f 100644 --- a/crates/context/interface/src/lib.rs +++ b/crates/context/interface/src/lib.rs @@ -7,6 +7,7 @@ extern crate alloc as std; pub mod block; pub mod cfg; +pub mod context; pub mod errors; pub mod host; pub mod journaled_state; @@ -15,6 +16,7 @@ pub mod transaction; pub use block::{Block, BlockGetter}; pub use cfg::{Cfg, CfgGetter, CreateScheme, TransactTo}; +pub use context::PerformantContextAccess; pub use database_interface::{DBErrorMarker, Database, DatabaseGetter}; pub use errors::ErrorGetter; pub use journaled_state::{Journal, JournalDBError, JournalGetter}; diff --git a/crates/context/src/context.rs b/crates/context/src/context.rs index 9979c5b520..5ddb9b1037 100644 --- a/crates/context/src/context.rs +++ b/crates/context/src/context.rs @@ -1,3 +1,5 @@ +pub mod performant_access; + use crate::{block::BlockEnv, cfg::CfgEnv, journaled_state::JournaledState, tx::TxEnv}; use bytecode::{Bytecode, EOF_MAGIC_BYTES, EOF_MAGIC_HASH}; use context_interface::{ diff --git a/crates/context/src/context/performant_access.rs b/crates/context/src/context/performant_access.rs new file mode 100644 index 0000000000..2644c2bf03 --- /dev/null +++ b/crates/context/src/context/performant_access.rs @@ -0,0 +1,28 @@ +use super::Context; +use context_interface::{Block, Cfg, Database, Journal, PerformantContextAccess, Transaction}; +use primitives::U256; + +impl< + BLOCK: Block, + TX: Transaction, + CFG: Cfg, + DB: Database, + JOURNAL: Journal, + CHAIN, + > PerformantContextAccess for Context +{ + type Error = ::Error; + + fn load_access_list(&mut self) -> Result<(), Self::Error> { + let Some(access_list) = self.tx.access_list() else { + return Ok(()); + }; + for access_list in access_list { + self.journaled_state.warm_account_and_storage( + *access_list.0, + access_list.1.iter().map(|i| U256::from_be_bytes(i.0)), + )?; + } + Ok(()) + } +} diff --git a/crates/context/src/journaled_state.rs b/crates/context/src/journaled_state.rs index 9926f3a098..f03ab17669 100644 --- a/crates/context/src/journaled_state.rs +++ b/crates/context/src/journaled_state.rs @@ -881,6 +881,7 @@ impl JournaledState { key: U256, new: U256, ) -> Result, DB::Error> { + println!("sstore state: {:#?}", self.state); // assume that acc exists and load the slot. let present = self.sload(address, key)?; let acc = self.state.get_mut(&address).unwrap(); diff --git a/crates/handler/src/pre_execution.rs b/crates/handler/src/pre_execution.rs index 24d62a686b..96c853572b 100644 --- a/crates/handler/src/pre_execution.rs +++ b/crates/handler/src/pre_execution.rs @@ -7,7 +7,8 @@ use context_interface::{ journaled_state::Journal, result::InvalidTransaction, transaction::{Transaction, TransactionType}, - Block, BlockGetter, Cfg, CfgGetter, JournalDBError, JournalGetter, TransactionGetter, + Block, BlockGetter, Cfg, CfgGetter, Database, DatabaseGetter, JournalDBError, JournalGetter, + PerformantContextAccess, TransactionGetter, }; use handler_interface::PreExecutionHandler; use primitives::{Address, BLOCKHASH_STORAGE_ADDRESS, U256}; @@ -58,7 +59,7 @@ where } // Load access list - // TODO + context.load_access_list()?; // if let Some(access_list) = context.tx().access_list().cloned() { // for access_list in access_list.iter() { // context.journal().warm_account_and_storage( @@ -141,7 +142,6 @@ pub fn apply_eip7702_auth_list< let authorization_list = tx .authorization_list() - .into_iter() .map(|a| Authorization { authority: a.0, chain_id: a.1, @@ -203,12 +203,21 @@ pub fn apply_eip7702_auth_list< } pub trait EthPreExecutionContext: - TransactionGetter + BlockGetter + JournalGetter + CfgGetter + TransactionGetter + + BlockGetter + + JournalGetter + + CfgGetter + + PerformantContextAccess::Database as Database>::Error> { } -impl EthPreExecutionContext - for CTX +impl< + CTX: TransactionGetter + + BlockGetter + + JournalGetter + + CfgGetter + + PerformantContextAccess::Database as Database>::Error>, + > EthPreExecutionContext for CTX { } diff --git a/crates/inspector/src/inspector.rs b/crates/inspector/src/inspector.rs index 7b7833789d..0b67a8b263 100644 --- a/crates/inspector/src/inspector.rs +++ b/crates/inspector/src/inspector.rs @@ -5,6 +5,7 @@ use revm::{ context::JournaledState, context_interface::{ block::BlockSetter, + context::PerformantContextAccess, journaled_state::{AccountLoad, Eip7702CodeLoad}, transaction::TransactionSetter, BlockGetter, CfgGetter, DatabaseGetter, ErrorGetter, Journal, JournalDBError, @@ -387,6 +388,17 @@ where } } +impl PerformantContextAccess for InspectorContext +where + CTX: PerformantContextAccess + DatabaseGetter, +{ + type Error = ::Error; + + fn load_access_list(&mut self) -> Result<(), Self::Error> { + self.inner.load_access_list() + } +} + impl DatabaseGetter for InspectorContext where CTX: DatabaseGetter, diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index 14effd3576..c989fb0a9b 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -370,8 +370,8 @@ pub fn validate_initial_tx_gas( }; // Get number of access list account and storages. - initial_gas += access_list_accounts as u64 * ACCESS_LIST_ADDRESS; - initial_gas += access_list_storages as u64 * ACCESS_LIST_STORAGE_KEY; + initial_gas += access_list_accounts * ACCESS_LIST_ADDRESS; + initial_gas += access_list_storages * ACCESS_LIST_STORAGE_KEY; // Base stipend initial_gas += if is_create { diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index 6d0fbe2774..7966af09f7 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -2,6 +2,7 @@ use crate::{exec::EvmCommit, EvmExec}; use context::{block::BlockEnv, tx::TxEnv, CfgEnv, Context, JournaledState}; use context_interface::{ block::BlockSetter, + context::PerformantContextAccess, journaled_state::Journal, result::{ EVMError, ExecutionResult, HaltReasonTrait, InvalidHeader, InvalidTransaction, @@ -54,7 +55,8 @@ where FinalOutput = (EvmState, Vec), Database = ::Database, >, - > + Host, + > + Host + + PerformantContextAccess::Database as Database>::Error>, ERROR: From + From + From> @@ -101,7 +103,8 @@ where FinalOutput = (EvmState, Vec), Database = ::Database, >, - > + Host, + > + Host + + PerformantContextAccess::Database as Database>::Error>, ERROR: From + From + From> @@ -159,7 +162,8 @@ where FinalOutput = (EvmState, Vec), Database = ::Database, >, - > + Host, + > + Host + + PerformantContextAccess::Database as Database>::Error>, ERROR: From + From + From> diff --git a/crates/statetest-types/src/test_authorization.rs b/crates/statetest-types/src/test_authorization.rs index a2ec31defd..3399969964 100644 --- a/crates/statetest-types/src/test_authorization.rs +++ b/crates/statetest-types/src/test_authorization.rs @@ -1,5 +1,3 @@ -use std::u64; - use revm::{ context_interface::transaction::AuthorizationItem, primitives::{Address, U256},