mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
test(state): in-memory state root (#5226)
This commit is contained in:
@ -376,6 +376,7 @@ mod tests {
|
|||||||
use crate::{AccountReader, BundleStateWithReceipts, ProviderFactory};
|
use crate::{AccountReader, BundleStateWithReceipts, ProviderFactory};
|
||||||
use reth_db::{
|
use reth_db::{
|
||||||
cursor::{DbCursorRO, DbDupCursorRO},
|
cursor::{DbCursorRO, DbDupCursorRO},
|
||||||
|
database::Database,
|
||||||
models::{AccountBeforeTx, BlockNumberAddress},
|
models::{AccountBeforeTx, BlockNumberAddress},
|
||||||
tables,
|
tables,
|
||||||
test_utils::create_test_rw_db,
|
test_utils::create_test_rw_db,
|
||||||
@ -384,6 +385,7 @@ mod tests {
|
|||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
revm::compat::into_reth_acc, Address, Receipt, Receipts, StorageEntry, B256, MAINNET, U256,
|
revm::compat::into_reth_acc, Address, Receipt, Receipts, StorageEntry, B256, MAINNET, U256,
|
||||||
};
|
};
|
||||||
|
use reth_trie::test_utils::state_root;
|
||||||
use revm::{
|
use revm::{
|
||||||
db::{
|
db::{
|
||||||
states::{
|
states::{
|
||||||
@ -391,13 +393,15 @@ mod tests {
|
|||||||
changes::PlainStorageRevert,
|
changes::PlainStorageRevert,
|
||||||
PlainStorageChangeset,
|
PlainStorageChangeset,
|
||||||
},
|
},
|
||||||
BundleState,
|
BundleState, EmptyDB,
|
||||||
},
|
},
|
||||||
primitives::{
|
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]
|
#[test]
|
||||||
fn write_to_db_account_info() {
|
fn write_to_db_account_info() {
|
||||||
@ -413,16 +417,14 @@ mod tests {
|
|||||||
let account_b_changed =
|
let account_b_changed =
|
||||||
RevmAccountInfo { balance: U256::from(3), nonce: 3, ..Default::default() };
|
RevmAccountInfo { balance: U256::from(3), nonce: 3, ..Default::default() };
|
||||||
|
|
||||||
let mut cache_state = CacheState::new(true);
|
let mut state = State::builder().with_bundle_update().build();
|
||||||
cache_state.insert_not_existing(address_a);
|
state.insert_not_existing(address_a);
|
||||||
cache_state.insert_account(address_b, account_b.clone());
|
state.insert_account(address_b, account_b.clone());
|
||||||
let mut state =
|
|
||||||
State::builder().with_cached_prestate(cache_state).with_bundle_update().build();
|
|
||||||
|
|
||||||
// 0x00.. is created
|
// 0x00.. is created
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address_a,
|
address_a,
|
||||||
Account {
|
RevmAccount {
|
||||||
info: account_a.clone(),
|
info: account_a.clone(),
|
||||||
status: AccountStatus::Touched | AccountStatus::Created,
|
status: AccountStatus::Touched | AccountStatus::Created,
|
||||||
storage: HashMap::default(),
|
storage: HashMap::default(),
|
||||||
@ -432,7 +434,7 @@ mod tests {
|
|||||||
// 0xff.. is changed (balance + 1, nonce + 1)
|
// 0xff.. is changed (balance + 1, nonce + 1)
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address_b,
|
address_b,
|
||||||
Account {
|
RevmAccount {
|
||||||
info: account_b_changed.clone(),
|
info: account_b_changed.clone(),
|
||||||
status: AccountStatus::Touched,
|
status: AccountStatus::Touched,
|
||||||
storage: HashMap::default(),
|
storage: HashMap::default(),
|
||||||
@ -488,15 +490,13 @@ mod tests {
|
|||||||
"Account B changeset is wrong"
|
"Account B changeset is wrong"
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut cache_state = CacheState::new(true);
|
let mut state = State::builder().with_bundle_update().build();
|
||||||
cache_state.insert_account(address_b, account_b_changed.clone());
|
state.insert_account(address_b, account_b_changed.clone());
|
||||||
let mut state =
|
|
||||||
State::builder().with_cached_prestate(cache_state).with_bundle_update().build();
|
|
||||||
|
|
||||||
// 0xff.. is destroyed
|
// 0xff.. is destroyed
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address_b,
|
address_b,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched | AccountStatus::SelfDestructed,
|
status: AccountStatus::Touched | AccountStatus::SelfDestructed,
|
||||||
info: account_b_changed,
|
info: account_b_changed,
|
||||||
storage: HashMap::default(),
|
storage: HashMap::default(),
|
||||||
@ -553,20 +553,18 @@ mod tests {
|
|||||||
|
|
||||||
let account_b = RevmAccountInfo { balance: U256::from(2), nonce: 2, ..Default::default() };
|
let account_b = RevmAccountInfo { balance: U256::from(2), nonce: 2, ..Default::default() };
|
||||||
|
|
||||||
let mut cache_state = CacheState::new(true);
|
let mut state = State::builder().with_bundle_update().build();
|
||||||
cache_state.insert_not_existing(address_a);
|
state.insert_not_existing(address_a);
|
||||||
cache_state.insert_account_with_storage(
|
state.insert_account_with_storage(
|
||||||
address_b,
|
address_b,
|
||||||
account_b.clone(),
|
account_b.clone(),
|
||||||
HashMap::from([(U256::from(1), U256::from(1))]),
|
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([
|
state.commit(HashMap::from([
|
||||||
(
|
(
|
||||||
address_a,
|
address_a,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched | AccountStatus::Created,
|
status: AccountStatus::Touched | AccountStatus::Created,
|
||||||
info: RevmAccountInfo::default(),
|
info: RevmAccountInfo::default(),
|
||||||
// 0x00 => 0 => 1
|
// 0x00 => 0 => 1
|
||||||
@ -585,7 +583,7 @@ mod tests {
|
|||||||
),
|
),
|
||||||
(
|
(
|
||||||
address_b,
|
address_b,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched,
|
status: AccountStatus::Touched,
|
||||||
info: account_b,
|
info: account_b,
|
||||||
// 0x01 => 1 => 2
|
// 0x01 => 1 => 2
|
||||||
@ -687,14 +685,12 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Delete account A
|
// Delete account A
|
||||||
let mut cache_state = CacheState::new(true);
|
let mut state = State::builder().with_bundle_update().build();
|
||||||
cache_state.insert_account(address_a, RevmAccountInfo::default());
|
state.insert_account(address_a, RevmAccountInfo::default());
|
||||||
let mut state =
|
|
||||||
State::builder().with_cached_prestate(cache_state).with_bundle_update().build();
|
|
||||||
|
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address_a,
|
address_a,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched | AccountStatus::SelfDestructed,
|
status: AccountStatus::Touched | AccountStatus::SelfDestructed,
|
||||||
info: RevmAccountInfo::default(),
|
info: RevmAccountInfo::default(),
|
||||||
storage: HashMap::default(),
|
storage: HashMap::default(),
|
||||||
@ -745,13 +741,11 @@ mod tests {
|
|||||||
let account_info = RevmAccountInfo { nonce: 1, ..Default::default() };
|
let account_info = RevmAccountInfo { nonce: 1, ..Default::default() };
|
||||||
|
|
||||||
// Block #0: initial state.
|
// Block #0: initial state.
|
||||||
let mut cache_state = CacheState::new(true);
|
let mut init_state = State::builder().with_bundle_update().build();
|
||||||
cache_state.insert_not_existing(address1);
|
init_state.insert_not_existing(address1);
|
||||||
let mut init_state =
|
|
||||||
State::builder().with_cached_prestate(cache_state).with_bundle_update().build();
|
|
||||||
init_state.commit(HashMap::from([(
|
init_state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
info: account_info.clone(),
|
info: account_info.clone(),
|
||||||
status: AccountStatus::Touched | AccountStatus::Created,
|
status: AccountStatus::Touched | AccountStatus::Created,
|
||||||
// 0x00 => 0 => 1
|
// 0x00 => 0 => 1
|
||||||
@ -773,19 +767,17 @@ mod tests {
|
|||||||
.write_to_db(provider.tx_ref(), OriginalValuesKnown::Yes)
|
.write_to_db(provider.tx_ref(), OriginalValuesKnown::Yes)
|
||||||
.expect("Could not write init bundle state to DB");
|
.expect("Could not write init bundle state to DB");
|
||||||
|
|
||||||
let mut cache_state = CacheState::new(true);
|
let mut state = State::builder().with_bundle_update().build();
|
||||||
cache_state.insert_account_with_storage(
|
state.insert_account_with_storage(
|
||||||
address1,
|
address1,
|
||||||
account_info.clone(),
|
account_info.clone(),
|
||||||
HashMap::from([(U256::ZERO, U256::from(1)), (U256::from(1), U256::from(2))]),
|
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.
|
// Block #1: change storage.
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched,
|
status: AccountStatus::Touched,
|
||||||
info: account_info.clone(),
|
info: account_info.clone(),
|
||||||
// 0x00 => 1 => 2
|
// 0x00 => 1 => 2
|
||||||
@ -803,7 +795,7 @@ mod tests {
|
|||||||
// Block #2: destroy account.
|
// Block #2: destroy account.
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched | AccountStatus::SelfDestructed,
|
status: AccountStatus::Touched | AccountStatus::SelfDestructed,
|
||||||
info: account_info.clone(),
|
info: account_info.clone(),
|
||||||
storage: HashMap::default(),
|
storage: HashMap::default(),
|
||||||
@ -814,7 +806,7 @@ mod tests {
|
|||||||
// Block #3: re-create account and change storage.
|
// Block #3: re-create account and change storage.
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched | AccountStatus::Created,
|
status: AccountStatus::Touched | AccountStatus::Created,
|
||||||
info: account_info.clone(),
|
info: account_info.clone(),
|
||||||
storage: HashMap::default(),
|
storage: HashMap::default(),
|
||||||
@ -825,7 +817,7 @@ mod tests {
|
|||||||
// Block #4: change storage.
|
// Block #4: change storage.
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched,
|
status: AccountStatus::Touched,
|
||||||
info: account_info.clone(),
|
info: account_info.clone(),
|
||||||
// 0x00 => 0 => 2
|
// 0x00 => 0 => 2
|
||||||
@ -852,7 +844,7 @@ mod tests {
|
|||||||
// Block #5: Destroy account again.
|
// Block #5: Destroy account again.
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched | AccountStatus::SelfDestructed,
|
status: AccountStatus::Touched | AccountStatus::SelfDestructed,
|
||||||
info: account_info.clone(),
|
info: account_info.clone(),
|
||||||
storage: HashMap::default(),
|
storage: HashMap::default(),
|
||||||
@ -863,7 +855,7 @@ mod tests {
|
|||||||
// Block #6: Create, change, destroy and re-create in the same block.
|
// Block #6: Create, change, destroy and re-create in the same block.
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched | AccountStatus::Created,
|
status: AccountStatus::Touched | AccountStatus::Created,
|
||||||
info: account_info.clone(),
|
info: account_info.clone(),
|
||||||
storage: HashMap::default(),
|
storage: HashMap::default(),
|
||||||
@ -871,7 +863,7 @@ mod tests {
|
|||||||
)]));
|
)]));
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched,
|
status: AccountStatus::Touched,
|
||||||
info: account_info.clone(),
|
info: account_info.clone(),
|
||||||
// 0x00 => 0 => 2
|
// 0x00 => 0 => 2
|
||||||
@ -883,7 +875,7 @@ mod tests {
|
|||||||
)]));
|
)]));
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched | AccountStatus::SelfDestructed,
|
status: AccountStatus::Touched | AccountStatus::SelfDestructed,
|
||||||
info: account_info.clone(),
|
info: account_info.clone(),
|
||||||
storage: HashMap::default(),
|
storage: HashMap::default(),
|
||||||
@ -891,7 +883,7 @@ mod tests {
|
|||||||
)]));
|
)]));
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched | AccountStatus::Created,
|
status: AccountStatus::Touched | AccountStatus::Created,
|
||||||
info: account_info.clone(),
|
info: account_info.clone(),
|
||||||
storage: HashMap::default(),
|
storage: HashMap::default(),
|
||||||
@ -902,7 +894,7 @@ mod tests {
|
|||||||
// Block #7: Change storage.
|
// Block #7: Change storage.
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched,
|
status: AccountStatus::Touched,
|
||||||
info: account_info.clone(),
|
info: account_info.clone(),
|
||||||
// 0x00 => 0 => 9
|
// 0x00 => 0 => 9
|
||||||
@ -1058,13 +1050,11 @@ mod tests {
|
|||||||
let account1 = RevmAccountInfo { nonce: 1, ..Default::default() };
|
let account1 = RevmAccountInfo { nonce: 1, ..Default::default() };
|
||||||
|
|
||||||
// Block #0: initial state.
|
// Block #0: initial state.
|
||||||
let mut cache_state = CacheState::new(true);
|
let mut init_state = State::builder().with_bundle_update().build();
|
||||||
cache_state.insert_not_existing(address1);
|
init_state.insert_not_existing(address1);
|
||||||
let mut init_state =
|
|
||||||
State::builder().with_cached_prestate(cache_state).with_bundle_update().build();
|
|
||||||
init_state.commit(HashMap::from([(
|
init_state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
info: account1.clone(),
|
info: account1.clone(),
|
||||||
status: AccountStatus::Touched | AccountStatus::Created,
|
status: AccountStatus::Touched | AccountStatus::Created,
|
||||||
// 0x00 => 0 => 1
|
// 0x00 => 0 => 1
|
||||||
@ -1086,19 +1076,17 @@ mod tests {
|
|||||||
.write_to_db(provider.tx_ref(), OriginalValuesKnown::Yes)
|
.write_to_db(provider.tx_ref(), OriginalValuesKnown::Yes)
|
||||||
.expect("Could not write init bundle state to DB");
|
.expect("Could not write init bundle state to DB");
|
||||||
|
|
||||||
let mut cache_state = CacheState::new(true);
|
let mut state = State::builder().with_bundle_update().build();
|
||||||
cache_state.insert_account_with_storage(
|
state.insert_account_with_storage(
|
||||||
address1,
|
address1,
|
||||||
account1.clone(),
|
account1.clone(),
|
||||||
HashMap::from([(U256::ZERO, U256::from(1)), (U256::from(1), U256::from(2))]),
|
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.
|
// Block #1: Destroy, re-create, change storage.
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched | AccountStatus::SelfDestructed,
|
status: AccountStatus::Touched | AccountStatus::SelfDestructed,
|
||||||
info: account1.clone(),
|
info: account1.clone(),
|
||||||
storage: HashMap::default(),
|
storage: HashMap::default(),
|
||||||
@ -1107,7 +1095,7 @@ mod tests {
|
|||||||
|
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched | AccountStatus::Created,
|
status: AccountStatus::Touched | AccountStatus::Created,
|
||||||
info: account1.clone(),
|
info: account1.clone(),
|
||||||
storage: HashMap::default(),
|
storage: HashMap::default(),
|
||||||
@ -1116,7 +1104,7 @@ mod tests {
|
|||||||
|
|
||||||
state.commit(HashMap::from([(
|
state.commit(HashMap::from([(
|
||||||
address1,
|
address1,
|
||||||
Account {
|
RevmAccount {
|
||||||
status: AccountStatus::Touched,
|
status: AccountStatus::Touched,
|
||||||
info: account1.clone(),
|
info: account1.clone(),
|
||||||
// 0x01 => 0 => 5
|
// 0x01 => 0 => 5
|
||||||
@ -1185,4 +1173,168 @@ mod tests {
|
|||||||
assert!(!this.revert_to(17));
|
assert!(!this.revert_to(17));
|
||||||
assert_eq!(this.receipts.len(), 7);
|
assert_eq!(this.receipts.len(), 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bundle_state_state_root() {
|
||||||
|
type PreState = BTreeMap<Address, (Account, BTreeMap<B256, U256>)>;
|
||||||
|
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::<tables::HashedAccount>(hashed_address, *account).unwrap();
|
||||||
|
for (slot, value) in storage {
|
||||||
|
tx.put::<tables::HashedStorage>(
|
||||||
|
hashed_address,
|
||||||
|
StorageEntry { key: keccak256(slot), value: *value },
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let (_, updates) = StateRoot::new(tx).root_with_updates().unwrap();
|
||||||
|
updates.flush(tx).unwrap();
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let tx = db.tx().unwrap();
|
||||||
|
let mut state = State::builder().with_bundle_update().build();
|
||||||
|
|
||||||
|
let assert_state_root = |state: &State<EmptyDB>, expected: &PreState, msg| {
|
||||||
|
assert_eq!(
|
||||||
|
BundleStateWithReceipts::new(state.bundle_state.clone(), Receipts::default(), 0)
|
||||||
|
.state_root_slow(&tx)
|
||||||
|
.unwrap(),
|
||||||
|
state_root(expected.clone().into_iter().map(|(address, (account, storage))| (
|
||||||
|
address,
|
||||||
|
(account, storage.into_iter())
|
||||||
|
))),
|
||||||
|
"{msg}"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// database only state root is correct
|
||||||
|
assert_state_root(&state, &prestate, "empty");
|
||||||
|
|
||||||
|
// destroy account 1
|
||||||
|
let address1 = Address::with_last_byte(1);
|
||||||
|
let account1_old = prestate.remove(&address1).unwrap();
|
||||||
|
state.insert_account(address1, into_revm_acc(account1_old.0));
|
||||||
|
state.commit(HashMap::from([(
|
||||||
|
address1,
|
||||||
|
RevmAccount {
|
||||||
|
status: AccountStatus::Touched | AccountStatus::SelfDestructed,
|
||||||
|
info: RevmAccountInfo::default(),
|
||||||
|
storage: HashMap::default(),
|
||||||
|
},
|
||||||
|
)]));
|
||||||
|
state.merge_transitions(BundleRetention::PlainState);
|
||||||
|
assert_state_root(&state, &prestate, "destroyed account");
|
||||||
|
|
||||||
|
// change slot 2 in account 2
|
||||||
|
let address2 = Address::with_last_byte(2);
|
||||||
|
let slot2 = U256::from(2);
|
||||||
|
let slot2_key = B256::from(slot2);
|
||||||
|
let account2 = prestate.get_mut(&address2).unwrap();
|
||||||
|
let account2_slot2_old_value = *account2.1.get(&slot2_key).unwrap();
|
||||||
|
state.insert_account_with_storage(
|
||||||
|
address2,
|
||||||
|
into_revm_acc(account2.0),
|
||||||
|
HashMap::from([(slot2, account2_slot2_old_value)]),
|
||||||
|
);
|
||||||
|
|
||||||
|
let account2_slot2_new_value = U256::from(100);
|
||||||
|
account2.1.insert(slot2_key, account2_slot2_new_value);
|
||||||
|
state.commit(HashMap::from([(
|
||||||
|
address2,
|
||||||
|
RevmAccount {
|
||||||
|
status: AccountStatus::Touched,
|
||||||
|
info: into_revm_acc(account2.0),
|
||||||
|
storage: HashMap::from_iter([(
|
||||||
|
slot2,
|
||||||
|
StorageSlot::new_changed(account2_slot2_old_value, account2_slot2_new_value),
|
||||||
|
)]),
|
||||||
|
},
|
||||||
|
)]));
|
||||||
|
state.merge_transitions(BundleRetention::PlainState);
|
||||||
|
assert_state_root(&state, &prestate, "changed storage");
|
||||||
|
|
||||||
|
// change balance of account 3
|
||||||
|
let address3 = Address::with_last_byte(3);
|
||||||
|
let account3 = prestate.get_mut(&address3).unwrap();
|
||||||
|
state.insert_account(address3, into_revm_acc(account3.0));
|
||||||
|
|
||||||
|
account3.0.balance = U256::from(24);
|
||||||
|
state.commit(HashMap::from([(
|
||||||
|
address3,
|
||||||
|
RevmAccount {
|
||||||
|
status: AccountStatus::Touched,
|
||||||
|
info: into_revm_acc(account3.0),
|
||||||
|
storage: HashMap::default(),
|
||||||
|
},
|
||||||
|
)]));
|
||||||
|
state.merge_transitions(BundleRetention::PlainState);
|
||||||
|
assert_state_root(&state, &prestate, "changed balance");
|
||||||
|
|
||||||
|
// change nonce of account 4
|
||||||
|
let address4 = Address::with_last_byte(4);
|
||||||
|
let account4 = prestate.get_mut(&address4).unwrap();
|
||||||
|
state.insert_account(address4, into_revm_acc(account4.0));
|
||||||
|
|
||||||
|
account4.0.nonce = 128;
|
||||||
|
state.commit(HashMap::from([(
|
||||||
|
address4,
|
||||||
|
RevmAccount {
|
||||||
|
status: AccountStatus::Touched,
|
||||||
|
info: into_revm_acc(account4.0),
|
||||||
|
storage: HashMap::default(),
|
||||||
|
},
|
||||||
|
)]));
|
||||||
|
state.merge_transitions(BundleRetention::PlainState);
|
||||||
|
assert_state_root(&state, &prestate, "changed nonce");
|
||||||
|
|
||||||
|
// recreate account 1
|
||||||
|
let account1_new =
|
||||||
|
Account { nonce: 56, balance: U256::from(123), bytecode_hash: Some(B256::random()) };
|
||||||
|
prestate.insert(address1, (account1_new, BTreeMap::default()));
|
||||||
|
state.commit(HashMap::from([(
|
||||||
|
address1,
|
||||||
|
RevmAccount {
|
||||||
|
status: AccountStatus::Touched | AccountStatus::Created,
|
||||||
|
info: into_revm_acc(account1_new),
|
||||||
|
storage: HashMap::default(),
|
||||||
|
},
|
||||||
|
)]));
|
||||||
|
state.merge_transitions(BundleRetention::PlainState);
|
||||||
|
assert_state_root(&state, &prestate, "recreated");
|
||||||
|
|
||||||
|
// update storage for account 1
|
||||||
|
let slot20 = U256::from(20);
|
||||||
|
let slot20_key = B256::from(slot20);
|
||||||
|
let account1_slot20_value = U256::from(12345);
|
||||||
|
prestate.get_mut(&address1).unwrap().1.insert(slot20_key, account1_slot20_value);
|
||||||
|
state.commit(HashMap::from([(
|
||||||
|
address1,
|
||||||
|
RevmAccount {
|
||||||
|
status: AccountStatus::Touched | AccountStatus::Created,
|
||||||
|
info: into_revm_acc(account1_new),
|
||||||
|
storage: HashMap::from_iter([(
|
||||||
|
slot20,
|
||||||
|
StorageSlot::new_changed(U256::ZERO, account1_slot20_value),
|
||||||
|
)]),
|
||||||
|
},
|
||||||
|
)]));
|
||||||
|
state.merge_transitions(BundleRetention::PlainState);
|
||||||
|
assert_state_root(&state, &prestate, "recreated changed storage");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user