referrerpolicy=no-referrer-when-downgrade

westend_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 Westend runtime. This can be compiled with `#[no_std]`, ready for Wasm.
18
19#![cfg_attr(not(feature = "std"), no_std)]
20// `#[frame_support::runtime]!` does a lot of recursion and requires us to increase the limit.
21#![recursion_limit = "512"]
22
23extern crate alloc;
24
25use alloc::{
26	collections::{btree_map::BTreeMap, vec_deque::VecDeque},
27	vec,
28	vec::Vec,
29};
30use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
31use frame_election_provider_support::{bounds::ElectionBoundsBuilder, onchain, SequentialPhragmen};
32use frame_support::{
33	derive_impl,
34	dynamic_params::{dynamic_pallet_params, dynamic_params},
35	genesis_builder_helper::{build_state, get_preset},
36	parameter_types,
37	traits::{
38		fungible::HoldConsideration, ConstU32, Contains, EnsureOriginWithArg, InstanceFilter,
39		KeyOwnerProofSystem, LinearStoragePrice, Nothing, ProcessMessage, ProcessMessageError,
40		VariantCountOf, WithdrawReasons,
41	},
42	weights::{ConstantMultiplier, WeightMeter},
43	PalletId,
44};
45#[cfg(not(feature = "runtime-benchmarks"))]
46use frame_system::EnsureNever;
47use frame_system::{EnsureRoot, EnsureSigned};
48use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId};
49use pallet_identity::legacy::IdentityInfo;
50use pallet_nomination_pools::PoolId;
51use pallet_session::historical as session_historical;
52use pallet_staking::UseValidatorsMap;
53use pallet_staking_async_ah_client as ah_client;
54use pallet_staking_async_rc_client as rc_client;
55use pallet_transaction_payment::{FeeDetails, FungibleAdapter, RuntimeDispatchInfo};
56use polkadot_primitives::{
57	async_backing::Constraints, slashing, AccountId, AccountIndex, ApprovalVotingParams, Balance,
58	BlockNumber, CandidateEvent, CandidateHash,
59	CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreIndex, CoreState, DisputeState,
60	ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage,
61	InboundHrmpMessage, Moment, NodeFeatures, Nonce, OccupiedCoreAssumption,
62	PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, SessionInfo, Signature,
63	ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature,
64	PARACHAIN_KEY_TYPE_ID,
65};
66use polkadot_runtime_common::{
67	assigned_slots, auctions, crowdloan,
68	elections::OnChainAccuracy,
69	identity_migrator, impl_runtime_weights,
70	impls::{ToAuthor, VersionedLocatableAsset},
71	paras_registrar, paras_sudo_wrapper, prod_or_fast, slots,
72	traits::OnSwap,
73	BalanceToU256, BlockHashCount, SlowAdjustingFeeUpdate, U256ToBalance,
74};
75use polkadot_runtime_parachains::{
76	configuration as parachains_configuration,
77	configuration::ActiveConfigHrmpChannelSizeAndCapacityRatio,
78	coretime, disputes as parachains_disputes,
79	disputes::slashing as parachains_slashing,
80	dmp as parachains_dmp, hrmp as parachains_hrmp, inclusion as parachains_inclusion,
81	inclusion::{AggregateMessageOrigin, UmpQueueId},
82	initializer as parachains_initializer, on_demand as parachains_on_demand,
83	origin as parachains_origin, paras as parachains_paras,
84	paras_inherent as parachains_paras_inherent, reward_points as parachains_reward_points,
85	runtime_api_impl::{
86		v13 as parachains_runtime_api_impl, vstaging as parachains_staging_runtime_api_impl,
87	},
88	scheduler as parachains_scheduler, session_info as parachains_session_info,
89	shared as parachains_shared,
90};
91use scale_info::TypeInfo;
92use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
93use sp_consensus_beefy::{
94	ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature},
95	mmr::{BeefyDataProvider, MmrLeafVersion},
96};
97use sp_core::{ConstBool, ConstU128, ConstUint, OpaqueMetadata, H256};
98#[cfg(any(feature = "std", test))]
99pub use sp_runtime::BuildStorage;
100use sp_runtime::{
101	generic, impl_opaque_keys,
102	traits::{
103		AccountIdConversion, BlakeTwo256, Block as BlockT, ConvertInto, Get, Keccak256, OpaqueKeys,
104		SaturatedConversion, Verify,
105	},
106	transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity},
107	ApplyExtrinsicResult, FixedU128, KeyTypeId, Percent,
108};
109use sp_staking::{EraIndex, SessionIndex};
110#[cfg(any(feature = "std", test))]
111use sp_version::NativeVersion;
112use sp_version::RuntimeVersion;
113use xcm::{
114	latest::prelude::*, Version as XcmVersion, VersionedAsset, VersionedAssetId, VersionedAssets,
115	VersionedLocation, VersionedXcm,
116};
117use xcm_runtime_apis::{
118	dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
119	fees::Error as XcmPaymentApiError,
120};
121
122pub use frame_system::Call as SystemCall;
123pub use pallet_balances::Call as BalancesCall;
124pub use pallet_election_provider_multi_phase::{Call as EPMCall, GeometricDepositBase};
125pub use pallet_timestamp::Call as TimestampCall;
126
127/// Constant values used within the runtime.
128use westend_runtime_constants::{
129	currency::*,
130	fee::*,
131	system_parachain::{
132		accumulate_forward::*, coretime::TIMESLICE_PERIOD, dap::*, ASSET_HUB_ID, BROKER_ID,
133	},
134	time::*,
135};
136
137mod bag_thresholds;
138mod genesis_config_presets;
139mod weights;
140pub mod xcm_config;
141
142// Implemented types.
143mod impls;
144use impls::ToParachainIdentityReaper;
145
146// XCM configuration.
147use xcm_config::XcmConfig;
148
149#[cfg(test)]
150mod tests;
151
152impl_runtime_weights!(westend_runtime_constants);
153
154// Make the WASM binary available.
155#[cfg(feature = "std")]
156include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
157
158#[cfg(feature = "std")]
159pub mod fast_runtime_binary {
160	include!(concat!(env!("OUT_DIR"), "/fast_runtime_binary.rs"));
161}
162
163/// Runtime version (Westend).
164#[sp_version::runtime_version]
165pub const VERSION: RuntimeVersion = RuntimeVersion {
166	spec_name: alloc::borrow::Cow::Borrowed("westend"),
167	impl_name: alloc::borrow::Cow::Borrowed("parity-westend"),
168	authoring_version: 2,
169	spec_version: 1_022_003,
170	impl_version: 0,
171	apis: RUNTIME_API_VERSIONS,
172	transaction_version: 27,
173	system_version: 1,
174};
175
176/// The BABE epoch configuration at genesis.
177pub const BABE_GENESIS_EPOCH_CONFIG: sp_consensus_babe::BabeEpochConfiguration =
178	sp_consensus_babe::BabeEpochConfiguration {
179		c: PRIMARY_PROBABILITY,
180		allowed_slots: sp_consensus_babe::AllowedSlots::PrimaryAndSecondaryVRFSlots,
181	};
182
183/// Native version.
184#[cfg(any(feature = "std", test))]
185pub fn native_version() -> NativeVersion {
186	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
187}
188
189/// A type to identify calls to the Identity pallet. These will be filtered to prevent invocation,
190/// locking the state of the pallet and preventing further updates to identities and sub-identities.
191/// The locked state will be the genesis state of a new system chain and then removed from the Relay
192/// Chain.
193pub struct IsIdentityCall;
194impl Contains<RuntimeCall> for IsIdentityCall {
195	fn contains(c: &RuntimeCall) -> bool {
196		matches!(c, RuntimeCall::Identity(_))
197	}
198}
199
200parameter_types! {
201	pub const Version: RuntimeVersion = VERSION;
202	pub const SS58Prefix: u8 = 42;
203	/// Maximum length of a relay-chain block is up to 10 MiB.
204	pub BlockLength: frame_system::limits::BlockLength =
205		frame_system::limits::BlockLength::builder()
206			.max_length(10 * 1024 * 1024)
207			.modify_max_length_for_class(
208				frame_support::dispatch::DispatchClass::Normal,
209				|m| { *m = polkadot_runtime_common::NORMAL_DISPATCH_RATIO * *m },
210			)
211			.build();
212}
213
214#[derive_impl(frame_system::config_preludes::RelayChainDefaultConfig)]
215impl frame_system::Config for Runtime {
216	type BlockWeights = BlockWeights;
217	type BlockLength = BlockLength;
218	type Nonce = Nonce;
219	type Hash = Hash;
220	type AccountId = AccountId;
221	type Block = Block;
222	type BlockHashCount = BlockHashCount;
223	type DbWeight = RocksDbWeight;
224	type Version = Version;
225	type AccountData = pallet_balances::AccountData<Balance>;
226	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
227	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
228	type SS58Prefix = SS58Prefix;
229	type MaxConsumers = frame_support::traits::ConstU32<16>;
230	type MultiBlockMigrator = MultiBlockMigrations;
231	type SingleBlockMigrations = Migrations;
232}
233
234parameter_types! {
235	pub MaximumSchedulerWeight: frame_support::weights::Weight = Perbill::from_percent(80) *
236		BlockWeights::get().max_block;
237	pub const MaxScheduledPerBlock: u32 = 50;
238	pub const NoPreimagePostponement: Option<u32> = Some(10);
239}
240
241impl pallet_scheduler::Config for Runtime {
242	type RuntimeOrigin = RuntimeOrigin;
243	type RuntimeEvent = RuntimeEvent;
244	type PalletsOrigin = OriginCaller;
245	type RuntimeCall = RuntimeCall;
246	type MaximumWeight = MaximumSchedulerWeight;
247	type ScheduleOrigin = EnsureRoot<AccountId>;
248	type MaxScheduledPerBlock = MaxScheduledPerBlock;
249	type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
250	type OriginPrivilegeCmp = frame_support::traits::EqualPrivilegeOnly;
251	type Preimages = Preimage;
252	type BlockNumberProvider = System;
253}
254
255parameter_types! {
256	pub const PreimageBaseDeposit: Balance = deposit(2, 64);
257	pub const PreimageByteDeposit: Balance = deposit(0, 1);
258	pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
259}
260
261/// Dynamic params that can be adjusted at runtime.
262#[dynamic_params(RuntimeParameters, pallet_parameters::Parameters::<Runtime>)]
263pub mod dynamic_params {
264	use super::*;
265
266	/// Parameters used to calculate era payouts, see
267	/// [`polkadot_runtime_common::impls::EraPayoutParams`].
268	#[dynamic_pallet_params]
269	#[codec(index = 0)]
270	pub mod inflation {
271		/// Minimum inflation rate used to calculate era payouts.
272		#[codec(index = 0)]
273		pub static MinInflation: Perquintill = Perquintill::from_rational(25u64, 1000u64);
274
275		/// Maximum inflation rate used to calculate era payouts.
276		#[codec(index = 1)]
277		pub static MaxInflation: Perquintill = Perquintill::from_rational(10u64, 100u64);
278
279		/// Ideal stake ratio used to calculate era payouts.
280		#[codec(index = 2)]
281		pub static IdealStake: Perquintill = Perquintill::from_rational(50u64, 100u64);
282
283		/// Falloff used to calculate era payouts.
284		#[codec(index = 3)]
285		pub static Falloff: Perquintill = Perquintill::from_rational(50u64, 1000u64);
286
287		/// Whether to use auction slots or not in the calculation of era payouts. If set to true,
288		/// the `legacy_auction_proportion` of 60% will be used in the calculation of era payouts.
289		#[codec(index = 4)]
290		pub static UseAuctionSlots: bool = false;
291	}
292}
293
294#[cfg(feature = "runtime-benchmarks")]
295impl Default for RuntimeParameters {
296	fn default() -> Self {
297		RuntimeParameters::Inflation(dynamic_params::inflation::Parameters::MinInflation(
298			dynamic_params::inflation::MinInflation,
299			Some(Perquintill::from_rational(25u64, 1000u64)),
300		))
301	}
302}
303
304impl pallet_parameters::Config for Runtime {
305	type RuntimeEvent = RuntimeEvent;
306	type RuntimeParameters = RuntimeParameters;
307	type AdminOrigin = DynamicParameterOrigin;
308	type WeightInfo = weights::pallet_parameters::WeightInfo<Runtime>;
309}
310
311/// Defines what origin can modify which dynamic parameters.
312pub struct DynamicParameterOrigin;
313impl EnsureOriginWithArg<RuntimeOrigin, RuntimeParametersKey> for DynamicParameterOrigin {
314	type Success = ();
315
316	fn try_origin(
317		origin: RuntimeOrigin,
318		key: &RuntimeParametersKey,
319	) -> Result<Self::Success, RuntimeOrigin> {
320		use crate::RuntimeParametersKey::*;
321
322		match key {
323			Inflation(_) => frame_system::ensure_root(origin.clone()),
324		}
325		.map_err(|_| origin)
326	}
327
328	#[cfg(feature = "runtime-benchmarks")]
329	fn try_successful_origin(_key: &RuntimeParametersKey) -> Result<RuntimeOrigin, ()> {
330		// Provide the origin for the parameter returned by `Default`:
331		Ok(RuntimeOrigin::root())
332	}
333}
334
335impl pallet_preimage::Config for Runtime {
336	type WeightInfo = weights::pallet_preimage::WeightInfo<Runtime>;
337	type RuntimeEvent = RuntimeEvent;
338	type Currency = Balances;
339	type ManagerOrigin = EnsureRoot<AccountId>;
340	type Consideration = HoldConsideration<
341		AccountId,
342		Balances,
343		PreimageHoldReason,
344		LinearStoragePrice<PreimageBaseDeposit, PreimageByteDeposit, Balance>,
345	>;
346}
347
348parameter_types! {
349	pub const EpochDuration: u64 = prod_or_fast!(
350		EPOCH_DURATION_IN_SLOTS as u64,
351		2 * MINUTES as u64
352	);
353	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
354	pub const ReportLongevity: u64 =
355		BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get();
356}
357
358impl pallet_babe::Config for Runtime {
359	type EpochDuration = EpochDuration;
360	type ExpectedBlockTime = ExpectedBlockTime;
361
362	// session module is the trigger
363	type EpochChangeTrigger = pallet_babe::ExternalTrigger;
364
365	type DisabledValidators = Session;
366
367	type WeightInfo = ();
368
369	type MaxAuthorities = MaxAuthorities;
370	type MaxNominators = MaxNominators;
371
372	type KeyOwnerProof = sp_session::MembershipProof;
373
374	type EquivocationReportSystem =
375		pallet_babe::EquivocationReportSystem<Self, Offences, Historical, ReportLongevity>;
376}
377
378parameter_types! {
379	pub const IndexDeposit: Balance = 100 * CENTS;
380}
381
382impl pallet_indices::Config for Runtime {
383	type AccountIndex = AccountIndex;
384	type Currency = Balances;
385	type Deposit = IndexDeposit;
386	type RuntimeEvent = RuntimeEvent;
387	type WeightInfo = weights::pallet_indices::WeightInfo<Runtime>;
388}
389
390parameter_types! {
391	pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
392	pub const MaxLocks: u32 = 50;
393	pub const MaxReserves: u32 = 50;
394}
395
396impl pallet_balances::Config for Runtime {
397	type Balance = Balance;
398	type DustRemoval = AccumulateForward;
399	type RuntimeEvent = RuntimeEvent;
400	type ExistentialDeposit = ExistentialDeposit;
401	type AccountStore = System;
402	type MaxLocks = MaxLocks;
403	type MaxReserves = MaxReserves;
404	type ReserveIdentifier = [u8; 8];
405	type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
406	type RuntimeHoldReason = RuntimeHoldReason;
407	type RuntimeFreezeReason = RuntimeFreezeReason;
408	type FreezeIdentifier = RuntimeFreezeReason;
409	type MaxFreezes = VariantCountOf<RuntimeFreezeReason>;
410	type DoneSlashHandler = ();
411}
412
413parameter_types! {
414	pub const BeefySetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get();
415}
416
417impl pallet_beefy::Config for Runtime {
418	type BeefyId = BeefyId;
419	type MaxAuthorities = MaxAuthorities;
420	type MaxNominators = MaxNominators;
421	type MaxSetIdSessionEntries = BeefySetIdSessionEntries;
422	type OnNewValidatorSet = BeefyMmrLeaf;
423	type AncestryHelper = BeefyMmrLeaf;
424	type WeightInfo = ();
425	type KeyOwnerProof = sp_session::MembershipProof;
426	type EquivocationReportSystem =
427		pallet_beefy::EquivocationReportSystem<Self, Offences, Historical, ReportLongevity>;
428}
429
430impl pallet_mmr::Config for Runtime {
431	const INDEXING_PREFIX: &'static [u8] = mmr::INDEXING_PREFIX;
432	type Hashing = Keccak256;
433	type OnNewRoot = pallet_beefy_mmr::DepositBeefyDigest<Runtime>;
434	type LeafData = pallet_beefy_mmr::Pallet<Runtime>;
435	type BlockHashProvider = pallet_mmr::DefaultBlockHashProvider<Runtime>;
436	type WeightInfo = weights::pallet_mmr::WeightInfo<Runtime>;
437	#[cfg(feature = "runtime-benchmarks")]
438	type BenchmarkHelper = parachains_paras::benchmarking::mmr_setup::MmrSetup<Runtime>;
439}
440
441/// MMR helper types.
442mod mmr {
443	use super::Runtime;
444	pub use pallet_mmr::primitives::*;
445
446	pub type Leaf = <<Runtime as pallet_mmr::Config>::LeafData as LeafDataProvider>::LeafData;
447	pub type Hashing = <Runtime as pallet_mmr::Config>::Hashing;
448	pub type Hash = <Hashing as sp_runtime::traits::Hash>::Output;
449}
450
451parameter_types! {
452	pub LeafVersion: MmrLeafVersion = MmrLeafVersion::new(0, 0);
453}
454
455/// A BEEFY data provider that merkelizes all the parachain heads at the current block
456/// (sorted by their parachain id).
457pub struct ParaHeadsRootProvider;
458impl BeefyDataProvider<H256> for ParaHeadsRootProvider {
459	fn extra_data() -> H256 {
460		let para_heads: Vec<(u32, Vec<u8>)> =
461			parachains_paras::Pallet::<Runtime>::sorted_para_heads();
462		binary_merkle_tree::merkle_root::<mmr::Hashing, _>(
463			para_heads.into_iter().map(|pair| pair.encode()),
464		)
465		.into()
466	}
467}
468
469impl pallet_beefy_mmr::Config for Runtime {
470	type LeafVersion = LeafVersion;
471	type BeefyAuthorityToMerkleLeaf = pallet_beefy_mmr::BeefyEcdsaToEthereum;
472	type LeafExtra = H256;
473	type BeefyDataProvider = ParaHeadsRootProvider;
474	type WeightInfo = weights::pallet_beefy_mmr::WeightInfo<Runtime>;
475}
476
477parameter_types! {
478	pub const TransactionByteFee: Balance = 10 * MILLICENTS;
479	/// This value increases the priority of `Operational` transactions by adding
480	/// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
481	pub const OperationalFeeMultiplier: u8 = 5;
482	/// Percentage of fees that go to the accumulation account.
483	/// The remainder goes to block author. Tips always go 100% to author.
484	pub const AccumulateForwardFeePercent: Percent = Percent::from_percent(100);
485}
486
487/// Fee handler that splits fees between the accumulation account and block author.
488type DealWithFeesAccumulate = pallet_accumulate_and_forward::DealWithFeesSplit<
489	Runtime,
490	AccumulateForwardFeePercent,
491	ToAuthor<Runtime>,
492>;
493
494impl pallet_transaction_payment::Config for Runtime {
495	type RuntimeEvent = RuntimeEvent;
496	type OnChargeTransaction = FungibleAdapter<Balances, DealWithFeesAccumulate>;
497	type OperationalFeeMultiplier = OperationalFeeMultiplier;
498	type WeightToFee = WeightToFee;
499	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
500	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
501	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
502}
503
504parameter_types! {
505	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
506}
507impl pallet_timestamp::Config for Runtime {
508	type Moment = u64;
509	type OnTimestampSet = Babe;
510	type MinimumPeriod = MinimumPeriod;
511	type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
512}
513
514impl pallet_authorship::Config for Runtime {
515	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
516	type EventHandler = StakingAhClient;
517}
518
519parameter_types! {
520	pub const Period: BlockNumber = 10 * MINUTES;
521	pub const Offset: BlockNumber = 0;
522}
523
524impl_opaque_keys! {
525	pub struct SessionKeys {
526		pub grandpa: Grandpa,
527		pub babe: Babe,
528		pub para_validator: Initializer,
529		pub para_assignment: ParaSessionInfo,
530		pub authority_discovery: AuthorityDiscovery,
531		pub beefy: Beefy,
532	}
533}
534
535impl pallet_session::Config for Runtime {
536	type RuntimeEvent = RuntimeEvent;
537	type ValidatorId = AccountId;
538	type ValidatorIdOf = ConvertInto;
539	type ShouldEndSession = Babe;
540	type NextSessionRotation = Babe;
541	type SessionManager = session_historical::NoteHistoricalRoot<Self, StakingAhClient>;
542	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
543	type Keys = SessionKeys;
544	type DisablingStrategy = pallet_session::disabling::UpToLimitWithReEnablingDisablingStrategy;
545	type WeightInfo = weights::pallet_session::WeightInfo<Runtime>;
546	type Currency = Balances;
547	type KeyDeposit = ();
548}
549
550impl pallet_session::historical::Config for Runtime {
551	type RuntimeEvent = RuntimeEvent;
552	type FullIdentification = sp_staking::Exposure<AccountId, Balance>;
553	type FullIdentificationOf = pallet_staking::DefaultExposureOf<Self>;
554}
555
556pub struct MaybeSignedPhase;
557
558impl Get<u32> for MaybeSignedPhase {
559	fn get() -> u32 {
560		// 1 day = 4 eras -> 1 week = 28 eras. We want to disable signed phase once a week to test
561		// the fallback unsigned phase is able to compute elections on Westend.
562		if pallet_staking::CurrentEra::<Runtime>::get().unwrap_or(1).is_multiple_of(28) {
563			0
564		} else {
565			SignedPhase::get()
566		}
567	}
568}
569
570parameter_types! {
571	// phase durations. 1/4 of the last session for each.
572	pub SignedPhase: u32 = prod_or_fast!(
573		EPOCH_DURATION_IN_SLOTS / 4,
574		(1 * MINUTES).min(EpochDuration::get().saturated_into::<u32>() / 2)
575	);
576	pub UnsignedPhase: u32 = prod_or_fast!(
577		EPOCH_DURATION_IN_SLOTS / 4,
578		(1 * MINUTES).min(EpochDuration::get().saturated_into::<u32>() / 2)
579	);
580
581	// signed config
582	pub const SignedMaxSubmissions: u32 = 128;
583	pub const SignedMaxRefunds: u32 = 128 / 4;
584	pub const SignedFixedDeposit: Balance = deposit(2, 0);
585	pub const SignedDepositIncreaseFactor: Percent = Percent::from_percent(10);
586	pub const SignedDepositByte: Balance = deposit(0, 10) / 1024;
587	// Each good submission will get 1 WND as reward
588	pub SignedRewardBase: Balance = 1 * UNITS;
589
590	// 1 hour session, 15 minutes unsigned phase, 4 offchain executions.
591	pub OffchainRepeat: BlockNumber = UnsignedPhase::get() / 4;
592
593	pub const MaxElectingVoters: u32 = 22_500;
594	/// We take the top 22500 nominators as electing voters and all of the validators as electable
595	/// targets. Whilst this is the case, we cannot and shall not increase the size of the
596	/// validator intentions.
597	pub ElectionBounds: frame_election_provider_support::bounds::ElectionBounds =
598		ElectionBoundsBuilder::default().voters_count(MaxElectingVoters::get().into()).build();
599	// Maximum winners that can be chosen as active validators
600	pub const MaxActiveValidators: u32 = 1000;
601	// One page only, fill the whole page with the `MaxActiveValidators`.
602	pub const MaxWinnersPerPage: u32 = MaxActiveValidators::get();
603	// Unbonded, thus the max backers per winner maps to the max electing voters limit.
604	pub const MaxBackersPerWinner: u32 = MaxElectingVoters::get();
605}
606
607frame_election_provider_support::generate_solution_type!(
608	#[compact]
609	pub struct NposCompactSolution16::<
610		VoterIndex = u32,
611		TargetIndex = u16,
612		Accuracy = sp_runtime::PerU16,
613		MaxVoters = MaxElectingVoters,
614	>(16)
615);
616
617pub struct OnChainSeqPhragmen;
618impl onchain::Config for OnChainSeqPhragmen {
619	type Sort = ConstBool<true>;
620	type System = Runtime;
621	type Solver = SequentialPhragmen<AccountId, OnChainAccuracy>;
622	type DataProvider = Staking;
623	type WeightInfo = weights::frame_election_provider_support::WeightInfo<Runtime>;
624	type Bounds = ElectionBounds;
625	type MaxBackersPerWinner = MaxBackersPerWinner;
626	type MaxWinnersPerPage = MaxWinnersPerPage;
627}
628
629impl pallet_election_provider_multi_phase::MinerConfig for Runtime {
630	type AccountId = AccountId;
631	type MaxLength = OffchainSolutionLengthLimit;
632	type MaxWeight = OffchainSolutionWeightLimit;
633	type Solution = NposCompactSolution16;
634	type MaxVotesPerVoter = <
635    <Self as pallet_election_provider_multi_phase::Config>::DataProvider
636    as
637    frame_election_provider_support::ElectionDataProvider
638    >::MaxVotesPerVoter;
639	type MaxBackersPerWinner = MaxBackersPerWinner;
640	type MaxWinners = MaxWinnersPerPage;
641
642	// The unsigned submissions have to respect the weight of the submit_unsigned call, thus their
643	// weight estimate function is wired to this call's weight.
644	fn solution_weight(v: u32, t: u32, a: u32, d: u32) -> Weight {
645		<
646        <Self as pallet_election_provider_multi_phase::Config>::WeightInfo
647        as
648        pallet_election_provider_multi_phase::WeightInfo
649        >::submit_unsigned(v, t, a, d)
650	}
651}
652
653impl pallet_election_provider_multi_phase::Config for Runtime {
654	type RuntimeEvent = RuntimeEvent;
655	type Currency = Balances;
656	type EstimateCallFee = TransactionPayment;
657	type SignedPhase = MaybeSignedPhase;
658	type UnsignedPhase = UnsignedPhase;
659	type SignedMaxSubmissions = SignedMaxSubmissions;
660	type SignedMaxRefunds = SignedMaxRefunds;
661	type SignedRewardBase = SignedRewardBase;
662	type SignedDepositBase =
663		GeometricDepositBase<Balance, SignedFixedDeposit, SignedDepositIncreaseFactor>;
664	type SignedDepositByte = SignedDepositByte;
665	type SignedDepositWeight = ();
666	type SignedMaxWeight =
667		<Self::MinerConfig as pallet_election_provider_multi_phase::MinerConfig>::MaxWeight;
668	type MinerConfig = Self;
669	type SlashHandler = (); // burn slashes
670	type RewardHandler = (); // rewards are minted from the void
671	type BetterSignedThreshold = ();
672	type OffchainRepeat = OffchainRepeat;
673	type MinerTxPriority = NposSolutionPriority;
674	type MaxWinners = MaxWinnersPerPage;
675	type MaxBackersPerWinner = MaxBackersPerWinner;
676	type DataProvider = Staking;
677	#[cfg(any(feature = "fast-runtime", feature = "runtime-benchmarks"))]
678	type Fallback = onchain::OnChainExecution<OnChainSeqPhragmen>;
679	#[cfg(not(any(feature = "fast-runtime", feature = "runtime-benchmarks")))]
680	type Fallback = frame_election_provider_support::NoElection<(
681		AccountId,
682		BlockNumber,
683		Staking,
684		MaxWinnersPerPage,
685		MaxBackersPerWinner,
686	)>;
687	type GovernanceFallback = onchain::OnChainExecution<OnChainSeqPhragmen>;
688	type Solver = SequentialPhragmen<
689		AccountId,
690		pallet_election_provider_multi_phase::SolutionAccuracyOf<Self>,
691		(),
692	>;
693	type BenchmarkingConfig = polkadot_runtime_common::elections::BenchmarkConfig;
694	// TODO: drop once pallet is removed from Westend RC (post-AHM cleanup).
695	#[cfg(not(feature = "runtime-benchmarks"))]
696	type ForceOrigin = EnsureNever<AccountId>;
697	#[cfg(feature = "runtime-benchmarks")]
698	type ForceOrigin = EnsureRoot<AccountId>;
699	type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Self>;
700	type ElectionBounds = ElectionBounds;
701}
702
703parameter_types! {
704	pub const BagThresholds: &'static [u64] = &bag_thresholds::THRESHOLDS;
705	pub const AutoRebagNumber: u32 = 10;
706}
707
708type VoterBagsListInstance = pallet_bags_list::Instance1;
709impl pallet_bags_list::Config<VoterBagsListInstance> for Runtime {
710	type RuntimeEvent = RuntimeEvent;
711	type WeightInfo = weights::pallet_bags_list::WeightInfo<Runtime>;
712	type ScoreProvider = Staking;
713	type BagThresholds = BagThresholds;
714	type MaxAutoRebagPerBlock = AutoRebagNumber;
715	type Score = sp_npos_elections::VoteWeight;
716}
717
718pub struct EraPayout;
719impl pallet_staking::EraPayout<Balance> for EraPayout {
720	fn era_payout(
721		_total_staked: Balance,
722		_total_issuance: Balance,
723		era_duration_millis: u64,
724	) -> (Balance, Balance) {
725		const MILLISECONDS_PER_YEAR: u64 = (1000 * 3600 * 24 * 36525) / 100;
726		// A normal-sized era will have 1 / 365.25 here:
727		let relative_era_len =
728			FixedU128::from_rational(era_duration_millis.into(), MILLISECONDS_PER_YEAR.into());
729
730		// Fixed total TI that we use as baseline for the issuance.
731		let fixed_total_issuance: i128 = 5_216_342_402_773_185_773;
732		let fixed_inflation_rate = FixedU128::from_rational(8, 100);
733		let yearly_emission = fixed_inflation_rate.saturating_mul_int(fixed_total_issuance);
734
735		let era_emission = relative_era_len.saturating_mul_int(yearly_emission);
736		// 15% to treasury, as per Polkadot ref 1139.
737		let to_treasury = FixedU128::from_rational(15, 100).saturating_mul_int(era_emission);
738		let to_stakers = era_emission.saturating_sub(to_treasury);
739
740		(to_stakers.saturated_into(), to_treasury.saturated_into())
741	}
742}
743
744parameter_types! {
745	// Six sessions in an era (6 hours).
746	pub const SessionsPerEra: SessionIndex = prod_or_fast!(6, 2);
747	// 2 eras for unbonding (12 hours).
748	pub const BondingDuration: EraIndex = 2;
749	// 1 era in which slashes can be cancelled (6 hours).
750	pub const SlashDeferDuration: EraIndex = 1;
751	pub const MaxExposurePageSize: u32 = 64;
752	// Note: this is not really correct as Max Nominators is (MaxExposurePageSize * page_count) but
753	// this is an unbounded number. We just set it to a reasonably high value, 1 full page
754	// of nominators.
755	pub const MaxNominators: u32 = 64;
756	pub const MaxNominations: u32 = <NposCompactSolution16 as frame_election_provider_support::NposSolution>::LIMIT as u32;
757	pub const MaxControllersInDeprecationBatch: u32 = 751;
758}
759
760impl pallet_staking::Config for Runtime {
761	type OldCurrency = Balances;
762	type Currency = Balances;
763	type CurrencyBalance = Balance;
764	type RuntimeHoldReason = RuntimeHoldReason;
765	type UnixTime = Timestamp;
766	// Westend's total issuance is already more than `u64::MAX`, this will work better.
767	type CurrencyToVote = sp_staking::currency_to_vote::SaturatingCurrencyToVote;
768	type RewardRemainder = ();
769	type RuntimeEvent = RuntimeEvent;
770	type Slash = ();
771	type Reward = ();
772	type SessionsPerEra = SessionsPerEra;
773	type BondingDuration = BondingDuration;
774	type SlashDeferDuration = SlashDeferDuration;
775	// TODO: drop once pallet is removed from Westend RC (post-AHM cleanup).
776	#[cfg(not(feature = "runtime-benchmarks"))]
777	type AdminOrigin = EnsureNever<AccountId>;
778	#[cfg(feature = "runtime-benchmarks")]
779	type AdminOrigin = EnsureRoot<AccountId>;
780	type SessionInterface = Self;
781	type EraPayout = EraPayout;
782	type MaxExposurePageSize = MaxExposurePageSize;
783	type NextNewSession = Session;
784	type ElectionProvider = ElectionProviderMultiPhase;
785	type GenesisElectionProvider = onchain::OnChainExecution<OnChainSeqPhragmen>;
786	type VoterList = VoterList;
787	type TargetList = UseValidatorsMap<Self>;
788	type MaxValidatorSet = MaxActiveValidators;
789	type NominationsQuota = pallet_staking::FixedNominationsQuota<{ MaxNominations::get() }>;
790	type MaxUnlockingChunks = frame_support::traits::ConstU32<32>;
791	type HistoryDepth = frame_support::traits::ConstU32<84>;
792	type MaxControllersInDeprecationBatch = MaxControllersInDeprecationBatch;
793	type BenchmarkingConfig = polkadot_runtime_common::StakingBenchmarkingConfig;
794	type EventListeners = (NominationPools, DelegatedStaking);
795	type WeightInfo = weights::pallet_staking::WeightInfo<Runtime>;
796	// Genesis benchmarking setup needs this until we remove the pallet completely.
797	#[cfg(not(feature = "on-chain-release-build"))]
798	type Filter = Nothing;
799	#[cfg(feature = "on-chain-release-build")]
800	type Filter = frame_support::traits::Everything;
801}
802
803#[derive(Encode, Decode)]
804enum AssetHubRuntimePallets<AccountId> {
805	// Audit: `StakingRcClient` in asset-hub-westend
806	#[codec(index = 89)]
807	RcClient(RcClientCalls<AccountId>),
808}
809
810#[derive(Encode, Decode)]
811enum RcClientCalls<AccountId> {
812	#[codec(index = 0)]
813	RelaySessionReport(rc_client::SessionReport<AccountId>),
814	#[codec(index = 1)]
815	RelayNewOffencePaged(Vec<(SessionIndex, rc_client::Offence<AccountId>)>),
816}
817
818pub struct AssetHubLocation;
819impl Get<Location> for AssetHubLocation {
820	fn get() -> Location {
821		Location::new(0, [Junction::Parachain(ASSET_HUB_ID)])
822	}
823}
824
825pub struct EnsureAssetHub;
826impl frame_support::traits::EnsureOrigin<RuntimeOrigin> for EnsureAssetHub {
827	type Success = ();
828	fn try_origin(o: RuntimeOrigin) -> Result<Self::Success, RuntimeOrigin> {
829		match <RuntimeOrigin as Into<Result<parachains_origin::Origin, RuntimeOrigin>>>::into(
830			o.clone(),
831		) {
832			Ok(parachains_origin::Origin::Parachain(id)) if id == ASSET_HUB_ID.into() => Ok(()),
833			_ => Err(o),
834		}
835	}
836
837	#[cfg(feature = "runtime-benchmarks")]
838	fn try_successful_origin() -> Result<RuntimeOrigin, ()> {
839		Ok(RuntimeOrigin::root())
840	}
841}
842
843pub struct SessionReportToXcm;
844impl sp_runtime::traits::Convert<rc_client::SessionReport<AccountId>, Xcm<()>>
845	for SessionReportToXcm
846{
847	fn convert(a: rc_client::SessionReport<AccountId>) -> Xcm<()> {
848		Xcm(vec![
849			Instruction::UnpaidExecution {
850				weight_limit: WeightLimit::Unlimited,
851				check_origin: None,
852			},
853			Instruction::Transact {
854				origin_kind: OriginKind::Superuser,
855				fallback_max_weight: None,
856				call: AssetHubRuntimePallets::RcClient(RcClientCalls::RelaySessionReport(a))
857					.encode()
858					.into(),
859			},
860		])
861	}
862}
863
864pub struct QueuedOffenceToXcm;
865impl sp_runtime::traits::Convert<Vec<ah_client::QueuedOffenceOf<Runtime>>, Xcm<()>>
866	for QueuedOffenceToXcm
867{
868	fn convert(offences: Vec<ah_client::QueuedOffenceOf<Runtime>>) -> Xcm<()> {
869		Xcm(vec![
870			Instruction::UnpaidExecution {
871				weight_limit: WeightLimit::Unlimited,
872				check_origin: None,
873			},
874			Instruction::Transact {
875				origin_kind: OriginKind::Superuser,
876				fallback_max_weight: None,
877				call: AssetHubRuntimePallets::RcClient(RcClientCalls::RelayNewOffencePaged(
878					offences,
879				))
880				.encode()
881				.into(),
882			},
883		])
884	}
885}
886
887pub struct StakingXcmToAssetHub;
888impl ah_client::SendToAssetHub for StakingXcmToAssetHub {
889	type AccountId = AccountId;
890
891	fn relay_session_report(
892		session_report: rc_client::SessionReport<Self::AccountId>,
893	) -> Result<(), ()> {
894		rc_client::XCMSender::<
895			xcm_config::XcmRouter,
896			AssetHubLocation,
897			rc_client::SessionReport<AccountId>,
898			SessionReportToXcm,
899		>::send(session_report)
900	}
901
902	fn relay_new_offence_paged(
903		offences: Vec<ah_client::QueuedOffenceOf<Runtime>>,
904	) -> Result<(), ()> {
905		rc_client::XCMSender::<
906			xcm_config::XcmRouter,
907			AssetHubLocation,
908			Vec<ah_client::QueuedOffenceOf<Runtime>>,
909			QueuedOffenceToXcm,
910		>::send(offences)
911	}
912}
913
914impl ah_client::Config for Runtime {
915	type CurrencyBalance = Balance;
916	type AssetHubOrigin =
917		frame_support::traits::EitherOfDiverse<EnsureRoot<AccountId>, EnsureAssetHub>;
918	type AdminOrigin = EnsureRoot<AccountId>;
919	type SessionInterface = Session;
920	type SendToAssetHub = StakingXcmToAssetHub;
921	type MinimumValidatorSetSize = ConstU32<1>;
922	type UnixTime = Timestamp;
923	type PointsPerBlock = ConstU32<20>;
924	type MaxOffenceBatchSize = ConstU32<50>;
925	type Fallback = Staking;
926	type MaximumValidatorsWithPoints = ConstU32<{ MaxActiveValidators::get() * 4 }>;
927	type MaxSessionReportRetries = ConstU32<5>;
928}
929
930impl pallet_fast_unstake::Config for Runtime {
931	type RuntimeEvent = RuntimeEvent;
932	type Currency = Balances;
933	type BatchSize = ConstU32<64>;
934	type Deposit = ConstU128<{ UNITS }>;
935	// TODO: drop once pallet is removed from Westend RC (post-AHM cleanup).
936	#[cfg(not(feature = "runtime-benchmarks"))]
937	type ControlOrigin = EnsureNever<AccountId>;
938	#[cfg(feature = "runtime-benchmarks")]
939	type ControlOrigin = EnsureRoot<AccountId>;
940	type Staking = Staking;
941	type MaxErasToCheckPerBlock = ConstU32<1>;
942	type WeightInfo = weights::pallet_fast_unstake::WeightInfo<Runtime>;
943}
944
945parameter_types! {
946	pub const MaxAuthorities: u32 = 100_000;
947}
948
949impl pallet_offences::Config for Runtime {
950	type RuntimeEvent = RuntimeEvent;
951	type IdentificationTuple = session_historical::IdentificationTuple<Self>;
952	type OnOffenceHandler = StakingAhClient;
953}
954
955impl pallet_authority_discovery::Config for Runtime {
956	type MaxAuthorities = MaxAuthorities;
957}
958
959parameter_types! {
960	pub const NposSolutionPriority: TransactionPriority = TransactionPriority::max_value() / 2;
961}
962
963parameter_types! {
964	pub const MaxSetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get();
965}
966
967impl pallet_grandpa::Config for Runtime {
968	type RuntimeEvent = RuntimeEvent;
969
970	type WeightInfo = ();
971	type MaxAuthorities = MaxAuthorities;
972	type MaxNominators = MaxNominators;
973	type MaxSetIdSessionEntries = MaxSetIdSessionEntries;
974
975	type KeyOwnerProof = sp_session::MembershipProof;
976
977	type EquivocationReportSystem =
978		pallet_grandpa::EquivocationReportSystem<Self, Offences, Historical, ReportLongevity>;
979}
980
981impl frame_system::offchain::SigningTypes for Runtime {
982	type Public = <Signature as Verify>::Signer;
983	type Signature = Signature;
984}
985
986impl<C> frame_system::offchain::CreateTransactionBase<C> for Runtime
987where
988	RuntimeCall: From<C>,
989{
990	type RuntimeCall = RuntimeCall;
991	type Extrinsic = UncheckedExtrinsic;
992}
993
994impl<LocalCall> frame_system::offchain::CreateTransaction<LocalCall> for Runtime
995where
996	RuntimeCall: From<LocalCall>,
997{
998	type Extension = TxExtension;
999
1000	fn create_transaction(call: RuntimeCall, extension: TxExtension) -> UncheckedExtrinsic {
1001		UncheckedExtrinsic::new_transaction(call, extension)
1002	}
1003}
1004
1005/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
1006/// format of the chain.
1007impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
1008where
1009	RuntimeCall: From<LocalCall>,
1010{
1011	fn create_signed_transaction<
1012		C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>,
1013	>(
1014		call: RuntimeCall,
1015		public: <Signature as Verify>::Signer,
1016		account: AccountId,
1017		nonce: <Runtime as frame_system::Config>::Nonce,
1018	) -> Option<UncheckedExtrinsic> {
1019		use sp_runtime::traits::StaticLookup;
1020		// take the biggest period possible.
1021		let period =
1022			BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64;
1023
1024		let current_block = System::block_number()
1025			.saturated_into::<u64>()
1026			// The `System::block_number` is initialized with `n+1`,
1027			// so the actual block number is `n`.
1028			.saturating_sub(1);
1029		let tip = 0;
1030		let tx_ext: TxExtension = (
1031			frame_system::AuthorizeCall::<Runtime>::new(),
1032			frame_system::CheckNonZeroSender::<Runtime>::new(),
1033			frame_system::CheckSpecVersion::<Runtime>::new(),
1034			frame_system::CheckTxVersion::<Runtime>::new(),
1035			frame_system::CheckGenesis::<Runtime>::new(),
1036			frame_system::CheckMortality::<Runtime>::from(generic::Era::mortal(
1037				period,
1038				current_block,
1039			)),
1040			frame_system::CheckNonce::<Runtime>::from(nonce),
1041			frame_system::CheckWeight::<Runtime>::new(),
1042			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
1043			frame_metadata_hash_extension::CheckMetadataHash::<Runtime>::new(true),
1044			frame_system::WeightReclaim::<Runtime>::new(),
1045		)
1046			.into();
1047		let raw_payload = SignedPayload::new(call, tx_ext)
1048			.map_err(|e| {
1049				log::warn!("Unable to create signed payload: {:?}", e);
1050			})
1051			.ok()?;
1052		let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?;
1053		let (call, tx_ext, _) = raw_payload.deconstruct();
1054		let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
1055		let transaction = UncheckedExtrinsic::new_signed(call, address, signature, tx_ext);
1056		Some(transaction)
1057	}
1058}
1059
1060impl<LocalCall> frame_system::offchain::CreateBare<LocalCall> for Runtime
1061where
1062	RuntimeCall: From<LocalCall>,
1063{
1064	fn create_bare(call: RuntimeCall) -> UncheckedExtrinsic {
1065		UncheckedExtrinsic::new_bare(call)
1066	}
1067}
1068
1069impl<LocalCall> frame_system::offchain::CreateAuthorizedTransaction<LocalCall> for Runtime
1070where
1071	RuntimeCall: From<LocalCall>,
1072{
1073	fn create_extension() -> Self::Extension {
1074		(
1075			frame_system::AuthorizeCall::<Runtime>::new(),
1076			frame_system::CheckNonZeroSender::<Runtime>::new(),
1077			frame_system::CheckSpecVersion::<Runtime>::new(),
1078			frame_system::CheckTxVersion::<Runtime>::new(),
1079			frame_system::CheckGenesis::<Runtime>::new(),
1080			frame_system::CheckMortality::<Runtime>::from(generic::Era::Immortal),
1081			frame_system::CheckNonce::<Runtime>::from(0),
1082			frame_system::CheckWeight::<Runtime>::new(),
1083			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
1084			frame_metadata_hash_extension::CheckMetadataHash::<Runtime>::new(false),
1085			frame_system::WeightReclaim::<Runtime>::new(),
1086		)
1087	}
1088}
1089
1090parameter_types! {
1091	// Minimum 100 bytes/KSM deposited (1 CENT/byte)
1092	pub const BasicDeposit: Balance = 1000 * CENTS;       // 258 bytes on-chain
1093	pub const ByteDeposit: Balance = deposit(0, 1);
1094	pub const UsernameDeposit: Balance = deposit(0, 32);
1095	pub const SubAccountDeposit: Balance = 200 * CENTS;   // 53 bytes on-chain
1096	pub const MaxSubAccounts: u32 = 100;
1097	pub const MaxAdditionalFields: u32 = 100;
1098	pub const MaxRegistrars: u32 = 20;
1099}
1100
1101impl pallet_identity::Config for Runtime {
1102	type RuntimeEvent = RuntimeEvent;
1103	type Currency = Balances;
1104	type Slashed = ();
1105	type BasicDeposit = BasicDeposit;
1106	type ByteDeposit = ByteDeposit;
1107	type UsernameDeposit = UsernameDeposit;
1108	type SubAccountDeposit = SubAccountDeposit;
1109	type MaxSubAccounts = MaxSubAccounts;
1110	type IdentityInformation = IdentityInfo<MaxAdditionalFields>;
1111	type MaxRegistrars = MaxRegistrars;
1112	type ForceOrigin = EnsureRoot<Self::AccountId>;
1113	type RegistrarOrigin = EnsureRoot<Self::AccountId>;
1114	type OffchainSignature = Signature;
1115	type SigningPublicKey = <Signature as Verify>::Signer;
1116	type UsernameAuthorityOrigin = EnsureRoot<Self::AccountId>;
1117	type PendingUsernameExpiration = ConstU32<{ 7 * DAYS }>;
1118	type UsernameGracePeriod = ConstU32<{ 30 * DAYS }>;
1119	type MaxSuffixLength = ConstU32<7>;
1120	type MaxUsernameLength = ConstU32<32>;
1121	#[cfg(feature = "runtime-benchmarks")]
1122	type BenchmarkHelper = ();
1123	type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
1124}
1125
1126impl pallet_utility::Config for Runtime {
1127	type RuntimeEvent = RuntimeEvent;
1128	type RuntimeCall = RuntimeCall;
1129	type PalletsOrigin = OriginCaller;
1130	type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
1131}
1132
1133parameter_types! {
1134	// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
1135	pub const DepositBase: Balance = deposit(1, 88);
1136	// Additional storage item size of 32 bytes.
1137	pub const DepositFactor: Balance = deposit(0, 32);
1138	pub const MaxSignatories: u32 = 100;
1139}
1140
1141impl pallet_multisig::Config for Runtime {
1142	type RuntimeEvent = RuntimeEvent;
1143	type RuntimeCall = RuntimeCall;
1144	type Currency = Balances;
1145	type DepositBase = DepositBase;
1146	type DepositFactor = DepositFactor;
1147	type MaxSignatories = MaxSignatories;
1148	type WeightInfo = weights::pallet_multisig::WeightInfo<Runtime>;
1149	type BlockNumberProvider = frame_system::Pallet<Runtime>;
1150}
1151
1152parameter_types! {
1153	pub const MinVestedTransfer: Balance = 100 * CENTS;
1154	pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons =
1155		WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE);
1156}
1157
1158impl pallet_vesting::Config for Runtime {
1159	type RuntimeEvent = RuntimeEvent;
1160	type Currency = Balances;
1161	type BlockNumberToBalance = ConvertInto;
1162	type MinVestedTransfer = MinVestedTransfer;
1163	type WeightInfo = weights::pallet_vesting::WeightInfo<Runtime>;
1164	type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons;
1165	type BlockNumberProvider = System;
1166	const MAX_VESTING_SCHEDULES: u32 = 28;
1167}
1168
1169impl pallet_sudo::Config for Runtime {
1170	type RuntimeEvent = RuntimeEvent;
1171	type RuntimeCall = RuntimeCall;
1172	type WeightInfo = weights::pallet_sudo::WeightInfo<Runtime>;
1173}
1174
1175parameter_types! {
1176	// One storage item; key size 32, value size 8; .
1177	pub const ProxyDepositBase: Balance = deposit(1, 8);
1178	// Additional storage item size of 33 bytes.
1179	pub const ProxyDepositFactor: Balance = deposit(0, 33);
1180	pub const MaxProxies: u16 = 32;
1181	pub const AnnouncementDepositBase: Balance = deposit(1, 8);
1182	pub const AnnouncementDepositFactor: Balance = deposit(0, 66);
1183	pub const MaxPending: u16 = 32;
1184}
1185
1186/// The type used to represent the kinds of proxying allowed.
1187#[derive(
1188	Copy,
1189	Clone,
1190	Eq,
1191	PartialEq,
1192	Ord,
1193	PartialOrd,
1194	Encode,
1195	Decode,
1196	DecodeWithMemTracking,
1197	Debug,
1198	MaxEncodedLen,
1199	TypeInfo,
1200)]
1201pub enum ProxyType {
1202	Any,
1203	NonTransfer,
1204	Governance,
1205	Staking,
1206	SudoBalances,
1207	IdentityJudgement,
1208	CancelProxy,
1209	Auction,
1210	NominationPools,
1211	ParaRegistration,
1212}
1213impl Default for ProxyType {
1214	fn default() -> Self {
1215		Self::Any
1216	}
1217}
1218impl InstanceFilter<RuntimeCall> for ProxyType {
1219	fn filter(&self, c: &RuntimeCall) -> bool {
1220		match self {
1221			ProxyType::Any => true,
1222			ProxyType::NonTransfer => matches!(
1223				c,
1224				RuntimeCall::System(..) |
1225				RuntimeCall::Babe(..) |
1226				RuntimeCall::Timestamp(..) |
1227				RuntimeCall::Indices(pallet_indices::Call::claim{..}) |
1228				RuntimeCall::Indices(pallet_indices::Call::free{..}) |
1229				RuntimeCall::Indices(pallet_indices::Call::freeze{..}) |
1230				// Specifically omitting Indices `transfer`, `force_transfer`
1231				// Specifically omitting the entire Balances pallet
1232				RuntimeCall::Staking(..) |
1233				RuntimeCall::Session(..) |
1234				RuntimeCall::Grandpa(..) |
1235				RuntimeCall::Utility(..) |
1236				RuntimeCall::Identity(..) |
1237				RuntimeCall::Vesting(pallet_vesting::Call::vest{..}) |
1238				RuntimeCall::Vesting(pallet_vesting::Call::vest_other{..}) |
1239				// Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer`
1240				RuntimeCall::Scheduler(..) |
1241				// Specifically omitting Sudo pallet
1242				RuntimeCall::Proxy(..) |
1243				RuntimeCall::Multisig(..) |
1244				RuntimeCall::Registrar(paras_registrar::Call::register{..}) |
1245				RuntimeCall::Registrar(paras_registrar::Call::deregister{..}) |
1246				// Specifically omitting Registrar `swap`
1247				RuntimeCall::Registrar(paras_registrar::Call::reserve{..}) |
1248				RuntimeCall::Crowdloan(..) |
1249				RuntimeCall::Slots(..) |
1250				RuntimeCall::Auctions(..) | // Specifically omitting the entire XCM Pallet
1251				RuntimeCall::VoterList(..) |
1252				RuntimeCall::NominationPools(..) |
1253				RuntimeCall::FastUnstake(..)
1254			),
1255			ProxyType::Staking => {
1256				matches!(
1257					c,
1258					RuntimeCall::Staking(..) |
1259						RuntimeCall::Session(..) |
1260						RuntimeCall::Utility(..) |
1261						RuntimeCall::FastUnstake(..) |
1262						RuntimeCall::VoterList(..) |
1263						RuntimeCall::NominationPools(..)
1264				)
1265			},
1266			ProxyType::NominationPools => {
1267				matches!(c, RuntimeCall::NominationPools(..) | RuntimeCall::Utility(..))
1268			},
1269			ProxyType::SudoBalances => match c {
1270				RuntimeCall::Sudo(pallet_sudo::Call::sudo { call: ref x }) => {
1271					matches!(x.as_ref(), &RuntimeCall::Balances(..))
1272				},
1273				RuntimeCall::Utility(..) => true,
1274				_ => false,
1275			},
1276			// Governance has moved to AssetHub post-AHM; no calls to proxy.
1277			ProxyType::Governance => false,
1278			ProxyType::IdentityJudgement => matches!(
1279				c,
1280				RuntimeCall::Identity(pallet_identity::Call::provide_judgement { .. }) |
1281					RuntimeCall::Utility(..)
1282			),
1283			ProxyType::CancelProxy => {
1284				matches!(c, RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }))
1285			},
1286			ProxyType::Auction => matches!(
1287				c,
1288				RuntimeCall::Auctions(..) |
1289					RuntimeCall::Crowdloan(..) |
1290					RuntimeCall::Registrar(..) |
1291					RuntimeCall::Slots(..)
1292			),
1293			ProxyType::ParaRegistration => matches!(
1294				c,
1295				RuntimeCall::Registrar(paras_registrar::Call::reserve { .. }) |
1296					RuntimeCall::Registrar(paras_registrar::Call::register { .. }) |
1297					RuntimeCall::Utility(pallet_utility::Call::batch { .. }) |
1298					RuntimeCall::Utility(pallet_utility::Call::batch_all { .. }) |
1299					RuntimeCall::Utility(pallet_utility::Call::force_batch { .. }) |
1300					RuntimeCall::Proxy(pallet_proxy::Call::remove_proxy { .. })
1301			),
1302		}
1303	}
1304	fn is_superset(&self, o: &Self) -> bool {
1305		match (self, o) {
1306			(x, y) if x == y => true,
1307			(ProxyType::Any, _) => true,
1308			(_, ProxyType::Any) => false,
1309			(ProxyType::NonTransfer, _) => true,
1310			_ => false,
1311		}
1312	}
1313}
1314
1315impl pallet_proxy::Config for Runtime {
1316	type RuntimeEvent = RuntimeEvent;
1317	type RuntimeCall = RuntimeCall;
1318	type Currency = Balances;
1319	type ProxyType = ProxyType;
1320	type ProxyDepositBase = ProxyDepositBase;
1321	type ProxyDepositFactor = ProxyDepositFactor;
1322	type MaxProxies = MaxProxies;
1323	type WeightInfo = weights::pallet_proxy::WeightInfo<Runtime>;
1324	type MaxPending = MaxPending;
1325	type CallHasher = BlakeTwo256;
1326	type AnnouncementDepositBase = AnnouncementDepositBase;
1327	type AnnouncementDepositFactor = AnnouncementDepositFactor;
1328	type BlockNumberProvider = frame_system::Pallet<Runtime>;
1329}
1330
1331impl parachains_origin::Config for Runtime {}
1332
1333impl parachains_configuration::Config for Runtime {
1334	type WeightInfo = weights::polkadot_runtime_parachains_configuration::WeightInfo<Runtime>;
1335}
1336
1337impl parachains_shared::Config for Runtime {
1338	type DisabledValidators = Session;
1339}
1340
1341impl parachains_session_info::Config for Runtime {
1342	type ValidatorSet = Historical;
1343}
1344
1345impl parachains_inclusion::Config for Runtime {
1346	type RuntimeEvent = RuntimeEvent;
1347	type DisputesHandler = ParasDisputes;
1348	type RewardValidators =
1349		parachains_reward_points::RewardValidatorsWithEraPoints<Runtime, StakingAhClient>;
1350	type MessageQueue = MessageQueue;
1351	type WeightInfo = weights::polkadot_runtime_parachains_inclusion::WeightInfo<Runtime>;
1352}
1353
1354parameter_types! {
1355	pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
1356}
1357
1358impl parachains_paras::Config for Runtime {
1359	type RuntimeEvent = RuntimeEvent;
1360	type WeightInfo = weights::polkadot_runtime_parachains_paras::WeightInfo<Runtime>;
1361	type UnsignedPriority = ParasUnsignedPriority;
1362	type QueueFootprinter = ParaInclusion;
1363	type NextSessionRotation = Babe;
1364	type OnNewHead = ();
1365	type AssignCoretime = ParaScheduler;
1366	type Fungible = Balances;
1367	// Per day the cooldown is removed earlier, it should cost 1000.
1368	type CooldownRemovalMultiplier = ConstUint<{ 1000 * UNITS / DAYS as u128 }>;
1369	type AuthorizeCurrentCodeOrigin = EnsureRoot<AccountId>;
1370}
1371
1372parameter_types! {
1373	/// Amount of weight that can be spent per block to service messages.
1374	///
1375	/// # WARNING
1376	///
1377	/// This is not a good value for para-chains since the `Scheduler` already uses up to 80% block weight.
1378	pub MessageQueueServiceWeight: Weight = Perbill::from_percent(20) * BlockWeights::get().max_block;
1379	pub const MessageQueueHeapSize: u32 = 128 * 1024;
1380	pub const MessageQueueMaxStale: u32 = 48;
1381}
1382
1383/// Message processor to handle any messages that were enqueued into the `MessageQueue` pallet.
1384pub struct MessageProcessor;
1385impl ProcessMessage for MessageProcessor {
1386	type Origin = AggregateMessageOrigin;
1387
1388	fn process_message(
1389		message: &[u8],
1390		origin: Self::Origin,
1391		meter: &mut WeightMeter,
1392		id: &mut [u8; 32],
1393	) -> Result<bool, ProcessMessageError> {
1394		let para = match origin {
1395			AggregateMessageOrigin::Ump(UmpQueueId::Para(para)) => para,
1396		};
1397		xcm_builder::ProcessXcmMessage::<
1398			Junction,
1399			xcm_executor::XcmExecutor<xcm_config::XcmConfig>,
1400			RuntimeCall,
1401		>::process_message(message, Junction::Parachain(para.into()), meter, id)
1402	}
1403}
1404
1405impl pallet_message_queue::Config for Runtime {
1406	type RuntimeEvent = RuntimeEvent;
1407	type Size = u32;
1408	type HeapSize = MessageQueueHeapSize;
1409	type MaxStale = MessageQueueMaxStale;
1410	type ServiceWeight = MessageQueueServiceWeight;
1411	type IdleMaxServiceWeight = MessageQueueServiceWeight;
1412	#[cfg(not(feature = "runtime-benchmarks"))]
1413	type MessageProcessor = MessageProcessor;
1414	#[cfg(feature = "runtime-benchmarks")]
1415	type MessageProcessor =
1416		pallet_message_queue::mock_helpers::NoopMessageProcessor<AggregateMessageOrigin>;
1417	type QueueChangeHandler = ParaInclusion;
1418	type QueuePausedQuery = ();
1419	type WeightInfo = weights::pallet_message_queue::WeightInfo<Runtime>;
1420}
1421
1422impl parachains_dmp::Config for Runtime {}
1423
1424parameter_types! {
1425	pub const HrmpChannelSizeAndCapacityWithSystemRatio: Percent = Percent::from_percent(100);
1426}
1427
1428impl parachains_hrmp::Config for Runtime {
1429	type RuntimeOrigin = RuntimeOrigin;
1430	type RuntimeEvent = RuntimeEvent;
1431	type ChannelManager = EnsureRoot<AccountId>;
1432	type Currency = Balances;
1433	type DefaultChannelSizeAndCapacityWithSystem = ActiveConfigHrmpChannelSizeAndCapacityRatio<
1434		Runtime,
1435		HrmpChannelSizeAndCapacityWithSystemRatio,
1436	>;
1437	type VersionWrapper = crate::XcmPallet;
1438	type WeightInfo = weights::polkadot_runtime_parachains_hrmp::WeightInfo<Self>;
1439}
1440
1441impl parachains_paras_inherent::Config for Runtime {
1442	type WeightInfo = weights::polkadot_runtime_parachains_paras_inherent::WeightInfo<Runtime>;
1443}
1444
1445impl parachains_scheduler::Config for Runtime {}
1446
1447parameter_types! {
1448	pub const BrokerId: u32 = BROKER_ID;
1449	pub const BrokerPalletId: PalletId = PalletId(*b"py/broke");
1450	pub MaxXcmTransactWeight: Weight = Weight::from_parts(200_000_000, 20_000);
1451}
1452
1453pub struct BrokerPot;
1454impl Get<InteriorLocation> for BrokerPot {
1455	fn get() -> InteriorLocation {
1456		Junction::AccountId32 { network: None, id: BrokerPalletId::get().into_account_truncating() }
1457			.into()
1458	}
1459}
1460
1461impl coretime::Config for Runtime {
1462	type RuntimeOrigin = RuntimeOrigin;
1463	type RuntimeEvent = RuntimeEvent;
1464	type BrokerId = BrokerId;
1465	type BrokerPotLocation = BrokerPot;
1466	type WeightInfo = weights::polkadot_runtime_parachains_coretime::WeightInfo<Runtime>;
1467	type SendXcm = crate::xcm_config::XcmRouter;
1468	type AssetTransactor = crate::xcm_config::LocalAssetTransactor;
1469	type AccountToLocation = xcm_builder::AliasesIntoAccountId32<
1470		xcm_config::ThisNetwork,
1471		<Runtime as frame_system::Config>::AccountId,
1472	>;
1473	type MaxXcmTransactWeight = MaxXcmTransactWeight;
1474}
1475
1476parameter_types! {
1477	pub const OnDemandTrafficDefaultValue: FixedU128 = FixedU128::from_u32(1);
1478	// Keep 2 timeslices worth of revenue information.
1479	pub const MaxHistoricalRevenue: BlockNumber = 2 * TIMESLICE_PERIOD;
1480	pub const OnDemandPalletId: PalletId = PalletId(*b"py/ondmd");
1481}
1482
1483impl parachains_on_demand::Config for Runtime {
1484	type RuntimeEvent = RuntimeEvent;
1485	type Currency = Balances;
1486	type TrafficDefaultValue = OnDemandTrafficDefaultValue;
1487	type WeightInfo = weights::polkadot_runtime_parachains_on_demand::WeightInfo<Runtime>;
1488	type MaxHistoricalRevenue = MaxHistoricalRevenue;
1489	type PalletId = OnDemandPalletId;
1490}
1491
1492impl parachains_initializer::Config for Runtime {
1493	type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
1494	type ForceOrigin = EnsureRoot<AccountId>;
1495	type WeightInfo = weights::polkadot_runtime_parachains_initializer::WeightInfo<Runtime>;
1496	type CoretimeOnNewSession = Coretime;
1497}
1498
1499impl paras_sudo_wrapper::Config for Runtime {}
1500
1501parameter_types! {
1502	pub const PermanentSlotLeasePeriodLength: u32 = 26;
1503	pub const TemporarySlotLeasePeriodLength: u32 = 1;
1504	pub const MaxTemporarySlotPerLeasePeriod: u32 = 5;
1505}
1506
1507impl assigned_slots::Config for Runtime {
1508	type RuntimeEvent = RuntimeEvent;
1509	type AssignSlotOrigin = EnsureRoot<AccountId>;
1510	type Leaser = Slots;
1511	type PermanentSlotLeasePeriodLength = PermanentSlotLeasePeriodLength;
1512	type TemporarySlotLeasePeriodLength = TemporarySlotLeasePeriodLength;
1513	type MaxTemporarySlotPerLeasePeriod = MaxTemporarySlotPerLeasePeriod;
1514	type WeightInfo = weights::polkadot_runtime_common_assigned_slots::WeightInfo<Runtime>;
1515}
1516
1517impl parachains_disputes::Config for Runtime {
1518	type RuntimeEvent = RuntimeEvent;
1519	type RewardValidators =
1520		parachains_reward_points::RewardValidatorsWithEraPoints<Runtime, StakingAhClient>;
1521	type SlashingHandler = parachains_slashing::SlashValidatorsForDisputes<ParasSlashing>;
1522	type WeightInfo = weights::polkadot_runtime_parachains_disputes::WeightInfo<Runtime>;
1523}
1524
1525impl parachains_slashing::Config for Runtime {
1526	type KeyOwnerProofSystem = Historical;
1527	type KeyOwnerProof =
1528		<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, ValidatorId)>>::Proof;
1529	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
1530		KeyTypeId,
1531		ValidatorId,
1532	)>>::IdentificationTuple;
1533	type HandleReports = parachains_slashing::SlashingReportHandler<
1534		Self::KeyOwnerIdentification,
1535		Offences,
1536		ReportLongevity,
1537	>;
1538	type WeightInfo = weights::polkadot_runtime_parachains_disputes_slashing::WeightInfo<Runtime>;
1539	type BenchmarkingConfig = parachains_slashing::BenchConfig<300>;
1540}
1541
1542parameter_types! {
1543	pub const ParaDeposit: Balance = 2000 * CENTS;
1544	pub const RegistrarDataDepositPerByte: Balance = deposit(0, 1);
1545}
1546
1547impl paras_registrar::Config for Runtime {
1548	type RuntimeOrigin = RuntimeOrigin;
1549	type RuntimeEvent = RuntimeEvent;
1550	type Currency = Balances;
1551	type OnSwap = (Crowdloan, Slots, SwapLeases);
1552	type ParaDeposit = ParaDeposit;
1553	type DataDepositPerByte = RegistrarDataDepositPerByte;
1554	type WeightInfo = weights::polkadot_runtime_common_paras_registrar::WeightInfo<Runtime>;
1555}
1556
1557parameter_types! {
1558	pub const LeasePeriod: BlockNumber = 28 * DAYS;
1559}
1560
1561impl slots::Config for Runtime {
1562	type RuntimeEvent = RuntimeEvent;
1563	type Currency = Balances;
1564	type Registrar = Registrar;
1565	type LeasePeriod = LeasePeriod;
1566	type LeaseOffset = ();
1567	type ForceOrigin = EnsureRoot<Self::AccountId>;
1568	type WeightInfo = weights::polkadot_runtime_common_slots::WeightInfo<Runtime>;
1569}
1570
1571parameter_types! {
1572	pub const CrowdloanId: PalletId = PalletId(*b"py/cfund");
1573	pub const SubmissionDeposit: Balance = 100 * 100 * CENTS;
1574	pub const MinContribution: Balance = 100 * CENTS;
1575	pub const RemoveKeysLimit: u32 = 500;
1576	// Allow 32 bytes for an additional memo to a crowdloan.
1577	pub const MaxMemoLength: u8 = 32;
1578}
1579
1580impl crowdloan::Config for Runtime {
1581	type RuntimeEvent = RuntimeEvent;
1582	type PalletId = CrowdloanId;
1583	type SubmissionDeposit = SubmissionDeposit;
1584	type MinContribution = MinContribution;
1585	type RemoveKeysLimit = RemoveKeysLimit;
1586	type Registrar = Registrar;
1587	type Auctioneer = Auctions;
1588	type MaxMemoLength = MaxMemoLength;
1589	type WeightInfo = weights::polkadot_runtime_common_crowdloan::WeightInfo<Runtime>;
1590}
1591
1592parameter_types! {
1593	// The average auction is 7 days long, so this will be 70% for ending period.
1594	// 5 Days = 72000 Blocks @ 6 sec per block
1595	pub const EndingPeriod: BlockNumber = 5 * DAYS;
1596	// ~ 1000 samples per day -> ~ 20 blocks per sample -> 2 minute samples
1597	pub const SampleLength: BlockNumber = 2 * MINUTES;
1598}
1599
1600impl auctions::Config for Runtime {
1601	type RuntimeEvent = RuntimeEvent;
1602	type Leaser = Slots;
1603	type Registrar = Registrar;
1604	type EndingPeriod = EndingPeriod;
1605	type SampleLength = SampleLength;
1606	type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
1607	type InitiateOrigin = EnsureRoot<Self::AccountId>;
1608	type WeightInfo = weights::polkadot_runtime_common_auctions::WeightInfo<Runtime>;
1609}
1610
1611impl identity_migrator::Config for Runtime {
1612	type RuntimeEvent = RuntimeEvent;
1613	type Reaper = EnsureSigned<AccountId>;
1614	type ReapIdentityHandler = ToParachainIdentityReaper<Runtime, Self::AccountId>;
1615	type WeightInfo = weights::polkadot_runtime_common_identity_migrator::WeightInfo<Runtime>;
1616}
1617
1618parameter_types! {
1619	pub const PoolsPalletId: PalletId = PalletId(*b"py/nopls");
1620	pub const MaxPointsToBalance: u8 = 10;
1621}
1622
1623impl pallet_nomination_pools::Config for Runtime {
1624	type RuntimeEvent = RuntimeEvent;
1625	type WeightInfo = weights::pallet_nomination_pools::WeightInfo<Self>;
1626	type Currency = Balances;
1627	type RuntimeFreezeReason = RuntimeFreezeReason;
1628	type RewardCounter = FixedU128;
1629	type BalanceToU256 = BalanceToU256;
1630	type U256ToBalance = U256ToBalance;
1631	type StakeAdapter =
1632		pallet_nomination_pools::adapter::DelegateStake<Self, Staking, DelegatedStaking>;
1633	type PostUnbondingPoolsWindow = ConstU32<4>;
1634	type MaxMetadataLen = ConstU32<256>;
1635	// we use the same number of allowed unlocking chunks as with staking.
1636	type MaxUnbonding = <Self as pallet_staking::Config>::MaxUnlockingChunks;
1637	type PalletId = PoolsPalletId;
1638	type MaxPointsToBalance = MaxPointsToBalance;
1639	// TODO: drop once pallet is removed from Westend RC (post-AHM cleanup).
1640	#[cfg(not(feature = "runtime-benchmarks"))]
1641	type AdminOrigin = EnsureNever<AccountId>;
1642	#[cfg(feature = "runtime-benchmarks")]
1643	type AdminOrigin = EnsureRoot<AccountId>;
1644	type BlockNumberProvider = System;
1645	type Filter = Nothing;
1646}
1647
1648parameter_types! {
1649	pub const DelegatedStakingPalletId: PalletId = PalletId(*b"py/dlstk");
1650	pub const SlashRewardFraction: Perbill = Perbill::from_percent(1);
1651}
1652
1653impl pallet_delegated_staking::Config for Runtime {
1654	type RuntimeEvent = RuntimeEvent;
1655	type PalletId = DelegatedStakingPalletId;
1656	type Currency = Balances;
1657	type OnSlash = ();
1658	type SlashRewardFraction = SlashRewardFraction;
1659	type RuntimeHoldReason = RuntimeHoldReason;
1660	type CoreStaking = Staking;
1661}
1662
1663impl pallet_root_testing::Config for Runtime {
1664	type RuntimeEvent = RuntimeEvent;
1665}
1666
1667impl pallet_root_offences::Config for Runtime {
1668	type RuntimeEvent = RuntimeEvent;
1669	type OffenceHandler = StakingAhClient;
1670	type ReportOffence = Offences;
1671}
1672
1673impl pallet_accumulate_and_forward::Config for Runtime {
1674	type Currency = Balances;
1675	type PalletId = AccumulateForwardPalletId;
1676	type Forwarder = xcm_builder::TeleportForwarderForAccountId32<
1677		xcm_config::XcmConfig,
1678		xcm_config::AssetHub,
1679		xcm_config::TokenLocation,
1680		DapStagingLocation,
1681	>;
1682	type TransferPeriod = ForwardPeriod;
1683	type MinTransferAmount = MinForwardAmount;
1684	type BlockNumberProvider = frame_system::Pallet<Runtime>;
1685	type WeightInfo = weights::pallet_accumulate_and_forward::WeightInfo<Runtime>;
1686}
1687
1688parameter_types! {
1689	pub MbmServiceWeight: Weight = Perbill::from_percent(80) * BlockWeights::get().max_block;
1690}
1691
1692impl pallet_migrations::Config for Runtime {
1693	type RuntimeEvent = RuntimeEvent;
1694	#[cfg(not(feature = "runtime-benchmarks"))]
1695	type Migrations = pallet_identity::migration::v2::LazyMigrationV1ToV2<Runtime>;
1696	// Benchmarks need mocked migrations to guarantee that they succeed.
1697	#[cfg(feature = "runtime-benchmarks")]
1698	type Migrations = pallet_migrations::mock_helpers::MockedMigrations;
1699	type CursorMaxLen = ConstU32<65_536>;
1700	type IdentifierMaxLen = ConstU32<256>;
1701	type MigrationStatusHandler = ();
1702	type FailedMigrationHandler = frame_support::migrations::FreezeChainOnFailedMigration;
1703	type MaxServiceWeight = MbmServiceWeight;
1704	type WeightInfo = weights::pallet_migrations::WeightInfo<Runtime>;
1705}
1706
1707parameter_types! {
1708	// The deposit configuration for the singed migration. Specially if you want to allow any signed account to do the migration (see `SignedFilter`, these deposits should be high)
1709	pub const MigrationSignedDepositPerItem: Balance = 1 * CENTS;
1710	pub const MigrationSignedDepositBase: Balance = 20 * CENTS * 100;
1711	pub const MigrationMaxKeyLen: u32 = 512;
1712}
1713
1714impl pallet_asset_rate::Config for Runtime {
1715	type WeightInfo = weights::pallet_asset_rate::WeightInfo<Runtime>;
1716	type RuntimeEvent = RuntimeEvent;
1717	type CreateOrigin = EnsureRoot<AccountId>;
1718	type RemoveOrigin = EnsureRoot<AccountId>;
1719	type UpdateOrigin = EnsureRoot<AccountId>;
1720	type Currency = Balances;
1721	type AssetKind = VersionedLocatableAsset;
1722	#[cfg(feature = "runtime-benchmarks")]
1723	type BenchmarkHelper = polkadot_runtime_common::impls::benchmarks::AssetRateArguments;
1724}
1725
1726// Notify `coretime` pallet when a lease swap occurs
1727pub struct SwapLeases;
1728impl OnSwap for SwapLeases {
1729	fn on_swap(one: ParaId, other: ParaId) {
1730		coretime::Pallet::<Runtime>::on_legacy_lease_swap(one, other);
1731	}
1732}
1733
1734#[frame_support::runtime(legacy_ordering)]
1735mod runtime {
1736	#[runtime::runtime]
1737	#[runtime::derive(
1738		RuntimeCall,
1739		RuntimeEvent,
1740		RuntimeError,
1741		RuntimeOrigin,
1742		RuntimeFreezeReason,
1743		RuntimeHoldReason,
1744		RuntimeSlashReason,
1745		RuntimeLockId,
1746		RuntimeTask,
1747		RuntimeViewFunction
1748	)]
1749	pub struct Runtime;
1750
1751	// Basic stuff; balances is uncallable initially.
1752	#[runtime::pallet_index(0)]
1753	pub type System = frame_system;
1754
1755	// Babe must be before session.
1756	#[runtime::pallet_index(1)]
1757	pub type Babe = pallet_babe;
1758
1759	#[runtime::pallet_index(2)]
1760	pub type Timestamp = pallet_timestamp;
1761	#[runtime::pallet_index(3)]
1762	pub type Indices = pallet_indices;
1763	#[runtime::pallet_index(4)]
1764	pub type Balances = pallet_balances;
1765	#[runtime::pallet_index(26)]
1766	pub type TransactionPayment = pallet_transaction_payment;
1767	// AccumulateForward - collects funds for periodic forwarding to DAP on AssetHub
1768	#[runtime::pallet_index(106)]
1769	pub type AccumulateForward = pallet_accumulate_and_forward;
1770
1771	// Consensus support.
1772	// Authorship must be before session in order to note author in the correct session and era.
1773	#[runtime::pallet_index(5)]
1774	pub type Authorship = pallet_authorship;
1775	#[runtime::pallet_index(6)]
1776	pub type Staking = pallet_staking;
1777	#[runtime::pallet_index(7)]
1778	pub type Offences = pallet_offences;
1779	#[runtime::pallet_index(27)]
1780	pub type Historical = session_historical;
1781	#[runtime::pallet_index(70)]
1782	pub type Parameters = pallet_parameters;
1783
1784	#[runtime::pallet_index(8)]
1785	pub type Session = pallet_session;
1786	#[runtime::pallet_index(10)]
1787	pub type Grandpa = pallet_grandpa;
1788	#[runtime::pallet_index(12)]
1789	pub type AuthorityDiscovery = pallet_authority_discovery;
1790
1791	// Utility module.
1792	#[runtime::pallet_index(16)]
1793	pub type Utility = pallet_utility;
1794
1795	// Less simple identity module.
1796	#[runtime::pallet_index(17)]
1797	pub type Identity = pallet_identity;
1798
1799	// Vesting. Usable initially, but removed once all vesting is finished.
1800	#[runtime::pallet_index(19)]
1801	pub type Vesting = pallet_vesting;
1802
1803	// System scheduler.
1804	#[runtime::pallet_index(20)]
1805	pub type Scheduler = pallet_scheduler;
1806
1807	// Preimage registrar.
1808	#[runtime::pallet_index(28)]
1809	pub type Preimage = pallet_preimage;
1810
1811	// Sudo.
1812	#[runtime::pallet_index(21)]
1813	pub type Sudo = pallet_sudo;
1814
1815	// Proxy module. Late addition.
1816	#[runtime::pallet_index(22)]
1817	pub type Proxy = pallet_proxy;
1818
1819	// Multisig module. Late addition.
1820	#[runtime::pallet_index(23)]
1821	pub type Multisig = pallet_multisig;
1822
1823	// Election pallet. Only works with staking, but placed here to maintain indices.
1824	#[runtime::pallet_index(24)]
1825	pub type ElectionProviderMultiPhase = pallet_election_provider_multi_phase;
1826
1827	// Provides a semi-sorted list of nominators for staking.
1828	#[runtime::pallet_index(25)]
1829	pub type VoterList = pallet_bags_list<Instance1>;
1830
1831	// Nomination pools for staking.
1832	#[runtime::pallet_index(29)]
1833	pub type NominationPools = pallet_nomination_pools;
1834
1835	// Fast unstake pallet = extension to staking.
1836	#[runtime::pallet_index(30)]
1837	pub type FastUnstake = pallet_fast_unstake;
1838
1839	// Indices 31, 32, 35, 36 permanently unused (OpenGov removed post-AHM).
1840
1841	// Staking extension for delegation
1842	#[runtime::pallet_index(38)]
1843	pub type DelegatedStaking = pallet_delegated_staking;
1844
1845	// Parachains pallets. Start indices at 40 to leave room.
1846	#[runtime::pallet_index(41)]
1847	pub type ParachainsOrigin = parachains_origin;
1848	#[runtime::pallet_index(42)]
1849	pub type Configuration = parachains_configuration;
1850	#[runtime::pallet_index(43)]
1851	pub type ParasShared = parachains_shared;
1852	#[runtime::pallet_index(44)]
1853	pub type ParaInclusion = parachains_inclusion;
1854	#[runtime::pallet_index(45)]
1855	pub type ParaInherent = parachains_paras_inherent;
1856	#[runtime::pallet_index(46)]
1857	pub type ParaScheduler = parachains_scheduler;
1858	#[runtime::pallet_index(47)]
1859	pub type Paras = parachains_paras;
1860	#[runtime::pallet_index(48)]
1861	pub type Initializer = parachains_initializer;
1862	#[runtime::pallet_index(49)]
1863	pub type Dmp = parachains_dmp;
1864	// RIP Ump 50
1865	#[runtime::pallet_index(51)]
1866	pub type Hrmp = parachains_hrmp;
1867	#[runtime::pallet_index(52)]
1868	pub type ParaSessionInfo = parachains_session_info;
1869	#[runtime::pallet_index(53)]
1870	pub type ParasDisputes = parachains_disputes;
1871	#[runtime::pallet_index(54)]
1872	pub type ParasSlashing = parachains_slashing;
1873	#[runtime::pallet_index(56)]
1874	pub type OnDemandAssignmentProvider = parachains_on_demand;
1875	// RIP CoretimeAssignmentProvider 57 - Moved to scheduler::assigner_coretime submodule in PR
1876	// #10184 (Had no extrinsics nor events exposed)
1877
1878	// Parachain Onboarding Pallets. Start indices at 60 to leave room.
1879	#[runtime::pallet_index(60)]
1880	pub type Registrar = paras_registrar;
1881	#[runtime::pallet_index(61)]
1882	pub type Slots = slots;
1883	#[runtime::pallet_index(62)]
1884	pub type ParasSudoWrapper = paras_sudo_wrapper;
1885	#[runtime::pallet_index(63)]
1886	pub type Auctions = auctions;
1887	#[runtime::pallet_index(64)]
1888	pub type Crowdloan = crowdloan;
1889	#[runtime::pallet_index(65)]
1890	pub type AssignedSlots = assigned_slots;
1891	#[runtime::pallet_index(66)]
1892	pub type Coretime = coretime;
1893	#[runtime::pallet_index(67)]
1894	pub type StakingAhClient = pallet_staking_async_ah_client;
1895
1896	// Migrations pallet
1897	#[runtime::pallet_index(98)]
1898	pub type MultiBlockMigrations = pallet_migrations;
1899
1900	// Pallet for sending XCM.
1901	#[runtime::pallet_index(99)]
1902	pub type XcmPallet = pallet_xcm;
1903
1904	// Generalized message queue
1905	#[runtime::pallet_index(100)]
1906	pub type MessageQueue = pallet_message_queue;
1907
1908	// Asset rate.
1909	#[runtime::pallet_index(101)]
1910	pub type AssetRate = pallet_asset_rate;
1911
1912	// Root testing pallet.
1913	#[runtime::pallet_index(102)]
1914	pub type RootTesting = pallet_root_testing;
1915
1916	// Root offences pallet
1917	#[runtime::pallet_index(105)]
1918	pub type RootOffences = pallet_root_offences;
1919
1920	// BEEFY Bridges support.
1921	#[runtime::pallet_index(200)]
1922	pub type Beefy = pallet_beefy;
1923	// MMR leaf construction must be after session in order to have a leaf's next_auth_set
1924	// refer to block<N>. See issue polkadot-fellows/runtimes#160 for details.
1925	#[runtime::pallet_index(201)]
1926	pub type Mmr = pallet_mmr;
1927	#[runtime::pallet_index(202)]
1928	pub type BeefyMmrLeaf = pallet_beefy_mmr;
1929
1930	// Pallet for migrating Identity to a parachain. To be removed post-migration.
1931	#[runtime::pallet_index(248)]
1932	pub type IdentityMigrator = identity_migrator;
1933}
1934
1935/// The address format for describing accounts.
1936pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
1937/// Block header type as expected by this runtime.
1938pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
1939/// Block type as expected by this runtime.
1940pub type Block = generic::Block<Header, UncheckedExtrinsic>;
1941/// A Block signed with a Justification
1942pub type SignedBlock = generic::SignedBlock<Block>;
1943/// `BlockId` type as expected by this runtime.
1944pub type BlockId = generic::BlockId<Block>;
1945/// The extension to the basic transaction logic.
1946pub type TxExtension = (
1947	frame_system::AuthorizeCall<Runtime>,
1948	frame_system::CheckNonZeroSender<Runtime>,
1949	frame_system::CheckSpecVersion<Runtime>,
1950	frame_system::CheckTxVersion<Runtime>,
1951	frame_system::CheckGenesis<Runtime>,
1952	frame_system::CheckMortality<Runtime>,
1953	frame_system::CheckNonce<Runtime>,
1954	frame_system::CheckWeight<Runtime>,
1955	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
1956	frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
1957	frame_system::WeightReclaim<Runtime>,
1958);
1959
1960parameter_types! {
1961	/// Bounding number of agent pot accounts to be migrated in a single block.
1962	pub const MaxAgentsToMigrate: u32 = 300;
1963	pub const RecoveryPalletName: &'static str = "Recovery";
1964}
1965
1966/// All migrations that will run on the next runtime upgrade.
1967///
1968/// This contains the combined migrations of the last 10 releases. It allows to skip runtime
1969/// upgrades in case governance decides to do so. THE ORDER IS IMPORTANT.
1970pub type Migrations = migrations::Unreleased;
1971
1972/// The runtime migrations per release.
1973#[allow(deprecated, missing_docs)]
1974pub mod migrations {
1975	use super::*;
1976	use frame_support::{
1977		traits::{
1978			fungible::{Balanced, Inspect},
1979			tokens::{Fortitude, Precision, Preservation},
1980			OnRuntimeUpgrade, OnUnbalanced,
1981		},
1982		weights::Weight,
1983	};
1984	use polkadot_primitives::AccountId;
1985	use sp_runtime::traits::Zero;
1986	#[cfg(feature = "try-runtime")]
1987	use {
1988		alloc::vec::Vec,
1989		codec::{Decode, Encode},
1990		polkadot_primitives::Balance,
1991	};
1992
1993	parameter_types! {
1994		pub const TreasuryPalletStr: &'static str = "Treasury";
1995		pub const ConvictionVotingPalletStr: &'static str = "ConvictionVoting";
1996		pub const ReferendaPalletStr: &'static str = "Referenda";
1997		pub const OriginsPalletStr: &'static str = "Origins";
1998		pub const WhitelistPalletStr: &'static str = "Whitelist";
1999	}
2000
2001	/// Legacy treasury `PalletId` (`py/trsry`).
2002	const LEGACY_TREASURY_PALLET_ID: PalletId = PalletId(*b"py/trsry");
2003	const DRAIN_LOG_TARGET: &str = "runtime::westend::drain-legacy-treasury";
2004
2005	/// One-shot migration that drains the reducible balance of the legacy
2006	/// `py/trsry`-derived account into the [`pallet_accumulate_and_forward`] accumulation
2007	/// account. The runtime's `Forwarder` then teleports the funds to AssetHub's central DAP
2008	/// on the next forwarding interval.
2009	///
2010	/// Runtime-local (not part of the generic ACF pallet).
2011	/// Idempotent: a zero reducible balance is a no-op.
2012	pub struct DrainLegacyTreasuryToAccumulationAccount;
2013
2014	impl OnRuntimeUpgrade for DrainLegacyTreasuryToAccumulationAccount {
2015		fn on_runtime_upgrade() -> Weight {
2016			let source: AccountId = LEGACY_TREASURY_PALLET_ID.into_account_truncating();
2017			// No further inflows expected, but `Preserve` is used as a safeguard since this
2018			// migration runs on every runtime upgrade until removed. Worst case: ED stays
2019			// behind on a dead account.
2020			let amount = <Balances as Inspect<AccountId>>::reducible_balance(
2021				&source,
2022				Preservation::Preserve,
2023				Fortitude::Polite,
2024			);
2025			if amount.is_zero() {
2026				log::info!(
2027					target: DRAIN_LOG_TARGET,
2028					"nothing to withdraw (reducible balance is zero)."
2029				);
2030				return <Runtime as frame_system::Config>::DbWeight::get().reads(1);
2031			}
2032
2033			match <Balances as Balanced<AccountId>>::withdraw(
2034				&source,
2035				amount,
2036				Precision::Exact,
2037				Preservation::Preserve,
2038				Fortitude::Polite,
2039			) {
2040				Ok(credit) => {
2041					<AccumulateForward as OnUnbalanced<_>>::on_unbalanced(credit);
2042					log::info!(
2043						target: DRAIN_LOG_TARGET,
2044						"swept {amount:?} to accumulation account."
2045					);
2046				},
2047				Err(_) => {
2048					frame_support::defensive!(
2049						"DrainLegacyTreasuryToAccumulationAccount: failed to withdraw from legacy treasury account"
2050					);
2051				},
2052			}
2053
2054			// Distinct storage keys touched: source Account (balances + system),
2055			// accumulation Account (balances + system) = 4 reads and 4 writes.
2056			<Runtime as frame_system::Config>::DbWeight::get().reads_writes(4, 4)
2057		}
2058
2059		#[cfg(feature = "try-runtime")]
2060		fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
2061			let source: AccountId = LEGACY_TREASURY_PALLET_ID.into_account_truncating();
2062			let legacy_pre = <Balances as Inspect<AccountId>>::reducible_balance(
2063				&source,
2064				Preservation::Preserve,
2065				Fortitude::Polite,
2066			);
2067			let accum_pre = <Balances as Inspect<AccountId>>::reducible_balance(
2068				&pallet_accumulate_and_forward::Pallet::<Runtime>::accumulation_account(),
2069				Preservation::Preserve,
2070				Fortitude::Polite,
2071			);
2072			log::info!(
2073				target: DRAIN_LOG_TARGET,
2074				"pre-upgrade legacy reducible = {legacy_pre:?}, accumulation reducible = {accum_pre:?}"
2075			);
2076			Ok((legacy_pre, accum_pre).encode())
2077		}
2078
2079		#[cfg(feature = "try-runtime")]
2080		fn post_upgrade(state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
2081			let (legacy_pre, accum_pre): (Balance, Balance) = Decode::decode(&mut &state[..])
2082				.expect("pre_upgrade encoded (legacy_pre, accum_pre)");
2083
2084			let source: AccountId = LEGACY_TREASURY_PALLET_ID.into_account_truncating();
2085			let legacy_post = <Balances as Inspect<AccountId>>::reducible_balance(
2086				&source,
2087				Preservation::Preserve,
2088				Fortitude::Polite,
2089			);
2090			frame_support::ensure!(
2091				legacy_post.is_zero(),
2092				"Legacy treasury reducible balance should be zero after migration"
2093			);
2094
2095			let accum_post = <Balances as Inspect<AccountId>>::reducible_balance(
2096				&pallet_accumulate_and_forward::Pallet::<Runtime>::accumulation_account(),
2097				Preservation::Preserve,
2098				Fortitude::Polite,
2099			);
2100			frame_support::ensure!(
2101				Some(accum_post) == accum_pre.checked_add(legacy_pre),
2102				"Accumulation account balance should have increased by exactly the drained amount"
2103			);
2104
2105			log::info!(
2106				target: DRAIN_LOG_TARGET,
2107				"post-upgrade OK. Legacy reducible: {legacy_post:?}, accumulation reducible: {accum_post:?}"
2108			);
2109			Ok(())
2110		}
2111	}
2112
2113	/// Unreleased migrations. Add new ones here:
2114	pub type Unreleased = (
2115		// This is only needed for Westend.
2116		pallet_delegated_staking::migration::unversioned::ProxyDelegatorMigration<
2117			Runtime,
2118			MaxAgentsToMigrate,
2119		>,
2120		pallet_staking::migrations::v16::MigrateV15ToV16<Runtime>,
2121		pallet_session::migrations::v1::MigrateV0ToV1<
2122			Runtime,
2123			pallet_staking::migrations::v17::MigrateDisabledToSession<Runtime>,
2124		>,
2125		// Migrate scheduler v3 -> v4 and on-demand v1 -> v2
2126		parachains_on_demand::migration::MigrateV1ToV2<Runtime>,
2127		parachains_scheduler::migration::MigrateV3ToV4<Runtime>,
2128		parachains_configuration::migration::v13::MigrateToV13<Runtime>,
2129		parachains_shared::migration::MigrateToV2<Runtime>,
2130		// #11705: drain residual legacy `py/trsry` balance into the ACF accumulation
2131		// account.
2132		// Idempotent. No further activity on the legacy `py/trsry`
2133		// account is expected. Safe to remove after the next runtime upgrade once confirmed.
2134		DrainLegacyTreasuryToAccumulationAccount,
2135		frame_support::migrations::RemovePallet<
2136			TreasuryPalletStr,
2137			<Runtime as frame_system::Config>::DbWeight,
2138		>,
2139		// OpenGov removal: clear orphaned storage for governance pallets.
2140		frame_support::migrations::RemovePallet<
2141			ConvictionVotingPalletStr,
2142			<Runtime as frame_system::Config>::DbWeight,
2143		>,
2144		frame_support::migrations::RemovePallet<
2145			ReferendaPalletStr,
2146			<Runtime as frame_system::Config>::DbWeight,
2147		>,
2148		frame_support::migrations::RemovePallet<
2149			OriginsPalletStr,
2150			<Runtime as frame_system::Config>::DbWeight,
2151		>,
2152		frame_support::migrations::RemovePallet<
2153			WhitelistPalletStr,
2154			<Runtime as frame_system::Config>::DbWeight,
2155		>,
2156		// Remove the Recovery pallet.
2157		frame_support::migrations::RemovePallet<
2158			RecoveryPalletName,
2159			<Runtime as frame_system::Config>::DbWeight,
2160		>,
2161		// permanent
2162		pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,
2163	);
2164}
2165
2166/// Unchecked extrinsic type as expected by this runtime.
2167pub type UncheckedExtrinsic =
2168	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
2169/// Unchecked signature payload type as expected by this runtime.
2170pub type UncheckedSignaturePayload =
2171	generic::UncheckedSignaturePayload<Address, Signature, TxExtension>;
2172
2173/// Executive: handles dispatch to the various modules.
2174pub type Executive = frame_executive::Executive<
2175	Runtime,
2176	Block,
2177	frame_system::ChainContext<Runtime>,
2178	Runtime,
2179	AllPalletsWithSystem,
2180>;
2181/// The payload being signed in transactions.
2182pub type SignedPayload = generic::SignedPayload<RuntimeCall, TxExtension>;
2183
2184#[cfg(feature = "runtime-benchmarks")]
2185mod benches {
2186	frame_benchmarking::define_benchmarks!(
2187		// Polkadot
2188		// NOTE: Make sure to prefix these with `runtime_common::` so
2189		// the that path resolves correctly in the generated file.
2190		[polkadot_runtime_common::assigned_slots, AssignedSlots]
2191		[polkadot_runtime_common::auctions, Auctions]
2192		[polkadot_runtime_common::crowdloan, Crowdloan]
2193		[polkadot_runtime_common::identity_migrator, IdentityMigrator]
2194		[polkadot_runtime_common::paras_registrar, Registrar]
2195		[polkadot_runtime_common::slots, Slots]
2196		[polkadot_runtime_parachains::configuration, Configuration]
2197		[polkadot_runtime_parachains::disputes, ParasDisputes]
2198		[polkadot_runtime_parachains::disputes::slashing, ParasSlashing]
2199		[polkadot_runtime_parachains::hrmp, Hrmp]
2200		[polkadot_runtime_parachains::inclusion, ParaInclusion]
2201		[polkadot_runtime_parachains::initializer, Initializer]
2202		[polkadot_runtime_parachains::paras, Paras]
2203		[polkadot_runtime_parachains::paras_inherent, ParaInherent]
2204		[polkadot_runtime_parachains::on_demand, OnDemandAssignmentProvider]
2205		[polkadot_runtime_parachains::coretime, Coretime]
2206		// Substrate
2207		[pallet_bags_list, VoterList]
2208		[pallet_balances, Balances]
2209		[pallet_beefy_mmr, BeefyMmrLeaf]
2210		[pallet_election_provider_multi_phase, ElectionProviderMultiPhase]
2211		[frame_election_provider_support, ElectionProviderBench::<Runtime>]
2212		[pallet_fast_unstake, FastUnstake]
2213		[pallet_identity, Identity]
2214		[pallet_indices, Indices]
2215		[pallet_message_queue, MessageQueue]
2216		[pallet_migrations, MultiBlockMigrations]
2217		[pallet_mmr, Mmr]
2218		[pallet_multisig, Multisig]
2219		[pallet_nomination_pools, NominationPoolsBench::<Runtime>]
2220		[pallet_offences, OffencesBench::<Runtime>]
2221		[pallet_parameters, Parameters]
2222		[pallet_preimage, Preimage]
2223		[pallet_proxy, Proxy]
2224		[pallet_scheduler, Scheduler]
2225		[pallet_session, SessionBench::<Runtime>]
2226		[pallet_staking, Staking]
2227		[pallet_sudo, Sudo]
2228		[frame_system, SystemBench::<Runtime>]
2229		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
2230		[pallet_timestamp, Timestamp]
2231		[pallet_transaction_payment, TransactionPayment]
2232		[pallet_utility, Utility]
2233		[pallet_vesting, Vesting]
2234		[pallet_asset_rate, AssetRate]
2235		[pallet_accumulate_and_forward, AccumulateForward]
2236		// XCM
2237		[pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
2238		// NOTE: Make sure you point to the individual modules below.
2239		[pallet_xcm_benchmarks::fungible, XcmBalances]
2240		[pallet_xcm_benchmarks::generic, XcmGeneric]
2241	);
2242}
2243
2244sp_api::impl_runtime_apis! {
2245	impl sp_api::Core<Block> for Runtime {
2246		fn version() -> RuntimeVersion {
2247			VERSION
2248		}
2249
2250		fn execute_block(block: <Block as BlockT>::LazyBlock) {
2251			Executive::execute_block(block);
2252		}
2253
2254		fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
2255			Executive::initialize_block(header)
2256		}
2257	}
2258
2259	impl sp_api::Metadata<Block> for Runtime {
2260		fn metadata() -> OpaqueMetadata {
2261			OpaqueMetadata::new(Runtime::metadata().into())
2262		}
2263
2264		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
2265			Runtime::metadata_at_version(version)
2266		}
2267
2268		fn metadata_versions() -> alloc::vec::Vec<u32> {
2269			Runtime::metadata_versions()
2270		}
2271	}
2272
2273	impl frame_support::view_functions::runtime_api::RuntimeViewFunction<Block> for Runtime {
2274		fn execute_view_function(id: frame_support::view_functions::ViewFunctionId, input: Vec<u8>) -> Result<Vec<u8>, frame_support::view_functions::ViewFunctionDispatchError> {
2275			Runtime::execute_view_function(id, input)
2276		}
2277	}
2278
2279	impl sp_block_builder::BlockBuilder<Block> for Runtime {
2280		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
2281			Executive::apply_extrinsic(extrinsic)
2282		}
2283
2284		fn finalize_block() -> <Block as BlockT>::Header {
2285			Executive::finalize_block()
2286		}
2287
2288		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
2289			data.create_extrinsics()
2290		}
2291
2292		fn check_inherents(
2293			block: <Block as BlockT>::LazyBlock,
2294			data: sp_inherents::InherentData,
2295		) -> sp_inherents::CheckInherentsResult {
2296			data.check_extrinsics(&block)
2297		}
2298	}
2299
2300	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
2301		fn validate_transaction(
2302			source: TransactionSource,
2303			tx: <Block as BlockT>::Extrinsic,
2304			block_hash: <Block as BlockT>::Hash,
2305		) -> TransactionValidity {
2306			Executive::validate_transaction(source, tx, block_hash)
2307		}
2308	}
2309
2310	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
2311		fn offchain_worker(header: &<Block as BlockT>::Header) {
2312			Executive::offchain_worker(header)
2313		}
2314	}
2315
2316	#[api_version(16)]
2317	impl polkadot_primitives::runtime_api::ParachainHost<Block> for Runtime {
2318		fn validators() -> Vec<ValidatorId> {
2319			parachains_runtime_api_impl::validators::<Runtime>()
2320		}
2321
2322		fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>) {
2323			parachains_runtime_api_impl::validator_groups::<Runtime>()
2324		}
2325
2326		fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>> {
2327			parachains_runtime_api_impl::availability_cores::<Runtime>()
2328		}
2329
2330		fn persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption)
2331			-> Option<PersistedValidationData<Hash, BlockNumber>> {
2332			parachains_runtime_api_impl::persisted_validation_data::<Runtime>(para_id, assumption)
2333		}
2334
2335		fn assumed_validation_data(
2336			para_id: ParaId,
2337			expected_persisted_validation_data_hash: Hash,
2338		) -> Option<(PersistedValidationData<Hash, BlockNumber>, ValidationCodeHash)> {
2339			parachains_runtime_api_impl::assumed_validation_data::<Runtime>(
2340				para_id,
2341				expected_persisted_validation_data_hash,
2342			)
2343		}
2344
2345		fn check_validation_outputs(
2346			para_id: ParaId,
2347			outputs: polkadot_primitives::CandidateCommitments,
2348		) -> bool {
2349			parachains_runtime_api_impl::check_validation_outputs::<Runtime>(para_id, outputs)
2350		}
2351
2352		fn session_index_for_child() -> SessionIndex {
2353			parachains_runtime_api_impl::session_index_for_child::<Runtime>()
2354		}
2355
2356		fn validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption)
2357			-> Option<ValidationCode> {
2358			parachains_runtime_api_impl::validation_code::<Runtime>(para_id, assumption)
2359		}
2360
2361		fn candidate_pending_availability(para_id: ParaId) -> Option<CommittedCandidateReceipt<Hash>> {
2362			#[allow(deprecated)]
2363			parachains_runtime_api_impl::candidate_pending_availability::<Runtime>(para_id)
2364		}
2365
2366		fn candidate_events() -> Vec<CandidateEvent<Hash>> {
2367			parachains_runtime_api_impl::candidate_events::<Runtime, _>(|ev| {
2368				match ev {
2369					RuntimeEvent::ParaInclusion(ev) => {
2370						Some(ev)
2371					}
2372					_ => None,
2373				}
2374			})
2375		}
2376
2377		fn session_info(index: SessionIndex) -> Option<SessionInfo> {
2378			parachains_runtime_api_impl::session_info::<Runtime>(index)
2379		}
2380
2381		fn session_executor_params(session_index: SessionIndex) -> Option<ExecutorParams> {
2382			parachains_runtime_api_impl::session_executor_params::<Runtime>(session_index)
2383		}
2384
2385		fn dmq_contents(recipient: ParaId) -> Vec<InboundDownwardMessage<BlockNumber>> {
2386			parachains_runtime_api_impl::dmq_contents::<Runtime>(recipient)
2387		}
2388
2389		fn inbound_hrmp_channels_contents(
2390			recipient: ParaId
2391		) -> BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>> {
2392			parachains_runtime_api_impl::inbound_hrmp_channels_contents::<Runtime>(recipient)
2393		}
2394
2395		fn validation_code_by_hash(hash: ValidationCodeHash) -> Option<ValidationCode> {
2396			parachains_runtime_api_impl::validation_code_by_hash::<Runtime>(hash)
2397		}
2398
2399		fn on_chain_votes() -> Option<ScrapedOnChainVotes<Hash>> {
2400			parachains_runtime_api_impl::on_chain_votes::<Runtime>()
2401		}
2402
2403		fn submit_pvf_check_statement(
2404			stmt: PvfCheckStatement,
2405			signature: ValidatorSignature,
2406		) {
2407			parachains_runtime_api_impl::submit_pvf_check_statement::<Runtime>(stmt, signature)
2408		}
2409
2410		fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
2411			parachains_runtime_api_impl::pvfs_require_precheck::<Runtime>()
2412		}
2413
2414		fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption)
2415			-> Option<ValidationCodeHash>
2416		{
2417			parachains_runtime_api_impl::validation_code_hash::<Runtime>(para_id, assumption)
2418		}
2419
2420		fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)> {
2421			parachains_runtime_api_impl::get_session_disputes::<Runtime>()
2422		}
2423
2424		fn unapplied_slashes(
2425		) -> Vec<(SessionIndex, CandidateHash, slashing::LegacyPendingSlashes)> {
2426			parachains_runtime_api_impl::unapplied_slashes::<Runtime>()
2427		}
2428
2429		fn unapplied_slashes_v2(
2430		) -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)> {
2431			parachains_runtime_api_impl::unapplied_slashes_v2::<Runtime>()
2432		}
2433
2434		fn key_ownership_proof(
2435			validator_id: ValidatorId,
2436		) -> Option<slashing::OpaqueKeyOwnershipProof> {
2437			use codec::Encode;
2438
2439			Historical::prove((PARACHAIN_KEY_TYPE_ID, validator_id))
2440				.map(|p| p.encode())
2441				.map(slashing::OpaqueKeyOwnershipProof::new)
2442		}
2443
2444		fn submit_report_dispute_lost(
2445			dispute_proof: slashing::DisputeProof,
2446			key_ownership_proof: slashing::OpaqueKeyOwnershipProof,
2447		) -> Option<()> {
2448			parachains_runtime_api_impl::submit_unsigned_slashing_report::<Runtime>(
2449				dispute_proof,
2450				key_ownership_proof,
2451			)
2452		}
2453
2454		fn minimum_backing_votes() -> u32 {
2455			parachains_runtime_api_impl::minimum_backing_votes::<Runtime>()
2456		}
2457
2458		fn para_backing_state(para_id: ParaId) -> Option<polkadot_primitives::async_backing::BackingState> {
2459			#[allow(deprecated)]
2460			parachains_runtime_api_impl::backing_state::<Runtime>(para_id)
2461		}
2462
2463		fn async_backing_params() -> polkadot_primitives::AsyncBackingParams {
2464			#[allow(deprecated)]
2465			parachains_runtime_api_impl::async_backing_params::<Runtime>()
2466		}
2467
2468		fn approval_voting_params() -> ApprovalVotingParams {
2469			parachains_runtime_api_impl::approval_voting_params::<Runtime>()
2470		}
2471
2472		fn disabled_validators() -> Vec<ValidatorIndex> {
2473			parachains_runtime_api_impl::disabled_validators::<Runtime>()
2474		}
2475
2476		fn node_features() -> NodeFeatures {
2477			parachains_runtime_api_impl::node_features::<Runtime>()
2478		}
2479
2480		fn claim_queue() -> BTreeMap<CoreIndex, VecDeque<ParaId>> {
2481			parachains_runtime_api_impl::claim_queue::<Runtime>()
2482		}
2483
2484		fn candidates_pending_availability(para_id: ParaId) -> Vec<CommittedCandidateReceipt<Hash>> {
2485			parachains_runtime_api_impl::candidates_pending_availability::<Runtime>(para_id)
2486		}
2487
2488		fn backing_constraints(para_id: ParaId) -> Option<Constraints> {
2489			parachains_runtime_api_impl::backing_constraints::<Runtime>(para_id)
2490		}
2491
2492		fn scheduling_lookahead() -> u32 {
2493			parachains_runtime_api_impl::scheduling_lookahead::<Runtime>()
2494		}
2495
2496		fn validation_code_bomb_limit() -> u32 {
2497			parachains_runtime_api_impl::validation_code_bomb_limit::<Runtime>()
2498		}
2499
2500		fn para_ids() -> Vec<ParaId> {
2501			parachains_staging_runtime_api_impl::para_ids::<Runtime>()
2502		}
2503
2504		fn max_relay_parent_session_age() -> u32 {
2505			parachains_staging_runtime_api_impl::max_relay_parent_session_age::<Runtime>()
2506		}
2507
2508		fn ancestor_relay_parent_info(
2509			session_index: SessionIndex,
2510			relay_parent: Hash,
2511		) -> Option<polkadot_primitives::vstaging::RelayParentInfo<Hash, BlockNumber>> {
2512			parachains_staging_runtime_api_impl::ancestor_relay_parent_info::<Runtime>(session_index, relay_parent)
2513		}
2514	}
2515
2516	#[api_version(6)]
2517	impl sp_consensus_beefy::BeefyApi<Block, BeefyId> for Runtime {
2518		fn beefy_genesis() -> Option<BlockNumber> {
2519			pallet_beefy::GenesisBlock::<Runtime>::get()
2520		}
2521
2522		fn validator_set() -> Option<sp_consensus_beefy::ValidatorSet<BeefyId>> {
2523			Beefy::validator_set()
2524		}
2525
2526		fn submit_report_double_voting_unsigned_extrinsic(
2527			equivocation_proof: sp_consensus_beefy::DoubleVotingProof<
2528				BlockNumber,
2529				BeefyId,
2530				BeefySignature,
2531			>,
2532			key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof,
2533		) -> Option<()> {
2534			let key_owner_proof = key_owner_proof.decode()?;
2535
2536			Beefy::submit_unsigned_double_voting_report(
2537				equivocation_proof,
2538				key_owner_proof,
2539			)
2540		}
2541
2542		fn submit_report_fork_voting_unsigned_extrinsic(
2543			equivocation_proof:
2544				sp_consensus_beefy::ForkVotingProof<
2545					<Block as BlockT>::Header,
2546					BeefyId,
2547					sp_runtime::OpaqueValue
2548				>,
2549			key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof,
2550		) -> Option<()> {
2551			Beefy::submit_unsigned_fork_voting_report(
2552				equivocation_proof.try_into()?,
2553				key_owner_proof.decode()?,
2554			)
2555		}
2556
2557		fn submit_report_future_block_voting_unsigned_extrinsic(
2558			equivocation_proof: sp_consensus_beefy::FutureBlockVotingProof<BlockNumber, BeefyId>,
2559			key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof,
2560		) -> Option<()> {
2561			Beefy::submit_unsigned_future_block_voting_report(
2562				equivocation_proof,
2563				key_owner_proof.decode()?,
2564			)
2565		}
2566
2567		fn generate_key_ownership_proof(
2568			_set_id: sp_consensus_beefy::ValidatorSetId,
2569			authority_id: BeefyId,
2570		) -> Option<sp_consensus_beefy::OpaqueKeyOwnershipProof> {
2571			use codec::Encode;
2572
2573			Historical::prove((sp_consensus_beefy::KEY_TYPE, authority_id))
2574				.map(|p| p.encode())
2575				.map(sp_consensus_beefy::OpaqueKeyOwnershipProof::new)
2576		}
2577	}
2578
2579	#[api_version(3)]
2580	impl mmr::MmrApi<Block, Hash, BlockNumber> for Runtime {
2581		fn mmr_root() -> Result<mmr::Hash, mmr::Error> {
2582			Ok(pallet_mmr::RootHash::<Runtime>::get())
2583		}
2584
2585		fn mmr_leaf_count() -> Result<mmr::LeafIndex, mmr::Error> {
2586			Ok(pallet_mmr::NumberOfLeaves::<Runtime>::get())
2587		}
2588
2589		fn generate_proof(
2590			block_numbers: Vec<BlockNumber>,
2591			best_known_block_number: Option<BlockNumber>,
2592		) -> Result<(Vec<mmr::EncodableOpaqueLeaf>, mmr::LeafProof<mmr::Hash>), mmr::Error> {
2593			Mmr::generate_proof(block_numbers, best_known_block_number).map(
2594				|(leaves, proof)| {
2595					(
2596						leaves
2597							.into_iter()
2598							.map(|leaf| mmr::EncodableOpaqueLeaf::from_leaf(&leaf))
2599							.collect(),
2600						proof,
2601					)
2602				},
2603			)
2604		}
2605
2606		fn generate_ancestry_proof(
2607			prev_block_number: BlockNumber,
2608			best_known_block_number: Option<BlockNumber>,
2609		) -> Result<mmr::AncestryProof<mmr::Hash>, mmr::Error> {
2610			Mmr::generate_ancestry_proof(prev_block_number, best_known_block_number)
2611		}
2612
2613		fn verify_proof(leaves: Vec<mmr::EncodableOpaqueLeaf>, proof: mmr::LeafProof<mmr::Hash>)
2614			-> Result<(), mmr::Error>
2615		{
2616			let leaves = leaves.into_iter().map(|leaf|
2617				leaf.into_opaque_leaf()
2618				.try_decode()
2619				.ok_or(mmr::Error::Verify)).collect::<Result<Vec<mmr::Leaf>, mmr::Error>>()?;
2620			Mmr::verify_leaves(leaves, proof)
2621		}
2622
2623		fn verify_proof_stateless(
2624			root: mmr::Hash,
2625			leaves: Vec<mmr::EncodableOpaqueLeaf>,
2626			proof: mmr::LeafProof<mmr::Hash>
2627		) -> Result<(), mmr::Error> {
2628			let nodes = leaves.into_iter().map(|leaf|mmr::DataOrHash::Data(leaf.into_opaque_leaf())).collect();
2629			pallet_mmr::verify_leaves_proof::<mmr::Hashing, _>(root, nodes, proof)
2630		}
2631	}
2632
2633	impl pallet_beefy_mmr::BeefyMmrApi<Block, Hash> for RuntimeApi {
2634		fn authority_set_proof() -> sp_consensus_beefy::mmr::BeefyAuthoritySet<Hash> {
2635			BeefyMmrLeaf::authority_set_proof()
2636		}
2637
2638		fn next_authority_set_proof() -> sp_consensus_beefy::mmr::BeefyNextAuthoritySet<Hash> {
2639			BeefyMmrLeaf::next_authority_set_proof()
2640		}
2641	}
2642
2643	impl fg_primitives::GrandpaApi<Block> for Runtime {
2644		fn grandpa_authorities() -> Vec<(GrandpaId, u64)> {
2645			Grandpa::grandpa_authorities()
2646		}
2647
2648		fn current_set_id() -> fg_primitives::SetId {
2649			pallet_grandpa::CurrentSetId::<Runtime>::get()
2650		}
2651
2652		fn submit_report_equivocation_unsigned_extrinsic(
2653			equivocation_proof: fg_primitives::EquivocationProof<
2654				<Block as BlockT>::Hash,
2655				sp_runtime::traits::NumberFor<Block>,
2656			>,
2657			key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,
2658		) -> Option<()> {
2659			let key_owner_proof = key_owner_proof.decode()?;
2660
2661			Grandpa::submit_unsigned_equivocation_report(
2662				equivocation_proof,
2663				key_owner_proof,
2664			)
2665		}
2666
2667		fn generate_key_ownership_proof(
2668			_set_id: fg_primitives::SetId,
2669			authority_id: fg_primitives::AuthorityId,
2670		) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {
2671			use codec::Encode;
2672
2673			Historical::prove((fg_primitives::KEY_TYPE, authority_id))
2674				.map(|p| p.encode())
2675				.map(fg_primitives::OpaqueKeyOwnershipProof::new)
2676		}
2677	}
2678
2679	impl sp_consensus_babe::BabeApi<Block> for Runtime {
2680		fn configuration() -> sp_consensus_babe::BabeConfiguration {
2681			let epoch_config = Babe::epoch_config().unwrap_or(BABE_GENESIS_EPOCH_CONFIG);
2682			sp_consensus_babe::BabeConfiguration {
2683				slot_duration: Babe::slot_duration(),
2684				epoch_length: EpochDuration::get(),
2685				c: epoch_config.c,
2686				authorities: Babe::authorities().to_vec(),
2687				randomness: Babe::randomness(),
2688				allowed_slots: epoch_config.allowed_slots,
2689			}
2690		}
2691
2692		fn current_epoch_start() -> sp_consensus_babe::Slot {
2693			Babe::current_epoch_start()
2694		}
2695
2696		fn current_epoch() -> sp_consensus_babe::Epoch {
2697			Babe::current_epoch()
2698		}
2699
2700		fn next_epoch() -> sp_consensus_babe::Epoch {
2701			Babe::next_epoch()
2702		}
2703
2704		fn generate_key_ownership_proof(
2705			_slot: sp_consensus_babe::Slot,
2706			authority_id: sp_consensus_babe::AuthorityId,
2707		) -> Option<sp_consensus_babe::OpaqueKeyOwnershipProof> {
2708			use codec::Encode;
2709
2710			Historical::prove((sp_consensus_babe::KEY_TYPE, authority_id))
2711				.map(|p| p.encode())
2712				.map(sp_consensus_babe::OpaqueKeyOwnershipProof::new)
2713		}
2714
2715		fn submit_report_equivocation_unsigned_extrinsic(
2716			equivocation_proof: sp_consensus_babe::EquivocationProof<<Block as BlockT>::Header>,
2717			key_owner_proof: sp_consensus_babe::OpaqueKeyOwnershipProof,
2718		) -> Option<()> {
2719			let key_owner_proof = key_owner_proof.decode()?;
2720
2721			Babe::submit_unsigned_equivocation_report(
2722				equivocation_proof,
2723				key_owner_proof,
2724			)
2725		}
2726	}
2727
2728	impl sp_authority_discovery::AuthorityDiscoveryApi<Block> for Runtime {
2729		fn authorities() -> Vec<AuthorityDiscoveryId> {
2730			parachains_runtime_api_impl::relevant_authority_ids::<Runtime>()
2731		}
2732	}
2733
2734	impl sp_session::SessionKeys<Block> for Runtime {
2735		fn generate_session_keys(owner: Vec<u8>, seed: Option<Vec<u8>>) -> sp_session::OpaqueGeneratedSessionKeys {
2736			SessionKeys::generate(&owner, seed).into()
2737		}
2738
2739		fn decode_session_keys(
2740			encoded: Vec<u8>,
2741		) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
2742			SessionKeys::decode_into_raw_public_keys(&encoded)
2743		}
2744	}
2745
2746	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
2747		fn account_nonce(account: AccountId) -> Nonce {
2748			System::account_nonce(account)
2749		}
2750	}
2751
2752	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
2753		Block,
2754		Balance,
2755	> for Runtime {
2756		fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
2757			TransactionPayment::query_info(uxt, len)
2758		}
2759		fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {
2760			TransactionPayment::query_fee_details(uxt, len)
2761		}
2762		fn query_weight_to_fee(weight: Weight) -> Balance {
2763			TransactionPayment::weight_to_fee(weight)
2764		}
2765		fn query_length_to_fee(length: u32) -> Balance {
2766			TransactionPayment::length_to_fee(length)
2767		}
2768	}
2769
2770	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
2771		for Runtime
2772	{
2773		fn query_call_info(call: RuntimeCall, len: u32) -> RuntimeDispatchInfo<Balance> {
2774			TransactionPayment::query_call_info(call, len)
2775		}
2776		fn query_call_fee_details(call: RuntimeCall, len: u32) -> FeeDetails<Balance> {
2777			TransactionPayment::query_call_fee_details(call, len)
2778		}
2779		fn query_weight_to_fee(weight: Weight) -> Balance {
2780			TransactionPayment::weight_to_fee(weight)
2781		}
2782		fn query_length_to_fee(length: u32) -> Balance {
2783			TransactionPayment::length_to_fee(length)
2784		}
2785	}
2786
2787	impl xcm_runtime_apis::fees::XcmPaymentApi<Block> for Runtime {
2788		fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
2789			let acceptable_assets = vec![AssetId(xcm_config::TokenLocation::get())];
2790			XcmPallet::query_acceptable_payment_assets(xcm_version, acceptable_assets)
2791		}
2792
2793		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
2794			type Trader = <XcmConfig as xcm_executor::Config>::Trader;
2795			XcmPallet::query_weight_to_asset_fee::<Trader>(weight, asset)
2796		}
2797
2798		fn query_xcm_weight(message: VersionedXcm<()>) -> Result<Weight, XcmPaymentApiError> {
2799			XcmPallet::query_xcm_weight(message)
2800		}
2801
2802		fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>, asset_id: VersionedAssetId) -> Result<VersionedAssets, XcmPaymentApiError> {
2803			type AssetExchanger = <XcmConfig as xcm_executor::Config>::AssetExchanger;
2804			XcmPallet::query_delivery_fees::<AssetExchanger>(destination, message, asset_id)
2805		}
2806	}
2807
2808	impl xcm_runtime_apis::dry_run::DryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
2809		fn dry_run_call(origin: OriginCaller, call: RuntimeCall, result_xcms_version: XcmVersion) -> Result<CallDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
2810			XcmPallet::dry_run_call::<Runtime, xcm_config::XcmRouter, OriginCaller, RuntimeCall>(origin, call, result_xcms_version)
2811		}
2812
2813		fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
2814			XcmPallet::dry_run_xcm::<xcm_config::XcmRouter>(origin_location, xcm)
2815		}
2816	}
2817
2818	impl xcm_runtime_apis::conversions::LocationToAccountApi<Block, AccountId> for Runtime {
2819		fn convert_location(location: VersionedLocation) -> Result<
2820			AccountId,
2821			xcm_runtime_apis::conversions::Error
2822		> {
2823			xcm_runtime_apis::conversions::LocationToAccountHelper::<
2824				AccountId,
2825				xcm_config::LocationConverter,
2826			>::convert_location(location)
2827		}
2828	}
2829
2830	impl pallet_nomination_pools_runtime_api::NominationPoolsApi<
2831		Block,
2832		AccountId,
2833		Balance,
2834	> for Runtime {
2835		fn pending_rewards(member: AccountId) -> Balance {
2836			NominationPools::api_pending_rewards(member).unwrap_or_default()
2837		}
2838
2839		fn points_to_balance(pool_id: PoolId, points: Balance) -> Balance {
2840			NominationPools::api_points_to_balance(pool_id, points)
2841		}
2842
2843		fn balance_to_points(pool_id: PoolId, new_funds: Balance) -> Balance {
2844			NominationPools::api_balance_to_points(pool_id, new_funds)
2845		}
2846
2847		fn pool_pending_slash(pool_id: PoolId) -> Balance {
2848			NominationPools::api_pool_pending_slash(pool_id)
2849		}
2850
2851		fn member_pending_slash(member: AccountId) -> Balance {
2852			NominationPools::api_member_pending_slash(member)
2853		}
2854
2855		fn pool_needs_delegate_migration(pool_id: PoolId) -> bool {
2856			NominationPools::api_pool_needs_delegate_migration(pool_id)
2857		}
2858
2859		fn member_needs_delegate_migration(member: AccountId) -> bool {
2860			NominationPools::api_member_needs_delegate_migration(member)
2861		}
2862
2863		fn member_total_balance(member: AccountId) -> Balance {
2864			NominationPools::api_member_total_balance(member)
2865		}
2866
2867		fn pool_balance(pool_id: PoolId) -> Balance {
2868			NominationPools::api_pool_balance(pool_id)
2869		}
2870
2871		fn pool_accounts(pool_id: PoolId) -> (AccountId, AccountId) {
2872			NominationPools::api_pool_accounts(pool_id)
2873		}
2874	}
2875
2876	impl pallet_staking_runtime_api::StakingApi<Block, Balance, AccountId> for Runtime {
2877		fn nominations_quota(balance: Balance) -> u32 {
2878			Staking::api_nominations_quota(balance)
2879		}
2880
2881		fn eras_stakers_page_count(era: sp_staking::EraIndex, account: AccountId) -> sp_staking::Page {
2882			Staking::api_eras_stakers_page_count(era, account)
2883		}
2884
2885		fn pending_rewards(era: sp_staking::EraIndex, account: AccountId) -> bool {
2886			Staking::api_pending_rewards(era, account)
2887		}
2888	}
2889
2890	#[cfg(feature = "try-runtime")]
2891	impl frame_try_runtime::TryRuntime<Block> for Runtime {
2892		fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
2893			log::info!("try-runtime::on_runtime_upgrade westend.");
2894		  // TODO:: remove once https://github.com/paritytech/polkadot-sdk/issues/9442 is resolved.
2895			let excluded_pallets = vec![
2896				b"Staking".to_vec(),          // replaced by staking-async
2897				b"NominationPools".to_vec(),  // moved to AH
2898				b"FastUnstake".to_vec(),      // deprecated
2899				b"DelegatedStaking".to_vec(), // moved to AH
2900			];
2901			let config = frame_executive::TryRuntimeUpgradeConfig::new(checks)
2902				.with_try_state_select(frame_try_runtime::TryStateSelect::AllExcept(
2903					excluded_pallets,
2904				));
2905			let weight = Executive::try_runtime_upgrade_with_config(config).unwrap();
2906			(weight, BlockWeights::get().max_block)
2907		}
2908
2909		fn execute_block(
2910			block: <Block as BlockT>::LazyBlock,
2911			state_root_check: bool,
2912			signature_check: bool,
2913			select: frame_try_runtime::TryStateSelect,
2914		) -> Weight {
2915			// NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
2916			// have a backtrace here.
2917			Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()
2918		}
2919	}
2920
2921	#[cfg(feature = "runtime-benchmarks")]
2922	impl frame_benchmarking::Benchmark<Block> for Runtime {
2923		fn benchmark_metadata(extra: bool) -> (
2924			Vec<frame_benchmarking::BenchmarkList>,
2925			Vec<frame_support::traits::StorageInfo>,
2926		) {
2927			use frame_benchmarking::BenchmarkList;
2928			use frame_support::traits::StorageInfoTrait;
2929
2930			use pallet_session_benchmarking::Pallet as SessionBench;
2931			use pallet_offences_benchmarking::Pallet as OffencesBench;
2932			use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench;
2933			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
2934			use frame_system_benchmarking::Pallet as SystemBench;
2935			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
2936			use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench;
2937
2938			type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
2939			type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::<Runtime>;
2940
2941			let mut list = Vec::<BenchmarkList>::new();
2942			list_benchmarks!(list, extra);
2943
2944			let storage_info = AllPalletsWithSystem::storage_info();
2945			return (list, storage_info)
2946		}
2947
2948		#[allow(non_local_definitions)]
2949		fn dispatch_benchmark(
2950			config: frame_benchmarking::BenchmarkConfig,
2951		) -> Result<
2952			Vec<frame_benchmarking::BenchmarkBatch>,
2953			alloc::string::String,
2954		> {
2955			use frame_support::traits::WhitelistedStorageKeys;
2956			use frame_benchmarking::{BenchmarkBatch, BenchmarkError};
2957			use sp_storage::TrackedStorageKey;
2958			// Trying to add benchmarks directly to some pallets caused cyclic dependency issues.
2959			// To get around that, we separated the benchmarks into its own crate.
2960			use pallet_session_benchmarking::Pallet as SessionBench;
2961			use pallet_offences_benchmarking::Pallet as OffencesBench;
2962			use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench;
2963			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
2964			use frame_system_benchmarking::Pallet as SystemBench;
2965			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
2966			use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench;
2967
2968			impl pallet_session_benchmarking::Config for Runtime {
2969				fn generate_session_keys_and_proof(owner: Self::AccountId) -> (Self::Keys, Vec<u8>) {
2970					let keys = SessionKeys::generate(&owner.encode(), None);
2971					(keys.keys, keys.proof.encode())
2972				}
2973			}
2974
2975			impl pallet_offences_benchmarking::Config for Runtime {}
2976			impl pallet_election_provider_support_benchmarking::Config for Runtime {}
2977
2978			use xcm_config::{AssetHub, TokenLocation};
2979
2980			use alloc::boxed::Box;
2981
2982			parameter_types! {
2983				pub ExistentialDepositAsset: Option<Asset> = Some((
2984					TokenLocation::get(),
2985					ExistentialDeposit::get()
2986				).into());
2987				pub AssetHubParaId: ParaId = westend_runtime_constants::system_parachain::ASSET_HUB_ID.into();
2988				pub const RandomParaId: ParaId = ParaId::new(43211234);
2989			}
2990
2991			impl pallet_xcm::benchmarking::Config for Runtime {
2992				type DeliveryHelper = (
2993					polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
2994						xcm_config::XcmConfig,
2995						ExistentialDepositAsset,
2996						xcm_config::PriceForChildParachainDelivery,
2997						AssetHubParaId,
2998						Dmp,
2999					>,
3000					polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
3001						xcm_config::XcmConfig,
3002						ExistentialDepositAsset,
3003						xcm_config::PriceForChildParachainDelivery,
3004						RandomParaId,
3005						Dmp,
3006					>
3007				);
3008
3009				fn reachable_dest() -> Option<Location> {
3010					Some(crate::xcm_config::AssetHub::get())
3011				}
3012
3013				fn teleportable_asset_and_dest() -> Option<(Asset, Location)> {
3014					// Relay/native token can be teleported to/from AH.
3015					Some((
3016						Asset { fun: Fungible(ExistentialDeposit::get()), id: AssetId(Here.into()) },
3017						crate::xcm_config::AssetHub::get(),
3018					))
3019				}
3020
3021				fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
3022					None
3023				}
3024
3025				fn set_up_complex_asset_transfer(
3026				) -> Option<(Assets, u32, Location, Box<dyn FnOnce()>)> {
3027					// Relay supports only native token, either reserve transfer it to non-system parachains,
3028					// or teleport it to system parachain. Use the teleport case for benchmarking as it's
3029					// slightly heavier.
3030
3031					// Relay/native token can be teleported to/from AH.
3032					let native_location = Here.into();
3033					let dest = crate::xcm_config::AssetHub::get();
3034					pallet_xcm::benchmarking::helpers::native_teleport_as_asset_transfer::<Runtime>(
3035						native_location,
3036						dest
3037					)
3038				}
3039
3040				fn get_asset() -> Asset {
3041					Asset {
3042						id: AssetId(Location::here()),
3043						fun: Fungible(ExistentialDeposit::get()),
3044					}
3045				}
3046			}
3047			impl frame_system_benchmarking::Config for Runtime {}
3048			impl pallet_transaction_payment::BenchmarkConfig for Runtime {}
3049			impl pallet_nomination_pools_benchmarking::Config for Runtime {}
3050			impl polkadot_runtime_parachains::disputes::slashing::benchmarking::Config for Runtime {}
3051
3052			use xcm::latest::{
3053				AssetId, Fungibility::*, InteriorLocation, Junction, Junctions::*,
3054				Asset, Assets, Location, NetworkId, Response,
3055			};
3056
3057			impl pallet_xcm_benchmarks::Config for Runtime {
3058				type XcmConfig = xcm_config::XcmConfig;
3059				type AccountIdConverter = xcm_config::LocationConverter;
3060				type DeliveryHelper = polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
3061					xcm_config::XcmConfig,
3062					ExistentialDepositAsset,
3063					xcm_config::PriceForChildParachainDelivery,
3064					AssetHubParaId,
3065					Dmp,
3066				>;
3067				fn valid_destination() -> Result<Location, BenchmarkError> {
3068					Ok(AssetHub::get())
3069				}
3070				fn worst_case_holding(_depositable_count: u32) -> xcm_executor::AssetsInHolding {
3071					use pallet_xcm_benchmarks::MockCredit;
3072					// Westend only knows about WND.
3073					let mut holding = xcm_executor::AssetsInHolding::new();
3074					holding.fungible.insert(
3075						AssetId(TokenLocation::get()),
3076						alloc::boxed::Box::new(MockCredit(1_000_000 * UNITS)),
3077					);
3078					holding
3079				}
3080			}
3081
3082			parameter_types! {
3083				pub TrustedTeleporter: Option<(Location, Asset)> = Some((
3084					AssetHub::get(),
3085					Asset { fun: Fungible(1 * UNITS), id: AssetId(TokenLocation::get()) },
3086				));
3087				pub const TrustedReserve: Option<(Location, Asset)> = None;
3088				pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None;
3089			}
3090
3091			impl pallet_xcm_benchmarks::fungible::Config for Runtime {
3092				type TransactAsset = Balances;
3093
3094				type CheckedAccount = CheckedAccount;
3095				type TrustedTeleporter = TrustedTeleporter;
3096				type TrustedReserve = TrustedReserve;
3097
3098				fn get_asset() -> Asset {
3099					Asset {
3100						id: AssetId(TokenLocation::get()),
3101						fun: Fungible(1 * UNITS),
3102					}
3103				}
3104			}
3105
3106			impl pallet_xcm_benchmarks::generic::Config for Runtime {
3107				type TransactAsset = Balances;
3108				type RuntimeCall = RuntimeCall;
3109
3110				fn worst_case_response() -> (u64, Response) {
3111					(0u64, Response::Version(Default::default()))
3112				}
3113
3114				fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> {
3115					// Westend doesn't support asset exchanges
3116					Err(BenchmarkError::Skip)
3117				}
3118
3119				fn universal_alias() -> Result<(Location, Junction), BenchmarkError> {
3120					// The XCM executor of Westend doesn't have a configured `UniversalAliases`
3121					Err(BenchmarkError::Skip)
3122				}
3123
3124				fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> {
3125					Ok((AssetHub::get(), frame_system::Call::remark_with_event { remark: vec![] }.into()))
3126				}
3127
3128				fn subscribe_origin() -> Result<Location, BenchmarkError> {
3129					Ok(AssetHub::get())
3130				}
3131
3132				fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> {
3133					let origin = AssetHub::get();
3134					let assets: Assets = (AssetId(TokenLocation::get()), 1_000 * UNITS).into();
3135					let ticket = Location { parents: 0, interior: Here };
3136					Ok((origin, ticket, assets))
3137				}
3138
3139				fn worst_case_for_trader() -> Result<(Asset, WeightLimit), BenchmarkError> {
3140					Ok((Asset {
3141						id: AssetId(TokenLocation::get()),
3142						fun: Fungible(1_000_000 * UNITS),
3143					}, WeightLimit::Limited(Weight::from_parts(5000, 5000))))
3144				}
3145
3146				fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> {
3147					// Westend doesn't support asset locking
3148					Err(BenchmarkError::Skip)
3149				}
3150
3151				fn export_message_origin_and_destination(
3152				) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> {
3153					// Westend doesn't support exporting messages
3154					Err(BenchmarkError::Skip)
3155				}
3156
3157				fn alias_origin() -> Result<(Location, Location), BenchmarkError> {
3158					let origin = Location::new(0, [Parachain(1000)]);
3159					let target = Location::new(0, [Parachain(1000), AccountId32 { id: [128u8; 32], network: None }]);
3160					Ok((origin, target))
3161				}
3162			}
3163
3164			type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
3165			type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::<Runtime>;
3166
3167			let whitelist: Vec<TrackedStorageKey> = AllPalletsWithSystem::whitelisted_storage_keys();
3168
3169			let mut batches = Vec::<BenchmarkBatch>::new();
3170			let params = (&config, &whitelist);
3171
3172			add_benchmarks!(params, batches);
3173
3174			Ok(batches)
3175		}
3176	}
3177
3178	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
3179		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
3180			build_state::<RuntimeGenesisConfig>(config)
3181		}
3182
3183		fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
3184			get_preset::<RuntimeGenesisConfig>(id, &genesis_config_presets::get_preset)
3185		}
3186
3187		fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
3188			genesis_config_presets::preset_names()
3189		}
3190	}
3191
3192	impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
3193		fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
3194			XcmPallet::is_trusted_reserve(asset, location)
3195		}
3196		fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
3197			XcmPallet::is_trusted_teleporter(asset, location)
3198		}
3199	}
3200}