rtvm_primitives/
db.rs

1use crate::{Account, AccountInfo, Address, Bytecode, HashMap, B256, U256};
2use auto_impl::auto_impl;
3
4pub mod components;
5pub use components::{
6    BlockHash, BlockHashRef, DatabaseComponentError, DatabaseComponents, State, StateRef,
7};
8
9/// EVM database interface.
10#[auto_impl(&mut, Box)]
11pub trait Database {
12    /// The database error type.
13    type Error;
14
15    /// Get basic account information.
16    fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error>;
17
18    /// Get account code by its hash.
19    fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error>;
20
21    /// Get storage value of address at index.
22    fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error>;
23
24    /// Get block hash by block number.
25    fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error>;
26}
27
28/// EVM database commit interface.
29#[auto_impl(&mut, Box)]
30pub trait DatabaseCommit {
31    /// Commit changes to the database.
32    fn commit(&mut self, changes: HashMap<Address, Account>);
33}
34
35/// EVM database interface.
36///
37/// Contains the same methods as [`Database`], but with `&self` receivers instead of `&mut self`.
38///
39/// Use [`WrapDatabaseRef`] to provide [`Database`] implementation for a type
40/// that only implements this trait.
41#[auto_impl(&, &mut, Box, Rc, Arc)]
42pub trait DatabaseRef {
43    /// The database error type.
44    type Error;
45
46    /// Get basic account information.
47    fn basic_ref(&self, address: Address) -> Result<Option<AccountInfo>, Self::Error>;
48
49    /// Get account code by its hash.
50    fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, Self::Error>;
51
52    /// Get storage value of address at index.
53    fn storage_ref(&self, address: Address, index: U256) -> Result<U256, Self::Error>;
54
55    /// Get block hash by block number.
56    fn block_hash_ref(&self, number: U256) -> Result<B256, Self::Error>;
57}
58
59/// Wraps a [`DatabaseRef`] to provide a [`Database`] implementation.
60#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
61pub struct WrapDatabaseRef<T: DatabaseRef>(pub T);
62
63impl<F: DatabaseRef> From<F> for WrapDatabaseRef<F> {
64    #[inline]
65    fn from(f: F) -> Self {
66        WrapDatabaseRef(f)
67    }
68}
69
70pub trait DatabaseWithDebugError: Database
71where
72    <Self as Database>::Error: std::fmt::Debug + std::fmt::Display,
73{
74}
75
76impl<T: DatabaseRef> Database for WrapDatabaseRef<T> {
77    type Error = T::Error;
78
79    #[inline]
80    fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
81        self.0.basic_ref(address)
82    }
83
84    #[inline]
85    fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> {
86        self.0.code_by_hash_ref(code_hash)
87    }
88
89    #[inline]
90    fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> {
91        self.0.storage_ref(address, index)
92    }
93
94    #[inline]
95    fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
96        self.0.block_hash_ref(number)
97    }
98}
99
100impl<T: DatabaseRef + DatabaseCommit> DatabaseCommit for WrapDatabaseRef<T> {
101    #[inline]
102    fn commit(&mut self, changes: HashMap<Address, Account>) {
103        self.0.commit(changes)
104    }
105}
106
107/// Wraps a `dyn DatabaseRef` to provide a [`Database`] implementation.
108#[doc(hidden)]
109#[deprecated = "use `WrapDatabaseRef` instead"]
110pub struct RefDBWrapper<'a, E> {
111    pub db: &'a dyn DatabaseRef<Error = E>,
112}
113
114#[allow(deprecated)]
115impl<'a, E> RefDBWrapper<'a, E> {
116    #[inline]
117    pub fn new(db: &'a dyn DatabaseRef<Error = E>) -> Self {
118        Self { db }
119    }
120}
121
122#[allow(deprecated)]
123impl<'a, E> Database for RefDBWrapper<'a, E> {
124    type Error = E;
125
126    #[inline]
127    fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
128        self.db.basic_ref(address)
129    }
130
131    #[inline]
132    fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> {
133        self.db.code_by_hash_ref(code_hash)
134    }
135
136    #[inline]
137    fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> {
138        self.db.storage_ref(address, index)
139    }
140
141    #[inline]
142    fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
143        self.db.block_hash_ref(number)
144    }
145}