asset_hub_rococo_runtime/
lib.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// SPDX-License-Identifier: Apache-2.0
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// 	http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! # Asset Hub Rococo Runtime
17//!
18//! Asset Hub Rococo, formerly known as "Rockmine", is the test network for its Kusama cousin.
19
20#![cfg_attr(not(feature = "std"), no_std)]
21#![recursion_limit = "256"]
22
23// Make the WASM binary available.
24#[cfg(feature = "std")]
25include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
26
27mod genesis_config_presets;
28mod weights;
29pub mod xcm_config;
30
31extern crate alloc;
32
33use alloc::{vec, vec::Vec};
34use assets_common::{
35	foreign_creators::ForeignCreators,
36	local_and_foreign_assets::{LocalFromLeft, TargetFromLeft},
37	matching::{FromNetwork, FromSiblingParachain},
38	AssetIdForPoolAssets, AssetIdForPoolAssetsConvert, AssetIdForTrustBackedAssetsConvert,
39};
40use bp_asset_hub_rococo::CreateForeignAssetDeposit;
41use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases;
42use cumulus_primitives_core::AggregateMessageOrigin;
43use sp_api::impl_runtime_apis;
44use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
45use sp_runtime::{
46	generic, impl_opaque_keys,
47	traits::{AccountIdConversion, BlakeTwo256, Block as BlockT, Saturating, Verify},
48	transaction_validity::{TransactionSource, TransactionValidity},
49	ApplyExtrinsicResult, Permill,
50};
51use testnet_parachains_constants::rococo::snowbridge::EthereumNetwork;
52
53#[cfg(feature = "std")]
54use sp_version::NativeVersion;
55use sp_version::RuntimeVersion;
56
57pub use assets_common::local_and_foreign_assets::ForeignAssetReserveData;
58use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
59use cumulus_primitives_core::ParaId;
60use frame_support::{
61	construct_runtime, derive_impl,
62	dispatch::DispatchClass,
63	genesis_builder_helper::{build_state, get_preset},
64	ord_parameter_types, parameter_types,
65	traits::{
66		fungible, fungible::HoldConsideration, fungibles, tokens::imbalance::ResolveAssetTo,
67		AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8,
68		ConstantStoragePrice, EitherOfDiverse, Equals, InstanceFilter, TransformOrigin,
69	},
70	weights::{ConstantMultiplier, Weight},
71	BoundedVec, PalletId,
72};
73use frame_system::{
74	limits::{BlockLength, BlockWeights},
75	EnsureRoot, EnsureSigned, EnsureSignedBy,
76};
77use pallet_asset_conversion_tx_payment::SwapAssetAdapter;
78use pallet_nfts::PalletFeatures;
79use parachains_common::{
80	impls::DealWithFees,
81	message_queue::{NarrowOriginToSibling, ParaIdToSibling},
82	AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, CollectionId, Hash,
83	Header, ItemId, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO, NORMAL_DISPATCH_RATIO,
84};
85use sp_runtime::{Perbill, RuntimeDebug};
86use testnet_parachains_constants::rococo::{consensus::*, currency::*, fee::WeightToFee, time::*};
87use xcm_config::{
88	ForeignAssetsConvertedConcreteId, GovernanceLocation, LocationToAccountId,
89	PoolAssetsConvertedConcreteId, PoolAssetsPalletLocation, TokenLocation,
90	TrustBackedAssetsConvertedConcreteId, TrustBackedAssetsPalletLocation, XcmConfig,
91};
92
93#[cfg(test)]
94mod tests;
95
96#[cfg(any(feature = "std", test))]
97pub use sp_runtime::BuildStorage;
98
99// Polkadot imports
100use pallet_xcm::{EnsureXcm, IsVoiceOfBody};
101use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
102#[cfg(feature = "runtime-benchmarks")]
103use xcm::latest::prelude::{
104	Asset, Assets as XcmAssets, Fungible, Here, InteriorLocation, Junction, Junction::*, Location,
105	NetworkId, NonFungible, ParentThen, Response, WeightLimit, XCM_VERSION,
106};
107use xcm::{
108	latest::prelude::{AssetId, BodyId},
109	Version as XcmVersion, VersionedAsset, VersionedAssetId, VersionedAssets, VersionedLocation,
110	VersionedXcm,
111};
112use xcm_runtime_apis::{
113	dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
114	fees::Error as XcmPaymentApiError,
115};
116
117#[cfg(feature = "runtime-benchmarks")]
118use frame_support::traits::PalletInfoAccess;
119
120use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};
121
122impl_opaque_keys! {
123	pub struct SessionKeys {
124		pub aura: Aura,
125	}
126}
127
128#[sp_version::runtime_version]
129pub const VERSION: RuntimeVersion = RuntimeVersion {
130	spec_name: alloc::borrow::Cow::Borrowed("statemine"),
131	impl_name: alloc::borrow::Cow::Borrowed("statemine"),
132	authoring_version: 1,
133	spec_version: 1_021_000,
134	impl_version: 0,
135	apis: RUNTIME_API_VERSIONS,
136	transaction_version: 16,
137	system_version: 1,
138};
139
140/// The version information used to identify this runtime when compiled natively.
141#[cfg(feature = "std")]
142pub fn native_version() -> NativeVersion {
143	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
144}
145
146parameter_types! {
147	pub const Version: RuntimeVersion = VERSION;
148	pub RuntimeBlockLength: BlockLength =
149		BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
150	pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
151		.base_block(BlockExecutionWeight::get())
152		.for_class(DispatchClass::all(), |weights| {
153			weights.base_extrinsic = ExtrinsicBaseWeight::get();
154		})
155		.for_class(DispatchClass::Normal, |weights| {
156			weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
157		})
158		.for_class(DispatchClass::Operational, |weights| {
159			weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
160			// Operational transactions have some extra reserved space, so that they
161			// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
162			weights.reserved = Some(
163				MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
164			);
165		})
166		.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
167		.build_or_panic();
168	pub const SS58Prefix: u8 = 42;
169}
170
171// Configure FRAME pallets to include in runtime.
172#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig)]
173impl frame_system::Config for Runtime {
174	type BlockWeights = RuntimeBlockWeights;
175	type BlockLength = RuntimeBlockLength;
176	type AccountId = AccountId;
177	type Nonce = Nonce;
178	type Hash = Hash;
179	type Block = Block;
180	type BlockHashCount = BlockHashCount;
181	type DbWeight = RocksDbWeight;
182	type Version = Version;
183	type AccountData = pallet_balances::AccountData<Balance>;
184	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
185	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
186	type SS58Prefix = SS58Prefix;
187	type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
188	type MaxConsumers = frame_support::traits::ConstU32<16>;
189	type SingleBlockMigrations = Migrations;
190}
191
192impl cumulus_pallet_weight_reclaim::Config for Runtime {
193	type WeightInfo = weights::cumulus_pallet_weight_reclaim::WeightInfo<Runtime>;
194}
195
196impl pallet_timestamp::Config for Runtime {
197	/// A timestamp: milliseconds since the unix epoch.
198	type Moment = u64;
199	type OnTimestampSet = Aura;
200	type MinimumPeriod = ConstU64<0>;
201	type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
202}
203
204impl pallet_authorship::Config for Runtime {
205	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
206	type EventHandler = (CollatorSelection,);
207}
208
209parameter_types! {
210	pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
211}
212
213impl pallet_balances::Config for Runtime {
214	type MaxLocks = ConstU32<50>;
215	/// The type for recording an account's balance.
216	type Balance = Balance;
217	/// The ubiquitous event type.
218	type RuntimeEvent = RuntimeEvent;
219	type DustRemoval = ();
220	type ExistentialDeposit = ExistentialDeposit;
221	type AccountStore = System;
222	type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
223	type MaxReserves = ConstU32<50>;
224	type ReserveIdentifier = [u8; 8];
225	type RuntimeHoldReason = RuntimeHoldReason;
226	type RuntimeFreezeReason = RuntimeFreezeReason;
227	type FreezeIdentifier = RuntimeFreezeReason;
228	type MaxFreezes = ConstU32<50>;
229	type DoneSlashHandler = ();
230}
231
232parameter_types! {
233	/// Relay Chain `TransactionByteFee` / 10
234	pub const TransactionByteFee: Balance = MILLICENTS;
235}
236
237impl pallet_transaction_payment::Config for Runtime {
238	type RuntimeEvent = RuntimeEvent;
239	type OnChargeTransaction =
240		pallet_transaction_payment::FungibleAdapter<Balances, DealWithFees<Runtime>>;
241	type WeightToFee = WeightToFee;
242	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
243	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
244	type OperationalFeeMultiplier = ConstU8<5>;
245	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
246}
247
248parameter_types! {
249	pub const AssetDeposit: Balance = UNITS / 10; // 1 / 10 UNITS deposit to create asset
250	pub const AssetAccountDeposit: Balance = deposit(1, 16);
251	pub const ApprovalDeposit: Balance = EXISTENTIAL_DEPOSIT;
252	pub const AssetsStringLimit: u32 = 50;
253	/// Key = 32 bytes, Value = 36 bytes (32+1+1+1+1)
254	// https://github.com/paritytech/substrate/blob/069917b/frame/assets/src/lib.rs#L257L271
255	pub const MetadataDepositBase: Balance = deposit(1, 68);
256	pub const MetadataDepositPerByte: Balance = deposit(0, 1);
257}
258
259/// We allow root to execute privileged asset operations.
260pub type AssetsForceOrigin = EnsureRoot<AccountId>;
261
262// Called "Trust Backed" assets because these are generally registered by some account, and users of
263// the asset assume it has some claimed backing. The pallet is called `Assets` in
264// `construct_runtime` to avoid breaking changes on storage reads.
265pub type TrustBackedAssetsInstance = pallet_assets::Instance1;
266type TrustBackedAssetsCall = pallet_assets::Call<Runtime, TrustBackedAssetsInstance>;
267impl pallet_assets::Config<TrustBackedAssetsInstance> for Runtime {
268	type RuntimeEvent = RuntimeEvent;
269	type Balance = Balance;
270	type AssetId = AssetIdForTrustBackedAssets;
271	type AssetIdParameter = codec::Compact<AssetIdForTrustBackedAssets>;
272	type ReserveData = ();
273	type Currency = Balances;
274	type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
275	type ForceOrigin = AssetsForceOrigin;
276	type AssetDeposit = AssetDeposit;
277	type MetadataDepositBase = MetadataDepositBase;
278	type MetadataDepositPerByte = MetadataDepositPerByte;
279	type ApprovalDeposit = ApprovalDeposit;
280	type StringLimit = AssetsStringLimit;
281	type Holder = ();
282	type Freezer = AssetsFreezer;
283	type Extra = ();
284	type WeightInfo = weights::pallet_assets_local::WeightInfo<Runtime>;
285	type CallbackHandle = pallet_assets::AutoIncAssetId<Runtime, TrustBackedAssetsInstance>;
286	type AssetAccountDeposit = AssetAccountDeposit;
287	type RemoveItemsLimit = frame_support::traits::ConstU32<1000>;
288	#[cfg(feature = "runtime-benchmarks")]
289	type BenchmarkHelper = ();
290}
291
292// Allow Freezes for the `Assets` pallet
293pub type AssetsFreezerInstance = pallet_assets_freezer::Instance1;
294impl pallet_assets_freezer::Config<AssetsFreezerInstance> for Runtime {
295	type RuntimeFreezeReason = RuntimeFreezeReason;
296	type RuntimeEvent = RuntimeEvent;
297}
298
299parameter_types! {
300	pub const AssetConversionPalletId: PalletId = PalletId(*b"py/ascon");
301	pub const LiquidityWithdrawalFee: Permill = Permill::from_percent(0);
302}
303
304ord_parameter_types! {
305	pub const AssetConversionOrigin: sp_runtime::AccountId32 =
306		AccountIdConversion::<sp_runtime::AccountId32>::into_account_truncating(&AssetConversionPalletId::get());
307}
308
309pub type PoolAssetsInstance = pallet_assets::Instance3;
310impl pallet_assets::Config<PoolAssetsInstance> for Runtime {
311	type RuntimeEvent = RuntimeEvent;
312	type Balance = Balance;
313	type RemoveItemsLimit = ConstU32<1000>;
314	type AssetId = AssetIdForPoolAssets;
315	type AssetIdParameter = u32;
316	type ReserveData = ();
317	type Currency = Balances;
318	type CreateOrigin =
319		AsEnsureOriginWithArg<EnsureSignedBy<AssetConversionOrigin, sp_runtime::AccountId32>>;
320	type ForceOrigin = AssetsForceOrigin;
321	// Deposits are zero because creation/admin is limited to Asset Conversion pallet.
322	type AssetDeposit = ConstU128<0>;
323	type AssetAccountDeposit = ConstU128<0>;
324	type MetadataDepositBase = ConstU128<0>;
325	type MetadataDepositPerByte = ConstU128<0>;
326	type ApprovalDeposit = ApprovalDeposit;
327	type StringLimit = ConstU32<50>;
328	type Holder = ();
329	type Freezer = PoolAssetsFreezer;
330	type Extra = ();
331	type WeightInfo = weights::pallet_assets_pool::WeightInfo<Runtime>;
332	type CallbackHandle = ();
333	#[cfg(feature = "runtime-benchmarks")]
334	type BenchmarkHelper = ();
335}
336
337// Allow Freezes for the `PoolAssets` pallet
338pub type PoolAssetsFreezerInstance = pallet_assets_freezer::Instance3;
339impl pallet_assets_freezer::Config<PoolAssetsFreezerInstance> for Runtime {
340	type RuntimeFreezeReason = RuntimeFreezeReason;
341	type RuntimeEvent = RuntimeEvent;
342}
343
344/// Union fungibles implementation for `Assets` and `ForeignAssets`.
345pub type LocalAndForeignAssets = fungibles::UnionOf<
346	Assets,
347	ForeignAssets,
348	LocalFromLeft<
349		AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation, xcm::v5::Location>,
350		AssetIdForTrustBackedAssets,
351		xcm::v5::Location,
352	>,
353	xcm::v5::Location,
354	AccountId,
355>;
356
357/// Union fungibles implementation for `AssetsFreezer` and `ForeignAssetsFreezer`.
358pub type LocalAndForeignAssetsFreezer = fungibles::UnionOf<
359	AssetsFreezer,
360	ForeignAssetsFreezer,
361	LocalFromLeft<
362		AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation, xcm::v5::Location>,
363		AssetIdForTrustBackedAssets,
364		xcm::v5::Location,
365	>,
366	xcm::v5::Location,
367	AccountId,
368>;
369
370/// Union fungibles implementation for [`LocalAndForeignAssets`] and [`Balances`].
371pub type NativeAndNonPoolAssets = fungible::UnionOf<
372	Balances,
373	LocalAndForeignAssets,
374	TargetFromLeft<TokenLocation, xcm::v5::Location>,
375	xcm::v5::Location,
376	AccountId,
377>;
378
379/// Union fungibles implementation for [`LocalAndForeignAssetsFreezer`] and [`Balances`].
380pub type NativeAndNonPoolAssetsFreezer = fungible::UnionOf<
381	Balances,
382	LocalAndForeignAssetsFreezer,
383	TargetFromLeft<TokenLocation, xcm::v5::Location>,
384	xcm::v5::Location,
385	AccountId,
386>;
387
388/// Union fungibles implementation for [`PoolAssets`] and [`NativeAndNonPoolAssets`].
389///
390/// NOTE: Should be kept updated to include ALL balances and assets in the runtime.
391pub type NativeAndAllAssets = fungibles::UnionOf<
392	PoolAssets,
393	NativeAndNonPoolAssets,
394	LocalFromLeft<
395		AssetIdForPoolAssetsConvert<PoolAssetsPalletLocation, xcm::v5::Location>,
396		AssetIdForPoolAssets,
397		xcm::v5::Location,
398	>,
399	xcm::v5::Location,
400	AccountId,
401>;
402
403/// Union fungibles implementation for [`PoolAssetsFreezer`] and [`NativeAndNonPoolAssetsFreezer`].
404///
405/// NOTE: Should be kept updated to include ALL balances and assets in the runtime.
406pub type NativeAndAllAssetsFreezer = fungibles::UnionOf<
407	PoolAssetsFreezer,
408	NativeAndNonPoolAssetsFreezer,
409	LocalFromLeft<
410		AssetIdForPoolAssetsConvert<PoolAssetsPalletLocation, xcm::v5::Location>,
411		AssetIdForPoolAssets,
412		xcm::v5::Location,
413	>,
414	xcm::v5::Location,
415	AccountId,
416>;
417
418pub type PoolIdToAccountId = pallet_asset_conversion::AccountIdConverter<
419	AssetConversionPalletId,
420	(xcm::v5::Location, xcm::v5::Location),
421>;
422
423impl pallet_asset_conversion::Config for Runtime {
424	type RuntimeEvent = RuntimeEvent;
425	type Balance = Balance;
426	type HigherPrecisionBalance = sp_core::U256;
427	type AssetKind = xcm::v5::Location;
428	type Assets = NativeAndNonPoolAssets;
429	type PoolId = (Self::AssetKind, Self::AssetKind);
430	type PoolLocator = pallet_asset_conversion::WithFirstAsset<
431		TokenLocation,
432		AccountId,
433		Self::AssetKind,
434		PoolIdToAccountId,
435	>;
436	type PoolAssetId = u32;
437	type PoolAssets = PoolAssets;
438	type PoolSetupFee = ConstU128<0>; // Asset class deposit fees are sufficient to prevent spam
439	type PoolSetupFeeAsset = TokenLocation;
440	type PoolSetupFeeTarget = ResolveAssetTo<AssetConversionOrigin, Self::Assets>;
441	type LiquidityWithdrawalFee = LiquidityWithdrawalFee;
442	type LPFee = ConstU32<3>;
443	type PalletId = AssetConversionPalletId;
444	type MaxSwapPathLength = ConstU32<3>;
445	type MintMinLiquidity = ConstU128<100>;
446	type WeightInfo = weights::pallet_asset_conversion::WeightInfo<Runtime>;
447	#[cfg(feature = "runtime-benchmarks")]
448	type BenchmarkHelper = assets_common::benchmarks::AssetPairFactory<
449		TokenLocation,
450		parachain_info::Pallet<Runtime>,
451		xcm_config::TrustBackedAssetsPalletIndex,
452		xcm::v5::Location,
453	>;
454}
455
456impl pallet_asset_conversion_ops::Config for Runtime {
457	type RuntimeEvent = RuntimeEvent;
458	type PriorAccountIdConverter = pallet_asset_conversion::AccountIdConverterNoSeed<
459		<Runtime as pallet_asset_conversion::Config>::PoolId,
460	>;
461	type AssetsRefund = <Runtime as pallet_asset_conversion::Config>::Assets;
462	type PoolAssetsRefund = <Runtime as pallet_asset_conversion::Config>::PoolAssets;
463	type PoolAssetsTeam = <Runtime as pallet_asset_conversion::Config>::PoolAssets;
464	type DepositAsset = Balances;
465	type WeightInfo = weights::pallet_asset_conversion_ops::WeightInfo<Runtime>;
466}
467
468parameter_types! {
469	pub const ForeignAssetsAssetDeposit: Balance = CreateForeignAssetDeposit::get();
470	pub const ForeignAssetsAssetAccountDeposit: Balance = AssetAccountDeposit::get();
471	pub const ForeignAssetsApprovalDeposit: Balance = ApprovalDeposit::get();
472	pub const ForeignAssetsAssetsStringLimit: u32 = AssetsStringLimit::get();
473	pub const ForeignAssetsMetadataDepositBase: Balance = MetadataDepositBase::get();
474	pub const ForeignAssetsMetadataDepositPerByte: Balance = MetadataDepositPerByte::get();
475}
476
477/// Assets managed by some foreign location. Note: we do not declare a `ForeignAssetsCall` type, as
478/// this type is used in proxy definitions. We assume that a foreign location would not want to set
479/// an individual, local account as a proxy for the issuance of their assets. This issuance should
480/// be managed by the foreign location's governance.
481pub type ForeignAssetsInstance = pallet_assets::Instance2;
482impl pallet_assets::Config<ForeignAssetsInstance> for Runtime {
483	type RuntimeEvent = RuntimeEvent;
484	type Balance = Balance;
485	type AssetId = xcm::v5::Location;
486	type AssetIdParameter = xcm::v5::Location;
487	type ReserveData = ForeignAssetReserveData;
488	type Currency = Balances;
489	type CreateOrigin = ForeignCreators<
490		(
491			FromSiblingParachain<parachain_info::Pallet<Runtime>, xcm::v5::Location>,
492			FromNetwork<xcm_config::UniversalLocation, EthereumNetwork, xcm::v5::Location>,
493			xcm_config::bridging::to_westend::WestendOrEthereumAssetFromAssetHubWestend,
494		),
495		LocationToAccountId,
496		AccountId,
497		xcm::v5::Location,
498	>;
499	type ForceOrigin = AssetsForceOrigin;
500	type AssetDeposit = ForeignAssetsAssetDeposit;
501	type MetadataDepositBase = ForeignAssetsMetadataDepositBase;
502	type MetadataDepositPerByte = ForeignAssetsMetadataDepositPerByte;
503	type ApprovalDeposit = ForeignAssetsApprovalDeposit;
504	type StringLimit = ForeignAssetsAssetsStringLimit;
505	type Holder = ();
506	type Freezer = ForeignAssetsFreezer;
507	type Extra = ();
508	type WeightInfo = weights::pallet_assets_foreign::WeightInfo<Runtime>;
509	type CallbackHandle = ();
510	type AssetAccountDeposit = ForeignAssetsAssetAccountDeposit;
511	type RemoveItemsLimit = frame_support::traits::ConstU32<1000>;
512	#[cfg(feature = "runtime-benchmarks")]
513	type BenchmarkHelper = assets_common::benchmarks::LocationAssetsBenchmarkHelper;
514}
515
516// Allow Freezes for the `ForeignAssets` pallet
517pub type ForeignAssetsFreezerInstance = pallet_assets_freezer::Instance2;
518impl pallet_assets_freezer::Config<ForeignAssetsFreezerInstance> for Runtime {
519	type RuntimeFreezeReason = RuntimeFreezeReason;
520	type RuntimeEvent = RuntimeEvent;
521}
522
523parameter_types! {
524	// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
525	pub const DepositBase: Balance = deposit(1, 88);
526	// Additional storage item size of 32 bytes.
527	pub const DepositFactor: Balance = deposit(0, 32);
528	pub const MaxSignatories: u32 = 100;
529}
530
531impl pallet_multisig::Config for Runtime {
532	type RuntimeEvent = RuntimeEvent;
533	type RuntimeCall = RuntimeCall;
534	type Currency = Balances;
535	type DepositBase = DepositBase;
536	type DepositFactor = DepositFactor;
537	type MaxSignatories = MaxSignatories;
538	type WeightInfo = weights::pallet_multisig::WeightInfo<Runtime>;
539	type BlockNumberProvider = frame_system::Pallet<Runtime>;
540}
541
542impl pallet_utility::Config for Runtime {
543	type RuntimeEvent = RuntimeEvent;
544	type RuntimeCall = RuntimeCall;
545	type PalletsOrigin = OriginCaller;
546	type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
547}
548
549parameter_types! {
550	// One storage item; key size 32, value size 8; .
551	pub const ProxyDepositBase: Balance = deposit(1, 40);
552	// Additional storage item size of 33 bytes.
553	pub const ProxyDepositFactor: Balance = deposit(0, 33);
554	pub const MaxProxies: u16 = 32;
555	// One storage item; key size 32, value size 16
556	pub const AnnouncementDepositBase: Balance = deposit(1, 48);
557	pub const AnnouncementDepositFactor: Balance = deposit(0, 66);
558	pub const MaxPending: u16 = 32;
559}
560
561/// The type used to represent the kinds of proxying allowed.
562#[derive(
563	Copy,
564	Clone,
565	Eq,
566	PartialEq,
567	Ord,
568	PartialOrd,
569	Encode,
570	Decode,
571	DecodeWithMemTracking,
572	RuntimeDebug,
573	MaxEncodedLen,
574	scale_info::TypeInfo,
575)]
576pub enum ProxyType {
577	/// Fully permissioned proxy. Can execute any call on behalf of _proxied_.
578	Any,
579	/// Can execute any call that does not transfer funds or assets.
580	NonTransfer,
581	/// Proxy with the ability to reject time-delay proxy announcements.
582	CancelProxy,
583	/// Assets proxy. Can execute any call from `assets`, **including asset transfers**.
584	Assets,
585	/// Owner proxy. Can execute calls related to asset ownership.
586	AssetOwner,
587	/// Asset manager. Can execute calls related to asset management.
588	AssetManager,
589	/// Collator selection proxy. Can execute calls related to collator selection mechanism.
590	Collator,
591}
592impl Default for ProxyType {
593	fn default() -> Self {
594		Self::Any
595	}
596}
597
598impl InstanceFilter<RuntimeCall> for ProxyType {
599	fn filter(&self, c: &RuntimeCall) -> bool {
600		match self {
601			ProxyType::Any => true,
602			ProxyType::NonTransfer => !matches!(
603				c,
604				RuntimeCall::Balances { .. } |
605					RuntimeCall::Assets { .. } |
606					RuntimeCall::NftFractionalization { .. } |
607					RuntimeCall::Nfts { .. } |
608					RuntimeCall::Uniques { .. }
609			),
610			ProxyType::CancelProxy => matches!(
611				c,
612				RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) |
613					RuntimeCall::Utility { .. } |
614					RuntimeCall::Multisig { .. }
615			),
616			ProxyType::Assets => {
617				matches!(
618					c,
619					RuntimeCall::Assets { .. } |
620						RuntimeCall::Utility { .. } |
621						RuntimeCall::Multisig { .. } |
622						RuntimeCall::NftFractionalization { .. } |
623						RuntimeCall::Nfts { .. } |
624						RuntimeCall::Uniques { .. }
625				)
626			},
627			ProxyType::AssetOwner => matches!(
628				c,
629				RuntimeCall::Assets(TrustBackedAssetsCall::create { .. }) |
630					RuntimeCall::Assets(TrustBackedAssetsCall::start_destroy { .. }) |
631					RuntimeCall::Assets(TrustBackedAssetsCall::destroy_accounts { .. }) |
632					RuntimeCall::Assets(TrustBackedAssetsCall::destroy_approvals { .. }) |
633					RuntimeCall::Assets(TrustBackedAssetsCall::finish_destroy { .. }) |
634					RuntimeCall::Assets(TrustBackedAssetsCall::transfer_ownership { .. }) |
635					RuntimeCall::Assets(TrustBackedAssetsCall::set_team { .. }) |
636					RuntimeCall::Assets(TrustBackedAssetsCall::set_metadata { .. }) |
637					RuntimeCall::Assets(TrustBackedAssetsCall::clear_metadata { .. }) |
638					RuntimeCall::Assets(TrustBackedAssetsCall::set_min_balance { .. }) |
639					RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) |
640					RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) |
641					RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) |
642					RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) |
643					RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) |
644					RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) |
645					RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) |
646					RuntimeCall::Uniques(pallet_uniques::Call::create { .. }) |
647					RuntimeCall::Uniques(pallet_uniques::Call::destroy { .. }) |
648					RuntimeCall::Uniques(pallet_uniques::Call::transfer_ownership { .. }) |
649					RuntimeCall::Uniques(pallet_uniques::Call::set_team { .. }) |
650					RuntimeCall::Uniques(pallet_uniques::Call::set_metadata { .. }) |
651					RuntimeCall::Uniques(pallet_uniques::Call::set_attribute { .. }) |
652					RuntimeCall::Uniques(pallet_uniques::Call::set_collection_metadata { .. }) |
653					RuntimeCall::Uniques(pallet_uniques::Call::clear_metadata { .. }) |
654					RuntimeCall::Uniques(pallet_uniques::Call::clear_attribute { .. }) |
655					RuntimeCall::Uniques(pallet_uniques::Call::clear_collection_metadata { .. }) |
656					RuntimeCall::Uniques(pallet_uniques::Call::set_collection_max_supply { .. }) |
657					RuntimeCall::Utility { .. } |
658					RuntimeCall::Multisig { .. }
659			),
660			ProxyType::AssetManager => matches!(
661				c,
662				RuntimeCall::Assets(TrustBackedAssetsCall::mint { .. }) |
663					RuntimeCall::Assets(TrustBackedAssetsCall::burn { .. }) |
664					RuntimeCall::Assets(TrustBackedAssetsCall::freeze { .. }) |
665					RuntimeCall::Assets(TrustBackedAssetsCall::block { .. }) |
666					RuntimeCall::Assets(TrustBackedAssetsCall::thaw { .. }) |
667					RuntimeCall::Assets(TrustBackedAssetsCall::freeze_asset { .. }) |
668					RuntimeCall::Assets(TrustBackedAssetsCall::thaw_asset { .. }) |
669					RuntimeCall::Assets(TrustBackedAssetsCall::touch_other { .. }) |
670					RuntimeCall::Assets(TrustBackedAssetsCall::refund_other { .. }) |
671					RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) |
672					RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) |
673					RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) |
674					RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) |
675					RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) |
676					RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) |
677					RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) |
678					RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) |
679					RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) |
680					RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) |
681					RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) |
682					RuntimeCall::Uniques(pallet_uniques::Call::mint { .. }) |
683					RuntimeCall::Uniques(pallet_uniques::Call::burn { .. }) |
684					RuntimeCall::Uniques(pallet_uniques::Call::freeze { .. }) |
685					RuntimeCall::Uniques(pallet_uniques::Call::thaw { .. }) |
686					RuntimeCall::Uniques(pallet_uniques::Call::freeze_collection { .. }) |
687					RuntimeCall::Uniques(pallet_uniques::Call::thaw_collection { .. }) |
688					RuntimeCall::Utility { .. } |
689					RuntimeCall::Multisig { .. }
690			),
691			ProxyType::Collator => matches!(
692				c,
693				RuntimeCall::CollatorSelection { .. } |
694					RuntimeCall::Utility { .. } |
695					RuntimeCall::Multisig { .. }
696			),
697		}
698	}
699
700	fn is_superset(&self, o: &Self) -> bool {
701		match (self, o) {
702			(x, y) if x == y => true,
703			(ProxyType::Any, _) => true,
704			(_, ProxyType::Any) => false,
705			(ProxyType::Assets, ProxyType::AssetOwner) => true,
706			(ProxyType::Assets, ProxyType::AssetManager) => true,
707			(ProxyType::NonTransfer, ProxyType::Collator) => true,
708			_ => false,
709		}
710	}
711}
712
713impl pallet_proxy::Config for Runtime {
714	type RuntimeEvent = RuntimeEvent;
715	type RuntimeCall = RuntimeCall;
716	type Currency = Balances;
717	type ProxyType = ProxyType;
718	type ProxyDepositBase = ProxyDepositBase;
719	type ProxyDepositFactor = ProxyDepositFactor;
720	type MaxProxies = MaxProxies;
721	type WeightInfo = weights::pallet_proxy::WeightInfo<Runtime>;
722	type MaxPending = MaxPending;
723	type CallHasher = BlakeTwo256;
724	type AnnouncementDepositBase = AnnouncementDepositBase;
725	type AnnouncementDepositFactor = AnnouncementDepositFactor;
726	type BlockNumberProvider = frame_system::Pallet<Runtime>;
727}
728
729parameter_types! {
730	pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
731	pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
732}
733
734impl cumulus_pallet_parachain_system::Config for Runtime {
735	type WeightInfo = weights::cumulus_pallet_parachain_system::WeightInfo<Runtime>;
736	type RuntimeEvent = RuntimeEvent;
737	type OnSystemEvent = ();
738	type SelfParaId = parachain_info::Pallet<Runtime>;
739	type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
740	type ReservedDmpWeight = ReservedDmpWeight;
741	type OutboundXcmpMessageSource = XcmpQueue;
742	type XcmpMessageHandler = XcmpQueue;
743	type ReservedXcmpWeight = ReservedXcmpWeight;
744	type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases;
745	type ConsensusHook = ConsensusHook;
746	type RelayParentOffset = ConstU32<0>;
747}
748
749type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
750	Runtime,
751	RELAY_CHAIN_SLOT_DURATION_MILLIS,
752	BLOCK_PROCESSING_VELOCITY,
753	UNINCLUDED_SEGMENT_CAPACITY,
754>;
755
756parameter_types! {
757	pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block;
758}
759
760impl pallet_message_queue::Config for Runtime {
761	type RuntimeEvent = RuntimeEvent;
762	type WeightInfo = weights::pallet_message_queue::WeightInfo<Runtime>;
763	#[cfg(feature = "runtime-benchmarks")]
764	type MessageProcessor = pallet_message_queue::mock_helpers::NoopMessageProcessor<
765		cumulus_primitives_core::AggregateMessageOrigin,
766	>;
767	#[cfg(not(feature = "runtime-benchmarks"))]
768	type MessageProcessor = xcm_builder::ProcessXcmMessage<
769		AggregateMessageOrigin,
770		xcm_executor::XcmExecutor<xcm_config::XcmConfig>,
771		RuntimeCall,
772	>;
773	type Size = u32;
774	// The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin:
775	type QueueChangeHandler = NarrowOriginToSibling<XcmpQueue>;
776	type QueuePausedQuery = NarrowOriginToSibling<XcmpQueue>;
777	type HeapSize = sp_core::ConstU32<{ 103 * 1024 }>;
778	type MaxStale = sp_core::ConstU32<8>;
779	type ServiceWeight = MessageQueueServiceWeight;
780	type IdleMaxServiceWeight = MessageQueueServiceWeight;
781}
782
783impl parachain_info::Config for Runtime {}
784
785impl cumulus_pallet_aura_ext::Config for Runtime {}
786
787parameter_types! {
788	/// The asset ID for the asset that we use to pay for message delivery fees.
789	pub FeeAssetId: AssetId = AssetId(xcm_config::TokenLocation::get());
790	/// The base fee for the message delivery fees.
791	pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3);
792}
793
794pub type PriceForSiblingParachainDelivery = polkadot_runtime_common::xcm_sender::ExponentialPrice<
795	FeeAssetId,
796	BaseDeliveryFee,
797	TransactionByteFee,
798	XcmpQueue,
799>;
800
801impl cumulus_pallet_xcmp_queue::Config for Runtime {
802	type WeightInfo = weights::cumulus_pallet_xcmp_queue::WeightInfo<Runtime>;
803	type RuntimeEvent = RuntimeEvent;
804	type ChannelInfo = ParachainSystem;
805	type VersionWrapper = PolkadotXcm;
806	type XcmpQueue = TransformOrigin<MessageQueue, AggregateMessageOrigin, ParaId, ParaIdToSibling>;
807	type MaxInboundSuspended = ConstU32<1_000>;
808	type MaxActiveOutboundChannels = ConstU32<128>;
809	// Most on-chain HRMP channels are configured to use 102400 bytes of max message size, so we
810	// need to set the page size larger than that until we reduce the channel size on-chain.
811	type MaxPageSize = ConstU32<{ 103 * 1024 }>;
812	type ControllerOrigin = EnsureRoot<AccountId>;
813	type ControllerOriginConverter = xcm_config::XcmOriginToTransactDispatchOrigin;
814	type PriceForSiblingDelivery = PriceForSiblingParachainDelivery;
815}
816
817impl cumulus_pallet_xcmp_queue::migration::v5::V5Config for Runtime {
818	// This must be the same as the `ChannelInfo` from the `Config`:
819	type ChannelList = ParachainSystem;
820}
821
822parameter_types! {
823	pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
824}
825
826parameter_types! {
827	pub const Period: u32 = 6 * HOURS;
828	pub const Offset: u32 = 0;
829}
830
831impl pallet_session::Config for Runtime {
832	type RuntimeEvent = RuntimeEvent;
833	type ValidatorId = <Self as frame_system::Config>::AccountId;
834	// we don't have stash and controller, thus we don't need the convert as well.
835	type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
836	type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
837	type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
838	type SessionManager = CollatorSelection;
839	// Essentially just Aura, but let's be pedantic.
840	type SessionHandler = <SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
841	type Keys = SessionKeys;
842	type DisablingStrategy = ();
843	type WeightInfo = weights::pallet_session::WeightInfo<Runtime>;
844	type Currency = Balances;
845	type KeyDeposit = ();
846}
847
848impl pallet_aura::Config for Runtime {
849	type AuthorityId = AuraId;
850	type DisabledValidators = ();
851	type MaxAuthorities = ConstU32<100_000>;
852	type AllowMultipleBlocksPerSlot = ConstBool<true>;
853	type SlotDuration = ConstU64<SLOT_DURATION>;
854}
855
856parameter_types! {
857	pub const PotId: PalletId = PalletId(*b"PotStake");
858	pub const SessionLength: BlockNumber = 6 * HOURS;
859	// StakingAdmin pluralistic body.
860	pub const StakingAdminBodyId: BodyId = BodyId::Defense;
861}
862
863/// We allow root and the `StakingAdmin` to execute privileged collator selection operations.
864pub type CollatorSelectionUpdateOrigin = EitherOfDiverse<
865	EnsureRoot<AccountId>,
866	EnsureXcm<IsVoiceOfBody<GovernanceLocation, StakingAdminBodyId>>,
867>;
868
869impl pallet_collator_selection::Config for Runtime {
870	type RuntimeEvent = RuntimeEvent;
871	type Currency = Balances;
872	type UpdateOrigin = CollatorSelectionUpdateOrigin;
873	type PotId = PotId;
874	type MaxCandidates = ConstU32<100>;
875	type MinEligibleCollators = ConstU32<4>;
876	type MaxInvulnerables = ConstU32<20>;
877	// should be a multiple of session or things will get inconsistent
878	type KickThreshold = Period;
879	type ValidatorId = <Self as frame_system::Config>::AccountId;
880	type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
881	type ValidatorRegistration = Session;
882	type WeightInfo = weights::pallet_collator_selection::WeightInfo<Runtime>;
883}
884
885parameter_types! {
886	pub StakingPot: AccountId = CollatorSelection::account_id();
887}
888
889impl pallet_asset_conversion_tx_payment::Config for Runtime {
890	type RuntimeEvent = RuntimeEvent;
891	type AssetId = xcm::v5::Location;
892	type OnChargeAssetTransaction = SwapAssetAdapter<
893		TokenLocation,
894		NativeAndNonPoolAssets,
895		AssetConversion,
896		ResolveAssetTo<StakingPot, NativeAndNonPoolAssets>,
897	>;
898	type WeightInfo = weights::pallet_asset_conversion_tx_payment::WeightInfo<Runtime>;
899	#[cfg(feature = "runtime-benchmarks")]
900	type BenchmarkHelper = AssetConversionTxHelper;
901}
902
903parameter_types! {
904	pub const UniquesCollectionDeposit: Balance = UNITS / 10; // 1 / 10 UNIT deposit to create a collection
905	pub const UniquesItemDeposit: Balance = UNITS / 1_000; // 1 / 1000 UNIT deposit to mint an item
906	pub const UniquesMetadataDepositBase: Balance = deposit(1, 129);
907	pub const UniquesAttributeDepositBase: Balance = deposit(1, 0);
908	pub const UniquesDepositPerByte: Balance = deposit(0, 1);
909}
910
911impl pallet_uniques::Config for Runtime {
912	type RuntimeEvent = RuntimeEvent;
913	type CollectionId = CollectionId;
914	type ItemId = ItemId;
915	type Currency = Balances;
916	type ForceOrigin = AssetsForceOrigin;
917	type CollectionDeposit = UniquesCollectionDeposit;
918	type ItemDeposit = UniquesItemDeposit;
919	type MetadataDepositBase = UniquesMetadataDepositBase;
920	type AttributeDepositBase = UniquesAttributeDepositBase;
921	type DepositPerByte = UniquesDepositPerByte;
922	type StringLimit = ConstU32<128>;
923	type KeyLimit = ConstU32<32>;
924	type ValueLimit = ConstU32<64>;
925	type WeightInfo = weights::pallet_uniques::WeightInfo<Runtime>;
926	#[cfg(feature = "runtime-benchmarks")]
927	type Helper = ();
928	type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
929	type Locker = ();
930}
931
932parameter_types! {
933	pub const NftFractionalizationPalletId: PalletId = PalletId(*b"fraction");
934	pub NewAssetSymbol: BoundedVec<u8, AssetsStringLimit> = (*b"FRAC").to_vec().try_into().unwrap();
935	pub NewAssetName: BoundedVec<u8, AssetsStringLimit> = (*b"Frac").to_vec().try_into().unwrap();
936}
937
938impl pallet_nft_fractionalization::Config for Runtime {
939	type RuntimeEvent = RuntimeEvent;
940	type Deposit = AssetDeposit;
941	type Currency = Balances;
942	type NewAssetSymbol = NewAssetSymbol;
943	type NewAssetName = NewAssetName;
944	type StringLimit = AssetsStringLimit;
945	type NftCollectionId = <Self as pallet_nfts::Config>::CollectionId;
946	type NftId = <Self as pallet_nfts::Config>::ItemId;
947	type AssetBalance = <Self as pallet_balances::Config>::Balance;
948	type AssetId = <Self as pallet_assets::Config<TrustBackedAssetsInstance>>::AssetId;
949	type Assets = Assets;
950	type Nfts = Nfts;
951	type PalletId = NftFractionalizationPalletId;
952	type WeightInfo = weights::pallet_nft_fractionalization::WeightInfo<Runtime>;
953	type RuntimeHoldReason = RuntimeHoldReason;
954	#[cfg(feature = "runtime-benchmarks")]
955	type BenchmarkHelper = ();
956}
957
958parameter_types! {
959	pub NftsPalletFeatures: PalletFeatures = PalletFeatures::all_enabled();
960	pub const NftsMaxDeadlineDuration: BlockNumber = 12 * 30 * DAYS;
961	// re-use the Uniques deposits
962	pub const NftsCollectionDeposit: Balance = UniquesCollectionDeposit::get();
963	pub const NftsItemDeposit: Balance = UniquesItemDeposit::get();
964	pub const NftsMetadataDepositBase: Balance = UniquesMetadataDepositBase::get();
965	pub const NftsAttributeDepositBase: Balance = UniquesAttributeDepositBase::get();
966	pub const NftsDepositPerByte: Balance = UniquesDepositPerByte::get();
967}
968
969impl pallet_nfts::Config for Runtime {
970	type RuntimeEvent = RuntimeEvent;
971	type CollectionId = CollectionId;
972	type ItemId = ItemId;
973	type Currency = Balances;
974	type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
975	type ForceOrigin = AssetsForceOrigin;
976	type Locker = ();
977	type CollectionDeposit = NftsCollectionDeposit;
978	type ItemDeposit = NftsItemDeposit;
979	type MetadataDepositBase = NftsMetadataDepositBase;
980	type AttributeDepositBase = NftsAttributeDepositBase;
981	type DepositPerByte = NftsDepositPerByte;
982	type StringLimit = ConstU32<256>;
983	type KeyLimit = ConstU32<64>;
984	type ValueLimit = ConstU32<256>;
985	type ApprovalsLimit = ConstU32<20>;
986	type ItemAttributesApprovalsLimit = ConstU32<30>;
987	type MaxTips = ConstU32<10>;
988	type MaxDeadlineDuration = NftsMaxDeadlineDuration;
989	type MaxAttributesPerCall = ConstU32<10>;
990	type Features = NftsPalletFeatures;
991	type OffchainSignature = Signature;
992	type OffchainPublic = <Signature as Verify>::Signer;
993	type WeightInfo = weights::pallet_nfts::WeightInfo<Runtime>;
994	#[cfg(feature = "runtime-benchmarks")]
995	type Helper = ();
996	type BlockNumberProvider = frame_system::Pallet<Runtime>;
997}
998
999/// XCM router instance to BridgeHub with bridging capabilities for `Westend` global
1000/// consensus with dynamic fees and back-pressure.
1001pub type ToWestendXcmRouterInstance = pallet_xcm_bridge_hub_router::Instance3;
1002impl pallet_xcm_bridge_hub_router::Config<ToWestendXcmRouterInstance> for Runtime {
1003	type RuntimeEvent = RuntimeEvent;
1004	type WeightInfo = weights::pallet_xcm_bridge_hub_router::WeightInfo<Runtime>;
1005
1006	type UniversalLocation = xcm_config::UniversalLocation;
1007	type SiblingBridgeHubLocation = xcm_config::bridging::SiblingBridgeHub;
1008	type BridgedNetworkId = xcm_config::bridging::to_westend::WestendNetwork;
1009	type Bridges = xcm_config::bridging::NetworkExportTable;
1010	type DestinationVersion = PolkadotXcm;
1011
1012	type BridgeHubOrigin = frame_support::traits::EitherOfDiverse<
1013		EnsureRoot<AccountId>,
1014		EnsureXcm<Equals<Self::SiblingBridgeHubLocation>>,
1015	>;
1016	type ToBridgeHubSender = XcmpQueue;
1017	type LocalXcmChannelManager =
1018		cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider<Runtime>;
1019
1020	type ByteFee = xcm_config::bridging::XcmBridgeHubRouterByteFee;
1021	type FeeAsset = xcm_config::bridging::XcmBridgeHubRouterFeeAssetId;
1022}
1023
1024#[cfg(feature = "runtime-benchmarks")]
1025pub struct PalletAssetRewardsBenchmarkHelper;
1026
1027#[cfg(feature = "runtime-benchmarks")]
1028impl pallet_asset_rewards::benchmarking::BenchmarkHelper<xcm::v5::Location>
1029	for PalletAssetRewardsBenchmarkHelper
1030{
1031	fn staked_asset() -> Location {
1032		Location::new(
1033			0,
1034			[PalletInstance(<Assets as PalletInfoAccess>::index() as u8), GeneralIndex(100)],
1035		)
1036	}
1037	fn reward_asset() -> Location {
1038		Location::new(
1039			0,
1040			[PalletInstance(<Assets as PalletInfoAccess>::index() as u8), GeneralIndex(101)],
1041		)
1042	}
1043}
1044
1045parameter_types! {
1046	pub const AssetRewardsPalletId: PalletId = PalletId(*b"py/astrd");
1047	pub const RewardsPoolCreationHoldReason: RuntimeHoldReason =
1048		RuntimeHoldReason::AssetRewards(pallet_asset_rewards::HoldReason::PoolCreation);
1049	// 1 item, 135 bytes into the storage on pool creation.
1050	pub const StakePoolCreationDeposit: Balance = deposit(1, 135);
1051}
1052
1053impl pallet_asset_rewards::Config for Runtime {
1054	type RuntimeEvent = RuntimeEvent;
1055	type PalletId = AssetRewardsPalletId;
1056	type Balance = Balance;
1057	type Assets = NativeAndAllAssets;
1058	type AssetsFreezer = NativeAndAllAssetsFreezer;
1059	type AssetId = xcm::v5::Location;
1060	type CreatePoolOrigin = EnsureSigned<AccountId>;
1061	type RuntimeFreezeReason = RuntimeFreezeReason;
1062	type Consideration = HoldConsideration<
1063		AccountId,
1064		Balances,
1065		RewardsPoolCreationHoldReason,
1066		ConstantStoragePrice<StakePoolCreationDeposit, Balance>,
1067	>;
1068	type WeightInfo = weights::pallet_asset_rewards::WeightInfo<Runtime>;
1069	type BlockNumberProvider = frame_system::Pallet<Runtime>;
1070	#[cfg(feature = "runtime-benchmarks")]
1071	type BenchmarkHelper = PalletAssetRewardsBenchmarkHelper;
1072}
1073
1074// Create the runtime by composing the FRAME pallets that were previously configured.
1075construct_runtime!(
1076	pub enum Runtime
1077	{
1078		// System support stuff.
1079		System: frame_system = 0,
1080		ParachainSystem: cumulus_pallet_parachain_system = 1,
1081		Timestamp: pallet_timestamp = 3,
1082		ParachainInfo: parachain_info = 4,
1083		WeightReclaim: cumulus_pallet_weight_reclaim = 5,
1084
1085		// Monetary stuff.
1086		Balances: pallet_balances = 10,
1087		TransactionPayment: pallet_transaction_payment = 11,
1088		AssetTxPayment: pallet_asset_conversion_tx_payment = 13,
1089
1090		// Collator support. the order of these 5 are important and shall not change.
1091		Authorship: pallet_authorship = 20,
1092		CollatorSelection: pallet_collator_selection = 21,
1093		Session: pallet_session = 22,
1094		Aura: pallet_aura = 23,
1095		AuraExt: cumulus_pallet_aura_ext = 24,
1096
1097		// XCM helpers.
1098		XcmpQueue: cumulus_pallet_xcmp_queue = 30,
1099		PolkadotXcm: pallet_xcm = 31,
1100		CumulusXcm: cumulus_pallet_xcm = 32,
1101		MessageQueue: pallet_message_queue = 34,
1102
1103		// Handy utilities.
1104		Utility: pallet_utility = 40,
1105		Multisig: pallet_multisig = 41,
1106		Proxy: pallet_proxy = 42,
1107
1108		// Bridge utilities.
1109		ToWestendXcmRouter: pallet_xcm_bridge_hub_router::<Instance3> = 45,
1110
1111		// The main stage.
1112		Assets: pallet_assets::<Instance1> = 50,
1113		Uniques: pallet_uniques = 51,
1114		Nfts: pallet_nfts = 52,
1115		ForeignAssets: pallet_assets::<Instance2> = 53,
1116		NftFractionalization: pallet_nft_fractionalization = 54,
1117		PoolAssets: pallet_assets::<Instance3> = 55,
1118		AssetConversion: pallet_asset_conversion = 56,
1119
1120		AssetsFreezer: pallet_assets_freezer::<Instance1> = 57,
1121		ForeignAssetsFreezer: pallet_assets_freezer::<Instance2> = 58,
1122		PoolAssetsFreezer: pallet_assets_freezer::<Instance3> = 59,
1123
1124		AssetRewards: pallet_asset_rewards = 60,
1125
1126		// TODO: the pallet instance should be removed once all pools have migrated
1127		// to the new account IDs.
1128		AssetConversionMigration: pallet_asset_conversion_ops = 200,
1129	}
1130);
1131
1132/// The address format for describing accounts.
1133pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
1134/// Block type as expected by this runtime.
1135pub type Block = generic::Block<Header, UncheckedExtrinsic>;
1136/// A Block signed with a Justification
1137pub type SignedBlock = generic::SignedBlock<Block>;
1138/// BlockId type as expected by this runtime.
1139pub type BlockId = generic::BlockId<Block>;
1140/// The extension to the basic transaction logic.
1141pub type TxExtension = cumulus_pallet_weight_reclaim::StorageWeightReclaim<
1142	Runtime,
1143	(
1144		frame_system::AuthorizeCall<Runtime>,
1145		frame_system::CheckNonZeroSender<Runtime>,
1146		frame_system::CheckSpecVersion<Runtime>,
1147		frame_system::CheckTxVersion<Runtime>,
1148		frame_system::CheckGenesis<Runtime>,
1149		frame_system::CheckEra<Runtime>,
1150		frame_system::CheckNonce<Runtime>,
1151		frame_system::CheckWeight<Runtime>,
1152		pallet_asset_conversion_tx_payment::ChargeAssetTxPayment<Runtime>,
1153		frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
1154	),
1155>;
1156/// Unchecked extrinsic type as expected by this runtime.
1157pub type UncheckedExtrinsic =
1158	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
1159/// Migrations to apply on runtime upgrade.
1160pub type Migrations = (
1161	InitStorageVersions,
1162	// unreleased
1163	cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4<Runtime>,
1164	cumulus_pallet_xcmp_queue::migration::v5::MigrateV4ToV5<Runtime>,
1165	pallet_collator_selection::migration::v2::MigrationToV2<Runtime>,
1166	frame_support::migrations::RemovePallet<StateTrieMigrationName, RocksDbWeight>,
1167	// unreleased
1168	pallet_assets::migration::next_asset_id::SetNextAssetId<
1169		ConstU32<50_000_000>,
1170		Runtime,
1171		TrustBackedAssetsInstance,
1172	>,
1173	pallet_session::migrations::v1::MigrateV0ToV1<
1174		Runtime,
1175		pallet_session::migrations::v1::InitOffenceSeverity<Runtime>,
1176	>,
1177	// permanent
1178	pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,
1179	cumulus_pallet_aura_ext::migration::MigrateV0ToV1<Runtime>,
1180);
1181
1182parameter_types! {
1183	pub const StateTrieMigrationName: &'static str = "StateTrieMigration";
1184}
1185
1186/// Migration to initialize storage versions for pallets added after genesis.
1187///
1188/// This is now done automatically (see <https://github.com/paritytech/polkadot-sdk/pull/1297>),
1189/// but some pallets had made it in and had storage set in them for this parachain before it was
1190/// merged.
1191pub struct InitStorageVersions;
1192
1193impl frame_support::traits::OnRuntimeUpgrade for InitStorageVersions {
1194	fn on_runtime_upgrade() -> Weight {
1195		use frame_support::traits::{GetStorageVersion, StorageVersion};
1196
1197		let mut writes = 0;
1198
1199		if PolkadotXcm::on_chain_storage_version() == StorageVersion::new(0) {
1200			PolkadotXcm::in_code_storage_version().put::<PolkadotXcm>();
1201			writes.saturating_inc();
1202		}
1203
1204		if Multisig::on_chain_storage_version() == StorageVersion::new(0) {
1205			Multisig::in_code_storage_version().put::<Multisig>();
1206			writes.saturating_inc();
1207		}
1208
1209		if Assets::on_chain_storage_version() == StorageVersion::new(0) {
1210			Assets::in_code_storage_version().put::<Assets>();
1211			writes.saturating_inc();
1212		}
1213
1214		if Uniques::on_chain_storage_version() == StorageVersion::new(0) {
1215			Uniques::in_code_storage_version().put::<Uniques>();
1216			writes.saturating_inc();
1217		}
1218
1219		if Nfts::on_chain_storage_version() == StorageVersion::new(0) {
1220			Nfts::in_code_storage_version().put::<Nfts>();
1221			writes.saturating_inc();
1222		}
1223
1224		if ForeignAssets::on_chain_storage_version() == StorageVersion::new(0) {
1225			ForeignAssets::in_code_storage_version().put::<ForeignAssets>();
1226			writes.saturating_inc();
1227		}
1228
1229		if PoolAssets::on_chain_storage_version() == StorageVersion::new(0) {
1230			PoolAssets::in_code_storage_version().put::<PoolAssets>();
1231			writes.saturating_inc();
1232		}
1233
1234		<Runtime as frame_system::Config>::DbWeight::get().reads_writes(7, writes)
1235	}
1236}
1237
1238/// Executive: handles dispatch to the various modules.
1239pub type Executive = frame_executive::Executive<
1240	Runtime,
1241	Block,
1242	frame_system::ChainContext<Runtime>,
1243	Runtime,
1244	AllPalletsWithSystem,
1245>;
1246
1247#[cfg(feature = "runtime-benchmarks")]
1248pub struct AssetConversionTxHelper;
1249
1250#[cfg(feature = "runtime-benchmarks")]
1251impl
1252	pallet_asset_conversion_tx_payment::BenchmarkHelperTrait<
1253		AccountId,
1254		cumulus_primitives_core::Location,
1255		cumulus_primitives_core::Location,
1256	> for AssetConversionTxHelper
1257{
1258	fn create_asset_id_parameter(seed: u32) -> (Location, Location) {
1259		// Use a different parachain' foreign assets pallet so that the asset is indeed foreign.
1260		let asset_id = Location::new(
1261			1,
1262			[
1263				cumulus_primitives_core::Junction::Parachain(3000),
1264				cumulus_primitives_core::Junction::PalletInstance(53),
1265				cumulus_primitives_core::Junction::GeneralIndex(seed.into()),
1266			],
1267		);
1268		(asset_id.clone(), asset_id)
1269	}
1270
1271	fn setup_balances_and_pool(asset_id: cumulus_primitives_core::Location, account: AccountId) {
1272		use frame_support::{assert_ok, traits::fungibles::Mutate};
1273		assert_ok!(ForeignAssets::force_create(
1274			RuntimeOrigin::root(),
1275			asset_id.clone().into(),
1276			account.clone().into(), /* owner */
1277			true,                   /* is_sufficient */
1278			1,
1279		));
1280
1281		let lp_provider = account.clone();
1282		use frame_support::traits::Currency;
1283		let _ = Balances::deposit_creating(&lp_provider, u64::MAX.into());
1284		assert_ok!(ForeignAssets::mint_into(
1285			asset_id.clone().into(),
1286			&lp_provider,
1287			u64::MAX.into()
1288		));
1289
1290		let token_native = alloc::boxed::Box::new(TokenLocation::get());
1291		let token_second = alloc::boxed::Box::new(asset_id);
1292
1293		assert_ok!(AssetConversion::create_pool(
1294			RuntimeOrigin::signed(lp_provider.clone()),
1295			token_native.clone(),
1296			token_second.clone()
1297		));
1298
1299		assert_ok!(AssetConversion::add_liquidity(
1300			RuntimeOrigin::signed(lp_provider.clone()),
1301			token_native,
1302			token_second,
1303			(u32::MAX / 8).into(), // 1 desired
1304			u32::MAX.into(),       // 2 desired
1305			1,                     // 1 min
1306			1,                     // 2 min
1307			lp_provider,
1308		));
1309	}
1310}
1311
1312#[cfg(feature = "runtime-benchmarks")]
1313mod benches {
1314	frame_benchmarking::define_benchmarks!(
1315		[frame_system, SystemBench::<Runtime>]
1316		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
1317		[pallet_assets, Local]
1318		[pallet_assets, Foreign]
1319		[pallet_assets, Pool]
1320		[pallet_asset_conversion, AssetConversion]
1321		[pallet_asset_rewards, AssetRewards]
1322		[pallet_asset_conversion_tx_payment, AssetTxPayment]
1323		[pallet_balances, Balances]
1324		[pallet_message_queue, MessageQueue]
1325		[pallet_multisig, Multisig]
1326		[pallet_nft_fractionalization, NftFractionalization]
1327		[pallet_nfts, Nfts]
1328		[pallet_proxy, Proxy]
1329		[pallet_session, SessionBench::<Runtime>]
1330		[pallet_uniques, Uniques]
1331		[pallet_utility, Utility]
1332		[pallet_timestamp, Timestamp]
1333		[pallet_transaction_payment, TransactionPayment]
1334		[pallet_collator_selection, CollatorSelection]
1335		[cumulus_pallet_parachain_system, ParachainSystem]
1336		[cumulus_pallet_xcmp_queue, XcmpQueue]
1337		[pallet_xcm_bridge_hub_router, ToWestend]
1338		[pallet_asset_conversion_ops, AssetConversionMigration]
1339		// XCM
1340		[pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
1341		// NOTE: Make sure you point to the individual modules below.
1342		[pallet_xcm_benchmarks::fungible, XcmBalances]
1343		[pallet_xcm_benchmarks::generic, XcmGeneric]
1344		[cumulus_pallet_weight_reclaim, WeightReclaim]
1345	);
1346}
1347
1348impl_runtime_apis! {
1349	impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
1350		fn slot_duration() -> sp_consensus_aura::SlotDuration {
1351			sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION)
1352		}
1353
1354		fn authorities() -> Vec<AuraId> {
1355			pallet_aura::Authorities::<Runtime>::get().into_inner()
1356		}
1357	}
1358
1359	impl cumulus_primitives_core::RelayParentOffsetApi<Block> for Runtime {
1360		fn relay_parent_offset() -> u32 {
1361			0
1362		}
1363	}
1364
1365	impl cumulus_primitives_aura::AuraUnincludedSegmentApi<Block> for Runtime {
1366		fn can_build_upon(
1367			included_hash: <Block as BlockT>::Hash,
1368			slot: cumulus_primitives_aura::Slot,
1369		) -> bool {
1370			ConsensusHook::can_build_upon(included_hash, slot)
1371		}
1372	}
1373
1374	impl sp_api::Core<Block> for Runtime {
1375		fn version() -> RuntimeVersion {
1376			VERSION
1377		}
1378
1379		fn execute_block(block: <Block as BlockT>::LazyBlock) {
1380			Executive::execute_block(block)
1381		}
1382
1383		fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
1384			Executive::initialize_block(header)
1385		}
1386	}
1387
1388	impl sp_api::Metadata<Block> for Runtime {
1389		fn metadata() -> OpaqueMetadata {
1390			OpaqueMetadata::new(Runtime::metadata().into())
1391		}
1392
1393		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
1394			Runtime::metadata_at_version(version)
1395		}
1396
1397		fn metadata_versions() -> alloc::vec::Vec<u32> {
1398			Runtime::metadata_versions()
1399		}
1400	}
1401
1402	impl sp_block_builder::BlockBuilder<Block> for Runtime {
1403		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
1404			Executive::apply_extrinsic(extrinsic)
1405		}
1406
1407		fn finalize_block() -> <Block as BlockT>::Header {
1408			Executive::finalize_block()
1409		}
1410
1411		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
1412			data.create_extrinsics()
1413		}
1414
1415		fn check_inherents(
1416			block: <Block as BlockT>::LazyBlock,
1417			data: sp_inherents::InherentData,
1418		) -> sp_inherents::CheckInherentsResult {
1419			data.check_extrinsics(&block)
1420		}
1421	}
1422
1423	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
1424		fn validate_transaction(
1425			source: TransactionSource,
1426			tx: <Block as BlockT>::Extrinsic,
1427			block_hash: <Block as BlockT>::Hash,
1428		) -> TransactionValidity {
1429			Executive::validate_transaction(source, tx, block_hash)
1430		}
1431	}
1432
1433	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
1434		fn offchain_worker(header: &<Block as BlockT>::Header) {
1435			Executive::offchain_worker(header)
1436		}
1437	}
1438
1439	impl sp_session::SessionKeys<Block> for Runtime {
1440		fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
1441			SessionKeys::generate(seed)
1442		}
1443
1444		fn decode_session_keys(
1445			encoded: Vec<u8>,
1446		) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
1447			SessionKeys::decode_into_raw_public_keys(&encoded)
1448		}
1449	}
1450
1451	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
1452		fn account_nonce(account: AccountId) -> Nonce {
1453			System::account_nonce(account)
1454		}
1455	}
1456
1457	impl pallet_asset_conversion::AssetConversionApi<
1458		Block,
1459		Balance,
1460		xcm::v5::Location,
1461	> for Runtime
1462	{
1463		fn quote_price_exact_tokens_for_tokens(asset1: xcm::v5::Location, asset2: xcm::v5::Location, amount: Balance, include_fee: bool) -> Option<Balance> {
1464			AssetConversion::quote_price_exact_tokens_for_tokens(asset1, asset2, amount, include_fee)
1465		}
1466		fn quote_price_tokens_for_exact_tokens(asset1: xcm::v5::Location, asset2: xcm::v5::Location, amount: Balance, include_fee: bool) -> Option<Balance> {
1467			AssetConversion::quote_price_tokens_for_exact_tokens(asset1, asset2, amount, include_fee)
1468		}
1469		fn get_reserves(asset1: xcm::v5::Location, asset2: xcm::v5::Location) -> Option<(Balance, Balance)> {
1470			AssetConversion::get_reserves(asset1, asset2).ok()
1471		}
1472	}
1473
1474	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
1475		fn query_info(
1476			uxt: <Block as BlockT>::Extrinsic,
1477			len: u32,
1478		) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
1479			TransactionPayment::query_info(uxt, len)
1480		}
1481		fn query_fee_details(
1482			uxt: <Block as BlockT>::Extrinsic,
1483			len: u32,
1484		) -> pallet_transaction_payment::FeeDetails<Balance> {
1485			TransactionPayment::query_fee_details(uxt, len)
1486		}
1487		fn query_weight_to_fee(weight: Weight) -> Balance {
1488			TransactionPayment::weight_to_fee(weight)
1489		}
1490		fn query_length_to_fee(length: u32) -> Balance {
1491			TransactionPayment::length_to_fee(length)
1492		}
1493	}
1494
1495	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
1496		for Runtime
1497	{
1498		fn query_call_info(
1499			call: RuntimeCall,
1500			len: u32,
1501		) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
1502			TransactionPayment::query_call_info(call, len)
1503		}
1504		fn query_call_fee_details(
1505			call: RuntimeCall,
1506			len: u32,
1507		) -> pallet_transaction_payment::FeeDetails<Balance> {
1508			TransactionPayment::query_call_fee_details(call, len)
1509		}
1510		fn query_weight_to_fee(weight: Weight) -> Balance {
1511			TransactionPayment::weight_to_fee(weight)
1512		}
1513		fn query_length_to_fee(length: u32) -> Balance {
1514			TransactionPayment::length_to_fee(length)
1515		}
1516	}
1517
1518	impl assets_common::runtime_api::FungiblesApi<
1519		Block,
1520		AccountId,
1521	> for Runtime
1522	{
1523		fn query_account_balances(account: AccountId) -> Result<xcm::VersionedAssets, assets_common::runtime_api::FungiblesAccessError> {
1524			use assets_common::fungible_conversion::{convert, convert_balance};
1525			Ok([
1526				// collect pallet_balance
1527				{
1528					let balance = Balances::free_balance(account.clone());
1529					if balance > 0 {
1530						vec![convert_balance::<TokenLocation, Balance>(balance)?]
1531					} else {
1532						vec![]
1533					}
1534				},
1535				// collect pallet_assets (TrustBackedAssets)
1536				convert::<_, _, _, _, TrustBackedAssetsConvertedConcreteId>(
1537					Assets::account_balances(account.clone())
1538						.iter()
1539						.filter(|(_, balance)| balance > &0)
1540				)?,
1541				// collect pallet_assets (ForeignAssets)
1542				convert::<_, _, _, _, ForeignAssetsConvertedConcreteId>(
1543					ForeignAssets::account_balances(account.clone())
1544						.iter()
1545						.filter(|(_, balance)| balance > &0)
1546				)?,
1547				// collect pallet_assets (PoolAssets)
1548				convert::<_, _, _, _, PoolAssetsConvertedConcreteId>(
1549					PoolAssets::account_balances(account)
1550						.iter()
1551						.filter(|(_, balance)| balance > &0)
1552				)?,
1553				// collect ... e.g. other tokens
1554			].concat().into())
1555		}
1556	}
1557
1558	impl xcm_runtime_apis::fees::XcmPaymentApi<Block> for Runtime {
1559		fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
1560			let native_token = xcm_config::TokenLocation::get();
1561			// We accept the native token to pay fees.
1562			let mut acceptable_assets = vec![AssetId(native_token.clone())];
1563			// We also accept all assets in a pool with the native token.
1564			acceptable_assets.extend(
1565				assets_common::PoolAdapter::<Runtime>::get_assets_in_pool_with(native_token)
1566				.map_err(|()| XcmPaymentApiError::VersionedConversionFailed)?
1567			);
1568			PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets)
1569		}
1570
1571		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
1572			type Trader = <XcmConfig as xcm_executor::Config>::Trader;
1573			PolkadotXcm::query_weight_to_asset_fee::<Trader>(weight, asset)
1574		}
1575
1576		fn query_xcm_weight(message: VersionedXcm<()>) -> Result<Weight, XcmPaymentApiError> {
1577			PolkadotXcm::query_xcm_weight(message)
1578		}
1579
1580		fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>, asset_id: VersionedAssetId) -> Result<VersionedAssets, XcmPaymentApiError> {
1581			type AssetExchanger = <XcmConfig as xcm_executor::Config>::AssetExchanger;
1582			PolkadotXcm::query_delivery_fees::<AssetExchanger>(destination, message, asset_id)
1583		}
1584	}
1585
1586	impl xcm_runtime_apis::dry_run::DryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
1587		fn dry_run_call(origin: OriginCaller, call: RuntimeCall, result_xcms_version: XcmVersion) -> Result<CallDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
1588			PolkadotXcm::dry_run_call::<Runtime, xcm_config::XcmRouter, OriginCaller, RuntimeCall>(origin, call, result_xcms_version)
1589		}
1590
1591		fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
1592			PolkadotXcm::dry_run_xcm::<xcm_config::XcmRouter>(origin_location, xcm)
1593		}
1594	}
1595
1596	impl xcm_runtime_apis::conversions::LocationToAccountApi<Block, AccountId> for Runtime {
1597		fn convert_location(location: VersionedLocation) -> Result<
1598			AccountId,
1599			xcm_runtime_apis::conversions::Error
1600		> {
1601			xcm_runtime_apis::conversions::LocationToAccountHelper::<
1602				AccountId,
1603				xcm_config::LocationToAccountId,
1604			>::convert_location(location)
1605		}
1606	}
1607
1608	impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
1609		fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
1610			ParachainSystem::collect_collation_info(header)
1611		}
1612	}
1613
1614	impl pallet_asset_rewards::AssetRewards<Block, Balance> for Runtime {
1615		fn pool_creation_cost() -> Balance {
1616			StakePoolCreationDeposit::get()
1617		}
1618	}
1619
1620	#[cfg(feature = "try-runtime")]
1621	impl frame_try_runtime::TryRuntime<Block> for Runtime {
1622		fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
1623			let weight = Executive::try_runtime_upgrade(checks).unwrap();
1624			(weight, RuntimeBlockWeights::get().max_block)
1625		}
1626
1627		fn execute_block(
1628			block: <Block as BlockT>::LazyBlock,
1629			state_root_check: bool,
1630			signature_check: bool,
1631			select: frame_try_runtime::TryStateSelect,
1632		) -> Weight {
1633			// NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
1634			// have a backtrace here.
1635			Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()
1636		}
1637	}
1638
1639	#[cfg(feature = "runtime-benchmarks")]
1640	impl frame_benchmarking::Benchmark<Block> for Runtime {
1641		fn benchmark_metadata(extra: bool) -> (
1642			Vec<frame_benchmarking::BenchmarkList>,
1643			Vec<frame_support::traits::StorageInfo>,
1644		) {
1645			use frame_benchmarking::BenchmarkList;
1646			use frame_support::traits::StorageInfoTrait;
1647			use frame_system_benchmarking::Pallet as SystemBench;
1648			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
1649			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
1650			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
1651			use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench;
1652
1653			// This is defined once again in dispatch_benchmark, because list_benchmarks!
1654			// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
1655			// are referenced in that call.
1656			type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
1657			type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::<Runtime>;
1658
1659			// Benchmark files generated for `Assets/ForeignAssets` instances are by default
1660			// `pallet_assets_assets.rs / pallet_assets_foreign_assets`, which is not really nice,
1661			// so with this redefinition we can change names to nicer:
1662			// `pallet_assets_local.rs / pallet_assets_foreign.rs`.
1663			type Local = pallet_assets::Pallet::<Runtime, TrustBackedAssetsInstance>;
1664			type Foreign = pallet_assets::Pallet::<Runtime, ForeignAssetsInstance>;
1665			type Pool = pallet_assets::Pallet::<Runtime, PoolAssetsInstance>;
1666
1667			type ToWestend = XcmBridgeHubRouterBench<Runtime, ToWestendXcmRouterInstance>;
1668
1669			let mut list = Vec::<BenchmarkList>::new();
1670			list_benchmarks!(list, extra);
1671
1672			let storage_info = AllPalletsWithSystem::storage_info();
1673			(list, storage_info)
1674		}
1675
1676		#[allow(non_local_definitions)]
1677		fn dispatch_benchmark(
1678			config: frame_benchmarking::BenchmarkConfig
1679		) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, alloc::string::String> {
1680			use frame_benchmarking::{BenchmarkBatch, BenchmarkError};
1681			use frame_support::assert_ok;
1682			use sp_storage::TrackedStorageKey;
1683
1684			use frame_system_benchmarking::Pallet as SystemBench;
1685			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
1686			impl frame_system_benchmarking::Config for Runtime {
1687				fn setup_set_code_requirements(code: &alloc::vec::Vec<u8>) -> Result<(), BenchmarkError> {
1688					ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
1689					Ok(())
1690				}
1691
1692				fn verify_set_code() {
1693					System::assert_last_event(cumulus_pallet_parachain_system::Event::<Runtime>::ValidationFunctionStored.into());
1694				}
1695			}
1696
1697			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
1698			impl cumulus_pallet_session_benchmarking::Config for Runtime {}
1699
1700			use pallet_xcm_bridge_hub_router::benchmarking::{
1701				Pallet as XcmBridgeHubRouterBench,
1702				Config as XcmBridgeHubRouterConfig,
1703			};
1704
1705			use testnet_parachains_constants::rococo::locations::{PeopleParaId, PeopleLocation};
1706			parameter_types! {
1707				pub ExistentialDepositAsset: Option<Asset> = Some((
1708					TokenLocation::get(),
1709					ExistentialDeposit::get()
1710				).into());
1711
1712				pub const RandomParaId: ParaId = ParaId::new(43211234);
1713			}
1714
1715			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
1716			impl pallet_xcm::benchmarking::Config for Runtime {
1717				type DeliveryHelper = (
1718				polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
1719						xcm_config::XcmConfig,
1720						ExistentialDepositAsset,
1721						PriceForSiblingParachainDelivery,
1722						RandomParaId,
1723						ParachainSystem
1724					>,
1725				polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
1726						xcm_config::XcmConfig,
1727						ExistentialDepositAsset,
1728						PriceForSiblingParachainDelivery,
1729						PeopleParaId,
1730						ParachainSystem
1731					>);
1732
1733				fn reachable_dest() -> Option<Location> {
1734					Some(PeopleLocation::get())
1735				}
1736
1737				fn teleportable_asset_and_dest() -> Option<(Asset, Location)> {
1738					// Relay/native token can be teleported between AH and Relay.
1739					Some((
1740						Asset {
1741							fun: Fungible(ExistentialDeposit::get()),
1742							id: AssetId(TokenLocation::get())
1743						},
1744						PeopleLocation::get(),
1745					))
1746				}
1747
1748				fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
1749					// We get an account to create USDT and give it enough WND to exist.
1750					let account = frame_benchmarking::whitelisted_caller();
1751					assert_ok!(<Balances as fungible::Mutate<_>>::mint_into(
1752						&account,
1753						ExistentialDeposit::get() + (1_000 * UNITS)
1754					));
1755
1756					// We then create USDT.
1757					let usdt_id = 1984u32;
1758					let usdt_location = Location::new(0, [PalletInstance(50), GeneralIndex(usdt_id.into())]);
1759					assert_ok!(Assets::force_create(
1760						RuntimeOrigin::root(),
1761						usdt_id.into(),
1762						account.clone().into(),
1763						true,
1764						1
1765					));
1766
1767					// And return USDT as the reserve transferable asset.
1768					Some((
1769						Asset { fun: Fungible(ExistentialDeposit::get()), id: AssetId(usdt_location) },
1770						ParentThen(Parachain(RandomParaId::get().into()).into()).into(),
1771					))
1772				}
1773
1774				fn set_up_complex_asset_transfer(
1775				) -> Option<(XcmAssets, u32, Location, alloc::boxed::Box<dyn FnOnce()>)> {
1776					let dest = PeopleLocation::get();
1777
1778					let fee_amount = EXISTENTIAL_DEPOSIT;
1779					let fee_asset: Asset = (TokenLocation::get(), fee_amount).into();
1780
1781					let who = frame_benchmarking::whitelisted_caller();
1782					// Give some multiple of the existential deposit
1783					let balance = fee_amount + EXISTENTIAL_DEPOSIT * 1000;
1784					let _ = <Balances as frame_support::traits::Currency<_>>::make_free_balance_be(
1785						&who, balance,
1786					);
1787					// verify initial balance
1788					assert_eq!(Balances::free_balance(&who), balance);
1789
1790					// set up local asset
1791					let asset_amount = 10u128;
1792					let initial_asset_amount = asset_amount * 10;
1793					let (asset_id, _, _) = pallet_assets::benchmarking::create_default_minted_asset::<
1794						Runtime,
1795						pallet_assets::Instance1
1796					>(true, initial_asset_amount);
1797					let asset_location = Location::new(
1798						0,
1799						[PalletInstance(50), GeneralIndex(u32::from(asset_id).into())]
1800					);
1801					let transfer_asset: Asset = (asset_location, asset_amount).into();
1802
1803					let assets: XcmAssets = vec![fee_asset.clone(), transfer_asset].into();
1804					let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 };
1805
1806					// verify transferred successfully
1807					let verify = alloc::boxed::Box::new(move || {
1808						// verify native balance after transfer, decreased by transferred fee amount
1809						// (plus transport fees)
1810						assert!(Balances::free_balance(&who) <= balance - fee_amount);
1811						// verify asset balance decreased by exactly transferred amount
1812						assert_eq!(
1813							Assets::balance(asset_id.into(), &who),
1814							initial_asset_amount - asset_amount,
1815						);
1816					});
1817					Some((assets, fee_index as u32, dest, verify))
1818				}
1819
1820				fn get_asset() -> Asset {
1821					use frame_benchmarking::whitelisted_caller;
1822					use frame_support::traits::tokens::fungible::{Inspect, Mutate};
1823					let account = whitelisted_caller();
1824					assert_ok!(<Balances as Mutate<_>>::mint_into(
1825						&account,
1826						<Balances as Inspect<_>>::minimum_balance(),
1827					));
1828					let asset_id = 1984;
1829					assert_ok!(Assets::force_create(
1830						RuntimeOrigin::root(),
1831						asset_id.into(),
1832						account.into(),
1833						true,
1834						1u128,
1835					));
1836					let amount = 1_000_000u128;
1837					let asset_location = Location::new(0, [PalletInstance(50), GeneralIndex(u32::from(asset_id).into())]);
1838
1839					Asset {
1840						id: AssetId(asset_location),
1841						fun: Fungible(amount),
1842					}
1843				}
1844			}
1845
1846			impl XcmBridgeHubRouterConfig<ToWestendXcmRouterInstance> for Runtime {
1847				fn make_congested() {
1848					cumulus_pallet_xcmp_queue::bridging::suspend_channel_for_benchmarks::<Runtime>(
1849						xcm_config::bridging::SiblingBridgeHubParaId::get().into()
1850					);
1851				}
1852				fn ensure_bridged_target_destination() -> Result<Location, BenchmarkError> {
1853					ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
1854						xcm_config::bridging::SiblingBridgeHubParaId::get().into()
1855					);
1856					let bridged_asset_hub = xcm_config::bridging::to_westend::AssetHubWestend::get();
1857					let _ = PolkadotXcm::force_xcm_version(
1858						RuntimeOrigin::root(),
1859						alloc::boxed::Box::new(bridged_asset_hub.clone()),
1860						XCM_VERSION,
1861					).map_err(|e| {
1862						tracing::error!(
1863							target: "bridges::benchmark",
1864							error=?e,
1865							origin=?RuntimeOrigin::root(),
1866							location=?bridged_asset_hub,
1867							version=?XCM_VERSION,
1868							"Failed to dispatch `force_xcm_version`"
1869						);
1870						BenchmarkError::Stop("XcmVersion was not stored!")
1871					})?;
1872					Ok(bridged_asset_hub)
1873				}
1874			}
1875
1876			use xcm_config::{TokenLocation, MaxAssetsIntoHolding};
1877			use pallet_xcm_benchmarks::asset_instance_from;
1878
1879			impl pallet_xcm_benchmarks::Config for Runtime {
1880				type XcmConfig = xcm_config::XcmConfig;
1881				type AccountIdConverter = xcm_config::LocationToAccountId;
1882				type DeliveryHelper = polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
1883						xcm_config::XcmConfig,
1884						ExistentialDepositAsset,
1885						PriceForSiblingParachainDelivery,
1886						PeopleParaId,
1887						ParachainSystem
1888					>;
1889				fn valid_destination() -> Result<Location, BenchmarkError> {
1890					Ok(PeopleLocation::get())
1891				}
1892				fn worst_case_holding(depositable_count: u32) -> XcmAssets {
1893					// A mix of fungible, non-fungible, and concrete assets.
1894					let holding_non_fungibles = MaxAssetsIntoHolding::get() / 2 - depositable_count;
1895					let holding_fungibles = holding_non_fungibles.saturating_sub(2);  // -2 for two `iter::once` bellow
1896					let fungibles_amount: u128 = 100;
1897					(0..holding_fungibles)
1898						.map(|i| {
1899							Asset {
1900								id: GeneralIndex(i as u128).into(),
1901								fun: Fungible(fungibles_amount * (i + 1) as u128), // non-zero amount
1902							}
1903						})
1904						.chain(core::iter::once(Asset { id: Here.into(), fun: Fungible(u128::MAX) }))
1905						.chain(core::iter::once(Asset { id: AssetId(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS) }))
1906						.chain((0..holding_non_fungibles).map(|i| Asset {
1907							id: GeneralIndex(i as u128).into(),
1908							fun: NonFungible(asset_instance_from(i)),
1909						}))
1910						.collect::<Vec<_>>()
1911						.into()
1912				}
1913			}
1914
1915			parameter_types! {
1916				pub TrustedTeleporter: Option<(Location, Asset)> = Some((
1917					PeopleLocation::get(),
1918					Asset { fun: Fungible(UNITS), id: AssetId(TokenLocation::get()) },
1919				));
1920				pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None;
1921				// AssetHubRococo trusts AssetHubWestend as reserve for WNDs
1922				pub TrustedReserve: Option<(Location, Asset)> = Some(
1923					(
1924						xcm_config::bridging::to_westend::AssetHubWestend::get(),
1925						Asset::from((xcm_config::bridging::to_westend::WndLocation::get(), 1000000000000 as u128))
1926					)
1927				);
1928			}
1929
1930			impl pallet_xcm_benchmarks::fungible::Config for Runtime {
1931				type TransactAsset = Balances;
1932
1933				type CheckedAccount = CheckedAccount;
1934				type TrustedTeleporter = TrustedTeleporter;
1935				type TrustedReserve = TrustedReserve;
1936
1937				fn get_asset() -> Asset {
1938					use frame_support::traits::tokens::fungible::{Inspect, Mutate};
1939					let (account, _) = pallet_xcm_benchmarks::account_and_location::<Runtime>(1);
1940					assert_ok!(<Balances as Mutate<_>>::mint_into(
1941						&account,
1942						<Balances as Inspect<_>>::minimum_balance(),
1943					));
1944					let asset_id = 1984;
1945					assert_ok!(Assets::force_create(
1946						RuntimeOrigin::root(),
1947						asset_id.into(),
1948						account.clone().into(),
1949						true,
1950						1u128,
1951					));
1952					let amount = 1_000_000u128;
1953					let asset_location = Location::new(0, [PalletInstance(50), GeneralIndex(u32::from(asset_id).into())]);
1954
1955					Asset {
1956						id: AssetId(asset_location),
1957						fun: Fungible(amount),
1958					}
1959				}
1960			}
1961
1962			impl pallet_xcm_benchmarks::generic::Config for Runtime {
1963				type TransactAsset = Balances;
1964				type RuntimeCall = RuntimeCall;
1965
1966				fn worst_case_response() -> (u64, Response) {
1967					(0u64, Response::Version(Default::default()))
1968				}
1969
1970				fn worst_case_asset_exchange() -> Result<(XcmAssets, XcmAssets), BenchmarkError> {
1971					Err(BenchmarkError::Skip)
1972				}
1973
1974				fn universal_alias() -> Result<(Location, Junction), BenchmarkError> {
1975					xcm_config::bridging::BridgingBenchmarksHelper::prepare_universal_alias()
1976					.ok_or(BenchmarkError::Skip)
1977				}
1978
1979				fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> {
1980					Ok((
1981						PeopleLocation::get(),
1982						frame_system::Call::remark_with_event {remark: vec![]}.into()
1983					))
1984				}
1985
1986				fn subscribe_origin() -> Result<Location, BenchmarkError> {
1987					Ok(PeopleLocation::get())
1988				}
1989
1990				fn claimable_asset() -> Result<(Location, Location, XcmAssets), BenchmarkError> {
1991					let origin = PeopleLocation::get();
1992					let assets: XcmAssets = (TokenLocation::get(), 1_000 * UNITS).into();
1993					let ticket = Location { parents: 0, interior: Here };
1994					Ok((origin, ticket, assets))
1995				}
1996
1997				fn worst_case_for_trader() -> Result<(Asset, WeightLimit), BenchmarkError> {
1998					Ok((Asset {
1999						id: AssetId(TokenLocation::get()),
2000						fun: Fungible(1_000_000 * UNITS),
2001					}, WeightLimit::Limited(Weight::from_parts(5000, 5000))))
2002				}
2003
2004				fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> {
2005					Err(BenchmarkError::Skip)
2006				}
2007
2008				fn export_message_origin_and_destination(
2009				) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> {
2010					Err(BenchmarkError::Skip)
2011				}
2012
2013				fn alias_origin() -> Result<(Location, Location), BenchmarkError> {
2014					// Any location can alias to an internal location.
2015					// Here parachain 1001 aliases to an internal account.
2016					Ok((
2017						Location::new(1, [Parachain(1001)]),
2018						Location::new(1, [Parachain(1001), AccountId32 { id: [111u8; 32], network: None }]),
2019					))
2020				}
2021			}
2022
2023			type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
2024			type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::<Runtime>;
2025
2026			type Local = pallet_assets::Pallet::<Runtime, TrustBackedAssetsInstance>;
2027			type Foreign = pallet_assets::Pallet::<Runtime, ForeignAssetsInstance>;
2028			type Pool = pallet_assets::Pallet::<Runtime, PoolAssetsInstance>;
2029
2030			type ToWestend = XcmBridgeHubRouterBench<Runtime, ToWestendXcmRouterInstance>;
2031
2032			use frame_support::traits::WhitelistedStorageKeys;
2033			let whitelist: Vec<TrackedStorageKey> = AllPalletsWithSystem::whitelisted_storage_keys();
2034
2035			let mut batches = Vec::<BenchmarkBatch>::new();
2036			let params = (&config, &whitelist);
2037			add_benchmarks!(params, batches);
2038
2039			Ok(batches)
2040		}
2041	}
2042
2043	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
2044		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
2045			build_state::<RuntimeGenesisConfig>(config)
2046		}
2047
2048		fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
2049			get_preset::<RuntimeGenesisConfig>(id, &genesis_config_presets::get_preset)
2050		}
2051
2052		fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
2053			genesis_config_presets::preset_names()
2054		}
2055	}
2056
2057	impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
2058		fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> xcm_runtime_apis::trusted_query::XcmTrustedQueryResult {
2059			PolkadotXcm::is_trusted_reserve(asset, location)
2060		}
2061		fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> xcm_runtime_apis::trusted_query::XcmTrustedQueryResult {
2062			PolkadotXcm::is_trusted_teleporter(asset, location)
2063		}
2064	}
2065
2066	impl cumulus_primitives_core::GetParachainInfo<Block> for Runtime {
2067		fn parachain_id() -> ParaId {
2068			ParachainInfo::parachain_id()
2069		}
2070	}
2071
2072	impl cumulus_primitives_core::TargetBlockRate<Block> for Runtime {
2073		fn target_block_rate() -> u32 {
2074			1
2075		}
2076	}
2077
2078	impl xcm_runtime_apis::authorized_aliases::AuthorizedAliasersApi<Block> for Runtime {
2079		fn authorized_aliasers(target: VersionedLocation) -> Result<
2080			Vec<xcm_runtime_apis::authorized_aliases::OriginAliaser>,
2081			xcm_runtime_apis::authorized_aliases::Error
2082		> {
2083			PolkadotXcm::authorized_aliasers(target)
2084		}
2085		fn is_authorized_alias(origin: VersionedLocation, target: VersionedLocation) -> Result<
2086			bool,
2087			xcm_runtime_apis::authorized_aliases::Error
2088		> {
2089			PolkadotXcm::is_authorized_alias(origin, target)
2090		}
2091	}
2092}
2093
2094cumulus_pallet_parachain_system::register_validate_block! {
2095	Runtime = Runtime,
2096	BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
2097}