1use alloc::vec::Vec;
2use alloy_primitives::{
3 keccak256,
4 map::{B256HashMap, HashMap},
5 Address, BlockNumber, Bytes, StorageKey, B256,
6};
7use reth_primitives::{Account, Bytecode};
8use reth_storage_api::{
9 AccountReader, BlockHashReader, HashedPostStateProvider, StateProofProvider, StateProvider,
10 StateRootProvider, StorageRootProvider,
11};
12use reth_storage_errors::provider::ProviderResult;
13use reth_trie::{
14 updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, KeccakKeyHasher,
15 MultiProof, MultiProofTargets, StorageMultiProof, StorageProof, TrieInput,
16};
17
18#[cfg(not(feature = "std"))]
19use alloc::vec::Vec;
20use revm::primitives::FlaggedStorage;
21
22#[derive(Debug, Default, Clone, Eq, PartialEq)]
24pub struct StateProviderTest {
25 accounts: HashMap<Address, (HashMap<StorageKey, FlaggedStorage>, Account)>,
26 contracts: HashMap<B256, Bytecode>,
27 block_hash: HashMap<u64, B256>,
28}
29
30impl StateProviderTest {
31 pub fn insert_account(
33 &mut self,
34 address: Address,
35 mut account: Account,
36 bytecode: Option<Bytes>,
37 storage: HashMap<StorageKey, FlaggedStorage>,
38 ) {
39 if let Some(bytecode) = bytecode {
40 let hash = keccak256(&bytecode);
41 account.bytecode_hash = Some(hash);
42 self.contracts.insert(hash, Bytecode::new_raw(bytecode));
43 }
44 self.accounts.insert(address, (storage, account));
45 }
46
47 pub fn insert_block_hash(&mut self, block_number: u64, block_hash: B256) {
49 self.block_hash.insert(block_number, block_hash);
50 }
51}
52
53impl AccountReader for StateProviderTest {
54 fn basic_account(&self, address: Address) -> ProviderResult<Option<Account>> {
55 Ok(self.accounts.get(&address).map(|(_, acc)| *acc))
56 }
57}
58
59impl BlockHashReader for StateProviderTest {
60 fn block_hash(&self, number: u64) -> ProviderResult<Option<B256>> {
61 Ok(self.block_hash.get(&number).copied())
62 }
63
64 fn canonical_hashes_range(
65 &self,
66 start: BlockNumber,
67 end: BlockNumber,
68 ) -> ProviderResult<Vec<B256>> {
69 let range = start..end;
70 Ok(self
71 .block_hash
72 .iter()
73 .filter_map(|(block, hash)| range.contains(block).then_some(*hash))
74 .collect())
75 }
76}
77
78impl StateRootProvider for StateProviderTest {
79 fn state_root(&self, _hashed_state: HashedPostState) -> ProviderResult<B256> {
80 unimplemented!("state root computation is not supported")
81 }
82
83 fn state_root_from_nodes(&self, _input: TrieInput) -> ProviderResult<B256> {
84 unimplemented!("state root computation is not supported")
85 }
86
87 fn state_root_with_updates(
88 &self,
89 _hashed_state: HashedPostState,
90 ) -> ProviderResult<(B256, TrieUpdates)> {
91 unimplemented!("state root computation is not supported")
92 }
93
94 fn state_root_from_nodes_with_updates(
95 &self,
96 _input: TrieInput,
97 ) -> ProviderResult<(B256, TrieUpdates)> {
98 unimplemented!("state root computation is not supported")
99 }
100}
101
102impl StorageRootProvider for StateProviderTest {
103 fn storage_root(
104 &self,
105 _address: Address,
106 _hashed_storage: HashedStorage,
107 ) -> ProviderResult<B256> {
108 unimplemented!("storage root is not supported")
109 }
110
111 fn storage_proof(
112 &self,
113 _address: Address,
114 _slot: B256,
115 _hashed_storage: HashedStorage,
116 ) -> ProviderResult<StorageProof> {
117 unimplemented!("proof generation is not supported")
118 }
119
120 fn storage_multiproof(
121 &self,
122 _address: Address,
123 _slots: &[B256],
124 _hashed_storage: HashedStorage,
125 ) -> ProviderResult<StorageMultiProof> {
126 unimplemented!("proof generation is not supported")
127 }
128}
129
130impl StateProofProvider for StateProviderTest {
131 fn proof(
132 &self,
133 _input: TrieInput,
134 _address: Address,
135 _slots: &[B256],
136 ) -> ProviderResult<AccountProof> {
137 unimplemented!("proof generation is not supported")
138 }
139
140 fn multiproof(
141 &self,
142 _input: TrieInput,
143 _targets: MultiProofTargets,
144 ) -> ProviderResult<MultiProof> {
145 unimplemented!("proof generation is not supported")
146 }
147
148 fn witness(
149 &self,
150 _input: TrieInput,
151 _target: HashedPostState,
152 ) -> ProviderResult<B256HashMap<Bytes>> {
153 unimplemented!("witness generation is not supported")
154 }
155}
156
157impl HashedPostStateProvider for StateProviderTest {
158 fn hashed_post_state(&self, bundle_state: &revm::db::BundleState) -> HashedPostState {
159 HashedPostState::from_bundle_state::<KeccakKeyHasher>(bundle_state.state())
160 }
161}
162
163impl StateProvider for StateProviderTest {
164 fn storage(
165 &self,
166 account: Address,
167 storage_key: StorageKey,
168 ) -> ProviderResult<Option<FlaggedStorage>> {
169 Ok(self.accounts.get(&account).and_then(|(storage, _)| storage.get(&storage_key).copied()))
170 }
171
172 fn bytecode_by_hash(&self, code_hash: B256) -> ProviderResult<Option<Bytecode>> {
173 Ok(self.contracts.get(&code_hash).cloned())
174 }
175}