--- a/pallets/evm-contract-helpers/src/eth.rs +++ b/pallets/evm-contract-helpers/src/eth.rs @@ -26,7 +26,7 @@ }; use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder, dispatch_to_evm}; use pallet_evm_transaction_payment::CallContext; -use sp_core::H160; +use sp_core::{H160, U256}; use up_data_structs::SponsorshipState; use crate::{ AllowlistEnabled, Config, Owner, Pallet, SponsorBasket, SponsoringFeeLimit, @@ -258,12 +258,13 @@ fee_limit: uint256, ) -> Result { >::ensure_owner(contract_address, caller).map_err(dispatch_to_evm::)?; - >::set_sponsoring_fee_limit(contract_address, fee_limit.into()); + >::set_sponsoring_fee_limit(contract_address, fee_limit.into()) + .map_err(dispatch_to_evm::)?; Ok(()) } fn get_sponsoring_fee_limit(&self, contract_address: address) -> Result { - Ok(>::get(contract_address, 0xffffffff)) + Ok(get_sponsoring_fee_limit::(contract_address)) } /// Is specified user present in contract allow list @@ -413,7 +414,7 @@ } } - let sponsored_fee_limit = >::get(contract_address, 0xffffffff); + let sponsored_fee_limit = get_sponsoring_fee_limit::(contract_address); if call_context.max_fee > sponsored_fee_limit { return None; @@ -425,5 +426,12 @@ } } +fn get_sponsoring_fee_limit(contract_address: address) -> uint256 { + >::get(contract_address) + .get(&0xffffffff) + .cloned() + .unwrap_or(U256::MAX) +} + generate_stubgen!(contract_helpers_impl, ContractHelpersCall<()>, true); generate_stubgen!(contract_helpers_iface, ContractHelpersCall<()>, false); --- a/pallets/evm-contract-helpers/src/lib.rs +++ b/pallets/evm-contract-helpers/src/lib.rs @@ -22,8 +22,12 @@ pub use pallet::*; pub use eth::*; use scale_info::TypeInfo; +use frame_support::storage::bounded_btree_map::BoundedBTreeMap; pub mod eth; +/// Maximum number of methods per contract that could have fee limit +pub const MAX_FEE_LIMITED_METHODS: u32 = 5; + #[frame_support::pallet] pub mod pallet { pub use super::*; @@ -48,9 +52,6 @@ /// In case of enabled sponsoring, but no sponsoring rate limit set, /// this value will be used implicitly type DefaultSponsoringRateLimit: Get; - /// In case of enabled sponsoring, but no sponsoring fee limit set, - /// this value will be used implicitly - type DefaultSponsoringFeeLimit: Get; } #[pallet::error] @@ -60,6 +61,9 @@ /// No pending sponsor for contract. NoPendingSponsor, + + /// Number of methods that sponsored limit is defined for exceeds maximum. + TooManyMethodsHaveSponsoredLimit, } #[pallet::pallet] @@ -121,14 +125,11 @@ /// * **Key2** - sponsored user address. /// * **Value** - last sponsored block number. #[pallet::storage] - pub(super) type SponsoringFeeLimit = StorageDoubleMap< - Hasher1 = Twox128, - Key1 = H160, - Hasher2 = Blake2_128Concat, - Key2 = u32, - Value = U256, + pub(super) type SponsoringFeeLimit = StorageMap< + Hasher = Twox128, + Key = H160, + Value = BoundedBTreeMap>, QueryKind = ValueQuery, - OnEmpty = T::DefaultSponsoringFeeLimit, >; #[pallet::storage] @@ -368,8 +369,13 @@ } /// Set maximum for gas limit of transaction - pub fn set_sponsoring_fee_limit(contract: H160, fee_limit: U256) { - >::insert(contract, 0xffffffff, fee_limit); + pub fn set_sponsoring_fee_limit(contract: H160, fee_limit: U256) -> DispatchResult { + >::try_mutate(contract, |limits_map| { + limits_map + .try_insert(0xffffffff, fee_limit) + .map_err(|_| >::TooManyMethodsHaveSponsoredLimit) + })?; + Ok(()) } /// Is user added to allowlist, or he is owner of specified contract --- a/runtime/common/config/ethereum.rs +++ b/runtime/common/config/ethereum.rs @@ -7,10 +7,8 @@ use sp_runtime::{RuntimeAppPublic, Perbill}; use crate::{ runtime_common::{ - dispatch::CollectionDispatchT, - ethereum::sponsoring::EvmSponsorshipHandler, - config::sponsoring::{DefaultSponsoringFeeLimit, DefaultSponsoringRateLimit}, - DealWithFees, + dispatch::CollectionDispatchT, ethereum::sponsoring::EvmSponsorshipHandler, + config::sponsoring::DefaultSponsoringRateLimit, DealWithFees, }, Runtime, Aura, Balances, Event, ChainId, }; @@ -117,7 +115,6 @@ type Event = Event; type ContractAddress = HelpersContractAddress; type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit; - type DefaultSponsoringFeeLimit = DefaultSponsoringFeeLimit; } impl pallet_evm_coder_substrate::Config for Runtime {}