1use crate::primitives::alloy_primitives::{BlockNumber, StorageKey, StorageValue};
2use alloy_primitives::{Address, B256, U256};
3use core::ops::{Deref, DerefMut};
4use reth_primitives_traits::Account;
5use reth_storage_api::{AccountReader, BlockHashReader, BytecodeReader, StateProvider};
6use reth_storage_errors::provider::{ProviderError, ProviderResult};
7use revm::{bytecode::Bytecode, state::AccountInfo, Database, DatabaseRef};
8
9pub trait EvmStateProvider: Send + Sync {
13 fn basic_account(&self, address: &Address) -> ProviderResult<Option<Account>>;
17
18 fn block_hash(&self, number: BlockNumber) -> ProviderResult<Option<B256>>;
21
22 fn bytecode_by_hash(
24 &self,
25 code_hash: &B256,
26 ) -> ProviderResult<Option<reth_primitives_traits::Bytecode>>;
27
28 fn storage(
30 &self,
31 account: Address,
32 storage_key: StorageKey,
33 ) -> ProviderResult<Option<StorageValue>>;
34}
35
36impl<T: StateProvider> EvmStateProvider for T {
38 fn basic_account(&self, address: &Address) -> ProviderResult<Option<Account>> {
39 <T as AccountReader>::basic_account(self, address)
40 }
41
42 fn block_hash(&self, number: BlockNumber) -> ProviderResult<Option<B256>> {
43 <T as BlockHashReader>::block_hash(self, number)
44 }
45
46 fn bytecode_by_hash(
47 &self,
48 code_hash: &B256,
49 ) -> ProviderResult<Option<reth_primitives_traits::Bytecode>> {
50 <T as BytecodeReader>::bytecode_by_hash(self, code_hash)
51 }
52
53 fn storage(
54 &self,
55 account: Address,
56 storage_key: StorageKey,
57 ) -> ProviderResult<Option<StorageValue>> {
58 <T as StateProvider>::storage(self, account, storage_key)
59 }
60}
61
62#[derive(Clone)]
65pub struct StateProviderDatabase<DB>(pub DB);
66
67impl<DB> StateProviderDatabase<DB> {
68 pub const fn new(db: DB) -> Self {
70 Self(db)
71 }
72
73 pub fn into_inner(self) -> DB {
75 self.0
76 }
77}
78
79impl<DB> core::fmt::Debug for StateProviderDatabase<DB> {
80 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
81 f.debug_struct("StateProviderDatabase").finish_non_exhaustive()
82 }
83}
84
85impl<DB> AsRef<DB> for StateProviderDatabase<DB> {
86 fn as_ref(&self) -> &DB {
87 self
88 }
89}
90
91impl<DB> Deref for StateProviderDatabase<DB> {
92 type Target = DB;
93
94 fn deref(&self) -> &Self::Target {
95 &self.0
96 }
97}
98
99impl<DB> DerefMut for StateProviderDatabase<DB> {
100 fn deref_mut(&mut self) -> &mut Self::Target {
101 &mut self.0
102 }
103}
104
105impl<DB: EvmStateProvider> Database for StateProviderDatabase<DB> {
106 type Error = ProviderError;
107
108 fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
113 self.basic_ref(address)
114 }
115
116 fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> {
120 self.code_by_hash_ref(code_hash)
121 }
122
123 fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> {
127 self.storage_ref(address, index)
128 }
129
130 fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
135 self.block_hash_ref(number)
136 }
137}
138
139impl<DB: EvmStateProvider> DatabaseRef for StateProviderDatabase<DB> {
140 type Error = <Self as Database>::Error;
141
142 fn basic_ref(&self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
147 Ok(self.basic_account(&address)?.map(Into::into))
148 }
149
150 fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, Self::Error> {
154 Ok(self.bytecode_by_hash(&code_hash)?.unwrap_or_default().0)
155 }
156
157 fn storage_ref(&self, address: Address, index: U256) -> Result<U256, Self::Error> {
161 Ok(self.0.storage(address, B256::new(index.to_be_bytes()))?.unwrap_or_default())
162 }
163
164 fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error> {
168 Ok(self.0.block_hash(number)?.unwrap_or_default())
170 }
171}