Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions crates/storage/provider/src/post_state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,60 @@ mod tests {
assert_eq!(storage_changes.next(), None);
}

#[test]
fn storage_change_after_selfdestruct_within_block() {
let db: Arc<DatabaseEnv> = create_test_rw_db();
let tx = db.tx_mut().expect("Could not get database tx");

let address1 = Address::random();

let mut init_state = PostState::new();
init_state.create_account(0, address1, Account::default());
init_state.change_storage(
0,
address1,
// 0x00 => 0 => 1
// 0x01 => 0 => 2
BTreeMap::from([
(U256::from(0), (U256::ZERO, U256::from(1))),
(U256::from(1), (U256::ZERO, U256::from(2))),
]),
);
init_state.write_to_db(&tx, 0).expect("Could not write init state to DB");

let mut post_state = PostState::new();
post_state.destroy_account(1, address1, Account::default());
post_state.create_account(1, address1, Account::default());
post_state.change_storage(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change storage here to some other slot 0x100 for example and check if changeset is set to zero value for that slot

1,
address1,
// 0x01 => 0 => 5
BTreeMap::from([(U256::from(1), (U256::ZERO, U256::from(5)))]),
);
post_state.write_to_db(&tx, 1).expect("Could not write post state to DB");

let mut storage_changeset_cursor = tx
.cursor_dup_read::<tables::StorageChangeSet>()
.expect("Could not open plain storage state cursor");
let range = BlockNumberAddress::range(1..=1);
let mut storage_changes = storage_changeset_cursor.walk_range(range).unwrap();

assert_eq!(
storage_changes.next(),
Some(Ok((
BlockNumberAddress((1, address1)),
StorageEntry { key: H256::from_low_u64_be(0), value: U256::from(1) }
)))
);
assert_eq!(
storage_changes.next(),
Some(Ok((
BlockNumberAddress((1, address1)),
StorageEntry { key: H256::from_low_u64_be(1), value: U256::from(2) }
)))
);
}

#[test]
fn reuse_selfdestructed_account() {
let address_a = Address::zero();
Expand Down
17 changes: 11 additions & 6 deletions crates/storage/provider/src/post_state/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,20 @@ impl StorageChanges {
{
let block_entry = self.inner.entry(block).or_default();
let storage_entry = block_entry.entry(address).or_default();

let was_previously_wiped = storage_entry.wipe.is_wiped();
if !was_previously_wiped {
for (slot, value) in storage {
if let Entry::Vacant(entry) = storage_entry.storage.entry(slot) {
entry.insert(value);
self.size += 1;
}
}
}

if wipe.is_wiped() {
storage_entry.wipe = wipe;
}
for (slot, value) in storage {
if let Entry::Vacant(entry) = storage_entry.storage.entry(slot) {
entry.insert(value);
self.size += 1;
}
}
}

/// Drain and return any entries above the target block number.
Expand Down