1use crate::primitives::alloy_primitives::{BlockNumber, StorageKey};
2use alloy_primitives::{Address, B256, U256};
3use core::ops::{Deref, DerefMut};
4use reth_primitives::Account;
5use reth_storage_errors::provider::{ProviderError, ProviderResult};
6use revm::{
7 db::DatabaseRef,
8 primitives::{AccountInfo, Bytecode, FlaggedStorage},
9 Database,
10};
11
12pub trait EvmStateProvider: Send + Sync {
16 fn basic_account(&self, address: Address) -> ProviderResult<Option<Account>>;
20
21 fn block_hash(&self, number: BlockNumber) -> ProviderResult<Option<B256>>;
24
25 fn bytecode_by_hash(
27 &self,
28 code_hash: B256,
29 ) -> ProviderResult<Option<reth_primitives::Bytecode>>;
30
31 fn storage(
33 &self,
34 account: Address,
35 storage_key: StorageKey,
36 ) -> ProviderResult<Option<FlaggedStorage>>;
37}
38
39impl<T: reth_storage_api::StateProvider> EvmStateProvider for T {
41 fn basic_account(&self, address: Address) -> ProviderResult<Option<Account>> {
42 <T as reth_storage_api::AccountReader>::basic_account(self, address)
43 }
44
45 fn block_hash(&self, number: BlockNumber) -> ProviderResult<Option<B256>> {
46 <T as reth_storage_api::BlockHashReader>::block_hash(self, number)
47 }
48
49 fn bytecode_by_hash(
50 &self,
51 code_hash: B256,
52 ) -> ProviderResult<Option<reth_primitives::Bytecode>> {
53 <T as reth_storage_api::StateProvider>::bytecode_by_hash(self, code_hash)
54 }
55
56 fn storage(
57 &self,
58 account: Address,
59 storage_key: StorageKey,
60 ) -> ProviderResult<Option<FlaggedStorage>> {
61 <T as reth_storage_api::StateProvider>::storage(self, account, storage_key)
62 }
63}
64
65#[derive(Debug, Clone)]
68pub struct StateProviderDatabase<DB>(pub DB);
69
70impl<DB> StateProviderDatabase<DB> {
71 pub const fn new(db: DB) -> Self {
73 Self(db)
74 }
75
76 pub fn into_inner(self) -> DB {
78 self.0
79 }
80}
81
82impl<DB> AsRef<DB> for StateProviderDatabase<DB> {
83 fn as_ref(&self) -> &DB {
84 self
85 }
86}
87
88impl<DB> Deref for StateProviderDatabase<DB> {
89 type Target = DB;
90
91 fn deref(&self) -> &Self::Target {
92 &self.0
93 }
94}
95
96impl<DB> DerefMut for StateProviderDatabase<DB> {
97 fn deref_mut(&mut self) -> &mut Self::Target {
98 &mut self.0
99 }
100}
101
102impl<DB: EvmStateProvider> Database for StateProviderDatabase<DB> {
103 type Error = ProviderError;
104
105 fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
110 self.basic_ref(address)
111 }
112
113 fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> {
117 self.code_by_hash_ref(code_hash)
118 }
119
120 fn storage(&mut self, address: Address, index: U256) -> Result<FlaggedStorage, Self::Error> {
124 self.storage_ref(address, index)
125 }
126
127 fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
132 self.block_hash_ref(number)
133 }
134}
135
136impl<DB: EvmStateProvider> DatabaseRef for StateProviderDatabase<DB> {
137 type Error = <Self as Database>::Error;
138
139 fn basic_ref(&self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
144 Ok(self.basic_account(address)?.map(Into::into))
145 }
146
147 fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, Self::Error> {
151 Ok(self.bytecode_by_hash(code_hash)?.unwrap_or_default().0)
152 }
153
154 fn storage_ref(&self, address: Address, index: U256) -> Result<FlaggedStorage, Self::Error> {
158 Ok(self.0.storage(address, B256::new(index.to_be_bytes()))?.unwrap_or_default())
159 }
160
161 fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error> {
165 Ok(self.0.block_hash(number)?.unwrap_or_default())
167 }
168}