Skip to main content

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_024_001,
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_offences, OffencesBench::<Runtime>]
2220		[pallet_parameters, Parameters]
2221		[pallet_preimage, Preimage]
2222		[pallet_proxy, Proxy]
2223		[pallet_scheduler, Scheduler]
2224		[pallet_session, SessionBench::<Runtime>]
2225		[pallet_staking, Staking]
2226		[pallet_sudo, Sudo]
2227		[frame_system, SystemBench::<Runtime>]
2228		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
2229		[pallet_timestamp, Timestamp]
2230		[pallet_transaction_payment, TransactionPayment]
2231		[pallet_utility, Utility]
2232		[pallet_vesting, Vesting]
2233		[pallet_asset_rate, AssetRate]
2234		[pallet_accumulate_and_forward, AccumulateForward]
2235		// XCM
2236		[pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
2237		// NOTE: Make sure you point to the individual modules below.
2238		[pallet_xcm_benchmarks::fungible, XcmBalances]
2239		[pallet_xcm_benchmarks::generic, XcmGeneric]
2240	);
2241}
2242
2243sp_api::impl_runtime_apis! {
2244	impl sp_api::Core<Block> for Runtime {
2245		fn version() -> RuntimeVersion {
2246			VERSION
2247		}
2248
2249		fn execute_block(block: <Block as BlockT>::LazyBlock) {
2250			Executive::execute_block(block);
2251		}
2252
2253		fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
2254			Executive::initialize_block(header)
2255		}
2256	}
2257
2258	impl sp_api::Metadata<Block> for Runtime {
2259		fn metadata() -> OpaqueMetadata {
2260			OpaqueMetadata::new(Runtime::metadata().into())
2261		}
2262
2263		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
2264			Runtime::metadata_at_version(version)
2265		}
2266
2267		fn metadata_versions() -> alloc::vec::Vec<u32> {
2268			Runtime::metadata_versions()
2269		}
2270	}
2271
2272	impl frame_support::view_functions::runtime_api::RuntimeViewFunction<Block> for Runtime {
2273		fn execute_view_function(id: frame_support::view_functions::ViewFunctionId, input: Vec<u8>) -> Result<Vec<u8>, frame_support::view_functions::ViewFunctionDispatchError> {
2274			Runtime::execute_view_function(id, input)
2275		}
2276	}
2277
2278	impl sp_block_builder::BlockBuilder<Block> for Runtime {
2279		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
2280			Executive::apply_extrinsic(extrinsic)
2281		}
2282
2283		fn finalize_block() -> <Block as BlockT>::Header {
2284			Executive::finalize_block()
2285		}
2286
2287		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
2288			data.create_extrinsics()
2289		}
2290
2291		fn check_inherents(
2292			block: <Block as BlockT>::LazyBlock,
2293			data: sp_inherents::InherentData,
2294		) -> sp_inherents::CheckInherentsResult {
2295			data.check_extrinsics(&block)
2296		}
2297	}
2298
2299	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
2300		fn validate_transaction(
2301			source: TransactionSource,
2302			tx: <Block as BlockT>::Extrinsic,
2303			block_hash: <Block as BlockT>::Hash,
2304		) -> TransactionValidity {
2305			Executive::validate_transaction(source, tx, block_hash)
2306		}
2307	}
2308
2309	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
2310		fn offchain_worker(header: &<Block as BlockT>::Header) {
2311			Executive::offchain_worker(header)
2312		}
2313	}
2314
2315	#[api_version(16)]
2316	impl polkadot_primitives::runtime_api::ParachainHost<Block> for Runtime {
2317		fn validators() -> Vec<ValidatorId> {
2318			parachains_runtime_api_impl::validators::<Runtime>()
2319		}
2320
2321		fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>) {
2322			parachains_runtime_api_impl::validator_groups::<Runtime>()
2323		}
2324
2325		fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>> {
2326			parachains_runtime_api_impl::availability_cores::<Runtime>()
2327		}
2328
2329		fn persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption)
2330			-> Option<PersistedValidationData<Hash, BlockNumber>> {
2331			parachains_runtime_api_impl::persisted_validation_data::<Runtime>(para_id, assumption)
2332		}
2333
2334		fn assumed_validation_data(
2335			para_id: ParaId,
2336			expected_persisted_validation_data_hash: Hash,
2337		) -> Option<(PersistedValidationData<Hash, BlockNumber>, ValidationCodeHash)> {
2338			parachains_runtime_api_impl::assumed_validation_data::<Runtime>(
2339				para_id,
2340				expected_persisted_validation_data_hash,
2341			)
2342		}
2343
2344		fn check_validation_outputs(
2345			para_id: ParaId,
2346			outputs: polkadot_primitives::CandidateCommitments,
2347		) -> bool {
2348			parachains_runtime_api_impl::check_validation_outputs::<Runtime>(para_id, outputs)
2349		}
2350
2351		fn session_index_for_child() -> SessionIndex {
2352			parachains_runtime_api_impl::session_index_for_child::<Runtime>()
2353		}
2354
2355		fn validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption)
2356			-> Option<ValidationCode> {
2357			parachains_runtime_api_impl::validation_code::<Runtime>(para_id, assumption)
2358		}
2359
2360		fn candidate_pending_availability(para_id: ParaId) -> Option<CommittedCandidateReceipt<Hash>> {
2361			#[allow(deprecated)]
2362			parachains_runtime_api_impl::candidate_pending_availability::<Runtime>(para_id)
2363		}
2364
2365		fn candidate_events() -> Vec<CandidateEvent<Hash>> {
2366			parachains_runtime_api_impl::candidate_events::<Runtime, _>(|ev| {
2367				match ev {
2368					RuntimeEvent::ParaInclusion(ev) => {
2369						Some(ev)
2370					}
2371					_ => None,
2372				}
2373			})
2374		}
2375
2376		fn session_info(index: SessionIndex) -> Option<SessionInfo> {
2377			parachains_runtime_api_impl::session_info::<Runtime>(index)
2378		}
2379
2380		fn session_executor_params(session_index: SessionIndex) -> Option<ExecutorParams> {
2381			parachains_runtime_api_impl::session_executor_params::<Runtime>(session_index)
2382		}
2383
2384		fn dmq_contents(recipient: ParaId) -> Vec<InboundDownwardMessage<BlockNumber>> {
2385			parachains_runtime_api_impl::dmq_contents::<Runtime>(recipient)
2386		}
2387
2388		fn inbound_hrmp_channels_contents(
2389			recipient: ParaId
2390		) -> BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>> {
2391			parachains_runtime_api_impl::inbound_hrmp_channels_contents::<Runtime>(recipient)
2392		}
2393
2394		fn validation_code_by_hash(hash: ValidationCodeHash) -> Option<ValidationCode> {
2395			parachains_runtime_api_impl::validation_code_by_hash::<Runtime>(hash)
2396		}
2397
2398		fn on_chain_votes() -> Option<ScrapedOnChainVotes<Hash>> {
2399			parachains_runtime_api_impl::on_chain_votes::<Runtime>()
2400		}
2401
2402		fn submit_pvf_check_statement(
2403			stmt: PvfCheckStatement,
2404			signature: ValidatorSignature,
2405		) {
2406			parachains_runtime_api_impl::submit_pvf_check_statement::<Runtime>(stmt, signature)
2407		}
2408
2409		fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
2410			parachains_runtime_api_impl::pvfs_require_precheck::<Runtime>()
2411		}
2412
2413		fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption)
2414			-> Option<ValidationCodeHash>
2415		{
2416			parachains_runtime_api_impl::validation_code_hash::<Runtime>(para_id, assumption)
2417		}
2418
2419		fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)> {
2420			parachains_runtime_api_impl::get_session_disputes::<Runtime>()
2421		}
2422
2423		fn unapplied_slashes(
2424		) -> Vec<(SessionIndex, CandidateHash, slashing::LegacyPendingSlashes)> {
2425			parachains_runtime_api_impl::unapplied_slashes::<Runtime>()
2426		}
2427
2428		fn unapplied_slashes_v2(
2429		) -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)> {
2430			parachains_runtime_api_impl::unapplied_slashes_v2::<Runtime>()
2431		}
2432
2433		fn key_ownership_proof(
2434			validator_id: ValidatorId,
2435		) -> Option<slashing::OpaqueKeyOwnershipProof> {
2436			use codec::Encode;
2437
2438			Historical::prove((PARACHAIN_KEY_TYPE_ID, validator_id))
2439				.map(|p| p.encode())
2440				.map(slashing::OpaqueKeyOwnershipProof::new)
2441		}
2442
2443		fn submit_report_dispute_lost(
2444			dispute_proof: slashing::DisputeProof,
2445			key_ownership_proof: slashing::OpaqueKeyOwnershipProof,
2446		) -> Option<()> {
2447			parachains_runtime_api_impl::submit_unsigned_slashing_report::<Runtime>(
2448				dispute_proof,
2449				key_ownership_proof,
2450			)
2451		}
2452
2453		fn minimum_backing_votes() -> u32 {
2454			parachains_runtime_api_impl::minimum_backing_votes::<Runtime>()
2455		}
2456
2457		fn para_backing_state(para_id: ParaId) -> Option<polkadot_primitives::async_backing::BackingState> {
2458			#[allow(deprecated)]
2459			parachains_runtime_api_impl::backing_state::<Runtime>(para_id)
2460		}
2461
2462		fn async_backing_params() -> polkadot_primitives::AsyncBackingParams {
2463			#[allow(deprecated)]
2464			parachains_runtime_api_impl::async_backing_params::<Runtime>()
2465		}
2466
2467		fn approval_voting_params() -> ApprovalVotingParams {
2468			parachains_runtime_api_impl::approval_voting_params::<Runtime>()
2469		}
2470
2471		fn disabled_validators() -> Vec<ValidatorIndex> {
2472			parachains_runtime_api_impl::disabled_validators::<Runtime>()
2473		}
2474
2475		fn node_features() -> NodeFeatures {
2476			parachains_runtime_api_impl::node_features::<Runtime>()
2477		}
2478
2479		fn claim_queue() -> BTreeMap<CoreIndex, VecDeque<ParaId>> {
2480			parachains_runtime_api_impl::claim_queue::<Runtime>()
2481		}
2482
2483		fn candidates_pending_availability(para_id: ParaId) -> Vec<CommittedCandidateReceipt<Hash>> {
2484			parachains_runtime_api_impl::candidates_pending_availability::<Runtime>(para_id)
2485		}
2486
2487		fn backing_constraints(para_id: ParaId) -> Option<Constraints> {
2488			parachains_runtime_api_impl::backing_constraints::<Runtime>(para_id)
2489		}
2490
2491		fn scheduling_lookahead() -> u32 {
2492			parachains_runtime_api_impl::scheduling_lookahead::<Runtime>()
2493		}
2494
2495		fn validation_code_bomb_limit() -> u32 {
2496			parachains_runtime_api_impl::validation_code_bomb_limit::<Runtime>()
2497		}
2498
2499		fn para_ids() -> Vec<ParaId> {
2500			parachains_staging_runtime_api_impl::para_ids::<Runtime>()
2501		}
2502
2503		fn max_relay_parent_session_age() -> u32 {
2504			parachains_staging_runtime_api_impl::max_relay_parent_session_age::<Runtime>()
2505		}
2506
2507		fn ancestor_relay_parent_info(
2508			session_index: SessionIndex,
2509			relay_parent: Hash,
2510		) -> Option<polkadot_primitives::vstaging::RelayParentInfo<Hash, BlockNumber>> {
2511			parachains_staging_runtime_api_impl::ancestor_relay_parent_info::<Runtime>(session_index, relay_parent)
2512		}
2513	}
2514
2515	#[api_version(6)]
2516	impl sp_consensus_beefy::BeefyApi<Block, BeefyId> for Runtime {
2517		fn beefy_genesis() -> Option<BlockNumber> {
2518			pallet_beefy::GenesisBlock::<Runtime>::get()
2519		}
2520
2521		fn validator_set() -> Option<sp_consensus_beefy::ValidatorSet<BeefyId>> {
2522			Beefy::validator_set()
2523		}
2524
2525		fn submit_report_double_voting_unsigned_extrinsic(
2526			equivocation_proof: sp_consensus_beefy::DoubleVotingProof<
2527				BlockNumber,
2528				BeefyId,
2529				BeefySignature,
2530			>,
2531			key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof,
2532		) -> Option<()> {
2533			let key_owner_proof = key_owner_proof.decode()?;
2534
2535			Beefy::submit_unsigned_double_voting_report(
2536				equivocation_proof,
2537				key_owner_proof,
2538			)
2539		}
2540
2541		fn submit_report_fork_voting_unsigned_extrinsic(
2542			equivocation_proof:
2543				sp_consensus_beefy::ForkVotingProof<
2544					<Block as BlockT>::Header,
2545					BeefyId,
2546					sp_runtime::OpaqueValue
2547				>,
2548			key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof,
2549		) -> Option<()> {
2550			Beefy::submit_unsigned_fork_voting_report(
2551				equivocation_proof.try_into()?,
2552				key_owner_proof.decode()?,
2553			)
2554		}
2555
2556		fn submit_report_future_block_voting_unsigned_extrinsic(
2557			equivocation_proof: sp_consensus_beefy::FutureBlockVotingProof<BlockNumber, BeefyId>,
2558			key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof,
2559		) -> Option<()> {
2560			Beefy::submit_unsigned_future_block_voting_report(
2561				equivocation_proof,
2562				key_owner_proof.decode()?,
2563			)
2564		}
2565
2566		fn generate_key_ownership_proof(
2567			_set_id: sp_consensus_beefy::ValidatorSetId,
2568			authority_id: BeefyId,
2569		) -> Option<sp_consensus_beefy::OpaqueKeyOwnershipProof> {
2570			use codec::Encode;
2571
2572			Historical::prove((sp_consensus_beefy::KEY_TYPE, authority_id))
2573				.map(|p| p.encode())
2574				.map(sp_consensus_beefy::OpaqueKeyOwnershipProof::new)
2575		}
2576	}
2577
2578	#[api_version(3)]
2579	impl mmr::MmrApi<Block, Hash, BlockNumber> for Runtime {
2580		fn mmr_root() -> Result<mmr::Hash, mmr::Error> {
2581			Ok(pallet_mmr::RootHash::<Runtime>::get())
2582		}
2583
2584		fn mmr_leaf_count() -> Result<mmr::LeafIndex, mmr::Error> {
2585			Ok(pallet_mmr::NumberOfLeaves::<Runtime>::get())
2586		}
2587
2588		fn generate_proof(
2589			block_numbers: Vec<BlockNumber>,
2590			best_known_block_number: Option<BlockNumber>,
2591		) -> Result<(Vec<mmr::EncodableOpaqueLeaf>, mmr::LeafProof<mmr::Hash>), mmr::Error> {
2592			Mmr::generate_proof(block_numbers, best_known_block_number).map(
2593				|(leaves, proof)| {
2594					(
2595						leaves
2596							.into_iter()
2597							.map(|leaf| mmr::EncodableOpaqueLeaf::from_leaf(&leaf))
2598							.collect(),
2599						proof,
2600					)
2601				},
2602			)
2603		}
2604
2605		fn generate_ancestry_proof(
2606			prev_block_number: BlockNumber,
2607			best_known_block_number: Option<BlockNumber>,
2608		) -> Result<mmr::AncestryProof<mmr::Hash>, mmr::Error> {
2609			Mmr::generate_ancestry_proof(prev_block_number, best_known_block_number)
2610		}
2611
2612		fn verify_proof(leaves: Vec<mmr::EncodableOpaqueLeaf>, proof: mmr::LeafProof<mmr::Hash>)
2613			-> Result<(), mmr::Error>
2614		{
2615			let leaves = leaves.into_iter().map(|leaf|
2616				leaf.into_opaque_leaf()
2617				.try_decode()
2618				.ok_or(mmr::Error::Verify)).collect::<Result<Vec<mmr::Leaf>, mmr::Error>>()?;
2619			Mmr::verify_leaves(leaves, proof)
2620		}
2621
2622		fn verify_proof_stateless(
2623			root: mmr::Hash,
2624			leaves: Vec<mmr::EncodableOpaqueLeaf>,
2625			proof: mmr::LeafProof<mmr::Hash>
2626		) -> Result<(), mmr::Error> {
2627			let nodes = leaves.into_iter().map(|leaf|mmr::DataOrHash::Data(leaf.into_opaque_leaf())).collect();
2628			pallet_mmr::verify_leaves_proof::<mmr::Hashing, _>(root, nodes, proof)
2629		}
2630	}
2631
2632	impl pallet_beefy_mmr::BeefyMmrApi<Block, Hash> for RuntimeApi {
2633		fn authority_set_proof() -> sp_consensus_beefy::mmr::BeefyAuthoritySet<Hash> {
2634			BeefyMmrLeaf::authority_set_proof()
2635		}
2636
2637		fn next_authority_set_proof() -> sp_consensus_beefy::mmr::BeefyNextAuthoritySet<Hash> {
2638			BeefyMmrLeaf::next_authority_set_proof()
2639		}
2640	}
2641
2642	impl fg_primitives::GrandpaApi<Block> for Runtime {
2643		fn grandpa_authorities() -> Vec<(GrandpaId, u64)> {
2644			Grandpa::grandpa_authorities()
2645		}
2646
2647		fn current_set_id() -> fg_primitives::SetId {
2648			pallet_grandpa::CurrentSetId::<Runtime>::get()
2649		}
2650
2651		fn submit_report_equivocation_unsigned_extrinsic(
2652			equivocation_proof: fg_primitives::EquivocationProof<
2653				<Block as BlockT>::Hash,
2654				sp_runtime::traits::NumberFor<Block>,
2655			>,
2656			key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,
2657		) -> Option<()> {
2658			let key_owner_proof = key_owner_proof.decode()?;
2659
2660			Grandpa::submit_unsigned_equivocation_report(
2661				equivocation_proof,
2662				key_owner_proof,
2663			)
2664		}
2665
2666		fn generate_key_ownership_proof(
2667			_set_id: fg_primitives::SetId,
2668			authority_id: fg_primitives::AuthorityId,
2669		) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {
2670			use codec::Encode;
2671
2672			Historical::prove((fg_primitives::KEY_TYPE, authority_id))
2673				.map(|p| p.encode())
2674				.map(fg_primitives::OpaqueKeyOwnershipProof::new)
2675		}
2676	}
2677
2678	impl sp_consensus_babe::BabeApi<Block> for Runtime {
2679		fn configuration() -> sp_consensus_babe::BabeConfiguration {
2680			let epoch_config = Babe::epoch_config().unwrap_or(BABE_GENESIS_EPOCH_CONFIG);
2681			sp_consensus_babe::BabeConfiguration {
2682				slot_duration: Babe::slot_duration(),
2683				epoch_length: EpochDuration::get(),
2684				c: epoch_config.c,
2685				authorities: Babe::authorities().to_vec(),
2686				randomness: Babe::randomness(),
2687				allowed_slots: epoch_config.allowed_slots,
2688			}
2689		}
2690
2691		fn current_epoch_start() -> sp_consensus_babe::Slot {
2692			Babe::current_epoch_start()
2693		}
2694
2695		fn current_epoch() -> sp_consensus_babe::Epoch {
2696			Babe::current_epoch()
2697		}
2698
2699		fn next_epoch() -> sp_consensus_babe::Epoch {
2700			Babe::next_epoch()
2701		}
2702
2703		fn generate_key_ownership_proof(
2704			_slot: sp_consensus_babe::Slot,
2705			authority_id: sp_consensus_babe::AuthorityId,
2706		) -> Option<sp_consensus_babe::OpaqueKeyOwnershipProof> {
2707			use codec::Encode;
2708
2709			Historical::prove((sp_consensus_babe::KEY_TYPE, authority_id))
2710				.map(|p| p.encode())
2711				.map(sp_consensus_babe::OpaqueKeyOwnershipProof::new)
2712		}
2713
2714		fn submit_report_equivocation_unsigned_extrinsic(
2715			equivocation_proof: sp_consensus_babe::EquivocationProof<<Block as BlockT>::Header>,
2716			key_owner_proof: sp_consensus_babe::OpaqueKeyOwnershipProof,
2717		) -> Option<()> {
2718			let key_owner_proof = key_owner_proof.decode()?;
2719
2720			Babe::submit_unsigned_equivocation_report(
2721				equivocation_proof,
2722				key_owner_proof,
2723			)
2724		}
2725	}
2726
2727	impl sp_authority_discovery::AuthorityDiscoveryApi<Block> for Runtime {
2728		fn authorities() -> Vec<AuthorityDiscoveryId> {
2729			parachains_runtime_api_impl::relevant_authority_ids::<Runtime>()
2730		}
2731	}
2732
2733	impl sp_session::SessionKeys<Block> for Runtime {
2734		fn generate_session_keys(owner: Vec<u8>, seed: Option<Vec<u8>>) -> sp_session::OpaqueGeneratedSessionKeys {
2735			SessionKeys::generate(&owner, seed).into()
2736		}
2737
2738		fn decode_session_keys(
2739			encoded: Vec<u8>,
2740		) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
2741			SessionKeys::decode_into_raw_public_keys(&encoded)
2742		}
2743	}
2744
2745	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
2746		fn account_nonce(account: AccountId) -> Nonce {
2747			System::account_nonce(account)
2748		}
2749	}
2750
2751	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
2752		Block,
2753		Balance,
2754	> for Runtime {
2755		fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
2756			TransactionPayment::query_info(uxt, len)
2757		}
2758		fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {
2759			TransactionPayment::query_fee_details(uxt, len)
2760		}
2761		fn query_weight_to_fee(weight: Weight) -> Balance {
2762			TransactionPayment::weight_to_fee(weight)
2763		}
2764		fn query_length_to_fee(length: u32) -> Balance {
2765			TransactionPayment::length_to_fee(length)
2766		}
2767	}
2768
2769	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
2770		for Runtime
2771	{
2772		fn query_call_info(call: RuntimeCall, len: u32) -> RuntimeDispatchInfo<Balance> {
2773			TransactionPayment::query_call_info(call, len)
2774		}
2775		fn query_call_fee_details(call: RuntimeCall, len: u32) -> FeeDetails<Balance> {
2776			TransactionPayment::query_call_fee_details(call, len)
2777		}
2778		fn query_weight_to_fee(weight: Weight) -> Balance {
2779			TransactionPayment::weight_to_fee(weight)
2780		}
2781		fn query_length_to_fee(length: u32) -> Balance {
2782			TransactionPayment::length_to_fee(length)
2783		}
2784	}
2785
2786	impl xcm_runtime_apis::fees::XcmPaymentApi<Block> for Runtime {
2787		fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
2788			let acceptable_assets = vec![AssetId(xcm_config::TokenLocation::get())];
2789			XcmPallet::query_acceptable_payment_assets(xcm_version, acceptable_assets)
2790		}
2791
2792		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
2793			type Trader = <XcmConfig as xcm_executor::Config>::Trader;
2794			XcmPallet::query_weight_to_asset_fee::<Trader>(weight, asset)
2795		}
2796
2797		fn query_xcm_weight(message: VersionedXcm<()>) -> Result<Weight, XcmPaymentApiError> {
2798			XcmPallet::query_xcm_weight(message)
2799		}
2800
2801		fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>, asset_id: VersionedAssetId) -> Result<VersionedAssets, XcmPaymentApiError> {
2802			type AssetExchanger = <XcmConfig as xcm_executor::Config>::AssetExchanger;
2803			XcmPallet::query_delivery_fees::<AssetExchanger>(destination, message, asset_id)
2804		}
2805	}
2806
2807	impl xcm_runtime_apis::dry_run::DryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
2808		fn dry_run_call(origin: OriginCaller, call: RuntimeCall, result_xcms_version: XcmVersion) -> Result<CallDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
2809			XcmPallet::dry_run_call::<Runtime, xcm_config::XcmRouter, OriginCaller, RuntimeCall>(origin, call, result_xcms_version)
2810		}
2811
2812		fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
2813			XcmPallet::dry_run_xcm::<xcm_config::XcmRouter>(origin_location, xcm)
2814		}
2815	}
2816
2817	impl xcm_runtime_apis::conversions::LocationToAccountApi<Block, AccountId> for Runtime {
2818		fn convert_location(location: VersionedLocation) -> Result<
2819			AccountId,
2820			xcm_runtime_apis::conversions::Error
2821		> {
2822			xcm_runtime_apis::conversions::LocationToAccountHelper::<
2823				AccountId,
2824				xcm_config::LocationConverter,
2825			>::convert_location(location)
2826		}
2827	}
2828
2829	impl pallet_nomination_pools_runtime_api::NominationPoolsApi<
2830		Block,
2831		AccountId,
2832		Balance,
2833	> for Runtime {
2834		fn pending_rewards(member: AccountId) -> Balance {
2835			NominationPools::api_pending_rewards(member).unwrap_or_default()
2836		}
2837
2838		fn points_to_balance(pool_id: PoolId, points: Balance) -> Balance {
2839			NominationPools::api_points_to_balance(pool_id, points)
2840		}
2841
2842		fn balance_to_points(pool_id: PoolId, new_funds: Balance) -> Balance {
2843			NominationPools::api_balance_to_points(pool_id, new_funds)
2844		}
2845
2846		fn pool_pending_slash(pool_id: PoolId) -> Balance {
2847			NominationPools::api_pool_pending_slash(pool_id)
2848		}
2849
2850		fn member_pending_slash(member: AccountId) -> Balance {
2851			NominationPools::api_member_pending_slash(member)
2852		}
2853
2854		fn pool_needs_delegate_migration(pool_id: PoolId) -> bool {
2855			NominationPools::api_pool_needs_delegate_migration(pool_id)
2856		}
2857
2858		fn member_needs_delegate_migration(member: AccountId) -> bool {
2859			NominationPools::api_member_needs_delegate_migration(member)
2860		}
2861
2862		fn member_total_balance(member: AccountId) -> Balance {
2863			NominationPools::api_member_total_balance(member)
2864		}
2865
2866		fn pool_balance(pool_id: PoolId) -> Balance {
2867			NominationPools::api_pool_balance(pool_id)
2868		}
2869
2870		fn pool_accounts(pool_id: PoolId) -> (AccountId, AccountId) {
2871			NominationPools::api_pool_accounts(pool_id)
2872		}
2873	}
2874
2875	impl pallet_staking_runtime_api::StakingApi<Block, Balance, AccountId> for Runtime {
2876		fn nominations_quota(balance: Balance) -> u32 {
2877			Staking::api_nominations_quota(balance)
2878		}
2879
2880		fn eras_stakers_page_count(era: sp_staking::EraIndex, account: AccountId) -> sp_staking::Page {
2881			Staking::api_eras_stakers_page_count(era, account)
2882		}
2883
2884		fn pending_rewards(era: sp_staking::EraIndex, account: AccountId) -> bool {
2885			Staking::api_pending_rewards(era, account)
2886		}
2887	}
2888
2889	#[cfg(feature = "try-runtime")]
2890	impl frame_try_runtime::TryRuntime<Block> for Runtime {
2891		fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
2892			log::info!("try-runtime::on_runtime_upgrade westend.");
2893		  // TODO:: remove once https://github.com/paritytech/polkadot-sdk/issues/9442 is resolved.
2894			let excluded_pallets = vec![
2895				b"Staking".to_vec(),          // replaced by staking-async
2896				b"NominationPools".to_vec(),  // moved to AH
2897				b"FastUnstake".to_vec(),      // deprecated
2898				b"DelegatedStaking".to_vec(), // moved to AH
2899			];
2900			let config = frame_executive::TryRuntimeUpgradeConfig::new(checks)
2901				.with_try_state_select(frame_try_runtime::TryStateSelect::AllExcept(
2902					excluded_pallets,
2903				));
2904			let weight = Executive::try_runtime_upgrade_with_config(config).unwrap();
2905			(weight, BlockWeights::get().max_block)
2906		}
2907
2908		fn execute_block(
2909			block: <Block as BlockT>::LazyBlock,
2910			state_root_check: bool,
2911			signature_check: bool,
2912			select: frame_try_runtime::TryStateSelect,
2913		) -> Weight {
2914			// NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
2915			// have a backtrace here.
2916			Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()
2917		}
2918	}
2919
2920	#[cfg(feature = "runtime-benchmarks")]
2921	impl frame_benchmarking::Benchmark<Block> for Runtime {
2922		fn benchmark_metadata(extra: bool) -> (
2923			Vec<frame_benchmarking::BenchmarkList>,
2924			Vec<frame_support::traits::StorageInfo>,
2925		) {
2926			use frame_benchmarking::BenchmarkList;
2927			use frame_support::traits::StorageInfoTrait;
2928
2929			use pallet_session_benchmarking::Pallet as SessionBench;
2930			use pallet_offences_benchmarking::Pallet as OffencesBench;
2931			use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench;
2932			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
2933			use frame_system_benchmarking::Pallet as SystemBench;
2934			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
2935
2936			type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
2937			type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::<Runtime>;
2938
2939			let mut list = Vec::<BenchmarkList>::new();
2940			list_benchmarks!(list, extra);
2941
2942			let storage_info = AllPalletsWithSystem::storage_info();
2943			return (list, storage_info)
2944		}
2945
2946		#[allow(non_local_definitions)]
2947		fn dispatch_benchmark(
2948			config: frame_benchmarking::BenchmarkConfig,
2949		) -> Result<
2950			Vec<frame_benchmarking::BenchmarkBatch>,
2951			alloc::string::String,
2952		> {
2953			use frame_support::traits::WhitelistedStorageKeys;
2954			use frame_benchmarking::{BenchmarkBatch, BenchmarkError};
2955			use sp_storage::TrackedStorageKey;
2956			// Trying to add benchmarks directly to some pallets caused cyclic dependency issues.
2957			// To get around that, we separated the benchmarks into its own crate.
2958			use pallet_session_benchmarking::Pallet as SessionBench;
2959			use pallet_offences_benchmarking::Pallet as OffencesBench;
2960			use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench;
2961			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
2962			use frame_system_benchmarking::Pallet as SystemBench;
2963			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
2964
2965			impl pallet_session_benchmarking::Config for Runtime {
2966				fn generate_session_keys_and_proof(owner: Self::AccountId) -> (Self::Keys, Vec<u8>) {
2967					let keys = SessionKeys::generate(&owner.encode(), None);
2968					(keys.keys, keys.proof.encode())
2969				}
2970			}
2971
2972			impl pallet_offences_benchmarking::Config for Runtime {}
2973			impl pallet_election_provider_support_benchmarking::Config for Runtime {}
2974
2975			use xcm_config::{AssetHub, TokenLocation};
2976
2977			use alloc::boxed::Box;
2978
2979			parameter_types! {
2980				pub ExistentialDepositAsset: Option<Asset> = Some((
2981					TokenLocation::get(),
2982					ExistentialDeposit::get()
2983				).into());
2984				pub AssetHubParaId: ParaId = westend_runtime_constants::system_parachain::ASSET_HUB_ID.into();
2985				pub const RandomParaId: ParaId = ParaId::new(43211234);
2986			}
2987
2988			impl pallet_xcm::benchmarking::Config for Runtime {
2989				type DeliveryHelper = (
2990					polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
2991						xcm_config::XcmConfig,
2992						ExistentialDepositAsset,
2993						xcm_config::PriceForChildParachainDelivery,
2994						AssetHubParaId,
2995						Dmp,
2996					>,
2997					polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
2998						xcm_config::XcmConfig,
2999						ExistentialDepositAsset,
3000						xcm_config::PriceForChildParachainDelivery,
3001						RandomParaId,
3002						Dmp,
3003					>
3004				);
3005
3006				fn reachable_dest() -> Option<Location> {
3007					Some(crate::xcm_config::AssetHub::get())
3008				}
3009
3010				fn teleportable_asset_and_dest() -> Option<(Asset, Location)> {
3011					// Relay/native token can be teleported to/from AH.
3012					Some((
3013						Asset { fun: Fungible(ExistentialDeposit::get()), id: AssetId(Here.into()) },
3014						crate::xcm_config::AssetHub::get(),
3015					))
3016				}
3017
3018				fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
3019					None
3020				}
3021
3022				fn set_up_complex_asset_transfer(
3023				) -> Option<(Assets, u32, Location, Box<dyn FnOnce()>)> {
3024					// Relay supports only native token, either reserve transfer it to non-system parachains,
3025					// or teleport it to system parachain. Use the teleport case for benchmarking as it's
3026					// slightly heavier.
3027
3028					// Relay/native token can be teleported to/from AH.
3029					let native_location = Here.into();
3030					let dest = crate::xcm_config::AssetHub::get();
3031					pallet_xcm::benchmarking::helpers::native_teleport_as_asset_transfer::<Runtime>(
3032						native_location,
3033						dest
3034					)
3035				}
3036
3037				fn get_asset() -> Asset {
3038					Asset {
3039						id: AssetId(Location::here()),
3040						fun: Fungible(ExistentialDeposit::get()),
3041					}
3042				}
3043			}
3044			impl frame_system_benchmarking::Config for Runtime {}
3045			impl pallet_transaction_payment::BenchmarkConfig for Runtime {}
3046			impl polkadot_runtime_parachains::disputes::slashing::benchmarking::Config for Runtime {}
3047
3048			use xcm::latest::{
3049				AssetId, Fungibility::*, InteriorLocation, Junction, Junctions::*,
3050				Asset, Assets, Location, NetworkId, Response,
3051			};
3052
3053			impl pallet_xcm_benchmarks::Config for Runtime {
3054				type XcmConfig = xcm_config::XcmConfig;
3055				type AccountIdConverter = xcm_config::LocationConverter;
3056				type DeliveryHelper = polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
3057					xcm_config::XcmConfig,
3058					ExistentialDepositAsset,
3059					xcm_config::PriceForChildParachainDelivery,
3060					AssetHubParaId,
3061					Dmp,
3062				>;
3063				fn valid_destination() -> Result<Location, BenchmarkError> {
3064					Ok(AssetHub::get())
3065				}
3066				fn worst_case_holding(_depositable_count: u32) -> xcm_executor::AssetsInHolding {
3067					use pallet_xcm_benchmarks::MockCredit;
3068					// Westend only knows about WND.
3069					let mut holding = xcm_executor::AssetsInHolding::new();
3070					holding.fungible.insert(
3071						AssetId(TokenLocation::get()),
3072						alloc::boxed::Box::new(MockCredit(1_000_000 * UNITS)),
3073					);
3074					holding
3075				}
3076			}
3077
3078			parameter_types! {
3079				pub TrustedTeleporter: Option<(Location, Asset)> = Some((
3080					AssetHub::get(),
3081					Asset { fun: Fungible(1 * UNITS), id: AssetId(TokenLocation::get()) },
3082				));
3083				pub const TrustedReserve: Option<(Location, Asset)> = None;
3084				pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None;
3085			}
3086
3087			impl pallet_xcm_benchmarks::fungible::Config for Runtime {
3088				type TransactAsset = Balances;
3089
3090				type CheckedAccount = CheckedAccount;
3091				type TrustedTeleporter = TrustedTeleporter;
3092				type TrustedReserve = TrustedReserve;
3093
3094				fn get_asset() -> Asset {
3095					Asset {
3096						id: AssetId(TokenLocation::get()),
3097						fun: Fungible(1 * UNITS),
3098					}
3099				}
3100			}
3101
3102			impl pallet_xcm_benchmarks::generic::Config for Runtime {
3103				type TransactAsset = Balances;
3104				type RuntimeCall = RuntimeCall;
3105
3106				fn worst_case_response() -> (u64, Response) {
3107					(0u64, Response::Version(Default::default()))
3108				}
3109
3110				fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> {
3111					// Westend doesn't support asset exchanges
3112					Err(BenchmarkError::Skip)
3113				}
3114
3115				fn universal_alias() -> Result<(Location, Junction), BenchmarkError> {
3116					// The XCM executor of Westend doesn't have a configured `UniversalAliases`
3117					Err(BenchmarkError::Skip)
3118				}
3119
3120				fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> {
3121					Ok((AssetHub::get(), frame_system::Call::remark_with_event { remark: vec![] }.into()))
3122				}
3123
3124				fn subscribe_origin() -> Result<Location, BenchmarkError> {
3125					Ok(AssetHub::get())
3126				}
3127
3128				fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> {
3129					let origin = AssetHub::get();
3130					let assets: Assets = (AssetId(TokenLocation::get()), 1_000 * UNITS).into();
3131					let ticket = Location { parents: 0, interior: Here };
3132					Ok((origin, ticket, assets))
3133				}
3134
3135				fn worst_case_for_trader() -> Result<(Asset, WeightLimit), BenchmarkError> {
3136					Ok((Asset {
3137						id: AssetId(TokenLocation::get()),
3138						fun: Fungible(1_000_000 * UNITS),
3139					}, WeightLimit::Limited(Weight::from_parts(5000, 5000))))
3140				}
3141
3142				fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> {
3143					// Westend doesn't support asset locking
3144					Err(BenchmarkError::Skip)
3145				}
3146
3147				fn export_message_origin_and_destination(
3148				) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> {
3149					// Westend doesn't support exporting messages
3150					Err(BenchmarkError::Skip)
3151				}
3152
3153				fn alias_origin() -> Result<(Location, Location), BenchmarkError> {
3154					let origin = Location::new(0, [Parachain(1000)]);
3155					let target = Location::new(0, [Parachain(1000), AccountId32 { id: [128u8; 32], network: None }]);
3156					Ok((origin, target))
3157				}
3158			}
3159
3160			type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
3161			type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::<Runtime>;
3162
3163			let whitelist: Vec<TrackedStorageKey> = AllPalletsWithSystem::whitelisted_storage_keys();
3164
3165			let mut batches = Vec::<BenchmarkBatch>::new();
3166			let params = (&config, &whitelist);
3167
3168			add_benchmarks!(params, batches);
3169
3170			Ok(batches)
3171		}
3172	}
3173
3174	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
3175		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
3176			build_state::<RuntimeGenesisConfig>(config)
3177		}
3178
3179		fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
3180			get_preset::<RuntimeGenesisConfig>(id, &genesis_config_presets::get_preset)
3181		}
3182
3183		fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
3184			genesis_config_presets::preset_names()
3185		}
3186	}
3187
3188	impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
3189		fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
3190			XcmPallet::is_trusted_reserve(asset, location)
3191		}
3192		fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
3193			XcmPallet::is_trusted_teleporter(asset, location)
3194		}
3195	}
3196}