Skip to main content

reth_storage_api/
evm.rs

1//! State access for EVM execution.
2
3use crate::StateProvider;
4use alloc::boxed::Box;
5use alloy_primitives::{Address, BlockNumber, StorageKey, StorageValue, B256};
6use core::ops::Deref;
7use reth_primitives_traits::{Account, Bytecode};
8use reth_storage_errors::provider::ProviderResult;
9
10/// Provides the state necessary for EVM execution.
11#[auto_impl::auto_impl(&, Arc, Box)]
12pub trait EvmStateProvider {
13    /// Returns the account, or `None` if it does not exist.
14    fn basic_account(&self, address: &Address) -> ProviderResult<Option<Account>>;
15
16    /// Returns the block hash, or `None` if the block does not exist.
17    fn block_hash(&self, number: BlockNumber) -> ProviderResult<Option<B256>>;
18
19    /// Returns bytecode by its hash.
20    fn bytecode_by_hash(&self, code_hash: &B256) -> ProviderResult<Option<Bytecode>>;
21
22    /// Returns the storage value of the given account and slot.
23    fn storage(
24        &self,
25        account: Address,
26        storage_key: StorageKey,
27    ) -> ProviderResult<Option<StorageValue>>;
28}
29
30/// Type-erased provider for EVM execution.
31pub type EvmStateProviderBox = Box<dyn EvmStateProvider + Send>;
32
33/// Adapts an owned or borrowed full state provider for EVM execution.
34#[derive(Debug, Clone, Copy)]
35pub struct EvmStateProviderAdapter<P>(pub P);
36
37impl<P> Deref for EvmStateProviderAdapter<P> {
38    type Target = P;
39
40    fn deref(&self) -> &Self::Target {
41        &self.0
42    }
43}
44
45impl<P: StateProvider> EvmStateProvider for EvmStateProviderAdapter<P> {
46    fn basic_account(&self, address: &Address) -> ProviderResult<Option<Account>> {
47        self.0.basic_account(address)
48    }
49
50    fn block_hash(&self, number: BlockNumber) -> ProviderResult<Option<B256>> {
51        self.0.block_hash(number)
52    }
53
54    fn bytecode_by_hash(&self, code_hash: &B256) -> ProviderResult<Option<Bytecode>> {
55        self.0.bytecode_by_hash(code_hash)
56    }
57
58    fn storage(
59        &self,
60        account: Address,
61        storage_key: StorageKey,
62    ) -> ProviderResult<Option<StorageValue>> {
63        self.0.storage(account, storage_key)
64    }
65}