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