diff --git a/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs b/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs index 6a4bdf7ea..ba98104d8 100644 --- a/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs +++ b/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs @@ -376,6 +376,7 @@ mod tests { use crate::{AccountReader, BundleStateWithReceipts, ProviderFactory}; use reth_db::{ cursor::{DbCursorRO, DbDupCursorRO}, + database::Database, models::{AccountBeforeTx, BlockNumberAddress}, tables, test_utils::create_test_rw_db, @@ -384,6 +385,7 @@ mod tests { use reth_primitives::{ revm::compat::into_reth_acc, Address, Receipt, Receipts, StorageEntry, B256, MAINNET, U256, }; + use reth_trie::test_utils::state_root; use revm::{ db::{ states::{ @@ -391,13 +393,15 @@ mod tests { changes::PlainStorageRevert, PlainStorageChangeset, }, - BundleState, + BundleState, EmptyDB, }, primitives::{ - Account, AccountInfo as RevmAccountInfo, AccountStatus, HashMap, StorageSlot, + Account as RevmAccount, AccountInfo as RevmAccountInfo, AccountStatus, HashMap, + StorageSlot, }, - CacheState, DatabaseCommit, State, + DatabaseCommit, State, }; + use std::collections::BTreeMap; #[test] fn write_to_db_account_info() { @@ -413,16 +417,14 @@ mod tests { let account_b_changed = RevmAccountInfo { balance: U256::from(3), nonce: 3, ..Default::default() }; - let mut cache_state = CacheState::new(true); - cache_state.insert_not_existing(address_a); - cache_state.insert_account(address_b, account_b.clone()); - let mut state = - State::builder().with_cached_prestate(cache_state).with_bundle_update().build(); + let mut state = State::builder().with_bundle_update().build(); + state.insert_not_existing(address_a); + state.insert_account(address_b, account_b.clone()); // 0x00.. is created state.commit(HashMap::from([( address_a, - Account { + RevmAccount { info: account_a.clone(), status: AccountStatus::Touched | AccountStatus::Created, storage: HashMap::default(), @@ -432,7 +434,7 @@ mod tests { // 0xff.. is changed (balance + 1, nonce + 1) state.commit(HashMap::from([( address_b, - Account { + RevmAccount { info: account_b_changed.clone(), status: AccountStatus::Touched, storage: HashMap::default(), @@ -488,15 +490,13 @@ mod tests { "Account B changeset is wrong" ); - let mut cache_state = CacheState::new(true); - cache_state.insert_account(address_b, account_b_changed.clone()); - let mut state = - State::builder().with_cached_prestate(cache_state).with_bundle_update().build(); + let mut state = State::builder().with_bundle_update().build(); + state.insert_account(address_b, account_b_changed.clone()); // 0xff.. is destroyed state.commit(HashMap::from([( address_b, - Account { + RevmAccount { status: AccountStatus::Touched | AccountStatus::SelfDestructed, info: account_b_changed, storage: HashMap::default(), @@ -553,20 +553,18 @@ mod tests { let account_b = RevmAccountInfo { balance: U256::from(2), nonce: 2, ..Default::default() }; - let mut cache_state = CacheState::new(true); - cache_state.insert_not_existing(address_a); - cache_state.insert_account_with_storage( + let mut state = State::builder().with_bundle_update().build(); + state.insert_not_existing(address_a); + state.insert_account_with_storage( address_b, account_b.clone(), HashMap::from([(U256::from(1), U256::from(1))]), ); - let mut state = - State::builder().with_cached_prestate(cache_state).with_bundle_update().build(); state.commit(HashMap::from([ ( address_a, - Account { + RevmAccount { status: AccountStatus::Touched | AccountStatus::Created, info: RevmAccountInfo::default(), // 0x00 => 0 => 1 @@ -585,7 +583,7 @@ mod tests { ), ( address_b, - Account { + RevmAccount { status: AccountStatus::Touched, info: account_b, // 0x01 => 1 => 2 @@ -687,14 +685,12 @@ mod tests { ); // Delete account A - let mut cache_state = CacheState::new(true); - cache_state.insert_account(address_a, RevmAccountInfo::default()); - let mut state = - State::builder().with_cached_prestate(cache_state).with_bundle_update().build(); + let mut state = State::builder().with_bundle_update().build(); + state.insert_account(address_a, RevmAccountInfo::default()); state.commit(HashMap::from([( address_a, - Account { + RevmAccount { status: AccountStatus::Touched | AccountStatus::SelfDestructed, info: RevmAccountInfo::default(), storage: HashMap::default(), @@ -745,13 +741,11 @@ mod tests { let account_info = RevmAccountInfo { nonce: 1, ..Default::default() }; // Block #0: initial state. - let mut cache_state = CacheState::new(true); - cache_state.insert_not_existing(address1); - let mut init_state = - State::builder().with_cached_prestate(cache_state).with_bundle_update().build(); + let mut init_state = State::builder().with_bundle_update().build(); + init_state.insert_not_existing(address1); init_state.commit(HashMap::from([( address1, - Account { + RevmAccount { info: account_info.clone(), status: AccountStatus::Touched | AccountStatus::Created, // 0x00 => 0 => 1 @@ -773,19 +767,17 @@ mod tests { .write_to_db(provider.tx_ref(), OriginalValuesKnown::Yes) .expect("Could not write init bundle state to DB"); - let mut cache_state = CacheState::new(true); - cache_state.insert_account_with_storage( + let mut state = State::builder().with_bundle_update().build(); + state.insert_account_with_storage( address1, account_info.clone(), HashMap::from([(U256::ZERO, U256::from(1)), (U256::from(1), U256::from(2))]), ); - let mut state = - State::builder().with_cached_prestate(cache_state).with_bundle_update().build(); // Block #1: change storage. state.commit(HashMap::from([( address1, - Account { + RevmAccount { status: AccountStatus::Touched, info: account_info.clone(), // 0x00 => 1 => 2 @@ -803,7 +795,7 @@ mod tests { // Block #2: destroy account. state.commit(HashMap::from([( address1, - Account { + RevmAccount { status: AccountStatus::Touched | AccountStatus::SelfDestructed, info: account_info.clone(), storage: HashMap::default(), @@ -814,7 +806,7 @@ mod tests { // Block #3: re-create account and change storage. state.commit(HashMap::from([( address1, - Account { + RevmAccount { status: AccountStatus::Touched | AccountStatus::Created, info: account_info.clone(), storage: HashMap::default(), @@ -825,7 +817,7 @@ mod tests { // Block #4: change storage. state.commit(HashMap::from([( address1, - Account { + RevmAccount { status: AccountStatus::Touched, info: account_info.clone(), // 0x00 => 0 => 2 @@ -852,7 +844,7 @@ mod tests { // Block #5: Destroy account again. state.commit(HashMap::from([( address1, - Account { + RevmAccount { status: AccountStatus::Touched | AccountStatus::SelfDestructed, info: account_info.clone(), storage: HashMap::default(), @@ -863,7 +855,7 @@ mod tests { // Block #6: Create, change, destroy and re-create in the same block. state.commit(HashMap::from([( address1, - Account { + RevmAccount { status: AccountStatus::Touched | AccountStatus::Created, info: account_info.clone(), storage: HashMap::default(), @@ -871,7 +863,7 @@ mod tests { )])); state.commit(HashMap::from([( address1, - Account { + RevmAccount { status: AccountStatus::Touched, info: account_info.clone(), // 0x00 => 0 => 2 @@ -883,7 +875,7 @@ mod tests { )])); state.commit(HashMap::from([( address1, - Account { + RevmAccount { status: AccountStatus::Touched | AccountStatus::SelfDestructed, info: account_info.clone(), storage: HashMap::default(), @@ -891,7 +883,7 @@ mod tests { )])); state.commit(HashMap::from([( address1, - Account { + RevmAccount { status: AccountStatus::Touched | AccountStatus::Created, info: account_info.clone(), storage: HashMap::default(), @@ -902,7 +894,7 @@ mod tests { // Block #7: Change storage. state.commit(HashMap::from([( address1, - Account { + RevmAccount { status: AccountStatus::Touched, info: account_info.clone(), // 0x00 => 0 => 9 @@ -1058,13 +1050,11 @@ mod tests { let account1 = RevmAccountInfo { nonce: 1, ..Default::default() }; // Block #0: initial state. - let mut cache_state = CacheState::new(true); - cache_state.insert_not_existing(address1); - let mut init_state = - State::builder().with_cached_prestate(cache_state).with_bundle_update().build(); + let mut init_state = State::builder().with_bundle_update().build(); + init_state.insert_not_existing(address1); init_state.commit(HashMap::from([( address1, - Account { + RevmAccount { info: account1.clone(), status: AccountStatus::Touched | AccountStatus::Created, // 0x00 => 0 => 1 @@ -1086,19 +1076,17 @@ mod tests { .write_to_db(provider.tx_ref(), OriginalValuesKnown::Yes) .expect("Could not write init bundle state to DB"); - let mut cache_state = CacheState::new(true); - cache_state.insert_account_with_storage( + let mut state = State::builder().with_bundle_update().build(); + state.insert_account_with_storage( address1, account1.clone(), HashMap::from([(U256::ZERO, U256::from(1)), (U256::from(1), U256::from(2))]), ); - let mut state = - State::builder().with_cached_prestate(cache_state).with_bundle_update().build(); // Block #1: Destroy, re-create, change storage. state.commit(HashMap::from([( address1, - Account { + RevmAccount { status: AccountStatus::Touched | AccountStatus::SelfDestructed, info: account1.clone(), storage: HashMap::default(), @@ -1107,7 +1095,7 @@ mod tests { state.commit(HashMap::from([( address1, - Account { + RevmAccount { status: AccountStatus::Touched | AccountStatus::Created, info: account1.clone(), storage: HashMap::default(), @@ -1116,7 +1104,7 @@ mod tests { state.commit(HashMap::from([( address1, - Account { + RevmAccount { status: AccountStatus::Touched, info: account1.clone(), // 0x01 => 0 => 5 @@ -1185,4 +1173,168 @@ mod tests { assert!(!this.revert_to(17)); assert_eq!(this.receipts.len(), 7); } + + #[test] + fn bundle_state_state_root() { + type PreState = BTreeMap
)>; + let mut prestate: PreState = (0..10) + .map(|key| { + let account = Account { nonce: 1, balance: U256::from(key), bytecode_hash: None }; + let storage = + (1..11).map(|key| (B256::with_last_byte(key), U256::from(key))).collect(); + (Address::with_last_byte(key), (account, storage)) + }) + .collect(); + + let db = create_test_rw_db(); + + // insert initial state to the database + db.update(|tx| { + for (address, (account, storage)) in prestate.iter() { + let hashed_address = keccak256(address); + tx.put::