polkadot_runtime/
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//! The Polkadot runtime. This can be compiled with `#[no_std]`, ready for Wasm.
18
19#![cfg_attr(not(feature = "std"), no_std)]
20// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
21#![recursion_limit = "512"]
22
23use pallet_transaction_payment::CurrencyAdapter;
24use runtime_common::{
25	auctions, claims, crowdloan, impl_runtime_weights, impls::DealWithFees, paras_registrar,
26	prod_or_fast, slots, BlockHashCount, BlockLength, CurrencyToVote, SlowAdjustingFeeUpdate,
27};
28
29use runtime_parachains::{
30	assigner_parachains as parachains_assigner_parachains,
31	configuration as parachains_configuration, disputes as parachains_disputes,
32	disputes::slashing as parachains_slashing,
33	dmp as parachains_dmp, hrmp as parachains_hrmp, inclusion as parachains_inclusion,
34	inclusion::{AggregateMessageOrigin, UmpQueueId},
35	initializer as parachains_initializer, origin as parachains_origin, paras as parachains_paras,
36	paras_inherent as parachains_paras_inherent, reward_points as parachains_reward_points,
37	runtime_api_impl::v7 as parachains_runtime_api_impl,
38	scheduler as parachains_scheduler, session_info as parachains_session_info,
39	shared as parachains_shared,
40};
41
42use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
43use beefy_primitives::ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature};
44use frame_election_provider_support::{
45	bounds::ElectionBoundsBuilder, generate_solution_type, onchain, SequentialPhragmen,
46};
47use frame_support::{
48	construct_runtime,
49	genesis_builder_helper::{build_config, create_default_config},
50	parameter_types,
51	traits::{
52		fungible::HoldConsideration, ConstU32, Contains, EitherOf, EitherOfDiverse, EverythingBut,
53		InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, PrivilegeCmp, ProcessMessage,
54		ProcessMessageError, WithdrawReasons,
55	},
56	weights::{ConstantMultiplier, WeightMeter},
57	PalletId,
58};
59use frame_system::EnsureRoot;
60use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId};
61use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
62use pallet_session::historical as session_historical;
63use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
64use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
65use primitives::{
66	slashing, AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash,
67	CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash,
68	Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce,
69	OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes, SessionInfo, Signature,
70	ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, LOWEST_PUBLIC_ID,
71	PARACHAIN_KEY_TYPE_ID,
72};
73use sp_core::OpaqueMetadata;
74use sp_mmr_primitives as mmr;
75use sp_runtime::{
76	create_runtime_str,
77	curve::PiecewiseLinear,
78	generic, impl_opaque_keys,
79	traits::{
80		AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Extrinsic as ExtrinsicT,
81		OpaqueKeys, SaturatedConversion, Verify,
82	},
83	transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity},
84	ApplyExtrinsicResult, FixedU128, KeyTypeId, Perbill, Percent, Permill, RuntimeDebug,
85};
86use sp_staking::SessionIndex;
87use sp_std::{cmp::Ordering, collections::btree_map::BTreeMap, prelude::*};
88#[cfg(any(feature = "std", test))]
89use sp_version::NativeVersion;
90use sp_version::RuntimeVersion;
91use xcm::latest::Junction;
92
93pub use frame_system::Call as SystemCall;
94pub use pallet_balances::Call as BalancesCall;
95pub use pallet_election_provider_multi_phase::{Call as EPMCall, GeometricDepositBase};
96#[cfg(feature = "std")]
97pub use pallet_staking::StakerStatus;
98use pallet_staking::UseValidatorsMap;
99pub use pallet_timestamp::Call as TimestampCall;
100use sp_runtime::traits::Get;
101#[cfg(any(feature = "std", test))]
102pub use sp_runtime::BuildStorage;
103
104/// Constant values used within the runtime.
105use polkadot_runtime_constants::{currency::*, fee::*, time::*};
106
107// Weights used in the runtime.
108mod weights;
109
110mod bag_thresholds;
111
112// Governance configurations.
113pub mod governance;
114use governance::{
115	pallet_custom_origins, AuctionAdmin, FellowshipAdmin, GeneralAdmin, LeaseAdmin, StakingAdmin,
116	Treasurer, TreasurySpender,
117};
118
119pub mod xcm_config;
120
121impl_runtime_weights!(polkadot_runtime_constants);
122
123// Make the WASM binary available.
124#[cfg(feature = "std")]
125include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
126
127// Polkadot version identifier;
128/// Runtime version (Polkadot).
129#[sp_version::runtime_version]
130pub const VERSION: RuntimeVersion = RuntimeVersion {
131	spec_name: create_runtime_str!("polkadot"),
132	impl_name: create_runtime_str!("parity-polkadot"),
133	authoring_version: 0,
134	spec_version: 9430,
135	impl_version: 0,
136	apis: RUNTIME_API_VERSIONS,
137	transaction_version: 24,
138	state_version: 0,
139};
140
141/// The BABE epoch configuration at genesis.
142pub const BABE_GENESIS_EPOCH_CONFIG: babe_primitives::BabeEpochConfiguration =
143	babe_primitives::BabeEpochConfiguration {
144		c: PRIMARY_PROBABILITY,
145		allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots,
146	};
147
148/// Native version.
149#[cfg(any(feature = "std", test))]
150pub fn native_version() -> NativeVersion {
151	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
152}
153
154/// A type to identify calls to the Identity pallet. These will be filtered to prevent invocation,
155/// locking the state of the pallet and preventing further updates to identities and sub-identities.
156/// The locked state will be the genesis state of a new system chain and then removed from the Relay
157/// Chain.
158pub struct IdentityCalls;
159impl Contains<RuntimeCall> for IdentityCalls {
160	fn contains(c: &RuntimeCall) -> bool {
161		matches!(c, RuntimeCall::Identity(_))
162	}
163}
164
165parameter_types! {
166	pub const Version: RuntimeVersion = VERSION;
167	pub const SS58Prefix: u8 = 0;
168}
169
170impl frame_system::Config for Runtime {
171	type BaseCallFilter = EverythingBut<IdentityCalls>;
172	type BlockWeights = BlockWeights;
173	type BlockLength = BlockLength;
174	type RuntimeOrigin = RuntimeOrigin;
175	type RuntimeCall = RuntimeCall;
176	type Nonce = Nonce;
177	type Hash = Hash;
178	type Hashing = BlakeTwo256;
179	type AccountId = AccountId;
180	type Lookup = AccountIdLookup<AccountId, ()>;
181	type Block = Block;
182	type RuntimeEvent = RuntimeEvent;
183	type BlockHashCount = BlockHashCount;
184	type DbWeight = RocksDbWeight;
185	type Version = Version;
186	type PalletInfo = PalletInfo;
187	type AccountData = pallet_balances::AccountData<Balance>;
188	type OnNewAccount = ();
189	type OnKilledAccount = ();
190	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
191	type SS58Prefix = SS58Prefix;
192	type OnSetCode = ();
193	type MaxConsumers = frame_support::traits::ConstU32<16>;
194}
195
196parameter_types! {
197	pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
198		BlockWeights::get().max_block;
199	pub const MaxScheduledPerBlock: u32 = 50;
200	pub const NoPreimagePostponement: Option<u32> = Some(10);
201}
202
203/// Used the compare the privilege of an origin inside the scheduler.
204pub struct OriginPrivilegeCmp;
205
206impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {
207	fn cmp_privilege(left: &OriginCaller, right: &OriginCaller) -> Option<Ordering> {
208		if left == right {
209			return Some(Ordering::Equal)
210		}
211
212		match (left, right) {
213			// Root is greater than anything.
214			(OriginCaller::system(frame_system::RawOrigin::Root), _) => Some(Ordering::Greater),
215			// For every other origin we don't care, as they are not used for `ScheduleOrigin`.
216			_ => None,
217		}
218	}
219}
220
221impl pallet_scheduler::Config for Runtime {
222	type RuntimeOrigin = RuntimeOrigin;
223	type RuntimeEvent = RuntimeEvent;
224	type PalletsOrigin = OriginCaller;
225	type RuntimeCall = RuntimeCall;
226	type MaximumWeight = MaximumSchedulerWeight;
227	// The goal of having ScheduleOrigin include AuctionAdmin is to allow the auctions track of
228	// OpenGov to schedule periodic auctions.
229	// Also allow Treasurer to schedule recurring payments.
230	type ScheduleOrigin = EitherOf<EitherOf<EnsureRoot<AccountId>, AuctionAdmin>, Treasurer>;
231	type MaxScheduledPerBlock = MaxScheduledPerBlock;
232	type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
233	type OriginPrivilegeCmp = OriginPrivilegeCmp;
234	type Preimages = Preimage;
235}
236
237parameter_types! {
238	pub const PreimageBaseDeposit: Balance = deposit(2, 64);
239	pub const PreimageByteDeposit: Balance = deposit(0, 1);
240	pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
241}
242
243impl pallet_preimage::Config for Runtime {
244	type WeightInfo = weights::pallet_preimage::WeightInfo<Runtime>;
245	type RuntimeEvent = RuntimeEvent;
246	type Currency = Balances;
247	type ManagerOrigin = EnsureRoot<AccountId>;
248	type Consideration = HoldConsideration<
249		AccountId,
250		Balances,
251		PreimageHoldReason,
252		LinearStoragePrice<PreimageBaseDeposit, PreimageByteDeposit, Balance>,
253	>;
254}
255
256parameter_types! {
257	pub EpochDuration: u64 = prod_or_fast!(
258		EPOCH_DURATION_IN_SLOTS as u64,
259		2 * MINUTES as u64,
260		"DOT_EPOCH_DURATION"
261	);
262	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
263	pub ReportLongevity: u64 =
264		BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get();
265}
266
267impl pallet_babe::Config for Runtime {
268	type EpochDuration = EpochDuration;
269	type ExpectedBlockTime = ExpectedBlockTime;
270
271	// session module is the trigger
272	type EpochChangeTrigger = pallet_babe::ExternalTrigger;
273
274	type DisabledValidators = Session;
275
276	type WeightInfo = ();
277
278	type MaxAuthorities = MaxAuthorities;
279	type MaxNominators = MaxNominatorRewardedPerValidator;
280
281	type KeyOwnerProof =
282		<Historical as KeyOwnerProofSystem<(KeyTypeId, pallet_babe::AuthorityId)>>::Proof;
283
284	type EquivocationReportSystem =
285		pallet_babe::EquivocationReportSystem<Self, Offences, Historical, ReportLongevity>;
286}
287
288parameter_types! {
289	pub const IndexDeposit: Balance = 10 * DOLLARS;
290}
291
292impl pallet_indices::Config for Runtime {
293	type AccountIndex = AccountIndex;
294	type Currency = Balances;
295	type Deposit = IndexDeposit;
296	type RuntimeEvent = RuntimeEvent;
297	type WeightInfo = weights::pallet_indices::WeightInfo<Runtime>;
298}
299
300parameter_types! {
301	pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
302	pub const MaxLocks: u32 = 50;
303	pub const MaxReserves: u32 = 50;
304}
305
306impl pallet_balances::Config for Runtime {
307	type Balance = Balance;
308	type DustRemoval = ();
309	type RuntimeEvent = RuntimeEvent;
310	type ExistentialDeposit = ExistentialDeposit;
311	type AccountStore = System;
312	type MaxLocks = MaxLocks;
313	type MaxReserves = MaxReserves;
314	type ReserveIdentifier = [u8; 8];
315	type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
316	type RuntimeHoldReason = RuntimeHoldReason;
317	type FreezeIdentifier = ();
318	type MaxHolds = ConstU32<1>;
319	type MaxFreezes = ConstU32<0>;
320}
321
322parameter_types! {
323	pub const TransactionByteFee: Balance = 10 * MILLICENTS;
324	/// This value increases the priority of `Operational` transactions by adding
325	/// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
326	pub const OperationalFeeMultiplier: u8 = 5;
327}
328
329impl pallet_transaction_payment::Config for Runtime {
330	type RuntimeEvent = RuntimeEvent;
331	type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees<Runtime>>;
332	type OperationalFeeMultiplier = OperationalFeeMultiplier;
333	type WeightToFee = WeightToFee;
334	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
335	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
336}
337
338parameter_types! {
339	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
340}
341impl pallet_timestamp::Config for Runtime {
342	type Moment = u64;
343	type OnTimestampSet = Babe;
344	type MinimumPeriod = MinimumPeriod;
345	type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
346}
347
348impl pallet_authorship::Config for Runtime {
349	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
350	type EventHandler = (Staking, ImOnline);
351}
352
353impl_opaque_keys! {
354	pub struct SessionKeys {
355		pub grandpa: Grandpa,
356		pub babe: Babe,
357		pub im_online: ImOnline,
358		pub para_validator: Initializer,
359		pub para_assignment: ParaSessionInfo,
360		pub authority_discovery: AuthorityDiscovery,
361	}
362}
363
364impl pallet_session::Config for Runtime {
365	type RuntimeEvent = RuntimeEvent;
366	type ValidatorId = AccountId;
367	type ValidatorIdOf = pallet_staking::StashOf<Self>;
368	type ShouldEndSession = Babe;
369	type NextSessionRotation = Babe;
370	type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, Staking>;
371	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
372	type Keys = SessionKeys;
373	type WeightInfo = weights::pallet_session::WeightInfo<Runtime>;
374}
375
376impl pallet_session::historical::Config for Runtime {
377	type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
378	type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
379}
380
381parameter_types! {
382	// phase durations. 1/4 of the last session for each.
383	// in testing: 1min or half of the session for each
384	pub SignedPhase: u32 = prod_or_fast!(
385		EPOCH_DURATION_IN_SLOTS / 4,
386		(1 * MINUTES).min(EpochDuration::get().saturated_into::<u32>() / 2),
387		"DOT_SIGNED_PHASE"
388	);
389	pub UnsignedPhase: u32 = prod_or_fast!(
390		EPOCH_DURATION_IN_SLOTS / 4,
391		(1 * MINUTES).min(EpochDuration::get().saturated_into::<u32>() / 2),
392		"DOT_UNSIGNED_PHASE"
393	);
394
395	// signed config
396	pub const SignedMaxSubmissions: u32 = 16;
397	pub const SignedMaxRefunds: u32 = 16 / 4;
398	pub const SignedFixedDeposit: Balance = deposit(2, 0);
399	pub const SignedDepositIncreaseFactor: Percent = Percent::from_percent(10);
400	// 40 DOTs fixed deposit..
401	pub const SignedDepositBase: Balance = deposit(2, 0);
402	// 0.01 DOT per KB of solution data.
403	pub const SignedDepositByte: Balance = deposit(0, 10) / 1024;
404	// Each good submission will get 1 DOT as reward
405	pub SignedRewardBase: Balance = 1 * UNITS;
406	pub BetterUnsignedThreshold: Perbill = Perbill::from_rational(5u32, 10_000);
407
408	// 4 hour session, 1 hour unsigned phase, 32 offchain executions.
409	pub OffchainRepeat: BlockNumber = UnsignedPhase::get() / 32;
410
411	pub const MaxElectingVoters: u32 = 22_500;
412	/// We take the top 22500 nominators as electing voters and all of the validators as electable
413	/// targets. Whilst this is the case, we cannot and shall not increase the size of the
414	/// validator intentions.
415	pub ElectionBounds: frame_election_provider_support::bounds::ElectionBounds =
416		ElectionBoundsBuilder::default().voters_count(MaxElectingVoters::get().into()).build();
417	/// Setup election pallet to support maximum winners upto 1200. This will mean Staking Pallet
418	/// cannot have active validators higher than this count.
419	pub const MaxActiveValidators: u32 = 1200;
420}
421
422generate_solution_type!(
423	#[compact]
424	pub struct NposCompactSolution16::<
425		VoterIndex = u32,
426		TargetIndex = u16,
427		Accuracy = sp_runtime::PerU16,
428		MaxVoters = MaxElectingVoters,
429	>(16)
430);
431
432pub struct OnChainSeqPhragmen;
433impl onchain::Config for OnChainSeqPhragmen {
434	type System = Runtime;
435	type Solver = SequentialPhragmen<AccountId, runtime_common::elections::OnChainAccuracy>;
436	type DataProvider = Staking;
437	type WeightInfo = weights::frame_election_provider_support::WeightInfo<Runtime>;
438	type MaxWinners = MaxActiveValidators;
439	type Bounds = ElectionBounds;
440}
441
442impl pallet_election_provider_multi_phase::MinerConfig for Runtime {
443	type AccountId = AccountId;
444	type MaxLength = OffchainSolutionLengthLimit;
445	type MaxWeight = OffchainSolutionWeightLimit;
446	type Solution = NposCompactSolution16;
447	type MaxVotesPerVoter = <
448		<Self as pallet_election_provider_multi_phase::Config>::DataProvider
449		as
450		frame_election_provider_support::ElectionDataProvider
451	>::MaxVotesPerVoter;
452	type MaxWinners = MaxActiveValidators;
453
454	// The unsigned submissions have to respect the weight of the submit_unsigned call, thus their
455	// weight estimate function is wired to this call's weight.
456	fn solution_weight(v: u32, t: u32, a: u32, d: u32) -> Weight {
457		<
458			<Self as pallet_election_provider_multi_phase::Config>::WeightInfo
459			as
460			pallet_election_provider_multi_phase::WeightInfo
461		>::submit_unsigned(v, t, a, d)
462	}
463}
464
465impl pallet_election_provider_multi_phase::Config for Runtime {
466	type RuntimeEvent = RuntimeEvent;
467	type Currency = Balances;
468	type EstimateCallFee = TransactionPayment;
469	type SignedPhase = SignedPhase;
470	type UnsignedPhase = UnsignedPhase;
471	type SignedMaxSubmissions = SignedMaxSubmissions;
472	type SignedMaxRefunds = SignedMaxRefunds;
473	type SignedRewardBase = SignedRewardBase;
474	type SignedDepositBase =
475		GeometricDepositBase<Balance, SignedFixedDeposit, SignedDepositIncreaseFactor>;
476	type SignedDepositByte = SignedDepositByte;
477	type SignedDepositWeight = ();
478	type SignedMaxWeight =
479		<Self::MinerConfig as pallet_election_provider_multi_phase::MinerConfig>::MaxWeight;
480	type MinerConfig = Self;
481	type SlashHandler = (); // burn slashes
482	type RewardHandler = (); // nothing to do upon rewards
483	type BetterUnsignedThreshold = BetterUnsignedThreshold;
484	type BetterSignedThreshold = ();
485	type OffchainRepeat = OffchainRepeat;
486	type MinerTxPriority = NposSolutionPriority;
487	type DataProvider = Staking;
488	#[cfg(any(feature = "fast-runtime", feature = "runtime-benchmarks"))]
489	type Fallback = onchain::OnChainExecution<OnChainSeqPhragmen>;
490	#[cfg(not(any(feature = "fast-runtime", feature = "runtime-benchmarks")))]
491	type Fallback = frame_election_provider_support::NoElection<(
492		AccountId,
493		BlockNumber,
494		Staking,
495		MaxActiveValidators,
496	)>;
497	type GovernanceFallback = onchain::OnChainExecution<OnChainSeqPhragmen>;
498	type Solver = SequentialPhragmen<
499		AccountId,
500		pallet_election_provider_multi_phase::SolutionAccuracyOf<Self>,
501		(),
502	>;
503	type BenchmarkingConfig = runtime_common::elections::BenchmarkConfig;
504	type ForceOrigin = EitherOf<EnsureRoot<Self::AccountId>, StakingAdmin>;
505	type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Self>;
506	type MaxWinners = MaxActiveValidators;
507	type ElectionBounds = ElectionBounds;
508}
509
510parameter_types! {
511	pub const BagThresholds: &'static [u64] = &bag_thresholds::THRESHOLDS;
512}
513
514type VoterBagsListInstance = pallet_bags_list::Instance1;
515impl pallet_bags_list::Config<VoterBagsListInstance> for Runtime {
516	type RuntimeEvent = RuntimeEvent;
517	type ScoreProvider = Staking;
518	type WeightInfo = weights::pallet_bags_list::WeightInfo<Runtime>;
519	type BagThresholds = BagThresholds;
520	type Score = sp_npos_elections::VoteWeight;
521}
522
523// TODO #6469: This shouldn't be static, but a lazily cached value, not built unless needed, and
524// re-built in case input parameters have changed. The `ideal_stake` should be determined by the
525// amount of parachain slots being bid on: this should be around `(75 - 25.min(slots / 4))%`.
526pallet_staking_reward_curve::build! {
527	const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
528		min_inflation: 0_025_000,
529		max_inflation: 0_100_000,
530		// 3:2:1 staked : parachains : float.
531		// while there's no parachains, then this is 75% staked : 25% float.
532		ideal_stake: 0_750_000,
533		falloff: 0_050_000,
534		max_piece_count: 40,
535		test_precision: 0_005_000,
536	);
537}
538
539parameter_types! {
540	// Six sessions in an era (24 hours).
541	pub const SessionsPerEra: SessionIndex = prod_or_fast!(6, 1);
542
543	// 28 eras for unbonding (28 days).
544	pub BondingDuration: sp_staking::EraIndex = prod_or_fast!(
545		28,
546		28,
547		"DOT_BONDING_DURATION"
548	);
549	pub SlashDeferDuration: sp_staking::EraIndex = prod_or_fast!(
550		27,
551		27,
552		"DOT_SLASH_DEFER_DURATION"
553	);
554	pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
555	pub const MaxNominatorRewardedPerValidator: u32 = 512;
556	pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17);
557	// 16
558	pub const MaxNominations: u32 = <NposCompactSolution16 as frame_election_provider_support::NposSolution>::LIMIT as u32;
559}
560
561pub struct EraPayout;
562impl pallet_staking::EraPayout<Balance> for EraPayout {
563	fn era_payout(
564		total_staked: Balance,
565		total_issuance: Balance,
566		era_duration_millis: u64,
567	) -> (Balance, Balance) {
568		// all para-ids that are not active.
569		let auctioned_slots = Paras::parachains()
570			.into_iter()
571			// all active para-ids that do not belong to a system chain is the number
572			// of parachains that we should take into account for inflation.
573			.filter(|i| *i >= LOWEST_PUBLIC_ID)
574			.count() as u64;
575
576		const MAX_ANNUAL_INFLATION: Perquintill = Perquintill::from_percent(10);
577		const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100;
578
579		runtime_common::impls::era_payout(
580			total_staked,
581			total_issuance,
582			MAX_ANNUAL_INFLATION,
583			Perquintill::from_rational(era_duration_millis, MILLISECONDS_PER_YEAR),
584			auctioned_slots,
585		)
586	}
587}
588
589impl pallet_staking::Config for Runtime {
590	type Currency = Balances;
591	type CurrencyBalance = Balance;
592	type UnixTime = Timestamp;
593	type CurrencyToVote = CurrencyToVote;
594	type RewardRemainder = Treasury;
595	type RuntimeEvent = RuntimeEvent;
596	type Slash = Treasury;
597	type Reward = ();
598	type SessionsPerEra = SessionsPerEra;
599	type BondingDuration = BondingDuration;
600	type SlashDeferDuration = SlashDeferDuration;
601	type AdminOrigin = EitherOf<EnsureRoot<Self::AccountId>, StakingAdmin>;
602	type SessionInterface = Self;
603	type EraPayout = EraPayout;
604	type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
605	type OffendingValidatorsThreshold = OffendingValidatorsThreshold;
606	type NextNewSession = Session;
607	type ElectionProvider = ElectionProviderMultiPhase;
608	type GenesisElectionProvider = onchain::OnChainExecution<OnChainSeqPhragmen>;
609	type VoterList = VoterList;
610	type TargetList = UseValidatorsMap<Self>;
611	type NominationsQuota = pallet_staking::FixedNominationsQuota<{ MaxNominations::get() }>;
612	type MaxUnlockingChunks = frame_support::traits::ConstU32<32>;
613	type HistoryDepth = frame_support::traits::ConstU32<84>;
614	type BenchmarkingConfig = runtime_common::StakingBenchmarkingConfig;
615	type EventListeners = NominationPools;
616	type WeightInfo = weights::pallet_staking::WeightInfo<Runtime>;
617}
618
619impl pallet_fast_unstake::Config for Runtime {
620	type RuntimeEvent = RuntimeEvent;
621	type Currency = Balances;
622	type BatchSize = frame_support::traits::ConstU32<16>;
623	type Deposit = frame_support::traits::ConstU128<{ UNITS }>;
624	type ControlOrigin = EnsureRoot<AccountId>;
625	type Staking = Staking;
626	type MaxErasToCheckPerBlock = ConstU32<1>;
627	#[cfg(feature = "runtime-benchmarks")]
628	type MaxBackersPerValidator = MaxNominatorRewardedPerValidator;
629	type WeightInfo = weights::pallet_fast_unstake::WeightInfo<Runtime>;
630}
631
632parameter_types! {
633	// Minimum 4 CENTS/byte
634	pub const BasicDeposit: Balance = deposit(1, 258);
635	pub const FieldDeposit: Balance = deposit(0, 66);
636	pub const SubAccountDeposit: Balance = deposit(1, 53);
637	pub const MaxSubAccounts: u32 = 100;
638	pub const MaxAdditionalFields: u32 = 100;
639	pub const MaxRegistrars: u32 = 20;
640}
641
642impl pallet_identity::Config for Runtime {
643	type RuntimeEvent = RuntimeEvent;
644	type Currency = Balances;
645	type BasicDeposit = BasicDeposit;
646	type FieldDeposit = FieldDeposit;
647	type SubAccountDeposit = SubAccountDeposit;
648	type MaxSubAccounts = MaxSubAccounts;
649	type MaxAdditionalFields = MaxAdditionalFields;
650	type MaxRegistrars = MaxRegistrars;
651	type Slashed = Treasury;
652	type ForceOrigin = EitherOf<EnsureRoot<Self::AccountId>, GeneralAdmin>;
653	type RegistrarOrigin = EitherOf<EnsureRoot<Self::AccountId>, GeneralAdmin>;
654	type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
655}
656
657parameter_types! {
658	pub const ProposalBond: Permill = Permill::from_percent(5);
659	pub const ProposalBondMinimum: Balance = 100 * DOLLARS;
660	pub const ProposalBondMaximum: Balance = 500 * DOLLARS;
661	pub const SpendPeriod: BlockNumber = 24 * DAYS;
662	pub const Burn: Permill = Permill::from_percent(1);
663	pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
664
665	pub const TipCountdown: BlockNumber = 1 * DAYS;
666	pub const TipFindersFee: Percent = Percent::from_percent(20);
667	pub const TipReportDepositBase: Balance = 1 * DOLLARS;
668	pub const DataDepositPerByte: Balance = 1 * CENTS;
669	pub const MaxApprovals: u32 = 100;
670	pub const MaxAuthorities: u32 = 100_000;
671	pub const MaxKeys: u32 = 10_000;
672	pub const MaxPeerInHeartbeats: u32 = 10_000;
673	pub const RootSpendOriginMaxAmount: Balance = Balance::MAX;
674	pub const CouncilSpendOriginMaxAmount: Balance = Balance::MAX;
675}
676
677impl pallet_treasury::Config for Runtime {
678	type PalletId = TreasuryPalletId;
679	type Currency = Balances;
680	type ApproveOrigin = EitherOfDiverse<EnsureRoot<AccountId>, Treasurer>;
681	type RejectOrigin = EitherOfDiverse<EnsureRoot<AccountId>, Treasurer>;
682	type RuntimeEvent = RuntimeEvent;
683	type OnSlash = Treasury;
684	type ProposalBond = ProposalBond;
685	type ProposalBondMinimum = ProposalBondMinimum;
686	type ProposalBondMaximum = ProposalBondMaximum;
687	type SpendPeriod = SpendPeriod;
688	type Burn = Burn;
689	type BurnDestination = ();
690	type SpendFunds = Bounties;
691	type MaxApprovals = MaxApprovals;
692	type WeightInfo = weights::pallet_treasury::WeightInfo<Runtime>;
693	type SpendOrigin = TreasurySpender;
694}
695
696parameter_types! {
697	pub const BountyDepositBase: Balance = 1 * DOLLARS;
698	pub const BountyDepositPayoutDelay: BlockNumber = 8 * DAYS;
699	pub const BountyUpdatePeriod: BlockNumber = 90 * DAYS;
700	pub const MaximumReasonLength: u32 = 16384;
701	pub const CuratorDepositMultiplier: Permill = Permill::from_percent(50);
702	pub const CuratorDepositMin: Balance = 10 * DOLLARS;
703	pub const CuratorDepositMax: Balance = 200 * DOLLARS;
704	pub const BountyValueMinimum: Balance = 10 * DOLLARS;
705}
706
707impl pallet_bounties::Config for Runtime {
708	type RuntimeEvent = RuntimeEvent;
709	type BountyDepositBase = BountyDepositBase;
710	type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
711	type BountyUpdatePeriod = BountyUpdatePeriod;
712	type CuratorDepositMultiplier = CuratorDepositMultiplier;
713	type CuratorDepositMin = CuratorDepositMin;
714	type CuratorDepositMax = CuratorDepositMax;
715	type BountyValueMinimum = BountyValueMinimum;
716	type ChildBountyManager = ChildBounties;
717	type DataDepositPerByte = DataDepositPerByte;
718	type MaximumReasonLength = MaximumReasonLength;
719	type WeightInfo = weights::pallet_bounties::WeightInfo<Runtime>;
720}
721
722parameter_types! {
723	pub const MaxActiveChildBountyCount: u32 = 100;
724	pub const ChildBountyValueMinimum: Balance = BountyValueMinimum::get() / 10;
725}
726
727impl pallet_child_bounties::Config for Runtime {
728	type RuntimeEvent = RuntimeEvent;
729	type MaxActiveChildBountyCount = MaxActiveChildBountyCount;
730	type ChildBountyValueMinimum = ChildBountyValueMinimum;
731	type WeightInfo = weights::pallet_child_bounties::WeightInfo<Runtime>;
732}
733
734impl pallet_offences::Config for Runtime {
735	type RuntimeEvent = RuntimeEvent;
736	type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
737	type OnOffenceHandler = Staking;
738}
739
740impl pallet_authority_discovery::Config for Runtime {
741	type MaxAuthorities = MaxAuthorities;
742}
743
744parameter_types! {
745	pub NposSolutionPriority: TransactionPriority =
746		Perbill::from_percent(90) * TransactionPriority::max_value();
747	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
748}
749
750impl pallet_im_online::Config for Runtime {
751	type AuthorityId = ImOnlineId;
752	type RuntimeEvent = RuntimeEvent;
753	type ValidatorSet = Historical;
754	type NextSessionRotation = Babe;
755	type ReportUnresponsiveness = Offences;
756	type UnsignedPriority = ImOnlineUnsignedPriority;
757	type WeightInfo = weights::pallet_im_online::WeightInfo<Runtime>;
758	type MaxKeys = MaxKeys;
759	type MaxPeerInHeartbeats = MaxPeerInHeartbeats;
760}
761
762parameter_types! {
763	pub MaxSetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get();
764}
765
766impl pallet_grandpa::Config for Runtime {
767	type RuntimeEvent = RuntimeEvent;
768
769	type WeightInfo = ();
770	type MaxAuthorities = MaxAuthorities;
771	type MaxNominators = MaxNominatorRewardedPerValidator;
772	type MaxSetIdSessionEntries = MaxSetIdSessionEntries;
773
774	type KeyOwnerProof = <Historical as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
775
776	type EquivocationReportSystem =
777		pallet_grandpa::EquivocationReportSystem<Self, Offences, Historical, ReportLongevity>;
778}
779
780/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
781/// format of the chain.
782impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
783where
784	RuntimeCall: From<LocalCall>,
785{
786	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
787		call: RuntimeCall,
788		public: <Signature as Verify>::Signer,
789		account: AccountId,
790		nonce: <Runtime as frame_system::Config>::Nonce,
791	) -> Option<(RuntimeCall, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
792		use sp_runtime::traits::StaticLookup;
793		// take the biggest period possible.
794		let period =
795			BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64;
796
797		let current_block = System::block_number()
798			.saturated_into::<u64>()
799			// The `System::block_number` is initialized with `n+1`,
800			// so the actual block number is `n`.
801			.saturating_sub(1);
802		let tip = 0;
803		let extra: SignedExtra = (
804			frame_system::CheckNonZeroSender::<Runtime>::new(),
805			frame_system::CheckSpecVersion::<Runtime>::new(),
806			frame_system::CheckTxVersion::<Runtime>::new(),
807			frame_system::CheckGenesis::<Runtime>::new(),
808			frame_system::CheckMortality::<Runtime>::from(generic::Era::mortal(
809				period,
810				current_block,
811			)),
812			frame_system::CheckNonce::<Runtime>::from(nonce),
813			frame_system::CheckWeight::<Runtime>::new(),
814			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
815			claims::PrevalidateAttests::<Runtime>::new(),
816		);
817		let raw_payload = SignedPayload::new(call, extra)
818			.map_err(|e| {
819				log::warn!("Unable to create signed payload: {:?}", e);
820			})
821			.ok()?;
822		let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?;
823		let (call, extra, _) = raw_payload.deconstruct();
824		let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
825		Some((call, (address, signature, extra)))
826	}
827}
828
829impl frame_system::offchain::SigningTypes for Runtime {
830	type Public = <Signature as Verify>::Signer;
831	type Signature = Signature;
832}
833
834impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
835where
836	RuntimeCall: From<C>,
837{
838	type Extrinsic = UncheckedExtrinsic;
839	type OverarchingCall = RuntimeCall;
840}
841
842parameter_types! {
843	// Deposit for a parathread (on-demand parachain)
844	pub const ParathreadDeposit: Balance = 500 * DOLLARS;
845	pub const MaxRetries: u32 = 3;
846}
847
848parameter_types! {
849	pub Prefix: &'static [u8] = b"Pay DOTs to the Polkadot account:";
850}
851
852impl claims::Config for Runtime {
853	type RuntimeEvent = RuntimeEvent;
854	type VestingSchedule = Vesting;
855	type Prefix = Prefix;
856	/// Only Root can move a claim.
857	type MoveClaimOrigin = EnsureRoot<AccountId>;
858	type WeightInfo = weights::runtime_common_claims::WeightInfo<Runtime>;
859}
860
861parameter_types! {
862	pub const MinVestedTransfer: Balance = 1 * DOLLARS;
863	pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons =
864		WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE);
865}
866
867impl pallet_vesting::Config for Runtime {
868	type RuntimeEvent = RuntimeEvent;
869	type Currency = Balances;
870	type BlockNumberToBalance = ConvertInto;
871	type MinVestedTransfer = MinVestedTransfer;
872	type WeightInfo = weights::pallet_vesting::WeightInfo<Runtime>;
873	type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons;
874	const MAX_VESTING_SCHEDULES: u32 = 28;
875}
876
877impl pallet_utility::Config for Runtime {
878	type RuntimeEvent = RuntimeEvent;
879	type RuntimeCall = RuntimeCall;
880	type PalletsOrigin = OriginCaller;
881	type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
882}
883
884parameter_types! {
885	// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
886	pub const DepositBase: Balance = deposit(1, 88);
887	// Additional storage item size of 32 bytes.
888	pub const DepositFactor: Balance = deposit(0, 32);
889	pub const MaxSignatories: u32 = 100;
890}
891
892impl pallet_multisig::Config for Runtime {
893	type RuntimeEvent = RuntimeEvent;
894	type RuntimeCall = RuntimeCall;
895	type Currency = Balances;
896	type DepositBase = DepositBase;
897	type DepositFactor = DepositFactor;
898	type MaxSignatories = MaxSignatories;
899	type WeightInfo = weights::pallet_multisig::WeightInfo<Runtime>;
900}
901
902parameter_types! {
903	// One storage item; key size 32, value size 8; .
904	pub const ProxyDepositBase: Balance = deposit(1, 8);
905	// Additional storage item size of 33 bytes.
906	pub const ProxyDepositFactor: Balance = deposit(0, 33);
907	pub const MaxProxies: u16 = 32;
908	pub const AnnouncementDepositBase: Balance = deposit(1, 8);
909	pub const AnnouncementDepositFactor: Balance = deposit(0, 66);
910	pub const MaxPending: u16 = 32;
911}
912
913/// The type used to represent the kinds of proxying allowed.
914#[derive(
915	Copy,
916	Clone,
917	Eq,
918	PartialEq,
919	Ord,
920	PartialOrd,
921	Encode,
922	Decode,
923	RuntimeDebug,
924	MaxEncodedLen,
925	scale_info::TypeInfo,
926)]
927pub enum ProxyType {
928	Any = 0,
929	NonTransfer = 1,
930	Governance = 2,
931	Staking = 3,
932	// Skip 4 as it is now removed (was SudoBalances)
933	IdentityJudgement = 5,
934	CancelProxy = 6,
935	Auction = 7,
936	NominationPools = 8,
937}
938
939#[cfg(test)]
940mod proxy_type_tests {
941	use super::*;
942
943	#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug)]
944	pub enum OldProxyType {
945		Any,
946		NonTransfer,
947		Governance,
948		Staking,
949		SudoBalances,
950		IdentityJudgement,
951	}
952
953	#[test]
954	fn proxy_type_decodes_correctly() {
955		for (i, j) in vec![
956			(OldProxyType::Any, ProxyType::Any),
957			(OldProxyType::NonTransfer, ProxyType::NonTransfer),
958			(OldProxyType::Governance, ProxyType::Governance),
959			(OldProxyType::Staking, ProxyType::Staking),
960			(OldProxyType::IdentityJudgement, ProxyType::IdentityJudgement),
961		]
962		.into_iter()
963		{
964			assert_eq!(i.encode(), j.encode());
965		}
966		assert!(ProxyType::decode(&mut &OldProxyType::SudoBalances.encode()[..]).is_err());
967	}
968}
969
970impl Default for ProxyType {
971	fn default() -> Self {
972		Self::Any
973	}
974}
975impl InstanceFilter<RuntimeCall> for ProxyType {
976	fn filter(&self, c: &RuntimeCall) -> bool {
977		match self {
978			ProxyType::Any => true,
979			ProxyType::NonTransfer => matches!(
980				c,
981				RuntimeCall::System(..) |
982				RuntimeCall::Scheduler(..) |
983				RuntimeCall::Babe(..) |
984				RuntimeCall::Timestamp(..) |
985				RuntimeCall::Indices(pallet_indices::Call::claim{..}) |
986				RuntimeCall::Indices(pallet_indices::Call::free{..}) |
987				RuntimeCall::Indices(pallet_indices::Call::freeze{..}) |
988				// Specifically omitting Indices `transfer`, `force_transfer`
989				// Specifically omitting the entire Balances pallet
990				RuntimeCall::Staking(..) |
991				RuntimeCall::Session(..) |
992				RuntimeCall::Grandpa(..) |
993				RuntimeCall::ImOnline(..) |
994				RuntimeCall::Treasury(..) |
995				RuntimeCall::Bounties(..) |
996				RuntimeCall::ChildBounties(..) |
997				RuntimeCall::ConvictionVoting(..) |
998				RuntimeCall::Referenda(..) |
999				RuntimeCall::Whitelist(..) |
1000				RuntimeCall::Claims(..) |
1001				RuntimeCall::Vesting(pallet_vesting::Call::vest{..}) |
1002				RuntimeCall::Vesting(pallet_vesting::Call::vest_other{..}) |
1003				// Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer`
1004				RuntimeCall::Utility(..) |
1005				RuntimeCall::Identity(..) |
1006				RuntimeCall::Proxy(..) |
1007				RuntimeCall::Multisig(..) |
1008				RuntimeCall::Registrar(paras_registrar::Call::register {..}) |
1009				RuntimeCall::Registrar(paras_registrar::Call::deregister {..}) |
1010				// Specifically omitting Registrar `swap`
1011				RuntimeCall::Registrar(paras_registrar::Call::reserve {..}) |
1012				RuntimeCall::Crowdloan(..) |
1013				RuntimeCall::Slots(..) |
1014				RuntimeCall::Auctions(..) | // Specifically omitting the entire XCM Pallet
1015				RuntimeCall::VoterList(..) |
1016				RuntimeCall::NominationPools(..) |
1017				RuntimeCall::FastUnstake(..)
1018			),
1019			ProxyType::Governance => matches!(
1020				c,
1021				RuntimeCall::Treasury(..) |
1022					RuntimeCall::Bounties(..) |
1023					RuntimeCall::Utility(..) |
1024					RuntimeCall::ChildBounties(..) |
1025					RuntimeCall::ConvictionVoting(..) |
1026					RuntimeCall::Referenda(..) |
1027					RuntimeCall::Whitelist(..)
1028			),
1029			ProxyType::Staking => {
1030				matches!(
1031					c,
1032					RuntimeCall::Staking(..) |
1033						RuntimeCall::Session(..) | RuntimeCall::Utility(..) |
1034						RuntimeCall::FastUnstake(..) |
1035						RuntimeCall::VoterList(..) |
1036						RuntimeCall::NominationPools(..)
1037				)
1038			},
1039			ProxyType::NominationPools => {
1040				matches!(c, RuntimeCall::NominationPools(..) | RuntimeCall::Utility(..))
1041			},
1042			ProxyType::IdentityJudgement => matches!(
1043				c,
1044				RuntimeCall::Identity(pallet_identity::Call::provide_judgement { .. }) |
1045					RuntimeCall::Utility(..)
1046			),
1047			ProxyType::CancelProxy => {
1048				matches!(c, RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }))
1049			},
1050			ProxyType::Auction => matches!(
1051				c,
1052				RuntimeCall::Auctions(..) |
1053					RuntimeCall::Crowdloan(..) |
1054					RuntimeCall::Registrar(..) |
1055					RuntimeCall::Slots(..)
1056			),
1057		}
1058	}
1059	fn is_superset(&self, o: &Self) -> bool {
1060		match (self, o) {
1061			(x, y) if x == y => true,
1062			(ProxyType::Any, _) => true,
1063			(_, ProxyType::Any) => false,
1064			(ProxyType::NonTransfer, _) => true,
1065			_ => false,
1066		}
1067	}
1068}
1069
1070impl pallet_proxy::Config for Runtime {
1071	type RuntimeEvent = RuntimeEvent;
1072	type RuntimeCall = RuntimeCall;
1073	type Currency = Balances;
1074	type ProxyType = ProxyType;
1075	type ProxyDepositBase = ProxyDepositBase;
1076	type ProxyDepositFactor = ProxyDepositFactor;
1077	type MaxProxies = MaxProxies;
1078	type WeightInfo = weights::pallet_proxy::WeightInfo<Runtime>;
1079	type MaxPending = MaxPending;
1080	type CallHasher = BlakeTwo256;
1081	type AnnouncementDepositBase = AnnouncementDepositBase;
1082	type AnnouncementDepositFactor = AnnouncementDepositFactor;
1083}
1084
1085impl parachains_origin::Config for Runtime {}
1086
1087impl parachains_configuration::Config for Runtime {
1088	type WeightInfo = weights::runtime_parachains_configuration::WeightInfo<Runtime>;
1089}
1090
1091impl parachains_shared::Config for Runtime {}
1092
1093impl parachains_session_info::Config for Runtime {
1094	type ValidatorSet = Historical;
1095}
1096
1097impl parachains_inclusion::Config for Runtime {
1098	type RuntimeEvent = RuntimeEvent;
1099	type DisputesHandler = ParasDisputes;
1100	type RewardValidators = parachains_reward_points::RewardValidatorsWithEraPoints<Runtime>;
1101	type MessageQueue = MessageQueue;
1102	type WeightInfo = weights::runtime_parachains_inclusion::WeightInfo<Runtime>;
1103}
1104
1105parameter_types! {
1106	pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
1107}
1108
1109impl parachains_paras::Config for Runtime {
1110	type RuntimeEvent = RuntimeEvent;
1111	type WeightInfo = weights::runtime_parachains_paras::WeightInfo<Runtime>;
1112	type UnsignedPriority = ParasUnsignedPriority;
1113	type QueueFootprinter = ParaInclusion;
1114	type NextSessionRotation = Babe;
1115	type OnNewHead = Registrar;
1116}
1117
1118parameter_types! {
1119	/// Amount of weight that can be spent per block to service messages.
1120	///
1121	/// # WARNING
1122	///
1123	/// This is not a good value for para-chains since the `Scheduler` already uses up to 80% block weight.
1124	pub MessageQueueServiceWeight: Weight = Perbill::from_percent(20) * BlockWeights::get().max_block;
1125	pub const MessageQueueHeapSize: u32 = 65_536;
1126	pub const MessageQueueMaxStale: u32 = 8;
1127}
1128
1129/// Message processor to handle any messages that were enqueued into the `MessageQueue` pallet.
1130pub struct MessageProcessor;
1131impl ProcessMessage for MessageProcessor {
1132	type Origin = AggregateMessageOrigin;
1133
1134	fn process_message(
1135		message: &[u8],
1136		origin: Self::Origin,
1137		meter: &mut WeightMeter,
1138		id: &mut [u8; 32],
1139	) -> Result<bool, ProcessMessageError> {
1140		let para = match origin {
1141			AggregateMessageOrigin::Ump(UmpQueueId::Para(para)) => para,
1142		};
1143		xcm_builder::ProcessXcmMessage::<
1144			Junction,
1145			xcm_executor::XcmExecutor<xcm_config::XcmConfig>,
1146			RuntimeCall,
1147		>::process_message(message, Junction::Parachain(para.into()), meter, id)
1148	}
1149}
1150
1151impl pallet_message_queue::Config for Runtime {
1152	type RuntimeEvent = RuntimeEvent;
1153	type Size = u32;
1154	type HeapSize = MessageQueueHeapSize;
1155	type MaxStale = MessageQueueMaxStale;
1156	type ServiceWeight = MessageQueueServiceWeight;
1157	#[cfg(not(feature = "runtime-benchmarks"))]
1158	type MessageProcessor = MessageProcessor;
1159	#[cfg(feature = "runtime-benchmarks")]
1160	type MessageProcessor =
1161		pallet_message_queue::mock_helpers::NoopMessageProcessor<AggregateMessageOrigin>;
1162	type QueueChangeHandler = ParaInclusion;
1163	type QueuePausedQuery = ();
1164	type WeightInfo = weights::pallet_message_queue::WeightInfo<Runtime>;
1165}
1166
1167impl parachains_dmp::Config for Runtime {}
1168
1169impl parachains_hrmp::Config for Runtime {
1170	type RuntimeOrigin = RuntimeOrigin;
1171	type RuntimeEvent = RuntimeEvent;
1172	type ChannelManager = EitherOf<EnsureRoot<Self::AccountId>, GeneralAdmin>;
1173	type Currency = Balances;
1174	type WeightInfo = weights::runtime_parachains_hrmp::WeightInfo<Self>;
1175}
1176
1177impl parachains_paras_inherent::Config for Runtime {
1178	type WeightInfo = weights::runtime_parachains_paras_inherent::WeightInfo<Runtime>;
1179}
1180
1181impl parachains_scheduler::Config for Runtime {
1182	type AssignmentProvider = ParaAssignmentProvider;
1183}
1184
1185impl parachains_assigner_parachains::Config for Runtime {}
1186
1187impl parachains_initializer::Config for Runtime {
1188	type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
1189	type ForceOrigin = EnsureRoot<AccountId>;
1190	type WeightInfo = weights::runtime_parachains_initializer::WeightInfo<Runtime>;
1191}
1192
1193impl parachains_disputes::Config for Runtime {
1194	type RuntimeEvent = RuntimeEvent;
1195	type RewardValidators = parachains_reward_points::RewardValidatorsWithEraPoints<Runtime>;
1196	type SlashingHandler = parachains_slashing::SlashValidatorsForDisputes<ParasSlashing>;
1197	type WeightInfo = weights::runtime_parachains_disputes::WeightInfo<Runtime>;
1198}
1199
1200impl parachains_slashing::Config for Runtime {
1201	type KeyOwnerProofSystem = Historical;
1202	type KeyOwnerProof =
1203		<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, ValidatorId)>>::Proof;
1204	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
1205		KeyTypeId,
1206		ValidatorId,
1207	)>>::IdentificationTuple;
1208	type HandleReports = parachains_slashing::SlashingReportHandler<
1209		Self::KeyOwnerIdentification,
1210		Offences,
1211		ReportLongevity,
1212	>;
1213	type WeightInfo = weights::runtime_parachains_disputes_slashing::WeightInfo<Runtime>;
1214	type BenchmarkingConfig = parachains_slashing::BenchConfig<1000>;
1215}
1216
1217parameter_types! {
1218	// Mostly arbitrary deposit price, but should provide an adequate incentive not to spam reserve
1219	// `ParaId`s.
1220	pub const ParaDeposit: Balance = 100 * DOLLARS;
1221	pub const ParaDataByteDeposit: Balance = deposit(0, 1);
1222}
1223
1224impl paras_registrar::Config for Runtime {
1225	type RuntimeOrigin = RuntimeOrigin;
1226	type RuntimeEvent = RuntimeEvent;
1227	type Currency = Balances;
1228	type OnSwap = (Crowdloan, Slots);
1229	type ParaDeposit = ParaDeposit;
1230	type DataDepositPerByte = ParaDataByteDeposit;
1231	type WeightInfo = weights::runtime_common_paras_registrar::WeightInfo<Runtime>;
1232}
1233
1234parameter_types! {
1235	// 12 weeks = 3 months per lease period -> 8 lease periods ~ 2 years
1236	pub LeasePeriod: BlockNumber = prod_or_fast!(12 * WEEKS, 12 * WEEKS, "DOT_LEASE_PERIOD");
1237	// Polkadot Genesis was on May 26, 2020.
1238	// Target Parachain Onboarding Date: Dec 15, 2021.
1239	// Difference is 568 days.
1240	// We want a lease period to start on the target onboarding date.
1241	// 568 % (12 * 7) = 64 day offset
1242	pub LeaseOffset: BlockNumber = prod_or_fast!(64 * DAYS, 0, "DOT_LEASE_OFFSET");
1243}
1244
1245impl slots::Config for Runtime {
1246	type RuntimeEvent = RuntimeEvent;
1247	type Currency = Balances;
1248	type Registrar = Registrar;
1249	type LeasePeriod = LeasePeriod;
1250	type LeaseOffset = LeaseOffset;
1251	type ForceOrigin = EitherOf<EnsureRoot<Self::AccountId>, LeaseAdmin>;
1252	type WeightInfo = weights::runtime_common_slots::WeightInfo<Runtime>;
1253}
1254
1255parameter_types! {
1256	pub const CrowdloanId: PalletId = PalletId(*b"py/cfund");
1257	// Accounts for 10_000 contributions, each using 48 bytes (16 bytes for balance, and 32 bytes
1258	// for a memo).
1259	pub const SubmissionDeposit: Balance = deposit(1, 480_000);
1260	// The minimum crowdloan contribution.
1261	pub const MinContribution: Balance = 5 * DOLLARS;
1262	pub const RemoveKeysLimit: u32 = 1000;
1263	// Allow 32 bytes for an additional memo to a crowdloan.
1264	pub const MaxMemoLength: u8 = 32;
1265}
1266
1267impl crowdloan::Config for Runtime {
1268	type RuntimeEvent = RuntimeEvent;
1269	type PalletId = CrowdloanId;
1270	type SubmissionDeposit = SubmissionDeposit;
1271	type MinContribution = MinContribution;
1272	type RemoveKeysLimit = RemoveKeysLimit;
1273	type Registrar = Registrar;
1274	type Auctioneer = Auctions;
1275	type MaxMemoLength = MaxMemoLength;
1276	type WeightInfo = weights::runtime_common_crowdloan::WeightInfo<Runtime>;
1277}
1278
1279parameter_types! {
1280	// The average auction is 7 days long, so this will be 70% for ending period.
1281	// 5 Days = 72000 Blocks @ 6 sec per block
1282	pub const EndingPeriod: BlockNumber = 5 * DAYS;
1283	// ~ 1000 samples per day -> ~ 20 blocks per sample -> 2 minute samples
1284	pub const SampleLength: BlockNumber = 2 * MINUTES;
1285}
1286
1287impl auctions::Config for Runtime {
1288	type RuntimeEvent = RuntimeEvent;
1289	type Leaser = Slots;
1290	type Registrar = Registrar;
1291	type EndingPeriod = EndingPeriod;
1292	type SampleLength = SampleLength;
1293	type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
1294	type InitiateOrigin = EitherOf<EnsureRoot<Self::AccountId>, AuctionAdmin>;
1295	type WeightInfo = weights::runtime_common_auctions::WeightInfo<Runtime>;
1296}
1297
1298parameter_types! {
1299	pub const PoolsPalletId: PalletId = PalletId(*b"py/nopls");
1300	// Allow pools that got slashed up to 90% to remain operational.
1301	pub const MaxPointsToBalance: u8 = 10;
1302}
1303
1304impl pallet_nomination_pools::Config for Runtime {
1305	type RuntimeEvent = RuntimeEvent;
1306	type Currency = Balances;
1307	type RewardCounter = FixedU128;
1308	type BalanceToU256 = runtime_common::BalanceToU256;
1309	type U256ToBalance = runtime_common::U256ToBalance;
1310	type Staking = Staking;
1311	type PostUnbondingPoolsWindow = frame_support::traits::ConstU32<4>;
1312	type MaxMetadataLen = frame_support::traits::ConstU32<256>;
1313	// we use the same number of allowed unlocking chunks as with staking.
1314	type MaxUnbonding = <Self as pallet_staking::Config>::MaxUnlockingChunks;
1315	type PalletId = PoolsPalletId;
1316	type MaxPointsToBalance = MaxPointsToBalance;
1317	type WeightInfo = weights::pallet_nomination_pools::WeightInfo<Self>;
1318}
1319
1320pub struct InitiateNominationPools;
1321impl frame_support::traits::OnRuntimeUpgrade for InitiateNominationPools {
1322	fn on_runtime_upgrade() -> frame_support::weights::Weight {
1323		// we use one as an indicator if this has already been set.
1324		if pallet_nomination_pools::MaxPools::<Runtime>::get().is_none() {
1325			// 5 DOT to join a pool.
1326			pallet_nomination_pools::MinJoinBond::<Runtime>::put(5 * UNITS);
1327			// 100 DOT to create a pool.
1328			pallet_nomination_pools::MinCreateBond::<Runtime>::put(100 * UNITS);
1329
1330			// Initialize with limits for now.
1331			pallet_nomination_pools::MaxPools::<Runtime>::put(0);
1332			pallet_nomination_pools::MaxPoolMembersPerPool::<Runtime>::put(0);
1333			pallet_nomination_pools::MaxPoolMembers::<Runtime>::put(0);
1334
1335			log::info!(target: "runtime::polkadot", "pools config initiated 🎉");
1336			<Runtime as frame_system::Config>::DbWeight::get().reads_writes(1, 5)
1337		} else {
1338			log::info!(target: "runtime::polkadot", "pools config already initiated 😏");
1339			<Runtime as frame_system::Config>::DbWeight::get().reads(1)
1340		}
1341	}
1342}
1343
1344construct_runtime! {
1345	pub enum Runtime
1346	{
1347		// Basic stuff; balances is uncallable initially.
1348		System: frame_system::{Pallet, Call, Storage, Config<T>, Event<T>} = 0,
1349		Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event<T>} = 1,
1350		Preimage: pallet_preimage::{Pallet, Call, Storage, Event<T>, HoldReason} = 10,
1351
1352		// Babe must be before session.
1353		Babe: pallet_babe::{Pallet, Call, Storage, Config<T>, ValidateUnsigned} = 2,
1354
1355		Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3,
1356		Indices: pallet_indices::{Pallet, Call, Storage, Config<T>, Event<T>} = 4,
1357		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 5,
1358		TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event<T>} = 32,
1359
1360		// Consensus support.
1361		// Authorship must be before session in order to note author in the correct session and era
1362		// for im-online and staking.
1363		Authorship: pallet_authorship::{Pallet, Storage} = 6,
1364		Staking: pallet_staking::{Pallet, Call, Storage, Config<T>, Event<T>} = 7,
1365		Offences: pallet_offences::{Pallet, Storage, Event} = 8,
1366		Historical: session_historical::{Pallet} = 33,
1367		Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>} = 9,
1368		Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config<T>, Event, ValidateUnsigned} = 11,
1369		ImOnline: pallet_im_online::{Pallet, Call, Storage, Event<T>, ValidateUnsigned, Config<T>} = 12,
1370		AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config<T>} = 13,
1371
1372		// OpenGov stuff.
1373		Treasury: pallet_treasury::{Pallet, Call, Storage, Config<T>, Event<T>} = 19,
1374		ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event<T>} = 20,
1375		Referenda: pallet_referenda::{Pallet, Call, Storage, Event<T>} = 21,
1376		Origins: pallet_custom_origins::{Origin} = 22,
1377		Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event<T>} = 23,
1378
1379		// Claims. Usable initially.
1380		Claims: claims::{Pallet, Call, Storage, Event<T>, Config<T>, ValidateUnsigned} = 24,
1381		// Vesting. Usable initially, but removed once all vesting is finished.
1382		Vesting: pallet_vesting::{Pallet, Call, Storage, Event<T>, Config<T>} = 25,
1383		// Cunning utilities. Usable initially.
1384		Utility: pallet_utility::{Pallet, Call, Event} = 26,
1385
1386		// Identity. Late addition.
1387		Identity: pallet_identity::{Pallet, Call, Storage, Event<T>} = 28,
1388
1389		// Proxy module. Late addition.
1390		Proxy: pallet_proxy::{Pallet, Call, Storage, Event<T>} = 29,
1391
1392		// Multisig dispatch. Late addition.
1393		Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 30,
1394
1395		// Bounties modules.
1396		Bounties: pallet_bounties::{Pallet, Call, Storage, Event<T>} = 34,
1397		ChildBounties: pallet_child_bounties = 38,
1398
1399		// Election pallet. Only works with staking, but placed here to maintain indices.
1400		ElectionProviderMultiPhase: pallet_election_provider_multi_phase::{Pallet, Call, Storage, Event<T>, ValidateUnsigned} = 36,
1401
1402		// Provides a semi-sorted list of nominators for staking.
1403		VoterList: pallet_bags_list::<Instance1>::{Pallet, Call, Storage, Event<T>} = 37,
1404
1405		// Nomination pools: extension to staking.
1406		NominationPools: pallet_nomination_pools::{Pallet, Call, Storage, Event<T>, Config<T>} = 39,
1407
1408		// Fast unstake pallet: extension to staking.
1409		FastUnstake: pallet_fast_unstake = 40,
1410
1411		// Parachains pallets. Start indices at 50 to leave room.
1412		ParachainsOrigin: parachains_origin::{Pallet, Origin} = 50,
1413		Configuration: parachains_configuration::{Pallet, Call, Storage, Config<T>} = 51,
1414		ParasShared: parachains_shared::{Pallet, Call, Storage} = 52,
1415		ParaInclusion: parachains_inclusion::{Pallet, Call, Storage, Event<T>} = 53,
1416		ParaInherent: parachains_paras_inherent::{Pallet, Call, Storage, Inherent} = 54,
1417		ParaScheduler: parachains_scheduler::{Pallet, Storage} = 55,
1418		Paras: parachains_paras::{Pallet, Call, Storage, Event, Config<T>, ValidateUnsigned} = 56,
1419		Initializer: parachains_initializer::{Pallet, Call, Storage} = 57,
1420		Dmp: parachains_dmp::{Pallet, Storage} = 58,
1421		// Ump 59
1422		Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event<T>, Config<T>} = 60,
1423		ParaSessionInfo: parachains_session_info::{Pallet, Storage} = 61,
1424		ParasDisputes: parachains_disputes::{Pallet, Call, Storage, Event<T>} = 62,
1425		ParasSlashing: parachains_slashing::{Pallet, Call, Storage, ValidateUnsigned} = 63,
1426		ParaAssignmentProvider: parachains_assigner_parachains::{Pallet} = 64,
1427
1428		// Parachain Onboarding Pallets. Start indices at 70 to leave room.
1429		Registrar: paras_registrar::{Pallet, Call, Storage, Event<T>} = 70,
1430		Slots: slots::{Pallet, Call, Storage, Event<T>} = 71,
1431		Auctions: auctions::{Pallet, Call, Storage, Event<T>} = 72,
1432		Crowdloan: crowdloan::{Pallet, Call, Storage, Event<T>} = 73,
1433
1434		// Pallet for sending XCM.
1435		XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin, Config<T>} = 99,
1436
1437		// Generalized message queue
1438		MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event<T>} = 100,
1439	}
1440}
1441
1442/// The address format for describing accounts.
1443pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
1444/// Block header type as expected by this runtime.
1445pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
1446/// Block type as expected by this runtime.
1447pub type Block = generic::Block<Header, UncheckedExtrinsic>;
1448/// A Block signed with a Justification
1449pub type SignedBlock = generic::SignedBlock<Block>;
1450/// `BlockId` type as expected by this runtime.
1451pub type BlockId = generic::BlockId<Block>;
1452/// The `SignedExtension` to the basic transaction logic.
1453pub type SignedExtra = (
1454	frame_system::CheckNonZeroSender<Runtime>,
1455	frame_system::CheckSpecVersion<Runtime>,
1456	frame_system::CheckTxVersion<Runtime>,
1457	frame_system::CheckGenesis<Runtime>,
1458	frame_system::CheckMortality<Runtime>,
1459	frame_system::CheckNonce<Runtime>,
1460	frame_system::CheckWeight<Runtime>,
1461	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
1462	claims::PrevalidateAttests<Runtime>,
1463);
1464
1465pub struct NominationPoolsMigrationV4OldPallet;
1466impl Get<Perbill> for NominationPoolsMigrationV4OldPallet {
1467	fn get() -> Perbill {
1468		Perbill::zero()
1469	}
1470}
1471
1472/// All migrations that will run on the next runtime upgrade.
1473///
1474/// This contains the combined migrations of the last 10 releases. It allows to skip runtime
1475/// upgrades in case governance decides to do so. THE ORDER IS IMPORTANT.
1476pub type Migrations = migrations::Unreleased;
1477
1478/// The runtime migrations per release.
1479#[allow(deprecated, missing_docs)]
1480pub mod migrations {
1481	use super::*;
1482	use frame_support::traits::LockIdentifier;
1483	use frame_system::pallet_prelude::BlockNumberFor;
1484
1485	parameter_types! {
1486		pub const DemocracyPalletName: &'static str = "Democracy";
1487		pub const CouncilPalletName: &'static str = "Council";
1488		pub const TechnicalCommitteePalletName: &'static str = "TechnicalCommittee";
1489		pub const PhragmenElectionPalletName: &'static str = "PhragmenElection";
1490		pub const TechnicalMembershipPalletName: &'static str = "TechnicalMembership";
1491		pub const TipsPalletName: &'static str = "Tips";
1492		pub const PhragmenElectionPalletId: LockIdentifier = *b"phrelect";
1493	}
1494
1495	// Special Config for Gov V1 pallets, allowing us to run migrations for them without
1496	// implementing their configs on [`Runtime`].
1497	pub struct UnlockConfig;
1498	impl pallet_democracy::migrations::unlock_and_unreserve_all_funds::UnlockConfig for UnlockConfig {
1499		type Currency = Balances;
1500		type MaxVotes = ConstU32<100>;
1501		type MaxDeposits = ConstU32<100>;
1502		type AccountId = AccountId;
1503		type BlockNumber = BlockNumberFor<Runtime>;
1504		type DbWeight = <Runtime as frame_system::Config>::DbWeight;
1505		type PalletName = DemocracyPalletName;
1506	}
1507	impl pallet_elections_phragmen::migrations::unlock_and_unreserve_all_funds::UnlockConfig
1508		for UnlockConfig
1509	{
1510		type Currency = Balances;
1511		type MaxVotesPerVoter = ConstU32<16>;
1512		type PalletId = PhragmenElectionPalletId;
1513		type AccountId = AccountId;
1514		type DbWeight = <Runtime as frame_system::Config>::DbWeight;
1515		type PalletName = PhragmenElectionPalletName;
1516	}
1517	impl pallet_tips::migrations::unreserve_deposits::UnlockConfig<()> for UnlockConfig {
1518		type Currency = Balances;
1519		type Hash = Hash;
1520		type DataDepositPerByte = DataDepositPerByte;
1521		type TipReportDepositBase = TipReportDepositBase;
1522		type AccountId = AccountId;
1523		type BlockNumber = BlockNumberFor<Runtime>;
1524		type DbWeight = <Runtime as frame_system::Config>::DbWeight;
1525		type PalletName = TipsPalletName;
1526	}
1527
1528	pub struct ParachainsToUnlock;
1529	impl Contains<ParaId> for ParachainsToUnlock {
1530		fn contains(id: &ParaId) -> bool {
1531			let id: u32 = (*id).into();
1532			// polkadot parachains/parathreads that are locked and never produced block
1533			match id {
1534				2003 | 2015 | 2017 | 2018 | 2025 | 2028 | 2036 | 2038 | 2053 | 2055 | 2090 |
1535				2097 | 2106 | 3336 | 3338 | 3342 => true,
1536				_ => false,
1537			}
1538		}
1539	}
1540
1541	/// Unreleased migrations. Add new ones here:
1542	pub type Unreleased = (
1543		pallet_im_online::migration::v1::Migration<Runtime>,
1544		parachains_configuration::migration::v7::MigrateToV7<Runtime>,
1545		parachains_scheduler::migration::v1::MigrateToV1<Runtime>,
1546		parachains_configuration::migration::v8::MigrateToV8<Runtime>,
1547
1548		// Gov v1 storage migrations
1549		// https://github.com/paritytech/polkadot/issues/6749
1550		pallet_elections_phragmen::migrations::unlock_and_unreserve_all_funds::UnlockAndUnreserveAllFunds<UnlockConfig>,
1551		pallet_democracy::migrations::unlock_and_unreserve_all_funds::UnlockAndUnreserveAllFunds<UnlockConfig>,
1552		pallet_tips::migrations::unreserve_deposits::UnreserveDeposits<UnlockConfig, ()>,
1553
1554		// Delete all Gov v1 pallet storage key/values.
1555		frame_support::migrations::RemovePallet<DemocracyPalletName, <Runtime as frame_system::Config>::DbWeight>,
1556		frame_support::migrations::RemovePallet<CouncilPalletName, <Runtime as frame_system::Config>::DbWeight>,
1557		frame_support::migrations::RemovePallet<TechnicalCommitteePalletName, <Runtime as frame_system::Config>::DbWeight>,
1558		frame_support::migrations::RemovePallet<PhragmenElectionPalletName, <Runtime as frame_system::Config>::DbWeight>,
1559		frame_support::migrations::RemovePallet<TechnicalMembershipPalletName, <Runtime as frame_system::Config>::DbWeight>,
1560		frame_support::migrations::RemovePallet<TipsPalletName, <Runtime as frame_system::Config>::DbWeight>,
1561
1562		parachains_configuration::migration::v9::MigrateToV9<Runtime>,
1563		// Migrate parachain info format
1564		paras_registrar::migration::VersionCheckedMigrateToV1<Runtime, ParachainsToUnlock>,
1565	);
1566}
1567
1568/// Unchecked extrinsic type as expected by this runtime.
1569pub type UncheckedExtrinsic =
1570	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
1571/// Executive: handles dispatch to the various modules.
1572pub type Executive = frame_executive::Executive<
1573	Runtime,
1574	Block,
1575	frame_system::ChainContext<Runtime>,
1576	Runtime,
1577	AllPalletsWithSystem,
1578	Migrations,
1579>;
1580
1581/// The payload being signed in transactions.
1582pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
1583
1584#[cfg(feature = "runtime-benchmarks")]
1585mod benches {
1586	frame_benchmarking::define_benchmarks!(
1587		// Polkadot
1588		// NOTE: Make sure to prefix these with `runtime_common::` so
1589		// the that path resolves correctly in the generated file.
1590		[runtime_common::auctions, Auctions]
1591		[runtime_common::claims, Claims]
1592		[runtime_common::crowdloan, Crowdloan]
1593		[runtime_common::slots, Slots]
1594		[runtime_common::paras_registrar, Registrar]
1595		[runtime_parachains::configuration, Configuration]
1596		[runtime_parachains::disputes, ParasDisputes]
1597		[runtime_parachains::disputes::slashing, ParasSlashing]
1598		[runtime_parachains::hrmp, Hrmp]
1599		[runtime_parachains::inclusion, ParaInclusion]
1600		[runtime_parachains::initializer, Initializer]
1601		[runtime_parachains::paras, Paras]
1602		[runtime_parachains::paras_inherent, ParaInherent]
1603		// Substrate
1604		[pallet_bags_list, VoterList]
1605		[pallet_balances, Balances]
1606		[frame_benchmarking::baseline, Baseline::<Runtime>]
1607		[pallet_bounties, Bounties]
1608		[pallet_child_bounties, ChildBounties]
1609		[pallet_election_provider_multi_phase, ElectionProviderMultiPhase]
1610		[frame_election_provider_support, ElectionProviderBench::<Runtime>]
1611		[pallet_fast_unstake, FastUnstake]
1612		[pallet_identity, Identity]
1613		[pallet_im_online, ImOnline]
1614		[pallet_indices, Indices]
1615		[pallet_message_queue, MessageQueue]
1616		[pallet_multisig, Multisig]
1617		[pallet_nomination_pools, NominationPoolsBench::<Runtime>]
1618		[pallet_offences, OffencesBench::<Runtime>]
1619		[pallet_preimage, Preimage]
1620		[pallet_proxy, Proxy]
1621		[pallet_scheduler, Scheduler]
1622		[pallet_session, SessionBench::<Runtime>]
1623		[pallet_staking, Staking]
1624		[frame_system, SystemBench::<Runtime>]
1625		[pallet_timestamp, Timestamp]
1626		[pallet_treasury, Treasury]
1627		[pallet_utility, Utility]
1628		[pallet_vesting, Vesting]
1629		[pallet_conviction_voting, ConvictionVoting]
1630		[pallet_referenda, Referenda]
1631		[pallet_whitelist, Whitelist]
1632		// XCM
1633		[pallet_xcm, XcmPallet]
1634		[pallet_xcm_benchmarks::fungible, pallet_xcm_benchmarks::fungible::Pallet::<Runtime>]
1635		[pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet::<Runtime>]
1636	);
1637}
1638
1639sp_api::impl_runtime_apis! {
1640	impl sp_api::Core<Block> for Runtime {
1641		fn version() -> RuntimeVersion {
1642			VERSION
1643		}
1644
1645		fn execute_block(block: Block) {
1646			Executive::execute_block(block);
1647		}
1648
1649		fn initialize_block(header: &<Block as BlockT>::Header) {
1650			Executive::initialize_block(header)
1651		}
1652	}
1653
1654	impl sp_api::Metadata<Block> for Runtime {
1655		fn metadata() -> OpaqueMetadata {
1656			OpaqueMetadata::new(Runtime::metadata().into())
1657		}
1658
1659		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
1660			Runtime::metadata_at_version(version)
1661		}
1662
1663		fn metadata_versions() -> sp_std::vec::Vec<u32> {
1664			Runtime::metadata_versions()
1665		}
1666	}
1667
1668	impl block_builder_api::BlockBuilder<Block> for Runtime {
1669		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
1670			Executive::apply_extrinsic(extrinsic)
1671		}
1672
1673		fn finalize_block() -> <Block as BlockT>::Header {
1674			Executive::finalize_block()
1675		}
1676
1677		fn inherent_extrinsics(data: inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
1678			data.create_extrinsics()
1679		}
1680
1681		fn check_inherents(
1682			block: Block,
1683			data: inherents::InherentData,
1684		) -> inherents::CheckInherentsResult {
1685			data.check_extrinsics(&block)
1686		}
1687	}
1688
1689	impl pallet_nomination_pools_runtime_api::NominationPoolsApi<
1690		Block,
1691		AccountId,
1692		Balance,
1693	> for Runtime {
1694		fn pending_rewards(member: AccountId) -> Balance {
1695			NominationPools::api_pending_rewards(member).unwrap_or_default()
1696		}
1697
1698		fn points_to_balance(pool_id: pallet_nomination_pools::PoolId, points: Balance) -> Balance {
1699			NominationPools::api_points_to_balance(pool_id, points)
1700		}
1701
1702		fn balance_to_points(pool_id: pallet_nomination_pools::PoolId, new_funds: Balance) -> Balance {
1703			NominationPools::api_balance_to_points(pool_id, new_funds)
1704		}
1705	}
1706
1707	impl pallet_staking_runtime_api::StakingApi<Block, Balance> for Runtime {
1708		fn nominations_quota(balance: Balance) -> u32 {
1709			Staking::api_nominations_quota(balance)
1710		}
1711	}
1712
1713	impl tx_pool_api::runtime_api::TaggedTransactionQueue<Block> for Runtime {
1714		fn validate_transaction(
1715			source: TransactionSource,
1716			tx: <Block as BlockT>::Extrinsic,
1717			block_hash: <Block as BlockT>::Hash,
1718		) -> TransactionValidity {
1719			Executive::validate_transaction(source, tx, block_hash)
1720		}
1721	}
1722
1723	impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
1724		fn offchain_worker(header: &<Block as BlockT>::Header) {
1725			Executive::offchain_worker(header)
1726		}
1727	}
1728
1729	impl primitives::runtime_api::ParachainHost<Block, Hash, BlockNumber> for Runtime {
1730		fn validators() -> Vec<ValidatorId> {
1731			parachains_runtime_api_impl::validators::<Runtime>()
1732		}
1733
1734		fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>) {
1735			parachains_runtime_api_impl::validator_groups::<Runtime>()
1736		}
1737
1738		fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>> {
1739			parachains_runtime_api_impl::availability_cores::<Runtime>()
1740		}
1741
1742		fn persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption)
1743			-> Option<PersistedValidationData<Hash, BlockNumber>> {
1744			parachains_runtime_api_impl::persisted_validation_data::<Runtime>(para_id, assumption)
1745		}
1746
1747		fn assumed_validation_data(
1748			para_id: ParaId,
1749			expected_persisted_validation_data_hash: Hash,
1750		) -> Option<(PersistedValidationData<Hash, BlockNumber>, ValidationCodeHash)> {
1751			parachains_runtime_api_impl::assumed_validation_data::<Runtime>(
1752				para_id,
1753				expected_persisted_validation_data_hash,
1754			)
1755		}
1756
1757		fn check_validation_outputs(
1758			para_id: ParaId,
1759			outputs: primitives::CandidateCommitments,
1760		) -> bool {
1761			parachains_runtime_api_impl::check_validation_outputs::<Runtime>(para_id, outputs)
1762		}
1763
1764		fn session_index_for_child() -> SessionIndex {
1765			parachains_runtime_api_impl::session_index_for_child::<Runtime>()
1766		}
1767
1768		fn validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption)
1769			-> Option<ValidationCode> {
1770			parachains_runtime_api_impl::validation_code::<Runtime>(para_id, assumption)
1771		}
1772
1773		fn candidate_pending_availability(para_id: ParaId) -> Option<CommittedCandidateReceipt<Hash>> {
1774			parachains_runtime_api_impl::candidate_pending_availability::<Runtime>(para_id)
1775		}
1776
1777		fn candidate_events() -> Vec<CandidateEvent<Hash>> {
1778			parachains_runtime_api_impl::candidate_events::<Runtime, _>(|ev| {
1779				match ev {
1780					RuntimeEvent::ParaInclusion(ev) => {
1781						Some(ev)
1782					}
1783					_ => None,
1784				}
1785			})
1786		}
1787
1788		fn session_info(index: SessionIndex) -> Option<SessionInfo> {
1789			parachains_runtime_api_impl::session_info::<Runtime>(index)
1790		}
1791
1792		fn session_executor_params(session_index: SessionIndex) -> Option<ExecutorParams> {
1793			parachains_runtime_api_impl::session_executor_params::<Runtime>(session_index)
1794		}
1795
1796		fn dmq_contents(recipient: ParaId) -> Vec<InboundDownwardMessage<BlockNumber>> {
1797			parachains_runtime_api_impl::dmq_contents::<Runtime>(recipient)
1798		}
1799
1800		fn inbound_hrmp_channels_contents(
1801			recipient: ParaId
1802		) -> BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>> {
1803			parachains_runtime_api_impl::inbound_hrmp_channels_contents::<Runtime>(recipient)
1804		}
1805
1806		fn validation_code_by_hash(hash: ValidationCodeHash) -> Option<ValidationCode> {
1807			parachains_runtime_api_impl::validation_code_by_hash::<Runtime>(hash)
1808		}
1809
1810		fn on_chain_votes() -> Option<ScrapedOnChainVotes<Hash>> {
1811			parachains_runtime_api_impl::on_chain_votes::<Runtime>()
1812		}
1813
1814		fn submit_pvf_check_statement(
1815			stmt: primitives::PvfCheckStatement,
1816			signature: primitives::ValidatorSignature,
1817		) {
1818			parachains_runtime_api_impl::submit_pvf_check_statement::<Runtime>(stmt, signature)
1819		}
1820
1821		fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
1822			parachains_runtime_api_impl::pvfs_require_precheck::<Runtime>()
1823		}
1824
1825		fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption)
1826			-> Option<ValidationCodeHash>
1827		{
1828			parachains_runtime_api_impl::validation_code_hash::<Runtime>(para_id, assumption)
1829		}
1830
1831		fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)> {
1832			parachains_runtime_api_impl::get_session_disputes::<Runtime>()
1833		}
1834
1835		fn unapplied_slashes(
1836		) -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)> {
1837			parachains_runtime_api_impl::unapplied_slashes::<Runtime>()
1838		}
1839
1840		fn key_ownership_proof(
1841			validator_id: ValidatorId,
1842		) -> Option<slashing::OpaqueKeyOwnershipProof> {
1843			use parity_scale_codec::Encode;
1844
1845			Historical::prove((PARACHAIN_KEY_TYPE_ID, validator_id))
1846				.map(|p| p.encode())
1847				.map(slashing::OpaqueKeyOwnershipProof::new)
1848		}
1849
1850		fn submit_report_dispute_lost(
1851			dispute_proof: slashing::DisputeProof,
1852			key_ownership_proof: slashing::OpaqueKeyOwnershipProof,
1853		) -> Option<()> {
1854			parachains_runtime_api_impl::submit_unsigned_slashing_report::<Runtime>(
1855				dispute_proof,
1856				key_ownership_proof,
1857			)
1858		}
1859	}
1860
1861	impl beefy_primitives::BeefyApi<Block, BeefyId> for Runtime {
1862		fn beefy_genesis() -> Option<BlockNumber> {
1863			// dummy implementation due to lack of BEEFY pallet.
1864			None
1865		}
1866
1867		fn validator_set() -> Option<beefy_primitives::ValidatorSet<BeefyId>> {
1868			// dummy implementation due to lack of BEEFY pallet.
1869			None
1870		}
1871
1872		fn submit_report_equivocation_unsigned_extrinsic(
1873			_equivocation_proof: beefy_primitives::EquivocationProof<
1874				BlockNumber,
1875				BeefyId,
1876				BeefySignature,
1877			>,
1878			_key_owner_proof: beefy_primitives::OpaqueKeyOwnershipProof,
1879		) -> Option<()> {
1880			None
1881		}
1882
1883		fn generate_key_ownership_proof(
1884			_set_id: beefy_primitives::ValidatorSetId,
1885			_authority_id: BeefyId,
1886		) -> Option<beefy_primitives::OpaqueKeyOwnershipProof> {
1887			None
1888		}
1889	}
1890
1891	impl mmr::MmrApi<Block, Hash, BlockNumber> for Runtime {
1892		fn mmr_root() -> Result<Hash, mmr::Error> {
1893			Err(mmr::Error::PalletNotIncluded)
1894		}
1895
1896		fn mmr_leaf_count() -> Result<mmr::LeafIndex, mmr::Error> {
1897			Err(mmr::Error::PalletNotIncluded)
1898		}
1899
1900		fn generate_proof(
1901			_block_numbers: Vec<BlockNumber>,
1902			_best_known_block_number: Option<BlockNumber>,
1903		) -> Result<(Vec<mmr::EncodableOpaqueLeaf>, mmr::Proof<Hash>), mmr::Error> {
1904			Err(mmr::Error::PalletNotIncluded)
1905		}
1906
1907		fn verify_proof(_leaves: Vec<mmr::EncodableOpaqueLeaf>, _proof: mmr::Proof<Hash>)
1908			-> Result<(), mmr::Error>
1909		{
1910			Err(mmr::Error::PalletNotIncluded)
1911		}
1912
1913		fn verify_proof_stateless(
1914			_root: Hash,
1915			_leaves: Vec<mmr::EncodableOpaqueLeaf>,
1916			_proof: mmr::Proof<Hash>
1917		) -> Result<(), mmr::Error> {
1918			Err(mmr::Error::PalletNotIncluded)
1919		}
1920	}
1921
1922	impl fg_primitives::GrandpaApi<Block> for Runtime {
1923		fn grandpa_authorities() -> Vec<(GrandpaId, u64)> {
1924			Grandpa::grandpa_authorities()
1925		}
1926
1927		fn current_set_id() -> fg_primitives::SetId {
1928			Grandpa::current_set_id()
1929		}
1930
1931		fn submit_report_equivocation_unsigned_extrinsic(
1932			equivocation_proof: fg_primitives::EquivocationProof<
1933				<Block as BlockT>::Hash,
1934				sp_runtime::traits::NumberFor<Block>,
1935			>,
1936			key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,
1937		) -> Option<()> {
1938			let key_owner_proof = key_owner_proof.decode()?;
1939
1940			Grandpa::submit_unsigned_equivocation_report(
1941				equivocation_proof,
1942				key_owner_proof,
1943			)
1944		}
1945
1946		fn generate_key_ownership_proof(
1947			_set_id: fg_primitives::SetId,
1948			authority_id: fg_primitives::AuthorityId,
1949		) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {
1950			use parity_scale_codec::Encode;
1951
1952			Historical::prove((fg_primitives::KEY_TYPE, authority_id))
1953				.map(|p| p.encode())
1954				.map(fg_primitives::OpaqueKeyOwnershipProof::new)
1955		}
1956	}
1957
1958	impl babe_primitives::BabeApi<Block> for Runtime {
1959		fn configuration() -> babe_primitives::BabeConfiguration {
1960			let epoch_config = Babe::epoch_config().unwrap_or(BABE_GENESIS_EPOCH_CONFIG);
1961			babe_primitives::BabeConfiguration {
1962				slot_duration: Babe::slot_duration(),
1963				epoch_length: EpochDuration::get(),
1964				c: epoch_config.c,
1965				authorities: Babe::authorities().to_vec(),
1966				randomness: Babe::randomness(),
1967				allowed_slots: epoch_config.allowed_slots,
1968			}
1969		}
1970
1971		fn current_epoch_start() -> babe_primitives::Slot {
1972			Babe::current_epoch_start()
1973		}
1974
1975		fn current_epoch() -> babe_primitives::Epoch {
1976			Babe::current_epoch()
1977		}
1978
1979		fn next_epoch() -> babe_primitives::Epoch {
1980			Babe::next_epoch()
1981		}
1982
1983		fn generate_key_ownership_proof(
1984			_slot: babe_primitives::Slot,
1985			authority_id: babe_primitives::AuthorityId,
1986		) -> Option<babe_primitives::OpaqueKeyOwnershipProof> {
1987			use parity_scale_codec::Encode;
1988
1989			Historical::prove((babe_primitives::KEY_TYPE, authority_id))
1990				.map(|p| p.encode())
1991				.map(babe_primitives::OpaqueKeyOwnershipProof::new)
1992		}
1993
1994		fn submit_report_equivocation_unsigned_extrinsic(
1995			equivocation_proof: babe_primitives::EquivocationProof<<Block as BlockT>::Header>,
1996			key_owner_proof: babe_primitives::OpaqueKeyOwnershipProof,
1997		) -> Option<()> {
1998			let key_owner_proof = key_owner_proof.decode()?;
1999
2000			Babe::submit_unsigned_equivocation_report(
2001				equivocation_proof,
2002				key_owner_proof,
2003			)
2004		}
2005	}
2006
2007	impl authority_discovery_primitives::AuthorityDiscoveryApi<Block> for Runtime {
2008		fn authorities() -> Vec<AuthorityDiscoveryId> {
2009			parachains_runtime_api_impl::relevant_authority_ids::<Runtime>()
2010		}
2011	}
2012
2013	impl sp_session::SessionKeys<Block> for Runtime {
2014		fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
2015			SessionKeys::generate(seed)
2016		}
2017
2018		fn decode_session_keys(
2019			encoded: Vec<u8>,
2020		) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
2021			SessionKeys::decode_into_raw_public_keys(&encoded)
2022		}
2023	}
2024
2025	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
2026		fn account_nonce(account: AccountId) -> Nonce {
2027			System::account_nonce(account)
2028		}
2029	}
2030
2031	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
2032		Block,
2033		Balance,
2034	> for Runtime {
2035		fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
2036			TransactionPayment::query_info(uxt, len)
2037		}
2038		fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {
2039			TransactionPayment::query_fee_details(uxt, len)
2040		}
2041		fn query_weight_to_fee(weight: Weight) -> Balance {
2042			TransactionPayment::weight_to_fee(weight)
2043		}
2044		fn query_length_to_fee(length: u32) -> Balance {
2045			TransactionPayment::length_to_fee(length)
2046		}
2047	}
2048
2049	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
2050		for Runtime
2051	{
2052		fn query_call_info(call: RuntimeCall, len: u32) -> RuntimeDispatchInfo<Balance> {
2053			TransactionPayment::query_call_info(call, len)
2054		}
2055		fn query_call_fee_details(call: RuntimeCall, len: u32) -> FeeDetails<Balance> {
2056			TransactionPayment::query_call_fee_details(call, len)
2057		}
2058		fn query_weight_to_fee(weight: Weight) -> Balance {
2059			TransactionPayment::weight_to_fee(weight)
2060		}
2061		fn query_length_to_fee(length: u32) -> Balance {
2062			TransactionPayment::length_to_fee(length)
2063		}
2064	}
2065
2066	#[cfg(feature = "try-runtime")]
2067	impl frame_try_runtime::TryRuntime<Block> for Runtime {
2068		fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
2069			log::info!("try-runtime::on_runtime_upgrade polkadot.");
2070			let weight = Executive::try_runtime_upgrade(checks).unwrap();
2071			(weight, BlockWeights::get().max_block)
2072		}
2073
2074		fn execute_block(
2075			block: Block,
2076			state_root_check: bool,
2077			signature_check: bool,
2078			select: frame_try_runtime::TryStateSelect,
2079		) -> Weight {
2080			// NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
2081			// have a backtrace here.
2082			Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()
2083		}
2084	}
2085
2086	#[cfg(feature = "runtime-benchmarks")]
2087	impl frame_benchmarking::Benchmark<Block> for Runtime {
2088		fn benchmark_metadata(extra: bool) -> (
2089			Vec<frame_benchmarking::BenchmarkList>,
2090			Vec<frame_support::traits::StorageInfo>,
2091		) {
2092			use frame_benchmarking::{Benchmarking, BenchmarkList};
2093			use frame_support::traits::StorageInfoTrait;
2094
2095			use pallet_session_benchmarking::Pallet as SessionBench;
2096			use pallet_offences_benchmarking::Pallet as OffencesBench;
2097			use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench;
2098			use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench;
2099			use frame_system_benchmarking::Pallet as SystemBench;
2100			use frame_benchmarking::baseline::Pallet as Baseline;
2101
2102			let mut list = Vec::<BenchmarkList>::new();
2103			list_benchmarks!(list, extra);
2104
2105			let storage_info = AllPalletsWithSystem::storage_info();
2106			return (list, storage_info)
2107		}
2108
2109		fn dispatch_benchmark(
2110			config: frame_benchmarking::BenchmarkConfig
2111		) -> Result<
2112			Vec<frame_benchmarking::BenchmarkBatch>,
2113			sp_runtime::RuntimeString,
2114		> {
2115			use frame_support::traits::WhitelistedStorageKeys;
2116			use frame_benchmarking::{Benchmarking, BenchmarkBatch, BenchmarkError};
2117			use sp_storage::TrackedStorageKey;
2118			// Trying to add benchmarks directly to some pallets caused cyclic dependency issues.
2119			// To get around that, we separated the benchmarks into its own crate.
2120			use pallet_session_benchmarking::Pallet as SessionBench;
2121			use pallet_offences_benchmarking::Pallet as OffencesBench;
2122			use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench;
2123			use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench;
2124			use frame_system_benchmarking::Pallet as SystemBench;
2125			use frame_benchmarking::baseline::Pallet as Baseline;
2126			use xcm::latest::prelude::*;
2127			use xcm_config::{XcmConfig, StatemintLocation, TokenLocation, LocalCheckAccount, SovereignAccountOf};
2128
2129			impl pallet_session_benchmarking::Config for Runtime {}
2130			impl pallet_offences_benchmarking::Config for Runtime {}
2131			impl pallet_election_provider_support_benchmarking::Config for Runtime {}
2132			impl frame_system_benchmarking::Config for Runtime {}
2133			impl frame_benchmarking::baseline::Config for Runtime {}
2134			impl pallet_nomination_pools_benchmarking::Config for Runtime {}
2135			impl runtime_parachains::disputes::slashing::benchmarking::Config for Runtime {}
2136
2137			let mut whitelist: Vec<TrackedStorageKey> = AllPalletsWithSystem::whitelisted_storage_keys();
2138			let treasury_key = frame_system::Account::<Runtime>::hashed_key_for(Treasury::account_id());
2139			whitelist.push(treasury_key.to_vec().into());
2140
2141			impl pallet_xcm_benchmarks::Config for Runtime {
2142				type XcmConfig = XcmConfig;
2143				type AccountIdConverter = SovereignAccountOf;
2144				fn valid_destination() -> Result<MultiLocation, BenchmarkError> {
2145					Ok(StatemintLocation::get())
2146				}
2147				fn worst_case_holding(_depositable_count: u32) -> MultiAssets {
2148					// Polkadot only knows about DOT
2149					vec![MultiAsset { id: Concrete(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS) }].into()
2150				}
2151			}
2152
2153			parameter_types! {
2154				pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some((
2155					StatemintLocation::get(),
2156					MultiAsset { id: Concrete(TokenLocation::get()), fun: Fungible(1 * UNITS) }
2157				));
2158				pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None;
2159			}
2160
2161			impl pallet_xcm_benchmarks::fungible::Config for Runtime {
2162				type TransactAsset = Balances;
2163
2164				type CheckedAccount = LocalCheckAccount;
2165				type TrustedTeleporter = TrustedTeleporter;
2166				type TrustedReserve = TrustedReserve;
2167
2168				fn get_multi_asset() -> MultiAsset {
2169					MultiAsset {
2170						id: Concrete(TokenLocation::get()),
2171						fun: Fungible(1 * UNITS)
2172					}
2173				}
2174			}
2175
2176			impl pallet_xcm_benchmarks::generic::Config for Runtime {
2177				type RuntimeCall = RuntimeCall;
2178
2179				fn worst_case_response() -> (u64, Response) {
2180					(0u64, Response::Version(Default::default()))
2181				}
2182
2183				fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> {
2184					// Polkadot doesn't support asset exchanges
2185					Err(BenchmarkError::Skip)
2186				}
2187
2188				fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> {
2189					// The XCM executor of Polkadot doesn't have a configured `UniversalAliases`
2190					Err(BenchmarkError::Skip)
2191				}
2192
2193				fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> {
2194					Ok((StatemintLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into()))
2195				}
2196
2197				fn subscribe_origin() -> Result<MultiLocation, BenchmarkError> {
2198					Ok(StatemintLocation::get())
2199				}
2200
2201				fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> {
2202					let origin = StatemintLocation::get();
2203					let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into();
2204					let ticket = MultiLocation { parents: 0, interior: Here };
2205					Ok((origin, ticket, assets))
2206				}
2207
2208				fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> {
2209					// Polkadot doesn't support asset locking
2210					Err(BenchmarkError::Skip)
2211				}
2212
2213				fn export_message_origin_and_destination(
2214				) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> {
2215					// Polkadot doesn't support exporting messages
2216					Err(BenchmarkError::Skip)
2217				}
2218
2219				fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> {
2220					// The XCM executor of Polkadot doesn't have a configured `Aliasers`
2221					Err(BenchmarkError::Skip)
2222				}
2223			}
2224
2225			let mut batches = Vec::<BenchmarkBatch>::new();
2226			let params = (&config, &whitelist);
2227
2228			add_benchmarks!(params, batches);
2229
2230			Ok(batches)
2231		}
2232	}
2233
2234	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
2235		fn create_default_config() -> Vec<u8> {
2236			create_default_config::<RuntimeGenesisConfig>()
2237		}
2238
2239		fn build_config(config: Vec<u8>) -> sp_genesis_builder::Result {
2240			build_config::<RuntimeGenesisConfig>(config)
2241		}
2242	}
2243
2244}
2245
2246#[cfg(test)]
2247mod test_fees {
2248	use super::*;
2249	use frame_support::{dispatch::GetDispatchInfo, weights::WeightToFee as WeightToFeeT};
2250	use keyring::Sr25519Keyring::{Alice, Charlie};
2251	use pallet_transaction_payment::Multiplier;
2252	use runtime_common::MinimumMultiplier;
2253	use separator::Separatable;
2254	use sp_runtime::{assert_eq_error_rate, FixedPointNumber, MultiAddress, MultiSignature};
2255
2256	#[test]
2257	fn payout_weight_portion() {
2258		use pallet_staking::WeightInfo;
2259		let payout_weight =
2260			<Runtime as pallet_staking::Config>::WeightInfo::payout_stakers_alive_staked(
2261				MaxNominatorRewardedPerValidator::get(),
2262			)
2263			.ref_time() as f64;
2264		let block_weight = BlockWeights::get().max_block.ref_time() as f64;
2265
2266		println!(
2267			"a full payout takes {:.2} of the block weight [{} / {}]",
2268			payout_weight / block_weight,
2269			payout_weight,
2270			block_weight
2271		);
2272		assert!(payout_weight * 2f64 < block_weight);
2273	}
2274
2275	#[test]
2276	fn block_cost() {
2277		let max_block_weight = BlockWeights::get().max_block;
2278		let raw_fee = WeightToFee::weight_to_fee(&max_block_weight);
2279
2280		let fee_with_multiplier = |m: Multiplier| {
2281			println!(
2282				"Full Block weight == {} // multiplier: {:?} // WeightToFee(full_block) == {} plank",
2283				max_block_weight,
2284				m,
2285				m.saturating_mul_int(raw_fee).separated_string(),
2286			);
2287		};
2288		fee_with_multiplier(MinimumMultiplier::get());
2289		fee_with_multiplier(Multiplier::from_rational(1, 2));
2290		fee_with_multiplier(Multiplier::from_u32(1));
2291		fee_with_multiplier(Multiplier::from_u32(2));
2292	}
2293
2294	#[test]
2295	fn transfer_cost_min_multiplier() {
2296		let min_multiplier = MinimumMultiplier::get();
2297		let call = pallet_balances::Call::<Runtime>::transfer_keep_alive {
2298			dest: Charlie.to_account_id().into(),
2299			value: Default::default(),
2300		};
2301		let info = call.get_dispatch_info();
2302		println!("call = {:?} / info = {:?}", call, info);
2303		// convert to runtime call.
2304		let call = RuntimeCall::Balances(call);
2305		let extra: SignedExtra = (
2306			frame_system::CheckNonZeroSender::<Runtime>::new(),
2307			frame_system::CheckSpecVersion::<Runtime>::new(),
2308			frame_system::CheckTxVersion::<Runtime>::new(),
2309			frame_system::CheckGenesis::<Runtime>::new(),
2310			frame_system::CheckMortality::<Runtime>::from(generic::Era::immortal()),
2311			frame_system::CheckNonce::<Runtime>::from(1),
2312			frame_system::CheckWeight::<Runtime>::new(),
2313			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
2314			claims::PrevalidateAttests::<Runtime>::new(),
2315		);
2316		let uxt = UncheckedExtrinsic {
2317			function: call,
2318			signature: Some((
2319				MultiAddress::Id(Alice.to_account_id()),
2320				MultiSignature::Sr25519(Alice.sign(b"foo")),
2321				extra,
2322			)),
2323		};
2324		let len = uxt.encoded_size();
2325
2326		let mut ext = sp_io::TestExternalities::new_empty();
2327		let mut test_with_multiplier = |m: Multiplier| {
2328			ext.execute_with(|| {
2329				pallet_transaction_payment::NextFeeMultiplier::<Runtime>::put(m);
2330				let fee = TransactionPayment::query_fee_details(uxt.clone(), len as u32);
2331				println!(
2332					"multiplier = {:?} // fee details = {:?} // final fee = {:?}",
2333					pallet_transaction_payment::NextFeeMultiplier::<Runtime>::get(),
2334					fee,
2335					fee.final_fee().separated_string(),
2336				);
2337			});
2338		};
2339
2340		test_with_multiplier(min_multiplier);
2341		test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1u128));
2342		test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_0u128));
2343		test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_00u128));
2344		test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_000u128));
2345		test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_000_000u128));
2346		test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_000_000_000u128));
2347	}
2348
2349	#[test]
2350	fn nominator_limit() {
2351		use pallet_election_provider_multi_phase::WeightInfo;
2352		// starting point of the nominators.
2353		let target_voters: u32 = 50_000;
2354
2355		// assuming we want around 5k candidates and 1k active validators. (March 31, 2021)
2356		let all_targets: u32 = 5_000;
2357		let desired: u32 = 1_000;
2358		let weight_with = |active| {
2359			<Runtime as pallet_election_provider_multi_phase::Config>::WeightInfo::submit_unsigned(
2360				active,
2361				all_targets,
2362				active,
2363				desired,
2364			)
2365		};
2366
2367		let mut active = target_voters;
2368		while weight_with(active).all_lte(OffchainSolutionWeightLimit::get()) ||
2369			active == target_voters
2370		{
2371			active += 1;
2372		}
2373
2374		println!("can support {} nominators to yield a weight of {}", active, weight_with(active));
2375		assert!(active > target_voters, "we need to reevaluate the weight of the election system");
2376	}
2377
2378	#[test]
2379	fn signed_deposit_is_sensible() {
2380		// ensure this number does not change, or that it is checked after each change.
2381		// a 1 MB solution should take (40 + 10) DOTs of deposit.
2382		let deposit = SignedFixedDeposit::get() + (SignedDepositByte::get() * 1024 * 1024);
2383		assert_eq_error_rate!(deposit, 50 * DOLLARS, DOLLARS);
2384	}
2385}
2386
2387#[cfg(test)]
2388mod test {
2389	use std::collections::HashSet;
2390
2391	use super::*;
2392	use frame_support::traits::WhitelistedStorageKeys;
2393	use sp_core::hexdisplay::HexDisplay;
2394
2395	#[test]
2396	fn call_size() {
2397		RuntimeCall::assert_size_under(230);
2398	}
2399
2400	#[test]
2401	fn check_whitelist() {
2402		let whitelist: HashSet<String> = AllPalletsWithSystem::whitelisted_storage_keys()
2403			.iter()
2404			.map(|e| HexDisplay::from(&e.key).to_string())
2405			.collect();
2406
2407		// Block number
2408		assert!(
2409			whitelist.contains("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac")
2410		);
2411		// Total issuance
2412		assert!(
2413			whitelist.contains("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80")
2414		);
2415		// Execution phase
2416		assert!(
2417			whitelist.contains("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a")
2418		);
2419		// Event count
2420		assert!(
2421			whitelist.contains("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850")
2422		);
2423		// System events
2424		assert!(
2425			whitelist.contains("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7")
2426		);
2427		// XcmPallet VersionDiscoveryQueue
2428		assert!(
2429			whitelist.contains("1405f2411d0af5a7ff397e7c9dc68d194a222ba0333561192e474c59ed8e30e1")
2430		);
2431		// XcmPallet SafeXcmVersion
2432		assert!(
2433			whitelist.contains("1405f2411d0af5a7ff397e7c9dc68d196323ae84c43568be0d1394d5d0d522c4")
2434		);
2435	}
2436}
2437
2438#[cfg(test)]
2439mod multiplier_tests {
2440	use super::*;
2441	use frame_support::{dispatch::DispatchInfo, traits::OnFinalize};
2442	use runtime_common::{MinimumMultiplier, TargetBlockFullness};
2443	use separator::Separatable;
2444	use sp_runtime::traits::Convert;
2445
2446	fn run_with_system_weight<F>(w: Weight, mut assertions: F)
2447	where
2448		F: FnMut() -> (),
2449	{
2450		let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::<Runtime>::default()
2451			.build_storage()
2452			.unwrap()
2453			.into();
2454		t.execute_with(|| {
2455			System::set_block_consumed_resources(w, 0);
2456			assertions()
2457		});
2458	}
2459
2460	#[test]
2461	fn multiplier_can_grow_from_zero() {
2462		let minimum_multiplier = MinimumMultiplier::get();
2463		let target = TargetBlockFullness::get() *
2464			BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap();
2465		// if the min is too small, then this will not change, and we are doomed forever.
2466		// the weight is 1/100th bigger than target.
2467		run_with_system_weight(target.saturating_mul(101) / 100, || {
2468			let next = SlowAdjustingFeeUpdate::<Runtime>::convert(minimum_multiplier);
2469			assert!(next > minimum_multiplier, "{:?} !>= {:?}", next, minimum_multiplier);
2470		})
2471	}
2472
2473	#[test]
2474	fn fast_unstake_estimate() {
2475		use pallet_fast_unstake::WeightInfo;
2476		let block_time = BlockWeights::get().max_block.ref_time() as f32;
2477		let on_idle = weights::pallet_fast_unstake::WeightInfo::<Runtime>::on_idle_check(
2478			300,
2479			<Runtime as pallet_fast_unstake::Config>::BatchSize::get(),
2480		)
2481		.ref_time() as f32;
2482		println!("ratio of block weight for full batch fast-unstake {}", on_idle / block_time);
2483		assert!(on_idle / block_time <= 0.5f32)
2484	}
2485
2486	#[test]
2487	#[ignore]
2488	fn multiplier_growth_simulator() {
2489		// assume the multiplier is initially set to its minimum. We update it with values twice the
2490		//target (target is 25%, thus 50%) and we see at which point it reaches 1.
2491		let mut multiplier = MinimumMultiplier::get();
2492		let block_weight = BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap();
2493		let mut blocks = 0;
2494		let mut fees_paid = 0;
2495
2496		frame_system::Pallet::<Runtime>::set_block_consumed_resources(Weight::MAX, 0);
2497		let info = DispatchInfo { weight: Weight::MAX, ..Default::default() };
2498
2499		let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::<Runtime>::default()
2500			.build_storage()
2501			.unwrap()
2502			.into();
2503		// set the minimum
2504		t.execute_with(|| {
2505			pallet_transaction_payment::NextFeeMultiplier::<Runtime>::set(MinimumMultiplier::get());
2506		});
2507
2508		while multiplier <= Multiplier::from_u32(1) {
2509			t.execute_with(|| {
2510				// imagine this tx was called.
2511				let fee = TransactionPayment::compute_fee(0, &info, 0);
2512				fees_paid += fee;
2513
2514				// this will update the multiplier.
2515				System::set_block_consumed_resources(block_weight, 0);
2516				TransactionPayment::on_finalize(1);
2517				let next = TransactionPayment::next_fee_multiplier();
2518
2519				assert!(next > multiplier, "{:?} !>= {:?}", next, multiplier);
2520				multiplier = next;
2521
2522				println!(
2523					"block = {} / multiplier {:?} / fee = {:?} / fess so far {:?}",
2524					blocks,
2525					multiplier,
2526					fee.separated_string(),
2527					fees_paid.separated_string()
2528				);
2529			});
2530			blocks += 1;
2531		}
2532	}
2533
2534	#[test]
2535	#[ignore]
2536	fn multiplier_cool_down_simulator() {
2537		// assume the multiplier is initially set to its minimum. We update it with values twice the
2538		//target (target is 25%, thus 50%) and we see at which point it reaches 1.
2539		let mut multiplier = Multiplier::from_u32(2);
2540		let mut blocks = 0;
2541
2542		let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::<Runtime>::default()
2543			.build_storage()
2544			.unwrap()
2545			.into();
2546		// set the minimum
2547		t.execute_with(|| {
2548			pallet_transaction_payment::NextFeeMultiplier::<Runtime>::set(multiplier);
2549		});
2550
2551		while multiplier > Multiplier::from_u32(0) {
2552			t.execute_with(|| {
2553				// this will update the multiplier.
2554				TransactionPayment::on_finalize(1);
2555				let next = TransactionPayment::next_fee_multiplier();
2556
2557				assert!(next < multiplier, "{:?} !>= {:?}", next, multiplier);
2558				multiplier = next;
2559
2560				println!("block = {} / multiplier {:?}", blocks, multiplier);
2561			});
2562			blocks += 1;
2563		}
2564	}
2565}
2566
2567#[cfg(all(test, feature = "try-runtime"))]
2568mod remote_tests {
2569	use super::*;
2570	use frame_try_runtime::{runtime_decl_for_try_runtime::TryRuntime, UpgradeCheckSelect};
2571	use remote_externalities::{
2572		Builder, Mode, OfflineConfig, OnlineConfig, SnapshotConfig, Transport,
2573	};
2574	use std::env::var;
2575
2576	#[tokio::test]
2577	async fn run_migrations() {
2578		if var("RUN_MIGRATION_TESTS").is_err() {
2579			return
2580		}
2581
2582		sp_tracing::try_init_simple();
2583		let transport: Transport =
2584			var("WS").unwrap_or("wss://rpc.polkadot.io:443".to_string()).into();
2585		let maybe_state_snapshot: Option<SnapshotConfig> = var("SNAP").map(|s| s.into()).ok();
2586		let mut ext = Builder::<Block>::default()
2587			.mode(if let Some(state_snapshot) = maybe_state_snapshot {
2588				Mode::OfflineOrElseOnline(
2589					OfflineConfig { state_snapshot: state_snapshot.clone() },
2590					OnlineConfig {
2591						transport,
2592						state_snapshot: Some(state_snapshot),
2593						..Default::default()
2594					},
2595				)
2596			} else {
2597				Mode::Online(OnlineConfig { transport, ..Default::default() })
2598			})
2599			.build()
2600			.await
2601			.unwrap();
2602		ext.execute_with(|| Runtime::on_runtime_upgrade(UpgradeCheckSelect::PreAndPost));
2603	}
2604
2605	#[tokio::test]
2606	#[ignore = "this test is meant to be executed manually"]
2607	async fn try_fast_unstake_all() {
2608		sp_tracing::try_init_simple();
2609		let transport: Transport =
2610			var("WS").unwrap_or("wss://rpc.polkadot.io:443".to_string()).into();
2611		let maybe_state_snapshot: Option<SnapshotConfig> = var("SNAP").map(|s| s.into()).ok();
2612		let mut ext = Builder::<Block>::default()
2613			.mode(if let Some(state_snapshot) = maybe_state_snapshot {
2614				Mode::OfflineOrElseOnline(
2615					OfflineConfig { state_snapshot: state_snapshot.clone() },
2616					OnlineConfig {
2617						transport,
2618						state_snapshot: Some(state_snapshot),
2619						..Default::default()
2620					},
2621				)
2622			} else {
2623				Mode::Online(OnlineConfig { transport, ..Default::default() })
2624			})
2625			.build()
2626			.await
2627			.unwrap();
2628		ext.execute_with(|| {
2629			pallet_fast_unstake::ErasToCheckPerBlock::<Runtime>::put(1);
2630			runtime_common::try_runtime::migrate_all_inactive_nominators::<Runtime>()
2631		});
2632	}
2633}