referrerpolicy=no-referrer-when-downgrade

westend_runtime/
lib.rs

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