reth_rpc_eth_types/cache/
db.rs1use alloy_eip7928::{bal::DecodedBal, BlockAccessIndex};
4use reth_revm::database::StateProviderDatabase;
5use reth_storage_api::{EvmStateProviderAdapter, StateProviderBox};
6use revm::{database::State, state::bal::Bal as RevmBal, Database};
7use std::sync::Arc;
8
9pub type StateCacheDb = State<StateProviderDatabase<EvmStateProviderAdapter<StateProviderBox>>>;
11
12#[inline]
22pub fn attach_bal_before_tx<DB: Database>(
23 db: &mut State<DB>,
24 bal: &DecodedBal<Arc<RevmBal>>,
25 tx_index: usize,
26) {
27 db.set_bal(Some(bal.as_bal().clone()));
28 db.set_allow_bal_db_fallback(true);
29 db.set_bal_index(BlockAccessIndex::from_tx_index(tx_index as u64));
30}
31
32#[cfg(test)]
33mod tests {
34
35 use super::*;
36 use alloy_primitives::{Address, Bytes, U256};
37 use revm::{
38 database::InMemoryDB,
39 state::{
40 bal::{AccountBal, Bal, BalWrites, BlockAccessIndex},
41 AccountInfo,
42 },
43 };
44
45 #[test]
46 fn attach_bal_before_tx_serves_positioned_reads() {
47 let covered = Address::with_last_byte(1);
48 let uncovered = Address::with_last_byte(2);
49 let written_slot = U256::ONE;
50 let read_slot = U256::from(2);
51
52 let mut db = InMemoryDB::default();
54 db.insert_account_info(
55 covered,
56 AccountInfo { balance: U256::from(7), nonce: 5, ..Default::default() },
57 );
58 db.insert_account_storage(covered, written_slot, U256::from(11)).unwrap();
59 db.insert_account_storage(covered, read_slot, U256::from(99)).unwrap();
60 db.insert_account_info(
61 uncovered,
62 AccountInfo { balance: U256::from(3), ..Default::default() },
63 );
64
65 let mut account = AccountBal::default();
67 account.storage.storage.insert(
68 written_slot,
69 BalWrites::new(vec![(BlockAccessIndex::from_tx_index(1), U256::from(42))]),
70 );
71 account.account_info.balance =
72 BalWrites::new(vec![(BlockAccessIndex::from_tx_index(2), U256::from(1000))]);
73 let mut bal = Bal::default();
74 bal.accounts.insert(covered, account);
75 let bal = DecodedBal::new(Arc::new(bal), Bytes::new());
76
77 let mut state = State::builder().with_database(db).build();
78
79 attach_bal_before_tx(&mut state, &bal, 0);
81 assert_eq!(Database::storage(&mut state, covered, written_slot).unwrap(), U256::from(11));
82 assert_eq!(Database::basic(&mut state, covered).unwrap().unwrap().balance, U256::from(7));
83
84 attach_bal_before_tx(&mut state, &bal, 2);
86 assert_eq!(Database::storage(&mut state, covered, written_slot).unwrap(), U256::from(42));
87 assert_eq!(Database::basic(&mut state, covered).unwrap().unwrap().balance, U256::from(7));
88
89 attach_bal_before_tx(&mut state, &bal, 3);
91 assert_eq!(
92 Database::basic(&mut state, covered).unwrap().unwrap().balance,
93 U256::from(1000)
94 );
95
96 assert_eq!(Database::storage(&mut state, covered, read_slot).unwrap(), U256::from(99));
98 assert_eq!(Database::basic(&mut state, uncovered).unwrap().unwrap().balance, U256::from(3));
99 }
100}