reth_rpc_eth_types/cache/
db.rs1use alloy_eip7928::{bal::DecodedBal, BlockAccessIndex};
4use reth_revm::database::StateProviderDatabase;
5use reth_storage_api::StateProviderBox;
6use revm::{database::State, state::bal::Bal as RevmBal, Database};
7use std::sync::Arc;
8
9pub type StateCacheDb = State<StateProviderDatabase<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 use super::*;
35 use alloy_primitives::{address, Bytes, U256};
36 use revm::{
37 database::{CacheDB, EmptyDB},
38 state::{
39 bal::{AccountBal, Bal, BalWrites, BlockAccessIndex},
40 AccountInfo,
41 },
42 };
43
44 #[test]
45 fn attach_bal_before_tx_serves_positioned_reads() {
46 let covered = address!("0x0000000000000000000000000000000000000001");
47 let uncovered = address!("0x0000000000000000000000000000000000000002");
48 let written_slot = U256::from(1);
49 let read_slot = U256::from(2);
50
51 let mut db = CacheDB::new(EmptyDB::default());
53 db.insert_account_info(
54 covered,
55 AccountInfo { balance: U256::from(7), nonce: 5, ..Default::default() },
56 );
57 db.insert_account_storage(covered, written_slot, U256::from(11)).unwrap();
58 db.insert_account_storage(covered, read_slot, U256::from(99)).unwrap();
59 db.insert_account_info(
60 uncovered,
61 AccountInfo { balance: U256::from(3), ..Default::default() },
62 );
63
64 let mut account = AccountBal::default();
66 account.storage.storage.insert(
67 written_slot,
68 BalWrites::new(vec![(BlockAccessIndex::from_tx_index(1), U256::from(42))]),
69 );
70 account.account_info.balance =
71 BalWrites::new(vec![(BlockAccessIndex::from_tx_index(2), U256::from(1000))]);
72 let mut bal = Bal::default();
73 bal.accounts.insert(covered, account);
74 let bal = DecodedBal::new(Arc::new(bal), Bytes::new());
75
76 let mut state = State::builder().with_database(db).build();
77
78 attach_bal_before_tx(&mut state, &bal, 0);
80 assert_eq!(Database::storage(&mut state, covered, written_slot).unwrap(), U256::from(11));
81 assert_eq!(Database::basic(&mut state, covered).unwrap().unwrap().balance, U256::from(7));
82
83 attach_bal_before_tx(&mut state, &bal, 2);
85 assert_eq!(Database::storage(&mut state, covered, written_slot).unwrap(), U256::from(42));
86 assert_eq!(Database::basic(&mut state, covered).unwrap().unwrap().balance, U256::from(7));
87
88 attach_bal_before_tx(&mut state, &bal, 3);
90 assert_eq!(
91 Database::basic(&mut state, covered).unwrap().unwrap().balance,
92 U256::from(1000)
93 );
94
95 assert_eq!(Database::storage(&mut state, covered, read_slot).unwrap(), U256::from(99));
97 assert_eq!(Database::basic(&mut state, uncovered).unwrap().unwrap().balance, U256::from(3));
98 }
99}