diff --git a/crates/chain-state/src/memory_overlay.rs b/crates/chain-state/src/memory_overlay.rs index bd6676b778..cb296a3227 100644 --- a/crates/chain-state/src/memory_overlay.rs +++ b/crates/chain-state/src/memory_overlay.rs @@ -5,14 +5,14 @@ use reth_errors::ProviderResult; use reth_primitives_traits::{Account, Bytecode, NodePrimitives}; use reth_storage_api::{ AccountReader, BlockHashReader, BytecodeReader, HashedPostStateProvider, StateProofProvider, - StateProvider, StateRootProvider, StorageRootProvider, + StateProvider, StateProviderBox, StateRootProvider, StorageRootProvider, }; use reth_trie::{ updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, MultiProofTargets, StorageMultiProof, TrieInput, }; use revm_database::BundleState; -use std::sync::OnceLock; +use std::{borrow::Cow, sync::OnceLock}; /// A state provider that stores references to in-memory blocks along with their state as well as a /// reference of the historical state provider for fallback lookups. @@ -24,7 +24,7 @@ pub struct MemoryOverlayStateProviderRef< /// Historical state provider for state lookups that are not found in memory blocks. pub(crate) historical: Box, /// The collection of executed parent blocks. Expected order is newest to oldest. - pub(crate) in_memory: &'a Vec>, + pub(crate) in_memory: Cow<'a, Vec>>, /// Lazy-loaded in-memory trie data. pub(crate) trie_input: OnceLock, } @@ -37,11 +37,8 @@ impl<'a, N: NodePrimitives> MemoryOverlayStateProviderRef<'a, N> { /// - `in_memory` - the collection of executed ancestor blocks in reverse. /// - `historical` - a historical state provider for the latest ancestor block stored in the /// database. - pub fn new( - historical: Box, - in_memory: &'a Vec>, - ) -> Self { - Self { historical, in_memory, trie_input: OnceLock::new() } + pub fn new(historical: Box, in_memory: Vec>) -> Self { + Self { historical, in_memory: Cow::Owned(in_memory), trie_input: OnceLock::new() } } /// Turn this state provider into a state provider @@ -70,7 +67,7 @@ impl<'a, N: NodePrimitives> MemoryOverlayStateProviderRef<'a, N> { impl BlockHashReader for MemoryOverlayStateProviderRef<'_, N> { fn block_hash(&self, number: BlockNumber) -> ProviderResult> { - for block in self.in_memory { + for block in self.in_memory.iter() { if block.recovered_block().number() == number { return Ok(Some(block.recovered_block().hash())); } @@ -89,7 +86,7 @@ impl BlockHashReader for MemoryOverlayStateProviderRef<'_, N> let mut in_memory_hashes = Vec::with_capacity(range.size_hint().0); // iterate in ascending order (oldest to newest = low to high) - for block in self.in_memory { + for block in self.in_memory.iter() { let block_num = block.recovered_block().number(); if range.contains(&block_num) { in_memory_hashes.push(block.recovered_block().hash()); @@ -111,7 +108,7 @@ impl BlockHashReader for MemoryOverlayStateProviderRef<'_, N> impl AccountReader for MemoryOverlayStateProviderRef<'_, N> { fn basic_account(&self, address: &Address) -> ProviderResult> { - for block in self.in_memory { + for block in self.in_memory.iter() { if let Some(account) = block.execution_output.account(address) { return Ok(account); } @@ -215,7 +212,7 @@ impl StateProvider for MemoryOverlayStateProviderRef<'_, N> { address: Address, storage_key: StorageKey, ) -> ProviderResult> { - for block in self.in_memory { + for block in self.in_memory.iter() { if let Some(value) = block.execution_output.storage(&address, storage_key.into()) { return Ok(Some(value)); } @@ -227,7 +224,7 @@ impl StateProvider for MemoryOverlayStateProviderRef<'_, N> { impl BytecodeReader for MemoryOverlayStateProviderRef<'_, N> { fn bytecode_by_hash(&self, code_hash: &B256) -> ProviderResult> { - for block in self.in_memory { + for block in self.in_memory.iter() { if let Some(contract) = block.execution_output.bytecode(code_hash) { return Ok(Some(contract)); } @@ -242,7 +239,7 @@ impl BytecodeReader for MemoryOverlayStateProviderRef<'_, N> #[expect(missing_debug_implementations)] pub struct MemoryOverlayStateProvider { /// Historical state provider for state lookups that are not found in memory blocks. - pub(crate) historical: Box, + pub(crate) historical: StateProviderBox, /// The collection of executed parent blocks. Expected order is newest to oldest. pub(crate) in_memory: Vec>, /// Lazy-loaded in-memory trie data. @@ -257,7 +254,7 @@ impl MemoryOverlayStateProvider { /// - `in_memory` - the collection of executed ancestor blocks in reverse. /// - `historical` - a historical state provider for the latest ancestor block stored in the /// database. - pub fn new(historical: Box, in_memory: Vec>) -> Self { + pub fn new(historical: StateProviderBox, in_memory: Vec>) -> Self { Self { historical, in_memory, trie_input: OnceLock::new() } } @@ -266,10 +263,15 @@ impl MemoryOverlayStateProvider { fn as_ref(&self) -> MemoryOverlayStateProviderRef<'_, N> { MemoryOverlayStateProviderRef { historical: Box::new(self.historical.as_ref()), - in_memory: &self.in_memory, + in_memory: Cow::Borrowed(&self.in_memory), trie_input: self.trie_input.clone(), } } + + /// Wraps the [`Self`] in a `Box`. + pub fn boxed(self) -> StateProviderBox { + Box::new(self) + } } // Delegates all provider impls to [`MemoryOverlayStateProviderRef`] diff --git a/crates/engine/tree/src/tree/payload_validator.rs b/crates/engine/tree/src/tree/payload_validator.rs index b64611fb5e..b89821c340 100644 --- a/crates/engine/tree/src/tree/payload_validator.rs +++ b/crates/engine/tree/src/tree/payload_validator.rs @@ -435,8 +435,7 @@ where } // Execute the block and handle any execution errors - let (output, senders) = match self.execute_block(&state_provider, env, &input, &mut handle) - { + let (output, senders) = match self.execute_block(state_provider, env, &input, &mut handle) { Ok(output) => output, Err(err) => return self.handle_execution_error(input, err, &parent_block), }; @@ -603,7 +602,7 @@ where handle: &mut PayloadHandle, Err, N::Receipt>, ) -> Result<(BlockExecutionOutput, Vec
), InsertBlockErrorKind> where - S: StateProvider, + S: StateProvider + Send, Err: core::error::Error + Send + Sync + 'static, V: PayloadValidator, T: PayloadTypes>, diff --git a/crates/era-utils/src/history.rs b/crates/era-utils/src/history.rs index 25f929ca99..5fce250aac 100644 --- a/crates/era-utils/src/history.rs +++ b/crates/era-utils/src/history.rs @@ -116,7 +116,7 @@ where /// these stages that this work has already been done. Otherwise, there might be some conflict with /// database integrity. pub fn save_stage_checkpoints

( - provider: &P, + provider: P, from: BlockNumber, to: BlockNumber, processed: u64, diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index 640cdf17e5..2da07cc18b 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -155,7 +155,7 @@ where let state_provider = client.state_by_block_hash(parent_header.hash())?; let state = StateProviderDatabase::new(state_provider); let mut db = - State::builder().with_database_ref(cached_reads.as_db(state)).with_bundle_update().build(); + State::builder().with_database(cached_reads.as_db_mut(state)).with_bundle_update().build(); let mut builder = evm_config .builder_for_next_block( @@ -358,6 +358,7 @@ where return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads }) } + let state_provider = client.state_by_block_hash(parent_header.hash())?; let BlockBuilderOutcome { execution_result, block, .. } = builder.finish(state_provider)?; let requests = chain_spec diff --git a/crates/revm/src/database.rs b/crates/revm/src/database.rs index 231f3b38cb..a4d74ff262 100644 --- a/crates/revm/src/database.rs +++ b/crates/revm/src/database.rs @@ -9,7 +9,7 @@ use revm::{bytecode::Bytecode, state::AccountInfo, Database, DatabaseRef}; /// A helper trait responsible for providing state necessary for EVM execution. /// /// This serves as the data layer for [`Database`]. -pub trait EvmStateProvider: Send { +pub trait EvmStateProvider { /// Get basic account information. /// /// Returns [`None`] if the account doesn't exist. @@ -34,7 +34,7 @@ pub trait EvmStateProvider: Send { } // Blanket implementation of EvmStateProvider for any type that implements StateProvider. -impl EvmStateProvider for T { +impl EvmStateProvider for T { fn basic_account(&self, address: &Address) -> ProviderResult> { ::basic_account(self, address) } diff --git a/crates/rpc/rpc-eth-api/src/helpers/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index db2ac48c5c..d3790251e5 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -33,7 +33,7 @@ use reth_rpc_eth_types::{ simulate::{self, EthSimulateError}, EthApiError, StateCacheDb, }; -use reth_storage_api::{BlockIdReader, ProviderTx, StateProvider}; +use reth_storage_api::{BlockIdReader, ProviderTx, StateProviderBox}; use revm::{ context::Block, context_interface::{result::ResultAndState, Transaction}, @@ -491,11 +491,11 @@ pub trait Call: ) -> impl Future> + Send where R: Send + 'static, - F: FnOnce(Self, &dyn StateProvider) -> Result + Send + 'static, + F: FnOnce(Self, StateProviderBox) -> Result + Send + 'static, { self.spawn_blocking_io_fut(move |this| async move { let state = this.state_at_block_id(at).await?; - f(this, &state) + f(this, state) }) } diff --git a/crates/storage/provider/src/lib.rs b/crates/storage/provider/src/lib.rs index 3609d82d5c..84e1a4f8b4 100644 --- a/crates/storage/provider/src/lib.rs +++ b/crates/storage/provider/src/lib.rs @@ -20,8 +20,8 @@ pub use traits::*; pub mod providers; pub use providers::{ DatabaseProvider, DatabaseProviderRO, DatabaseProviderRW, HistoricalStateProvider, - HistoricalStateProviderRef, LatestStateProvider, ProviderFactory, StaticFileAccess, - StaticFileProviderBuilder, StaticFileWriter, + HistoricalStateProviderRef, LatestStateProvider, LatestStateProviderRef, ProviderFactory, + StaticFileAccess, StaticFileProviderBuilder, StaticFileWriter, }; pub mod changesets_utils; diff --git a/crates/storage/storage-api/src/stage_checkpoint.rs b/crates/storage/storage-api/src/stage_checkpoint.rs index 1138a5f8cb..d643dfbde9 100644 --- a/crates/storage/storage-api/src/stage_checkpoint.rs +++ b/crates/storage/storage-api/src/stage_checkpoint.rs @@ -19,7 +19,7 @@ pub trait StageCheckpointReader: Send { /// The trait for updating stage checkpoint related data. #[auto_impl::auto_impl(&)] -pub trait StageCheckpointWriter: Send { +pub trait StageCheckpointWriter { /// Save stage checkpoint. fn save_stage_checkpoint(&self, id: StageId, checkpoint: StageCheckpoint) -> ProviderResult<()>; diff --git a/crates/storage/storage-api/src/stats.rs b/crates/storage/storage-api/src/stats.rs index cfce2ac036..34a39a9274 100644 --- a/crates/storage/storage-api/src/stats.rs +++ b/crates/storage/storage-api/src/stats.rs @@ -2,7 +2,7 @@ use reth_db_api::table::Table; /// The trait for fetching provider statistics. #[auto_impl::auto_impl(&)] -pub trait StatsReader: Send { +pub trait StatsReader { /// Fetch the number of entries in the corresponding [Table]. Depending on the provider, it may /// route to different data sources other than [Table]. fn count_entries(&self) -> reth_storage_errors::provider::ProviderResult;