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