kabu_evm_db/
database_helpers.rs1use crate::fast_cache_db::FastDbAccount;
2use alloy::primitives::map::HashMap;
3use alloy::primitives::{Address, U256};
4use alloy::rpc::types::trace::geth::AccountState;
5use revm::bytecode::Bytecode;
6use revm::state::{Account, EvmStorageSlot};
7use revm::{DatabaseCommit, DatabaseRef};
8use std::collections::BTreeMap;
9use tracing::trace;
10
11pub struct DatabaseHelpers {}
12
13impl DatabaseHelpers {
14 #[inline]
15 pub fn account_db_to_revm(db: FastDbAccount) -> Account {
16 let storage = db.storage.into_iter().map(|(k, v)| (k, EvmStorageSlot::new(v, 0))).collect();
17 Account { info: db.info, storage, status: Default::default(), transaction_id: 0 }
18 }
19
20 #[inline]
21 pub fn trace_update_to_commit_update<DB: DatabaseRef>(db: &DB, update: BTreeMap<Address, AccountState>) -> HashMap<Address, Account> {
22 let mut result: HashMap<Address, Account> = Default::default();
23 for (address, state) in update {
24 trace!(%address, code=state.code.is_some(), storage=state.storage.len(), "trace_update_to_commit_update");
25 if address.is_zero() {
26 continue;
27 }
28 let mut info = db.basic_ref(address).map(|a| a.unwrap_or_default()).unwrap_or_default();
29
30 if let Some(code) = state.code {
31 let code = Bytecode::new_raw(code);
32 let hash = code.hash_slow();
33 info.code_hash = hash;
34 info.code = Some(code);
35 }
36
37 if let Some(nonce) = state.nonce {
38 info.nonce = nonce
39 }
40
41 if let Some(balance) = state.balance {
42 info.balance = balance
43 }
44
45 let storage =
46 state.storage.into_iter().map(|(k, v)| (k.into(), EvmStorageSlot::new_changed(U256::ZERO, v.into(), 0))).collect();
47
48 result.insert(address, Account { info, storage, status: Default::default(), transaction_id: 0 });
49 }
50 result
51 }
52 #[inline]
53 pub fn apply_geth_state_update<DB: DatabaseRef + DatabaseCommit>(db: &mut DB, update: BTreeMap<Address, AccountState>) {
54 let update = Self::trace_update_to_commit_update(db, update);
55 db.commit(update);
56 }
57
58 #[inline]
59 pub fn apply_geth_state_update_vec<DB: DatabaseRef + DatabaseCommit>(db: &mut DB, update_vec: Vec<BTreeMap<Address, AccountState>>) {
60 let mut update_map: HashMap<Address, Account> = Default::default();
61
62 for update in update_vec {
63 let update_record = Self::trace_update_to_commit_update(db, update);
64 update_map.extend(update_record);
65 }
66 db.commit(update_map)
67 }
68}