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