revm_database_interface/
empty_db.rs

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