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_025_002,
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 = parachains_reward_points::RewardValidatorsWithEraPoints<
1065		Runtime,
1066		StakingAhClient,
1067		ConstU32<20>,
1068	>;
1069	type MessageQueue = MessageQueue;
1070	type WeightInfo = weights::polkadot_runtime_parachains_inclusion::WeightInfo<Runtime>;
1071}
1072
1073parameter_types! {
1074	pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
1075}
1076
1077impl parachains_paras::Config for Runtime {
1078	type RuntimeEvent = RuntimeEvent;
1079	type WeightInfo = weights::polkadot_runtime_parachains_paras::WeightInfo<Runtime>;
1080	type UnsignedPriority = ParasUnsignedPriority;
1081	type QueueFootprinter = ParaInclusion;
1082	type NextSessionRotation = Babe;
1083	type OnNewHead = ();
1084	type AssignCoretime = ParaScheduler;
1085	type Fungible = Balances;
1086	// Per day the cooldown is removed earlier, it should cost 1000.
1087	type CooldownRemovalMultiplier = ConstUint<{ 1000 * UNITS / DAYS as u128 }>;
1088	type AuthorizeCurrentCodeOrigin = EnsureRoot<AccountId>;
1089}
1090
1091parameter_types! {
1092	/// Amount of weight that can be spent per block to service messages.
1093	///
1094	/// # WARNING
1095	///
1096	/// This is not a good value for para-chains since the `Scheduler` already uses up to 80% block weight.
1097	pub MessageQueueServiceWeight: Weight = Perbill::from_percent(20) * BlockWeights::get().max_block;
1098	pub const MessageQueueHeapSize: u32 = 128 * 1024;
1099	pub const MessageQueueMaxStale: u32 = 48;
1100}
1101
1102/// Message processor to handle any messages that were enqueued into the `MessageQueue` pallet.
1103pub struct MessageProcessor;
1104impl ProcessMessage for MessageProcessor {
1105	type Origin = AggregateMessageOrigin;
1106
1107	fn process_message(
1108		message: &[u8],
1109		origin: Self::Origin,
1110		meter: &mut WeightMeter,
1111		id: &mut [u8; 32],
1112	) -> Result<bool, ProcessMessageError> {
1113		let para = match origin {
1114			AggregateMessageOrigin::Ump(UmpQueueId::Para(para)) => para,
1115		};
1116		xcm_builder::ProcessXcmMessage::<
1117			Junction,
1118			xcm_executor::XcmExecutor<xcm_config::XcmConfig>,
1119			RuntimeCall,
1120		>::process_message(message, Junction::Parachain(para.into()), meter, id)
1121	}
1122}
1123
1124impl pallet_message_queue::Config for Runtime {
1125	type RuntimeEvent = RuntimeEvent;
1126	type Size = u32;
1127	type HeapSize = MessageQueueHeapSize;
1128	type MaxStale = MessageQueueMaxStale;
1129	type ServiceWeight = MessageQueueServiceWeight;
1130	type IdleMaxServiceWeight = MessageQueueServiceWeight;
1131	#[cfg(not(feature = "runtime-benchmarks"))]
1132	type MessageProcessor = MessageProcessor;
1133	#[cfg(feature = "runtime-benchmarks")]
1134	type MessageProcessor =
1135		pallet_message_queue::mock_helpers::NoopMessageProcessor<AggregateMessageOrigin>;
1136	type QueueChangeHandler = ParaInclusion;
1137	type QueuePausedQuery = ();
1138	type WeightInfo = weights::pallet_message_queue::WeightInfo<Runtime>;
1139}
1140
1141impl parachains_dmp::Config for Runtime {
1142	type WeightInfo = ();
1143}
1144
1145parameter_types! {
1146	pub const HrmpChannelSizeAndCapacityWithSystemRatio: Percent = Percent::from_percent(100);
1147}
1148
1149impl parachains_hrmp::Config for Runtime {
1150	type RuntimeOrigin = RuntimeOrigin;
1151	type RuntimeEvent = RuntimeEvent;
1152	type ChannelManager = EnsureRoot<AccountId>;
1153	type Currency = Balances;
1154	type DepositProvider = Hrmp;
1155	type DefaultChannelSizeAndCapacityWithSystem = ActiveConfigHrmpChannelSizeAndCapacityRatio<
1156		Runtime,
1157		HrmpChannelSizeAndCapacityWithSystemRatio,
1158	>;
1159	type VersionWrapper = crate::XcmPallet;
1160	type WeightInfo = weights::polkadot_runtime_parachains_hrmp::WeightInfo<Self>;
1161}
1162
1163impl parachains_paras_inherent::Config for Runtime {
1164	type WeightInfo = weights::polkadot_runtime_parachains_paras_inherent::WeightInfo<Runtime>;
1165}
1166
1167impl parachains_scheduler::Config for Runtime {}
1168
1169parameter_types! {
1170	pub const BrokerId: u32 = BROKER_ID;
1171	pub const BrokerPalletId: PalletId = PalletId(*b"py/broke");
1172	pub MaxXcmTransactWeight: Weight = Weight::from_parts(200_000_000, 20_000);
1173}
1174
1175pub struct BrokerPot;
1176impl Get<InteriorLocation> for BrokerPot {
1177	fn get() -> InteriorLocation {
1178		Junction::AccountId32 { network: None, id: BrokerPalletId::get().into_account_truncating() }
1179			.into()
1180	}
1181}
1182
1183impl coretime::Config for Runtime {
1184	type RuntimeOrigin = RuntimeOrigin;
1185	type RuntimeEvent = RuntimeEvent;
1186	type BrokerId = BrokerId;
1187	type BrokerPotLocation = BrokerPot;
1188	type WeightInfo = weights::polkadot_runtime_parachains_coretime::WeightInfo<Runtime>;
1189	type SendXcm = crate::xcm_config::XcmRouter;
1190	type AssetTransactor = crate::xcm_config::LocalAssetTransactor;
1191	type AccountToLocation = xcm_builder::AliasesIntoAccountId32<
1192		xcm_config::ThisNetwork,
1193		<Runtime as frame_system::Config>::AccountId,
1194	>;
1195	type MaxXcmTransactWeight = MaxXcmTransactWeight;
1196}
1197
1198parameter_types! {
1199	pub const OnDemandTrafficDefaultValue: FixedU128 = FixedU128::from_u32(1);
1200	// Keep 2 timeslices worth of revenue information.
1201	pub const MaxHistoricalRevenue: BlockNumber = 2 * TIMESLICE_PERIOD;
1202	pub const OnDemandPalletId: PalletId = PalletId(*b"py/ondmd");
1203}
1204
1205impl parachains_on_demand::Config for Runtime {
1206	type RuntimeEvent = RuntimeEvent;
1207	type Currency = Balances;
1208	type TrafficDefaultValue = OnDemandTrafficDefaultValue;
1209	type WeightInfo = weights::polkadot_runtime_parachains_on_demand::WeightInfo<Runtime>;
1210	type MaxHistoricalRevenue = MaxHistoricalRevenue;
1211	type PalletId = OnDemandPalletId;
1212}
1213
1214impl parachains_initializer::Config for Runtime {
1215	type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
1216	type ForceOrigin = EnsureRoot<AccountId>;
1217	type WeightInfo = weights::polkadot_runtime_parachains_initializer::WeightInfo<Runtime>;
1218	type CoretimeOnNewSession = Coretime;
1219}
1220
1221impl paras_sudo_wrapper::Config for Runtime {}
1222
1223parameter_types! {
1224	pub const PermanentSlotLeasePeriodLength: u32 = 26;
1225	pub const TemporarySlotLeasePeriodLength: u32 = 1;
1226	pub const MaxTemporarySlotPerLeasePeriod: u32 = 5;
1227}
1228
1229impl assigned_slots::Config for Runtime {
1230	type RuntimeEvent = RuntimeEvent;
1231	type AssignSlotOrigin = EnsureRoot<AccountId>;
1232	type Leaser = Slots;
1233	type PermanentSlotLeasePeriodLength = PermanentSlotLeasePeriodLength;
1234	type TemporarySlotLeasePeriodLength = TemporarySlotLeasePeriodLength;
1235	type MaxTemporarySlotPerLeasePeriod = MaxTemporarySlotPerLeasePeriod;
1236	type WeightInfo = weights::polkadot_runtime_common_assigned_slots::WeightInfo<Runtime>;
1237}
1238
1239impl parachains_disputes::Config for Runtime {
1240	type RuntimeEvent = RuntimeEvent;
1241	type RewardValidators = parachains_reward_points::RewardValidatorsWithEraPoints<
1242		Runtime,
1243		StakingAhClient,
1244		ConstU32<20>,
1245	>;
1246	type SlashingHandler = parachains_slashing::SlashValidatorsForDisputes<ParasSlashing>;
1247	type WeightInfo = weights::polkadot_runtime_parachains_disputes::WeightInfo<Runtime>;
1248}
1249
1250impl parachains_slashing::Config for Runtime {
1251	type KeyOwnerProofSystem = Historical;
1252	type KeyOwnerProof =
1253		<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, ValidatorId)>>::Proof;
1254	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
1255		KeyTypeId,
1256		ValidatorId,
1257	)>>::IdentificationTuple;
1258	type HandleReports = parachains_slashing::SlashingReportHandler<
1259		Self::KeyOwnerIdentification,
1260		Offences,
1261		ReportLongevity,
1262	>;
1263	type WeightInfo = weights::polkadot_runtime_parachains_disputes_slashing::WeightInfo<Runtime>;
1264	type BenchmarkingConfig = parachains_slashing::BenchConfig<300>;
1265}
1266
1267parameter_types! {
1268	pub const ParaDeposit: Balance = 2000 * CENTS;
1269	pub const RegistrarDataDepositPerByte: Balance = deposit(0, 1);
1270}
1271
1272impl paras_registrar::Config for Runtime {
1273	type RuntimeOrigin = RuntimeOrigin;
1274	type RuntimeEvent = RuntimeEvent;
1275	type Currency = Balances;
1276	type OnSwap = (Crowdloan, Slots, SwapLeases);
1277	type ParaDeposit = ParaDeposit;
1278	type DataDepositPerByte = RegistrarDataDepositPerByte;
1279	type WeightInfo = weights::polkadot_runtime_common_paras_registrar::WeightInfo<Runtime>;
1280}
1281
1282parameter_types! {
1283	pub const LeasePeriod: BlockNumber = 28 * DAYS;
1284}
1285
1286impl slots::Config for Runtime {
1287	type RuntimeEvent = RuntimeEvent;
1288	type Currency = Balances;
1289	type Registrar = Registrar;
1290	type LeasePeriod = LeasePeriod;
1291	type LeaseOffset = ();
1292	type ForceOrigin = EnsureRoot<Self::AccountId>;
1293	type WeightInfo = weights::polkadot_runtime_common_slots::WeightInfo<Runtime>;
1294}
1295
1296parameter_types! {
1297	pub const CrowdloanId: PalletId = PalletId(*b"py/cfund");
1298	pub const SubmissionDeposit: Balance = 100 * 100 * CENTS;
1299	pub const MinContribution: Balance = 100 * CENTS;
1300	pub const RemoveKeysLimit: u32 = 500;
1301	// Allow 32 bytes for an additional memo to a crowdloan.
1302	pub const MaxMemoLength: u8 = 32;
1303}
1304
1305impl crowdloan::Config for Runtime {
1306	type RuntimeEvent = RuntimeEvent;
1307	type PalletId = CrowdloanId;
1308	type SubmissionDeposit = SubmissionDeposit;
1309	type MinContribution = MinContribution;
1310	type RemoveKeysLimit = RemoveKeysLimit;
1311	type Registrar = Registrar;
1312	type Auctioneer = Auctions;
1313	type MaxMemoLength = MaxMemoLength;
1314	type WeightInfo = weights::polkadot_runtime_common_crowdloan::WeightInfo<Runtime>;
1315}
1316
1317parameter_types! {
1318	// The average auction is 7 days long, so this will be 70% for ending period.
1319	// 5 Days = 72000 Blocks @ 6 sec per block
1320	pub const EndingPeriod: BlockNumber = 5 * DAYS;
1321	// ~ 1000 samples per day -> ~ 20 blocks per sample -> 2 minute samples
1322	pub const SampleLength: BlockNumber = 2 * MINUTES;
1323}
1324
1325impl auctions::Config for Runtime {
1326	type RuntimeEvent = RuntimeEvent;
1327	type Leaser = Slots;
1328	type Registrar = Registrar;
1329	type EndingPeriod = EndingPeriod;
1330	type SampleLength = SampleLength;
1331	type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
1332	type InitiateOrigin = EnsureRoot<Self::AccountId>;
1333	type WeightInfo = weights::polkadot_runtime_common_auctions::WeightInfo<Runtime>;
1334}
1335
1336impl identity_migrator::Config for Runtime {
1337	type RuntimeEvent = RuntimeEvent;
1338	type Reaper = EnsureSigned<AccountId>;
1339	type ReapIdentityHandler = ToParachainIdentityReaper<Runtime, Self::AccountId>;
1340	type WeightInfo = weights::polkadot_runtime_common_identity_migrator::WeightInfo<Runtime>;
1341}
1342
1343impl pallet_root_testing::Config for Runtime {
1344	type RuntimeEvent = RuntimeEvent;
1345}
1346
1347impl pallet_root_offences::Config for Runtime {
1348	type RuntimeEvent = RuntimeEvent;
1349	type OffenceHandler = StakingAhClient;
1350	type ReportOffence = Offences;
1351}
1352
1353impl pallet_accumulate_and_forward::Config for Runtime {
1354	type Currency = Balances;
1355	type PalletId = AccumulateForwardPalletId;
1356	type Forwarder = xcm_builder::TeleportForwarderForAccountId32<
1357		xcm_config::XcmConfig,
1358		xcm_config::AssetHub,
1359		xcm_config::TokenLocation,
1360		DapStagingLocation,
1361	>;
1362	type TransferPeriod = ForwardPeriod;
1363	type MinTransferAmount = MinForwardAmount;
1364	type BlockNumberProvider = frame_system::Pallet<Runtime>;
1365	type WeightInfo = weights::pallet_accumulate_and_forward::WeightInfo<Runtime>;
1366}
1367
1368parameter_types! {
1369	pub MbmServiceWeight: Weight = Perbill::from_percent(80) * BlockWeights::get().max_block;
1370}
1371
1372impl pallet_migrations::Config for Runtime {
1373	type RuntimeEvent = RuntimeEvent;
1374	#[cfg(not(feature = "runtime-benchmarks"))]
1375	type Migrations = (
1376		pallet_identity::migration::v2::LazyMigrationV1ToV2<Runtime>,
1377		parachains_dmp::migration::MigrateV0ToV1<Runtime>,
1378	);
1379	// Benchmarks need mocked migrations to guarantee that they succeed.
1380	#[cfg(feature = "runtime-benchmarks")]
1381	type Migrations = pallet_migrations::mock_helpers::MockedMigrations;
1382	type CursorMaxLen = ConstU32<65_536>;
1383	type IdentifierMaxLen = ConstU32<256>;
1384	type MigrationStatusHandler = ();
1385	type FailedMigrationHandler = frame_support::migrations::FreezeChainOnFailedMigration;
1386	type MaxServiceWeight = MbmServiceWeight;
1387	type WeightInfo = weights::pallet_migrations::WeightInfo<Runtime>;
1388}
1389
1390parameter_types! {
1391	// 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)
1392	pub const MigrationSignedDepositPerItem: Balance = 1 * CENTS;
1393	pub const MigrationSignedDepositBase: Balance = 20 * CENTS * 100;
1394	pub const MigrationMaxKeyLen: u32 = 512;
1395}
1396
1397impl pallet_asset_rate::Config for Runtime {
1398	type WeightInfo = weights::pallet_asset_rate::WeightInfo<Runtime>;
1399	type RuntimeEvent = RuntimeEvent;
1400	type CreateOrigin = EnsureRoot<AccountId>;
1401	type RemoveOrigin = EnsureRoot<AccountId>;
1402	type UpdateOrigin = EnsureRoot<AccountId>;
1403	type Currency = Balances;
1404	type AssetKind = VersionedLocatableAsset;
1405	#[cfg(feature = "runtime-benchmarks")]
1406	type BenchmarkHelper = polkadot_runtime_common::impls::benchmarks::AssetRateArguments;
1407}
1408
1409// Notify `coretime` pallet when a lease swap occurs
1410pub struct SwapLeases;
1411impl OnSwap for SwapLeases {
1412	fn on_swap(one: ParaId, other: ParaId) {
1413		coretime::Pallet::<Runtime>::on_legacy_lease_swap(one, other);
1414	}
1415}
1416
1417/// Minimal stub pallet preserving `RuntimeHoldReason::DelegatedStaking(StakingDelegation)`
1418/// encoding (pallet_index 38, codec index 0) for existing on-chain holds created by the
1419/// now-removed `pallet_delegated_staking`. Enables `try_decode_entire_state` to succeed
1420/// until all holds are migrated away. Remove once Westend storage is clean.
1421pub mod delegated_staking_stub {
1422	pub use pallet::*;
1423
1424	#[frame_support::pallet]
1425	pub mod pallet {
1426		#[pallet::pallet]
1427		pub struct Pallet<T>(_);
1428
1429		#[pallet::config]
1430		pub trait Config: frame_system::Config {}
1431
1432		#[pallet::composite_enum]
1433		pub enum HoldReason {
1434			#[codec(index = 0)]
1435			StakingDelegation,
1436		}
1437	}
1438}
1439
1440impl delegated_staking_stub::pallet::Config for Runtime {}
1441
1442#[frame_support::runtime(legacy_ordering)]
1443mod runtime {
1444	#[runtime::runtime]
1445	#[runtime::derive(
1446		RuntimeCall,
1447		RuntimeEvent,
1448		RuntimeError,
1449		RuntimeOrigin,
1450		RuntimeFreezeReason,
1451		RuntimeHoldReason,
1452		RuntimeSlashReason,
1453		RuntimeLockId,
1454		RuntimeTask,
1455		RuntimeViewFunction
1456	)]
1457	pub struct Runtime;
1458
1459	// Basic stuff; balances is uncallable initially.
1460	#[runtime::pallet_index(0)]
1461	pub type System = frame_system;
1462
1463	// Babe must be before session.
1464	#[runtime::pallet_index(1)]
1465	pub type Babe = pallet_babe;
1466
1467	#[runtime::pallet_index(2)]
1468	pub type Timestamp = pallet_timestamp;
1469	#[runtime::pallet_index(3)]
1470	pub type Indices = pallet_indices;
1471	#[runtime::pallet_index(4)]
1472	pub type Balances = pallet_balances;
1473	#[runtime::pallet_index(26)]
1474	pub type TransactionPayment = pallet_transaction_payment;
1475	// AccumulateForward - collects funds for periodic forwarding to DAP on AssetHub
1476	#[runtime::pallet_index(106)]
1477	pub type AccumulateForward = pallet_accumulate_and_forward;
1478
1479	// Consensus support.
1480	// Authorship must be before session in order to note author in the correct session and era.
1481	#[runtime::pallet_index(5)]
1482	pub type Authorship = pallet_authorship;
1483	#[runtime::pallet_index(7)]
1484	pub type Offences = pallet_offences;
1485	#[runtime::pallet_index(27)]
1486	pub type Historical = session_historical;
1487	#[runtime::pallet_index(70)]
1488	pub type Parameters = pallet_parameters;
1489
1490	#[runtime::pallet_index(8)]
1491	pub type Session = pallet_session;
1492	#[runtime::pallet_index(10)]
1493	pub type Grandpa = pallet_grandpa;
1494	#[runtime::pallet_index(12)]
1495	pub type AuthorityDiscovery = pallet_authority_discovery;
1496
1497	// Utility module.
1498	#[runtime::pallet_index(16)]
1499	pub type Utility = pallet_utility;
1500
1501	// Less simple identity module.
1502	#[runtime::pallet_index(17)]
1503	pub type Identity = pallet_identity;
1504
1505	// Vesting. Usable initially, but removed once all vesting is finished.
1506	#[runtime::pallet_index(19)]
1507	pub type Vesting = pallet_vesting;
1508
1509	// System scheduler.
1510	#[runtime::pallet_index(20)]
1511	pub type Scheduler = pallet_scheduler;
1512
1513	// Preimage registrar.
1514	#[runtime::pallet_index(28)]
1515	pub type Preimage = pallet_preimage;
1516
1517	// Sudo.
1518	#[runtime::pallet_index(21)]
1519	pub type Sudo = pallet_sudo;
1520
1521	// Proxy module. Late addition.
1522	#[runtime::pallet_index(22)]
1523	pub type Proxy = pallet_proxy;
1524
1525	// Multisig module. Late addition.
1526	#[runtime::pallet_index(23)]
1527	pub type Multisig = pallet_multisig;
1528
1529	// Stub preserving RuntimeHoldReason::DelegatedStaking encoding for on-chain holds left by
1530	// the removed pallet_delegated_staking. Remove once Westend storage is clean.
1531	#[runtime::pallet_index(38)]
1532	pub type DelegatedStaking = delegated_staking_stub;
1533
1534	// Parachains pallets. Start indices at 40 to leave room.
1535	#[runtime::pallet_index(41)]
1536	pub type ParachainsOrigin = parachains_origin;
1537	#[runtime::pallet_index(42)]
1538	pub type Configuration = parachains_configuration;
1539	#[runtime::pallet_index(43)]
1540	pub type ParasShared = parachains_shared;
1541	#[runtime::pallet_index(44)]
1542	pub type ParaInclusion = parachains_inclusion;
1543	#[runtime::pallet_index(45)]
1544	pub type ParaInherent = parachains_paras_inherent;
1545	#[runtime::pallet_index(46)]
1546	pub type ParaScheduler = parachains_scheduler;
1547	#[runtime::pallet_index(47)]
1548	pub type Paras = parachains_paras;
1549	#[runtime::pallet_index(48)]
1550	pub type Initializer = parachains_initializer;
1551	#[runtime::pallet_index(49)]
1552	pub type Dmp = parachains_dmp;
1553	// RIP Ump 50
1554	#[runtime::pallet_index(51)]
1555	pub type Hrmp = parachains_hrmp;
1556	#[runtime::pallet_index(52)]
1557	pub type ParaSessionInfo = parachains_session_info;
1558	#[runtime::pallet_index(53)]
1559	pub type ParasDisputes = parachains_disputes;
1560	#[runtime::pallet_index(54)]
1561	pub type ParasSlashing = parachains_slashing;
1562	#[runtime::pallet_index(56)]
1563	pub type OnDemandAssignmentProvider = parachains_on_demand;
1564	// RIP CoretimeAssignmentProvider 57 - Moved to scheduler::assigner_coretime submodule in PR
1565	// #10184 (Had no extrinsics nor events exposed)
1566
1567	// Parachain Onboarding Pallets. Start indices at 60 to leave room.
1568	#[runtime::pallet_index(60)]
1569	pub type Registrar = paras_registrar;
1570	#[runtime::pallet_index(61)]
1571	pub type Slots = slots;
1572	#[runtime::pallet_index(62)]
1573	pub type ParasSudoWrapper = paras_sudo_wrapper;
1574	#[runtime::pallet_index(63)]
1575	pub type Auctions = auctions;
1576	#[runtime::pallet_index(64)]
1577	pub type Crowdloan = crowdloan;
1578	#[runtime::pallet_index(65)]
1579	pub type AssignedSlots = assigned_slots;
1580	#[runtime::pallet_index(66)]
1581	pub type Coretime = coretime;
1582	#[runtime::pallet_index(67)]
1583	pub type StakingAhClient = pallet_staking_async_ah_client;
1584
1585	// Migrations pallet
1586	#[runtime::pallet_index(98)]
1587	pub type MultiBlockMigrations = pallet_migrations;
1588
1589	// Pallet for sending XCM.
1590	#[runtime::pallet_index(99)]
1591	pub type XcmPallet = pallet_xcm;
1592
1593	// Generalized message queue
1594	#[runtime::pallet_index(100)]
1595	pub type MessageQueue = pallet_message_queue;
1596
1597	// Asset rate.
1598	#[runtime::pallet_index(101)]
1599	pub type AssetRate = pallet_asset_rate;
1600
1601	// Root testing pallet.
1602	#[runtime::pallet_index(102)]
1603	pub type RootTesting = pallet_root_testing;
1604
1605	// Root offences pallet
1606	#[runtime::pallet_index(105)]
1607	pub type RootOffences = pallet_root_offences;
1608
1609	// BEEFY Bridges support.
1610	#[runtime::pallet_index(200)]
1611	pub type Beefy = pallet_beefy;
1612	// MMR leaf construction must be after session in order to have a leaf's next_auth_set
1613	// refer to block<N>. See issue polkadot-fellows/runtimes#160 for details.
1614	#[runtime::pallet_index(201)]
1615	pub type Mmr = pallet_mmr;
1616	#[runtime::pallet_index(202)]
1617	pub type BeefyMmrLeaf = pallet_beefy_mmr;
1618
1619	// Pallet for migrating Identity to a parachain. To be removed post-migration.
1620	#[runtime::pallet_index(248)]
1621	pub type IdentityMigrator = identity_migrator;
1622}
1623
1624/// The address format for describing accounts.
1625pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
1626/// Block header type as expected by this runtime.
1627pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
1628/// Block type as expected by this runtime.
1629pub type Block = generic::Block<Header, UncheckedExtrinsic>;
1630/// A Block signed with a Justification
1631pub type SignedBlock = generic::SignedBlock<Block>;
1632/// `BlockId` type as expected by this runtime.
1633pub type BlockId = generic::BlockId<Block>;
1634/// The extension to the basic transaction logic.
1635pub type TxExtension = (
1636	frame_system::AuthorizeCall<Runtime>,
1637	frame_system::CheckNonZeroSender<Runtime>,
1638	frame_system::CheckSpecVersion<Runtime>,
1639	frame_system::CheckTxVersion<Runtime>,
1640	frame_system::CheckGenesis<Runtime>,
1641	frame_system::CheckMortality<Runtime>,
1642	frame_system::CheckNonce<Runtime>,
1643	frame_system::CheckWeight<Runtime>,
1644	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
1645	frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
1646	frame_system::WeightReclaim<Runtime>,
1647);
1648
1649parameter_types! {
1650	/// Bounding number of agent pot accounts to be migrated in a single block.
1651	pub const MaxAgentsToMigrate: u32 = 300;
1652	pub const RecoveryPalletName: &'static str = "Recovery";
1653}
1654
1655/// All migrations that will run on the next runtime upgrade.
1656///
1657/// This contains the combined migrations of the last 10 releases. It allows to skip runtime
1658/// upgrades in case governance decides to do so. THE ORDER IS IMPORTANT.
1659pub type Migrations = migrations::Unreleased;
1660
1661/// The runtime migrations per release.
1662#[allow(deprecated, missing_docs)]
1663pub mod migrations {
1664	use super::*;
1665	use frame_support::{
1666		traits::{
1667			fungible::{Balanced, Inspect},
1668			tokens::{Fortitude, Precision, Preservation},
1669			OnRuntimeUpgrade, OnUnbalanced,
1670		},
1671		weights::Weight,
1672	};
1673	use polkadot_primitives::AccountId;
1674	use sp_runtime::traits::Zero;
1675	#[cfg(feature = "try-runtime")]
1676	use {
1677		alloc::vec::Vec,
1678		codec::{Decode, Encode},
1679		polkadot_primitives::Balance,
1680	};
1681
1682	parameter_types! {
1683		pub const TreasuryPalletStr: &'static str = "Treasury";
1684		pub const ConvictionVotingPalletStr: &'static str = "ConvictionVoting";
1685		pub const ReferendaPalletStr: &'static str = "Referenda";
1686		pub const OriginsPalletStr: &'static str = "Origins";
1687		pub const WhitelistPalletStr: &'static str = "Whitelist";
1688		pub const StakingPalletStr: &'static str = "Staking";
1689		pub const ElectionProviderMultiPhasePalletStr: &'static str = "ElectionProviderMultiPhase";
1690		pub const VoterListPalletStr: &'static str = "VoterList";
1691		pub const NominationPoolsPalletStr: &'static str = "NominationPools";
1692		pub const FastUnstakePalletStr: &'static str = "FastUnstake";
1693	}
1694
1695	/// Legacy treasury `PalletId` (`py/trsry`).
1696	const LEGACY_TREASURY_PALLET_ID: PalletId = PalletId(*b"py/trsry");
1697	const DRAIN_LOG_TARGET: &str = "runtime::westend::drain-legacy-treasury";
1698
1699	/// One-shot migration that drains the reducible balance of the legacy
1700	/// `py/trsry`-derived account into the [`pallet_accumulate_and_forward`] accumulation
1701	/// account. The runtime's `Forwarder` then teleports the funds to AssetHub's central DAP
1702	/// on the next forwarding interval.
1703	///
1704	/// Runtime-local (not part of the generic ACF pallet).
1705	/// Idempotent: a zero reducible balance is a no-op.
1706	pub struct DrainLegacyTreasuryToAccumulationAccount;
1707
1708	impl OnRuntimeUpgrade for DrainLegacyTreasuryToAccumulationAccount {
1709		fn on_runtime_upgrade() -> Weight {
1710			let source: AccountId = LEGACY_TREASURY_PALLET_ID.into_account_truncating();
1711			// No further inflows expected, but `Preserve` is used as a safeguard since this
1712			// migration runs on every runtime upgrade until removed. Worst case: ED stays
1713			// behind on a dead account.
1714			let amount = <Balances as Inspect<AccountId>>::reducible_balance(
1715				&source,
1716				Preservation::Preserve,
1717				Fortitude::Polite,
1718			);
1719			if amount.is_zero() {
1720				log::info!(
1721					target: DRAIN_LOG_TARGET,
1722					"nothing to withdraw (reducible balance is zero)."
1723				);
1724				return <Runtime as frame_system::Config>::DbWeight::get().reads(1);
1725			}
1726
1727			match <Balances as Balanced<AccountId>>::withdraw(
1728				&source,
1729				amount,
1730				Precision::Exact,
1731				Preservation::Preserve,
1732				Fortitude::Polite,
1733			) {
1734				Ok(credit) => {
1735					<AccumulateForward as OnUnbalanced<_>>::on_unbalanced(credit);
1736					log::info!(
1737						target: DRAIN_LOG_TARGET,
1738						"swept {amount:?} to accumulation account."
1739					);
1740				},
1741				Err(_) => {
1742					frame_support::defensive!(
1743						"DrainLegacyTreasuryToAccumulationAccount: failed to withdraw from legacy treasury account"
1744					);
1745				},
1746			}
1747
1748			// Distinct storage keys touched: source Account (balances + system),
1749			// accumulation Account (balances + system) = 4 reads and 4 writes.
1750			<Runtime as frame_system::Config>::DbWeight::get().reads_writes(4, 4)
1751		}
1752
1753		#[cfg(feature = "try-runtime")]
1754		fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
1755			let source: AccountId = LEGACY_TREASURY_PALLET_ID.into_account_truncating();
1756			let legacy_pre = <Balances as Inspect<AccountId>>::reducible_balance(
1757				&source,
1758				Preservation::Preserve,
1759				Fortitude::Polite,
1760			);
1761			let accum_pre = <Balances as Inspect<AccountId>>::reducible_balance(
1762				&pallet_accumulate_and_forward::Pallet::<Runtime>::accumulation_account(),
1763				Preservation::Preserve,
1764				Fortitude::Polite,
1765			);
1766			log::info!(
1767				target: DRAIN_LOG_TARGET,
1768				"pre-upgrade legacy reducible = {legacy_pre:?}, accumulation reducible = {accum_pre:?}"
1769			);
1770			Ok((legacy_pre, accum_pre).encode())
1771		}
1772
1773		#[cfg(feature = "try-runtime")]
1774		fn post_upgrade(state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
1775			let (legacy_pre, accum_pre): (Balance, Balance) = Decode::decode(&mut &state[..])
1776				.expect("pre_upgrade encoded (legacy_pre, accum_pre)");
1777
1778			let source: AccountId = LEGACY_TREASURY_PALLET_ID.into_account_truncating();
1779			let legacy_post = <Balances as Inspect<AccountId>>::reducible_balance(
1780				&source,
1781				Preservation::Preserve,
1782				Fortitude::Polite,
1783			);
1784			frame_support::ensure!(
1785				legacy_post.is_zero(),
1786				"Legacy treasury reducible balance should be zero after migration"
1787			);
1788
1789			let accum_post = <Balances as Inspect<AccountId>>::reducible_balance(
1790				&pallet_accumulate_and_forward::Pallet::<Runtime>::accumulation_account(),
1791				Preservation::Preserve,
1792				Fortitude::Polite,
1793			);
1794			frame_support::ensure!(
1795				Some(accum_post) == accum_pre.checked_add(legacy_pre),
1796				"Accumulation account balance should have increased by exactly the drained amount"
1797			);
1798
1799			log::info!(
1800				target: DRAIN_LOG_TARGET,
1801				"post-upgrade OK. Legacy reducible: {legacy_post:?}, accumulation reducible: {accum_post:?}"
1802			);
1803			Ok(())
1804		}
1805	}
1806
1807	/// Unreleased migrations. Add new ones here:
1808	pub type Unreleased = (
1809		// Migrate scheduler v3 -> v4 and on-demand v1 -> v2
1810		parachains_on_demand::migration::MigrateV1ToV2<Runtime>,
1811		parachains_scheduler::migration::MigrateV3ToV4<Runtime>,
1812		parachains_configuration::migration::v13::MigrateToV13<Runtime>,
1813		parachains_shared::migration::MigrateToV2<Runtime>,
1814		// #11705: drain residual legacy `py/trsry` balance into the ACF accumulation
1815		// account.
1816		// Idempotent. No further activity on the legacy `py/trsry`
1817		// account is expected. Safe to remove after the next runtime upgrade once confirmed.
1818		DrainLegacyTreasuryToAccumulationAccount,
1819		frame_support::migrations::RemovePallet<
1820			TreasuryPalletStr,
1821			<Runtime as frame_system::Config>::DbWeight,
1822		>,
1823		// OpenGov removal: clear orphaned storage for governance pallets.
1824		frame_support::migrations::RemovePallet<
1825			ConvictionVotingPalletStr,
1826			<Runtime as frame_system::Config>::DbWeight,
1827		>,
1828		frame_support::migrations::RemovePallet<
1829			ReferendaPalletStr,
1830			<Runtime as frame_system::Config>::DbWeight,
1831		>,
1832		frame_support::migrations::RemovePallet<
1833			OriginsPalletStr,
1834			<Runtime as frame_system::Config>::DbWeight,
1835		>,
1836		frame_support::migrations::RemovePallet<
1837			WhitelistPalletStr,
1838			<Runtime as frame_system::Config>::DbWeight,
1839		>,
1840		// Remove the Recovery pallet.
1841		frame_support::migrations::RemovePallet<
1842			RecoveryPalletName,
1843			<Runtime as frame_system::Config>::DbWeight,
1844		>,
1845		// Staking removal: clear orphaned storage for staking-related pallets.
1846		frame_support::migrations::RemovePallet<
1847			StakingPalletStr,
1848			<Runtime as frame_system::Config>::DbWeight,
1849		>,
1850		frame_support::migrations::RemovePallet<
1851			ElectionProviderMultiPhasePalletStr,
1852			<Runtime as frame_system::Config>::DbWeight,
1853		>,
1854		frame_support::migrations::RemovePallet<
1855			VoterListPalletStr,
1856			<Runtime as frame_system::Config>::DbWeight,
1857		>,
1858		frame_support::migrations::RemovePallet<
1859			NominationPoolsPalletStr,
1860			<Runtime as frame_system::Config>::DbWeight,
1861		>,
1862		frame_support::migrations::RemovePallet<
1863			FastUnstakePalletStr,
1864			<Runtime as frame_system::Config>::DbWeight,
1865		>,
1866		// permanent
1867		pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,
1868	);
1869}
1870
1871/// Unchecked extrinsic type as expected by this runtime.
1872pub type UncheckedExtrinsic =
1873	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
1874/// Unchecked signature payload type as expected by this runtime.
1875pub type UncheckedSignaturePayload =
1876	generic::UncheckedSignaturePayload<Address, Signature, TxExtension>;
1877
1878/// Executive: handles dispatch to the various modules.
1879pub type Executive = frame_executive::Executive<
1880	Runtime,
1881	Block,
1882	frame_system::ChainContext<Runtime>,
1883	Runtime,
1884	AllPalletsWithSystem,
1885>;
1886/// The payload being signed in transactions.
1887pub type SignedPayload = generic::SignedPayload<RuntimeCall, TxExtension>;
1888
1889#[cfg(feature = "runtime-benchmarks")]
1890mod benches {
1891	frame_benchmarking::define_benchmarks!(
1892		// Polkadot
1893		// NOTE: Make sure to prefix these with `runtime_common::` so
1894		// the that path resolves correctly in the generated file.
1895		[polkadot_runtime_common::assigned_slots, AssignedSlots]
1896		[polkadot_runtime_common::auctions, Auctions]
1897		[polkadot_runtime_common::crowdloan, Crowdloan]
1898		[polkadot_runtime_common::identity_migrator, IdentityMigrator]
1899		[polkadot_runtime_common::paras_registrar, Registrar]
1900		[polkadot_runtime_common::slots, Slots]
1901		[polkadot_runtime_parachains::configuration, Configuration]
1902		[polkadot_runtime_parachains::disputes, ParasDisputes]
1903		[polkadot_runtime_parachains::dmp, Dmp]
1904		[polkadot_runtime_parachains::hrmp, Hrmp]
1905		[polkadot_runtime_parachains::inclusion, ParaInclusion]
1906		[polkadot_runtime_parachains::initializer, Initializer]
1907		[polkadot_runtime_parachains::paras, Paras]
1908		[polkadot_runtime_parachains::paras_inherent, ParaInherent]
1909		[polkadot_runtime_parachains::on_demand, OnDemandAssignmentProvider]
1910		[polkadot_runtime_parachains::coretime, Coretime]
1911		// Substrate
1912		[pallet_balances, Balances]
1913		[pallet_beefy_mmr, BeefyMmrLeaf]
1914		[pallet_identity, Identity]
1915		[pallet_indices, Indices]
1916		[pallet_message_queue, MessageQueue]
1917		[pallet_migrations, MultiBlockMigrations]
1918		[pallet_mmr, Mmr]
1919		[pallet_multisig, Multisig]
1920		[pallet_parameters, Parameters]
1921		[pallet_preimage, Preimage]
1922		[pallet_proxy, Proxy]
1923		[pallet_scheduler, Scheduler]
1924		[pallet_sudo, Sudo]
1925		[frame_system, SystemBench::<Runtime>]
1926		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
1927		[pallet_timestamp, Timestamp]
1928		[pallet_transaction_payment, TransactionPayment]
1929		[pallet_utility, Utility]
1930		[pallet_vesting, Vesting]
1931		[pallet_asset_rate, AssetRate]
1932		[pallet_accumulate_and_forward, AccumulateForward]
1933		// XCM
1934		[pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
1935		// NOTE: Make sure you point to the individual modules below.
1936		[pallet_xcm_benchmarks::fungible, XcmBalances]
1937		[pallet_xcm_benchmarks::generic, XcmGeneric]
1938	);
1939}
1940
1941sp_api::impl_runtime_apis! {
1942	impl sp_api::Core<Block> for Runtime {
1943		fn version() -> RuntimeVersion {
1944			VERSION
1945		}
1946
1947		fn execute_block(block: <Block as BlockT>::LazyBlock) {
1948			Executive::execute_block(block);
1949		}
1950
1951		fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
1952			Executive::initialize_block(header)
1953		}
1954	}
1955
1956	impl sp_api::Metadata<Block> for Runtime {
1957		fn metadata() -> OpaqueMetadata {
1958			OpaqueMetadata::new(Runtime::metadata().into())
1959		}
1960
1961		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
1962			Runtime::metadata_at_version(version)
1963		}
1964
1965		fn metadata_versions() -> alloc::vec::Vec<u32> {
1966			Runtime::metadata_versions()
1967		}
1968	}
1969
1970	impl frame_support::view_functions::runtime_api::RuntimeViewFunction<Block> for Runtime {
1971		fn execute_view_function(id: frame_support::view_functions::ViewFunctionId, input: Vec<u8>) -> Result<Vec<u8>, frame_support::view_functions::ViewFunctionDispatchError> {
1972			Runtime::execute_view_function(id, input)
1973		}
1974	}
1975
1976	impl sp_block_builder::BlockBuilder<Block> for Runtime {
1977		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
1978			Executive::apply_extrinsic(extrinsic)
1979		}
1980
1981		fn finalize_block() -> <Block as BlockT>::Header {
1982			Executive::finalize_block()
1983		}
1984
1985		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
1986			data.create_extrinsics()
1987		}
1988
1989		fn check_inherents(
1990			block: <Block as BlockT>::LazyBlock,
1991			data: sp_inherents::InherentData,
1992		) -> sp_inherents::CheckInherentsResult {
1993			data.check_extrinsics(&block)
1994		}
1995	}
1996
1997	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
1998		fn validate_transaction(
1999			source: TransactionSource,
2000			tx: <Block as BlockT>::Extrinsic,
2001			block_hash: <Block as BlockT>::Hash,
2002		) -> TransactionValidity {
2003			Executive::validate_transaction(source, tx, block_hash)
2004		}
2005	}
2006
2007	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
2008		fn offchain_worker(header: &<Block as BlockT>::Header) {
2009			Executive::offchain_worker(header)
2010		}
2011	}
2012
2013	#[api_version(16)]
2014	impl polkadot_primitives::runtime_api::ParachainHost<Block> for Runtime {
2015		fn validators() -> Vec<ValidatorId> {
2016			parachains_runtime_api_impl::validators::<Runtime>()
2017		}
2018
2019		fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>) {
2020			parachains_runtime_api_impl::validator_groups::<Runtime>()
2021		}
2022
2023		fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>> {
2024			parachains_runtime_api_impl::availability_cores::<Runtime>()
2025		}
2026
2027		fn persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption)
2028			-> Option<PersistedValidationData<Hash, BlockNumber>> {
2029			parachains_runtime_api_impl::persisted_validation_data::<Runtime>(para_id, assumption)
2030		}
2031
2032		fn assumed_validation_data(
2033			para_id: ParaId,
2034			expected_persisted_validation_data_hash: Hash,
2035		) -> Option<(PersistedValidationData<Hash, BlockNumber>, ValidationCodeHash)> {
2036			parachains_runtime_api_impl::assumed_validation_data::<Runtime>(
2037				para_id,
2038				expected_persisted_validation_data_hash,
2039			)
2040		}
2041
2042		fn check_validation_outputs(
2043			para_id: ParaId,
2044			outputs: polkadot_primitives::CandidateCommitments,
2045		) -> bool {
2046			parachains_runtime_api_impl::check_validation_outputs::<Runtime>(para_id, outputs)
2047		}
2048
2049		fn session_index_for_child() -> SessionIndex {
2050			parachains_runtime_api_impl::session_index_for_child::<Runtime>()
2051		}
2052
2053		fn validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption)
2054			-> Option<ValidationCode> {
2055			parachains_runtime_api_impl::validation_code::<Runtime>(para_id, assumption)
2056		}
2057
2058		fn candidate_pending_availability(para_id: ParaId) -> Option<CommittedCandidateReceipt<Hash>> {
2059			#[allow(deprecated)]
2060			parachains_runtime_api_impl::candidate_pending_availability::<Runtime>(para_id)
2061		}
2062
2063		fn candidate_events() -> Vec<CandidateEvent<Hash>> {
2064			parachains_runtime_api_impl::candidate_events::<Runtime, _>(|ev| {
2065				match ev {
2066					RuntimeEvent::ParaInclusion(ev) => {
2067						Some(ev)
2068					}
2069					_ => None,
2070				}
2071			})
2072		}
2073
2074		fn session_info(index: SessionIndex) -> Option<SessionInfo> {
2075			parachains_runtime_api_impl::session_info::<Runtime>(index)
2076		}
2077
2078		fn session_executor_params(session_index: SessionIndex) -> Option<ExecutorParams> {
2079			parachains_runtime_api_impl::session_executor_params::<Runtime>(session_index)
2080		}
2081
2082		fn dmq_contents(recipient: ParaId) -> Vec<InboundDownwardMessage<BlockNumber>> {
2083			parachains_runtime_api_impl::dmq_contents::<Runtime>(recipient)
2084		}
2085
2086		fn inbound_hrmp_channels_contents(
2087			recipient: ParaId
2088		) -> BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>> {
2089			parachains_runtime_api_impl::inbound_hrmp_channels_contents::<Runtime>(recipient)
2090		}
2091
2092		fn validation_code_by_hash(hash: ValidationCodeHash) -> Option<ValidationCode> {
2093			parachains_runtime_api_impl::validation_code_by_hash::<Runtime>(hash)
2094		}
2095
2096		fn on_chain_votes() -> Option<ScrapedOnChainVotes<Hash>> {
2097			parachains_runtime_api_impl::on_chain_votes::<Runtime>()
2098		}
2099
2100		fn submit_pvf_check_statement(
2101			stmt: PvfCheckStatement,
2102			signature: ValidatorSignature,
2103		) {
2104			parachains_runtime_api_impl::submit_pvf_check_statement::<Runtime>(stmt, signature)
2105		}
2106
2107		fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
2108			parachains_runtime_api_impl::pvfs_require_precheck::<Runtime>()
2109		}
2110
2111		fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption)
2112			-> Option<ValidationCodeHash>
2113		{
2114			parachains_runtime_api_impl::validation_code_hash::<Runtime>(para_id, assumption)
2115		}
2116
2117		fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)> {
2118			parachains_runtime_api_impl::get_session_disputes::<Runtime>()
2119		}
2120
2121		fn unapplied_slashes(
2122		) -> Vec<(SessionIndex, CandidateHash, slashing::LegacyPendingSlashes)> {
2123			parachains_runtime_api_impl::unapplied_slashes::<Runtime>()
2124		}
2125
2126		fn unapplied_slashes_v2(
2127		) -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)> {
2128			parachains_runtime_api_impl::unapplied_slashes_v2::<Runtime>()
2129		}
2130
2131		fn key_ownership_proof(
2132			validator_id: ValidatorId,
2133		) -> Option<slashing::OpaqueKeyOwnershipProof> {
2134			use codec::Encode;
2135
2136			Historical::prove((PARACHAIN_KEY_TYPE_ID, validator_id))
2137				.map(|p| p.encode())
2138				.map(slashing::OpaqueKeyOwnershipProof::new)
2139		}
2140
2141		fn submit_report_dispute_lost(
2142			dispute_proof: slashing::DisputeProof,
2143			key_ownership_proof: slashing::OpaqueKeyOwnershipProof,
2144		) -> Option<()> {
2145			parachains_runtime_api_impl::submit_unsigned_slashing_report::<Runtime>(
2146				dispute_proof,
2147				key_ownership_proof,
2148			)
2149		}
2150
2151		fn minimum_backing_votes() -> u32 {
2152			parachains_runtime_api_impl::minimum_backing_votes::<Runtime>()
2153		}
2154
2155		fn para_backing_state(para_id: ParaId) -> Option<polkadot_primitives::async_backing::BackingState> {
2156			#[allow(deprecated)]
2157			parachains_runtime_api_impl::backing_state::<Runtime>(para_id)
2158		}
2159
2160		fn async_backing_params() -> polkadot_primitives::AsyncBackingParams {
2161			#[allow(deprecated)]
2162			parachains_runtime_api_impl::async_backing_params::<Runtime>()
2163		}
2164
2165		fn approval_voting_params() -> ApprovalVotingParams {
2166			parachains_runtime_api_impl::approval_voting_params::<Runtime>()
2167		}
2168
2169		fn disabled_validators() -> Vec<ValidatorIndex> {
2170			parachains_runtime_api_impl::disabled_validators::<Runtime>()
2171		}
2172
2173		fn node_features() -> NodeFeatures {
2174			parachains_runtime_api_impl::node_features::<Runtime>()
2175		}
2176
2177		fn claim_queue() -> BTreeMap<CoreIndex, VecDeque<ParaId>> {
2178			parachains_runtime_api_impl::claim_queue::<Runtime>()
2179		}
2180
2181		fn candidates_pending_availability(para_id: ParaId) -> Vec<CommittedCandidateReceipt<Hash>> {
2182			parachains_runtime_api_impl::candidates_pending_availability::<Runtime>(para_id)
2183		}
2184
2185		fn backing_constraints(para_id: ParaId) -> Option<Constraints> {
2186			parachains_runtime_api_impl::backing_constraints::<Runtime>(para_id)
2187		}
2188
2189		fn scheduling_lookahead() -> u32 {
2190			parachains_runtime_api_impl::scheduling_lookahead::<Runtime>()
2191		}
2192
2193		fn validation_code_bomb_limit() -> u32 {
2194			parachains_runtime_api_impl::validation_code_bomb_limit::<Runtime>()
2195		}
2196
2197		fn para_ids() -> Vec<ParaId> {
2198			parachains_staging_runtime_api_impl::para_ids::<Runtime>()
2199		}
2200
2201		fn max_relay_parent_session_age() -> u32 {
2202			parachains_staging_runtime_api_impl::max_relay_parent_session_age::<Runtime>()
2203		}
2204
2205		fn ancestor_relay_parent_info(
2206			session_index: SessionIndex,
2207			relay_parent: Hash,
2208		) -> Option<polkadot_primitives::vstaging::RelayParentInfo<Hash, BlockNumber>> {
2209			parachains_staging_runtime_api_impl::ancestor_relay_parent_info::<Runtime>(session_index, relay_parent)
2210		}
2211	}
2212
2213	#[api_version(6)]
2214	impl sp_consensus_beefy::BeefyApi<Block, BeefyId> for Runtime {
2215		fn beefy_genesis() -> Option<BlockNumber> {
2216			pallet_beefy::GenesisBlock::<Runtime>::get()
2217		}
2218
2219		fn validator_set() -> Option<sp_consensus_beefy::ValidatorSet<BeefyId>> {
2220			Beefy::validator_set()
2221		}
2222
2223		fn submit_report_double_voting_unsigned_extrinsic(
2224			equivocation_proof: sp_consensus_beefy::DoubleVotingProof<
2225				BlockNumber,
2226				BeefyId,
2227				BeefySignature,
2228			>,
2229			key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof,
2230		) -> Option<()> {
2231			let key_owner_proof = key_owner_proof.decode()?;
2232
2233			Beefy::submit_unsigned_double_voting_report(
2234				equivocation_proof,
2235				key_owner_proof,
2236			)
2237		}
2238
2239		fn submit_report_fork_voting_unsigned_extrinsic(
2240			equivocation_proof:
2241				sp_consensus_beefy::ForkVotingProof<
2242					<Block as BlockT>::Header,
2243					BeefyId,
2244					sp_runtime::OpaqueValue
2245				>,
2246			key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof,
2247		) -> Option<()> {
2248			Beefy::submit_unsigned_fork_voting_report(
2249				equivocation_proof.try_into()?,
2250				key_owner_proof.decode()?,
2251			)
2252		}
2253
2254		fn submit_report_future_block_voting_unsigned_extrinsic(
2255			equivocation_proof: sp_consensus_beefy::FutureBlockVotingProof<BlockNumber, BeefyId>,
2256			key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof,
2257		) -> Option<()> {
2258			Beefy::submit_unsigned_future_block_voting_report(
2259				equivocation_proof,
2260				key_owner_proof.decode()?,
2261			)
2262		}
2263
2264		fn generate_key_ownership_proof(
2265			_set_id: sp_consensus_beefy::ValidatorSetId,
2266			authority_id: BeefyId,
2267		) -> Option<sp_consensus_beefy::OpaqueKeyOwnershipProof> {
2268			use codec::Encode;
2269
2270			Historical::prove((sp_consensus_beefy::KEY_TYPE, authority_id))
2271				.map(|p| p.encode())
2272				.map(sp_consensus_beefy::OpaqueKeyOwnershipProof::new)
2273		}
2274	}
2275
2276	#[api_version(3)]
2277	impl mmr::MmrApi<Block, Hash, BlockNumber> for Runtime {
2278		fn mmr_root() -> Result<mmr::Hash, mmr::Error> {
2279			Ok(pallet_mmr::RootHash::<Runtime>::get())
2280		}
2281
2282		fn mmr_leaf_count() -> Result<mmr::LeafIndex, mmr::Error> {
2283			Ok(pallet_mmr::NumberOfLeaves::<Runtime>::get())
2284		}
2285
2286		fn generate_proof(
2287			block_numbers: Vec<BlockNumber>,
2288			best_known_block_number: Option<BlockNumber>,
2289		) -> Result<(Vec<mmr::EncodableOpaqueLeaf>, mmr::LeafProof<mmr::Hash>), mmr::Error> {
2290			Mmr::generate_proof(block_numbers, best_known_block_number).map(
2291				|(leaves, proof)| {
2292					(
2293						leaves
2294							.into_iter()
2295							.map(|leaf| mmr::EncodableOpaqueLeaf::from_leaf(&leaf))
2296							.collect(),
2297						proof,
2298					)
2299				},
2300			)
2301		}
2302
2303		fn generate_ancestry_proof(
2304			prev_block_number: BlockNumber,
2305			best_known_block_number: Option<BlockNumber>,
2306		) -> Result<mmr::AncestryProof<mmr::Hash>, mmr::Error> {
2307			Mmr::generate_ancestry_proof(prev_block_number, best_known_block_number)
2308		}
2309
2310		fn verify_proof(leaves: Vec<mmr::EncodableOpaqueLeaf>, proof: mmr::LeafProof<mmr::Hash>)
2311			-> Result<(), mmr::Error>
2312		{
2313			let leaves = leaves.into_iter().map(|leaf|
2314				leaf.into_opaque_leaf()
2315				.try_decode()
2316				.ok_or(mmr::Error::Verify)).collect::<Result<Vec<mmr::Leaf>, mmr::Error>>()?;
2317			Mmr::verify_leaves(leaves, proof)
2318		}
2319
2320		fn verify_proof_stateless(
2321			root: mmr::Hash,
2322			leaves: Vec<mmr::EncodableOpaqueLeaf>,
2323			proof: mmr::LeafProof<mmr::Hash>
2324		) -> Result<(), mmr::Error> {
2325			let nodes = leaves.into_iter().map(|leaf|mmr::DataOrHash::Data(leaf.into_opaque_leaf())).collect();
2326			pallet_mmr::verify_leaves_proof::<mmr::Hashing, _>(root, nodes, proof)
2327		}
2328	}
2329
2330	impl pallet_beefy_mmr::BeefyMmrApi<Block, Hash> for RuntimeApi {
2331		fn authority_set_proof() -> sp_consensus_beefy::mmr::BeefyAuthoritySet<Hash> {
2332			BeefyMmrLeaf::authority_set_proof()
2333		}
2334
2335		fn next_authority_set_proof() -> sp_consensus_beefy::mmr::BeefyNextAuthoritySet<Hash> {
2336			BeefyMmrLeaf::next_authority_set_proof()
2337		}
2338	}
2339
2340	impl fg_primitives::GrandpaApi<Block> for Runtime {
2341		fn grandpa_authorities() -> Vec<(GrandpaId, u64)> {
2342			Grandpa::grandpa_authorities()
2343		}
2344
2345		fn current_set_id() -> fg_primitives::SetId {
2346			pallet_grandpa::CurrentSetId::<Runtime>::get()
2347		}
2348
2349		fn submit_report_equivocation_unsigned_extrinsic(
2350			equivocation_proof: fg_primitives::EquivocationProof<
2351				<Block as BlockT>::Hash,
2352				sp_runtime::traits::NumberFor<Block>,
2353			>,
2354			key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,
2355		) -> Option<()> {
2356			let key_owner_proof = key_owner_proof.decode()?;
2357
2358			Grandpa::submit_unsigned_equivocation_report(
2359				equivocation_proof,
2360				key_owner_proof,
2361			)
2362		}
2363
2364		fn generate_key_ownership_proof(
2365			_set_id: fg_primitives::SetId,
2366			authority_id: fg_primitives::AuthorityId,
2367		) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {
2368			use codec::Encode;
2369
2370			Historical::prove((fg_primitives::KEY_TYPE, authority_id))
2371				.map(|p| p.encode())
2372				.map(fg_primitives::OpaqueKeyOwnershipProof::new)
2373		}
2374	}
2375
2376	impl sp_consensus_babe::BabeApi<Block> for Runtime {
2377		fn configuration() -> sp_consensus_babe::BabeConfiguration {
2378			let epoch_config = Babe::epoch_config().unwrap_or(BABE_GENESIS_EPOCH_CONFIG);
2379			sp_consensus_babe::BabeConfiguration {
2380				slot_duration: Babe::slot_duration(),
2381				epoch_length: EpochDuration::get(),
2382				c: epoch_config.c,
2383				authorities: Babe::authorities().to_vec(),
2384				randomness: Babe::randomness(),
2385				allowed_slots: epoch_config.allowed_slots,
2386			}
2387		}
2388
2389		fn current_epoch_start() -> sp_consensus_babe::Slot {
2390			Babe::current_epoch_start()
2391		}
2392
2393		fn current_epoch() -> sp_consensus_babe::Epoch {
2394			Babe::current_epoch()
2395		}
2396
2397		fn next_epoch() -> sp_consensus_babe::Epoch {
2398			Babe::next_epoch()
2399		}
2400
2401		fn generate_key_ownership_proof(
2402			_slot: sp_consensus_babe::Slot,
2403			authority_id: sp_consensus_babe::AuthorityId,
2404		) -> Option<sp_consensus_babe::OpaqueKeyOwnershipProof> {
2405			use codec::Encode;
2406
2407			Historical::prove((sp_consensus_babe::KEY_TYPE, authority_id))
2408				.map(|p| p.encode())
2409				.map(sp_consensus_babe::OpaqueKeyOwnershipProof::new)
2410		}
2411
2412		fn submit_report_equivocation_unsigned_extrinsic(
2413			equivocation_proof: sp_consensus_babe::EquivocationProof<<Block as BlockT>::Header>,
2414			key_owner_proof: sp_consensus_babe::OpaqueKeyOwnershipProof,
2415		) -> Option<()> {
2416			let key_owner_proof = key_owner_proof.decode()?;
2417
2418			Babe::submit_unsigned_equivocation_report(
2419				equivocation_proof,
2420				key_owner_proof,
2421			)
2422		}
2423	}
2424
2425	impl sp_authority_discovery::AuthorityDiscoveryApi<Block> for Runtime {
2426		fn authorities() -> Vec<AuthorityDiscoveryId> {
2427			parachains_runtime_api_impl::relevant_authority_ids::<Runtime>()
2428		}
2429	}
2430
2431	impl sp_session::SessionKeys<Block> for Runtime {
2432		fn generate_session_keys(owner: Vec<u8>, seed: Option<Vec<u8>>) -> sp_session::OpaqueGeneratedSessionKeys {
2433			SessionKeys::generate(&owner, seed).into()
2434		}
2435
2436		fn decode_session_keys(
2437			encoded: Vec<u8>,
2438		) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
2439			SessionKeys::decode_into_raw_public_keys(&encoded)
2440		}
2441	}
2442
2443	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
2444		fn account_nonce(account: AccountId) -> Nonce {
2445			System::account_nonce(account)
2446		}
2447	}
2448
2449	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
2450		Block,
2451		Balance,
2452	> for Runtime {
2453		fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
2454			TransactionPayment::query_info(uxt, len)
2455		}
2456		fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {
2457			TransactionPayment::query_fee_details(uxt, len)
2458		}
2459		fn query_weight_to_fee(weight: Weight) -> Balance {
2460			TransactionPayment::weight_to_fee(weight)
2461		}
2462		fn query_length_to_fee(length: u32) -> Balance {
2463			TransactionPayment::length_to_fee(length)
2464		}
2465	}
2466
2467	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
2468		for Runtime
2469	{
2470		fn query_call_info(call: RuntimeCall, len: u32) -> RuntimeDispatchInfo<Balance> {
2471			TransactionPayment::query_call_info(call, len)
2472		}
2473		fn query_call_fee_details(call: RuntimeCall, len: u32) -> FeeDetails<Balance> {
2474			TransactionPayment::query_call_fee_details(call, len)
2475		}
2476		fn query_weight_to_fee(weight: Weight) -> Balance {
2477			TransactionPayment::weight_to_fee(weight)
2478		}
2479		fn query_length_to_fee(length: u32) -> Balance {
2480			TransactionPayment::length_to_fee(length)
2481		}
2482	}
2483
2484	impl xcm_runtime_apis::fees::XcmPaymentApi<Block> for Runtime {
2485		fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
2486			let acceptable_assets = vec![AssetId(xcm_config::TokenLocation::get())];
2487			XcmPallet::query_acceptable_payment_assets(xcm_version, acceptable_assets)
2488		}
2489
2490		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
2491			type Trader = <XcmConfig as xcm_executor::Config>::Trader;
2492			XcmPallet::query_weight_to_asset_fee::<Trader>(weight, asset)
2493		}
2494
2495		fn query_xcm_weight(message: VersionedXcm<()>) -> Result<Weight, XcmPaymentApiError> {
2496			XcmPallet::query_xcm_weight(message)
2497		}
2498
2499		fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>, asset_id: VersionedAssetId) -> Result<VersionedAssets, XcmPaymentApiError> {
2500			type AssetExchanger = <XcmConfig as xcm_executor::Config>::AssetExchanger;
2501			XcmPallet::query_delivery_fees::<AssetExchanger>(destination, message, asset_id)
2502		}
2503	}
2504
2505	impl xcm_runtime_apis::dry_run::DryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
2506		fn dry_run_call(origin: OriginCaller, call: RuntimeCall, result_xcms_version: XcmVersion) -> Result<CallDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
2507			XcmPallet::dry_run_call::<Runtime, xcm_config::XcmRouter, OriginCaller, RuntimeCall>(origin, call, result_xcms_version)
2508		}
2509
2510		fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
2511			XcmPallet::dry_run_xcm::<xcm_config::XcmRouter>(origin_location, xcm)
2512		}
2513	}
2514
2515	impl xcm_runtime_apis::conversions::LocationToAccountApi<Block, AccountId> for Runtime {
2516		fn convert_location(location: VersionedLocation) -> Result<
2517			AccountId,
2518			xcm_runtime_apis::conversions::Error
2519		> {
2520			xcm_runtime_apis::conversions::LocationToAccountHelper::<
2521				AccountId,
2522				xcm_config::LocationConverter,
2523			>::convert_location(location)
2524		}
2525	}
2526
2527	#[cfg(feature = "try-runtime")]
2528	impl frame_try_runtime::TryRuntime<Block> for Runtime {
2529		fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
2530			log::info!("try-runtime::on_runtime_upgrade westend.");
2531			let config = frame_executive::TryRuntimeUpgradeConfig::new(checks);
2532			let weight = Executive::try_runtime_upgrade_with_config(config).unwrap();
2533			(weight, BlockWeights::get().max_block)
2534		}
2535
2536		fn execute_block(
2537			block: <Block as BlockT>::LazyBlock,
2538			state_root_check: bool,
2539			signature_check: bool,
2540			select: frame_try_runtime::TryStateSelect,
2541		) -> Weight {
2542			// NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
2543			// have a backtrace here.
2544			Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()
2545		}
2546	}
2547
2548	#[cfg(feature = "runtime-benchmarks")]
2549	impl frame_benchmarking::Benchmark<Block> for Runtime {
2550		fn benchmark_metadata(extra: bool) -> (
2551			Vec<frame_benchmarking::BenchmarkList>,
2552			Vec<frame_support::traits::StorageInfo>,
2553		) {
2554			use frame_benchmarking::BenchmarkList;
2555			use frame_support::traits::StorageInfoTrait;
2556
2557			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
2558			use frame_system_benchmarking::Pallet as SystemBench;
2559			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
2560
2561			type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
2562			type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::<Runtime>;
2563
2564			let mut list = Vec::<BenchmarkList>::new();
2565			list_benchmarks!(list, extra);
2566
2567			let storage_info = AllPalletsWithSystem::storage_info();
2568			return (list, storage_info)
2569		}
2570
2571		#[allow(non_local_definitions)]
2572		fn dispatch_benchmark(
2573			config: frame_benchmarking::BenchmarkConfig,
2574		) -> Result<
2575			Vec<frame_benchmarking::BenchmarkBatch>,
2576			alloc::string::String,
2577		> {
2578			use frame_support::traits::WhitelistedStorageKeys;
2579			use frame_benchmarking::{BenchmarkBatch, BenchmarkError};
2580			use sp_storage::TrackedStorageKey;
2581			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
2582			use frame_system_benchmarking::Pallet as SystemBench;
2583			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
2584			use xcm_config::{AssetHub, TokenLocation};
2585			use alloc::boxed::Box;
2586
2587			parameter_types! {
2588				pub ExistentialDepositAsset: Option<Asset> = Some((
2589					TokenLocation::get(),
2590					ExistentialDeposit::get()
2591				).into());
2592				pub AssetHubParaId: ParaId = westend_runtime_constants::system_parachain::ASSET_HUB_ID.into();
2593				pub const RandomParaId: ParaId = ParaId::new(43211234);
2594			}
2595
2596			impl pallet_xcm::benchmarking::Config for Runtime {
2597				type DeliveryHelper = (
2598					polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
2599						xcm_config::XcmConfig,
2600						ExistentialDepositAsset,
2601						xcm_config::PriceForChildParachainDelivery,
2602						AssetHubParaId,
2603						Dmp,
2604					>,
2605					polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
2606						xcm_config::XcmConfig,
2607						ExistentialDepositAsset,
2608						xcm_config::PriceForChildParachainDelivery,
2609						RandomParaId,
2610						Dmp,
2611					>
2612				);
2613
2614				fn reachable_dest() -> Option<Location> {
2615					Some(crate::xcm_config::AssetHub::get())
2616				}
2617
2618				fn teleportable_asset_and_dest() -> Option<(Asset, Location)> {
2619					// Relay/native token can be teleported to/from AH.
2620					Some((
2621						Asset { fun: Fungible(ExistentialDeposit::get()), id: AssetId(Here.into()) },
2622						crate::xcm_config::AssetHub::get(),
2623					))
2624				}
2625
2626				fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
2627					None
2628				}
2629
2630				fn set_up_complex_asset_transfer(
2631				) -> Option<(Assets, u32, Location, Box<dyn FnOnce()>)> {
2632					// Relay supports only native token, either reserve transfer it to non-system parachains,
2633					// or teleport it to system parachain. Use the teleport case for benchmarking as it's
2634					// slightly heavier.
2635
2636					// Relay/native token can be teleported to/from AH.
2637					let native_location = Here.into();
2638					let dest = crate::xcm_config::AssetHub::get();
2639					pallet_xcm::benchmarking::helpers::native_teleport_as_asset_transfer::<Runtime>(
2640						native_location,
2641						dest
2642					)
2643				}
2644
2645				// `get_assets` stays at its default: the `AssetTransactor` only handles the
2646				// native token, so a multi-asset worst case is not constructible here.
2647				fn get_asset() -> Asset {
2648					Asset {
2649						id: AssetId(Location::here()),
2650						fun: Fungible(ExistentialDeposit::get()),
2651					}
2652				}
2653				fn batch_call(calls: Vec<RuntimeCall>) -> Option<RuntimeCall> {
2654					Some(RuntimeCall::Utility(pallet_utility::Call::batch { calls }))
2655				}
2656			}
2657			impl frame_system_benchmarking::Config for Runtime {}
2658			impl pallet_transaction_payment::BenchmarkConfig for Runtime {}
2659
2660			use xcm::latest::{
2661				AssetId, Fungibility::*, InteriorLocation, Junction, Junctions::*,
2662				Asset, Assets, Location, NetworkId, Response,
2663			};
2664
2665			impl pallet_xcm_benchmarks::Config for Runtime {
2666				type XcmConfig = xcm_config::XcmConfig;
2667				type AccountIdConverter = xcm_config::LocationConverter;
2668				type DeliveryHelper = polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
2669					xcm_config::XcmConfig,
2670					ExistentialDepositAsset,
2671					xcm_config::PriceForChildParachainDelivery,
2672					AssetHubParaId,
2673					Dmp,
2674				>;
2675				fn valid_destination() -> Result<Location, BenchmarkError> {
2676					Ok(AssetHub::get())
2677				}
2678				fn worst_case_holding(_depositable_count: u32) -> xcm_executor::AssetsInHolding {
2679					use pallet_xcm_benchmarks::MockCredit;
2680					// Westend only knows about WND.
2681					let mut holding = xcm_executor::AssetsInHolding::new();
2682					holding.fungible.insert(
2683						AssetId(TokenLocation::get()),
2684						alloc::boxed::Box::new(MockCredit(1_000_000 * UNITS)),
2685					);
2686					holding
2687				}
2688			}
2689
2690			parameter_types! {
2691				pub TrustedTeleporter: Option<(Location, Asset)> = Some((
2692					AssetHub::get(),
2693					Asset { fun: Fungible(1 * UNITS), id: AssetId(TokenLocation::get()) },
2694				));
2695				pub const TrustedReserve: Option<(Location, Asset)> = None;
2696				pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None;
2697			}
2698
2699			impl pallet_xcm_benchmarks::fungible::Config for Runtime {
2700				type TransactAsset = Balances;
2701
2702				type CheckedAccount = CheckedAccount;
2703				type TrustedTeleporter = TrustedTeleporter;
2704				type TrustedReserve = TrustedReserve;
2705
2706				fn get_asset() -> Asset {
2707					Asset {
2708						id: AssetId(TokenLocation::get()),
2709						fun: Fungible(1 * UNITS),
2710					}
2711				}
2712			}
2713
2714			impl pallet_xcm_benchmarks::generic::Config for Runtime {
2715				type TransactAsset = Balances;
2716				type RuntimeCall = RuntimeCall;
2717
2718				fn worst_case_response() -> (u64, Response) {
2719					(0u64, Response::Version(Default::default()))
2720				}
2721
2722				fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> {
2723					// Westend doesn't support asset exchanges
2724					Err(BenchmarkError::Skip)
2725				}
2726
2727				fn universal_alias() -> Result<(Location, Junction), BenchmarkError> {
2728					// The XCM executor of Westend doesn't have a configured `UniversalAliases`
2729					Err(BenchmarkError::Skip)
2730				}
2731
2732				fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> {
2733					Ok((AssetHub::get(), frame_system::Call::remark_with_event { remark: vec![] }.into()))
2734				}
2735
2736				fn subscribe_origin() -> Result<Location, BenchmarkError> {
2737					Ok(AssetHub::get())
2738				}
2739
2740				fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> {
2741					let origin = AssetHub::get();
2742					let assets: Assets = (AssetId(TokenLocation::get()), 1_000 * UNITS).into();
2743					let ticket = Location { parents: 0, interior: Here };
2744					Ok((origin, ticket, assets))
2745				}
2746
2747				fn worst_case_for_trader() -> Result<(Asset, WeightLimit), BenchmarkError> {
2748					Ok((Asset {
2749						id: AssetId(TokenLocation::get()),
2750						fun: Fungible(1_000_000 * UNITS),
2751					}, WeightLimit::Limited(Weight::from_parts(5000, 5000))))
2752				}
2753
2754				fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> {
2755					// Westend doesn't support asset locking
2756					Err(BenchmarkError::Skip)
2757				}
2758
2759				fn export_message_origin_and_destination(
2760				) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> {
2761					// Westend doesn't support exporting messages
2762					Err(BenchmarkError::Skip)
2763				}
2764
2765				fn alias_origin() -> Result<(Location, Location), BenchmarkError> {
2766					let origin = Location::new(0, [Parachain(1000)]);
2767					let target = Location::new(0, [Parachain(1000), AccountId32 { id: [128u8; 32], network: None }]);
2768					Ok((origin, target))
2769				}
2770			}
2771
2772			type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
2773			type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::<Runtime>;
2774
2775			let whitelist: Vec<TrackedStorageKey> = AllPalletsWithSystem::whitelisted_storage_keys();
2776
2777			let mut batches = Vec::<BenchmarkBatch>::new();
2778			let params = (&config, &whitelist);
2779
2780			add_benchmarks!(params, batches);
2781
2782			Ok(batches)
2783		}
2784	}
2785
2786	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
2787		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
2788			build_state::<RuntimeGenesisConfig>(config)
2789		}
2790
2791		fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
2792			get_preset::<RuntimeGenesisConfig>(id, &genesis_config_presets::get_preset)
2793		}
2794
2795		fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
2796			genesis_config_presets::preset_names()
2797		}
2798	}
2799
2800	impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
2801		fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
2802			XcmPallet::is_trusted_reserve(asset, location)
2803		}
2804		fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
2805			XcmPallet::is_trusted_teleporter(asset, location)
2806		}
2807	}
2808}