1use crate::Database;
4use alloc::boxed::Box;
5use alloy_primitives::{Address, Log, B256, U256};
6use core::{error::Error, fmt, fmt::Debug};
7use revm::{
8 context::{journaled_state::TransferError, Block, DBErrorMarker, JournalTr},
9 interpreter::{SStoreResult, StateLoad},
10 primitives::{StorageKey, StorageValue},
11 state::{Account, AccountInfo, Bytecode},
12};
13
14#[derive(thiserror::Error, Debug)]
16#[error(transparent)]
17pub struct ErasedError(Box<dyn Error + Send + Sync + 'static>);
18
19impl ErasedError {
20 pub fn new(error: impl Error + Send + Sync + 'static) -> Self {
22 Self(Box::new(error))
23 }
24}
25
26impl DBErrorMarker for ErasedError {}
27
28#[derive(Debug, thiserror::Error)]
30pub enum EvmInternalsError {
31 #[error(transparent)]
33 Database(ErasedError),
34}
35
36impl EvmInternalsError {
37 pub fn database(err: impl Error + Send + Sync + 'static) -> Self {
39 Self::Database(ErasedError::new(err))
40 }
41}
42
43trait EvmInternalsTr: Database<Error = ErasedError> + Debug {
48 fn load_account(&mut self, address: Address) -> Result<StateLoad<&Account>, EvmInternalsError>;
49
50 fn load_account_code(
51 &mut self,
52 address: Address,
53 ) -> Result<StateLoad<&Account>, EvmInternalsError>;
54
55 fn balance_incr(&mut self, address: Address, balance: U256) -> Result<(), EvmInternalsError>;
57
58 fn set_balance(&mut self, address: Address, balance: U256) -> Result<(), EvmInternalsError>;
64
65 fn transfer(
69 &mut self,
70 from: Address,
71 to: Address,
72 balance: U256,
73 ) -> Result<Option<TransferError>, EvmInternalsError>;
74
75 fn bump_nonce(&mut self, address: Address) -> Result<(), EvmInternalsError>;
79
80 fn sload(
81 &mut self,
82 address: Address,
83 key: StorageKey,
84 ) -> Result<StateLoad<StorageValue>, EvmInternalsError>;
85
86 fn touch_account(&mut self, address: Address);
87
88 fn set_code(&mut self, address: Address, code: Bytecode);
89
90 fn set_code_with_hash(&mut self, address: Address, code: Bytecode, hash: B256);
92
93 fn sstore(
94 &mut self,
95 address: Address,
96 key: StorageKey,
97 value: StorageValue,
98 ) -> Result<StateLoad<SStoreResult>, EvmInternalsError>;
99
100 fn log(&mut self, log: Log);
101
102 fn tload(&mut self, address: Address, key: StorageKey) -> StorageValue;
103
104 fn tstore(&mut self, address: Address, key: StorageKey, value: StorageValue);
105}
106
107#[derive(Debug)]
109struct EvmInternalsImpl<'a, T>(&'a mut T);
110
111impl<T> revm::Database for EvmInternalsImpl<'_, T>
112where
113 T: JournalTr<Database: Database>,
114{
115 type Error = ErasedError;
116
117 fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
118 self.0.db_mut().basic(address).map_err(ErasedError::new)
119 }
120
121 fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> {
122 self.0.db_mut().code_by_hash(code_hash).map_err(ErasedError::new)
123 }
124
125 fn storage(
126 &mut self,
127 address: Address,
128 index: StorageKey,
129 ) -> Result<StorageValue, Self::Error> {
130 self.0.db_mut().storage(address, index).map_err(ErasedError::new)
131 }
132
133 fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
134 self.0.db_mut().block_hash(number).map_err(ErasedError::new)
135 }
136}
137
138impl<T> EvmInternalsTr for EvmInternalsImpl<'_, T>
139where
140 T: JournalTr<Database: Database> + Debug,
141{
142 fn load_account(&mut self, address: Address) -> Result<StateLoad<&Account>, EvmInternalsError> {
143 self.0.load_account(address).map_err(EvmInternalsError::database)
144 }
145
146 fn load_account_code(
147 &mut self,
148 address: Address,
149 ) -> Result<StateLoad<&Account>, EvmInternalsError> {
150 self.0.load_account_with_code(address).map_err(EvmInternalsError::database)
151 }
152
153 fn balance_incr(&mut self, address: Address, balance: U256) -> Result<(), EvmInternalsError> {
154 self.0.balance_incr(address, balance).map_err(EvmInternalsError::database)
155 }
156
157 fn set_balance(&mut self, address: Address, balance: U256) -> Result<(), EvmInternalsError> {
158 let mut account = self.0.load_account_mut(address).map_err(EvmInternalsError::database)?;
159 account.set_balance(balance);
160 Ok(())
161 }
162
163 fn transfer(
164 &mut self,
165 from: Address,
166 to: Address,
167 balance: U256,
168 ) -> Result<Option<TransferError>, EvmInternalsError> {
169 self.0.transfer(from, to, balance).map_err(EvmInternalsError::database)
170 }
171
172 fn bump_nonce(&mut self, address: Address) -> Result<(), EvmInternalsError> {
173 self.0.load_account_mut(address).map_err(EvmInternalsError::database)?.bump_nonce();
174 Ok(())
175 }
176
177 fn sload(
178 &mut self,
179 address: Address,
180 key: StorageKey,
181 ) -> Result<StateLoad<StorageValue>, EvmInternalsError> {
182 self.0.sload(address, key).map_err(EvmInternalsError::database)
183 }
184
185 fn touch_account(&mut self, address: Address) {
186 self.0.touch_account(address);
187 }
188
189 fn set_code(&mut self, address: Address, code: Bytecode) {
190 self.0.set_code(address, code);
191 }
192
193 fn set_code_with_hash(&mut self, address: Address, code: Bytecode, hash: B256) {
194 self.0.set_code_with_hash(address, code, hash);
195 }
196
197 fn sstore(
198 &mut self,
199 address: Address,
200 key: StorageKey,
201 value: StorageValue,
202 ) -> Result<StateLoad<SStoreResult>, EvmInternalsError> {
203 self.0.sstore(address, key, value).map_err(EvmInternalsError::database)
204 }
205
206 fn log(&mut self, log: Log) {
207 self.0.log(log);
208 }
209
210 fn tload(&mut self, address: Address, key: StorageKey) -> StorageValue {
211 self.0.tload(address, key)
212 }
213
214 fn tstore(&mut self, address: Address, key: StorageKey, value: StorageValue) {
215 self.0.tstore(address, key, value);
216 }
217}
218
219pub struct EvmInternals<'a> {
221 internals: Box<dyn EvmInternalsTr + 'a>,
222 block_env: &'a (dyn Block + 'a),
223}
224
225impl<'a> EvmInternals<'a> {
226 pub fn new<T>(journal: &'a mut T, block_env: &'a dyn Block) -> Self
228 where
229 T: JournalTr<Database: Database> + Debug,
230 {
231 Self { internals: Box::new(EvmInternalsImpl(journal)), block_env }
232 }
233
234 pub const fn block_env(&self) -> impl Block + 'a {
236 self.block_env
237 }
238
239 pub fn block_number(&self) -> U256 {
241 self.block_env.number()
242 }
243
244 pub fn block_timestamp(&self) -> U256 {
246 self.block_env.timestamp()
247 }
248
249 pub fn db_mut(&mut self) -> impl Database<Error = ErasedError> + '_ {
254 &mut *self.internals
255 }
256
257 pub fn load_account(
259 &mut self,
260 address: Address,
261 ) -> Result<StateLoad<&Account>, EvmInternalsError> {
262 self.internals.load_account(address)
263 }
264
265 pub fn load_account_code(
267 &mut self,
268 address: Address,
269 ) -> Result<StateLoad<&Account>, EvmInternalsError> {
270 self.internals.load_account_code(address)
271 }
272
273 pub fn balance_incr(
275 &mut self,
276 address: Address,
277 balance: U256,
278 ) -> Result<(), EvmInternalsError> {
279 self.internals.balance_incr(address, balance)
280 }
281
282 pub fn set_balance(
288 &mut self,
289 address: Address,
290 balance: U256,
291 ) -> Result<(), EvmInternalsError> {
292 self.internals.set_balance(address, balance)
293 }
294
295 pub fn transfer(
299 &mut self,
300 from: Address,
301 to: Address,
302 balance: U256,
303 ) -> Result<Option<TransferError>, EvmInternalsError> {
304 self.internals.transfer(from, to, balance)
305 }
306
307 pub fn bump_nonce(&mut self, address: Address) -> Result<(), EvmInternalsError> {
311 self.internals.bump_nonce(address)
312 }
313
314 pub fn sload(
316 &mut self,
317 address: Address,
318 key: StorageKey,
319 ) -> Result<StateLoad<StorageValue>, EvmInternalsError> {
320 self.internals.sload(address, key)
321 }
322
323 pub fn touch_account(&mut self, address: Address) {
325 self.internals.touch_account(address);
326 }
327
328 pub fn set_code(&mut self, address: Address, code: Bytecode) {
330 self.internals.set_code(address, code);
331 }
332
333 pub fn set_code_with_hash(&mut self, address: Address, code: Bytecode, hash: B256) {
337 self.internals.set_code_with_hash(address, code, hash);
338 }
339
340 pub fn sstore(
342 &mut self,
343 address: Address,
344 key: StorageKey,
345 value: StorageValue,
346 ) -> Result<StateLoad<SStoreResult>, EvmInternalsError> {
347 self.internals.sstore(address, key, value)
348 }
349
350 pub fn log(&mut self, log: Log) {
352 self.internals.log(log);
353 }
354
355 pub fn tload(&mut self, address: Address, key: StorageKey) -> StorageValue {
357 self.internals.tload(address, key)
358 }
359
360 pub fn tstore(&mut self, address: Address, key: StorageKey, value: StorageValue) {
362 self.internals.tstore(address, key, value);
363 }
364}
365
366impl<'a> fmt::Debug for EvmInternals<'a> {
367 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
368 f.debug_struct("EvmInternals")
369 .field("internals", &self.internals)
370 .field("block_env", &"{{}}")
371 .finish_non_exhaustive()
372 }
373}