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, 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/// We assume that an on-initialize consumes 1% of the weight on average, hence a single extrinsic
69/// will not be allowed to consume more than `AvailableBlockRatio - 1%`.
70pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(1);
71/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used
72/// by  Operational  extrinsics.
73pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
74/// We allow for 2 seconds of compute with a 6 second average block time.
75/// The storage proof size is not limited so far.
76pub const MAXIMUM_BLOCK_WEIGHT: Weight =
77	Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX);
78
79const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct());
80
81// Common constants used in all runtimes.
82parameter_types! {
83	pub const BlockHashCount: BlockNumber = 4096;
84	/// The portion of the `NORMAL_DISPATCH_RATIO` that we adjust the fees with. Blocks filled less
85	/// than this will decrease the weight and more will increase.
86	pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25);
87	/// The adjustment variable of the runtime. Higher values will cause `TargetBlockFullness` to
88	/// change the fees more rapidly.
89	pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(75, 1000_000);
90	/// Minimum amount of the multiplier. This value cannot be too low. A test case should ensure
91	/// that combined with `AdjustmentVariable`, we can recover from the minimum.
92	/// See `multiplier_can_grow_from_zero`.
93	pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 10u128);
94	/// The maximum amount of the multiplier.
95	pub MaximumMultiplier: Multiplier = Bounded::max_value();
96	/// Maximum length of block. Up to 5MB.
97	pub BlockLength: limits::BlockLength = limits::BlockLength::builder()
98		.max_length(5 * 1024 * 1024)
99		.modify_max_length_for_class(frame_support::dispatch::DispatchClass::Normal, |m| {
100			*m = NORMAL_DISPATCH_RATIO * *m
101		})
102		.build();
103}
104
105/// Parameterized slow adjusting fee updated based on
106/// <https://research.web3.foundation/Polkadot/overview/token-economics#2-slow-adjusting-mechanism>
107pub type SlowAdjustingFeeUpdate<R> = TargetedFeeAdjustment<
108	R,
109	TargetBlockFullness,
110	AdjustmentVariable,
111	MinimumMultiplier,
112	MaximumMultiplier,
113>;
114
115/// Implements the weight types for a runtime.
116/// It expects the passed runtime constants to contain a `weights` module.
117/// The generated weight types were formerly part of the common
118/// runtime but are now runtime dependant.
119#[macro_export]
120macro_rules! impl_runtime_weights {
121	($runtime:ident) => {
122		use frame_support::{dispatch::DispatchClass, weights::Weight};
123		use frame_system::limits;
124		use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment};
125		pub use polkadot_runtime_common::{
126			impl_elections_weights, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT,
127			NORMAL_DISPATCH_RATIO,
128		};
129		use sp_runtime::{FixedPointNumber, Perquintill};
130
131		// Implement the weight types of the elections module.
132		impl_elections_weights!($runtime);
133
134		// Expose the weight from the runtime constants module.
135		pub use $runtime::weights::{
136			BlockExecutionWeight, ExtrinsicBaseWeight, ParityDbWeight, RocksDbWeight,
137		};
138
139		parameter_types! {
140			/// Block weights base values and limits.
141			pub BlockWeights: limits::BlockWeights = limits::BlockWeights::builder()
142				.base_block($runtime::weights::BlockExecutionWeight::get())
143				.for_class(DispatchClass::all(), |weights| {
144					weights.base_extrinsic = $runtime::weights::ExtrinsicBaseWeight::get();
145				})
146				.for_class(DispatchClass::Normal, |weights| {
147					weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
148				})
149				.for_class(DispatchClass::Operational, |weights| {
150					weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
151					// Operational transactions have an extra reserved space, so that they
152					// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
153					weights.reserved = Some(
154						MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT,
155					);
156				})
157				.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
158				.build_or_panic();
159		}
160	};
161}
162
163/// The type used for currency conversion.
164///
165/// This must only be used as long as the balance type is `u128`.
166pub type CurrencyToVote = sp_staking::currency_to_vote::U128CurrencyToVote;
167static_assertions::assert_eq_size!(polkadot_primitives::Balance, u128);
168
169/// A placeholder since there is currently no provided session key handler for parachain validator
170/// keys.
171pub struct ParachainSessionKeyPlaceholder<T>(core::marker::PhantomData<T>);
172impl<T> sp_runtime::BoundToRuntimeAppPublic for ParachainSessionKeyPlaceholder<T> {
173	type Public = ValidatorId;
174}
175
176impl<T: pallet_session::Config> OneSessionHandler<T::AccountId>
177	for ParachainSessionKeyPlaceholder<T>
178{
179	type Key = ValidatorId;
180
181	fn on_genesis_session<'a, I: 'a>(_validators: I)
182	where
183		I: Iterator<Item = (&'a T::AccountId, ValidatorId)>,
184		T::AccountId: 'a,
185	{
186	}
187
188	fn on_new_session<'a, I: 'a>(_changed: bool, _v: I, _q: I)
189	where
190		I: Iterator<Item = (&'a T::AccountId, ValidatorId)>,
191		T::AccountId: 'a,
192	{
193	}
194
195	fn on_disabled(_: u32) {}
196}
197
198/// A placeholder since there is currently no provided session key handler for parachain validator
199/// keys.
200pub struct AssignmentSessionKeyPlaceholder<T>(core::marker::PhantomData<T>);
201impl<T> sp_runtime::BoundToRuntimeAppPublic for AssignmentSessionKeyPlaceholder<T> {
202	type Public = AssignmentId;
203}
204
205impl<T: pallet_session::Config> OneSessionHandler<T::AccountId>
206	for AssignmentSessionKeyPlaceholder<T>
207{
208	type Key = AssignmentId;
209
210	fn on_genesis_session<'a, I: 'a>(_validators: I)
211	where
212		I: Iterator<Item = (&'a T::AccountId, AssignmentId)>,
213		T::AccountId: 'a,
214	{
215	}
216
217	fn on_new_session<'a, I: 'a>(_changed: bool, _v: I, _q: I)
218	where
219		I: Iterator<Item = (&'a T::AccountId, AssignmentId)>,
220		T::AccountId: 'a,
221	{
222	}
223
224	fn on_disabled(_: u32) {}
225}
226
227/// A reasonable benchmarking config for staking pallet.
228pub struct StakingBenchmarkingConfig;
229impl pallet_staking::BenchmarkingConfig for StakingBenchmarkingConfig {
230	type MaxValidators = ConstU32<1000>;
231	type MaxNominators = ConstU32<1000>;
232}
233
234/// Convert a balance to an unsigned 256-bit number, use in nomination pools.
235pub struct BalanceToU256;
236impl sp_runtime::traits::Convert<Balance, sp_core::U256> for BalanceToU256 {
237	fn convert(n: Balance) -> sp_core::U256 {
238		n.into()
239	}
240}
241
242/// Convert an unsigned 256-bit number to balance, use in nomination pools.
243pub struct U256ToBalance;
244impl sp_runtime::traits::Convert<sp_core::U256, Balance> for U256ToBalance {
245	fn convert(n: sp_core::U256) -> Balance {
246		use frame_support::traits::Defensive;
247		n.try_into().defensive_unwrap_or(Balance::MAX)
248	}
249}
250
251/// Macro to set a value (e.g. when using the `parameter_types` macro) to either a production value
252/// or to an environment variable or testing value (in case the `fast-runtime` feature is selected)
253/// or one of two testing values depending on feature.
254/// Note that the environment variable is evaluated _at compile time_.
255///
256/// Usage:
257/// ```Rust
258/// parameter_types! {
259/// 	// Note that the env variable version parameter cannot be const.
260/// 	pub LaunchPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1, "KSM_LAUNCH_PERIOD");
261/// 	pub const VotingPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1 * MINUTES);
262/// 	pub const EpochDuration: BlockNumber =
263/// 		prod_or_fast!(1 * HOURS, "fast-runtime", 1 * MINUTES, "fast-runtime-10m", 10 * MINUTES);
264/// }
265/// ```
266#[macro_export]
267macro_rules! prod_or_fast {
268	($prod:expr, $test:expr) => {
269		if cfg!(feature = "fast-runtime") {
270			$test
271		} else {
272			$prod
273		}
274	};
275	($prod:expr, $test:expr, $env:expr) => {
276		if cfg!(feature = "fast-runtime") {
277			core::option_env!($env).map(|s| s.parse().ok()).flatten().unwrap_or($test)
278		} else {
279			$prod
280		}
281	};
282}