referrerpolicy=no-referrer-when-downgrade

polkadot_runtime_common/
lib.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16
17//! Common runtime code for the Relay Chain, e.g. Rococo, Westend, Polkadot, Kusama ...
18
19#![cfg_attr(not(feature = "std"), no_std)]
20
21pub mod assigned_slots;
22pub mod auctions;
23pub mod claims;
24pub mod crowdloan;
25pub mod elections;
26pub mod identity_migrator;
27pub mod impls;
28pub mod paras_registrar;
29pub mod paras_sudo_wrapper;
30pub mod purchase;
31pub mod slot_range;
32pub mod slots;
33pub mod traits;
34
35#[cfg(feature = "try-runtime")]
36pub mod try_runtime;
37pub mod xcm_sender;
38
39#[cfg(test)]
40mod integration_tests;
41#[cfg(test)]
42mod mock;
43
44extern crate alloc;
45
46use frame_support::{
47	parameter_types,
48	traits::{ConstU32, Currency, OneSessionHandler},
49	weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight},
50};
51use frame_system::limits;
52use polkadot_primitives::{AssignmentId, Balance, BlockNumber, ValidatorId};
53use sp_runtime::{FixedPointNumber, Perbill, Perquintill};
54use static_assertions::const_assert;
55
56pub use pallet_balances::Call as BalancesCall;
57#[cfg(feature = "std")]
58pub use pallet_staking::StakerStatus;
59pub use pallet_timestamp::Call as TimestampCall;
60use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment};
61pub use sp_runtime::traits::Bounded;
62#[cfg(any(feature = "std", test))]
63pub use sp_runtime::BuildStorage;
64
65/// Implementations of some helper traits passed into runtime modules as associated types.
66pub use impls::ToAuthor;
67
68#[deprecated(
69	note = "Please use fungible::Credit instead. This type will be removed some time after March 2024."
70)]
71pub type NegativeImbalance<T> = <pallet_balances::Pallet<T> as Currency<
72	<T as frame_system::Config>::AccountId,
73>>::NegativeImbalance;
74
75/// We assume that an on-initialize consumes 1% of the weight on average, hence a single extrinsic
76/// will not be allowed to consume more than `AvailableBlockRatio - 1%`.
77pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(1);
78/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used
79/// by  Operational  extrinsics.
80pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
81/// We allow for 2 seconds of compute with a 6 second average block time.
82/// The storage proof size is not limited so far.
83pub const MAXIMUM_BLOCK_WEIGHT: Weight =
84	Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX);
85
86const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct());
87
88// Common constants used in all runtimes.
89parameter_types! {
90	pub const BlockHashCount: BlockNumber = 4096;
91	/// The portion of the `NORMAL_DISPATCH_RATIO` that we adjust the fees with. Blocks filled less
92	/// than this will decrease the weight and more will increase.
93	pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25);
94	/// The adjustment variable of the runtime. Higher values will cause `TargetBlockFullness` to
95	/// change the fees more rapidly.
96	pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(75, 1000_000);
97	/// Minimum amount of the multiplier. This value cannot be too low. A test case should ensure
98	/// that combined with `AdjustmentVariable`, we can recover from the minimum.
99	/// See `multiplier_can_grow_from_zero`.
100	pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 10u128);
101	/// The maximum amount of the multiplier.
102	pub MaximumMultiplier: Multiplier = Bounded::max_value();
103	/// Maximum length of block. Up to 5MB.
104	pub BlockLength: limits::BlockLength =
105	limits::BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
106}
107
108/// Parameterized slow adjusting fee updated based on
109/// <https://research.web3.foundation/Polkadot/overview/token-economics#2-slow-adjusting-mechanism>
110pub type SlowAdjustingFeeUpdate<R> = TargetedFeeAdjustment<
111	R,
112	TargetBlockFullness,
113	AdjustmentVariable,
114	MinimumMultiplier,
115	MaximumMultiplier,
116>;
117
118/// Implements the weight types for a runtime.
119/// It expects the passed runtime constants to contain a `weights` module.
120/// The generated weight types were formerly part of the common
121/// runtime but are now runtime dependant.
122#[macro_export]
123macro_rules! impl_runtime_weights {
124	($runtime:ident) => {
125		use frame_support::{dispatch::DispatchClass, weights::Weight};
126		use frame_system::limits;
127		use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment};
128		pub use polkadot_runtime_common::{
129			impl_elections_weights, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT,
130			NORMAL_DISPATCH_RATIO,
131		};
132		use sp_runtime::{FixedPointNumber, Perquintill};
133
134		// Implement the weight types of the elections module.
135		impl_elections_weights!($runtime);
136
137		// Expose the weight from the runtime constants module.
138		pub use $runtime::weights::{
139			BlockExecutionWeight, ExtrinsicBaseWeight, ParityDbWeight, RocksDbWeight,
140		};
141
142		parameter_types! {
143			/// Block weights base values and limits.
144			pub BlockWeights: limits::BlockWeights = limits::BlockWeights::builder()
145				.base_block($runtime::weights::BlockExecutionWeight::get())
146				.for_class(DispatchClass::all(), |weights| {
147					weights.base_extrinsic = $runtime::weights::ExtrinsicBaseWeight::get();
148				})
149				.for_class(DispatchClass::Normal, |weights| {
150					weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
151				})
152				.for_class(DispatchClass::Operational, |weights| {
153					weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
154					// Operational transactions have an extra reserved space, so that they
155					// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
156					weights.reserved = Some(
157						MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT,
158					);
159				})
160				.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
161				.build_or_panic();
162		}
163	};
164}
165
166/// The type used for currency conversion.
167///
168/// This must only be used as long as the balance type is `u128`.
169pub type CurrencyToVote = sp_staking::currency_to_vote::U128CurrencyToVote;
170static_assertions::assert_eq_size!(polkadot_primitives::Balance, u128);
171
172/// A placeholder since there is currently no provided session key handler for parachain validator
173/// keys.
174pub struct ParachainSessionKeyPlaceholder<T>(core::marker::PhantomData<T>);
175impl<T> sp_runtime::BoundToRuntimeAppPublic for ParachainSessionKeyPlaceholder<T> {
176	type Public = ValidatorId;
177}
178
179impl<T: pallet_session::Config> OneSessionHandler<T::AccountId>
180	for ParachainSessionKeyPlaceholder<T>
181{
182	type Key = ValidatorId;
183
184	fn on_genesis_session<'a, I: 'a>(_validators: I)
185	where
186		I: Iterator<Item = (&'a T::AccountId, ValidatorId)>,
187		T::AccountId: 'a,
188	{
189	}
190
191	fn on_new_session<'a, I: 'a>(_changed: bool, _v: I, _q: I)
192	where
193		I: Iterator<Item = (&'a T::AccountId, ValidatorId)>,
194		T::AccountId: 'a,
195	{
196	}
197
198	fn on_disabled(_: u32) {}
199}
200
201/// A placeholder since there is currently no provided session key handler for parachain validator
202/// keys.
203pub struct AssignmentSessionKeyPlaceholder<T>(core::marker::PhantomData<T>);
204impl<T> sp_runtime::BoundToRuntimeAppPublic for AssignmentSessionKeyPlaceholder<T> {
205	type Public = AssignmentId;
206}
207
208impl<T: pallet_session::Config> OneSessionHandler<T::AccountId>
209	for AssignmentSessionKeyPlaceholder<T>
210{
211	type Key = AssignmentId;
212
213	fn on_genesis_session<'a, I: 'a>(_validators: I)
214	where
215		I: Iterator<Item = (&'a T::AccountId, AssignmentId)>,
216		T::AccountId: 'a,
217	{
218	}
219
220	fn on_new_session<'a, I: 'a>(_changed: bool, _v: I, _q: I)
221	where
222		I: Iterator<Item = (&'a T::AccountId, AssignmentId)>,
223		T::AccountId: 'a,
224	{
225	}
226
227	fn on_disabled(_: u32) {}
228}
229
230/// A reasonable benchmarking config for staking pallet.
231pub struct StakingBenchmarkingConfig;
232impl pallet_staking::BenchmarkingConfig for StakingBenchmarkingConfig {
233	type MaxValidators = ConstU32<1000>;
234	type MaxNominators = ConstU32<1000>;
235}
236
237/// Convert a balance to an unsigned 256-bit number, use in nomination pools.
238pub struct BalanceToU256;
239impl sp_runtime::traits::Convert<Balance, sp_core::U256> for BalanceToU256 {
240	fn convert(n: Balance) -> sp_core::U256 {
241		n.into()
242	}
243}
244
245/// Convert an unsigned 256-bit number to balance, use in nomination pools.
246pub struct U256ToBalance;
247impl sp_runtime::traits::Convert<sp_core::U256, Balance> for U256ToBalance {
248	fn convert(n: sp_core::U256) -> Balance {
249		use frame_support::traits::Defensive;
250		n.try_into().defensive_unwrap_or(Balance::MAX)
251	}
252}
253
254/// Macro to set a value (e.g. when using the `parameter_types` macro) to either a production value
255/// or to an environment variable or testing value (in case the `fast-runtime` feature is selected)
256/// or one of two testing values depending on feature.
257/// Note that the environment variable is evaluated _at compile time_.
258///
259/// Usage:
260/// ```Rust
261/// parameter_types! {
262/// 	// Note that the env variable version parameter cannot be const.
263/// 	pub LaunchPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1, "KSM_LAUNCH_PERIOD");
264/// 	pub const VotingPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1 * MINUTES);
265/// 	pub const EpochDuration: BlockNumber =
266/// 		prod_or_fast!(1 * HOURS, "fast-runtime", 1 * MINUTES, "fast-runtime-10m", 10 * MINUTES);
267/// }
268/// ```
269#[macro_export]
270macro_rules! prod_or_fast {
271	($prod:expr, $test:expr) => {
272		if cfg!(feature = "fast-runtime") {
273			$test
274		} else {
275			$prod
276		}
277	};
278	($prod:expr, $test:expr, $env:expr) => {
279		if cfg!(feature = "fast-runtime") {
280			core::option_env!($env).map(|s| s.parse().ok()).flatten().unwrap_or($test)
281		} else {
282			$prod
283		}
284	};
285}