mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-15 02:08:09 -05:00
fix(trie): collect revert state for historical storage root (#10465)
This commit is contained in:
@@ -20,8 +20,8 @@ use reth_trie::{
|
||||
AccountProof, HashedPostState, HashedStorage, StateRoot, StorageRoot,
|
||||
};
|
||||
use reth_trie_db::{
|
||||
DatabaseHashedPostState, DatabaseProof, DatabaseStateRoot, DatabaseStorageRoot,
|
||||
DatabaseTrieWitness,
|
||||
DatabaseHashedPostState, DatabaseHashedStorage, DatabaseProof, DatabaseStateRoot,
|
||||
DatabaseStorageRoot, DatabaseTrieWitness,
|
||||
};
|
||||
use std::{collections::HashMap, fmt::Debug};
|
||||
|
||||
@@ -111,14 +111,8 @@ impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Retrieve revert hashed state for this history provider.
|
||||
fn revert_state(&self) -> ProviderResult<HashedPostState> {
|
||||
if !self.lowest_available_blocks.is_account_history_available(self.block_number) ||
|
||||
!self.lowest_available_blocks.is_storage_history_available(self.block_number)
|
||||
{
|
||||
return Err(ProviderError::StateAtBlockPruned(self.block_number))
|
||||
}
|
||||
|
||||
/// Checks and returns `true` if distance to historical block exceeds the provided limit.
|
||||
fn check_distance_against_limit(&self, limit: u64) -> ProviderResult<bool> {
|
||||
let tip = self
|
||||
.tx
|
||||
.cursor_read::<tables::CanonicalHeaders>()?
|
||||
@@ -129,17 +123,45 @@ impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> {
|
||||
})
|
||||
.ok_or(ProviderError::BestBlockNotFound)?;
|
||||
|
||||
if tip.saturating_sub(self.block_number) > EPOCH_SLOTS {
|
||||
Ok(tip.saturating_sub(self.block_number) > limit)
|
||||
}
|
||||
|
||||
/// Retrieve revert hashed state for this history provider.
|
||||
fn revert_state(&self) -> ProviderResult<HashedPostState> {
|
||||
if !self.lowest_available_blocks.is_account_history_available(self.block_number) ||
|
||||
!self.lowest_available_blocks.is_storage_history_available(self.block_number)
|
||||
{
|
||||
return Err(ProviderError::StateAtBlockPruned(self.block_number))
|
||||
}
|
||||
|
||||
if self.check_distance_against_limit(EPOCH_SLOTS)? {
|
||||
tracing::warn!(
|
||||
target: "provider::historical_sp",
|
||||
target = self.block_number,
|
||||
"Attempt to calculate state root for an old block might result in OOM, treat carefully"
|
||||
"Attempt to calculate state root for an old block might result in OOM"
|
||||
);
|
||||
}
|
||||
|
||||
Ok(HashedPostState::from_reverts(self.tx, self.block_number)?)
|
||||
}
|
||||
|
||||
/// Retrieve revert hashed storage for this history provider and target address.
|
||||
fn revert_storage(&self, address: Address) -> ProviderResult<HashedStorage> {
|
||||
if !self.lowest_available_blocks.is_storage_history_available(self.block_number) {
|
||||
return Err(ProviderError::StateAtBlockPruned(self.block_number))
|
||||
}
|
||||
|
||||
if self.check_distance_against_limit(EPOCH_SLOTS * 10)? {
|
||||
tracing::warn!(
|
||||
target: "provider::historical_sp",
|
||||
target = self.block_number,
|
||||
"Attempt to calculate storage root for an old block might result in OOM"
|
||||
);
|
||||
}
|
||||
|
||||
Ok(HashedStorage::from_reverts(self.tx, address, self.block_number)?)
|
||||
}
|
||||
|
||||
fn history_info<T, K>(
|
||||
&self,
|
||||
key: K,
|
||||
@@ -318,7 +340,9 @@ impl<'b, TX: DbTx> StateRootProvider for HistoricalStateProviderRef<'b, TX> {
|
||||
address: Address,
|
||||
hashed_storage: HashedStorage,
|
||||
) -> ProviderResult<B256> {
|
||||
StorageRoot::overlay_root(self.tx, address, hashed_storage)
|
||||
let mut revert_storage = self.revert_storage(address)?;
|
||||
revert_storage.extend(hashed_storage);
|
||||
StorageRoot::overlay_root(self.tx, address, revert_storage)
|
||||
.map_err(|err| ProviderError::Database(err.into()))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user