git.delta.rocks / unique-network / refs/commits / d78c2fedc380

difftreelog

chore store limits in BTreeMap

Grigoriy Simonov2022-09-13parent: #7e9e885.patch.diff
in: master

3 files changed

modifiedpallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth
--- 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<void> {
 		<Pallet<T>>::ensure_owner(contract_address, caller).map_err(dispatch_to_evm::<T>)?;
-		<Pallet<T>>::set_sponsoring_fee_limit(contract_address, fee_limit.into());
+		<Pallet<T>>::set_sponsoring_fee_limit(contract_address, fee_limit.into())
+			.map_err(dispatch_to_evm::<T>)?;
 		Ok(())
 	}
 
 	fn get_sponsoring_fee_limit(&self, contract_address: address) -> Result<uint256> {
-		Ok(<SponsoringFeeLimit<T>>::get(contract_address, 0xffffffff))
+		Ok(get_sponsoring_fee_limit::<T>(contract_address))
 	}
 
 	/// Is specified user present in contract allow list
@@ -413,7 +414,7 @@
 			}
 		}
 
-		let sponsored_fee_limit = <SponsoringFeeLimit<T>>::get(contract_address, 0xffffffff);
+		let sponsored_fee_limit = get_sponsoring_fee_limit::<T>(contract_address);
 
 		if call_context.max_fee > sponsored_fee_limit {
 			return None;
@@ -425,5 +426,12 @@
 	}
 }
 
+fn get_sponsoring_fee_limit<T: Config>(contract_address: address) -> uint256 {
+	<SponsoringFeeLimit<T>>::get(contract_address)
+		.get(&0xffffffff)
+		.cloned()
+		.unwrap_or(U256::MAX)
+}
+
 generate_stubgen!(contract_helpers_impl, ContractHelpersCall<()>, true);
 generate_stubgen!(contract_helpers_iface, ContractHelpersCall<()>, false);
modifiedpallets/evm-contract-helpers/src/lib.rsdiffbeforeafterboth
--- 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<Self::BlockNumber>;
-		/// In case of enabled sponsoring, but no sponsoring fee limit set,
-		/// this value will be used implicitly
-		type DefaultSponsoringFeeLimit: Get<U256>;
 	}
 
 	#[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<T: Config> = StorageDoubleMap<
-		Hasher1 = Twox128,
-		Key1 = H160,
-		Hasher2 = Blake2_128Concat,
-		Key2 = u32,
-		Value = U256,
+	pub(super) type SponsoringFeeLimit<T: Config> = StorageMap<
+		Hasher = Twox128,
+		Key = H160,
+		Value = BoundedBTreeMap<u32, U256, ConstU32<MAX_FEE_LIMITED_METHODS>>,
 		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) {
-			<SponsoringFeeLimit<T>>::insert(contract, 0xffffffff, fee_limit);
+		pub fn set_sponsoring_fee_limit(contract: H160, fee_limit: U256) -> DispatchResult {
+			<SponsoringFeeLimit<T>>::try_mutate(contract, |limits_map| {
+				limits_map
+					.try_insert(0xffffffff, fee_limit)
+					.map_err(|_| <Error<T>>::TooManyMethodsHaveSponsoredLimit)
+			})?;
+			Ok(())
 		}
 
 		/// Is user added to allowlist, or he is owner of specified contract
modifiedruntime/common/config/ethereum.rsdiffbeforeafterboth
before · runtime/common/config/ethereum.rs
1use sp_core::{U256, H160};2use frame_support::{3	weights::{Weight, constants::WEIGHT_PER_SECOND},4	traits::{FindAuthor},5	parameter_types, ConsensusEngineId,6};7use sp_runtime::{RuntimeAppPublic, Perbill};8use crate::{9	runtime_common::{10		dispatch::CollectionDispatchT,11		ethereum::sponsoring::EvmSponsorshipHandler,12		config::sponsoring::{DefaultSponsoringFeeLimit, DefaultSponsoringRateLimit},13		DealWithFees,14	},15	Runtime, Aura, Balances, Event, ChainId,16};17use pallet_evm::{EnsureAddressTruncated, HashedAddressMapping};18use up_common::constants::*;1920pub type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;2122impl pallet_evm::account::Config for Runtime {23	type CrossAccountId = CrossAccountId;24	type EvmAddressMapping = pallet_evm::HashedAddressMapping<Self::Hashing>;25	type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;26}2728// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case29// (contract, which only writes a lot of data),30// approximating on top of our real store write weight31parameter_types! {32	pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / <Runtime as frame_system::Config>::DbWeight::get().write;33	pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;34	pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get();35}3637/// Limiting EVM execution to 50% of block for substrate users and management tasks38/// EVM transaction consumes more weight than substrate's, so we can't rely on them being39/// scheduled fairly40const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);41parameter_types! {42	pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get());43}4445pub enum FixedGasWeightMapping {}46impl pallet_evm::GasWeightMapping for FixedGasWeightMapping {47	fn gas_to_weight(gas: u64) -> Weight {48		gas.saturating_mul(WeightPerGas::get())49	}50	fn weight_to_gas(weight: Weight) -> u64 {51		weight / WeightPerGas::get()52	}53}5455pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);56impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {57	fn find_author<'a, I>(digests: I) -> Option<H160>58	where59		I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,60	{61		if let Some(author_index) = F::find_author(digests) {62			let authority_id = Aura::authorities()[author_index as usize].clone();63			return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));64		}65		None66	}67}6869impl pallet_evm::Config for Runtime {70	type BlockGasLimit = BlockGasLimit;71	type FeeCalculator = pallet_configuration::FeeCalculator<Self>;72	type GasWeightMapping = FixedGasWeightMapping;73	type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;74	type CallOrigin = EnsureAddressTruncated<Self>;75	type WithdrawOrigin = EnsureAddressTruncated<Self>;76	type AddressMapping = HashedAddressMapping<Self::Hashing>;77	type PrecompilesType = ();78	type PrecompilesValue = ();79	type Currency = Balances;80	type Event = Event;81	type OnMethodCall = (82		pallet_evm_migration::OnMethodCall<Self>,83		pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,84		CollectionDispatchT<Self>,85		pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,86	);87	type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;88	type ChainId = ChainId;89	type Runner = pallet_evm::runner::stack::Runner<Self>;90	type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;91	type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;92	type FindAuthor = EthereumFindAuthor<Aura>;93}9495impl pallet_evm_migration::Config for Runtime {96	type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;97}9899impl pallet_ethereum::Config for Runtime {100	type Event = Event;101	type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;102}103104parameter_types! {105	// 0x842899ECF380553E8a4de75bF534cdf6fBF64049106	pub const HelpersContractAddress: H160 = H160([107		0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,108	]);109110	// 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f111	pub const EvmCollectionHelpersAddress: H160 = H160([112		0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,113	]);114}115116impl pallet_evm_contract_helpers::Config for Runtime {117	type Event = Event;118	type ContractAddress = HelpersContractAddress;119	type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;120	type DefaultSponsoringFeeLimit = DefaultSponsoringFeeLimit;121}122123impl pallet_evm_coder_substrate::Config for Runtime {}124125impl pallet_evm_transaction_payment::Config for Runtime {126	type EvmSponsorshipHandler = EvmSponsorshipHandler;127}