fix(trie): collect revert state for historical storage root (#10465)

This commit is contained in:
Roman Krasiuk
2024-08-22 22:48:22 -07:00
committed by GitHub
parent 0a7ac41772
commit debd1ebd32

View File

@@ -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()))
}
}