revm_database_interface/
lib.rs

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