revm_database_interface/
empty_db.rs

1//! Empty database implementation.
2use crate::{DBErrorMarker, Database, DatabaseRef};
3use core::error::Error;
4use core::{convert::Infallible, fmt, marker::PhantomData};
5use primitives::{keccak256, Address, StorageKey, StorageValue, B256};
6use state::{AccountInfo, Bytecode};
7use std::string::ToString;
8
9/// An empty database that always returns default values when queried
10pub type EmptyDB = EmptyDBTyped<Infallible>;
11
12/// An empty database that always returns default values when queried
13///
14/// This is generic over a type which is used as the database error type.
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16pub struct EmptyDBTyped<E> {
17    _phantom: PhantomData<E>,
18}
19
20// Don't derive traits, because the type parameter is unused.
21impl<E> Clone for EmptyDBTyped<E> {
22    fn clone(&self) -> Self {
23        *self
24    }
25}
26
27impl<E> Copy for EmptyDBTyped<E> {}
28
29impl<E> Default for EmptyDBTyped<E> {
30    fn default() -> Self {
31        Self::new()
32    }
33}
34
35impl<E> fmt::Debug for EmptyDBTyped<E> {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        f.debug_struct("EmptyDB").finish_non_exhaustive()
38    }
39}
40
41impl<E> PartialEq for EmptyDBTyped<E> {
42    fn eq(&self, _: &Self) -> bool {
43        true
44    }
45}
46
47impl<E> Eq for EmptyDBTyped<E> {}
48
49impl<E> EmptyDBTyped<E> {
50    /// Create a new empty database.
51    pub fn new() -> Self {
52        Self {
53            _phantom: PhantomData,
54        }
55    }
56}
57
58impl<E: DBErrorMarker + Error> Database for EmptyDBTyped<E> {
59    type Error = E;
60
61    #[inline]
62    fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
63        <Self as DatabaseRef>::basic_ref(self, address)
64    }
65
66    #[inline]
67    fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> {
68        <Self as DatabaseRef>::code_by_hash_ref(self, code_hash)
69    }
70
71    #[inline]
72    fn storage(
73        &mut self,
74        address: Address,
75        index: StorageKey,
76    ) -> Result<StorageValue, Self::Error> {
77        <Self as DatabaseRef>::storage_ref(self, address, index)
78    }
79
80    #[inline]
81    fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
82        <Self as DatabaseRef>::block_hash_ref(self, number)
83    }
84}
85
86impl<E: DBErrorMarker + Error> DatabaseRef for EmptyDBTyped<E> {
87    type Error = E;
88
89    #[inline]
90    fn basic_ref(&self, _address: Address) -> Result<Option<AccountInfo>, Self::Error> {
91        Ok(None)
92    }
93
94    #[inline]
95    fn code_by_hash_ref(&self, _code_hash: B256) -> Result<Bytecode, Self::Error> {
96        Ok(Bytecode::default())
97    }
98
99    #[inline]
100    fn storage_ref(
101        &self,
102        _address: Address,
103        _index: StorageKey,
104    ) -> Result<StorageValue, Self::Error> {
105        Ok(StorageValue::default())
106    }
107
108    #[inline]
109    fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error> {
110        Ok(keccak256(number.to_string().as_bytes()))
111    }
112}
113
114#[cfg(test)]
115mod tests {
116    use super::*;
117    use primitives::b256;
118
119    #[test]
120    fn conform_block_hash_calculation() {
121        let db = EmptyDB::new();
122        assert_eq!(
123            db.block_hash_ref(0u64),
124            Ok(b256!(
125                "0x044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d"
126            ))
127        );
128
129        assert_eq!(
130            db.block_hash_ref(1u64),
131            Ok(b256!(
132                "0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6"
133            ))
134        );
135
136        assert_eq!(
137            db.block_hash_ref(100u64),
138            Ok(b256!(
139                "0x8c18210df0d9514f2d2e5d8ca7c100978219ee80d3968ad850ab5ead208287b3"
140            ))
141        );
142    }
143}