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

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	weights::{WeightToFeePolynomial, WeightToFeeCoefficients, WeightToFeeCoefficient, Weight},24	traits::Get,25	Parameter,26};27use codec::{Decode, Encode, MaxEncodedLen};28use scale_info::TypeInfo;29use sp_arithmetic::{30	per_things::{Perbill, PerThing},31	traits::{BaseArithmetic, Unsigned},32};33use smallvec::smallvec;3435pub use pallet::*;36use sp_core::U256;3738#[cfg(feature = "runtime-benchmarks")]39mod benchmarking;40pub mod weights;4142#[pallet]43mod pallet {44	use super::*;45	use frame_support::{46		traits::Get,47		pallet_prelude::*,48		log,49		dispatch::{Codec, fmt::Debug},50	};51	use frame_system::{pallet_prelude::OriginFor, ensure_root, pallet_prelude::*};52	use sp_arithmetic::{FixedPointOperand, traits::AtLeast32BitUnsigned, Permill};53	pub use crate::weights::WeightInfo;5455	#[pallet::config]56	pub trait Config: frame_system::Config {57		/// Overarching event type.58		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;5960		type Balance: Parameter61			+ Member62			+ AtLeast32BitUnsigned63			+ From<up_common::types::Balance>64			+ Codec65			+ Default66			+ Copy67			+ MaybeSerializeDeserialize68			+ Debug69			+ MaxEncodedLen70			+ TypeInfo71			+ FixedPointOperand;7273		#[pallet::constant]74		type DefaultWeightToFeeCoefficient: Get<u64>;75		#[pallet::constant]76		type DefaultMinGasPrice: Get<u64>;7778		#[pallet::constant]79		type MaxXcmAllowedLocations: Get<u32>;80		#[pallet::constant]81		type AppPromotionDailyRate: Get<Perbill>;82		#[pallet::constant]83		type DayRelayBlocks: Get<Self::BlockNumber>;8485		#[pallet::constant]86		type DefaultCollatorSelectionMaxCollators: Get<u32>;87		#[pallet::constant]88		type DefaultCollatorSelectionLicenseBond: Get<Self::Balance>;89		#[pallet::constant]90		type DefaultCollatorSelectionKickThreshold: Get<Self::BlockNumber>;9192		/// The weight information of this pallet.93		type WeightInfo: WeightInfo;94	}9596	#[pallet::event]97	#[pallet::generate_deposit(pub(super) fn deposit_event)]98	pub enum Event<T: Config> {99		NewDesiredCollators {100			desired_collators: Option<u32>,101		},102		NewCollatorLicenseBond {103			bond_cost: Option<T::Balance>,104		},105		NewCollatorKickThreshold {106			length_in_blocks: Option<T::BlockNumber>,107		},108	}109110	fn update_base_fee<T: Config>() {111		let base_fee_per_gas: U256 = <MinGasPriceOverride<T>>::get().into();112		let elasticity: Permill = Permill::zero();113		// twox_128(BaseFee) ++ twox_128(BaseFeePerGas)114		sp_io::storage::set(115			&hex_literal::hex!("c1fef3b7207c11a52df13c12884e77263864ade243c642793ebcfe9e16f454ca"),116			&base_fee_per_gas.encode(),117		);118		// twox_128(BaseFee) ++ twox_128(Elasticity)119		sp_io::storage::set(120			&hex_literal::hex!("c1fef3b7207c11a52df13c12884e772609bc3a1e532c9cb85d57feed02cbff8e"),121			&elasticity.encode(),122		);123	}124125	/// We update our default weights on every release126	#[pallet::hooks]127	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {128		fn on_runtime_upgrade() -> Weight {129			update_base_fee::<T>();130			T::DbWeight::get().reads_writes(1, 2)131		}132	}133134	#[pallet::genesis_config]135	pub struct GenesisConfig<T>(PhantomData<T>);136137	#[cfg(feature = "std")]138	impl<T: Config> Default for GenesisConfig<T> {139		fn default() -> Self {140			Self(Default::default())141		}142	}143144	#[pallet::genesis_build]145	impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {146		fn build(&self) {147			update_base_fee::<T>();148		}149	}150151	#[pallet::error]152	pub enum Error<T> {153		InconsistentConfiguration,154	}155156	#[pallet::storage]157	pub type WeightToFeeCoefficientOverride<T: Config> = StorageValue<158		Value = u64,159		QueryKind = ValueQuery,160		OnEmpty = T::DefaultWeightToFeeCoefficient,161	>;162163	#[pallet::storage]164	pub type MinGasPriceOverride<T: Config> =165		StorageValue<Value = u64, QueryKind = ValueQuery, OnEmpty = T::DefaultMinGasPrice>;166167	#[pallet::storage]168	pub type AppPromomotionConfigurationOverride<T: Config> =169		StorageValue<Value = AppPromotionConfiguration<T::BlockNumber>, QueryKind = ValueQuery>;170171	#[pallet::storage]172	pub type CollatorSelectionDesiredCollatorsOverride<T: Config> = StorageValue<173		Value = u32,174		QueryKind = ValueQuery,175		OnEmpty = T::DefaultCollatorSelectionMaxCollators,176	>;177178	#[pallet::storage]179	pub type CollatorSelectionLicenseBondOverride<T: Config> = StorageValue<180		Value = T::Balance,181		QueryKind = ValueQuery,182		OnEmpty = T::DefaultCollatorSelectionLicenseBond,183	>;184185	#[pallet::storage]186	pub type CollatorSelectionKickThresholdOverride<T: Config> = StorageValue<187		Value = T::BlockNumber,188		QueryKind = ValueQuery,189		OnEmpty = T::DefaultCollatorSelectionKickThreshold,190	>;191192	#[pallet::call]193	impl<T: Config> Pallet<T> {194		#[pallet::call_index(0)]195		#[pallet::weight(T::WeightInfo::set_weight_to_fee_coefficient_override())]196		pub fn set_weight_to_fee_coefficient_override(197			origin: OriginFor<T>,198			coeff: Option<u64>,199		) -> DispatchResult {200			ensure_root(origin)?;201			if let Some(coeff) = coeff {202				<WeightToFeeCoefficientOverride<T>>::set(coeff);203			} else {204				<WeightToFeeCoefficientOverride<T>>::kill();205			}206			Ok(())207		}208209		#[pallet::call_index(1)]210		#[pallet::weight(T::WeightInfo::set_min_gas_price_override())]211		pub fn set_min_gas_price_override(212			origin: OriginFor<T>,213			coeff: Option<u64>,214		) -> DispatchResult {215			ensure_root(origin)?;216			if let Some(coeff) = coeff {217				<MinGasPriceOverride<T>>::set(coeff);218			} else {219				<MinGasPriceOverride<T>>::kill();220			}221			// This code should not be called in production, but why keep development in the222			// inconsistent state223			update_base_fee::<T>();224			Ok(())225		}226227		#[pallet::call_index(3)]228		#[pallet::weight(T::WeightInfo::set_app_promotion_configuration_override())]229		pub fn set_app_promotion_configuration_override(230			origin: OriginFor<T>,231			mut configuration: AppPromotionConfiguration<T::BlockNumber>,232		) -> DispatchResult {233			ensure_root(origin)?;234			if configuration.interval_income.is_some() {235				return Err(<Error<T>>::InconsistentConfiguration.into());236			}237238			configuration.interval_income = configuration.recalculation_interval.map(|b| {239				Perbill::from_rational(b, T::DayRelayBlocks::get())240					* T::AppPromotionDailyRate::get()241			});242243			<AppPromomotionConfigurationOverride<T>>::set(configuration);244245			Ok(())246		}247248		#[pallet::call_index(4)]249		#[pallet::weight(T::WeightInfo::set_collator_selection_desired_collators())]250		pub fn set_collator_selection_desired_collators(251			origin: OriginFor<T>,252			max: Option<u32>,253		) -> DispatchResult {254			ensure_root(origin)?;255			if let Some(max) = max {256				// we trust origin calls, this is just a for more accurate benchmarking257				if max > T::DefaultCollatorSelectionMaxCollators::get() {258					log::warn!("max > T::DefaultCollatorSelectionMaxCollators; you might need to run benchmarks again");259				}260				<CollatorSelectionDesiredCollatorsOverride<T>>::set(max);261			} else {262				<CollatorSelectionDesiredCollatorsOverride<T>>::kill();263			}264			Self::deposit_event(Event::NewDesiredCollators {265				desired_collators: max,266			});267			Ok(())268		}269270		#[pallet::call_index(5)]271		#[pallet::weight(T::WeightInfo::set_collator_selection_license_bond())]272		pub fn set_collator_selection_license_bond(273			origin: OriginFor<T>,274			amount: Option<<T as Config>::Balance>,275		) -> DispatchResult {276			ensure_root(origin)?;277			if let Some(amount) = amount {278				<CollatorSelectionLicenseBondOverride<T>>::set(amount);279			} else {280				<CollatorSelectionLicenseBondOverride<T>>::kill();281			}282			Self::deposit_event(Event::NewCollatorLicenseBond { bond_cost: amount });283			Ok(())284		}285286		#[pallet::call_index(6)]287		#[pallet::weight(T::WeightInfo::set_collator_selection_kick_threshold())]288		pub fn set_collator_selection_kick_threshold(289			origin: OriginFor<T>,290			threshold: Option<T::BlockNumber>,291		) -> DispatchResult {292			ensure_root(origin)?;293			if let Some(threshold) = threshold {294				<CollatorSelectionKickThresholdOverride<T>>::set(threshold);295			} else {296				<CollatorSelectionKickThresholdOverride<T>>::kill();297			}298			Self::deposit_event(Event::NewCollatorKickThreshold {299				length_in_blocks: threshold,300			});301			Ok(())302		}303	}304305	#[pallet::pallet]306	pub struct Pallet<T>(_);307}308309pub struct WeightToFee<T, B>(PhantomData<(T, B)>);310311impl<T, B> WeightToFeePolynomial for WeightToFee<T, B>312where313	T: Config,314	B: BaseArithmetic + From<u32> + From<u64> + Copy + Unsigned,315{316	type Balance = B;317318	fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {319		smallvec!(WeightToFeeCoefficient {320			coeff_integer: (<WeightToFeeCoefficientOverride<T>>::get() / Perbill::ACCURACY as u64)321				.into(),322			coeff_frac: Perbill::from_parts(323				(<WeightToFeeCoefficientOverride<T>>::get() % Perbill::ACCURACY as u64) as u32324			),325			negative: false,326			degree: 1,327		})328	}329}330331pub struct FeeCalculator<T>(PhantomData<T>);332impl<T: Config> fp_evm::FeeCalculator for FeeCalculator<T> {333	fn min_gas_price() -> (U256, Weight) {334		(335			<MinGasPriceOverride<T>>::get().into(),336			T::DbWeight::get().reads(1),337		)338	}339}340341#[derive(Encode, Decode, Clone, Debug, Default, TypeInfo, MaxEncodedLen, PartialEq, PartialOrd)]342pub struct AppPromotionConfiguration<BlockNumber> {343	/// In relay blocks.344	pub recalculation_interval: Option<BlockNumber>,345	/// In parachain blocks.346	pub pending_interval: Option<BlockNumber>,347	/// Value for `RecalculationInterval` based on 0.05% per 24h.348	pub interval_income: Option<Perbill>,349	/// Maximum allowable number of stakers calculated per call of the `app-promotion::PayoutStakers` extrinsic.350	pub max_stakers_per_calculation: Option<u8>,351}