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, B256, U256},
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(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> {
47        self.state
48            .storage(address, index)
49            .map_err(Self::Error::State)
50    }
51
52    fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
53        self.block_hash
54            .block_hash(number)
55            .map_err(Self::Error::BlockHash)
56    }
57}
58
59impl<S: StateRef, BH: BlockHashRef> DatabaseRef for DatabaseComponents<S, BH> {
60    type Error = DatabaseComponentError<S::Error, BH::Error>;
61
62    fn basic_ref(&self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
63        self.state.basic(address).map_err(Self::Error::State)
64    }
65
66    fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, Self::Error> {
67        self.state
68            .code_by_hash(code_hash)
69            .map_err(Self::Error::State)
70    }
71
72    fn storage_ref(&self, address: Address, index: U256) -> Result<U256, Self::Error> {
73        self.state
74            .storage(address, index)
75            .map_err(Self::Error::State)
76    }
77
78    fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error> {
79        self.block_hash
80            .block_hash(number)
81            .map_err(Self::Error::BlockHash)
82    }
83}
84
85impl<S: DatabaseCommit, BH: BlockHashRef> DatabaseCommit for DatabaseComponents<S, BH> {
86    fn commit(&mut self, changes: HashMap<Address, Account>) {
87        self.state.commit(changes);
88    }
89}