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