diff --git a/frame/ethereum/src/mock.rs b/frame/ethereum/src/mock.rs index c4d01b2f55..9eeb8f7e7b 100644 --- a/frame/ethereum/src/mock.rs +++ b/frame/ethereum/src/mock.rs @@ -151,6 +151,10 @@ impl AddressMapping for HashedAddressMapping { } } +parameter_types! { + pub SuicideQuickClearLimit: u32 = 0; +} + impl pallet_evm::Config for Test { type FeeCalculator = FixedGasPrice; type GasWeightMapping = pallet_evm::FixedGasWeightMapping; @@ -170,6 +174,7 @@ impl pallet_evm::Config for Test { type OnCreate = (); type FindAuthor = FindAuthorTruncated; type GasLimitPovSizeRatio = GasLimitPovSizeRatio; + type SuicideQuickClearLimit = SuicideQuickClearLimit; type Timestamp = Timestamp; type WeightInfo = (); } diff --git a/frame/evm/precompile/dispatch/src/mock.rs b/frame/evm/precompile/dispatch/src/mock.rs index cb55296bda..1c55895817 100644 --- a/frame/evm/precompile/dispatch/src/mock.rs +++ b/frame/evm/precompile/dispatch/src/mock.rs @@ -130,6 +130,7 @@ impl FindAuthor for FindAuthorTruncated { parameter_types! { pub BlockGasLimit: U256 = U256::max_value(); pub WeightPerGas: Weight = Weight::from_parts(20_000, 0); + pub SuicideQuickClearLimit: u32 = 0; } impl pallet_evm::Config for Test { type FeeCalculator = FixedGasPrice; @@ -152,6 +153,7 @@ impl pallet_evm::Config for Test { type OnChargeTransaction = (); type OnCreate = (); type FindAuthor = FindAuthorTruncated; + type SuicideQuickClearLimit = SuicideQuickClearLimit; type GasLimitPovSizeRatio = (); type Timestamp = Timestamp; type WeightInfo = (); diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index 012d5e796d..7261e5dc85 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -75,6 +75,7 @@ use scale_info::TypeInfo; // Substrate use frame_support::{ dispatch::{DispatchResultWithPostInfo, Pays, PostDispatchInfo}, + storage::child::KillStorageResult, traits::{ tokens::{ currency::Currency, @@ -168,6 +169,9 @@ pub mod pallet { /// Gas limit Pov size ratio. type GasLimitPovSizeRatio: Get; + /// Define the quick clear limit of storage clearing when a contract suicides. Set to 0 to disable it. + type SuicideQuickClearLimit: Get; + /// Get the timestamp for the current block. type Timestamp: Time; @@ -807,6 +811,21 @@ impl Pallet { >::remove(address); >::remove(address); + + if T::SuicideQuickClearLimit::get() > 0 { + #[allow(deprecated)] + let res = >::remove_prefix(address, Some(T::SuicideQuickClearLimit::get())); + + match res { + KillStorageResult::AllRemoved(_) => { + >::remove(address); + + let account_id = T::AddressMapping::into_account_id(*address); + let _ = frame_system::Pallet::::dec_sufficients(&account_id); + } + KillStorageResult::SomeRemaining(_) => (), + } + } } /// Create an account. diff --git a/frame/evm/src/mock.rs b/frame/evm/src/mock.rs index 2ba1495eb4..9e1e481d5d 100644 --- a/frame/evm/src/mock.rs +++ b/frame/evm/src/mock.rs @@ -128,6 +128,7 @@ parameter_types! { pub const GasLimitPovSizeRatio: u64 = BLOCK_GAS_LIMIT.saturating_div(MAX_POV_SIZE); pub WeightPerGas: Weight = Weight::from_parts(20_000, 0); pub MockPrecompiles: MockPrecompileSet = MockPrecompileSet; + pub SuicideQuickClearLimit: u32 = 0; } impl crate::Config for Test { type FeeCalculator = FixedGasPrice; @@ -151,6 +152,7 @@ impl crate::Config for Test { type OnCreate = (); type FindAuthor = FindAuthorTruncated; type GasLimitPovSizeRatio = GasLimitPovSizeRatio; + type SuicideQuickClearLimit = SuicideQuickClearLimit; type Timestamp = Timestamp; type WeightInfo = (); } diff --git a/precompiles/tests-external/lib.rs b/precompiles/tests-external/lib.rs index bdf46e2932..75199c1cee 100644 --- a/precompiles/tests-external/lib.rs +++ b/precompiles/tests-external/lib.rs @@ -219,6 +219,7 @@ parameter_types! { let block_gas_limit = BlockGasLimit::get().min(u64::MAX.into()).low_u64(); block_gas_limit.saturating_div(MAX_POV_SIZE) }; + pub SuicideQuickClearLimit: u32 = 0; } impl pallet_evm::Config for Runtime { @@ -240,6 +241,7 @@ impl pallet_evm::Config for Runtime { type OnCreate = (); type FindAuthor = (); type GasLimitPovSizeRatio = GasLimitPovSizeRatio; + type SuicideQuickClearLimit = SuicideQuickClearLimit; type Timestamp = Timestamp; type WeightInfo = pallet_evm::weights::SubstrateWeight; } diff --git a/template/runtime/src/lib.rs b/template/runtime/src/lib.rs index d905e3d144..5995ec780a 100644 --- a/template/runtime/src/lib.rs +++ b/template/runtime/src/lib.rs @@ -324,6 +324,7 @@ parameter_types! { pub const GasLimitPovSizeRatio: u64 = BLOCK_GAS_LIMIT.saturating_div(MAX_POV_SIZE); pub PrecompilesValue: FrontierPrecompiles = FrontierPrecompiles::<_>::new(); pub WeightPerGas: Weight = Weight::from_parts(weight_per_gas(BLOCK_GAS_LIMIT, NORMAL_DISPATCH_RATIO, WEIGHT_MILLISECS_PER_BLOCK), 0); + pub SuicideQuickClearLimit: u32 = 0; } impl pallet_evm::Config for Runtime { @@ -345,6 +346,7 @@ impl pallet_evm::Config for Runtime { type OnCreate = (); type FindAuthor = FindAuthorTruncated; type GasLimitPovSizeRatio = GasLimitPovSizeRatio; + type SuicideQuickClearLimit = SuicideQuickClearLimit; type Timestamp = Timestamp; type WeightInfo = pallet_evm::weights::SubstrateWeight; }