kabu_evm_db/
kabu_db_helper.rs1use crate::error::KabuDBError;
2use alloy::primitives::{Address, B256, BlockNumber, U256};
3use eyre::eyre;
4use revm::DatabaseRef;
5use revm::state::{AccountInfo, Bytecode};
6use tracing::trace;
7
8pub struct KabuDBHelper {}
9
10impl KabuDBHelper {
11 #[inline]
12 pub fn get_code_by_hash<DB: DatabaseRef<Error = KabuDBError>>(
13 read_only_db: &Option<DB>,
14 code_hash: B256,
15 ) -> eyre::Result<Bytecode, KabuDBError> {
16 match read_only_db {
17 Some(read_only_db) => read_only_db.code_by_hash_ref(code_hash),
18 None => Err(KabuDBError::NoDB),
19 }
20 }
21
22 #[inline]
23 fn fetch_storage<ExtDB: DatabaseRef<Error = KabuDBError>>(
24 ext_db: &Option<ExtDB>,
25 address: Address,
26 slot: U256,
27 ) -> Result<U256, KabuDBError> {
28 trace!(%address, %slot, "fetch_storage");
29
30 if let Some(ext_db) = ext_db {
31 let value = ext_db.storage_ref(address, slot).map_err(|_| eyre!("ERROR_READING_ALLOY_DB"));
32 trace!(%address, %slot, ?value , "fetch_storage returned");
33 Ok(value.unwrap_or_default())
34 } else {
35 trace!("fetch_storage returned NO_EXT_DB");
36 Err(KabuDBError::NoDB)
37 }
38 }
39
40 #[inline]
41 pub fn get_or_fetch_storage<DB: DatabaseRef<Error = KabuDBError>, ExtDB: DatabaseRef<Error = KabuDBError>>(
42 read_only_db: &Option<DB>,
43 ext_db: &Option<ExtDB>,
44 address: Address,
45 slot: U256,
46 ) -> Result<U256, KabuDBError> {
47 trace!(%address, %slot, "get_or_fetch_storage");
48
49 match read_only_db {
50 Some(read_only_db) => {
51 let value = read_only_db.storage_ref(address, slot).or_else(|_| Self::fetch_storage(ext_db, address, slot));
52 trace!(%address, %slot, ?value , "get_or_fetch_storage with RO");
53 value
54 }
55 None => {
56 let value = Self::fetch_storage(ext_db, address, slot);
57 trace!(%address, %slot, ?value , "get_or_fetch_storage without RO");
58 value
59 }
60 }
61 }
62
63 #[inline]
64 fn fetch_basic<ExtDB: DatabaseRef<Error = KabuDBError>>(
65 ext_db: &Option<ExtDB>,
66 address: Address,
67 ) -> Result<Option<AccountInfo>, KabuDBError> {
68 trace!(%address, "fetch_basic");
69 if let Some(ext_db) = ext_db { ext_db.basic_ref(address) } else { Err(KabuDBError::NoDB) }
70 }
71
72 #[inline]
73 pub fn get_basic<DB: DatabaseRef<Error = KabuDBError>>(
74 read_only_db: &Option<DB>,
75 address: Address,
76 ) -> eyre::Result<Option<AccountInfo>> {
77 read_only_db
78 .as_ref()
79 .and_then(|db| db.basic_ref(address).ok().flatten())
80 .map_or_else(|| Err(eyre!("NO_ACCOUNT")), |info| Ok(Some(info)))
81 }
82
83 #[inline]
84 pub fn get_or_fetch_basic<DB: DatabaseRef<Error = KabuDBError>, ExtDB: DatabaseRef<Error = KabuDBError>>(
85 read_only_db: &Option<DB>,
86 ext_db: &Option<ExtDB>,
87 address: Address,
88 ) -> Result<Option<AccountInfo>, KabuDBError> {
89 trace!(%address, "get_or_fetch_basic");
90 match &read_only_db {
91 Some(read_only_db) => match read_only_db.basic_ref(address) {
92 Ok(Some(info)) => Ok(Some(info)),
93 _ => Self::fetch_basic(ext_db, address),
94 },
95 None => Self::fetch_basic(ext_db, address),
96 }
97 }
98
99 #[inline]
100 fn fetch_block_hash_ref<ExtDB: DatabaseRef<Error = KabuDBError>>(
101 ext_db: &Option<ExtDB>,
102 number: BlockNumber,
103 ) -> Result<B256, KabuDBError> {
104 if let Some(ext_db) = ext_db { ext_db.block_hash_ref(number) } else { Err(KabuDBError::NoDB) }
105 }
106
107 #[inline]
108 pub fn get_or_fetch_block_hash<DB: DatabaseRef<Error = KabuDBError>, ExtDB: DatabaseRef<Error = KabuDBError>>(
109 read_only_db: &Option<DB>,
110 ext_db: &Option<ExtDB>,
111 number: BlockNumber,
112 ) -> Result<B256, KabuDBError> {
113 match read_only_db {
114 Some(read_only_db) => read_only_db.block_hash_ref(number).or_else(|_| KabuDBHelper::fetch_block_hash_ref(ext_db, number)),
115 None => Self::fetch_block_hash_ref(ext_db, number),
116 }
117 }
118}