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