reth_rpc_eth_types/cache/
db.rs

1//! Helper types to workaround 'higher-ranked lifetime error'
2//! <https://github.com/rust-lang/rust/issues/100013> in default implementation of
3//! `reth_rpc_eth_api::helpers::Call`.
4
5use alloy_primitives::{Address, B256, U256};
6use reth_errors::ProviderResult;
7use reth_revm::{database::StateProviderDatabase, DatabaseRef};
8use reth_storage_api::{HashedPostStateProvider, StateProvider};
9use reth_trie::{HashedStorage, MultiProofTargets};
10use revm::{
11    database::{BundleState, CacheDB},
12    state::{AccountInfo, Bytecode},
13    Database,
14};
15
16/// Helper alias type for the state's [`CacheDB`]
17pub type StateCacheDb<'a> = CacheDB<StateProviderDatabase<StateProviderTraitObjWrapper<'a>>>;
18
19/// Hack to get around 'higher-ranked lifetime error', see
20/// <https://github.com/rust-lang/rust/issues/100013>
21#[expect(missing_debug_implementations)]
22pub struct StateProviderTraitObjWrapper<'a>(pub &'a dyn StateProvider);
23
24impl reth_storage_api::StateRootProvider for StateProviderTraitObjWrapper<'_> {
25    fn state_root(
26        &self,
27        hashed_state: reth_trie::HashedPostState,
28    ) -> reth_errors::ProviderResult<B256> {
29        self.0.state_root(hashed_state)
30    }
31
32    fn state_root_from_nodes(
33        &self,
34        input: reth_trie::TrieInput,
35    ) -> reth_errors::ProviderResult<B256> {
36        self.0.state_root_from_nodes(input)
37    }
38
39    fn state_root_with_updates(
40        &self,
41        hashed_state: reth_trie::HashedPostState,
42    ) -> reth_errors::ProviderResult<(B256, reth_trie::updates::TrieUpdates)> {
43        self.0.state_root_with_updates(hashed_state)
44    }
45
46    fn state_root_from_nodes_with_updates(
47        &self,
48        input: reth_trie::TrieInput,
49    ) -> reth_errors::ProviderResult<(B256, reth_trie::updates::TrieUpdates)> {
50        self.0.state_root_from_nodes_with_updates(input)
51    }
52}
53
54impl reth_storage_api::StorageRootProvider for StateProviderTraitObjWrapper<'_> {
55    fn storage_root(
56        &self,
57        address: Address,
58        hashed_storage: HashedStorage,
59    ) -> ProviderResult<B256> {
60        self.0.storage_root(address, hashed_storage)
61    }
62
63    fn storage_proof(
64        &self,
65        address: Address,
66        slot: B256,
67        hashed_storage: HashedStorage,
68    ) -> ProviderResult<reth_trie::StorageProof> {
69        self.0.storage_proof(address, slot, hashed_storage)
70    }
71
72    fn storage_multiproof(
73        &self,
74        address: Address,
75        slots: &[B256],
76        hashed_storage: HashedStorage,
77    ) -> ProviderResult<reth_trie::StorageMultiProof> {
78        self.0.storage_multiproof(address, slots, hashed_storage)
79    }
80}
81
82impl reth_storage_api::StateProofProvider for StateProviderTraitObjWrapper<'_> {
83    fn proof(
84        &self,
85        input: reth_trie::TrieInput,
86        address: Address,
87        slots: &[B256],
88    ) -> reth_errors::ProviderResult<reth_trie::AccountProof> {
89        self.0.proof(input, address, slots)
90    }
91
92    fn multiproof(
93        &self,
94        input: reth_trie::TrieInput,
95        targets: MultiProofTargets,
96    ) -> ProviderResult<reth_trie::MultiProof> {
97        self.0.multiproof(input, targets)
98    }
99
100    fn witness(
101        &self,
102        input: reth_trie::TrieInput,
103        target: reth_trie::HashedPostState,
104    ) -> reth_errors::ProviderResult<Vec<alloy_primitives::Bytes>> {
105        self.0.witness(input, target)
106    }
107}
108
109impl reth_storage_api::AccountReader for StateProviderTraitObjWrapper<'_> {
110    fn basic_account(
111        &self,
112        address: &Address,
113    ) -> reth_errors::ProviderResult<Option<reth_primitives_traits::Account>> {
114        self.0.basic_account(address)
115    }
116}
117
118impl reth_storage_api::BlockHashReader for StateProviderTraitObjWrapper<'_> {
119    fn block_hash(
120        &self,
121        block_number: alloy_primitives::BlockNumber,
122    ) -> reth_errors::ProviderResult<Option<B256>> {
123        self.0.block_hash(block_number)
124    }
125
126    fn convert_block_hash(
127        &self,
128        hash_or_number: alloy_rpc_types_eth::BlockHashOrNumber,
129    ) -> reth_errors::ProviderResult<Option<B256>> {
130        self.0.convert_block_hash(hash_or_number)
131    }
132
133    fn canonical_hashes_range(
134        &self,
135        start: alloy_primitives::BlockNumber,
136        end: alloy_primitives::BlockNumber,
137    ) -> reth_errors::ProviderResult<Vec<B256>> {
138        self.0.canonical_hashes_range(start, end)
139    }
140}
141
142impl HashedPostStateProvider for StateProviderTraitObjWrapper<'_> {
143    fn hashed_post_state(&self, bundle_state: &BundleState) -> reth_trie::HashedPostState {
144        self.0.hashed_post_state(bundle_state)
145    }
146}
147
148impl StateProvider for StateProviderTraitObjWrapper<'_> {
149    fn storage(
150        &self,
151        account: Address,
152        storage_key: alloy_primitives::StorageKey,
153    ) -> reth_errors::ProviderResult<Option<alloy_primitives::StorageValue>> {
154        self.0.storage(account, storage_key)
155    }
156
157    fn bytecode_by_hash(
158        &self,
159        code_hash: &B256,
160    ) -> reth_errors::ProviderResult<Option<reth_primitives_traits::Bytecode>> {
161        self.0.bytecode_by_hash(code_hash)
162    }
163
164    fn account_code(
165        &self,
166        addr: &Address,
167    ) -> reth_errors::ProviderResult<Option<reth_primitives_traits::Bytecode>> {
168        self.0.account_code(addr)
169    }
170
171    fn account_balance(&self, addr: &Address) -> reth_errors::ProviderResult<Option<U256>> {
172        self.0.account_balance(addr)
173    }
174
175    fn account_nonce(&self, addr: &Address) -> reth_errors::ProviderResult<Option<u64>> {
176        self.0.account_nonce(addr)
177    }
178}
179
180/// Hack to get around 'higher-ranked lifetime error', see
181/// <https://github.com/rust-lang/rust/issues/100013>
182#[expect(missing_debug_implementations)]
183pub struct StateCacheDbRefMutWrapper<'a, 'b>(pub &'b mut StateCacheDb<'a>);
184
185impl<'a> Database for StateCacheDbRefMutWrapper<'a, '_> {
186    type Error = <StateCacheDb<'a> as Database>::Error;
187    fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
188        self.0.basic(address)
189    }
190
191    fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> {
192        self.0.code_by_hash(code_hash)
193    }
194
195    fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> {
196        self.0.storage(address, index)
197    }
198
199    fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
200        self.0.block_hash(number)
201    }
202}
203
204impl<'a> DatabaseRef for StateCacheDbRefMutWrapper<'a, '_> {
205    type Error = <StateCacheDb<'a> as Database>::Error;
206
207    fn basic_ref(&self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
208        self.0.basic_ref(address)
209    }
210
211    fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, Self::Error> {
212        self.0.code_by_hash_ref(code_hash)
213    }
214
215    fn storage_ref(&self, address: Address, index: U256) -> Result<U256, Self::Error> {
216        self.0.storage_ref(address, index)
217    }
218
219    fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error> {
220        self.0.block_hash_ref(number)
221    }
222}