referrerpolicy=no-referrer-when-downgrade

asset_hub_westend_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 Westend Runtime
17//!
18//! Testnet for Asset Hub Polkadot.
19
20#![cfg_attr(not(feature = "std"), no_std)]
21#![recursion_limit = "512"]
22
23// Make the WASM binary available.
24#[cfg(feature = "std")]
25include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
26
27mod bridge_to_ethereum_config;
28mod genesis_config_presets;
29mod weights;
30pub mod xcm_config;
31
32// Configurations for next functionality.
33mod bag_thresholds;
34pub mod governance;
35mod staking;
36use governance::{pallet_custom_origins, FellowshipAdmin, GeneralAdmin, StakingAdmin, Treasurer};
37
38extern crate alloc;
39
40use alloc::{vec, vec::Vec};
41use assets_common::{
42	local_and_foreign_assets::{LocalFromLeft, TargetFromLeft},
43	AssetIdForPoolAssets, AssetIdForPoolAssetsConvert, AssetIdForTrustBackedAssetsConvert,
44};
45use bp_asset_hub_westend::CreateForeignAssetDeposit;
46use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
47use cumulus_pallet_parachain_system::{RelayNumberMonotonicallyIncreases, RelaychainDataProvider};
48use cumulus_primitives_core::{relay_chain::AccountIndex, AggregateMessageOrigin, ParaId};
49use frame_support::{
50	construct_runtime, derive_impl,
51	dispatch::DispatchClass,
52	genesis_builder_helper::{build_state, get_preset},
53	ord_parameter_types, parameter_types,
54	traits::{
55		fungible::{self, HoldConsideration},
56		fungibles,
57		tokens::{imbalance::ResolveAssetTo, nonfungibles_v2::Inspect},
58		AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8,
59		ConstantStoragePrice, EitherOfDiverse, Equals, InstanceFilter, LinearStoragePrice, Nothing,
60		TransformOrigin, WithdrawReasons,
61	},
62	weights::{ConstantMultiplier, Weight},
63	BoundedVec, PalletId,
64};
65use frame_system::{
66	limits::{BlockLength, BlockWeights},
67	EnsureRoot, EnsureSigned, EnsureSignedBy,
68};
69use pallet_asset_conversion_tx_payment::SwapAssetAdapter;
70use pallet_assets::precompiles::{InlineIdConfig, ERC20};
71use pallet_nfts::{DestroyWitness, PalletFeatures};
72use pallet_nomination_pools::PoolId;
73use pallet_revive::evm::runtime::EthExtra;
74use pallet_xcm::{precompiles::XcmPrecompile, EnsureXcm};
75use parachains_common::{
76	impls::DealWithFees, message_queue::*, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance,
77	BlockNumber, CollectionId, Hash, Header, ItemId, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO,
78	NORMAL_DISPATCH_RATIO,
79};
80use sp_api::impl_runtime_apis;
81use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
82use sp_runtime::{
83	generic, impl_opaque_keys,
84	traits::{AccountIdConversion, BlakeTwo256, Block as BlockT, ConvertInto, Saturating, Verify},
85	transaction_validity::{TransactionSource, TransactionValidity},
86	ApplyExtrinsicResult, Perbill, Permill, RuntimeDebug,
87};
88#[cfg(feature = "std")]
89use sp_version::NativeVersion;
90use sp_version::RuntimeVersion;
91use testnet_parachains_constants::westend::{
92	consensus::*, currency::*, fee::WeightToFee, snowbridge::EthereumNetwork, time::*,
93};
94use westend_runtime_constants::time::DAYS as RC_DAYS;
95use xcm_config::{
96	ForeignAssetsConvertedConcreteId, LocationToAccountId, PoolAssetsConvertedConcreteId,
97	PoolAssetsPalletLocation, TrustBackedAssetsConvertedConcreteId,
98	TrustBackedAssetsPalletLocation, WestendLocation, XcmOriginToTransactDispatchOrigin,
99};
100
101#[cfg(any(feature = "std", test))]
102pub use sp_runtime::BuildStorage;
103
104use assets_common::{
105	foreign_creators::ForeignCreators,
106	matching::{FromNetwork, FromSiblingParachain},
107};
108use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
109use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, InMemoryDbWeight};
110use xcm::{
111	latest::prelude::AssetId,
112	prelude::{
113		VersionedAsset, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm,
114		XcmVersion,
115	},
116};
117
118#[cfg(feature = "runtime-benchmarks")]
119use frame_support::traits::PalletInfoAccess;
120
121#[cfg(feature = "runtime-benchmarks")]
122use xcm::latest::prelude::{
123	Asset, Assets as XcmAssets, Fungible, Here, InteriorLocation, Junction, Junction::*, Location,
124	NetworkId, NonFungible, ParentThen, Response, WeightLimit, XCM_VERSION,
125};
126
127use xcm_runtime_apis::{
128	dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
129	fees::Error as XcmPaymentApiError,
130};
131
132impl_opaque_keys! {
133	pub struct SessionKeys {
134		pub aura: Aura,
135	}
136}
137
138#[sp_version::runtime_version]
139pub const VERSION: RuntimeVersion = RuntimeVersion {
140	// Note: "westmint" is the legacy name for this chain. It has been renamed to
141	// "asset-hub-westend". Many wallets/tools depend on the `spec_name`, so it remains "westmint"
142	// for the time being. Wallets/tools should update to treat "asset-hub-westend" equally.
143	spec_name: alloc::borrow::Cow::Borrowed("westmint"),
144	impl_name: alloc::borrow::Cow::Borrowed("westmint"),
145	authoring_version: 1,
146	spec_version: 1_019_004,
147	impl_version: 0,
148	apis: RUNTIME_API_VERSIONS,
149	transaction_version: 16,
150	system_version: 1,
151};
152
153/// The version information used to identify this runtime when compiled natively.
154#[cfg(feature = "std")]
155pub fn native_version() -> NativeVersion {
156	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
157}
158
159parameter_types! {
160	pub const Version: RuntimeVersion = VERSION;
161	pub RuntimeBlockLength: BlockLength =
162		BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
163	pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
164		.base_block(BlockExecutionWeight::get())
165		.for_class(DispatchClass::all(), |weights| {
166			weights.base_extrinsic = ExtrinsicBaseWeight::get();
167		})
168		.for_class(DispatchClass::Normal, |weights| {
169			weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
170		})
171		.for_class(DispatchClass::Operational, |weights| {
172			weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
173			// Operational transactions have some extra reserved space, so that they
174			// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
175			weights.reserved = Some(
176				MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
177			);
178		})
179		.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
180		.build_or_panic();
181	pub const SS58Prefix: u8 = 42;
182}
183
184// Configure FRAME pallets to include in runtime.
185#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig)]
186impl frame_system::Config for Runtime {
187	type BlockWeights = RuntimeBlockWeights;
188	type BlockLength = RuntimeBlockLength;
189	type AccountId = AccountId;
190	type Nonce = Nonce;
191	type Hash = Hash;
192	type Block = Block;
193	type BlockHashCount = BlockHashCount;
194	type DbWeight = InMemoryDbWeight;
195	type Version = Version;
196	type AccountData = pallet_balances::AccountData<Balance>;
197	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
198	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
199	type SS58Prefix = SS58Prefix;
200	type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
201	type MaxConsumers = frame_support::traits::ConstU32<16>;
202	type MultiBlockMigrator = MultiBlockMigrations;
203	type SingleBlockMigrations = Migrations;
204}
205
206impl cumulus_pallet_weight_reclaim::Config for Runtime {
207	type WeightInfo = weights::cumulus_pallet_weight_reclaim::WeightInfo<Runtime>;
208}
209
210impl pallet_timestamp::Config for Runtime {
211	/// A timestamp: milliseconds since the unix epoch.
212	type Moment = u64;
213	type OnTimestampSet = Aura;
214	type MinimumPeriod = ConstU64<0>;
215	type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
216}
217
218impl pallet_authorship::Config for Runtime {
219	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
220	type EventHandler = (CollatorSelection,);
221}
222
223parameter_types! {
224	pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
225}
226
227impl pallet_balances::Config for Runtime {
228	type MaxLocks = ConstU32<50>;
229	/// The type for recording an account's balance.
230	type Balance = Balance;
231	/// The ubiquitous event type.
232	type RuntimeEvent = RuntimeEvent;
233	type DustRemoval = ();
234	type ExistentialDeposit = ExistentialDeposit;
235	type AccountStore = System;
236	type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
237	type MaxReserves = ConstU32<50>;
238	type ReserveIdentifier = [u8; 8];
239	type RuntimeHoldReason = RuntimeHoldReason;
240	type RuntimeFreezeReason = RuntimeFreezeReason;
241	type FreezeIdentifier = RuntimeFreezeReason;
242	type MaxFreezes = frame_support::traits::VariantCountOf<RuntimeFreezeReason>;
243	type DoneSlashHandler = ();
244}
245
246parameter_types! {
247	/// Relay Chain `TransactionByteFee` / 10
248	pub const TransactionByteFee: Balance = MILLICENTS;
249}
250
251impl pallet_transaction_payment::Config for Runtime {
252	type RuntimeEvent = RuntimeEvent;
253	type OnChargeTransaction =
254		pallet_transaction_payment::FungibleAdapter<Balances, DealWithFees<Runtime>>;
255	type WeightToFee = WeightToFee;
256	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
257	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
258	type OperationalFeeMultiplier = ConstU8<5>;
259	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
260}
261
262parameter_types! {
263	pub const AssetDeposit: Balance = UNITS / 10; // 1 / 10 WND deposit to create asset
264	pub const AssetAccountDeposit: Balance = deposit(1, 16);
265	pub const ApprovalDeposit: Balance = EXISTENTIAL_DEPOSIT;
266	pub const AssetsStringLimit: u32 = 50;
267	/// Key = 32 bytes, Value = 36 bytes (32+1+1+1+1)
268	// https://github.com/paritytech/substrate/blob/069917b/frame/assets/src/lib.rs#L257L271
269	pub const MetadataDepositBase: Balance = deposit(1, 68);
270	pub const MetadataDepositPerByte: Balance = deposit(0, 1);
271}
272
273pub type AssetsForceOrigin = EnsureRoot<AccountId>;
274
275// Called "Trust Backed" assets because these are generally registered by some account, and users of
276// the asset assume it has some claimed backing. The pallet is called `Assets` in
277// `construct_runtime` to avoid breaking changes on storage reads.
278pub type TrustBackedAssetsInstance = pallet_assets::Instance1;
279type TrustBackedAssetsCall = pallet_assets::Call<Runtime, TrustBackedAssetsInstance>;
280impl pallet_assets::Config<TrustBackedAssetsInstance> for Runtime {
281	type RuntimeEvent = RuntimeEvent;
282	type Balance = Balance;
283	type AssetId = AssetIdForTrustBackedAssets;
284	type AssetIdParameter = codec::Compact<AssetIdForTrustBackedAssets>;
285	type Currency = Balances;
286	type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
287	type ForceOrigin = AssetsForceOrigin;
288	type AssetDeposit = AssetDeposit;
289	type MetadataDepositBase = MetadataDepositBase;
290	type MetadataDepositPerByte = MetadataDepositPerByte;
291	type ApprovalDeposit = ApprovalDeposit;
292	type StringLimit = AssetsStringLimit;
293	type Holder = ();
294	type Freezer = AssetsFreezer;
295	type Extra = ();
296	type WeightInfo = weights::pallet_assets_local::WeightInfo<Runtime>;
297	type CallbackHandle = pallet_assets::AutoIncAssetId<Runtime, TrustBackedAssetsInstance>;
298	type AssetAccountDeposit = AssetAccountDeposit;
299	type RemoveItemsLimit = ConstU32<1000>;
300	#[cfg(feature = "runtime-benchmarks")]
301	type BenchmarkHelper = ();
302}
303
304// Allow Freezes for the `Assets` pallet
305pub type AssetsFreezerInstance = pallet_assets_freezer::Instance1;
306impl pallet_assets_freezer::Config<AssetsFreezerInstance> for Runtime {
307	type RuntimeFreezeReason = RuntimeFreezeReason;
308	type RuntimeEvent = RuntimeEvent;
309}
310
311parameter_types! {
312	pub const AssetConversionPalletId: PalletId = PalletId(*b"py/ascon");
313	pub const LiquidityWithdrawalFee: Permill = Permill::from_percent(0);
314}
315
316ord_parameter_types! {
317	pub const AssetConversionOrigin: sp_runtime::AccountId32 =
318		AccountIdConversion::<sp_runtime::AccountId32>::into_account_truncating(&AssetConversionPalletId::get());
319}
320
321pub type PoolAssetsInstance = pallet_assets::Instance3;
322impl pallet_assets::Config<PoolAssetsInstance> for Runtime {
323	type RuntimeEvent = RuntimeEvent;
324	type Balance = Balance;
325	type RemoveItemsLimit = ConstU32<1000>;
326	type AssetId = u32;
327	type AssetIdParameter = u32;
328	type Currency = Balances;
329	type CreateOrigin =
330		AsEnsureOriginWithArg<EnsureSignedBy<AssetConversionOrigin, sp_runtime::AccountId32>>;
331	type ForceOrigin = AssetsForceOrigin;
332	type AssetDeposit = ConstU128<0>;
333	type AssetAccountDeposit = ConstU128<0>;
334	type MetadataDepositBase = ConstU128<0>;
335	type MetadataDepositPerByte = ConstU128<0>;
336	type ApprovalDeposit = ConstU128<0>;
337	type StringLimit = ConstU32<50>;
338	type Holder = ();
339	type Freezer = PoolAssetsFreezer;
340	type Extra = ();
341	type WeightInfo = weights::pallet_assets_pool::WeightInfo<Runtime>;
342	type CallbackHandle = ();
343	#[cfg(feature = "runtime-benchmarks")]
344	type BenchmarkHelper = ();
345}
346
347// Allow Freezes for the `PoolAssets` pallet
348pub type PoolAssetsFreezerInstance = pallet_assets_freezer::Instance3;
349impl pallet_assets_freezer::Config<PoolAssetsFreezerInstance> for Runtime {
350	type RuntimeFreezeReason = RuntimeFreezeReason;
351	type RuntimeEvent = RuntimeEvent;
352}
353
354/// Union fungibles implementation for `Assets` and `ForeignAssets`.
355pub type LocalAndForeignAssets = fungibles::UnionOf<
356	Assets,
357	ForeignAssets,
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 `AssetsFreezer` and `ForeignAssetsFreezer`.
368pub type LocalAndForeignAssetsFreezer = fungibles::UnionOf<
369	AssetsFreezer,
370	ForeignAssetsFreezer,
371	LocalFromLeft<
372		AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation, xcm::v5::Location>,
373		AssetIdForTrustBackedAssets,
374		xcm::v5::Location,
375	>,
376	xcm::v5::Location,
377	AccountId,
378>;
379
380/// Union fungibles implementation for [`LocalAndForeignAssets`] and `Balances`.
381pub type NativeAndNonPoolAssets = fungible::UnionOf<
382	Balances,
383	LocalAndForeignAssets,
384	TargetFromLeft<WestendLocation, xcm::v5::Location>,
385	xcm::v5::Location,
386	AccountId,
387>;
388
389/// Union fungibles implementation for [`LocalAndForeignAssetsFreezer`] and [`Balances`].
390pub type NativeAndNonPoolAssetsFreezer = fungible::UnionOf<
391	Balances,
392	LocalAndForeignAssetsFreezer,
393	TargetFromLeft<WestendLocation, xcm::v5::Location>,
394	xcm::v5::Location,
395	AccountId,
396>;
397
398/// Union fungibles implementation for [`PoolAssets`] and [`NativeAndNonPoolAssets`].
399///
400/// NOTE: Should be kept updated to include ALL balances and assets in the runtime.
401pub type NativeAndAllAssets = fungibles::UnionOf<
402	PoolAssets,
403	NativeAndNonPoolAssets,
404	LocalFromLeft<
405		AssetIdForPoolAssetsConvert<PoolAssetsPalletLocation, xcm::v5::Location>,
406		AssetIdForPoolAssets,
407		xcm::v5::Location,
408	>,
409	xcm::v5::Location,
410	AccountId,
411>;
412
413/// Union fungibles implementation for [`PoolAssetsFreezer`] and [`NativeAndNonPoolAssetsFreezer`].
414///
415/// NOTE: Should be kept updated to include ALL balances and assets in the runtime.
416pub type NativeAndAllAssetsFreezer = fungibles::UnionOf<
417	PoolAssetsFreezer,
418	NativeAndNonPoolAssetsFreezer,
419	LocalFromLeft<
420		AssetIdForPoolAssetsConvert<PoolAssetsPalletLocation, xcm::v5::Location>,
421		AssetIdForPoolAssets,
422		xcm::v5::Location,
423	>,
424	xcm::v5::Location,
425	AccountId,
426>;
427
428pub type PoolIdToAccountId = pallet_asset_conversion::AccountIdConverter<
429	AssetConversionPalletId,
430	(xcm::v5::Location, xcm::v5::Location),
431>;
432
433impl pallet_asset_conversion::Config for Runtime {
434	type RuntimeEvent = RuntimeEvent;
435	type Balance = Balance;
436	type HigherPrecisionBalance = sp_core::U256;
437	type AssetKind = xcm::v5::Location;
438	type Assets = NativeAndNonPoolAssets;
439	type PoolId = (Self::AssetKind, Self::AssetKind);
440	type PoolLocator = pallet_asset_conversion::WithFirstAsset<
441		WestendLocation,
442		AccountId,
443		Self::AssetKind,
444		PoolIdToAccountId,
445	>;
446	type PoolAssetId = u32;
447	type PoolAssets = PoolAssets;
448	type PoolSetupFee = ConstU128<0>; // Asset class deposit fees are sufficient to prevent spam
449	type PoolSetupFeeAsset = WestendLocation;
450	type PoolSetupFeeTarget = ResolveAssetTo<AssetConversionOrigin, Self::Assets>;
451	type LiquidityWithdrawalFee = LiquidityWithdrawalFee;
452	type LPFee = ConstU32<3>;
453	type PalletId = AssetConversionPalletId;
454	type MaxSwapPathLength = ConstU32<3>;
455	type MintMinLiquidity = ConstU128<100>;
456	type WeightInfo = weights::pallet_asset_conversion::WeightInfo<Runtime>;
457	#[cfg(feature = "runtime-benchmarks")]
458	type BenchmarkHelper = assets_common::benchmarks::AssetPairFactory<
459		WestendLocation,
460		parachain_info::Pallet<Runtime>,
461		xcm_config::TrustBackedAssetsPalletIndex,
462		xcm::v5::Location,
463	>;
464}
465
466#[cfg(feature = "runtime-benchmarks")]
467pub struct PalletAssetRewardsBenchmarkHelper;
468
469#[cfg(feature = "runtime-benchmarks")]
470impl pallet_asset_rewards::benchmarking::BenchmarkHelper<xcm::v5::Location>
471	for PalletAssetRewardsBenchmarkHelper
472{
473	fn staked_asset() -> Location {
474		Location::new(
475			0,
476			[PalletInstance(<Assets as PalletInfoAccess>::index() as u8), GeneralIndex(100)],
477		)
478	}
479	fn reward_asset() -> Location {
480		Location::new(
481			0,
482			[PalletInstance(<Assets as PalletInfoAccess>::index() as u8), GeneralIndex(101)],
483		)
484	}
485}
486
487parameter_types! {
488	pub const MinVestedTransfer: Balance = 100 * CENTS;
489	pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons =
490		WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE);
491}
492
493impl pallet_vesting::Config for Runtime {
494	const MAX_VESTING_SCHEDULES: u32 = 100;
495	type BlockNumberProvider = RelaychainDataProvider<Runtime>;
496	type BlockNumberToBalance = ConvertInto;
497	type Currency = Balances;
498	type MinVestedTransfer = MinVestedTransfer;
499	type RuntimeEvent = RuntimeEvent;
500	type WeightInfo = weights::pallet_vesting::WeightInfo<Runtime>;
501	type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons;
502}
503
504parameter_types! {
505	pub const AssetRewardsPalletId: PalletId = PalletId(*b"py/astrd");
506	pub const RewardsPoolCreationHoldReason: RuntimeHoldReason =
507		RuntimeHoldReason::AssetRewards(pallet_asset_rewards::HoldReason::PoolCreation);
508	// 1 item, 135 bytes into the storage on pool creation.
509	pub const StakePoolCreationDeposit: Balance = deposit(1, 135);
510}
511
512impl pallet_asset_rewards::Config for Runtime {
513	type RuntimeEvent = RuntimeEvent;
514	type PalletId = AssetRewardsPalletId;
515	type Balance = Balance;
516	type Assets = NativeAndAllAssets;
517	type AssetsFreezer = NativeAndAllAssetsFreezer;
518	type AssetId = xcm::v5::Location;
519	type CreatePoolOrigin = EnsureSigned<AccountId>;
520	type RuntimeFreezeReason = RuntimeFreezeReason;
521	type Consideration = HoldConsideration<
522		AccountId,
523		Balances,
524		RewardsPoolCreationHoldReason,
525		ConstantStoragePrice<StakePoolCreationDeposit, Balance>,
526	>;
527	type WeightInfo = weights::pallet_asset_rewards::WeightInfo<Runtime>;
528	#[cfg(feature = "runtime-benchmarks")]
529	type BenchmarkHelper = PalletAssetRewardsBenchmarkHelper;
530}
531
532impl pallet_asset_conversion_ops::Config for Runtime {
533	type RuntimeEvent = RuntimeEvent;
534	type PriorAccountIdConverter = pallet_asset_conversion::AccountIdConverterNoSeed<
535		<Runtime as pallet_asset_conversion::Config>::PoolId,
536	>;
537	type AssetsRefund = <Runtime as pallet_asset_conversion::Config>::Assets;
538	type PoolAssetsRefund = <Runtime as pallet_asset_conversion::Config>::PoolAssets;
539	type PoolAssetsTeam = <Runtime as pallet_asset_conversion::Config>::PoolAssets;
540	type DepositAsset = Balances;
541	type WeightInfo = weights::pallet_asset_conversion_ops::WeightInfo<Runtime>;
542}
543
544parameter_types! {
545	pub const ForeignAssetsAssetDeposit: Balance = CreateForeignAssetDeposit::get();
546	pub const ForeignAssetsAssetAccountDeposit: Balance = AssetAccountDeposit::get();
547	pub const ForeignAssetsApprovalDeposit: Balance = ApprovalDeposit::get();
548	pub const ForeignAssetsAssetsStringLimit: u32 = AssetsStringLimit::get();
549	pub const ForeignAssetsMetadataDepositBase: Balance = MetadataDepositBase::get();
550	pub const ForeignAssetsMetadataDepositPerByte: Balance = MetadataDepositPerByte::get();
551}
552
553/// Assets managed by some foreign location. Note: we do not declare a `ForeignAssetsCall` type, as
554/// this type is used in proxy definitions. We assume that a foreign location would not want to set
555/// an individual, local account as a proxy for the issuance of their assets. This issuance should
556/// be managed by the foreign location's governance.
557pub type ForeignAssetsInstance = pallet_assets::Instance2;
558impl pallet_assets::Config<ForeignAssetsInstance> for Runtime {
559	type RuntimeEvent = RuntimeEvent;
560	type Balance = Balance;
561	type AssetId = xcm::v5::Location;
562	type AssetIdParameter = xcm::v5::Location;
563	type Currency = Balances;
564	type CreateOrigin = ForeignCreators<
565		(
566			FromSiblingParachain<parachain_info::Pallet<Runtime>, xcm::v5::Location>,
567			FromNetwork<xcm_config::UniversalLocation, EthereumNetwork, xcm::v5::Location>,
568			xcm_config::bridging::to_rococo::RococoAssetFromAssetHubRococo,
569		),
570		LocationToAccountId,
571		AccountId,
572		xcm::v5::Location,
573	>;
574	type ForceOrigin = AssetsForceOrigin;
575	type AssetDeposit = ForeignAssetsAssetDeposit;
576	type MetadataDepositBase = ForeignAssetsMetadataDepositBase;
577	type MetadataDepositPerByte = ForeignAssetsMetadataDepositPerByte;
578	type ApprovalDeposit = ForeignAssetsApprovalDeposit;
579	type StringLimit = ForeignAssetsAssetsStringLimit;
580	type Holder = ();
581	type Freezer = ForeignAssetsFreezer;
582	type Extra = ();
583	type WeightInfo = weights::pallet_assets_foreign::WeightInfo<Runtime>;
584	type CallbackHandle = ();
585	type AssetAccountDeposit = ForeignAssetsAssetAccountDeposit;
586	type RemoveItemsLimit = frame_support::traits::ConstU32<1000>;
587	#[cfg(feature = "runtime-benchmarks")]
588	type BenchmarkHelper = xcm_config::XcmBenchmarkHelper;
589}
590
591// Allow Freezes for the `ForeignAssets` pallet
592pub type ForeignAssetsFreezerInstance = pallet_assets_freezer::Instance2;
593impl pallet_assets_freezer::Config<ForeignAssetsFreezerInstance> for Runtime {
594	type RuntimeFreezeReason = RuntimeFreezeReason;
595	type RuntimeEvent = RuntimeEvent;
596}
597
598parameter_types! {
599	// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
600	pub const DepositBase: Balance = deposit(1, 88);
601	// Additional storage item size of 32 bytes.
602	pub const DepositFactor: Balance = deposit(0, 32);
603	pub const MaxSignatories: u32 = 100;
604}
605
606impl pallet_multisig::Config for Runtime {
607	type RuntimeEvent = RuntimeEvent;
608	type RuntimeCall = RuntimeCall;
609	type Currency = Balances;
610	type DepositBase = DepositBase;
611	type DepositFactor = DepositFactor;
612	type MaxSignatories = MaxSignatories;
613	type WeightInfo = weights::pallet_multisig::WeightInfo<Runtime>;
614	type BlockNumberProvider = System;
615}
616
617impl pallet_utility::Config for Runtime {
618	type RuntimeEvent = RuntimeEvent;
619	type RuntimeCall = RuntimeCall;
620	type PalletsOrigin = OriginCaller;
621	type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
622}
623
624parameter_types! {
625	// One storage item; key size 32, value size 8; .
626	pub const ProxyDepositBase: Balance = deposit(1, 40);
627	// Additional storage item size of 33 bytes.
628	pub const ProxyDepositFactor: Balance = deposit(0, 33);
629	pub const MaxProxies: u16 = 32;
630	// One storage item; key size 32, value size 16
631	pub const AnnouncementDepositBase: Balance = deposit(1, 48);
632	pub const AnnouncementDepositFactor: Balance = deposit(0, 66);
633	pub const MaxPending: u16 = 32;
634}
635
636/// The type used to represent the kinds of proxying allowed.
637#[derive(
638	Copy,
639	Clone,
640	Eq,
641	PartialEq,
642	Ord,
643	PartialOrd,
644	Encode,
645	Decode,
646	DecodeWithMemTracking,
647	RuntimeDebug,
648	MaxEncodedLen,
649	scale_info::TypeInfo,
650)]
651pub enum ProxyType {
652	/// Fully permissioned proxy. Can execute any call on behalf of _proxied_.
653	Any,
654	/// Can execute any call that does not transfer funds or assets.
655	NonTransfer,
656	/// Proxy with the ability to reject time-delay proxy announcements.
657	CancelProxy,
658	/// Assets proxy. Can execute any call from `assets`, **including asset transfers**.
659	Assets,
660	/// Owner proxy. Can execute calls related to asset ownership.
661	AssetOwner,
662	/// Asset manager. Can execute calls related to asset management.
663	AssetManager,
664	/// Collator selection proxy. Can execute calls related to collator selection mechanism.
665	Collator,
666	// New variants introduced by the Asset Hub Migration from the Relay Chain.
667	/// Allow to do governance.
668	///
669	/// Contains pallets `Treasury`, `Bounties`, `Utility`, `ChildBounties`, `ConvictionVoting`,
670	/// `Referenda` and `Whitelist`.
671	Governance,
672	/// Allows access to staking related calls.
673	///
674	/// Contains the `Staking`, `Session`, `Utility`, `FastUnstake`, `VoterList`, `NominationPools`
675	/// pallets.
676	Staking,
677	/// Allows access to nomination pools related calls.
678	///
679	/// Contains the `NominationPools` and `Utility` pallets.
680	NominationPools,
681
682	/// Placeholder variant to track the state before the Asset Hub Migration.
683	OldSudoBalances,
684	/// Placeholder variant to track the state before the Asset Hub Migration.
685	OldIdentityJudgement,
686	/// Placeholder variant to track the state before the Asset Hub Migration.
687	OldAuction,
688	/// Placeholder variant to track the state before the Asset Hub Migration.
689	OldParaRegistration,
690}
691impl Default for ProxyType {
692	fn default() -> Self {
693		Self::Any
694	}
695}
696
697impl InstanceFilter<RuntimeCall> for ProxyType {
698	fn filter(&self, c: &RuntimeCall) -> bool {
699		match self {
700			ProxyType::Any => true,
701			ProxyType::OldSudoBalances |
702			ProxyType::OldIdentityJudgement |
703			ProxyType::OldAuction |
704			ProxyType::OldParaRegistration => false,
705			ProxyType::NonTransfer => !matches!(
706				c,
707				RuntimeCall::Balances { .. } |
708					RuntimeCall::Assets { .. } |
709					RuntimeCall::NftFractionalization { .. } |
710					RuntimeCall::Nfts { .. } |
711					RuntimeCall::Uniques { .. } |
712					RuntimeCall::Scheduler(..) |
713					RuntimeCall::Treasury(..) |
714					// We allow calling `vest` and merging vesting schedules, but obviously not
715					// vested transfers.
716					RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) |
717					RuntimeCall::ConvictionVoting(..) |
718					RuntimeCall::Referenda(..) |
719					RuntimeCall::Whitelist(..)
720			),
721			ProxyType::CancelProxy => matches!(
722				c,
723				RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) |
724					RuntimeCall::Utility { .. } |
725					RuntimeCall::Multisig { .. }
726			),
727			ProxyType::Assets => {
728				matches!(
729					c,
730					RuntimeCall::Assets { .. } |
731						RuntimeCall::Utility { .. } |
732						RuntimeCall::Multisig { .. } |
733						RuntimeCall::NftFractionalization { .. } |
734						RuntimeCall::Nfts { .. } |
735						RuntimeCall::Uniques { .. }
736				)
737			},
738			ProxyType::AssetOwner => matches!(
739				c,
740				RuntimeCall::Assets(TrustBackedAssetsCall::create { .. }) |
741					RuntimeCall::Assets(TrustBackedAssetsCall::start_destroy { .. }) |
742					RuntimeCall::Assets(TrustBackedAssetsCall::destroy_accounts { .. }) |
743					RuntimeCall::Assets(TrustBackedAssetsCall::destroy_approvals { .. }) |
744					RuntimeCall::Assets(TrustBackedAssetsCall::finish_destroy { .. }) |
745					RuntimeCall::Assets(TrustBackedAssetsCall::transfer_ownership { .. }) |
746					RuntimeCall::Assets(TrustBackedAssetsCall::set_team { .. }) |
747					RuntimeCall::Assets(TrustBackedAssetsCall::set_metadata { .. }) |
748					RuntimeCall::Assets(TrustBackedAssetsCall::clear_metadata { .. }) |
749					RuntimeCall::Assets(TrustBackedAssetsCall::set_min_balance { .. }) |
750					RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) |
751					RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) |
752					RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) |
753					RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) |
754					RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) |
755					RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) |
756					RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) |
757					RuntimeCall::Uniques(pallet_uniques::Call::create { .. }) |
758					RuntimeCall::Uniques(pallet_uniques::Call::destroy { .. }) |
759					RuntimeCall::Uniques(pallet_uniques::Call::transfer_ownership { .. }) |
760					RuntimeCall::Uniques(pallet_uniques::Call::set_team { .. }) |
761					RuntimeCall::Uniques(pallet_uniques::Call::set_metadata { .. }) |
762					RuntimeCall::Uniques(pallet_uniques::Call::set_attribute { .. }) |
763					RuntimeCall::Uniques(pallet_uniques::Call::set_collection_metadata { .. }) |
764					RuntimeCall::Uniques(pallet_uniques::Call::clear_metadata { .. }) |
765					RuntimeCall::Uniques(pallet_uniques::Call::clear_attribute { .. }) |
766					RuntimeCall::Uniques(pallet_uniques::Call::clear_collection_metadata { .. }) |
767					RuntimeCall::Uniques(pallet_uniques::Call::set_collection_max_supply { .. }) |
768					RuntimeCall::Utility { .. } |
769					RuntimeCall::Multisig { .. }
770			),
771			ProxyType::AssetManager => matches!(
772				c,
773				RuntimeCall::Assets(TrustBackedAssetsCall::mint { .. }) |
774					RuntimeCall::Assets(TrustBackedAssetsCall::burn { .. }) |
775					RuntimeCall::Assets(TrustBackedAssetsCall::freeze { .. }) |
776					RuntimeCall::Assets(TrustBackedAssetsCall::block { .. }) |
777					RuntimeCall::Assets(TrustBackedAssetsCall::thaw { .. }) |
778					RuntimeCall::Assets(TrustBackedAssetsCall::freeze_asset { .. }) |
779					RuntimeCall::Assets(TrustBackedAssetsCall::thaw_asset { .. }) |
780					RuntimeCall::Assets(TrustBackedAssetsCall::touch_other { .. }) |
781					RuntimeCall::Assets(TrustBackedAssetsCall::refund_other { .. }) |
782					RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) |
783					RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) |
784					RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) |
785					RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) |
786					RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) |
787					RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) |
788					RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) |
789					RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) |
790					RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) |
791					RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) |
792					RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) |
793					RuntimeCall::Uniques(pallet_uniques::Call::mint { .. }) |
794					RuntimeCall::Uniques(pallet_uniques::Call::burn { .. }) |
795					RuntimeCall::Uniques(pallet_uniques::Call::freeze { .. }) |
796					RuntimeCall::Uniques(pallet_uniques::Call::thaw { .. }) |
797					RuntimeCall::Uniques(pallet_uniques::Call::freeze_collection { .. }) |
798					RuntimeCall::Uniques(pallet_uniques::Call::thaw_collection { .. }) |
799					RuntimeCall::Utility { .. } |
800					RuntimeCall::Multisig { .. }
801			),
802			ProxyType::Collator => matches!(
803				c,
804				RuntimeCall::CollatorSelection { .. } |
805					RuntimeCall::Utility { .. } |
806					RuntimeCall::Multisig { .. }
807			),
808			// New variants introduced by the Asset Hub Migration from the Relay Chain.
809			ProxyType::Governance => matches!(
810				c,
811				RuntimeCall::Treasury(..) |
812					RuntimeCall::Utility(..) |
813					RuntimeCall::ConvictionVoting(..) |
814					RuntimeCall::Referenda(..) |
815					RuntimeCall::Whitelist(..)
816			),
817			ProxyType::Staking => {
818				matches!(
819					c,
820					RuntimeCall::Staking(..) |
821						RuntimeCall::Session(..) |
822						RuntimeCall::Utility(..) |
823						RuntimeCall::NominationPools(..) |
824						RuntimeCall::FastUnstake(..) |
825						RuntimeCall::VoterList(..)
826				)
827			},
828			ProxyType::NominationPools => {
829				matches!(c, RuntimeCall::NominationPools(..) | RuntimeCall::Utility(..))
830			},
831		}
832	}
833
834	fn is_superset(&self, o: &Self) -> bool {
835		match (self, o) {
836			(x, y) if x == y => true,
837			(ProxyType::Any, _) => true,
838			(_, ProxyType::Any) => false,
839			(ProxyType::Assets, ProxyType::AssetOwner) => true,
840			(ProxyType::Assets, ProxyType::AssetManager) => true,
841			(
842				ProxyType::NonTransfer,
843				ProxyType::Collator |
844				ProxyType::Governance |
845				ProxyType::Staking |
846				ProxyType::NominationPools,
847			) => true,
848			_ => false,
849		}
850	}
851}
852
853impl pallet_proxy::Config for Runtime {
854	type RuntimeEvent = RuntimeEvent;
855	type RuntimeCall = RuntimeCall;
856	type Currency = Balances;
857	type ProxyType = ProxyType;
858	type ProxyDepositBase = ProxyDepositBase;
859	type ProxyDepositFactor = ProxyDepositFactor;
860	type MaxProxies = MaxProxies;
861	type WeightInfo = weights::pallet_proxy::WeightInfo<Runtime>;
862	type MaxPending = MaxPending;
863	type CallHasher = BlakeTwo256;
864	type AnnouncementDepositBase = AnnouncementDepositBase;
865	type AnnouncementDepositFactor = AnnouncementDepositFactor;
866	type BlockNumberProvider = RelaychainDataProvider<Runtime>;
867}
868
869parameter_types! {
870	pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
871	pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
872}
873
874impl cumulus_pallet_parachain_system::Config for Runtime {
875	type WeightInfo = weights::cumulus_pallet_parachain_system::WeightInfo<Runtime>;
876	type RuntimeEvent = RuntimeEvent;
877	type OnSystemEvent = ();
878	type SelfParaId = parachain_info::Pallet<Runtime>;
879	type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
880	type ReservedDmpWeight = ReservedDmpWeight;
881	type OutboundXcmpMessageSource = XcmpQueue;
882	type XcmpMessageHandler = XcmpQueue;
883	type ReservedXcmpWeight = ReservedXcmpWeight;
884	type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases;
885	type ConsensusHook = ConsensusHook;
886	type RelayParentOffset = ConstU32<0>;
887}
888
889type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
890	Runtime,
891	RELAY_CHAIN_SLOT_DURATION_MILLIS,
892	BLOCK_PROCESSING_VELOCITY,
893	UNINCLUDED_SEGMENT_CAPACITY,
894>;
895
896impl parachain_info::Config for Runtime {}
897
898parameter_types! {
899	pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block;
900}
901
902impl pallet_message_queue::Config for Runtime {
903	type RuntimeEvent = RuntimeEvent;
904	type WeightInfo = weights::pallet_message_queue::WeightInfo<Runtime>;
905	#[cfg(feature = "runtime-benchmarks")]
906	type MessageProcessor = pallet_message_queue::mock_helpers::NoopMessageProcessor<
907		cumulus_primitives_core::AggregateMessageOrigin,
908	>;
909	#[cfg(not(feature = "runtime-benchmarks"))]
910	type MessageProcessor = xcm_builder::ProcessXcmMessage<
911		AggregateMessageOrigin,
912		xcm_executor::XcmExecutor<xcm_config::XcmConfig>,
913		RuntimeCall,
914	>;
915	type Size = u32;
916	// The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin:
917	type QueueChangeHandler = NarrowOriginToSibling<XcmpQueue>;
918	type QueuePausedQuery = NarrowOriginToSibling<XcmpQueue>;
919	type HeapSize = sp_core::ConstU32<{ 103 * 1024 }>;
920	type MaxStale = sp_core::ConstU32<8>;
921	type ServiceWeight = MessageQueueServiceWeight;
922	type IdleMaxServiceWeight = MessageQueueServiceWeight;
923}
924
925impl cumulus_pallet_aura_ext::Config for Runtime {}
926
927parameter_types! {
928	/// The asset ID for the asset that we use to pay for message delivery fees.
929	pub FeeAssetId: AssetId = AssetId(xcm_config::WestendLocation::get());
930	/// The base fee for the message delivery fees.
931	pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3);
932}
933
934pub type PriceForSiblingParachainDelivery = polkadot_runtime_common::xcm_sender::ExponentialPrice<
935	FeeAssetId,
936	BaseDeliveryFee,
937	TransactionByteFee,
938	XcmpQueue,
939>;
940
941impl cumulus_pallet_xcmp_queue::Config for Runtime {
942	type RuntimeEvent = RuntimeEvent;
943	type ChannelInfo = ParachainSystem;
944	type VersionWrapper = PolkadotXcm;
945	// Enqueue XCMP messages from siblings for later processing.
946	type XcmpQueue = TransformOrigin<MessageQueue, AggregateMessageOrigin, ParaId, ParaIdToSibling>;
947	type MaxInboundSuspended = ConstU32<1_000>;
948	type MaxActiveOutboundChannels = ConstU32<128>;
949	// Most on-chain HRMP channels are configured to use 102400 bytes of max message size, so we
950	// need to set the page size larger than that until we reduce the channel size on-chain.
951	type MaxPageSize = ConstU32<{ 103 * 1024 }>;
952	type ControllerOrigin = EnsureRoot<AccountId>;
953	type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
954	type WeightInfo = weights::cumulus_pallet_xcmp_queue::WeightInfo<Runtime>;
955	type PriceForSiblingDelivery = PriceForSiblingParachainDelivery;
956}
957
958impl cumulus_pallet_xcmp_queue::migration::v5::V5Config for Runtime {
959	// This must be the same as the `ChannelInfo` from the `Config`:
960	type ChannelList = ParachainSystem;
961}
962
963parameter_types! {
964	pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
965}
966
967parameter_types! {
968	pub const Period: u32 = 6 * HOURS;
969	pub const Offset: u32 = 0;
970}
971
972impl pallet_session::Config for Runtime {
973	type RuntimeEvent = RuntimeEvent;
974	type ValidatorId = <Self as frame_system::Config>::AccountId;
975	// we don't have stash and controller, thus we don't need the convert as well.
976	type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
977	type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
978	type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
979	type SessionManager = CollatorSelection;
980	// Essentially just Aura, but let's be pedantic.
981	type SessionHandler = <SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
982	type Keys = SessionKeys;
983	type DisablingStrategy = ();
984	type WeightInfo = weights::pallet_session::WeightInfo<Runtime>;
985	type Currency = Balances;
986	type KeyDeposit = ();
987}
988
989impl pallet_aura::Config for Runtime {
990	type AuthorityId = AuraId;
991	type DisabledValidators = ();
992	type MaxAuthorities = ConstU32<100_000>;
993	type AllowMultipleBlocksPerSlot = ConstBool<true>;
994	type SlotDuration = ConstU64<SLOT_DURATION>;
995}
996
997parameter_types! {
998	pub const PotId: PalletId = PalletId(*b"PotStake");
999	pub const SessionLength: BlockNumber = 6 * HOURS;
1000}
1001
1002pub type CollatorSelectionUpdateOrigin = EnsureRoot<AccountId>;
1003
1004impl pallet_collator_selection::Config for Runtime {
1005	type RuntimeEvent = RuntimeEvent;
1006	type Currency = Balances;
1007	type UpdateOrigin = CollatorSelectionUpdateOrigin;
1008	type PotId = PotId;
1009	type MaxCandidates = ConstU32<100>;
1010	type MinEligibleCollators = ConstU32<4>;
1011	type MaxInvulnerables = ConstU32<20>;
1012	// should be a multiple of session or things will get inconsistent
1013	type KickThreshold = Period;
1014	type ValidatorId = <Self as frame_system::Config>::AccountId;
1015	type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
1016	type ValidatorRegistration = Session;
1017	type WeightInfo = weights::pallet_collator_selection::WeightInfo<Runtime>;
1018}
1019
1020parameter_types! {
1021	pub StakingPot: AccountId = CollatorSelection::account_id();
1022}
1023
1024impl pallet_asset_conversion_tx_payment::Config for Runtime {
1025	type RuntimeEvent = RuntimeEvent;
1026	type AssetId = xcm::v5::Location;
1027	type OnChargeAssetTransaction = SwapAssetAdapter<
1028		WestendLocation,
1029		NativeAndNonPoolAssets,
1030		AssetConversion,
1031		ResolveAssetTo<StakingPot, NativeAndNonPoolAssets>,
1032	>;
1033	type WeightInfo = weights::pallet_asset_conversion_tx_payment::WeightInfo<Runtime>;
1034	#[cfg(feature = "runtime-benchmarks")]
1035	type BenchmarkHelper = AssetConversionTxHelper;
1036}
1037
1038parameter_types! {
1039	pub const UniquesCollectionDeposit: Balance = UNITS / 10; // 1 / 10 UNIT deposit to create a collection
1040	pub const UniquesItemDeposit: Balance = UNITS / 1_000; // 1 / 1000 UNIT deposit to mint an item
1041	pub const UniquesMetadataDepositBase: Balance = deposit(1, 129);
1042	pub const UniquesAttributeDepositBase: Balance = deposit(1, 0);
1043	pub const UniquesDepositPerByte: Balance = deposit(0, 1);
1044}
1045
1046impl pallet_uniques::Config for Runtime {
1047	type RuntimeEvent = RuntimeEvent;
1048	type CollectionId = CollectionId;
1049	type ItemId = ItemId;
1050	type Currency = Balances;
1051	type ForceOrigin = AssetsForceOrigin;
1052	type CollectionDeposit = UniquesCollectionDeposit;
1053	type ItemDeposit = UniquesItemDeposit;
1054	type MetadataDepositBase = UniquesMetadataDepositBase;
1055	type AttributeDepositBase = UniquesAttributeDepositBase;
1056	type DepositPerByte = UniquesDepositPerByte;
1057	type StringLimit = ConstU32<128>;
1058	type KeyLimit = ConstU32<32>;
1059	type ValueLimit = ConstU32<64>;
1060	type WeightInfo = weights::pallet_uniques::WeightInfo<Runtime>;
1061	#[cfg(feature = "runtime-benchmarks")]
1062	type Helper = ();
1063	type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
1064	type Locker = ();
1065}
1066
1067parameter_types! {
1068	pub const NftFractionalizationPalletId: PalletId = PalletId(*b"fraction");
1069	pub NewAssetSymbol: BoundedVec<u8, AssetsStringLimit> = (*b"FRAC").to_vec().try_into().unwrap();
1070	pub NewAssetName: BoundedVec<u8, AssetsStringLimit> = (*b"Frac").to_vec().try_into().unwrap();
1071}
1072
1073impl pallet_nft_fractionalization::Config for Runtime {
1074	type RuntimeEvent = RuntimeEvent;
1075	type Deposit = AssetDeposit;
1076	type Currency = Balances;
1077	type NewAssetSymbol = NewAssetSymbol;
1078	type NewAssetName = NewAssetName;
1079	type StringLimit = AssetsStringLimit;
1080	type NftCollectionId = <Self as pallet_nfts::Config>::CollectionId;
1081	type NftId = <Self as pallet_nfts::Config>::ItemId;
1082	type AssetBalance = <Self as pallet_balances::Config>::Balance;
1083	type AssetId = <Self as pallet_assets::Config<TrustBackedAssetsInstance>>::AssetId;
1084	type Assets = Assets;
1085	type Nfts = Nfts;
1086	type PalletId = NftFractionalizationPalletId;
1087	type WeightInfo = weights::pallet_nft_fractionalization::WeightInfo<Runtime>;
1088	type RuntimeHoldReason = RuntimeHoldReason;
1089	#[cfg(feature = "runtime-benchmarks")]
1090	type BenchmarkHelper = ();
1091}
1092
1093parameter_types! {
1094	pub NftsPalletFeatures: PalletFeatures = PalletFeatures::all_enabled();
1095	pub const NftsMaxDeadlineDuration: BlockNumber = 12 * 30 * DAYS;
1096	// re-use the Uniques deposits
1097	pub const NftsCollectionDeposit: Balance = UniquesCollectionDeposit::get();
1098	pub const NftsItemDeposit: Balance = UniquesItemDeposit::get();
1099	pub const NftsMetadataDepositBase: Balance = UniquesMetadataDepositBase::get();
1100	pub const NftsAttributeDepositBase: Balance = UniquesAttributeDepositBase::get();
1101	pub const NftsDepositPerByte: Balance = UniquesDepositPerByte::get();
1102}
1103
1104impl pallet_nfts::Config for Runtime {
1105	type RuntimeEvent = RuntimeEvent;
1106	type CollectionId = CollectionId;
1107	type ItemId = ItemId;
1108	type Currency = Balances;
1109	type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
1110	type ForceOrigin = AssetsForceOrigin;
1111	type Locker = ();
1112	type CollectionDeposit = NftsCollectionDeposit;
1113	type ItemDeposit = NftsItemDeposit;
1114	type MetadataDepositBase = NftsMetadataDepositBase;
1115	type AttributeDepositBase = NftsAttributeDepositBase;
1116	type DepositPerByte = NftsDepositPerByte;
1117	type StringLimit = ConstU32<256>;
1118	type KeyLimit = ConstU32<64>;
1119	type ValueLimit = ConstU32<256>;
1120	type ApprovalsLimit = ConstU32<20>;
1121	type ItemAttributesApprovalsLimit = ConstU32<30>;
1122	type MaxTips = ConstU32<10>;
1123	type MaxDeadlineDuration = NftsMaxDeadlineDuration;
1124	type MaxAttributesPerCall = ConstU32<10>;
1125	type Features = NftsPalletFeatures;
1126	type OffchainSignature = Signature;
1127	type OffchainPublic = <Signature as Verify>::Signer;
1128	type WeightInfo = weights::pallet_nfts::WeightInfo<Runtime>;
1129	#[cfg(feature = "runtime-benchmarks")]
1130	type Helper = ();
1131	type BlockNumberProvider = RelaychainDataProvider<Runtime>;
1132}
1133
1134/// XCM router instance to BridgeHub with bridging capabilities for `Rococo` global
1135/// consensus with dynamic fees and back-pressure.
1136pub type ToRococoXcmRouterInstance = pallet_xcm_bridge_hub_router::Instance1;
1137impl pallet_xcm_bridge_hub_router::Config<ToRococoXcmRouterInstance> for Runtime {
1138	type RuntimeEvent = RuntimeEvent;
1139	type WeightInfo = weights::pallet_xcm_bridge_hub_router::WeightInfo<Runtime>;
1140
1141	type UniversalLocation = xcm_config::UniversalLocation;
1142	type SiblingBridgeHubLocation = xcm_config::bridging::SiblingBridgeHub;
1143	type BridgedNetworkId = xcm_config::bridging::to_rococo::RococoNetwork;
1144	type Bridges = xcm_config::bridging::NetworkExportTable;
1145	type DestinationVersion = PolkadotXcm;
1146
1147	type BridgeHubOrigin = frame_support::traits::EitherOfDiverse<
1148		EnsureRoot<AccountId>,
1149		EnsureXcm<Equals<Self::SiblingBridgeHubLocation>>,
1150	>;
1151	type ToBridgeHubSender = XcmpQueue;
1152	type LocalXcmChannelManager =
1153		cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider<Runtime>;
1154
1155	type ByteFee = xcm_config::bridging::XcmBridgeHubRouterByteFee;
1156	type FeeAsset = xcm_config::bridging::XcmBridgeHubRouterFeeAssetId;
1157}
1158
1159parameter_types! {
1160	pub const DepositPerItem: Balance = deposit(1, 0);
1161	pub const DepositPerByte: Balance = deposit(0, 1);
1162	pub CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(30);
1163}
1164
1165impl pallet_revive::Config for Runtime {
1166	type Time = Timestamp;
1167	type Currency = Balances;
1168	type RuntimeEvent = RuntimeEvent;
1169	type RuntimeCall = RuntimeCall;
1170	type DepositPerItem = DepositPerItem;
1171	type DepositPerByte = DepositPerByte;
1172	type WeightPrice = pallet_transaction_payment::Pallet<Self>;
1173	type WeightInfo = pallet_revive::weights::SubstrateWeight<Self>;
1174	type Precompiles = (
1175		ERC20<Self, InlineIdConfig<0x120>, TrustBackedAssetsInstance>,
1176		ERC20<Self, InlineIdConfig<0x320>, PoolAssetsInstance>,
1177		XcmPrecompile<Self>,
1178	);
1179	type AddressMapper = pallet_revive::AccountId32Mapper<Self>;
1180	type RuntimeMemory = ConstU32<{ 128 * 1024 * 1024 }>;
1181	type PVFMemory = ConstU32<{ 512 * 1024 * 1024 }>;
1182	type UnsafeUnstableInterface = ConstBool<false>;
1183	#[cfg(feature = "runtime-benchmarks")]
1184	type AllowEVMBytecode = ConstBool<true>;
1185	#[cfg(not(feature = "runtime-benchmarks"))]
1186	type AllowEVMBytecode = ConstBool<false>;
1187	type UploadOrigin = EnsureSigned<Self::AccountId>;
1188	type InstantiateOrigin = EnsureSigned<Self::AccountId>;
1189	type RuntimeHoldReason = RuntimeHoldReason;
1190	type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
1191	type ChainId = ConstU64<420_420_421>;
1192	type NativeToEthRatio = ConstU32<1_000_000>; // 10^(18 - 12) Eth is 10^18, Native is 10^12.
1193	type EthGasEncoder = ();
1194	type FindAuthor = <Runtime as pallet_authorship::Config>::FindAuthor;
1195}
1196
1197parameter_types! {
1198	pub MbmServiceWeight: Weight = Perbill::from_percent(80) * RuntimeBlockWeights::get().max_block;
1199}
1200
1201impl pallet_migrations::Config for Runtime {
1202	type RuntimeEvent = RuntimeEvent;
1203	#[cfg(not(feature = "runtime-benchmarks"))]
1204	type Migrations = (
1205		pallet_revive::migrations::v1::Migration<Runtime>,
1206		pallet_revive::migrations::v2::Migration<Runtime>,
1207	);
1208	// Benchmarks need mocked migrations to guarantee that they succeed.
1209	#[cfg(feature = "runtime-benchmarks")]
1210	type Migrations = pallet_migrations::mock_helpers::MockedMigrations;
1211	type CursorMaxLen = ConstU32<65_536>;
1212	type IdentifierMaxLen = ConstU32<256>;
1213	type MigrationStatusHandler = ();
1214	type FailedMigrationHandler = frame_support::migrations::FreezeChainOnFailedMigration;
1215	type MaxServiceWeight = MbmServiceWeight;
1216	type WeightInfo = weights::pallet_migrations::WeightInfo<Runtime>;
1217}
1218
1219parameter_types! {
1220	pub MaximumSchedulerWeight: frame_support::weights::Weight = Perbill::from_percent(80) *
1221		RuntimeBlockWeights::get().max_block;
1222}
1223
1224impl pallet_scheduler::Config for Runtime {
1225	type RuntimeOrigin = RuntimeOrigin;
1226	type RuntimeEvent = RuntimeEvent;
1227	type PalletsOrigin = OriginCaller;
1228	type RuntimeCall = RuntimeCall;
1229	type MaximumWeight = MaximumSchedulerWeight;
1230	type ScheduleOrigin = EnsureRoot<AccountId>;
1231	#[cfg(feature = "runtime-benchmarks")]
1232	type MaxScheduledPerBlock = ConstU32<{ 512 * 15 }>; // MaxVotes * TRACKS_DATA length
1233	#[cfg(not(feature = "runtime-benchmarks"))]
1234	type MaxScheduledPerBlock = ConstU32<50>;
1235	type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
1236	type OriginPrivilegeCmp = frame_support::traits::EqualPrivilegeOnly;
1237	type Preimages = Preimage;
1238	type BlockNumberProvider = RelaychainDataProvider<Runtime>;
1239}
1240
1241parameter_types! {
1242	pub const PreimageBaseDeposit: Balance = deposit(2, 64);
1243	pub const PreimageByteDeposit: Balance = deposit(0, 1);
1244	pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
1245}
1246
1247impl pallet_preimage::Config for Runtime {
1248	type WeightInfo = weights::pallet_preimage::WeightInfo<Runtime>;
1249	type RuntimeEvent = RuntimeEvent;
1250	type Currency = Balances;
1251	type ManagerOrigin = EnsureRoot<AccountId>;
1252	type Consideration = HoldConsideration<
1253		AccountId,
1254		Balances,
1255		PreimageHoldReason,
1256		LinearStoragePrice<PreimageBaseDeposit, PreimageByteDeposit, Balance>,
1257	>;
1258}
1259
1260parameter_types! {
1261	/// Deposit for an index in the indices pallet.
1262	///
1263	/// 32 bytes for the account ID and 16 for the deposit. We cannot use `max_encoded_len` since it
1264	/// is not const.
1265	pub const IndexDeposit: Balance = deposit(1, 32 + 16);
1266}
1267
1268impl pallet_indices::Config for Runtime {
1269	type AccountIndex = AccountIndex;
1270	type Currency = Balances;
1271	type Deposit = IndexDeposit;
1272	type RuntimeEvent = RuntimeEvent;
1273	type WeightInfo = weights::pallet_indices::WeightInfo<Runtime>;
1274}
1275
1276impl pallet_ah_ops::Config for Runtime {
1277	type Currency = Balances;
1278	type RcBlockNumberProvider = RelaychainDataProvider<Runtime>;
1279	type WeightInfo = weights::pallet_ah_ops::WeightInfo<Runtime>;
1280}
1281
1282impl pallet_sudo::Config for Runtime {
1283	type RuntimeEvent = RuntimeEvent;
1284	type RuntimeCall = RuntimeCall;
1285	type WeightInfo = weights::pallet_sudo::WeightInfo<Runtime>;
1286}
1287
1288// Create the runtime by composing the FRAME pallets that were previously configured.
1289construct_runtime!(
1290	pub enum Runtime
1291	{
1292		// System support stuff.
1293		System: frame_system = 0,
1294		ParachainSystem: cumulus_pallet_parachain_system = 1,
1295		// RandomnessCollectiveFlip = 2 removed
1296		Timestamp: pallet_timestamp = 3,
1297		ParachainInfo: parachain_info = 4,
1298		WeightReclaim: cumulus_pallet_weight_reclaim = 5,
1299		MultiBlockMigrations: pallet_migrations = 6,
1300		Preimage: pallet_preimage = 7,
1301		Scheduler: pallet_scheduler = 8,
1302		Sudo: pallet_sudo = 9,
1303
1304		// Monetary stuff.
1305		Balances: pallet_balances = 10,
1306		TransactionPayment: pallet_transaction_payment = 11,
1307		// AssetTxPayment: pallet_asset_tx_payment = 12,
1308		AssetTxPayment: pallet_asset_conversion_tx_payment = 13,
1309		Vesting: pallet_vesting = 14,
1310
1311		// Collator support. the order of these 5 are important and shall not change.
1312		Authorship: pallet_authorship = 20,
1313		CollatorSelection: pallet_collator_selection = 21,
1314		Session: pallet_session = 22,
1315		Aura: pallet_aura = 23,
1316		AuraExt: cumulus_pallet_aura_ext = 24,
1317
1318		// XCM helpers.
1319		XcmpQueue: cumulus_pallet_xcmp_queue = 30,
1320		PolkadotXcm: pallet_xcm = 31,
1321		CumulusXcm: cumulus_pallet_xcm = 32,
1322		// Bridge utilities.
1323		ToRococoXcmRouter: pallet_xcm_bridge_hub_router::<Instance1> = 34,
1324		MessageQueue: pallet_message_queue = 35,
1325		// Snowbridge
1326		SnowbridgeSystemFrontend: snowbridge_pallet_system_frontend = 36,
1327
1328		// Handy utilities.
1329		Utility: pallet_utility = 40,
1330		Multisig: pallet_multisig = 41,
1331		Proxy: pallet_proxy = 42,
1332		Indices: pallet_indices = 43,
1333
1334		// The main stage.
1335		Assets: pallet_assets::<Instance1> = 50,
1336		Uniques: pallet_uniques = 51,
1337		Nfts: pallet_nfts = 52,
1338		ForeignAssets: pallet_assets::<Instance2> = 53,
1339		NftFractionalization: pallet_nft_fractionalization = 54,
1340		PoolAssets: pallet_assets::<Instance3> = 55,
1341		AssetConversion: pallet_asset_conversion = 56,
1342
1343		AssetsFreezer: pallet_assets_freezer::<Instance1> = 57,
1344		ForeignAssetsFreezer: pallet_assets_freezer::<Instance2> = 58,
1345		PoolAssetsFreezer: pallet_assets_freezer::<Instance3> = 59,
1346		Revive: pallet_revive = 60,
1347
1348		AssetRewards: pallet_asset_rewards = 61,
1349
1350		StateTrieMigration: pallet_state_trie_migration = 70,
1351
1352		// Staking.
1353		Staking: pallet_staking_async = 80,
1354		NominationPools: pallet_nomination_pools = 81,
1355		FastUnstake: pallet_fast_unstake = 82,
1356		VoterList: pallet_bags_list::<Instance1> = 83,
1357		DelegatedStaking: pallet_delegated_staking = 84,
1358		StakingRcClient: pallet_staking_async_rc_client = 89,
1359
1360		// Staking election apparatus.
1361		MultiBlockElection: pallet_election_provider_multi_block = 85,
1362		MultiBlockElectionVerifier: pallet_election_provider_multi_block::verifier = 86,
1363		MultiBlockElectionUnsigned: pallet_election_provider_multi_block::unsigned = 87,
1364		MultiBlockElectionSigned: pallet_election_provider_multi_block::signed = 88,
1365
1366		// Governance.
1367		ConvictionVoting: pallet_conviction_voting = 90,
1368		Referenda: pallet_referenda = 91,
1369		Origins: pallet_custom_origins = 92,
1370		Whitelist: pallet_whitelist = 93,
1371		Treasury: pallet_treasury = 94,
1372		AssetRate: pallet_asset_rate = 95,
1373
1374		// TODO: the pallet instance should be removed once all pools have migrated
1375		// to the new account IDs.
1376		AssetConversionMigration: pallet_asset_conversion_ops = 200,
1377
1378		AhOps: pallet_ah_ops = 254,
1379	}
1380);
1381
1382/// The address format for describing accounts.
1383pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
1384/// Block type as expected by this runtime.
1385pub type Block = generic::Block<Header, UncheckedExtrinsic>;
1386/// A Block signed with a Justification
1387pub type SignedBlock = generic::SignedBlock<Block>;
1388/// BlockId type as expected by this runtime.
1389pub type BlockId = generic::BlockId<Block>;
1390/// The extension to the basic transaction logic.
1391pub type TxExtension = cumulus_pallet_weight_reclaim::StorageWeightReclaim<
1392	Runtime,
1393	(
1394		frame_system::AuthorizeCall<Runtime>,
1395		frame_system::CheckNonZeroSender<Runtime>,
1396		frame_system::CheckSpecVersion<Runtime>,
1397		frame_system::CheckTxVersion<Runtime>,
1398		frame_system::CheckGenesis<Runtime>,
1399		frame_system::CheckEra<Runtime>,
1400		frame_system::CheckNonce<Runtime>,
1401		frame_system::CheckWeight<Runtime>,
1402		pallet_asset_conversion_tx_payment::ChargeAssetTxPayment<Runtime>,
1403		frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
1404	),
1405>;
1406
1407/// Default extensions applied to Ethereum transactions.
1408#[derive(Clone, PartialEq, Eq, Debug)]
1409pub struct EthExtraImpl;
1410
1411impl EthExtra for EthExtraImpl {
1412	type Config = Runtime;
1413	type Extension = TxExtension;
1414
1415	fn get_eth_extension(nonce: u32, tip: Balance) -> Self::Extension {
1416		(
1417			frame_system::AuthorizeCall::<Runtime>::new(),
1418			frame_system::CheckNonZeroSender::<Runtime>::new(),
1419			frame_system::CheckSpecVersion::<Runtime>::new(),
1420			frame_system::CheckTxVersion::<Runtime>::new(),
1421			frame_system::CheckGenesis::<Runtime>::new(),
1422			frame_system::CheckMortality::from(generic::Era::Immortal),
1423			frame_system::CheckNonce::<Runtime>::from(nonce),
1424			frame_system::CheckWeight::<Runtime>::new(),
1425			pallet_asset_conversion_tx_payment::ChargeAssetTxPayment::<Runtime>::from(tip, None),
1426			frame_metadata_hash_extension::CheckMetadataHash::<Runtime>::new(false),
1427		)
1428			.into()
1429	}
1430}
1431
1432/// Unchecked extrinsic type as expected by this runtime.
1433pub type UncheckedExtrinsic =
1434	pallet_revive::evm::runtime::UncheckedExtrinsic<Address, Signature, EthExtraImpl>;
1435
1436/// Migrations to apply on runtime upgrade.
1437pub type Migrations = (
1438	// v9420
1439	pallet_nfts::migration::v1::MigrateToV1<Runtime>,
1440	// unreleased
1441	pallet_collator_selection::migration::v2::MigrationToV2<Runtime>,
1442	// unreleased
1443	pallet_multisig::migrations::v1::MigrateToV1<Runtime>,
1444	// unreleased
1445	InitStorageVersions,
1446	// unreleased
1447	DeleteUndecodableStorage,
1448	// unreleased
1449	cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4<Runtime>,
1450	cumulus_pallet_xcmp_queue::migration::v5::MigrateV4ToV5<Runtime>,
1451	// unreleased
1452	pallet_assets::migration::next_asset_id::SetNextAssetId<
1453		ConstU32<50_000_000>,
1454		Runtime,
1455		TrustBackedAssetsInstance,
1456	>,
1457	pallet_session::migrations::v1::MigrateV0ToV1<
1458		Runtime,
1459		pallet_session::migrations::v1::InitOffenceSeverity<Runtime>,
1460	>,
1461	// permanent
1462	pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,
1463	cumulus_pallet_aura_ext::migration::MigrateV0ToV1<Runtime>,
1464);
1465
1466/// Asset Hub Westend has some undecodable storage, delete it.
1467/// See <https://github.com/paritytech/polkadot-sdk/issues/2241> for more info.
1468///
1469/// First we remove the bad Hold, then the bad NFT collection.
1470pub struct DeleteUndecodableStorage;
1471
1472impl frame_support::traits::OnRuntimeUpgrade for DeleteUndecodableStorage {
1473	fn on_runtime_upgrade() -> Weight {
1474		use sp_core::crypto::Ss58Codec;
1475
1476		let mut writes = 0;
1477
1478		// Remove Holds for account with undecodable hold
1479		// Westend doesn't have any HoldReasons implemented yet, so it's safe to just blanket remove
1480		// any for this account.
1481		match AccountId::from_ss58check("5GCCJthVSwNXRpbeg44gysJUx9vzjdGdfWhioeM7gCg6VyXf") {
1482			Ok(a) => {
1483				tracing::info!(target: "bridges::on_runtime_upgrade", "Removing holds for account with bad hold");
1484				pallet_balances::Holds::<Runtime, ()>::remove(a);
1485				writes.saturating_inc();
1486			},
1487			Err(_) => {
1488				tracing::error!(target: "bridges::on_runtime_upgrade", "CleanupUndecodableStorage: Somehow failed to convert valid SS58 address into an AccountId!");
1489			},
1490		};
1491
1492		// Destroy undecodable NFT item 1
1493		writes.saturating_inc();
1494		match pallet_nfts::Pallet::<Runtime, ()>::do_burn(3, 1, |_| Ok(())) {
1495			Ok(_) => {
1496				tracing::info!(target: "bridges::on_runtime_upgrade", "Destroyed undecodable NFT item 1");
1497			},
1498			Err(e) => {
1499				tracing::error!(target: "bridges::on_runtime_upgrade", error=?e, "Failed to destroy undecodable NFT item");
1500				return <Runtime as frame_system::Config>::DbWeight::get().reads_writes(0, writes);
1501			},
1502		}
1503
1504		// Destroy undecodable NFT item 2
1505		writes.saturating_inc();
1506		match pallet_nfts::Pallet::<Runtime, ()>::do_burn(3, 2, |_| Ok(())) {
1507			Ok(_) => {
1508				tracing::info!(target: "bridges::on_runtime_upgrade", "Destroyed undecodable NFT item 2");
1509			},
1510			Err(e) => {
1511				tracing::error!(target: "bridges::on_runtime_upgrade", error=?e, "Failed to destroy undecodable NFT item");
1512				return <Runtime as frame_system::Config>::DbWeight::get().reads_writes(0, writes);
1513			},
1514		}
1515
1516		// Finally, we can destroy the collection
1517		writes.saturating_inc();
1518		match pallet_nfts::Pallet::<Runtime, ()>::do_destroy_collection(
1519			3,
1520			DestroyWitness { attributes: 0, item_metadatas: 1, item_configs: 0 },
1521			None,
1522		) {
1523			Ok(_) => {
1524				tracing::info!(target: "bridges::on_runtime_upgrade", "Destroyed undecodable NFT collection");
1525			},
1526			Err(e) => {
1527				tracing::error!(target: "bridges::on_runtime_upgrade", error=?e, "Failed to destroy undecodable NFT collection");
1528			},
1529		};
1530
1531		<Runtime as frame_system::Config>::DbWeight::get().reads_writes(0, writes)
1532	}
1533}
1534
1535/// Migration to initialize storage versions for pallets added after genesis.
1536///
1537/// Ideally this would be done automatically (see
1538/// <https://github.com/paritytech/polkadot-sdk/pull/1297>), but it probably won't be ready for some
1539/// time and it's beneficial to get try-runtime-cli on-runtime-upgrade checks into the CI, so we're
1540/// doing it manually.
1541pub struct InitStorageVersions;
1542
1543impl frame_support::traits::OnRuntimeUpgrade for InitStorageVersions {
1544	fn on_runtime_upgrade() -> Weight {
1545		use frame_support::traits::{GetStorageVersion, StorageVersion};
1546
1547		let mut writes = 0;
1548
1549		if PolkadotXcm::on_chain_storage_version() == StorageVersion::new(0) {
1550			PolkadotXcm::in_code_storage_version().put::<PolkadotXcm>();
1551			writes.saturating_inc();
1552		}
1553
1554		if ForeignAssets::on_chain_storage_version() == StorageVersion::new(0) {
1555			ForeignAssets::in_code_storage_version().put::<ForeignAssets>();
1556			writes.saturating_inc();
1557		}
1558
1559		if PoolAssets::on_chain_storage_version() == StorageVersion::new(0) {
1560			PoolAssets::in_code_storage_version().put::<PoolAssets>();
1561			writes.saturating_inc();
1562		}
1563
1564		<Runtime as frame_system::Config>::DbWeight::get().reads_writes(3, writes)
1565	}
1566}
1567
1568/// Executive: handles dispatch to the various modules.
1569pub type Executive = frame_executive::Executive<
1570	Runtime,
1571	Block,
1572	frame_system::ChainContext<Runtime>,
1573	Runtime,
1574	AllPalletsWithSystem,
1575>;
1576
1577#[cfg(feature = "runtime-benchmarks")]
1578pub struct AssetConversionTxHelper;
1579
1580#[cfg(feature = "runtime-benchmarks")]
1581impl
1582	pallet_asset_conversion_tx_payment::BenchmarkHelperTrait<
1583		AccountId,
1584		cumulus_primitives_core::Location,
1585		cumulus_primitives_core::Location,
1586	> for AssetConversionTxHelper
1587{
1588	fn create_asset_id_parameter(
1589		seed: u32,
1590	) -> (cumulus_primitives_core::Location, cumulus_primitives_core::Location) {
1591		// Use a different parachain foreign assets pallet so that the asset is indeed foreign.
1592		let asset_id = cumulus_primitives_core::Location::new(
1593			1,
1594			[
1595				cumulus_primitives_core::Junction::Parachain(3000),
1596				cumulus_primitives_core::Junction::PalletInstance(53),
1597				cumulus_primitives_core::Junction::GeneralIndex(seed.into()),
1598			],
1599		);
1600		(asset_id.clone(), asset_id)
1601	}
1602
1603	fn setup_balances_and_pool(asset_id: cumulus_primitives_core::Location, account: AccountId) {
1604		use frame_support::{assert_ok, traits::fungibles::Mutate};
1605		assert_ok!(ForeignAssets::force_create(
1606			RuntimeOrigin::root(),
1607			asset_id.clone().into(),
1608			account.clone().into(), /* owner */
1609			true,                   /* is_sufficient */
1610			1,
1611		));
1612
1613		let lp_provider = account.clone();
1614		use frame_support::traits::Currency;
1615		let _ = Balances::deposit_creating(&lp_provider, u64::MAX.into());
1616		assert_ok!(ForeignAssets::mint_into(
1617			asset_id.clone().into(),
1618			&lp_provider,
1619			u64::MAX.into()
1620		));
1621
1622		let token_native = alloc::boxed::Box::new(cumulus_primitives_core::Location::new(
1623			1,
1624			cumulus_primitives_core::Junctions::Here,
1625		));
1626		let token_second = alloc::boxed::Box::new(asset_id);
1627
1628		assert_ok!(AssetConversion::create_pool(
1629			RuntimeOrigin::signed(lp_provider.clone()),
1630			token_native.clone(),
1631			token_second.clone()
1632		));
1633
1634		assert_ok!(AssetConversion::add_liquidity(
1635			RuntimeOrigin::signed(lp_provider.clone()),
1636			token_native,
1637			token_second,
1638			(u32::MAX / 2).into(), // 1 desired
1639			u32::MAX.into(),       // 2 desired
1640			1,                     // 1 min
1641			1,                     // 2 min
1642			lp_provider,
1643		));
1644	}
1645}
1646
1647#[cfg(feature = "runtime-benchmarks")]
1648mod benches {
1649	frame_benchmarking::define_benchmarks!(
1650		[frame_system, SystemBench::<Runtime>]
1651		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
1652		[pallet_asset_conversion_ops, AssetConversionMigration]
1653		[pallet_asset_rate, AssetRate]
1654		[pallet_assets, Local]
1655		[pallet_assets, Foreign]
1656		[pallet_assets, Pool]
1657		[pallet_asset_conversion, AssetConversion]
1658		[pallet_asset_rewards, AssetRewards]
1659		[pallet_asset_conversion_tx_payment, AssetTxPayment]
1660		[pallet_bags_list, VoterList]
1661		[pallet_balances, Balances]
1662		[pallet_conviction_voting, ConvictionVoting]
1663		// Temporarily disabled due to https://github.com/paritytech/polkadot-sdk/issues/7714
1664		// [pallet_election_provider_multi_block, MultiBlockElection]
1665		// [pallet_election_provider_multi_block_verifier, MultiBlockElectionVerifier]
1666		[pallet_election_provider_multi_block_unsigned, MultiBlockElectionUnsigned]
1667		[pallet_election_provider_multi_block_signed, MultiBlockElectionSigned]
1668		[pallet_fast_unstake, FastUnstake]
1669		[pallet_message_queue, MessageQueue]
1670		[pallet_migrations, MultiBlockMigrations]
1671		[pallet_multisig, Multisig]
1672		[pallet_nft_fractionalization, NftFractionalization]
1673		[pallet_nfts, Nfts]
1674		[pallet_proxy, Proxy]
1675		[pallet_session, SessionBench::<Runtime>]
1676		[pallet_staking_async, Staking]
1677		[pallet_uniques, Uniques]
1678		[pallet_utility, Utility]
1679		[pallet_timestamp, Timestamp]
1680		[pallet_transaction_payment, TransactionPayment]
1681		[pallet_collator_selection, CollatorSelection]
1682		[cumulus_pallet_parachain_system, ParachainSystem]
1683		[cumulus_pallet_xcmp_queue, XcmpQueue]
1684		[pallet_treasury, Treasury]
1685		[pallet_vesting, Vesting]
1686		[pallet_whitelist, Whitelist]
1687		[pallet_xcm_bridge_hub_router, ToRococo]
1688		[pallet_asset_conversion_ops, AssetConversionMigration]
1689		[pallet_revive, Revive]
1690		// XCM
1691		[pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
1692		// NOTE: Make sure you point to the individual modules below.
1693		[pallet_xcm_benchmarks::fungible, XcmBalances]
1694		[pallet_xcm_benchmarks::generic, XcmGeneric]
1695		[cumulus_pallet_weight_reclaim, WeightReclaim]
1696		[snowbridge_pallet_system_frontend, SnowbridgeSystemFrontend]
1697	);
1698}
1699
1700pallet_revive::impl_runtime_apis_plus_revive!(
1701	Runtime,
1702	Executive,
1703	EthExtraImpl,
1704
1705	impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
1706		fn slot_duration() -> sp_consensus_aura::SlotDuration {
1707			sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION)
1708		}
1709
1710		fn authorities() -> Vec<AuraId> {
1711			pallet_aura::Authorities::<Runtime>::get().into_inner()
1712		}
1713	}
1714
1715	impl cumulus_primitives_core::RelayParentOffsetApi<Block> for Runtime {
1716		fn relay_parent_offset() -> u32 {
1717			0
1718		}
1719	}
1720
1721	impl cumulus_primitives_core::GetParachainInfo<Block> for Runtime {
1722		fn parachain_id() -> ParaId {
1723			ParachainInfo::parachain_id()
1724		}
1725	}
1726
1727	impl cumulus_primitives_aura::AuraUnincludedSegmentApi<Block> for Runtime {
1728		fn can_build_upon(
1729			included_hash: <Block as BlockT>::Hash,
1730			slot: cumulus_primitives_aura::Slot,
1731		) -> bool {
1732			ConsensusHook::can_build_upon(included_hash, slot)
1733		}
1734	}
1735
1736	impl sp_api::Core<Block> for Runtime {
1737		fn version() -> RuntimeVersion {
1738			VERSION
1739		}
1740
1741		fn execute_block(block: Block) {
1742			Executive::execute_block(block)
1743		}
1744
1745		fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
1746			Executive::initialize_block(header)
1747		}
1748	}
1749
1750	impl sp_api::Metadata<Block> for Runtime {
1751		fn metadata() -> OpaqueMetadata {
1752			OpaqueMetadata::new(Runtime::metadata().into())
1753		}
1754
1755		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
1756			Runtime::metadata_at_version(version)
1757		}
1758
1759		fn metadata_versions() -> alloc::vec::Vec<u32> {
1760			Runtime::metadata_versions()
1761		}
1762	}
1763
1764	impl sp_block_builder::BlockBuilder<Block> for Runtime {
1765		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
1766			Executive::apply_extrinsic(extrinsic)
1767		}
1768
1769		fn finalize_block() -> <Block as BlockT>::Header {
1770			Executive::finalize_block()
1771		}
1772
1773		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
1774			data.create_extrinsics()
1775		}
1776
1777		fn check_inherents(
1778			block: Block,
1779			data: sp_inherents::InherentData,
1780		) -> sp_inherents::CheckInherentsResult {
1781			data.check_extrinsics(&block)
1782		}
1783	}
1784
1785	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
1786		fn validate_transaction(
1787			source: TransactionSource,
1788			tx: <Block as BlockT>::Extrinsic,
1789			block_hash: <Block as BlockT>::Hash,
1790		) -> TransactionValidity {
1791			Executive::validate_transaction(source, tx, block_hash)
1792		}
1793	}
1794
1795	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
1796		fn offchain_worker(header: &<Block as BlockT>::Header) {
1797			Executive::offchain_worker(header)
1798		}
1799	}
1800
1801	impl sp_session::SessionKeys<Block> for Runtime {
1802		fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
1803			SessionKeys::generate(seed)
1804		}
1805
1806		fn decode_session_keys(
1807			encoded: Vec<u8>,
1808		) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
1809			SessionKeys::decode_into_raw_public_keys(&encoded)
1810		}
1811	}
1812
1813	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
1814		fn account_nonce(account: AccountId) -> Nonce {
1815			System::account_nonce(account)
1816		}
1817	}
1818
1819	impl pallet_nfts_runtime_api::NftsApi<Block, AccountId, u32, u32> for Runtime {
1820		fn owner(collection: u32, item: u32) -> Option<AccountId> {
1821			<Nfts as Inspect<AccountId>>::owner(&collection, &item)
1822		}
1823
1824		fn collection_owner(collection: u32) -> Option<AccountId> {
1825			<Nfts as Inspect<AccountId>>::collection_owner(&collection)
1826		}
1827
1828		fn attribute(
1829			collection: u32,
1830			item: u32,
1831			key: Vec<u8>,
1832		) -> Option<Vec<u8>> {
1833			<Nfts as Inspect<AccountId>>::attribute(&collection, &item, &key)
1834		}
1835
1836		fn custom_attribute(
1837			account: AccountId,
1838			collection: u32,
1839			item: u32,
1840			key: Vec<u8>,
1841		) -> Option<Vec<u8>> {
1842			<Nfts as Inspect<AccountId>>::custom_attribute(
1843				&account,
1844				&collection,
1845				&item,
1846				&key,
1847			)
1848		}
1849
1850		fn system_attribute(
1851			collection: u32,
1852			item: Option<u32>,
1853			key: Vec<u8>,
1854		) -> Option<Vec<u8>> {
1855			<Nfts as Inspect<AccountId>>::system_attribute(&collection, item.as_ref(), &key)
1856		}
1857
1858		fn collection_attribute(collection: u32, key: Vec<u8>) -> Option<Vec<u8>> {
1859			<Nfts as Inspect<AccountId>>::collection_attribute(&collection, &key)
1860		}
1861	}
1862
1863	impl pallet_asset_conversion::AssetConversionApi<
1864		Block,
1865		Balance,
1866		xcm::v5::Location,
1867	> for Runtime
1868	{
1869		fn quote_price_exact_tokens_for_tokens(asset1: xcm::v5::Location, asset2: xcm::v5::Location, amount: Balance, include_fee: bool) -> Option<Balance> {
1870			AssetConversion::quote_price_exact_tokens_for_tokens(asset1, asset2, amount, include_fee)
1871		}
1872
1873		fn quote_price_tokens_for_exact_tokens(asset1: xcm::v5::Location, asset2: xcm::v5::Location, amount: Balance, include_fee: bool) -> Option<Balance> {
1874			AssetConversion::quote_price_tokens_for_exact_tokens(asset1, asset2, amount, include_fee)
1875		}
1876
1877		fn get_reserves(asset1: xcm::v5::Location, asset2: xcm::v5::Location) -> Option<(Balance, Balance)> {
1878			AssetConversion::get_reserves(asset1, asset2).ok()
1879		}
1880	}
1881
1882	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
1883		fn query_info(
1884			uxt: <Block as BlockT>::Extrinsic,
1885			len: u32,
1886		) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
1887			TransactionPayment::query_info(uxt, len)
1888		}
1889		fn query_fee_details(
1890			uxt: <Block as BlockT>::Extrinsic,
1891			len: u32,
1892		) -> pallet_transaction_payment::FeeDetails<Balance> {
1893			TransactionPayment::query_fee_details(uxt, len)
1894		}
1895		fn query_weight_to_fee(weight: Weight) -> Balance {
1896			TransactionPayment::weight_to_fee(weight)
1897		}
1898		fn query_length_to_fee(length: u32) -> Balance {
1899			TransactionPayment::length_to_fee(length)
1900		}
1901	}
1902
1903	impl xcm_runtime_apis::fees::XcmPaymentApi<Block> for Runtime {
1904		fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
1905			let native_token = xcm_config::WestendLocation::get();
1906			// We accept the native token to pay fees.
1907			let mut acceptable_assets = vec![AssetId(native_token.clone())];
1908			// We also accept all assets in a pool with the native token.
1909			acceptable_assets.extend(
1910				assets_common::PoolAdapter::<Runtime>::get_assets_in_pool_with(native_token)
1911				.map_err(|()| XcmPaymentApiError::VersionedConversionFailed)?
1912			);
1913			PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets)
1914		}
1915
1916		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
1917			use crate::xcm_config::XcmConfig;
1918
1919			type Trader = <XcmConfig as xcm_executor::Config>::Trader;
1920
1921			PolkadotXcm::query_weight_to_asset_fee::<Trader>(weight, asset)
1922		}
1923
1924		fn query_xcm_weight(message: VersionedXcm<()>) -> Result<Weight, XcmPaymentApiError> {
1925			PolkadotXcm::query_xcm_weight(message)
1926		}
1927
1928		fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result<VersionedAssets, XcmPaymentApiError> {
1929			PolkadotXcm::query_delivery_fees(destination, message)
1930		}
1931	}
1932
1933	impl xcm_runtime_apis::dry_run::DryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
1934		fn dry_run_call(origin: OriginCaller, call: RuntimeCall, result_xcms_version: XcmVersion) -> Result<CallDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
1935			PolkadotXcm::dry_run_call::<Runtime, xcm_config::XcmRouter, OriginCaller, RuntimeCall>(origin, call, result_xcms_version)
1936		}
1937
1938		fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
1939			PolkadotXcm::dry_run_xcm::<Runtime, xcm_config::XcmRouter, RuntimeCall, xcm_config::XcmConfig>(origin_location, xcm)
1940		}
1941	}
1942
1943	impl xcm_runtime_apis::conversions::LocationToAccountApi<Block, AccountId> for Runtime {
1944		fn convert_location(location: VersionedLocation) -> Result<
1945			AccountId,
1946			xcm_runtime_apis::conversions::Error
1947		> {
1948			xcm_runtime_apis::conversions::LocationToAccountHelper::<
1949				AccountId,
1950				xcm_config::LocationToAccountId,
1951			>::convert_location(location)
1952		}
1953	}
1954
1955	impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
1956		fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> xcm_runtime_apis::trusted_query::XcmTrustedQueryResult {
1957			PolkadotXcm::is_trusted_reserve(asset, location)
1958		}
1959		fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> xcm_runtime_apis::trusted_query::XcmTrustedQueryResult {
1960			PolkadotXcm::is_trusted_teleporter(asset, location)
1961		}
1962	}
1963
1964	impl xcm_runtime_apis::authorized_aliases::AuthorizedAliasersApi<Block> for Runtime {
1965		fn authorized_aliasers(target: VersionedLocation) -> Result<
1966			Vec<xcm_runtime_apis::authorized_aliases::OriginAliaser>,
1967			xcm_runtime_apis::authorized_aliases::Error
1968		> {
1969			PolkadotXcm::authorized_aliasers(target)
1970		}
1971		fn is_authorized_alias(origin: VersionedLocation, target: VersionedLocation) -> Result<
1972			bool,
1973			xcm_runtime_apis::authorized_aliases::Error
1974		> {
1975			PolkadotXcm::is_authorized_alias(origin, target)
1976		}
1977	}
1978
1979	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
1980		for Runtime
1981	{
1982		fn query_call_info(
1983			call: RuntimeCall,
1984			len: u32,
1985		) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
1986			TransactionPayment::query_call_info(call, len)
1987		}
1988		fn query_call_fee_details(
1989			call: RuntimeCall,
1990			len: u32,
1991		) -> pallet_transaction_payment::FeeDetails<Balance> {
1992			TransactionPayment::query_call_fee_details(call, len)
1993		}
1994		fn query_weight_to_fee(weight: Weight) -> Balance {
1995			TransactionPayment::weight_to_fee(weight)
1996		}
1997		fn query_length_to_fee(length: u32) -> Balance {
1998			TransactionPayment::length_to_fee(length)
1999		}
2000	}
2001
2002	impl assets_common::runtime_api::FungiblesApi<
2003		Block,
2004		AccountId,
2005	> for Runtime
2006	{
2007		fn query_account_balances(account: AccountId) -> Result<xcm::VersionedAssets, assets_common::runtime_api::FungiblesAccessError> {
2008			use assets_common::fungible_conversion::{convert, convert_balance};
2009			Ok([
2010				// collect pallet_balance
2011				{
2012					let balance = Balances::free_balance(account.clone());
2013					if balance > 0 {
2014						vec![convert_balance::<WestendLocation, Balance>(balance)?]
2015					} else {
2016						vec![]
2017					}
2018				},
2019				// collect pallet_assets (TrustBackedAssets)
2020				convert::<_, _, _, _, TrustBackedAssetsConvertedConcreteId>(
2021					Assets::account_balances(account.clone())
2022						.iter()
2023						.filter(|(_, balance)| balance > &0)
2024				)?,
2025				// collect pallet_assets (ForeignAssets)
2026				convert::<_, _, _, _, ForeignAssetsConvertedConcreteId>(
2027					ForeignAssets::account_balances(account.clone())
2028						.iter()
2029						.filter(|(_, balance)| balance > &0)
2030				)?,
2031				// collect pallet_assets (PoolAssets)
2032				convert::<_, _, _, _, PoolAssetsConvertedConcreteId>(
2033					PoolAssets::account_balances(account)
2034						.iter()
2035						.filter(|(_, balance)| balance > &0)
2036				)?,
2037				// collect ... e.g. other tokens
2038			].concat().into())
2039		}
2040	}
2041
2042	impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
2043		fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
2044			ParachainSystem::collect_collation_info(header)
2045		}
2046	}
2047
2048	impl pallet_asset_rewards::AssetRewards<Block, Balance> for Runtime {
2049		fn pool_creation_cost() -> Balance {
2050			StakePoolCreationDeposit::get()
2051		}
2052	}
2053
2054	#[cfg(feature = "try-runtime")]
2055	impl frame_try_runtime::TryRuntime<Block> for Runtime {
2056		fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
2057			let weight = Executive::try_runtime_upgrade(checks).unwrap();
2058			(weight, RuntimeBlockWeights::get().max_block)
2059		}
2060
2061		fn execute_block(
2062			block: Block,
2063			state_root_check: bool,
2064			signature_check: bool,
2065			select: frame_try_runtime::TryStateSelect,
2066		) -> Weight {
2067			// NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
2068			// have a backtrace here.
2069			Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()
2070		}
2071	}
2072
2073
2074	impl pallet_nomination_pools_runtime_api::NominationPoolsApi<
2075		Block,
2076		AccountId,
2077		Balance,
2078	> for Runtime {
2079		fn pending_rewards(member: AccountId) -> Balance {
2080			NominationPools::api_pending_rewards(member).unwrap_or_default()
2081		}
2082
2083		fn points_to_balance(pool_id: PoolId, points: Balance) -> Balance {
2084			NominationPools::api_points_to_balance(pool_id, points)
2085		}
2086
2087		fn balance_to_points(pool_id: PoolId, new_funds: Balance) -> Balance {
2088			NominationPools::api_balance_to_points(pool_id, new_funds)
2089		}
2090
2091		fn pool_pending_slash(pool_id: PoolId) -> Balance {
2092			NominationPools::api_pool_pending_slash(pool_id)
2093		}
2094
2095		fn member_pending_slash(member: AccountId) -> Balance {
2096			NominationPools::api_member_pending_slash(member)
2097		}
2098
2099		fn pool_needs_delegate_migration(pool_id: PoolId) -> bool {
2100			NominationPools::api_pool_needs_delegate_migration(pool_id)
2101		}
2102
2103		fn member_needs_delegate_migration(member: AccountId) -> bool {
2104			NominationPools::api_member_needs_delegate_migration(member)
2105		}
2106
2107		fn member_total_balance(member: AccountId) -> Balance {
2108			NominationPools::api_member_total_balance(member)
2109		}
2110
2111		fn pool_balance(pool_id: PoolId) -> Balance {
2112			NominationPools::api_pool_balance(pool_id)
2113		}
2114
2115		fn pool_accounts(pool_id: PoolId) -> (AccountId, AccountId) {
2116			NominationPools::api_pool_accounts(pool_id)
2117		}
2118	}
2119
2120	impl pallet_staking_runtime_api::StakingApi<Block, Balance, AccountId> for Runtime {
2121		fn nominations_quota(balance: Balance) -> u32 {
2122			Staking::api_nominations_quota(balance)
2123		}
2124
2125		fn eras_stakers_page_count(era: sp_staking::EraIndex, account: AccountId) -> sp_staking::Page {
2126			Staking::api_eras_stakers_page_count(era, account)
2127		}
2128
2129		fn pending_rewards(era: sp_staking::EraIndex, account: AccountId) -> bool {
2130			Staking::api_pending_rewards(era, account)
2131		}
2132	}
2133
2134	#[cfg(feature = "runtime-benchmarks")]
2135	impl frame_benchmarking::Benchmark<Block> for Runtime {
2136		fn benchmark_metadata(extra: bool) -> (
2137			Vec<frame_benchmarking::BenchmarkList>,
2138			Vec<frame_support::traits::StorageInfo>,
2139		) {
2140			use frame_benchmarking::BenchmarkList;
2141			use frame_support::traits::StorageInfoTrait;
2142			use frame_system_benchmarking::Pallet as SystemBench;
2143			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
2144			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
2145			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
2146			use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench;
2147
2148			// This is defined once again in dispatch_benchmark, because list_benchmarks!
2149			// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
2150			// are referenced in that call.
2151			type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
2152			type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::<Runtime>;
2153
2154			// Benchmark files generated for `Assets/ForeignAssets` instances are by default
2155			// `pallet_assets_assets.rs / pallet_assets_foreign_assets`, which is not really nice,
2156			// so with this redefinition we can change names to nicer:
2157			// `pallet_assets_local.rs / pallet_assets_foreign.rs`.
2158			type Local = pallet_assets::Pallet::<Runtime, TrustBackedAssetsInstance>;
2159			type Foreign = pallet_assets::Pallet::<Runtime, ForeignAssetsInstance>;
2160			type Pool = pallet_assets::Pallet::<Runtime, PoolAssetsInstance>;
2161
2162			type ToRococo = XcmBridgeHubRouterBench<Runtime, ToRococoXcmRouterInstance>;
2163
2164			let mut list = Vec::<BenchmarkList>::new();
2165			list_benchmarks!(list, extra);
2166
2167			let storage_info = AllPalletsWithSystem::storage_info();
2168			(list, storage_info)
2169		}
2170
2171		#[allow(non_local_definitions)]
2172		fn dispatch_benchmark(
2173			config: frame_benchmarking::BenchmarkConfig
2174		) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, alloc::string::String> {
2175			use frame_benchmarking::{BenchmarkBatch, BenchmarkError};
2176			use frame_support::assert_ok;
2177			use sp_storage::TrackedStorageKey;
2178			use frame_system_benchmarking::Pallet as SystemBench;
2179			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
2180			impl frame_system_benchmarking::Config for Runtime {
2181				fn setup_set_code_requirements(code: &alloc::vec::Vec<u8>) -> Result<(), BenchmarkError> {
2182					ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
2183					Ok(())
2184				}
2185
2186				fn verify_set_code() {
2187					System::assert_last_event(cumulus_pallet_parachain_system::Event::<Runtime>::ValidationFunctionStored.into());
2188				}
2189			}
2190
2191			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
2192			use xcm_config::{MaxAssetsIntoHolding, WestendLocation};
2193
2194			impl cumulus_pallet_session_benchmarking::Config for Runtime {}
2195			use testnet_parachains_constants::westend::locations::{PeopleParaId, PeopleLocation};
2196			parameter_types! {
2197				pub ExistentialDepositAsset: Option<Asset> = Some((
2198					WestendLocation::get(),
2199					ExistentialDeposit::get()
2200				).into());
2201
2202				pub RandomParaId: ParaId = ParaId::new(43211234);
2203			}
2204
2205			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
2206			impl pallet_xcm::benchmarking::Config for Runtime {
2207				type DeliveryHelper = (
2208				polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
2209						xcm_config::XcmConfig,
2210						ExistentialDepositAsset,
2211						PriceForSiblingParachainDelivery,
2212						RandomParaId,
2213						ParachainSystem
2214					>,
2215				polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
2216						xcm_config::XcmConfig,
2217						ExistentialDepositAsset,
2218						PriceForSiblingParachainDelivery,
2219						PeopleParaId,
2220						ParachainSystem
2221					>);
2222
2223				fn reachable_dest() -> Option<Location> {
2224					Some(PeopleLocation::get())
2225				}
2226
2227				fn teleportable_asset_and_dest() -> Option<(Asset, Location)> {
2228					// Relay/native token can be teleported between AH and Relay.
2229					Some((
2230						Asset {
2231							fun: Fungible(ExistentialDeposit::get()),
2232							id: AssetId(WestendLocation::get())
2233						},
2234						PeopleLocation::get(),
2235					))
2236				}
2237
2238				fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
2239					// We get an account to create USDT and give it enough WND to exist.
2240					let account = frame_benchmarking::whitelisted_caller();
2241					assert_ok!(<Balances as fungible::Mutate<_>>::mint_into(
2242						&account,
2243						ExistentialDeposit::get() + (1_000 * UNITS)
2244					));
2245
2246					// We then create USDT.
2247					let usdt_id = 1984u32;
2248					let usdt_location = Location::new(0, [PalletInstance(50), GeneralIndex(usdt_id.into())]);
2249					assert_ok!(Assets::force_create(
2250						RuntimeOrigin::root(),
2251						usdt_id.into(),
2252						account.clone().into(),
2253						true,
2254						1
2255					));
2256
2257					// And return USDT as the reserve transferable asset.
2258					Some((
2259						Asset { fun: Fungible(ExistentialDeposit::get()), id: AssetId(usdt_location) },
2260						ParentThen(Parachain(RandomParaId::get().into()).into()).into(),
2261					))
2262				}
2263
2264				fn set_up_complex_asset_transfer(
2265				) -> Option<(XcmAssets, u32, Location, alloc::boxed::Box<dyn FnOnce()>)> {
2266					// Transfer to Relay some local AH asset (local-reserve-transfer) while paying
2267					// fees using teleported native token.
2268					// (We don't care that Relay doesn't accept incoming unknown AH local asset)
2269					let dest: Location = PeopleLocation::get();
2270
2271					let fee_amount = EXISTENTIAL_DEPOSIT;
2272					let fee_asset: Asset = (WestendLocation::get(), fee_amount).into();
2273
2274					let who = frame_benchmarking::whitelisted_caller();
2275					// Give some multiple of the existential deposit
2276					let balance = fee_amount + EXISTENTIAL_DEPOSIT * 1000;
2277					let _ = <Balances as frame_support::traits::Currency<_>>::make_free_balance_be(
2278						&who, balance,
2279					);
2280					// verify initial balance
2281					assert_eq!(Balances::free_balance(&who), balance);
2282
2283					// set up local asset
2284					let asset_amount = 10u128;
2285					let initial_asset_amount = asset_amount * 10;
2286					let (asset_id, _, _) = pallet_assets::benchmarking::create_default_minted_asset::<
2287						Runtime,
2288						pallet_assets::Instance1
2289					>(true, initial_asset_amount);
2290					let asset_location = Location::new(
2291						0,
2292						[PalletInstance(50), GeneralIndex(u32::from(asset_id).into())]
2293					);
2294					let transfer_asset: Asset = (asset_location, asset_amount).into();
2295
2296					let assets: XcmAssets = vec![fee_asset.clone(), transfer_asset].into();
2297					let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 };
2298
2299					// verify transferred successfully
2300					let verify = alloc::boxed::Box::new(move || {
2301						// verify native balance after transfer, decreased by transferred fee amount
2302						// (plus transport fees)
2303						assert!(Balances::free_balance(&who) <= balance - fee_amount);
2304						// verify asset balance decreased by exactly transferred amount
2305						assert_eq!(
2306							Assets::balance(asset_id.into(), &who),
2307							initial_asset_amount - asset_amount,
2308						);
2309					});
2310					Some((assets, fee_index as u32, dest, verify))
2311				}
2312
2313				fn get_asset() -> Asset {
2314					use frame_benchmarking::whitelisted_caller;
2315					use frame_support::traits::tokens::fungible::{Inspect, Mutate};
2316					let account = whitelisted_caller();
2317					assert_ok!(<Balances as Mutate<_>>::mint_into(
2318						&account,
2319						<Balances as Inspect<_>>::minimum_balance(),
2320					));
2321					let asset_id = 1984;
2322					assert_ok!(Assets::force_create(
2323						RuntimeOrigin::root(),
2324						asset_id.into(),
2325						account.into(),
2326						true,
2327						1u128,
2328					));
2329					let amount = 1_000_000u128;
2330					let asset_location = Location::new(0, [PalletInstance(50), GeneralIndex(u32::from(asset_id).into())]);
2331
2332					Asset {
2333						id: AssetId(asset_location),
2334						fun: Fungible(amount),
2335					}
2336				}
2337			}
2338
2339			use pallet_xcm_bridge_hub_router::benchmarking::{
2340				Pallet as XcmBridgeHubRouterBench,
2341				Config as XcmBridgeHubRouterConfig,
2342			};
2343
2344			impl XcmBridgeHubRouterConfig<ToRococoXcmRouterInstance> for Runtime {
2345				fn make_congested() {
2346					cumulus_pallet_xcmp_queue::bridging::suspend_channel_for_benchmarks::<Runtime>(
2347						xcm_config::bridging::SiblingBridgeHubParaId::get().into()
2348					);
2349				}
2350				fn ensure_bridged_target_destination() -> Result<Location, BenchmarkError> {
2351					ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
2352						xcm_config::bridging::SiblingBridgeHubParaId::get().into()
2353					);
2354					let bridged_asset_hub = xcm_config::bridging::to_rococo::AssetHubRococo::get();
2355					let _ = PolkadotXcm::force_xcm_version(
2356						RuntimeOrigin::root(),
2357						alloc::boxed::Box::new(bridged_asset_hub.clone()),
2358						XCM_VERSION,
2359					).map_err(|e| {
2360						tracing::error!(
2361							target: "bridges::benchmark",
2362							error=?e,
2363							origin=?RuntimeOrigin::root(),
2364							location=?bridged_asset_hub,
2365							version=?XCM_VERSION,
2366							"Failed to dispatch `force_xcm_version`"
2367						);
2368						BenchmarkError::Stop("XcmVersion was not stored!")
2369					})?;
2370					Ok(bridged_asset_hub)
2371				}
2372			}
2373
2374			use pallet_xcm_benchmarks::asset_instance_from;
2375
2376			impl pallet_xcm_benchmarks::Config for Runtime {
2377				type XcmConfig = xcm_config::XcmConfig;
2378				type AccountIdConverter = xcm_config::LocationToAccountId;
2379				type DeliveryHelper = polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
2380										xcm_config::XcmConfig,
2381										ExistentialDepositAsset,
2382										PriceForSiblingParachainDelivery,
2383										PeopleParaId,
2384										ParachainSystem
2385				>;
2386				fn valid_destination() -> Result<Location, BenchmarkError> {
2387					Ok(PeopleLocation::get())
2388				}
2389				fn worst_case_holding(depositable_count: u32) -> XcmAssets {
2390					// A mix of fungible, non-fungible, and concrete assets.
2391					let holding_non_fungibles = MaxAssetsIntoHolding::get() / 2 - depositable_count;
2392					let holding_fungibles = holding_non_fungibles - 2; // -2 for two `iter::once` bellow
2393					let fungibles_amount: u128 = 100;
2394					(0..holding_fungibles)
2395						.map(|i| {
2396							Asset {
2397								id: AssetId(GeneralIndex(i as u128).into()),
2398								fun: Fungible(fungibles_amount * (i + 1) as u128), // non-zero amount
2399							}
2400						})
2401						.chain(core::iter::once(Asset { id: AssetId(Here.into()), fun: Fungible(u128::MAX) }))
2402						.chain(core::iter::once(Asset { id: AssetId(WestendLocation::get()), fun: Fungible(1_000_000 * UNITS) }))
2403						.chain((0..holding_non_fungibles).map(|i| Asset {
2404							id: AssetId(GeneralIndex(i as u128).into()),
2405							fun: NonFungible(asset_instance_from(i)),
2406						}))
2407						.collect::<Vec<_>>()
2408						.into()
2409				}
2410			}
2411
2412			parameter_types! {
2413				pub TrustedTeleporter: Option<(Location, Asset)> = Some((
2414					PeopleLocation::get(),
2415					Asset { fun: Fungible(UNITS), id: AssetId(WestendLocation::get()) },
2416				));
2417				// AssetHubWestend trusts AssetHubRococo as reserve for ROCs
2418				pub TrustedReserve: Option<(Location, Asset)> = Some(
2419					(
2420						xcm_config::bridging::to_rococo::AssetHubRococo::get(),
2421						Asset::from((xcm_config::bridging::to_rococo::RocLocation::get(), 1000000000000 as u128))
2422					)
2423				);
2424			}
2425
2426			impl pallet_xcm_benchmarks::fungible::Config for Runtime {
2427				type TransactAsset = Balances;
2428
2429				type CheckedAccount = xcm_config::TeleportTracking;
2430				type TrustedTeleporter = TrustedTeleporter;
2431				type TrustedReserve = TrustedReserve;
2432
2433				fn get_asset() -> Asset {
2434					use frame_support::traits::tokens::fungible::{Inspect, Mutate};
2435					let (account, _) = pallet_xcm_benchmarks::account_and_location::<Runtime>(1);
2436					assert_ok!(<Balances as Mutate<_>>::mint_into(
2437						&account,
2438						<Balances as Inspect<_>>::minimum_balance(),
2439					));
2440					let asset_id = 1984;
2441					assert_ok!(Assets::force_create(
2442						RuntimeOrigin::root(),
2443						asset_id.into(),
2444						account.clone().into(),
2445						true,
2446						1u128,
2447					));
2448					let amount = 1_000_000u128;
2449					let asset_location = Location::new(0, [PalletInstance(50), GeneralIndex(u32::from(asset_id).into())]);
2450
2451					Asset {
2452						id: AssetId(asset_location),
2453						fun: Fungible(amount),
2454					}
2455				}
2456			}
2457
2458			impl pallet_xcm_benchmarks::generic::Config for Runtime {
2459				type TransactAsset = Balances;
2460				type RuntimeCall = RuntimeCall;
2461
2462				fn worst_case_response() -> (u64, Response) {
2463					(0u64, Response::Version(Default::default()))
2464				}
2465
2466				fn worst_case_asset_exchange() -> Result<(XcmAssets, XcmAssets), BenchmarkError> {
2467					let native_asset_location = WestendLocation::get();
2468					let native_asset_id = AssetId(native_asset_location.clone());
2469					let (account, _) = pallet_xcm_benchmarks::account_and_location::<Runtime>(1);
2470					let origin = RuntimeOrigin::signed(account.clone());
2471					let asset_location = Location::new(1, [Parachain(2001)]);
2472					let asset_id = AssetId(asset_location.clone());
2473
2474					assert_ok!(<Balances as fungible::Mutate<_>>::mint_into(
2475						&account,
2476						ExistentialDeposit::get() + (1_000 * UNITS)
2477					));
2478
2479					assert_ok!(ForeignAssets::force_create(
2480						RuntimeOrigin::root(),
2481						asset_location.clone().into(),
2482						account.clone().into(),
2483						true,
2484						1,
2485					));
2486
2487					assert_ok!(ForeignAssets::mint(
2488						origin.clone(),
2489						asset_location.clone().into(),
2490						account.clone().into(),
2491						3_000 * UNITS,
2492					));
2493
2494					assert_ok!(AssetConversion::create_pool(
2495						origin.clone(),
2496						native_asset_location.clone().into(),
2497						asset_location.clone().into(),
2498					));
2499
2500					assert_ok!(AssetConversion::add_liquidity(
2501						origin,
2502						native_asset_location.into(),
2503						asset_location.into(),
2504						1_000 * UNITS,
2505						2_000 * UNITS,
2506						1,
2507						1,
2508						account.into(),
2509					));
2510
2511					let give_assets: XcmAssets = (native_asset_id, 500 * UNITS).into();
2512					let receive_assets: XcmAssets = (asset_id, 660 * UNITS).into();
2513
2514					Ok((give_assets, receive_assets))
2515				}
2516
2517				fn universal_alias() -> Result<(Location, Junction), BenchmarkError> {
2518					xcm_config::bridging::BridgingBenchmarksHelper::prepare_universal_alias()
2519					.ok_or(BenchmarkError::Skip)
2520				}
2521
2522				fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> {
2523					Ok((
2524						PeopleLocation::get(),
2525						frame_system::Call::remark_with_event { remark: vec![] }.into()
2526					))
2527				}
2528
2529				fn subscribe_origin() -> Result<Location, BenchmarkError> {
2530					Ok(PeopleLocation::get())
2531				}
2532
2533				fn claimable_asset() -> Result<(Location, Location, XcmAssets), BenchmarkError> {
2534					let origin = PeopleLocation::get();
2535					let assets: XcmAssets = (AssetId(WestendLocation::get()), 1_000 * UNITS).into();
2536					let ticket = Location { parents: 0, interior: Here };
2537					Ok((origin, ticket, assets))
2538				}
2539
2540				fn worst_case_for_trader() -> Result<(Asset, WeightLimit), BenchmarkError> {
2541					Ok((Asset {
2542						id: AssetId(WestendLocation::get()),
2543						fun: Fungible(1_000 * UNITS),
2544					}, WeightLimit::Limited(Weight::from_parts(5000, 5000))))
2545				}
2546
2547				fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> {
2548					Err(BenchmarkError::Skip)
2549				}
2550
2551				fn export_message_origin_and_destination(
2552				) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> {
2553					Err(BenchmarkError::Skip)
2554				}
2555
2556				fn alias_origin() -> Result<(Location, Location), BenchmarkError> {
2557					// Any location can alias to an internal location.
2558					// Here parachain 1001 aliases to an internal account.
2559					Ok((
2560						Location::new(1, [Parachain(1001)]),
2561						Location::new(1, [Parachain(1001), AccountId32 { id: [111u8; 32], network: None }]),
2562					))
2563				}
2564			}
2565
2566			type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
2567			type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::<Runtime>;
2568
2569			type Local = pallet_assets::Pallet::<Runtime, TrustBackedAssetsInstance>;
2570			type Foreign = pallet_assets::Pallet::<Runtime, ForeignAssetsInstance>;
2571			type Pool = pallet_assets::Pallet::<Runtime, PoolAssetsInstance>;
2572
2573			type ToRococo = XcmBridgeHubRouterBench<Runtime, ToRococoXcmRouterInstance>;
2574
2575			use frame_support::traits::WhitelistedStorageKeys;
2576			let whitelist: Vec<TrackedStorageKey> = AllPalletsWithSystem::whitelisted_storage_keys();
2577
2578			let mut batches = Vec::<BenchmarkBatch>::new();
2579			let params = (&config, &whitelist);
2580			add_benchmarks!(params, batches);
2581
2582			Ok(batches)
2583		}
2584	}
2585
2586	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
2587		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
2588			build_state::<RuntimeGenesisConfig>(config)
2589		}
2590
2591		fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
2592			get_preset::<RuntimeGenesisConfig>(id, &genesis_config_presets::get_preset)
2593		}
2594
2595		fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
2596			genesis_config_presets::preset_names()
2597		}
2598	}
2599);
2600
2601cumulus_pallet_parachain_system::register_validate_block! {
2602	Runtime = Runtime,
2603	BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
2604}
2605
2606parameter_types! {
2607	// The deposit configuration for the singed migration. Specially if you want to allow any signed account to do the migration (see `SignedFilter`, these deposits should be high)
2608	pub const MigrationSignedDepositPerItem: Balance = CENTS;
2609	pub const MigrationSignedDepositBase: Balance = 2_000 * CENTS;
2610	pub const MigrationMaxKeyLen: u32 = 512;
2611}
2612
2613impl pallet_state_trie_migration::Config for Runtime {
2614	type RuntimeEvent = RuntimeEvent;
2615	type Currency = Balances;
2616	type RuntimeHoldReason = RuntimeHoldReason;
2617	type SignedDepositPerItem = MigrationSignedDepositPerItem;
2618	type SignedDepositBase = MigrationSignedDepositBase;
2619	// An origin that can control the whole pallet: should be Root, or a part of your council.
2620	type ControlOrigin = frame_system::EnsureSignedBy<RootMigController, AccountId>;
2621	// specific account for the migration, can trigger the signed migrations.
2622	type SignedFilter = frame_system::EnsureSignedBy<MigController, AccountId>;
2623
2624	// Replace this with weight based on your runtime.
2625	type WeightInfo = pallet_state_trie_migration::weights::SubstrateWeight<Runtime>;
2626
2627	type MaxKeyLen = MigrationMaxKeyLen;
2628}
2629
2630frame_support::ord_parameter_types! {
2631	pub const MigController: AccountId = AccountId::from(hex_literal::hex!("8458ed39dc4b6f6c7255f7bc42be50c2967db126357c999d44e12ca7ac80dc52"));
2632	pub const RootMigController: AccountId = AccountId::from(hex_literal::hex!("8458ed39dc4b6f6c7255f7bc42be50c2967db126357c999d44e12ca7ac80dc52"));
2633}
2634
2635#[test]
2636fn ensure_key_ss58() {
2637	use frame_support::traits::SortedMembers;
2638	use sp_core::crypto::Ss58Codec;
2639	let acc =
2640		AccountId::from_ss58check("5F4EbSkZz18X36xhbsjvDNs6NuZ82HyYtq5UiJ1h9SBHJXZD").unwrap();
2641	assert_eq!(acc, MigController::sorted_members()[0]);
2642	let acc =
2643		AccountId::from_ss58check("5F4EbSkZz18X36xhbsjvDNs6NuZ82HyYtq5UiJ1h9SBHJXZD").unwrap();
2644	assert_eq!(acc, RootMigController::sorted_members()[0]);
2645}