From 54cd8b34a40d1c22c5c00bb49ec4eb855ae77690 Mon Sep 17 00:00:00 2001 From: nekomoto911 Date: Thu, 19 Jun 2025 22:14:07 +0800 Subject: [PATCH] perf: Reduce unnecessary MDBX transaction creation when constructing StateProvider (#16884) --- .../src/providers/blockchain_provider.rs | 12 ++-------- .../provider/src/providers/consistent.rs | 24 ++++++++++++++++++- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index b7b31cd493..5ee86e8cd7 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -526,20 +526,12 @@ impl StateProviderFactory for BlockchainProvider { let hash = provider .block_hash(block_number)? .ok_or_else(|| ProviderError::HeaderNotFound(block_number.into()))?; - self.history_by_block_hash(hash) + provider.into_state_provider_at_block_hash(hash) } fn history_by_block_hash(&self, block_hash: BlockHash) -> ProviderResult { trace!(target: "providers::blockchain", ?block_hash, "Getting history by block hash"); - - self.consistent_provider()?.get_in_memory_or_storage_by_block( - block_hash.into(), - |_| self.database.history_by_block_hash(block_hash), - |block_state| { - let state_provider = self.block_state_provider(block_state)?; - Ok(Box::new(state_provider)) - }, - ) + self.consistent_provider()?.into_state_provider_at_block_hash(block_hash) } fn state_by_block_hash(&self, hash: BlockHash) -> ProviderResult { diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index bb24cddb34..3922e286c2 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -27,7 +27,7 @@ use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; use reth_storage_api::{ BlockBodyIndicesProvider, DatabaseProviderFactory, NodePrimitivesProvider, StateProvider, - StorageChangeSetReader, + StorageChangeSetReader, TryIntoHistoricalStateProvider, }; use reth_storage_errors::provider::ProviderResult; use revm_database::states::PlainStorageRevert; @@ -591,6 +591,28 @@ impl ConsistentProvider { } fetch_from_db(&self.storage_provider) } + + /// Consumes the provider and returns a state provider for the specific block hash. + pub(crate) fn into_state_provider_at_block_hash( + self, + block_hash: BlockHash, + ) -> ProviderResult> { + let Self { storage_provider, head_block, .. } = self; + let into_history_at_block_hash = |block_hash| -> ProviderResult> { + let block_number = storage_provider + .block_number(block_hash)? + .ok_or(ProviderError::BlockHashNotFound(block_hash))?; + storage_provider.try_into_history_at_block(block_number) + }; + if let Some(Some(block_state)) = + head_block.as_ref().map(|b| b.block_on_chain(block_hash.into())) + { + let anchor_hash = block_state.anchor().hash; + let latest_historical = into_history_at_block_hash(anchor_hash)?; + return Ok(Box::new(block_state.state_provider(latest_historical))); + } + into_history_at_block_hash(block_hash) + } } impl ConsistentProvider {