Skip to content

Commit

Permalink
cover suicided contracts with no storage items
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmadkaouk committed Oct 16, 2023
1 parent 8f80890 commit aa01440
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 1 deletion.
9 changes: 8 additions & 1 deletion frame/evm/precompile/clear-storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ where
let addresses: Vec<_> = addresses.into();
let mut deleted_entries = 0;

// Ensure that all provided addresses are
'inner: for address in addresses {
// Read Suicided storage item
// Suicided: Blake2128(16) + H160(20)
Expand All @@ -62,6 +61,14 @@ where
}

let mut iter = pallet_evm::Pallet::<Runtime>::iter_account_storages(&address.0).drain();

// Contract has no storage entries
if iter.next().is_none() {
handle.record_db_read::<Runtime>(116)?;
Self::clear_suicided_contract(address);
continue 'inner;
}

// Delete a maximum of `ENTRY_LIMIT` entries in AccountStorages prefixed with `address`
while iter.next().is_some() {
handle.record_db_read::<Runtime>(116)?;
Expand Down
84 changes: 84 additions & 0 deletions frame/evm/precompile/clear-storage/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,3 +289,87 @@ fn test_clear_suicided_mixed_suicided_and_non_suicided() {
});
})
}

// Test that the precompile can handle suicided contracts that have no storage entries
#[test]
fn test_clear_suicided_no_storage_entries() {
ExtBuilder::default()
.with_balances(vec![(Alice.into(), 10000000000000000000)])
.build()
.execute_with(|| {
let contract_address1 = mock_contract_with_entries(1, 0);
let contract_address2 = mock_contract_with_entries(1, 500);
let contract_address3 = mock_contract_with_entries(1, 0);
let contract_address4 = mock_contract_with_entries(1, 400);
let contract_address5 = mock_contract_with_entries(1, 100);

// Add contract to the suicided contracts
pallet_evm::Suicided::<Runtime>::insert(contract_address1, ());
pallet_evm::Suicided::<Runtime>::insert(contract_address2, ());
pallet_evm::Suicided::<Runtime>::insert(contract_address3, ());
pallet_evm::Suicided::<Runtime>::insert(contract_address4, ());
pallet_evm::Suicided::<Runtime>::insert(contract_address5, ());

precompiles()
.prepare_test(
Alice,
Precompile1,
PCall::clear_suicided_storage {
addresses: vec![
contract_address1.into(),
]
.into(),
},
)
.execute_returns(());

assert_eq!(
pallet_evm::AccountStorages::<Runtime>::iter_prefix(contract_address1).count(),
0
);
assert_eq!(
pallet_evm::Suicided::<Runtime>::contains_key(contract_address1),
false
);
assert_eq!(
pallet_evm::AccountStorages::<Runtime>::iter_prefix(contract_address2).count(),
0
);
assert_eq!(
pallet_evm::Suicided::<Runtime>::contains_key(contract_address2),
false
);
assert_eq!(
pallet_evm::AccountStorages::<Runtime>::iter_prefix(contract_address3).count(),
0
);
assert_eq!(
pallet_evm::Suicided::<Runtime>::contains_key(contract_address3),
false
);
assert_eq!(
pallet_evm::AccountStorages::<Runtime>::iter_prefix(contract_address4).count(),
0
);
assert_eq!(
pallet_evm::Suicided::<Runtime>::contains_key(contract_address4),
false
);
assert_eq!(
pallet_evm::AccountStorages::<Runtime>::iter_prefix(contract_address4).count(),
0
);
assert_eq!(
pallet_evm::Suicided::<Runtime>::contains_key(contract_address4),
false
);
assert_eq!(
pallet_evm::AccountStorages::<Runtime>::iter_prefix(contract_address5).count(),
0
);
assert_eq!(
pallet_evm::Suicided::<Runtime>::contains_key(contract_address5),
false
);
})
}

0 comments on commit aa01440

Please sign in to comment.