referrerpolicy=no-referrer-when-downgrade

westend_runtime/
lib.rs

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