mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-26 23:58:46 -05:00
perf: Reduce unnecessary MDBX transaction creation when constructing StateProvider (#16884)
This commit is contained in:
@@ -526,20 +526,12 @@ impl<N: ProviderNodeTypes> StateProviderFactory for BlockchainProvider<N> {
|
||||
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<StateProviderBox> {
|
||||
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<StateProviderBox> {
|
||||
|
||||
@@ -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<N: ProviderNodeTypes> ConsistentProvider<N> {
|
||||
}
|
||||
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<Box<dyn StateProvider>> {
|
||||
let Self { storage_provider, head_block, .. } = self;
|
||||
let into_history_at_block_hash = |block_hash| -> ProviderResult<Box<dyn StateProvider>> {
|
||||
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<N: ProviderNodeTypes> ConsistentProvider<N> {
|
||||
|
||||
Reference in New Issue
Block a user