Skip to main content

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 = limits::BlockLength::builder()
105		.max_length(5 * 1024 * 1024)
106		.modify_max_length_for_class(frame_support::dispatch::DispatchClass::Normal, |m| {
107			*m = NORMAL_DISPATCH_RATIO * *m
108		})
109		.build();
110}
111
112/// Parameterized slow adjusting fee updated based on
113/// <https://research.web3.foundation/Polkadot/overview/token-economics#2-slow-adjusting-mechanism>
114pub type SlowAdjustingFeeUpdate<R> = TargetedFeeAdjustment<
115	R,
116	TargetBlockFullness,
117	AdjustmentVariable,
118	MinimumMultiplier,
119	MaximumMultiplier,
120>;
121
122/// Implements the weight types for a runtime.
123/// It expects the passed runtime constants to contain a `weights` module.
124/// The generated weight types were formerly part of the common
125/// runtime but are now runtime dependant.
126#[macro_export]
127macro_rules! impl_runtime_weights {
128	($runtime:ident) => {
129		use frame_support::{dispatch::DispatchClass, weights::Weight};
130		use frame_system::limits;
131		use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment};
132		pub use polkadot_runtime_common::{
133			impl_elections_weights, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT,
134			NORMAL_DISPATCH_RATIO,
135		};
136		use sp_runtime::{FixedPointNumber, Perquintill};
137
138		// Implement the weight types of the elections module.
139		impl_elections_weights!($runtime);
140
141		// Expose the weight from the runtime constants module.
142		pub use $runtime::weights::{
143			BlockExecutionWeight, ExtrinsicBaseWeight, ParityDbWeight, RocksDbWeight,
144		};
145
146		parameter_types! {
147			/// Block weights base values and limits.
148			pub BlockWeights: limits::BlockWeights = limits::BlockWeights::builder()
149				.base_block($runtime::weights::BlockExecutionWeight::get())
150				.for_class(DispatchClass::all(), |weights| {
151					weights.base_extrinsic = $runtime::weights::ExtrinsicBaseWeight::get();
152				})
153				.for_class(DispatchClass::Normal, |weights| {
154					weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
155				})
156				.for_class(DispatchClass::Operational, |weights| {
157					weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
158					// Operational transactions have an extra reserved space, so that they
159					// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
160					weights.reserved = Some(
161						MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT,
162					);
163				})
164				.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
165				.build_or_panic();
166		}
167	};
168}
169
170/// The type used for currency conversion.
171///
172/// This must only be used as long as the balance type is `u128`.
173pub type CurrencyToVote = sp_staking::currency_to_vote::U128CurrencyToVote;
174static_assertions::assert_eq_size!(polkadot_primitives::Balance, u128);
175
176/// A placeholder since there is currently no provided session key handler for parachain validator
177/// keys.
178pub struct ParachainSessionKeyPlaceholder<T>(core::marker::PhantomData<T>);
179impl<T> sp_runtime::BoundToRuntimeAppPublic for ParachainSessionKeyPlaceholder<T> {
180	type Public = ValidatorId;
181}
182
183impl<T: pallet_session::Config> OneSessionHandler<T::AccountId>
184	for ParachainSessionKeyPlaceholder<T>
185{
186	type Key = ValidatorId;
187
188	fn on_genesis_session<'a, I: 'a>(_validators: I)
189	where
190		I: Iterator<Item = (&'a T::AccountId, ValidatorId)>,
191		T::AccountId: 'a,
192	{
193	}
194
195	fn on_new_session<'a, I: 'a>(_changed: bool, _v: I, _q: I)
196	where
197		I: Iterator<Item = (&'a T::AccountId, ValidatorId)>,
198		T::AccountId: 'a,
199	{
200	}
201
202	fn on_disabled(_: u32) {}
203}
204
205/// A placeholder since there is currently no provided session key handler for parachain validator
206/// keys.
207pub struct AssignmentSessionKeyPlaceholder<T>(core::marker::PhantomData<T>);
208impl<T> sp_runtime::BoundToRuntimeAppPublic for AssignmentSessionKeyPlaceholder<T> {
209	type Public = AssignmentId;
210}
211
212impl<T: pallet_session::Config> OneSessionHandler<T::AccountId>
213	for AssignmentSessionKeyPlaceholder<T>
214{
215	type Key = AssignmentId;
216
217	fn on_genesis_session<'a, I: 'a>(_validators: I)
218	where
219		I: Iterator<Item = (&'a T::AccountId, AssignmentId)>,
220		T::AccountId: 'a,
221	{
222	}
223
224	fn on_new_session<'a, I: 'a>(_changed: bool, _v: I, _q: I)
225	where
226		I: Iterator<Item = (&'a T::AccountId, AssignmentId)>,
227		T::AccountId: 'a,
228	{
229	}
230
231	fn on_disabled(_: u32) {}
232}
233
234/// A reasonable benchmarking config for staking pallet.
235pub struct StakingBenchmarkingConfig;
236impl pallet_staking::BenchmarkingConfig for StakingBenchmarkingConfig {
237	type MaxValidators = ConstU32<1000>;
238	type MaxNominators = ConstU32<1000>;
239}
240
241/// Convert a balance to an unsigned 256-bit number, use in nomination pools.
242pub struct BalanceToU256;
243impl sp_runtime::traits::Convert<Balance, sp_core::U256> for BalanceToU256 {
244	fn convert(n: Balance) -> sp_core::U256 {
245		n.into()
246	}
247}
248
249/// Convert an unsigned 256-bit number to balance, use in nomination pools.
250pub struct U256ToBalance;
251impl sp_runtime::traits::Convert<sp_core::U256, Balance> for U256ToBalance {
252	fn convert(n: sp_core::U256) -> Balance {
253		use frame_support::traits::Defensive;
254		n.try_into().defensive_unwrap_or(Balance::MAX)
255	}
256}
257
258/// Macro to set a value (e.g. when using the `parameter_types` macro) to either a production value
259/// or to an environment variable or testing value (in case the `fast-runtime` feature is selected)
260/// or one of two testing values depending on feature.
261/// Note that the environment variable is evaluated _at compile time_.
262///
263/// Usage:
264/// ```Rust
265/// parameter_types! {
266/// 	// Note that the env variable version parameter cannot be const.
267/// 	pub LaunchPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1, "KSM_LAUNCH_PERIOD");
268/// 	pub const VotingPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1 * MINUTES);
269/// 	pub const EpochDuration: BlockNumber =
270/// 		prod_or_fast!(1 * HOURS, "fast-runtime", 1 * MINUTES, "fast-runtime-10m", 10 * MINUTES);
271/// }
272/// ```
273#[macro_export]
274macro_rules! prod_or_fast {
275	($prod:expr, $test:expr) => {
276		if cfg!(feature = "fast-runtime") {
277			$test
278		} else {
279			$prod
280		}
281	};
282	($prod:expr, $test:expr, $env:expr) => {
283		if cfg!(feature = "fast-runtime") {
284			core::option_env!($env).map(|s| s.parse().ok()).flatten().unwrap_or($test)
285		} else {
286			$prod
287		}
288	};
289}