Skip to main content

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