git.delta.rocks / unique-network / refs/commits / 0ceea0af66a9

difftreelog

source

pallets/configuration/src/lib.rs10.0 KiBsourcehistory
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617#![cfg_attr(not(feature = "std"), no_std)]1819use core::marker::PhantomData;2021use frame_support::{22	pallet,23	traits::Get,24	weights::{Weight, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial},25};26pub use pallet::*;27use parity_scale_codec::{Decode, Encode, MaxEncodedLen};28use scale_info::TypeInfo;29use smallvec::smallvec;30use sp_arithmetic::{31	per_things::{PerThing, Perbill},32	traits::{BaseArithmetic, Unsigned},33};34use sp_core::U256;3536#[cfg(feature = "runtime-benchmarks")]37mod benchmarking;38pub mod weights;3940#[pallet]41mod pallet {42	use core::fmt::Debug;4344	use frame_support::{pallet_prelude::*, traits::Get};45	use frame_system::{ensure_root, pallet_prelude::*};46	use parity_scale_codec::Codec;47	use sp_arithmetic::{traits::AtLeast32BitUnsigned, FixedPointOperand, Permill};4849	use super::*;50	pub use crate::weights::WeightInfo;5152	#[pallet::config]53	pub trait Config: frame_system::Config {54		/// Overarching event type.55		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;5657		type Balance: Parameter58			+ Member59			+ AtLeast32BitUnsigned60			+ From<up_common::types::Balance>61			+ Codec62			+ Default63			+ Copy64			+ MaybeSerializeDeserialize65			+ Debug66			+ MaxEncodedLen67			+ TypeInfo68			+ FixedPointOperand;6970		#[pallet::constant]71		type DefaultWeightToFeeCoefficient: Get<u64>;72		#[pallet::constant]73		type DefaultMinGasPrice: Get<u64>;7475		#[pallet::constant]76		type MaxXcmAllowedLocations: Get<u32>;77		#[pallet::constant]78		type AppPromotionDailyRate: Get<Perbill>;79		#[pallet::constant]80		type DayRelayBlocks: Get<BlockNumberFor<Self>>;8182		#[pallet::constant]83		type DefaultCollatorSelectionMaxCollators: Get<u32>;84		#[pallet::constant]85		type DefaultCollatorSelectionLicenseBond: Get<Self::Balance>;86		#[pallet::constant]87		type DefaultCollatorSelectionKickThreshold: Get<BlockNumberFor<Self>>;8889		/// The weight information of this pallet.90		type WeightInfo: WeightInfo;91	}9293	#[pallet::event]94	#[pallet::generate_deposit(pub(super) fn deposit_event)]95	pub enum Event<T: Config> {96		NewDesiredCollators {97			desired_collators: Option<u32>,98		},99		NewCollatorLicenseBond {100			bond_cost: Option<T::Balance>,101		},102		NewCollatorKickThreshold {103			length_in_blocks: Option<BlockNumberFor<T>>,104		},105	}106107	fn update_base_fee<T: Config>() {108		let base_fee_per_gas: U256 = <MinGasPriceOverride<T>>::get().into();109		let elasticity: Permill = Permill::zero();110		// twox_128(BaseFee) ++ twox_128(BaseFeePerGas)111		sp_io::storage::set(112			&hex_literal::hex!("c1fef3b7207c11a52df13c12884e77263864ade243c642793ebcfe9e16f454ca"),113			&base_fee_per_gas.encode(),114		);115		// twox_128(BaseFee) ++ twox_128(Elasticity)116		sp_io::storage::set(117			&hex_literal::hex!("c1fef3b7207c11a52df13c12884e772609bc3a1e532c9cb85d57feed02cbff8e"),118			&elasticity.encode(),119		);120	}121122	/// We update our default weights on every release123	#[pallet::hooks]124	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {125		fn on_runtime_upgrade() -> Weight {126			update_base_fee::<T>();127			T::DbWeight::get().reads_writes(1, 2)128		}129	}130131	#[pallet::genesis_config]132	pub struct GenesisConfig<T>(PhantomData<T>);133134	impl<T: Config> Default for GenesisConfig<T> {135		fn default() -> Self {136			Self(Default::default())137		}138	}139140	#[pallet::genesis_build]141	impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {142		fn build(&self) {143			update_base_fee::<T>();144		}145	}146147	#[pallet::error]148	pub enum Error<T> {149		InconsistentConfiguration,150	}151152	#[pallet::storage]153	pub type WeightToFeeCoefficientOverride<T: Config> = StorageValue<154		Value = u64,155		QueryKind = ValueQuery,156		OnEmpty = T::DefaultWeightToFeeCoefficient,157	>;158159	#[pallet::storage]160	pub type MinGasPriceOverride<T: Config> =161		StorageValue<Value = u64, QueryKind = ValueQuery, OnEmpty = T::DefaultMinGasPrice>;162163	#[pallet::storage]164	pub type AppPromomotionConfigurationOverride<T: Config> =165		StorageValue<Value = AppPromotionConfiguration<BlockNumberFor<T>>, QueryKind = ValueQuery>;166167	#[pallet::storage]168	pub type CollatorSelectionDesiredCollatorsOverride<T: Config> = StorageValue<169		Value = u32,170		QueryKind = ValueQuery,171		OnEmpty = T::DefaultCollatorSelectionMaxCollators,172	>;173174	#[pallet::storage]175	pub type CollatorSelectionLicenseBondOverride<T: Config> = StorageValue<176		Value = T::Balance,177		QueryKind = ValueQuery,178		OnEmpty = T::DefaultCollatorSelectionLicenseBond,179	>;180181	#[pallet::storage]182	pub type CollatorSelectionKickThresholdOverride<T: Config> = StorageValue<183		Value = BlockNumberFor<T>,184		QueryKind = ValueQuery,185		OnEmpty = T::DefaultCollatorSelectionKickThreshold,186	>;187188	#[pallet::call]189	impl<T: Config> Pallet<T> {190		#[pallet::call_index(0)]191		#[pallet::weight(T::WeightInfo::set_weight_to_fee_coefficient_override())]192		pub fn set_weight_to_fee_coefficient_override(193			origin: OriginFor<T>,194			coeff: Option<u64>,195		) -> DispatchResult {196			ensure_root(origin)?;197			if let Some(coeff) = coeff {198				<WeightToFeeCoefficientOverride<T>>::set(coeff);199			} else {200				<WeightToFeeCoefficientOverride<T>>::kill();201			}202			Ok(())203		}204205		#[pallet::call_index(1)]206		#[pallet::weight(T::WeightInfo::set_min_gas_price_override())]207		pub fn set_min_gas_price_override(208			origin: OriginFor<T>,209			coeff: Option<u64>,210		) -> DispatchResult {211			ensure_root(origin)?;212			if let Some(coeff) = coeff {213				<MinGasPriceOverride<T>>::set(coeff);214			} else {215				<MinGasPriceOverride<T>>::kill();216			}217			// This code should not be called in production, but why keep development in the218			// inconsistent state219			update_base_fee::<T>();220			Ok(())221		}222223		#[pallet::call_index(3)]224		#[pallet::weight(T::WeightInfo::set_app_promotion_configuration_override())]225		pub fn set_app_promotion_configuration_override(226			origin: OriginFor<T>,227			mut configuration: AppPromotionConfiguration<BlockNumberFor<T>>,228		) -> DispatchResult {229			ensure_root(origin)?;230			if configuration.interval_income.is_some() {231				return Err(<Error<T>>::InconsistentConfiguration.into());232			}233234			configuration.interval_income = configuration.recalculation_interval.map(|b| {235				Perbill::from_rational(b, T::DayRelayBlocks::get())236					* T::AppPromotionDailyRate::get()237			});238239			<AppPromomotionConfigurationOverride<T>>::set(configuration);240241			Ok(())242		}243244		#[pallet::call_index(4)]245		#[pallet::weight(T::WeightInfo::set_collator_selection_desired_collators())]246		pub fn set_collator_selection_desired_collators(247			origin: OriginFor<T>,248			max: Option<u32>,249		) -> DispatchResult {250			ensure_root(origin)?;251			if let Some(max) = max {252				// we trust origin calls, this is just a for more accurate benchmarking253				if max > T::DefaultCollatorSelectionMaxCollators::get() {254					log::warn!("max > T::DefaultCollatorSelectionMaxCollators; you might need to run benchmarks again");255				}256				<CollatorSelectionDesiredCollatorsOverride<T>>::set(max);257			} else {258				<CollatorSelectionDesiredCollatorsOverride<T>>::kill();259			}260			Self::deposit_event(Event::NewDesiredCollators {261				desired_collators: max,262			});263			Ok(())264		}265266		#[pallet::call_index(5)]267		#[pallet::weight(T::WeightInfo::set_collator_selection_license_bond())]268		pub fn set_collator_selection_license_bond(269			origin: OriginFor<T>,270			amount: Option<<T as Config>::Balance>,271		) -> DispatchResult {272			ensure_root(origin)?;273			if let Some(amount) = amount {274				<CollatorSelectionLicenseBondOverride<T>>::set(amount);275			} else {276				<CollatorSelectionLicenseBondOverride<T>>::kill();277			}278			Self::deposit_event(Event::NewCollatorLicenseBond { bond_cost: amount });279			Ok(())280		}281282		#[pallet::call_index(6)]283		#[pallet::weight(T::WeightInfo::set_collator_selection_kick_threshold())]284		pub fn set_collator_selection_kick_threshold(285			origin: OriginFor<T>,286			threshold: Option<BlockNumberFor<T>>,287		) -> DispatchResult {288			ensure_root(origin)?;289			if let Some(threshold) = threshold {290				<CollatorSelectionKickThresholdOverride<T>>::set(threshold);291			} else {292				<CollatorSelectionKickThresholdOverride<T>>::kill();293			}294			Self::deposit_event(Event::NewCollatorKickThreshold {295				length_in_blocks: threshold,296			});297			Ok(())298		}299	}300301	#[pallet::pallet]302	pub struct Pallet<T>(_);303}304305pub struct WeightToFee<T, B>(PhantomData<(T, B)>);306307impl<T, B> WeightToFeePolynomial for WeightToFee<T, B>308where309	T: Config,310	B: BaseArithmetic + From<u32> + From<u64> + Copy + Unsigned,311{312	type Balance = B;313314	fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {315		smallvec!(WeightToFeeCoefficient {316			coeff_integer: (<WeightToFeeCoefficientOverride<T>>::get() / Perbill::ACCURACY as u64)317				.into(),318			coeff_frac: Perbill::from_parts(319				(<WeightToFeeCoefficientOverride<T>>::get() % Perbill::ACCURACY as u64) as u32320			),321			negative: false,322			degree: 1,323		})324	}325}326327pub struct FeeCalculator<T>(PhantomData<T>);328impl<T: Config> fp_evm::FeeCalculator for FeeCalculator<T> {329	fn min_gas_price() -> (U256, Weight) {330		(331			<MinGasPriceOverride<T>>::get().into(),332			T::DbWeight::get().reads(1),333		)334	}335}336337#[derive(Encode, Decode, Clone, Debug, Default, TypeInfo, MaxEncodedLen, PartialEq, PartialOrd)]338pub struct AppPromotionConfiguration<BlockNumber> {339	/// In relay blocks.340	pub recalculation_interval: Option<BlockNumber>,341	/// In parachain blocks.342	pub pending_interval: Option<BlockNumber>,343	/// Value for `RecalculationInterval` based on 0.05% per 24h.344	pub interval_income: Option<Perbill>,345	/// Maximum allowable number of stakers calculated per call of the `app-promotion::PayoutStakers` extrinsic.346	pub max_stakers_per_calculation: Option<u8>,347}