diff --git a/crates/eth-sparse-mpt/src/lib.rs b/crates/eth-sparse-mpt/src/lib.rs index 306fd51e5..ac7e3a545 100644 --- a/crates/eth-sparse-mpt/src/lib.rs +++ b/crates/eth-sparse-mpt/src/lib.rs @@ -75,7 +75,7 @@ impl SparseTrieSharedCache { parent_state_root, ); let mut cache_v2 = v2::SharedCacheV2::default(); - cache_v2.last_block_hash = parent_block_hash; + cache_v2.parent_state_root = parent_state_root; let mut cache_v_experimental = v_experimental::SharedCacheVExperimental::default(); cache_v_experimental.last_block_hash = parent_block_hash; Self { diff --git a/crates/eth-sparse-mpt/src/v2/fetch.rs b/crates/eth-sparse-mpt/src/v2/fetch.rs index 43f27fcaf..7217620b4 100644 --- a/crates/eth-sparse-mpt/src/v2/fetch.rs +++ b/crates/eth-sparse-mpt/src/v2/fetch.rs @@ -11,17 +11,48 @@ use rayon::prelude::*; use alloy_primitives::B256; use nybbles::Nibbles; use reth_provider::{ - providers::ConsistentDbView, BlockHashReader, BlockNumReader, BlockReader, DBProvider, - DatabaseProviderFactory, + providers::ConsistentDbView, BlockReader, DBProvider, DatabaseProviderFactory, }; use reth_trie::{ proof::{Proof, StorageProof}, + trie_cursor::{TrieCursor, TrieCursorFactory}, MultiProofTargets, }; use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory}; use super::SharedCacheV2; +pub fn check_state_root_in_db( + provider: &impl DBProvider, + expected_state_root: B256, +) -> Result<(), SparseTrieError> { + let factory = DatabaseTrieCursorFactory::new(provider.tx_ref()); + let mut cursor = factory + .account_trie_cursor() + .map_err(SparseTrieError::other)?; + let root_node = cursor + .seek_exact(reth_trie::Nibbles::default()) + .map_err(SparseTrieError::other)?; + match root_node { + Some((_, node)) => { + let Some(node_root_hash) = node.root_hash else { + return Err(SparseTrieError::Other(eyre::eyre!( + "reth db account trie has no hash in root node" + ))); + }; + if node_root_hash == expected_state_root { + Ok(()) + } else { + Err(SparseTrieError::WrongDatabaseTrieError) + } + } + // reth db trie has no root node, this should only be possible on empty db tests + None => Err(SparseTrieError::Other(eyre::eyre!( + "reth db account trie has no root node" + ))), + } +} + #[derive(Debug, Default)] pub struct MissingNodesFetcher { storage_proof_targets: HashMap)>, @@ -59,7 +90,7 @@ impl MissingNodesFetcher { { let fetched_nodes: Arc> = Default::default(); - let last_block_hash = shared_cache.last_block_hash; + let parent_state_root = shared_cache.parent_state_root; std::mem::take(&mut self.storage_proof_targets) .into_par_iter() .map( @@ -67,16 +98,8 @@ impl MissingNodesFetcher { let provider = consistent_db_view .provider_ro() .map_err(SparseTrieError::other)?; - if !last_block_hash.is_zero() { - let block_number = provider - .last_block_number() - .map_err(SparseTrieError::other)?; - let block_hash = provider - .block_hash(block_number) - .map_err(SparseTrieError::other)?; - if block_hash != Some(shared_cache.last_block_hash) { - return Err(SparseTrieError::WrongDatabaseTrieError); - } + if !parent_state_root.is_zero() { + check_state_root_in_db(&provider, parent_state_root)?; } let proof = StorageProof::new_hashed( @@ -110,16 +133,8 @@ impl MissingNodesFetcher { let provider = consistent_db_view .provider_ro() .map_err(SparseTrieError::other)?; - if !last_block_hash.is_zero() { - let block_number = provider - .last_block_number() - .map_err(SparseTrieError::other)?; - let block_hash = provider - .block_hash(block_number) - .map_err(SparseTrieError::other)?; - if block_hash != Some(shared_cache.last_block_hash) { - return Err(SparseTrieError::WrongDatabaseTrieError); - } + if !parent_state_root.is_zero() { + check_state_root_in_db(&provider, parent_state_root)? } let proof = Proof::new( diff --git a/crates/eth-sparse-mpt/src/v2/mod.rs b/crates/eth-sparse-mpt/src/v2/mod.rs index 4986e84f7..fdc996a8b 100644 --- a/crates/eth-sparse-mpt/src/v2/mod.rs +++ b/crates/eth-sparse-mpt/src/v2/mod.rs @@ -31,7 +31,7 @@ const PARALLEL_HASHING_STORAGE_NODES: bool = true; pub struct SharedCacheV2 { pub account_trie: ProofStore, pub storage_tries: Arc>, - pub last_block_hash: B256, + pub parent_state_root: B256, } impl SharedCacheV2 {