kabu_evm_db/
kabu_db_helper.rs1use crate::error::KabuDBError;
2use alloy::primitives::{Address, BlockNumber, B256, U256};
3use eyre::eyre;
4use revm::state::{AccountInfo, Bytecode};
5use revm::DatabaseRef;
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 {
70 ext_db.basic_ref(address)
71 } else {
72 Err(KabuDBError::NoDB)
73 }
74 }
75
76 #[inline]
77 pub fn get_basic<DB: DatabaseRef<Error = KabuDBError>>(
78 read_only_db: &Option<DB>,
79 address: Address,
80 ) -> eyre::Result<Option<AccountInfo>> {
81 read_only_db
82 .as_ref()
83 .and_then(|db| db.basic_ref(address).ok().flatten())
84 .map_or_else(|| Err(eyre!("NO_ACCOUNT")), |info| Ok(Some(info)))
85 }
86
87 #[inline]
88 pub fn get_or_fetch_basic<DB: DatabaseRef<Error = KabuDBError>, ExtDB: DatabaseRef<Error = KabuDBError>>(
89 read_only_db: &Option<DB>,
90 ext_db: &Option<ExtDB>,
91 address: Address,
92 ) -> Result<Option<AccountInfo>, KabuDBError> {
93 trace!(%address, "get_or_fetch_basic");
94 match &read_only_db {
95 Some(read_only_db) => match read_only_db.basic_ref(address) {
96 Ok(Some(info)) => Ok(Some(info)),
97 _ => Self::fetch_basic(ext_db, address),
98 },
99 None => Self::fetch_basic(ext_db, address),
100 }
101 }
102
103 #[inline]
104 fn fetch_block_hash_ref<ExtDB: DatabaseRef<Error = KabuDBError>>(
105 ext_db: &Option<ExtDB>,
106 number: BlockNumber,
107 ) -> Result<B256, KabuDBError> {
108 if let Some(ext_db) = ext_db {
109 ext_db.block_hash_ref(number)
110 } else {
111 Err(KabuDBError::NoDB)
112 }
113 }
114
115 #[inline]
116 pub fn get_or_fetch_block_hash<DB: DatabaseRef<Error = KabuDBError>, ExtDB: DatabaseRef<Error = KabuDBError>>(
117 read_only_db: &Option<DB>,
118 ext_db: &Option<ExtDB>,
119 number: BlockNumber,
120 ) -> Result<B256, KabuDBError> {
121 match read_only_db {
122 Some(read_only_db) => read_only_db.block_hash_ref(number).or_else(|_| KabuDBHelper::fetch_block_hash_ref(ext_db, number)),
123 None => Self::fetch_block_hash_ref(ext_db, number),
124 }
125 }
126}