revm_database_interface/
lib.rs

1//! Optimism-specific constants, types, and helpers.
2#![cfg_attr(not(test), warn(unused_crate_dependencies))]
3#![cfg_attr(not(feature = "std"), no_std)]
4
5#[cfg(not(feature = "std"))]
6extern crate alloc as std;
7
8use core::convert::Infallible;
9
10use auto_impl::auto_impl;
11use core::error::Error;
12use primitives::{address, Address, HashMap, StorageKey, StorageValue, B256, U256};
13use state::{Account, AccountInfo, Bytecode};
14use std::string::String;
15
16/// Address with all `0xff..ff` in it. Used for testing.
17pub const FFADDRESS: Address = address!("0xffffffffffffffffffffffffffffffffffffffff");
18/// BENCH_TARGET address
19pub const BENCH_TARGET: Address = FFADDRESS;
20/// BENCH_TARGET_BALANCE balance
21pub const BENCH_TARGET_BALANCE: U256 = U256::from_limbs([10_000_000_000_000_000, 0, 0, 0]);
22/// Address with all `0xee..ee` in it. Used for testing.
23pub const EEADDRESS: Address = address!("0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
24/// BENCH_CALLER address
25pub const BENCH_CALLER: Address = EEADDRESS;
26/// BENCH_CALLER_BALANCE balance
27pub const BENCH_CALLER_BALANCE: U256 = U256::from_limbs([10_000_000_000_000_000, 0, 0, 0]);
28
29#[cfg(feature = "asyncdb")]
30pub mod async_db;
31pub mod empty_db;
32pub mod try_commit;
33
34#[cfg(feature = "asyncdb")]
35pub use async_db::{DatabaseAsync, WrapDatabaseAsync};
36pub use empty_db::{EmptyDB, EmptyDBTyped};
37pub use try_commit::{ArcUpgradeError, TryDatabaseCommit};
38
39/// Database error marker is needed to implement From conversion for Error type.
40pub trait DBErrorMarker {}
41
42/// Implement marker for `()`.
43impl DBErrorMarker for () {}
44impl DBErrorMarker for Infallible {}
45impl DBErrorMarker for String {}
46
47/// EVM database interface.
48#[auto_impl(&mut, Box)]
49pub trait Database {
50    /// The database error type.
51    type Error: DBErrorMarker + Error;
52
53    /// Gets basic account information.
54    fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error>;
55
56    /// Gets account code by its hash.
57    fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error>;
58
59    /// Gets storage value of address at index.
60    fn storage(&mut self, address: Address, index: StorageKey)
61        -> Result<StorageValue, Self::Error>;
62
63    /// Gets block hash by block number.
64    fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error>;
65}
66
67/// EVM database commit interface.
68#[auto_impl(&mut, Box)]
69pub trait DatabaseCommit {
70    /// Commit changes to the database.
71    fn commit(&mut self, changes: HashMap<Address, Account>);
72}
73
74/// EVM database interface.
75///
76/// Contains the same methods as [`Database`], but with `&self` receivers instead of `&mut self`.
77///
78/// Use [`WrapDatabaseRef`] to provide [`Database`] implementation for a type
79/// that only implements this trait.
80#[auto_impl(&, &mut, Box, Rc, Arc)]
81pub trait DatabaseRef {
82    /// The database error type.
83    type Error: DBErrorMarker + Error;
84
85    /// Gets basic account information.
86    fn basic_ref(&self, address: Address) -> Result<Option<AccountInfo>, Self::Error>;
87
88    /// Gets account code by its hash.
89    fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, Self::Error>;
90
91    /// Gets storage value of address at index.
92    fn storage_ref(&self, address: Address, index: StorageKey)
93        -> Result<StorageValue, Self::Error>;
94
95    /// Gets block hash by block number.
96    fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error>;
97}
98
99/// Wraps a [`DatabaseRef`] to provide a [`Database`] implementation.
100#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
101pub struct WrapDatabaseRef<T: DatabaseRef>(pub T);
102
103impl<F: DatabaseRef> From<F> for WrapDatabaseRef<F> {
104    #[inline]
105    fn from(f: F) -> Self {
106        WrapDatabaseRef(f)
107    }
108}
109
110impl<T: DatabaseRef> Database for WrapDatabaseRef<T> {
111    type Error = T::Error;
112
113    #[inline]
114    fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
115        self.0.basic_ref(address)
116    }
117
118    #[inline]
119    fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> {
120        self.0.code_by_hash_ref(code_hash)
121    }
122
123    #[inline]
124    fn storage(
125        &mut self,
126        address: Address,
127        index: StorageKey,
128    ) -> Result<StorageValue, Self::Error> {
129        self.0.storage_ref(address, index)
130    }
131
132    #[inline]
133    fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
134        self.0.block_hash_ref(number)
135    }
136}
137
138impl<T: DatabaseRef + DatabaseCommit> DatabaseCommit for WrapDatabaseRef<T> {
139    #[inline]
140    fn commit(&mut self, changes: HashMap<Address, Account>) {
141        self.0.commit(changes)
142    }
143}