referrerpolicy=no-referrer-when-downgrade

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