example_database_components/
lib.rs

1//! Database component example.
2#![cfg_attr(not(test), warn(unused_crate_dependencies))]
3
4//! Database that is split on State and BlockHash traits.
5pub mod block_hash;
6pub mod state;
7
8pub use block_hash::{BlockHash, BlockHashRef};
9pub use state::{State, StateRef};
10
11use revm::{
12    database_interface::{DBErrorMarker, Database, DatabaseCommit, DatabaseRef},
13    primitives::{Address, HashMap, StorageKey, StorageValue, B256},
14    state::{Account, AccountInfo, Bytecode},
15};
16
17#[derive(Debug)]
18pub struct DatabaseComponents<S, BH> {
19    pub state: S,
20    pub block_hash: BH,
21}
22
23#[derive(Debug, thiserror::Error)]
24pub enum DatabaseComponentError<SE, BHE> {
25    #[error(transparent)]
26    State(SE),
27    #[error(transparent)]
28    BlockHash(BHE),
29}
30
31impl<SE, BHE> DBErrorMarker for DatabaseComponentError<SE, BHE> {}
32
33impl<S: State, BH: BlockHash> Database for DatabaseComponents<S, BH> {
34    type Error = DatabaseComponentError<S::Error, BH::Error>;
35
36    fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
37        self.state.basic(address).map_err(Self::Error::State)
38    }
39
40    fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> {
41        self.state
42            .code_by_hash(code_hash)
43            .map_err(Self::Error::State)
44    }
45
46    fn storage(
47        &mut self,
48        address: Address,
49        index: StorageKey,
50    ) -> Result<StorageValue, Self::Error> {
51        self.state
52            .storage(address, index)
53            .map_err(Self::Error::State)
54    }
55
56    fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
57        self.block_hash
58            .block_hash(number)
59            .map_err(Self::Error::BlockHash)
60    }
61}
62
63impl<S: StateRef, BH: BlockHashRef> DatabaseRef for DatabaseComponents<S, BH> {
64    type Error = DatabaseComponentError<S::Error, BH::Error>;
65
66    fn basic_ref(&self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
67        self.state.basic(address).map_err(Self::Error::State)
68    }
69
70    fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, Self::Error> {
71        self.state
72            .code_by_hash(code_hash)
73            .map_err(Self::Error::State)
74    }
75
76    fn storage_ref(
77        &self,
78        address: Address,
79        index: StorageKey,
80    ) -> Result<StorageValue, Self::Error> {
81        self.state
82            .storage(address, index)
83            .map_err(Self::Error::State)
84    }
85
86    fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error> {
87        self.block_hash
88            .block_hash(number)
89            .map_err(Self::Error::BlockHash)
90    }
91}
92
93impl<S: DatabaseCommit, BH: BlockHashRef> DatabaseCommit for DatabaseComponents<S, BH> {
94    fn commit(&mut self, changes: HashMap<Address, Account>) {
95        self.state.commit(changes);
96    }
97}