reth_revm/
test_utils.rs

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/// Mock state for testing
23#[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    /// Insert account.
32    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    /// Insert a block hash.
48    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}