referrerpolicy=no-referrer-when-downgrade

penpal_runtime/
lib.rs

1// This file is part of Cumulus.
2// SPDX-License-Identifier: Unlicense
3
4// This is free and unencumbered software released into the public domain.
5
6// Anyone is free to copy, modify, publish, use, compile, sell, or
7// distribute this software, either in source code form or as a compiled
8// binary, for any purpose, commercial or non-commercial, and by any
9// means.
10
11// In jurisdictions that recognize copyright laws, the author or authors
12// of this software dedicate any and all copyright interest in the
13// software to the public domain. We make this dedication for the benefit
14// of the public at large and to the detriment of our heirs and
15// successors. We intend this dedication to be an overt act of
16// relinquishment in perpetuity of all present and future rights to this
17// software under copyright law.
18
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25// OTHER DEALINGS IN THE SOFTWARE.
26
27// For more information, please refer to <http://unlicense.org/>
28
29//! The PenPal runtime is designed as a test runtime that can be created with an arbitrary `ParaId`,
30//! such that multiple instances of the parachain can be on the same parent relay. Ensure that you
31//! have enough nodes running to support this or you will get scheduling errors.
32//!
33//! The PenPal runtime's primary use is for testing interactions between System parachains and
34//! other chains that are not trusted teleporters.
35
36#![cfg_attr(not(feature = "std"), no_std)]
37// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
38#![recursion_limit = "256"]
39
40// Make the WASM binary available.
41#[cfg(feature = "std")]
42include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
43
44mod genesis_config_presets;
45mod weights;
46pub mod xcm_config;
47
48extern crate alloc;
49
50use alloc::{vec, vec::Vec};
51use assets_common::{
52	foreign_creators::ForeignCreators,
53	local_and_foreign_assets::{LocalFromLeft, TargetFromLeft},
54	AssetIdForTrustBackedAssetsConvert,
55};
56use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases;
57use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
58
59use frame_support::{
60	construct_runtime, derive_impl,
61	dispatch::DispatchClass,
62	genesis_builder_helper::{build_state, get_preset},
63	ord_parameter_types,
64	pallet_prelude::Weight,
65	parameter_types,
66	traits::{
67		tokens::{fungible, fungibles, imbalance::ResolveAssetTo},
68		AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, Everything,
69		TransformOrigin,
70	},
71	weights::{
72		constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, FeePolynomial,
73		WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial,
74	},
75	PalletId,
76};
77use frame_system::{
78	limits::{BlockLength, BlockWeights},
79	EnsureRoot, EnsureSigned, EnsureSignedBy,
80};
81use pallet_revive::evm::runtime::EthExtra;
82use parachains_common::{
83	impls::{AssetsToBlockAuthor, NonZeroIssuance},
84	message_queue::{NarrowOriginToSibling, ParaIdToSibling},
85};
86use smallvec::smallvec;
87use sp_api::impl_runtime_apis;
88pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
89use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
90use sp_runtime::{
91	generic, impl_opaque_keys,
92	traits::{AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT},
93	transaction_validity::{TransactionSource, TransactionValidity},
94	ApplyExtrinsicResult,
95};
96pub use sp_runtime::{traits::ConvertInto, MultiAddress, Perbill, Permill};
97#[cfg(feature = "std")]
98use sp_version::NativeVersion;
99use sp_version::RuntimeVersion;
100use xcm_config::{ForeignAssetsAssetId, LocationToAccountId, XcmOriginToTransactDispatchOrigin};
101
102#[cfg(any(feature = "std", test))]
103pub use sp_runtime::BuildStorage;
104
105use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
106use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};
107use xcm::{
108	latest::prelude::{AssetId as AssetLocationId, BodyId},
109	Version as XcmVersion, VersionedAsset, VersionedAssetId, VersionedAssets, VersionedLocation,
110	VersionedXcm,
111};
112use xcm_runtime_apis::{
113	dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
114	fees::Error as XcmPaymentApiError,
115};
116
117use parachains_common::{AccountId, Balance, BlockNumber, Hash, Header, Nonce, Signature};
118use testnet_parachains_constants::westend::{consensus::*, time::*};
119
120/// The address format for describing accounts.
121pub type Address = MultiAddress<AccountId, ()>;
122
123/// Block type as expected by this runtime.
124pub type Block = generic::Block<Header, UncheckedExtrinsic>;
125
126/// A Block signed with a Justification
127pub type SignedBlock = generic::SignedBlock<Block>;
128
129/// BlockId type as expected by this runtime.
130pub type BlockId = generic::BlockId<Block>;
131
132// Id used for identifying assets.
133pub type AssetId = u32;
134
135/// The extension to the basic transaction logic.
136pub type TxExtension = (
137	frame_system::AuthorizeCall<Runtime>,
138	frame_system::CheckNonZeroSender<Runtime>,
139	frame_system::CheckSpecVersion<Runtime>,
140	frame_system::CheckTxVersion<Runtime>,
141	frame_system::CheckGenesis<Runtime>,
142	frame_system::CheckEra<Runtime>,
143	frame_system::CheckNonce<Runtime>,
144	frame_system::CheckWeight<Runtime>,
145	pallet_asset_tx_payment::ChargeAssetTxPayment<Runtime>,
146	frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
147	frame_system::WeightReclaim<Runtime>,
148);
149
150/// Default extensions applied to Ethereum transactions.
151#[derive(Clone, PartialEq, Eq, Debug)]
152pub struct EthExtraImpl;
153
154impl EthExtra for EthExtraImpl {
155	type Config = Runtime;
156	type Extension = TxExtension;
157
158	fn get_eth_extension(nonce: u32, tip: Balance) -> Self::Extension {
159		(
160			frame_system::AuthorizeCall::<Runtime>::new(),
161			frame_system::CheckNonZeroSender::<Runtime>::new(),
162			frame_system::CheckSpecVersion::<Runtime>::new(),
163			frame_system::CheckTxVersion::<Runtime>::new(),
164			frame_system::CheckGenesis::<Runtime>::new(),
165			frame_system::CheckEra::<Runtime>::from(generic::Era::Immortal),
166			frame_system::CheckNonce::<Runtime>::from(nonce),
167			frame_system::CheckWeight::<Runtime>::new(),
168			pallet_asset_tx_payment::ChargeAssetTxPayment::<Runtime>::from(tip, None),
169			frame_metadata_hash_extension::CheckMetadataHash::<Runtime>::new(false),
170			frame_system::WeightReclaim::<Runtime>::new(),
171		)
172			.into()
173	}
174}
175
176/// Unchecked extrinsic type as expected by this runtime.
177pub type UncheckedExtrinsic =
178	pallet_revive::evm::runtime::UncheckedExtrinsic<Address, Signature, EthExtraImpl>;
179
180pub type Migrations = (
181	pallet_balances::migration::MigrateToTrackInactive<Runtime, xcm_config::CheckingAccount>,
182	pallet_collator_selection::migration::v1::MigrateToV1<Runtime>,
183	pallet_session::migrations::v1::MigrateV0ToV1<
184		Runtime,
185		pallet_session::migrations::v1::InitOffenceSeverity<Runtime>,
186	>,
187);
188
189/// Executive: handles dispatch to the various modules.
190pub type Executive = frame_executive::Executive<
191	Runtime,
192	Block,
193	frame_system::ChainContext<Runtime>,
194	Runtime,
195	AllPalletsWithSystem,
196>;
197
198/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the
199/// node's balance type.
200///
201/// This should typically create a mapping between the following ranges:
202///   - `[0, MAXIMUM_BLOCK_WEIGHT]`
203///   - `[Balance::min, Balance::max]`
204///
205/// Yet, it can be used for any other sort of change to weight-fee. Some examples being:
206///   - Setting it to `0` will essentially disable the weight fee.
207///   - Setting it to `1` will cause the literal `#[weight = x]` values to be charged.
208pub struct WeightToFee;
209impl frame_support::weights::WeightToFee for WeightToFee {
210	type Balance = Balance;
211
212	fn weight_to_fee(weight: &Weight) -> Self::Balance {
213		let time_poly: FeePolynomial<Balance> = RefTimeToFee::polynomial().into();
214		let proof_poly: FeePolynomial<Balance> = ProofSizeToFee::polynomial().into();
215
216		// Take the maximum instead of the sum to charge by the more scarce resource.
217		time_poly.eval(weight.ref_time()).max(proof_poly.eval(weight.proof_size()))
218	}
219}
220
221/// Maps the reference time component of `Weight` to a fee.
222pub struct RefTimeToFee;
223impl WeightToFeePolynomial for RefTimeToFee {
224	type Balance = Balance;
225	fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
226		let p = MILLIUNIT / 10;
227		let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
228
229		smallvec![WeightToFeeCoefficient {
230			degree: 1,
231			negative: false,
232			coeff_frac: Perbill::from_rational(p % q, q),
233			coeff_integer: p / q,
234		}]
235	}
236}
237
238/// Maps the proof size component of `Weight` to a fee.
239pub struct ProofSizeToFee;
240impl WeightToFeePolynomial for ProofSizeToFee {
241	type Balance = Balance;
242	fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
243		// Map 10kb proof to 1 CENT.
244		let p = MILLIUNIT / 10;
245		let q = 10_000;
246
247		smallvec![WeightToFeeCoefficient {
248			degree: 1,
249			negative: false,
250			coeff_frac: Perbill::from_rational(p % q, q),
251			coeff_integer: p / q,
252		}]
253	}
254}
255/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
256/// the specifics of the runtime. They can then be made to be agnostic over specific formats
257/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
258/// to even the core data structures.
259pub mod opaque {
260	use super::*;
261	use sp_runtime::{generic, traits::BlakeTwo256};
262
263	pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
264	/// Opaque block header type.
265	pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
266	/// Opaque block type.
267	pub type Block = generic::Block<Header, UncheckedExtrinsic>;
268	/// Opaque block identifier type.
269	pub type BlockId = generic::BlockId<Block>;
270}
271
272impl_opaque_keys! {
273	pub struct SessionKeys {
274		pub aura: Aura,
275	}
276}
277
278#[sp_version::runtime_version]
279pub const VERSION: RuntimeVersion = RuntimeVersion {
280	spec_name: alloc::borrow::Cow::Borrowed("penpal-parachain"),
281	impl_name: alloc::borrow::Cow::Borrowed("penpal-parachain"),
282	authoring_version: 1,
283	spec_version: 1,
284	impl_version: 0,
285	apis: RUNTIME_API_VERSIONS,
286	transaction_version: 1,
287	system_version: 1,
288};
289
290// Unit = the base number of indivisible units for balances
291pub const UNIT: Balance = 1_000_000_000_000;
292pub const MILLIUNIT: Balance = 1_000_000_000;
293pub const MICROUNIT: Balance = 1_000_000;
294
295/// The existential deposit. Set to 1/10 of the Connected Relay Chain.
296pub const EXISTENTIAL_DEPOSIT: Balance = MILLIUNIT;
297
298/// We assume that ~5% of the block weight is consumed by `on_initialize` handlers. This is
299/// used to limit the maximal weight of a single extrinsic.
300const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5);
301
302/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used by
303/// `Operational` extrinsics.
304const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
305
306/// We allow for 0.5 of a second of compute with a 12 second average block time.
307const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(
308	WEIGHT_REF_TIME_PER_SECOND.saturating_div(2),
309	cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64,
310);
311
312/// The version information used to identify this runtime when compiled natively.
313#[cfg(feature = "std")]
314pub fn native_version() -> NativeVersion {
315	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
316}
317
318parameter_types! {
319	pub const Version: RuntimeVersion = VERSION;
320
321	// This part is copied from Substrate's `bin/node/runtime/src/lib.rs`.
322	//  The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the
323	// `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize
324	// the lazy contract deletion.
325	pub RuntimeBlockLength: BlockLength =
326		BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
327	pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
328		.base_block(BlockExecutionWeight::get())
329		.for_class(DispatchClass::all(), |weights| {
330			weights.base_extrinsic = ExtrinsicBaseWeight::get();
331		})
332		.for_class(DispatchClass::Normal, |weights| {
333			weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
334		})
335		.for_class(DispatchClass::Operational, |weights| {
336			weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
337			// Operational transactions have some extra reserved space, so that they
338			// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
339			weights.reserved = Some(
340				MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
341			);
342		})
343		.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
344		.build_or_panic();
345	pub const SS58Prefix: u16 = 42;
346}
347
348// Configure FRAME pallets to include in runtime.
349
350#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
351impl frame_system::Config for Runtime {
352	/// The identifier used to distinguish between accounts.
353	type AccountId = AccountId;
354	/// The aggregated dispatch type that is available for extrinsics.
355	type RuntimeCall = RuntimeCall;
356	/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
357	type Lookup = AccountIdLookup<AccountId, ()>;
358	/// The index type for storing how many extrinsics an account has signed.
359	type Nonce = Nonce;
360	/// The type for hashing blocks and tries.
361	type Hash = Hash;
362	/// The hashing algorithm used.
363	type Hashing = BlakeTwo256;
364	/// The block type.
365	type Block = Block;
366	/// The ubiquitous event type.
367	type RuntimeEvent = RuntimeEvent;
368	/// The ubiquitous origin type.
369	type RuntimeOrigin = RuntimeOrigin;
370	/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
371	type BlockHashCount = BlockHashCount;
372	/// Runtime version.
373	type Version = Version;
374	/// Converts a module to an index of this module in the runtime.
375	type PalletInfo = PalletInfo;
376	/// The data to be stored in an account.
377	type AccountData = pallet_balances::AccountData<Balance>;
378	/// What to do if a new account is created.
379	type OnNewAccount = ();
380	/// What to do if an account is fully reaped from the system.
381	type OnKilledAccount = ();
382	/// The weight of database operations that the runtime can invoke.
383	type DbWeight = RocksDbWeight;
384	/// The basic call filter to use in dispatchable.
385	type BaseCallFilter = Everything;
386	/// Weight information for the extrinsics of this pallet.
387	type SystemWeightInfo = ();
388	/// Block & extrinsics weights: base values and limits.
389	type BlockWeights = RuntimeBlockWeights;
390	/// The maximum length of a block (in bytes).
391	type BlockLength = RuntimeBlockLength;
392	/// This is used as an identifier of the chain. 42 is the generic substrate prefix.
393	type SS58Prefix = SS58Prefix;
394	/// The action to take on a Runtime Upgrade
395	type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
396	type MaxConsumers = frame_support::traits::ConstU32<16>;
397	type SingleBlockMigrations = Migrations;
398}
399
400impl pallet_timestamp::Config for Runtime {
401	/// A timestamp: milliseconds since the unix epoch.
402	type Moment = u64;
403	type OnTimestampSet = Aura;
404	type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>;
405	type WeightInfo = ();
406}
407
408impl pallet_authorship::Config for Runtime {
409	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
410	type EventHandler = (CollatorSelection,);
411}
412
413parameter_types! {
414	pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
415}
416
417impl pallet_balances::Config for Runtime {
418	type MaxLocks = ConstU32<50>;
419	/// The type for recording an account's balance.
420	type Balance = Balance;
421	/// The ubiquitous event type.
422	type RuntimeEvent = RuntimeEvent;
423	type DustRemoval = ();
424	type ExistentialDeposit = ExistentialDeposit;
425	type AccountStore = System;
426	type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
427	type MaxReserves = ConstU32<50>;
428	type ReserveIdentifier = [u8; 8];
429	type RuntimeHoldReason = RuntimeHoldReason;
430	type RuntimeFreezeReason = RuntimeFreezeReason;
431	type FreezeIdentifier = ();
432	type MaxFreezes = ConstU32<0>;
433	type DoneSlashHandler = ();
434}
435
436parameter_types! {
437	/// Relay Chain `TransactionByteFee` / 10
438	pub const TransactionByteFee: Balance = 10 * MICROUNIT;
439}
440
441impl pallet_transaction_payment::Config for Runtime {
442	type RuntimeEvent = RuntimeEvent;
443	type OnChargeTransaction = pallet_transaction_payment::FungibleAdapter<Balances, ()>;
444	type WeightToFee = WeightToFee;
445	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
446	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
447	type OperationalFeeMultiplier = ConstU8<5>;
448	type WeightInfo = ();
449}
450
451parameter_types! {
452	pub const AssetDeposit: Balance = 0;
453	pub const AssetAccountDeposit: Balance = 0;
454	pub const ApprovalDeposit: Balance = 0;
455	pub const AssetsStringLimit: u32 = 50;
456	pub const MetadataDepositBase: Balance = 0;
457	pub const MetadataDepositPerByte: Balance = 0;
458}
459
460// /// We allow root and the Relay Chain council to execute privileged asset operations.
461// pub type AssetsForceOrigin =
462// 	EnsureOneOf<EnsureRoot<AccountId>, EnsureXcm<IsMajorityOfBody<KsmLocation, ExecutiveBody>>>;
463
464pub type TrustBackedAssetsInstance = pallet_assets::Instance1;
465
466impl pallet_assets::Config<TrustBackedAssetsInstance> for Runtime {
467	type RuntimeEvent = RuntimeEvent;
468	type Balance = Balance;
469	type AssetId = AssetId;
470	type AssetIdParameter = codec::Compact<AssetId>;
471	type Currency = Balances;
472	type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
473	type ForceOrigin = EnsureRoot<AccountId>;
474	type AssetDeposit = AssetDeposit;
475	type MetadataDepositBase = MetadataDepositBase;
476	type MetadataDepositPerByte = MetadataDepositPerByte;
477	type ApprovalDeposit = ApprovalDeposit;
478	type StringLimit = AssetsStringLimit;
479	type Holder = ();
480	type Freezer = ();
481	type Extra = ();
482	type WeightInfo = pallet_assets::weights::SubstrateWeight<Runtime>;
483	type CallbackHandle = ();
484	type AssetAccountDeposit = AssetAccountDeposit;
485	type RemoveItemsLimit = frame_support::traits::ConstU32<1000>;
486	#[cfg(feature = "runtime-benchmarks")]
487	type BenchmarkHelper = ();
488}
489
490parameter_types! {
491	// we just reuse the same deposits
492	pub const ForeignAssetsAssetDeposit: Balance = AssetDeposit::get();
493	pub const ForeignAssetsAssetAccountDeposit: Balance = AssetAccountDeposit::get();
494	pub const ForeignAssetsApprovalDeposit: Balance = ApprovalDeposit::get();
495	pub const ForeignAssetsAssetsStringLimit: u32 = AssetsStringLimit::get();
496	pub const ForeignAssetsMetadataDepositBase: Balance = MetadataDepositBase::get();
497	pub const ForeignAssetsMetadataDepositPerByte: Balance = MetadataDepositPerByte::get();
498}
499
500/// Another pallet assets instance to store foreign assets from bridgehub.
501pub type ForeignAssetsInstance = pallet_assets::Instance2;
502impl pallet_assets::Config<ForeignAssetsInstance> for Runtime {
503	type RuntimeEvent = RuntimeEvent;
504	type Balance = Balance;
505	type AssetId = ForeignAssetsAssetId;
506	type AssetIdParameter = ForeignAssetsAssetId;
507	type Currency = Balances;
508	// This is to allow any other remote location to create foreign assets. Used in tests, not
509	// recommended on real chains.
510	type CreateOrigin =
511		ForeignCreators<Everything, LocationToAccountId, AccountId, xcm::latest::Location>;
512	type ForceOrigin = EnsureRoot<AccountId>;
513	type AssetDeposit = ForeignAssetsAssetDeposit;
514	type MetadataDepositBase = ForeignAssetsMetadataDepositBase;
515	type MetadataDepositPerByte = ForeignAssetsMetadataDepositPerByte;
516	type ApprovalDeposit = ForeignAssetsApprovalDeposit;
517	type StringLimit = ForeignAssetsAssetsStringLimit;
518	type Holder = ();
519	type Freezer = ();
520	type Extra = ();
521	type WeightInfo = pallet_assets::weights::SubstrateWeight<Runtime>;
522	type CallbackHandle = ();
523	type AssetAccountDeposit = ForeignAssetsAssetAccountDeposit;
524	type RemoveItemsLimit = frame_support::traits::ConstU32<1000>;
525	#[cfg(feature = "runtime-benchmarks")]
526	type BenchmarkHelper = xcm_config::XcmBenchmarkHelper;
527}
528
529parameter_types! {
530	pub const AssetConversionPalletId: PalletId = PalletId(*b"py/ascon");
531	pub const LiquidityWithdrawalFee: Permill = Permill::from_percent(0);
532}
533
534ord_parameter_types! {
535	pub const AssetConversionOrigin: sp_runtime::AccountId32 =
536		AccountIdConversion::<sp_runtime::AccountId32>::into_account_truncating(&AssetConversionPalletId::get());
537}
538
539pub type AssetsForceOrigin = EnsureRoot<AccountId>;
540
541pub type PoolAssetsInstance = pallet_assets::Instance3;
542impl pallet_assets::Config<PoolAssetsInstance> for Runtime {
543	type RuntimeEvent = RuntimeEvent;
544	type Balance = Balance;
545	type RemoveItemsLimit = ConstU32<1000>;
546	type AssetId = u32;
547	type AssetIdParameter = u32;
548	type Currency = Balances;
549	type CreateOrigin =
550		AsEnsureOriginWithArg<EnsureSignedBy<AssetConversionOrigin, sp_runtime::AccountId32>>;
551	type ForceOrigin = AssetsForceOrigin;
552	type AssetDeposit = ConstU128<0>;
553	type AssetAccountDeposit = ConstU128<0>;
554	type MetadataDepositBase = ConstU128<0>;
555	type MetadataDepositPerByte = ConstU128<0>;
556	type ApprovalDeposit = ConstU128<0>;
557	type StringLimit = ConstU32<50>;
558	type Holder = ();
559	type Freezer = ();
560	type Extra = ();
561	type WeightInfo = pallet_assets::weights::SubstrateWeight<Runtime>;
562	type CallbackHandle = ();
563	#[cfg(feature = "runtime-benchmarks")]
564	type BenchmarkHelper = ();
565}
566
567/// Union fungibles implementation for `Assets` and `ForeignAssets`.
568pub type LocalAndForeignAssets = fungibles::UnionOf<
569	Assets,
570	ForeignAssets,
571	LocalFromLeft<
572		AssetIdForTrustBackedAssetsConvert<
573			xcm_config::TrustBackedAssetsPalletLocation,
574			xcm::latest::Location,
575		>,
576		parachains_common::AssetIdForTrustBackedAssets,
577		xcm::latest::Location,
578	>,
579	xcm::latest::Location,
580	AccountId,
581>;
582
583/// Union fungibles implementation for [`LocalAndForeignAssets`] and `Balances`.
584pub type NativeAndAssets = fungible::UnionOf<
585	Balances,
586	LocalAndForeignAssets,
587	TargetFromLeft<xcm_config::RelayLocation, xcm::latest::Location>,
588	xcm::latest::Location,
589	AccountId,
590>;
591
592pub type PoolIdToAccountId = pallet_asset_conversion::AccountIdConverter<
593	AssetConversionPalletId,
594	(xcm::latest::Location, xcm::latest::Location),
595>;
596
597impl pallet_asset_conversion::Config for Runtime {
598	type RuntimeEvent = RuntimeEvent;
599	type Balance = Balance;
600	type HigherPrecisionBalance = sp_core::U256;
601	type AssetKind = xcm::latest::Location;
602	type Assets = NativeAndAssets;
603	type PoolId = (Self::AssetKind, Self::AssetKind);
604	type PoolLocator = pallet_asset_conversion::WithFirstAsset<
605		xcm_config::RelayLocation,
606		AccountId,
607		Self::AssetKind,
608		PoolIdToAccountId,
609	>;
610	type PoolAssetId = u32;
611	type PoolAssets = PoolAssets;
612	type PoolSetupFee = ConstU128<0>; // Asset class deposit fees are sufficient to prevent spam
613	type PoolSetupFeeAsset = xcm_config::RelayLocation;
614	type PoolSetupFeeTarget = ResolveAssetTo<AssetConversionOrigin, Self::Assets>;
615	type LiquidityWithdrawalFee = LiquidityWithdrawalFee;
616	type LPFee = ConstU32<3>;
617	type PalletId = AssetConversionPalletId;
618	type MaxSwapPathLength = ConstU32<3>;
619	type MintMinLiquidity = ConstU128<100>;
620	type WeightInfo = ();
621	#[cfg(feature = "runtime-benchmarks")]
622	type BenchmarkHelper = assets_common::benchmarks::AssetPairFactory<
623		xcm_config::RelayLocation,
624		parachain_info::Pallet<Runtime>,
625		xcm_config::TrustBackedAssetsPalletIndex,
626		xcm::latest::Location,
627	>;
628}
629
630parameter_types! {
631	pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
632	pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
633	pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
634}
635
636type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
637	Runtime,
638	RELAY_CHAIN_SLOT_DURATION_MILLIS,
639	BLOCK_PROCESSING_VELOCITY,
640	UNINCLUDED_SEGMENT_CAPACITY,
641>;
642
643impl cumulus_pallet_parachain_system::Config for Runtime {
644	type WeightInfo = ();
645	type RuntimeEvent = RuntimeEvent;
646	type OnSystemEvent = ();
647	type SelfParaId = parachain_info::Pallet<Runtime>;
648	type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
649	type ReservedDmpWeight = ReservedDmpWeight;
650	type OutboundXcmpMessageSource = XcmpQueue;
651	type XcmpMessageHandler = XcmpQueue;
652	type ReservedXcmpWeight = ReservedXcmpWeight;
653	type CheckAssociatedRelayNumber = RelayNumberStrictlyIncreases;
654	type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
655		Runtime,
656		RELAY_CHAIN_SLOT_DURATION_MILLIS,
657		BLOCK_PROCESSING_VELOCITY,
658		UNINCLUDED_SEGMENT_CAPACITY,
659	>;
660
661	type RelayParentOffset = ConstU32<0>;
662}
663
664impl parachain_info::Config for Runtime {}
665
666parameter_types! {
667	pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block;
668}
669
670impl pallet_message_queue::Config for Runtime {
671	type RuntimeEvent = RuntimeEvent;
672	type WeightInfo = ();
673	type MessageProcessor = xcm_builder::ProcessXcmMessage<
674		AggregateMessageOrigin,
675		xcm_executor::XcmExecutor<xcm_config::XcmConfig>,
676		RuntimeCall,
677	>;
678	type Size = u32;
679	// The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin:
680	type QueueChangeHandler = NarrowOriginToSibling<XcmpQueue>;
681	type QueuePausedQuery = NarrowOriginToSibling<XcmpQueue>;
682	type HeapSize = sp_core::ConstU32<{ 103 * 1024 }>;
683	type MaxStale = sp_core::ConstU32<8>;
684	type ServiceWeight = MessageQueueServiceWeight;
685	type IdleMaxServiceWeight = MessageQueueServiceWeight;
686}
687
688impl cumulus_pallet_aura_ext::Config for Runtime {}
689
690parameter_types! {
691	/// The asset ID for the asset that we use to pay for message delivery fees.
692	pub FeeAssetId: AssetLocationId = AssetLocationId(xcm_config::RelayLocation::get());
693	/// The base fee for the message delivery fees (3 CENTS).
694	pub const BaseDeliveryFee: u128 = (1_000_000_000_000u128 / 100).saturating_mul(3);
695}
696
697pub type PriceForSiblingParachainDelivery = polkadot_runtime_common::xcm_sender::ExponentialPrice<
698	FeeAssetId,
699	BaseDeliveryFee,
700	TransactionByteFee,
701	XcmpQueue,
702>;
703
704impl cumulus_pallet_xcmp_queue::Config for Runtime {
705	type RuntimeEvent = RuntimeEvent;
706	type ChannelInfo = ParachainSystem;
707	type VersionWrapper = PolkadotXcm;
708	// Enqueue XCMP messages from siblings for later processing.
709	type XcmpQueue = TransformOrigin<MessageQueue, AggregateMessageOrigin, ParaId, ParaIdToSibling>;
710	type MaxInboundSuspended = ConstU32<1_000>;
711	type MaxActiveOutboundChannels = ConstU32<128>;
712	// Most on-chain HRMP channels are configured to use 102400 bytes of max message size, so we
713	// need to set the page size larger than that until we reduce the channel size on-chain.
714	type MaxPageSize = ConstU32<{ 103 * 1024 }>;
715	type ControllerOrigin = EnsureRoot<AccountId>;
716	type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
717	type WeightInfo = ();
718	type PriceForSiblingDelivery = PriceForSiblingParachainDelivery;
719}
720
721parameter_types! {
722	pub const Period: u32 = 6 * HOURS;
723	pub const Offset: u32 = 0;
724}
725impl pallet_session::Config for Runtime {
726	type RuntimeEvent = RuntimeEvent;
727	type ValidatorId = <Self as frame_system::Config>::AccountId;
728	// we don't have stash and controller, thus we don't need the convert as well.
729	type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
730	type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
731	type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
732	type SessionManager = CollatorSelection;
733	// Essentially just Aura, but let's be pedantic.
734	type SessionHandler = <SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
735	type Keys = SessionKeys;
736	type DisablingStrategy = ();
737	type WeightInfo = ();
738	type Currency = Balances;
739	type KeyDeposit = ();
740}
741
742impl pallet_aura::Config for Runtime {
743	type AuthorityId = AuraId;
744	type DisabledValidators = ();
745	type MaxAuthorities = ConstU32<100_000>;
746	type AllowMultipleBlocksPerSlot = ConstBool<true>;
747	type SlotDuration = ConstU64<SLOT_DURATION>;
748}
749
750parameter_types! {
751	pub const PotId: PalletId = PalletId(*b"PotStake");
752	pub const SessionLength: BlockNumber = 6 * HOURS;
753	pub const ExecutiveBody: BodyId = BodyId::Executive;
754}
755
756// We allow root only to execute privileged collator selection operations.
757pub type CollatorSelectionUpdateOrigin = EnsureRoot<AccountId>;
758
759impl pallet_collator_selection::Config for Runtime {
760	type RuntimeEvent = RuntimeEvent;
761	type Currency = Balances;
762	type UpdateOrigin = CollatorSelectionUpdateOrigin;
763	type PotId = PotId;
764	type MaxCandidates = ConstU32<100>;
765	type MinEligibleCollators = ConstU32<4>;
766	type MaxInvulnerables = ConstU32<20>;
767	// should be a multiple of session or things will get inconsistent
768	type KickThreshold = Period;
769	type ValidatorId = <Self as frame_system::Config>::AccountId;
770	type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
771	type ValidatorRegistration = Session;
772	type WeightInfo = ();
773}
774
775#[cfg(feature = "runtime-benchmarks")]
776pub struct AssetTxHelper;
777
778#[cfg(feature = "runtime-benchmarks")]
779impl pallet_asset_tx_payment::BenchmarkHelperTrait<AccountId, u32, u32> for AssetTxHelper {
780	fn create_asset_id_parameter(_id: u32) -> (u32, u32) {
781		unimplemented!("Penpal uses default weights");
782	}
783	fn setup_balances_and_pool(_asset_id: u32, _account: AccountId) {
784		unimplemented!("Penpal uses default weights");
785	}
786}
787
788impl pallet_asset_tx_payment::Config for Runtime {
789	type RuntimeEvent = RuntimeEvent;
790	type Fungibles = Assets;
791	type OnChargeAssetTransaction = pallet_asset_tx_payment::FungiblesAdapter<
792		pallet_assets::BalanceToAssetBalance<
793			Balances,
794			Runtime,
795			ConvertInto,
796			TrustBackedAssetsInstance,
797		>,
798		AssetsToBlockAuthor<Runtime, TrustBackedAssetsInstance>,
799	>;
800	type WeightInfo = ();
801	#[cfg(feature = "runtime-benchmarks")]
802	type BenchmarkHelper = AssetTxHelper;
803}
804
805parameter_types! {
806	pub const DepositPerItem: Balance = 0;
807	pub const DepositPerByte: Balance = 0;
808	pub CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(30);
809}
810
811impl pallet_revive::Config for Runtime {
812	type Time = Timestamp;
813	type Currency = Balances;
814	type RuntimeEvent = RuntimeEvent;
815	type RuntimeCall = RuntimeCall;
816	type DepositPerItem = DepositPerItem;
817	type DepositPerByte = DepositPerByte;
818	type WeightPrice = pallet_transaction_payment::Pallet<Self>;
819	type WeightInfo = pallet_revive::weights::SubstrateWeight<Self>;
820	type Precompiles = ();
821	type AddressMapper = pallet_revive::AccountId32Mapper<Self>;
822	type RuntimeMemory = ConstU32<{ 128 * 1024 * 1024 }>;
823	type PVFMemory = ConstU32<{ 512 * 1024 * 1024 }>;
824	type UnsafeUnstableInterface = ConstBool<true>;
825	type AllowEVMBytecode = ConstBool<true>;
826	type UploadOrigin = EnsureSigned<Self::AccountId>;
827	type InstantiateOrigin = EnsureSigned<Self::AccountId>;
828	type RuntimeHoldReason = RuntimeHoldReason;
829	type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
830	type ChainId = ConstU64<420_420_999>;
831	type NativeToEthRatio = ConstU32<1_000_000>; // 10^(18 - 12) Eth is 10^18, Native is 10^12.
832	type EthGasEncoder = ();
833	type FindAuthor = <Runtime as pallet_authorship::Config>::FindAuthor;
834}
835
836impl pallet_sudo::Config for Runtime {
837	type RuntimeEvent = RuntimeEvent;
838	type RuntimeCall = RuntimeCall;
839	type WeightInfo = pallet_sudo::weights::SubstrateWeight<Runtime>;
840}
841
842impl pallet_utility::Config for Runtime {
843	type RuntimeEvent = RuntimeEvent;
844	type RuntimeCall = RuntimeCall;
845	type PalletsOrigin = OriginCaller;
846	type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
847}
848
849// Create the runtime by composing the FRAME pallets that were previously configured.
850construct_runtime!(
851	pub enum Runtime
852	{
853		// System support stuff.
854		System: frame_system = 0,
855		ParachainSystem: cumulus_pallet_parachain_system = 1,
856		Timestamp: pallet_timestamp = 2,
857		ParachainInfo: parachain_info = 3,
858
859		// Monetary stuff.
860		Balances: pallet_balances = 10,
861		TransactionPayment: pallet_transaction_payment = 11,
862		AssetTxPayment: pallet_asset_tx_payment = 12,
863
864		// Collator support. The order of these 4 are important and shall not change.
865		Authorship: pallet_authorship = 20,
866		CollatorSelection: pallet_collator_selection = 21,
867		Session: pallet_session = 22,
868		Aura: pallet_aura = 23,
869		AuraExt: cumulus_pallet_aura_ext = 24,
870
871		// XCM helpers.
872		XcmpQueue: cumulus_pallet_xcmp_queue = 30,
873		PolkadotXcm: pallet_xcm = 31,
874		CumulusXcm: cumulus_pallet_xcm = 32,
875		MessageQueue: pallet_message_queue = 34,
876
877		// Handy utilities.
878		Utility: pallet_utility = 40,
879
880		// The main stage.
881		Assets: pallet_assets::<Instance1> = 50,
882		ForeignAssets: pallet_assets::<Instance2> = 51,
883		PoolAssets: pallet_assets::<Instance3> = 52,
884		AssetConversion: pallet_asset_conversion = 53,
885
886		Revive: pallet_revive = 60,
887
888		Sudo: pallet_sudo = 255,
889	}
890);
891
892#[cfg(feature = "runtime-benchmarks")]
893mod benches {
894	frame_benchmarking::define_benchmarks!(
895		[frame_system, SystemBench::<Runtime>]
896		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
897		[pallet_balances, Balances]
898		[pallet_message_queue, MessageQueue]
899		[pallet_session, SessionBench::<Runtime>]
900		[pallet_sudo, Sudo]
901		[pallet_timestamp, Timestamp]
902		[pallet_collator_selection, CollatorSelection]
903		[cumulus_pallet_parachain_system, ParachainSystem]
904		[cumulus_pallet_xcmp_queue, XcmpQueue]
905		[pallet_utility, Utility]
906	);
907}
908
909impl_runtime_apis! {
910	impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
911		fn slot_duration() -> sp_consensus_aura::SlotDuration {
912			sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION)
913		}
914
915		fn authorities() -> Vec<AuraId> {
916			pallet_aura::Authorities::<Runtime>::get().into_inner()
917		}
918	}
919
920	impl sp_api::Core<Block> for Runtime {
921		fn version() -> RuntimeVersion {
922			VERSION
923		}
924
925		fn execute_block(block: Block) {
926			Executive::execute_block(block)
927		}
928
929		fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
930			Executive::initialize_block(header)
931		}
932	}
933
934	impl sp_api::Metadata<Block> for Runtime {
935		fn metadata() -> OpaqueMetadata {
936			OpaqueMetadata::new(Runtime::metadata().into())
937		}
938
939		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
940			Runtime::metadata_at_version(version)
941		}
942
943		fn metadata_versions() -> alloc::vec::Vec<u32> {
944			Runtime::metadata_versions()
945		}
946	}
947
948	impl sp_block_builder::BlockBuilder<Block> for Runtime {
949		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
950			Executive::apply_extrinsic(extrinsic)
951		}
952
953		fn finalize_block() -> <Block as BlockT>::Header {
954			Executive::finalize_block()
955		}
956
957		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
958			data.create_extrinsics()
959		}
960
961		fn check_inherents(
962			block: Block,
963			data: sp_inherents::InherentData,
964		) -> sp_inherents::CheckInherentsResult {
965			data.check_extrinsics(&block)
966		}
967	}
968
969	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
970		fn validate_transaction(
971			source: TransactionSource,
972			tx: <Block as BlockT>::Extrinsic,
973			block_hash: <Block as BlockT>::Hash,
974		) -> TransactionValidity {
975			Executive::validate_transaction(source, tx, block_hash)
976		}
977	}
978
979	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
980		fn offchain_worker(header: &<Block as BlockT>::Header) {
981			Executive::offchain_worker(header)
982		}
983	}
984
985	impl sp_session::SessionKeys<Block> for Runtime {
986		fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
987			SessionKeys::generate(seed)
988		}
989
990		fn decode_session_keys(
991			encoded: Vec<u8>,
992		) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
993			SessionKeys::decode_into_raw_public_keys(&encoded)
994		}
995	}
996
997	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
998		fn account_nonce(account: AccountId) -> Nonce {
999			System::account_nonce(account)
1000		}
1001	}
1002
1003	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
1004		fn query_info(
1005			uxt: <Block as BlockT>::Extrinsic,
1006			len: u32,
1007		) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
1008			TransactionPayment::query_info(uxt, len)
1009		}
1010		fn query_fee_details(
1011			uxt: <Block as BlockT>::Extrinsic,
1012			len: u32,
1013		) -> pallet_transaction_payment::FeeDetails<Balance> {
1014			TransactionPayment::query_fee_details(uxt, len)
1015		}
1016		fn query_weight_to_fee(weight: Weight) -> Balance {
1017			TransactionPayment::weight_to_fee(weight)
1018		}
1019		fn query_length_to_fee(length: u32) -> Balance {
1020			TransactionPayment::length_to_fee(length)
1021		}
1022	}
1023
1024	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
1025		for Runtime
1026	{
1027		fn query_call_info(
1028			call: RuntimeCall,
1029			len: u32,
1030		) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
1031			TransactionPayment::query_call_info(call, len)
1032		}
1033		fn query_call_fee_details(
1034			call: RuntimeCall,
1035			len: u32,
1036		) -> pallet_transaction_payment::FeeDetails<Balance> {
1037			TransactionPayment::query_call_fee_details(call, len)
1038		}
1039		fn query_weight_to_fee(weight: Weight) -> Balance {
1040			TransactionPayment::weight_to_fee(weight)
1041		}
1042		fn query_length_to_fee(length: u32) -> Balance {
1043			TransactionPayment::length_to_fee(length)
1044		}
1045	}
1046
1047	impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
1048		fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
1049			ParachainSystem::collect_collation_info(header)
1050		}
1051	}
1052
1053	impl xcm_runtime_apis::fees::XcmPaymentApi<Block> for Runtime {
1054		fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
1055			let acceptable_assets = vec![AssetLocationId(xcm_config::RelayLocation::get())];
1056			PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets)
1057		}
1058
1059		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
1060			use crate::xcm_config::XcmConfig;
1061
1062			type Trader = <XcmConfig as xcm_executor::Config>::Trader;
1063
1064			PolkadotXcm::query_weight_to_asset_fee::<Trader>(weight, asset)
1065		}
1066
1067		fn query_xcm_weight(message: VersionedXcm<()>) -> Result<Weight, XcmPaymentApiError> {
1068			PolkadotXcm::query_xcm_weight(message)
1069		}
1070
1071		fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result<VersionedAssets, XcmPaymentApiError> {
1072			PolkadotXcm::query_delivery_fees(destination, message)
1073		}
1074	}
1075
1076	impl xcm_runtime_apis::dry_run::DryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
1077		fn dry_run_call(origin: OriginCaller, call: RuntimeCall, result_xcms_version: XcmVersion) -> Result<CallDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
1078			PolkadotXcm::dry_run_call::<Runtime, xcm_config::XcmRouter, OriginCaller, RuntimeCall>(origin, call, result_xcms_version)
1079		}
1080
1081		fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
1082			PolkadotXcm::dry_run_xcm::<Runtime, xcm_config::XcmRouter, RuntimeCall, xcm_config::XcmConfig>(origin_location, xcm)
1083		}
1084	}
1085
1086	impl xcm_runtime_apis::conversions::LocationToAccountApi<Block, AccountId> for Runtime {
1087		fn convert_location(location: VersionedLocation) -> Result<
1088			AccountId,
1089			xcm_runtime_apis::conversions::Error
1090		> {
1091			xcm_runtime_apis::conversions::LocationToAccountHelper::<
1092				AccountId,
1093				xcm_config::LocationToAccountId,
1094			>::convert_location(location)
1095		}
1096	}
1097
1098	impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
1099		fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> xcm_runtime_apis::trusted_query::XcmTrustedQueryResult {
1100			PolkadotXcm::is_trusted_reserve(asset, location)
1101		}
1102		fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> xcm_runtime_apis::trusted_query::XcmTrustedQueryResult {
1103			PolkadotXcm::is_trusted_teleporter(asset, location)
1104		}
1105	}
1106
1107	impl xcm_runtime_apis::authorized_aliases::AuthorizedAliasersApi<Block> for Runtime {
1108		fn authorized_aliasers(target: VersionedLocation) -> Result<
1109			Vec<xcm_runtime_apis::authorized_aliases::OriginAliaser>,
1110			xcm_runtime_apis::authorized_aliases::Error
1111		> {
1112			PolkadotXcm::authorized_aliasers(target)
1113		}
1114		fn is_authorized_alias(origin: VersionedLocation, target: VersionedLocation) -> Result<
1115			bool,
1116			xcm_runtime_apis::authorized_aliases::Error
1117		> {
1118			PolkadotXcm::is_authorized_alias(origin, target)
1119		}
1120	}
1121
1122	#[cfg(feature = "try-runtime")]
1123	impl frame_try_runtime::TryRuntime<Block> for Runtime {
1124		fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
1125			let weight = Executive::try_runtime_upgrade(checks).unwrap();
1126			(weight, RuntimeBlockWeights::get().max_block)
1127		}
1128
1129		fn execute_block(
1130			block: Block,
1131			state_root_check: bool,
1132			signature_check: bool,
1133			select: frame_try_runtime::TryStateSelect,
1134		) -> Weight {
1135			// NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
1136			// have a backtrace here.
1137			Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()
1138		}
1139	}
1140
1141	#[cfg(feature = "runtime-benchmarks")]
1142	impl frame_benchmarking::Benchmark<Block> for Runtime {
1143		fn benchmark_metadata(extra: bool) -> (
1144			Vec<frame_benchmarking::BenchmarkList>,
1145			Vec<frame_support::traits::StorageInfo>,
1146		) {
1147			use frame_benchmarking::BenchmarkList;
1148			use frame_support::traits::StorageInfoTrait;
1149			use frame_system_benchmarking::Pallet as SystemBench;
1150			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
1151			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
1152
1153			let mut list = Vec::<BenchmarkList>::new();
1154			list_benchmarks!(list, extra);
1155
1156			let storage_info = AllPalletsWithSystem::storage_info();
1157			(list, storage_info)
1158		}
1159
1160		#[allow(non_local_definitions)]
1161		fn dispatch_benchmark(
1162			config: frame_benchmarking::BenchmarkConfig
1163		) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, alloc::string::String> {
1164			use frame_benchmarking::BenchmarkBatch;
1165			use sp_storage::TrackedStorageKey;
1166
1167			use frame_system_benchmarking::Pallet as SystemBench;
1168			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
1169			impl frame_system_benchmarking::Config for Runtime {}
1170
1171			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
1172			impl cumulus_pallet_session_benchmarking::Config for Runtime {}
1173
1174			use frame_support::traits::WhitelistedStorageKeys;
1175			let whitelist: Vec<TrackedStorageKey> = AllPalletsWithSystem::whitelisted_storage_keys();
1176
1177			let mut batches = Vec::<BenchmarkBatch>::new();
1178			let params = (&config, &whitelist);
1179			add_benchmarks!(params, batches);
1180
1181			if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
1182			Ok(batches)
1183		}
1184	}
1185
1186	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
1187		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
1188			build_state::<RuntimeGenesisConfig>(config)
1189		}
1190
1191		fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
1192			get_preset::<RuntimeGenesisConfig>(id, &genesis_config_presets::get_preset)
1193		}
1194
1195		fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
1196			genesis_config_presets::preset_names()
1197		}
1198	}
1199
1200	impl cumulus_primitives_core::GetParachainInfo<Block> for Runtime {
1201		fn parachain_id() -> ParaId {
1202			ParachainInfo::parachain_id()
1203		}
1204	}
1205
1206	impl cumulus_primitives_aura::AuraUnincludedSegmentApi<Block> for Runtime {
1207		fn can_build_upon(
1208			included_hash: <Block as BlockT>::Hash,
1209			slot: cumulus_primitives_aura::Slot,
1210		) -> bool {
1211			ConsensusHook::can_build_upon(included_hash, slot)
1212		}
1213	}
1214}
1215
1216cumulus_pallet_parachain_system::register_validate_block! {
1217	Runtime = Runtime,
1218	BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
1219}