1use crate::{
2 AccountReader, BlockHashReader, ExecutionDataProvider, StateProvider, StateRootProvider,
3};
4use alloy_primitives::{Address, BlockNumber, Bytes, B256};
5use reth_primitives::{Account, Bytecode};
6use reth_storage_api::{HashedPostStateProvider, StateProofProvider, StorageRootProvider};
7use reth_storage_errors::provider::ProviderResult;
8use reth_trie::{
9 updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof,
10 MultiProofTargets, StorageMultiProof, TrieInput,
11};
12
13#[derive(Debug)]
20pub struct BundleStateProvider<SP: StateProvider, EDP: ExecutionDataProvider> {
21 pub state_provider: SP,
23 pub block_execution_data_provider: EDP,
25}
26
27impl<SP: StateProvider, EDP: ExecutionDataProvider> BundleStateProvider<SP, EDP> {
28 pub const fn new(state_provider: SP, block_execution_data_provider: EDP) -> Self {
30 Self { state_provider, block_execution_data_provider }
31 }
32
33 fn get_hashed_storage(&self, address: Address) -> HashedStorage {
35 let bundle_state = self.block_execution_data_provider.execution_outcome().state();
36 bundle_state
37 .account(&address)
38 .map(|account| {
39 HashedStorage::from_plain_storage(
40 account.status,
41 account.storage.iter().map(|(slot, value)| (slot, &value.present_value)),
42 )
43 })
44 .unwrap_or_default()
45 }
46}
47
48impl<SP: StateProvider, EDP: ExecutionDataProvider> BlockHashReader
51 for BundleStateProvider<SP, EDP>
52{
53 fn block_hash(&self, block_number: BlockNumber) -> ProviderResult<Option<B256>> {
54 let block_hash = self.block_execution_data_provider.block_hash(block_number);
55 if block_hash.is_some() {
56 return Ok(block_hash)
57 }
58 self.state_provider.block_hash(block_number)
59 }
60
61 fn canonical_hashes_range(
62 &self,
63 _start: BlockNumber,
64 _end: BlockNumber,
65 ) -> ProviderResult<Vec<B256>> {
66 unimplemented!()
67 }
68}
69
70impl<SP: StateProvider, EDP: ExecutionDataProvider> AccountReader for BundleStateProvider<SP, EDP> {
71 fn basic_account(&self, address: &Address) -> ProviderResult<Option<Account>> {
72 if let Some(account) =
73 self.block_execution_data_provider.execution_outcome().account(address)
74 {
75 Ok(account)
76 } else {
77 self.state_provider.basic_account(address)
78 }
79 }
80}
81
82impl<SP: StateProvider, EDP: ExecutionDataProvider> StateRootProvider
83 for BundleStateProvider<SP, EDP>
84{
85 fn state_root(&self, hashed_state: HashedPostState) -> ProviderResult<B256> {
86 let bundle_state = self.block_execution_data_provider.execution_outcome().state();
87 let mut state = self.hashed_post_state(bundle_state);
88 state.extend(hashed_state);
89 self.state_provider.state_root(state)
90 }
91
92 fn state_root_from_nodes(&self, _input: TrieInput) -> ProviderResult<B256> {
93 unimplemented!()
94 }
95
96 fn state_root_with_updates(
97 &self,
98 hashed_state: HashedPostState,
99 ) -> ProviderResult<(B256, TrieUpdates)> {
100 let bundle_state = self.block_execution_data_provider.execution_outcome().state();
101 let mut state = self.hashed_post_state(bundle_state);
102 state.extend(hashed_state);
103 self.state_provider.state_root_with_updates(state)
104 }
105
106 fn state_root_from_nodes_with_updates(
107 &self,
108 mut input: TrieInput,
109 ) -> ProviderResult<(B256, TrieUpdates)> {
110 let bundle_state = self.block_execution_data_provider.execution_outcome().state();
111 input.prepend(self.hashed_post_state(bundle_state));
112 self.state_provider.state_root_from_nodes_with_updates(input)
113 }
114}
115
116impl<SP: StateProvider, EDP: ExecutionDataProvider> StorageRootProvider
117 for BundleStateProvider<SP, EDP>
118{
119 fn storage_root(
120 &self,
121 address: Address,
122 hashed_storage: HashedStorage,
123 ) -> ProviderResult<B256> {
124 let mut storage = self.get_hashed_storage(address);
125 storage.extend(&hashed_storage);
126 self.state_provider.storage_root(address, storage)
127 }
128
129 fn storage_proof(
130 &self,
131 address: Address,
132 slot: B256,
133 hashed_storage: HashedStorage,
134 ) -> ProviderResult<reth_trie::StorageProof> {
135 let mut storage = self.get_hashed_storage(address);
136 storage.extend(&hashed_storage);
137 self.state_provider.storage_proof(address, slot, storage)
138 }
139
140 fn storage_multiproof(
141 &self,
142 address: Address,
143 slots: &[B256],
144 hashed_storage: HashedStorage,
145 ) -> ProviderResult<StorageMultiProof> {
146 let mut storage = self.get_hashed_storage(address);
147 storage.extend(&hashed_storage);
148 self.state_provider.storage_multiproof(address, slots, storage)
149 }
150}
151
152impl<SP: StateProvider, EDP: ExecutionDataProvider> StateProofProvider
153 for BundleStateProvider<SP, EDP>
154{
155 fn proof(
156 &self,
157 mut input: TrieInput,
158 address: Address,
159 slots: &[B256],
160 ) -> ProviderResult<AccountProof> {
161 let bundle_state = self.block_execution_data_provider.execution_outcome().state();
162 input.prepend(self.hashed_post_state(bundle_state));
163 self.state_provider.proof(input, address, slots)
164 }
165
166 fn multiproof(
167 &self,
168 mut input: reth_trie::TrieInput,
169 targets: MultiProofTargets,
170 ) -> ProviderResult<MultiProof> {
171 let bundle_state = self.block_execution_data_provider.execution_outcome().state();
172 input.prepend(self.hashed_post_state(bundle_state));
173 self.state_provider.multiproof(input, targets)
174 }
175
176 fn witness(&self, mut input: TrieInput, target: HashedPostState) -> ProviderResult<Vec<Bytes>> {
177 let bundle_state = self.block_execution_data_provider.execution_outcome().state();
178 input.prepend(self.hashed_post_state(bundle_state));
179 self.state_provider.witness(input, target)
180 }
181}
182
183impl<SP: StateProvider, EDP: ExecutionDataProvider> HashedPostStateProvider
184 for BundleStateProvider<SP, EDP>
185{
186 fn hashed_post_state(&self, bundle_state: &revm_database::BundleState) -> HashedPostState {
187 self.state_provider.hashed_post_state(bundle_state)
188 }
189}
190
191impl<SP: StateProvider, EDP: ExecutionDataProvider> StateProvider for BundleStateProvider<SP, EDP> {
192 fn storage(
193 &self,
194 account: Address,
195 storage_key: alloy_primitives::StorageKey,
196 ) -> ProviderResult<Option<alloy_primitives::StorageValue>> {
197 let u256_storage_key = storage_key.into();
198 if let Some(value) = self
199 .block_execution_data_provider
200 .execution_outcome()
201 .storage(&account, u256_storage_key)
202 {
203 return Ok(Some(value))
204 }
205
206 self.state_provider.storage(account, storage_key)
207 }
208
209 fn bytecode_by_hash(&self, code_hash: &B256) -> ProviderResult<Option<Bytecode>> {
210 if let Some(bytecode) =
211 self.block_execution_data_provider.execution_outcome().bytecode(code_hash)
212 {
213 return Ok(Some(bytecode))
214 }
215
216 self.state_provider.bytecode_by_hash(code_hash)
217 }
218}