use crate::{ AccountReader, BlockHashReader, ExecutionDataProvider, StateProvider, StateRootProvider, }; use reth_primitives::{Account, Address, BlockNumber, Bytecode, Bytes, B256}; use reth_storage_api::StateProofProvider; use reth_storage_errors::provider::ProviderResult; use reth_trie::{ prefix_set::TriePrefixSetsMut, updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, }; use revm::db::BundleState; use std::collections::HashMap; /// A state provider that resolves to data from either a wrapped [`crate::ExecutionOutcome`] /// or an underlying state provider. /// /// This struct combines two sources of state data: the execution outcome and an underlying /// state provider. It can provide state information by leveraging both the post-block execution /// changes and the pre-existing state data. #[derive(Debug)] pub struct BundleStateProvider { /// The inner state provider. pub state_provider: SP, /// Block execution data. pub block_execution_data_provider: EDP, } impl BundleStateProvider { /// Create new bundle state provider pub const fn new(state_provider: SP, block_execution_data_provider: EDP) -> Self { Self { state_provider, block_execution_data_provider } } } /* Implement StateProvider traits */ impl BlockHashReader for BundleStateProvider { fn block_hash(&self, block_number: BlockNumber) -> ProviderResult> { let block_hash = self.block_execution_data_provider.block_hash(block_number); if block_hash.is_some() { return Ok(block_hash) } self.state_provider.block_hash(block_number) } fn canonical_hashes_range( &self, _start: BlockNumber, _end: BlockNumber, ) -> ProviderResult> { unimplemented!() } } impl AccountReader for BundleStateProvider { fn basic_account(&self, address: Address) -> ProviderResult> { if let Some(account) = self.block_execution_data_provider.execution_outcome().account(&address) { Ok(account) } else { self.state_provider.basic_account(address) } } } impl StateRootProvider for BundleStateProvider { fn state_root(&self, bundle_state: &BundleState) -> ProviderResult { let mut state = self.block_execution_data_provider.execution_outcome().state().clone(); state.extend(bundle_state.clone()); self.state_provider.state_root(&state) } fn hashed_state_root(&self, hashed_state: HashedPostState) -> ProviderResult { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); let mut state = HashedPostState::from_bundle_state(&bundle_state.state); state.extend(hashed_state); self.state_provider.hashed_state_root(state) } fn hashed_state_root_from_nodes( &self, _nodes: TrieUpdates, _hashed_state: HashedPostState, _prefix_sets: TriePrefixSetsMut, ) -> ProviderResult { unimplemented!() } fn state_root_with_updates( &self, bundle_state: &BundleState, ) -> ProviderResult<(B256, TrieUpdates)> { let mut state = self.block_execution_data_provider.execution_outcome().state().clone(); state.extend(bundle_state.clone()); self.state_provider.state_root_with_updates(&state) } fn hashed_state_root_with_updates( &self, hashed_state: HashedPostState, ) -> ProviderResult<(B256, TrieUpdates)> { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); let mut state = HashedPostState::from_bundle_state(&bundle_state.state); state.extend(hashed_state); self.state_provider.hashed_state_root_with_updates(state) } fn hashed_state_root_from_nodes_with_updates( &self, nodes: TrieUpdates, hashed_state: HashedPostState, prefix_sets: TriePrefixSetsMut, ) -> ProviderResult<(B256, TrieUpdates)> { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); let mut state = HashedPostState::from_bundle_state(&bundle_state.state); let mut state_prefix_sets = state.construct_prefix_sets(); state.extend(hashed_state); state_prefix_sets.extend(prefix_sets); self.state_provider.hashed_state_root_from_nodes_with_updates( nodes, state, state_prefix_sets, ) } fn hashed_storage_root( &self, address: Address, hashed_storage: HashedStorage, ) -> ProviderResult { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); let mut storage = bundle_state .account(&address) .map(|account| HashedStorage::from_bundle_state(account.status, &account.storage)) .unwrap_or_else(|| HashedStorage::new(false)); storage.extend(hashed_storage); self.state_provider.hashed_storage_root(address, storage) } } impl StateProofProvider for BundleStateProvider { fn hashed_proof( &self, hashed_state: HashedPostState, address: Address, slots: &[B256], ) -> ProviderResult { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); let mut state = HashedPostState::from_bundle_state(&bundle_state.state); state.extend(hashed_state); self.state_provider.hashed_proof(state, address, slots) } fn witness( &self, overlay: HashedPostState, target: HashedPostState, ) -> ProviderResult> { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); let mut state = HashedPostState::from_bundle_state(&bundle_state.state); state.extend(overlay); self.state_provider.witness(state, target) } } impl StateProvider for BundleStateProvider { fn storage( &self, account: Address, storage_key: reth_primitives::StorageKey, ) -> ProviderResult> { let u256_storage_key = storage_key.into(); if let Some(value) = self .block_execution_data_provider .execution_outcome() .storage(&account, u256_storage_key) { return Ok(Some(value)) } self.state_provider.storage(account, storage_key) } fn bytecode_by_hash(&self, code_hash: B256) -> ProviderResult> { if let Some(bytecode) = self.block_execution_data_provider.execution_outcome().bytecode(&code_hash) { return Ok(Some(bytecode)) } self.state_provider.bytecode_by_hash(code_hash) } }