difftreelog
chore store limits in BTreeMap
in: master
3 files changed
pallets/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);
pallets/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
runtime/common/config/ethereum.rsdiffbeforeafterboth1use 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}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, ethereum::sponsoring::EvmSponsorshipHandler,11 config::sponsoring::DefaultSponsoringRateLimit, DealWithFees,12 },13 Runtime, Aura, Balances, Event, ChainId,14};15use pallet_evm::{EnsureAddressTruncated, HashedAddressMapping};16use up_common::constants::*;1718pub type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;1920impl pallet_evm::account::Config for Runtime {21 type CrossAccountId = CrossAccountId;22 type EvmAddressMapping = pallet_evm::HashedAddressMapping<Self::Hashing>;23 type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;24}2526// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case27// (contract, which only writes a lot of data),28// approximating on top of our real store write weight29parameter_types! {30 pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / <Runtime as frame_system::Config>::DbWeight::get().write;31 pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;32 pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get();33}3435/// Limiting EVM execution to 50% of block for substrate users and management tasks36/// EVM transaction consumes more weight than substrate's, so we can't rely on them being37/// scheduled fairly38const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);39parameter_types! {40 pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get());41}4243pub enum FixedGasWeightMapping {}44impl pallet_evm::GasWeightMapping for FixedGasWeightMapping {45 fn gas_to_weight(gas: u64) -> Weight {46 gas.saturating_mul(WeightPerGas::get())47 }48 fn weight_to_gas(weight: Weight) -> u64 {49 weight / WeightPerGas::get()50 }51}5253pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);54impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {55 fn find_author<'a, I>(digests: I) -> Option<H160>56 where57 I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,58 {59 if let Some(author_index) = F::find_author(digests) {60 let authority_id = Aura::authorities()[author_index as usize].clone();61 return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));62 }63 None64 }65}6667impl pallet_evm::Config for Runtime {68 type BlockGasLimit = BlockGasLimit;69 type FeeCalculator = pallet_configuration::FeeCalculator<Self>;70 type GasWeightMapping = FixedGasWeightMapping;71 type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;72 type CallOrigin = EnsureAddressTruncated<Self>;73 type WithdrawOrigin = EnsureAddressTruncated<Self>;74 type AddressMapping = HashedAddressMapping<Self::Hashing>;75 type PrecompilesType = ();76 type PrecompilesValue = ();77 type Currency = Balances;78 type Event = Event;79 type OnMethodCall = (80 pallet_evm_migration::OnMethodCall<Self>,81 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,82 CollectionDispatchT<Self>,83 pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,84 );85 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;86 type ChainId = ChainId;87 type Runner = pallet_evm::runner::stack::Runner<Self>;88 type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;89 type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;90 type FindAuthor = EthereumFindAuthor<Aura>;91}9293impl pallet_evm_migration::Config for Runtime {94 type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;95}9697impl pallet_ethereum::Config for Runtime {98 type Event = Event;99 type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;100}101102parameter_types! {103 // 0x842899ECF380553E8a4de75bF534cdf6fBF64049104 pub const HelpersContractAddress: H160 = H160([105 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,106 ]);107108 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f109 pub const EvmCollectionHelpersAddress: H160 = H160([110 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,111 ]);112}113114impl pallet_evm_contract_helpers::Config for Runtime {115 type Event = Event;116 type ContractAddress = HelpersContractAddress;117 type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;118}119120impl pallet_evm_coder_substrate::Config for Runtime {}121122impl pallet_evm_transaction_payment::Config for Runtime {123 type EvmSponsorshipHandler = EvmSponsorshipHandler;124}