Skip to content

Commit

Permalink
add a limit
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmadkaouk committed Nov 2, 2023
1 parent a301ebb commit 76921f1
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 4 deletions.
11 changes: 8 additions & 3 deletions frame/evm/precompile/clear-storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ impl<Runtime> StorageCleanerPrecompile<Runtime>
where
Runtime: pallet_evm::Config,
{
#[precompile::public("clearSuicidedStorage(address[])")]
#[precompile::public("clearSuicidedStorage(address[],uint32)")]
fn clear_suicided_storage(
handle: &mut impl PrecompileHandle,
addresses: BoundedVec<Address, GetArrayLimit>,
limit: u32,
) -> EvmResult {
let addresses: Vec<_> = addresses.into();
let mut deleted_entries = 0;

for address in addresses {
// Read Suicided storage item
Expand All @@ -58,8 +60,7 @@ where
return Err(revert(format!("NotSuicided: {}", address.0)));
}

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

let mut iter = pallet_evm::AccountStorages::<Runtime>::drain_prefix(&address.0);
loop {
handle.record_db_read::<Runtime>(116)?;
// Record the gas cost of deleting the storage item
Expand All @@ -70,6 +71,10 @@ where
Self::clear_suicided_contract(address);
break;
}
deleted_entries += 1;
if deleted_entries >= limit {
return Ok(());
}
}
}

Expand Down
84 changes: 83 additions & 1 deletion frame/evm/precompile/clear-storage/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ fn test_clear_suicided_contract_succesfull() {
let contract_address = mock_contract_with_entries(1, 10);
// Add contract to the suicided contracts
pallet_evm::Suicided::<Runtime>::insert(contract_address, ());

precompiles()
.prepare_test(
Alice,
Precompile1,
PCall::clear_suicided_storage {
addresses: vec![contract_address.into()].into(),
limit: u32::MAX,
},
)
.execute_returns(());
Expand Down Expand Up @@ -106,6 +106,7 @@ fn test_clear_suicided_contract_failed() {
Precompile1,
PCall::clear_suicided_storage {
addresses: vec![contract_address.into()].into(),
limit: u32::MAX,
},
)
.execute_reverts(|output| {
Expand Down Expand Up @@ -136,6 +137,7 @@ fn test_clear_suicided_empty_input() {
Precompile1,
PCall::clear_suicided_storage {
addresses: vec![].into(),
limit: u32::MAX,
},
)
.execute_returns(());
Expand Down Expand Up @@ -178,6 +180,7 @@ fn test_clear_suicided_contract_multiple_addresses() {
contract_address3.into(),
]
.into(),
limit: u32::MAX,
},
)
.execute_returns(());
Expand Down Expand Up @@ -239,6 +242,7 @@ fn test_clear_suicided_mixed_suicided_and_non_suicided() {
contract_address4.into(),
]
.into(),
limit: u32::MAX,
},
)
.execute_reverts(|output| {
Expand Down Expand Up @@ -273,6 +277,7 @@ fn test_clear_suicided_no_storage_entries() {
Precompile1,
PCall::clear_suicided_storage {
addresses: vec![contract_address1.into()].into(),
limit: u32::MAX,
},
)
.execute_returns(());
Expand Down Expand Up @@ -327,3 +332,80 @@ fn test_clear_suicided_no_storage_entries() {
);
})
}

// Test that the precompile deletes a maximum of `ENTRY_LIMIT` entries
#[test]
fn test_clear_suicided_entry_limit() {
ExtBuilder::default()
.with_balances(vec![(Alice.into(), 10000000000000000000)])
.build()
.execute_with(|| {
let contract_address1 = mock_contract_with_entries(1, 4);
let contract_address2 = mock_contract_with_entries(2, 3);
// Add contract to the suicided contracts
pallet_evm::Suicided::<Runtime>::insert(contract_address1, ());
pallet_evm::Suicided::<Runtime>::insert(contract_address2, ());

precompiles()
.prepare_test(
Alice,
Precompile1,
PCall::clear_suicided_storage {
addresses: vec![contract_address1.into(), contract_address2.into()].into(),
limit: 5,
},
)
.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(),
2
);

assert_eq!(
pallet_evm::Suicided::<Runtime>::contains_key(contract_address2),
true
);
})
}

#[test]
fn test_clear_suicided_entry_limit_1() {
ExtBuilder::default()
.with_balances(vec![(Alice.into(), 10000000000000000000)])
.build()
.execute_with(|| {
let contract_address1 = mock_contract_with_entries(1, 5);
// Add contract to the suicided contracts
pallet_evm::Suicided::<Runtime>::insert(contract_address1, ());

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

assert_eq!(
pallet_evm::AccountStorages::<Runtime>::iter_prefix(contract_address1).count(),
1
);
assert_eq!(
pallet_evm::Suicided::<Runtime>::contains_key(contract_address1),
true
);
})
}

0 comments on commit 76921f1

Please sign in to comment.