pallet_staking_async_rc_runtime/
lib.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Substrate.
3
4// Substrate is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Substrate is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
16
17//! The Westend runtime. This can be compiled with `#[no_std]`, ready for Wasm.
18
19#![cfg_attr(not(feature = "std"), no_std)]
20// `#[frame_support::runtime]!` does a lot of recursion and requires us to increase the limit.
21#![recursion_limit = "512"]
22
23extern crate alloc;
24
25use alloc::{
26	collections::{btree_map::BTreeMap, vec_deque::VecDeque},
27	vec,
28	vec::Vec,
29};
30use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
31use frame_election_provider_support::{
32	bounds::ElectionBoundsBuilder, onchain, SequentialPhragmen, VoteWeight,
33};
34use frame_support::{
35	derive_impl,
36	dynamic_params::{dynamic_pallet_params, dynamic_params},
37	genesis_builder_helper::{build_state, get_preset},
38	parameter_types,
39	traits::{
40		fungible::HoldConsideration, tokens::UnityOrOuterConversion, ConstBool, ConstU32, Contains,
41		EitherOf, EitherOfDiverse, EnsureOriginWithArg, EverythingBut, FromContains,
42		InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, Nothing, ProcessMessage,
43		ProcessMessageError, VariantCountOf, WithdrawReasons,
44	},
45	weights::{ConstantMultiplier, WeightMeter, WeightToFee as _},
46	PalletId,
47};
48pub use frame_system::Call as SystemCall;
49use frame_system::{EnsureRoot, EnsureSigned};
50pub use pallet_balances::Call as BalancesCall;
51use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId};
52use pallet_identity::legacy::IdentityInfo;
53use pallet_session::historical as session_historical;
54use pallet_staking_async_ah_client::{self as ah_client};
55use pallet_staking_async_rc_client::{self as rc_client};
56pub use pallet_timestamp::Call as TimestampCall;
57use pallet_transaction_payment::{FeeDetails, FungibleAdapter, RuntimeDispatchInfo};
58use polkadot_primitives::{
59	slashing,
60	vstaging::{
61		async_backing::Constraints, CandidateEvent,
62		CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, ScrapedOnChainVotes,
63	},
64	AccountId, AccountIndex, ApprovalVotingParams, Balance, BlockNumber, CandidateHash, CoreIndex,
65	DisputeState, ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage,
66	InboundHrmpMessage, Moment, NodeFeatures, Nonce, OccupiedCoreAssumption,
67	PersistedValidationData, PvfCheckStatement, SessionInfo, Signature, ValidationCode,
68	ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, PARACHAIN_KEY_TYPE_ID,
69};
70use polkadot_runtime_common::{
71	assigned_slots, auctions, crowdloan, identity_migrator, impl_runtime_weights,
72	impls::{
73		ContainsParts, LocatableAssetConverter, ToAuthor, VersionedLocatableAsset,
74		VersionedLocationConverter,
75	},
76	paras_registrar, paras_sudo_wrapper, prod_or_fast, slots,
77	traits::OnSwap,
78	BlockHashCount, BlockLength, SlowAdjustingFeeUpdate,
79};
80use polkadot_runtime_parachains::{
81	assigner_coretime as parachains_assigner_coretime, configuration as parachains_configuration,
82	configuration::ActiveConfigHrmpChannelSizeAndCapacityRatio,
83	coretime, disputes as parachains_disputes,
84	disputes::slashing as parachains_slashing,
85	dmp as parachains_dmp, hrmp as parachains_hrmp, inclusion as parachains_inclusion,
86	inclusion::{AggregateMessageOrigin, UmpQueueId},
87	initializer as parachains_initializer, on_demand as parachains_on_demand,
88	origin as parachains_origin, paras as parachains_paras,
89	paras_inherent as parachains_paras_inherent, reward_points as parachains_reward_points,
90	runtime_api_impl::{
91		v11 as parachains_runtime_api_impl, vstaging as parachains_staging_runtime_api_impl,
92	},
93	scheduler as parachains_scheduler, session_info as parachains_session_info,
94	shared as parachains_shared,
95};
96use scale_info::TypeInfo;
97use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
98use sp_consensus_beefy::{
99	ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature},
100	mmr::{BeefyDataProvider, MmrLeafVersion},
101};
102use sp_core::{ConstU8, ConstUint, OpaqueMetadata, RuntimeDebug, H256};
103#[cfg(any(feature = "std", test))]
104pub use sp_runtime::BuildStorage;
105use sp_runtime::{
106	generic, impl_opaque_keys,
107	traits::{
108		AccountIdConversion, BlakeTwo256, Block as BlockT, Convert, ConvertInto, Get,
109		IdentityLookup, Keccak256, OpaqueKeys, SaturatedConversion, Verify,
110	},
111	transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity},
112	ApplyExtrinsicResult, FixedU128, KeyTypeId, Percent, Permill,
113};
114use sp_staking::SessionIndex;
115#[cfg(any(feature = "std", test))]
116use sp_version::NativeVersion;
117use sp_version::RuntimeVersion;
118use xcm::{
119	latest::prelude::*, VersionedAsset, VersionedAssetId, VersionedAssets, VersionedLocation,
120	VersionedXcm,
121};
122use xcm_builder::PayOverXcm;
123use xcm_runtime_apis::{
124	dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
125	fees::Error as XcmPaymentApiError,
126};
127
128/// Constant values used within the runtime.
129use pallet_staking_async_rc_runtime_constants::{
130	currency::*,
131	fee::*,
132	system_parachain::{coretime::TIMESLICE_PERIOD, ASSET_HUB_ID, BROKER_ID},
133	time::*,
134};
135
136mod genesis_config_presets;
137mod weights;
138pub mod xcm_config;
139
140// Implemented types.
141mod impls;
142use impls::ToParachainIdentityReaper;
143
144// Governance and configurations.
145pub mod governance;
146use governance::{
147	pallet_custom_origins, AuctionAdmin, FellowshipAdmin, GeneralAdmin, LeaseAdmin, StakingAdmin,
148	Treasurer, TreasurySpender,
149};
150
151#[cfg(test)]
152mod tests;
153
154impl_runtime_weights!(pallet_staking_async_rc_runtime_constants);
155
156// Make the WASM binary available.
157#[cfg(feature = "std")]
158include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
159
160#[cfg(feature = "std")]
161pub mod fast_runtime_binary {
162	include!(concat!(env!("OUT_DIR"), "/fast_runtime_binary.rs"));
163}
164
165/// Runtime version (Westend).
166#[sp_version::runtime_version]
167pub const VERSION: RuntimeVersion = RuntimeVersion {
168	spec_name: alloc::borrow::Cow::Borrowed("staking-async-rc"),
169	impl_name: alloc::borrow::Cow::Borrowed("staking-async-rc"),
170	authoring_version: 2,
171	spec_version: 1_017_001,
172	impl_version: 0,
173	apis: RUNTIME_API_VERSIONS,
174	transaction_version: 27,
175	system_version: 1,
176};
177
178/// The BABE epoch configuration at genesis.
179pub const BABE_GENESIS_EPOCH_CONFIG: sp_consensus_babe::BabeEpochConfiguration =
180	sp_consensus_babe::BabeEpochConfiguration {
181		c: PRIMARY_PROBABILITY,
182		allowed_slots: sp_consensus_babe::AllowedSlots::PrimaryAndSecondaryVRFSlots,
183	};
184
185/// Native version.
186#[cfg(any(feature = "std", test))]
187pub fn native_version() -> NativeVersion {
188	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
189}
190
191/// A type to identify calls to the Identity pallet. These will be filtered to prevent invocation,
192/// locking the state of the pallet and preventing further updates to identities and sub-identities.
193/// The locked state will be the genesis state of a new system chain and then removed from the Relay
194/// Chain.
195pub struct IsIdentityCall;
196impl Contains<RuntimeCall> for IsIdentityCall {
197	fn contains(c: &RuntimeCall) -> bool {
198		matches!(c, RuntimeCall::Identity(_))
199	}
200}
201
202parameter_types! {
203	pub const Version: RuntimeVersion = VERSION;
204	pub const SS58Prefix: u8 = 42;
205}
206
207#[derive_impl(frame_system::config_preludes::RelayChainDefaultConfig)]
208impl frame_system::Config for Runtime {
209	type BaseCallFilter = EverythingBut<IsIdentityCall>;
210	type BlockWeights = BlockWeights;
211	type BlockLength = BlockLength;
212	type Nonce = Nonce;
213	type Hash = Hash;
214	type AccountId = AccountId;
215	type Block = Block;
216	type BlockHashCount = BlockHashCount;
217	type DbWeight = RocksDbWeight;
218	type Version = Version;
219	type AccountData = pallet_balances::AccountData<Balance>;
220	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
221	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
222	type SS58Prefix = SS58Prefix;
223	type MaxConsumers = frame_support::traits::ConstU32<16>;
224	type MultiBlockMigrator = MultiBlockMigrations;
225}
226
227parameter_types! {
228	pub MaximumSchedulerWeight: frame_support::weights::Weight = Perbill::from_percent(80) *
229		BlockWeights::get().max_block;
230	pub const MaxScheduledPerBlock: u32 = 50;
231	pub const NoPreimagePostponement: Option<u32> = Some(10);
232}
233
234impl pallet_scheduler::Config for Runtime {
235	type RuntimeOrigin = RuntimeOrigin;
236	type RuntimeEvent = RuntimeEvent;
237	type PalletsOrigin = OriginCaller;
238	type RuntimeCall = RuntimeCall;
239	type MaximumWeight = MaximumSchedulerWeight;
240	// The goal of having ScheduleOrigin include AuctionAdmin is to allow the auctions track of
241	// OpenGov to schedule periodic auctions.
242	type ScheduleOrigin = EitherOf<EnsureRoot<AccountId>, AuctionAdmin>;
243	type MaxScheduledPerBlock = MaxScheduledPerBlock;
244	type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
245	type OriginPrivilegeCmp = frame_support::traits::EqualPrivilegeOnly;
246	type Preimages = Preimage;
247	type BlockNumberProvider = frame_system::Pallet<Runtime>;
248}
249
250parameter_types! {
251	pub const PreimageBaseDeposit: Balance = deposit(2, 64);
252	pub const PreimageByteDeposit: Balance = deposit(0, 1);
253	pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
254}
255
256/// Dynamic params that can be adjusted at runtime.
257#[dynamic_params(RuntimeParameters, pallet_parameters::Parameters::<Runtime>)]
258pub mod dynamic_params {
259	use super::*;
260
261	/// Parameters used to calculate era payouts, see
262	/// [`polkadot_runtime_common::impls::EraPayoutParams`].
263	#[dynamic_pallet_params]
264	#[codec(index = 0)]
265	pub mod inflation {
266		/// Minimum inflation rate used to calculate era payouts.
267		#[codec(index = 0)]
268		pub static MinInflation: Perquintill = Perquintill::from_rational(25u64, 1000u64);
269
270		/// Maximum inflation rate used to calculate era payouts.
271		#[codec(index = 1)]
272		pub static MaxInflation: Perquintill = Perquintill::from_rational(10u64, 100u64);
273
274		/// Ideal stake ratio used to calculate era payouts.
275		#[codec(index = 2)]
276		pub static IdealStake: Perquintill = Perquintill::from_rational(50u64, 100u64);
277
278		/// Falloff used to calculate era payouts.
279		#[codec(index = 3)]
280		pub static Falloff: Perquintill = Perquintill::from_rational(50u64, 1000u64);
281
282		/// Whether to use auction slots or not in the calculation of era payouts. If set to true,
283		/// the `legacy_auction_proportion` of 60% will be used in the calculation of era payouts.
284		#[codec(index = 4)]
285		pub static UseAuctionSlots: bool = false;
286	}
287}
288
289#[cfg(feature = "runtime-benchmarks")]
290impl Default for RuntimeParameters {
291	fn default() -> Self {
292		RuntimeParameters::Inflation(dynamic_params::inflation::Parameters::MinInflation(
293			dynamic_params::inflation::MinInflation,
294			Some(Perquintill::from_rational(25u64, 1000u64)),
295		))
296	}
297}
298
299impl pallet_parameters::Config for Runtime {
300	type RuntimeEvent = RuntimeEvent;
301	type RuntimeParameters = RuntimeParameters;
302	type AdminOrigin = DynamicParameterOrigin;
303	type WeightInfo = weights::pallet_parameters::WeightInfo<Runtime>;
304}
305
306/// Defines what origin can modify which dynamic parameters.
307pub struct DynamicParameterOrigin;
308impl EnsureOriginWithArg<RuntimeOrigin, RuntimeParametersKey> for DynamicParameterOrigin {
309	type Success = ();
310
311	fn try_origin(
312		origin: RuntimeOrigin,
313		key: &RuntimeParametersKey,
314	) -> Result<Self::Success, RuntimeOrigin> {
315		use crate::RuntimeParametersKey::*;
316
317		match key {
318			Inflation(_) => frame_system::ensure_root(origin.clone()),
319		}
320		.map_err(|_| origin)
321	}
322
323	#[cfg(feature = "runtime-benchmarks")]
324	fn try_successful_origin(_key: &RuntimeParametersKey) -> Result<RuntimeOrigin, ()> {
325		// Provide the origin for the parameter returned by `Default`:
326		Ok(RuntimeOrigin::root())
327	}
328}
329
330impl pallet_preimage::Config for Runtime {
331	type WeightInfo = weights::pallet_preimage::WeightInfo<Runtime>;
332	type RuntimeEvent = RuntimeEvent;
333	type Currency = Balances;
334	type ManagerOrigin = EnsureRoot<AccountId>;
335	type Consideration = HoldConsideration<
336		AccountId,
337		Balances,
338		PreimageHoldReason,
339		LinearStoragePrice<PreimageBaseDeposit, PreimageByteDeposit, Balance>,
340	>;
341}
342
343parameter_types! {
344	pub const EpochDuration: u64 = prod_or_fast!(
345		EPOCH_DURATION_IN_SLOTS as u64,
346		1 * MINUTES as u64
347	);
348	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
349	pub const ReportLongevity: u64 = 256 * EpochDuration::get();
350}
351
352impl pallet_babe::Config for Runtime {
353	type EpochDuration = EpochDuration;
354	type ExpectedBlockTime = ExpectedBlockTime;
355
356	// session module is the trigger
357	type EpochChangeTrigger = pallet_babe::ExternalTrigger;
358
359	type DisabledValidators = Session;
360
361	type WeightInfo = ();
362
363	type MaxAuthorities = MaxAuthorities;
364	type MaxNominators = ConstU32<1024>;
365
366	type KeyOwnerProof = sp_session::MembershipProof;
367
368	type EquivocationReportSystem =
369		pallet_babe::EquivocationReportSystem<Self, Offences, Historical, ReportLongevity>;
370}
371
372parameter_types! {
373	pub const IndexDeposit: Balance = 100 * CENTS;
374}
375
376impl pallet_indices::Config for Runtime {
377	type AccountIndex = AccountIndex;
378	type Currency = Balances;
379	type Deposit = IndexDeposit;
380	type RuntimeEvent = RuntimeEvent;
381	type WeightInfo = weights::pallet_indices::WeightInfo<Runtime>;
382}
383
384parameter_types! {
385	pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
386	pub const MaxLocks: u32 = 50;
387	pub const MaxReserves: u32 = 50;
388}
389
390impl pallet_balances::Config for Runtime {
391	type Balance = Balance;
392	type DustRemoval = ();
393	type RuntimeEvent = RuntimeEvent;
394	type ExistentialDeposit = ExistentialDeposit;
395	type AccountStore = System;
396	type MaxLocks = MaxLocks;
397	type MaxReserves = MaxReserves;
398	type ReserveIdentifier = [u8; 8];
399	type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
400	type RuntimeHoldReason = RuntimeHoldReason;
401	type RuntimeFreezeReason = RuntimeFreezeReason;
402	type FreezeIdentifier = RuntimeFreezeReason;
403	type MaxFreezes = VariantCountOf<RuntimeFreezeReason>;
404	type DoneSlashHandler = ();
405}
406
407parameter_types! {
408	pub const BeefySetIdSessionEntries: u32 = 1024;
409}
410
411impl pallet_beefy::Config for Runtime {
412	type BeefyId = BeefyId;
413	type MaxAuthorities = MaxAuthorities;
414	type MaxNominators = <Self as pallet_babe::Config>::MaxNominators;
415	type MaxSetIdSessionEntries = BeefySetIdSessionEntries;
416	type OnNewValidatorSet = BeefyMmrLeaf;
417	type AncestryHelper = BeefyMmrLeaf;
418	type WeightInfo = ();
419	type KeyOwnerProof = sp_session::MembershipProof;
420	type EquivocationReportSystem =
421		pallet_beefy::EquivocationReportSystem<Self, Offences, Historical, ReportLongevity>;
422}
423
424impl pallet_mmr::Config for Runtime {
425	const INDEXING_PREFIX: &'static [u8] = mmr::INDEXING_PREFIX;
426	type Hashing = Keccak256;
427	type OnNewRoot = pallet_beefy_mmr::DepositBeefyDigest<Runtime>;
428	type LeafData = pallet_beefy_mmr::Pallet<Runtime>;
429	type BlockHashProvider = pallet_mmr::DefaultBlockHashProvider<Runtime>;
430	type WeightInfo = weights::pallet_mmr::WeightInfo<Runtime>;
431	#[cfg(feature = "runtime-benchmarks")]
432	type BenchmarkHelper = parachains_paras::benchmarking::mmr_setup::MmrSetup<Runtime>;
433}
434
435/// MMR helper types.
436mod mmr {
437	use super::Runtime;
438	pub use pallet_mmr::primitives::*;
439
440	pub type Leaf = <<Runtime as pallet_mmr::Config>::LeafData as LeafDataProvider>::LeafData;
441	pub type Hashing = <Runtime as pallet_mmr::Config>::Hashing;
442	pub type Hash = <Hashing as sp_runtime::traits::Hash>::Output;
443}
444
445parameter_types! {
446	pub LeafVersion: MmrLeafVersion = MmrLeafVersion::new(0, 0);
447}
448
449/// A BEEFY data provider that merkelizes all the parachain heads at the current block
450/// (sorted by their parachain id).
451pub struct ParaHeadsRootProvider;
452impl BeefyDataProvider<H256> for ParaHeadsRootProvider {
453	fn extra_data() -> H256 {
454		let para_heads: Vec<(u32, Vec<u8>)> =
455			parachains_paras::Pallet::<Runtime>::sorted_para_heads();
456		binary_merkle_tree::merkle_root::<mmr::Hashing, _>(
457			para_heads.into_iter().map(|pair| pair.encode()),
458		)
459		.into()
460	}
461}
462
463impl pallet_beefy_mmr::Config for Runtime {
464	type LeafVersion = LeafVersion;
465	type BeefyAuthorityToMerkleLeaf = pallet_beefy_mmr::BeefyEcdsaToEthereum;
466	type LeafExtra = H256;
467	type BeefyDataProvider = ParaHeadsRootProvider;
468	type WeightInfo = weights::pallet_beefy_mmr::WeightInfo<Runtime>;
469}
470
471parameter_types! {
472	pub const TransactionByteFee: Balance = 10 * MILLICENTS;
473	/// This value increases the priority of `Operational` transactions by adding
474	/// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
475	pub const OperationalFeeMultiplier: u8 = 5;
476}
477
478impl pallet_transaction_payment::Config for Runtime {
479	type RuntimeEvent = RuntimeEvent;
480	type OnChargeTransaction = FungibleAdapter<Balances, ToAuthor<Runtime>>;
481	type OperationalFeeMultiplier = OperationalFeeMultiplier;
482	type WeightToFee = WeightToFee;
483	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
484	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
485	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
486}
487
488parameter_types! {
489	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
490}
491impl pallet_timestamp::Config for Runtime {
492	type Moment = u64;
493	type OnTimestampSet = Babe;
494	type MinimumPeriod = MinimumPeriod;
495	type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
496}
497
498impl pallet_authorship::Config for Runtime {
499	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
500	type EventHandler = StakingAhClient;
501}
502
503parameter_types! {
504	pub const Period: BlockNumber = 10 * MINUTES;
505	pub const Offset: BlockNumber = 0;
506}
507
508impl_opaque_keys! {
509	pub struct SessionKeys {
510		pub grandpa: Grandpa,
511		pub babe: Babe,
512		pub para_validator: Initializer,
513		pub para_assignment: ParaSessionInfo,
514		pub authority_discovery: AuthorityDiscovery,
515		pub beefy: Beefy,
516	}
517}
518
519pub struct IdentityValidatorIdeOf;
520impl sp_runtime::traits::Convert<AccountId, Option<AccountId>> for IdentityValidatorIdeOf {
521	fn convert(account: AccountId) -> Option<AccountId> {
522		Some(account)
523	}
524}
525
526/// A testing type that implements SessionManager, it receives a new validator set from
527/// `StakingAhClient`, but it prevents them from being passed over to the session pallet and
528/// just uses the previous session keys.
529pub struct AckButPreviousSessionValidatorsPersist<I>(core::marker::PhantomData<I>);
530
531impl<I: pallet_session::SessionManager<AccountId>> pallet_session::SessionManager<AccountId>
532	for AckButPreviousSessionValidatorsPersist<I>
533{
534	fn end_session(end_index: SessionIndex) {
535		<I as pallet_session::SessionManager<_>>::end_session(end_index);
536	}
537	fn new_session(new_index: SessionIndex) -> Option<Vec<AccountId>> {
538		match <I as pallet_session::SessionManager<_>>::new_session(new_index) {
539			Some(_new_ignored) => {
540				let current_validators = pallet_session::Validators::<Runtime>::get();
541				log::info!(target: "runtime", ">> received {} validators, but overriding with {} old ones", _new_ignored.len(), current_validators.len());
542				Some(current_validators)
543			},
544			None => None,
545		}
546	}
547	fn new_session_genesis(new_index: SessionIndex) -> Option<Vec<AccountId>> {
548		<I as pallet_session::SessionManager<_>>::new_session_genesis(new_index)
549	}
550	fn start_session(start_index: SessionIndex) {
551		<I as pallet_session::SessionManager<_>>::start_session(start_index);
552	}
553}
554
555impl pallet_session::Config for Runtime {
556	type RuntimeEvent = RuntimeEvent;
557	type ValidatorId = AccountId;
558	type ValidatorIdOf = IdentityValidatorIdeOf;
559	type ShouldEndSession = Babe;
560	type NextSessionRotation = Babe;
561	type SessionManager = AckButPreviousSessionValidatorsPersist<
562		session_historical::NoteHistoricalRoot<Self, StakingAhClient>,
563	>;
564	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
565	type Keys = SessionKeys;
566	type DisablingStrategy = pallet_session::disabling::UpToLimitWithReEnablingDisablingStrategy;
567	type WeightInfo = weights::pallet_session::WeightInfo<Runtime>;
568	type Currency = Balances;
569	type KeyDeposit = ();
570}
571
572impl session_historical::Config for Runtime {
573	type RuntimeEvent = RuntimeEvent;
574	type FullIdentification = sp_staking::Exposure<AccountId, Balance>;
575	type FullIdentificationOf = ah_client::DefaultExposureOf<Self>;
576}
577
578pub struct AssetHubLocation;
579impl Get<Location> for AssetHubLocation {
580	fn get() -> Location {
581		Location::new(0, [Junction::Parachain(1100)])
582	}
583}
584
585pub struct SessionReportToXcm;
586impl Convert<rc_client::SessionReport<AccountId>, Xcm<()>> for SessionReportToXcm {
587	fn convert(a: rc_client::SessionReport<AccountId>) -> Xcm<()> {
588		Xcm(vec![
589			Instruction::UnpaidExecution {
590				weight_limit: WeightLimit::Unlimited,
591				check_origin: None,
592			},
593			Instruction::Transact {
594				origin_kind: OriginKind::Superuser,
595				fallback_max_weight: None,
596				call: AssetHubRuntimePallets::RcClient(RcClientCalls::RelaySessionReport(a))
597					.encode()
598					.into(),
599			},
600		])
601	}
602}
603
604pub struct StakingXcmToAssetHub;
605impl ah_client::SendToAssetHub for StakingXcmToAssetHub {
606	type AccountId = AccountId;
607
608	fn relay_session_report(session_report: rc_client::SessionReport<Self::AccountId>) {
609		rc_client::XCMSender::<
610			xcm_config::XcmRouter,
611			AssetHubLocation,
612			rc_client::SessionReport<AccountId>,
613			SessionReportToXcm,
614		>::split_then_send(session_report, Some(8));
615	}
616
617	fn relay_new_offence(
618		session_index: SessionIndex,
619		offences: Vec<rc_client::Offence<Self::AccountId>>,
620	) {
621		let message = Xcm(vec![
622			Instruction::UnpaidExecution {
623				weight_limit: WeightLimit::Unlimited,
624				check_origin: None,
625			},
626			Instruction::Transact {
627				origin_kind: OriginKind::Superuser,
628				fallback_max_weight: None,
629				call: AssetHubRuntimePallets::RcClient(RcClientCalls::RelayNewOffence(
630					session_index,
631					offences,
632				))
633				.encode()
634				.into(),
635			},
636		]);
637		if let Err(err) = send_xcm::<xcm_config::XcmRouter>(AssetHubLocation::get(), message) {
638			log::error!(target: "runtime::ah-client", "Failed to send relay offence message: {:?}", err);
639		}
640	}
641}
642
643#[derive(Encode, Decode)]
644enum AssetHubRuntimePallets<AccountId> {
645	#[codec(index = 89)]
646	RcClient(RcClientCalls<AccountId>),
647}
648
649/// Call encoding for the calls needed from the rc-client pallet.
650#[derive(Encode, Decode)]
651enum RcClientCalls<AccountId> {
652	/// A session with the given index has started.
653	#[codec(index = 0)]
654	RelaySessionReport(rc_client::SessionReport<AccountId>),
655	#[codec(index = 1)]
656	RelayNewOffence(SessionIndex, Vec<rc_client::Offence<AccountId>>),
657}
658
659pub struct EnsureAssetHub;
660impl frame_support::traits::EnsureOrigin<RuntimeOrigin> for EnsureAssetHub {
661	type Success = ();
662	fn try_origin(o: RuntimeOrigin) -> Result<Self::Success, RuntimeOrigin> {
663		match <RuntimeOrigin as Into<Result<parachains_origin::Origin, RuntimeOrigin>>>::into(
664			o.clone(),
665		) {
666			Ok(parachains_origin::Origin::Parachain(id)) if id == 1100.into() => Ok(()),
667			_ => Err(o),
668		}
669	}
670
671	#[cfg(feature = "runtime-benchmarks")]
672	fn try_successful_origin() -> Result<RuntimeOrigin, ()> {
673		Ok(RuntimeOrigin::root())
674	}
675}
676
677parameter_types! {
678	pub const MaxOffenceBatchSize: u32 = 50;
679}
680
681impl pallet_staking_async_ah_client::Config for Runtime {
682	type CurrencyBalance = Balance;
683	type AssetHubOrigin =
684		frame_support::traits::EitherOfDiverse<EnsureRoot<AccountId>, EnsureAssetHub>;
685	type AdminOrigin = EnsureRoot<AccountId>;
686	type SessionInterface = Self;
687	type SendToAssetHub = StakingXcmToAssetHub;
688	type MinimumValidatorSetSize = ConstU32<10>;
689	type UnixTime = Timestamp;
690	type PointsPerBlock = ConstU32<20>;
691	type MaxOffenceBatchSize = MaxOffenceBatchSize;
692	type Fallback = Staking;
693	type WeightInfo = ();
694}
695
696parameter_types! {
697	// phase durations. 1/4 of the last session for each.
698	pub SignedPhase: u32 = prod_or_fast!(
699		EPOCH_DURATION_IN_SLOTS / 4,
700		(1 * MINUTES).min(EpochDuration::get().saturated_into::<u32>() / 2)
701	);
702	pub UnsignedPhase: u32 = prod_or_fast!(
703		EPOCH_DURATION_IN_SLOTS / 4,
704		(1 * MINUTES).min(EpochDuration::get().saturated_into::<u32>() / 2)
705	);
706
707	// signed config
708	pub const SignedMaxSubmissions: u32 = 128;
709	pub const SignedMaxRefunds: u32 = 128 / 4;
710	pub const SignedFixedDeposit: Balance = deposit(2, 0);
711	pub const SignedDepositIncreaseFactor: Percent = Percent::from_percent(10);
712	pub const SignedDepositByte: Balance = deposit(0, 10) / 1024;
713	// Each good submission will get 1 WND as reward
714	pub SignedRewardBase: Balance = 1 * UNITS;
715
716	// 1 hour session, 15 minutes unsigned phase, 4 offchain executions.
717	pub OffchainRepeat: BlockNumber = UnsignedPhase::get() / 4;
718
719	pub const MaxElectingVoters: u32 = 22_500;
720	/// We take the top 22500 nominators as electing voters and all of the validators as electable
721	/// targets. Whilst this is the case, we cannot and shall not increase the size of the
722	/// validator intentions.
723	pub ElectionBounds: frame_election_provider_support::bounds::ElectionBounds =
724		ElectionBoundsBuilder::default().voters_count(MaxElectingVoters::get().into()).build();
725	// Maximum winners that can be chosen as active validators
726	pub const MaxActiveValidators: u32 = 1000;
727	// One page only, fill the whole page with the `MaxActiveValidators`.
728	pub const MaxWinnersPerPage: u32 = MaxActiveValidators::get();
729	// Unbonded, thus the max backers per winner maps to the max electing voters limit.
730	pub const MaxBackersPerWinner: u32 = MaxElectingVoters::get();
731}
732
733frame_election_provider_support::generate_solution_type!(
734	#[compact]
735	pub struct NposCompactSolution16::<
736		VoterIndex = u32,
737		TargetIndex = u16,
738		Accuracy = sp_runtime::PerU16,
739		MaxVoters = MaxElectingVoters,
740	>(16)
741);
742
743pub struct OnChainSeqPhragmen;
744impl onchain::Config for OnChainSeqPhragmen {
745	type Sort = ConstBool<true>;
746	type System = Runtime;
747	type Solver = SequentialPhragmen<
748		AccountId,
749		pallet_election_provider_multi_phase::SolutionAccuracyOf<Runtime>,
750	>;
751	type DataProvider = Staking;
752	type WeightInfo = ();
753	type Bounds = ElectionBounds;
754	type MaxBackersPerWinner = MaxBackersPerWinner;
755	type MaxWinnersPerPage = MaxWinnersPerPage;
756}
757
758impl pallet_election_provider_multi_phase::MinerConfig for Runtime {
759	type AccountId = AccountId;
760	type MaxLength = OffchainSolutionLengthLimit;
761	type MaxWeight = OffchainSolutionWeightLimit;
762	type Solution = NposCompactSolution16;
763	type MaxVotesPerVoter = <
764	<Self as pallet_election_provider_multi_phase::Config>::DataProvider
765	as
766	frame_election_provider_support::ElectionDataProvider
767	>::MaxVotesPerVoter;
768	type MaxBackersPerWinner = MaxBackersPerWinner;
769	type MaxWinners = MaxWinnersPerPage;
770
771	// The unsigned submissions have to respect the weight of the submit_unsigned call, thus their
772	// weight estimate function is wired to this call's weight.
773	fn solution_weight(v: u32, t: u32, a: u32, d: u32) -> Weight {
774		<
775		<Self as pallet_election_provider_multi_phase::Config>::WeightInfo
776		as
777		pallet_election_provider_multi_phase::WeightInfo
778		>::submit_unsigned(v, t, a, d)
779	}
780}
781
782impl pallet_election_provider_multi_phase::Config for Runtime {
783	type RuntimeEvent = RuntimeEvent;
784	type Currency = Balances;
785	type EstimateCallFee = TransactionPayment;
786	type SignedPhase = SignedPhase;
787	type UnsignedPhase = UnsignedPhase;
788	type SignedMaxSubmissions = SignedMaxSubmissions;
789	type SignedMaxRefunds = SignedMaxRefunds;
790	type SignedRewardBase = SignedRewardBase;
791	type SignedDepositBase = pallet_election_provider_multi_phase::GeometricDepositBase<
792		Balance,
793		SignedFixedDeposit,
794		SignedDepositIncreaseFactor,
795	>;
796	type SignedDepositByte = SignedDepositByte;
797	type SignedDepositWeight = ();
798	type SignedMaxWeight =
799		<Self::MinerConfig as pallet_election_provider_multi_phase::MinerConfig>::MaxWeight;
800	type MinerConfig = Self;
801	type SlashHandler = (); // burn slashes
802	type RewardHandler = (); // rewards are minted from the void
803	type BetterSignedThreshold = ();
804	type OffchainRepeat = OffchainRepeat;
805	type MinerTxPriority = NposSolutionPriority;
806	type MaxWinners = MaxWinnersPerPage;
807	type MaxBackersPerWinner = MaxBackersPerWinner;
808	type DataProvider = Staking;
809	#[cfg(any(feature = "fast-runtime", feature = "runtime-benchmarks"))]
810	type Fallback = onchain::OnChainExecution<OnChainSeqPhragmen>;
811	#[cfg(not(any(feature = "fast-runtime", feature = "runtime-benchmarks")))]
812	type Fallback = frame_election_provider_support::NoElection<(
813		AccountId,
814		BlockNumber,
815		Staking,
816		MaxWinnersPerPage,
817		MaxBackersPerWinner,
818	)>;
819	type GovernanceFallback = onchain::OnChainExecution<OnChainSeqPhragmen>;
820	type Solver = SequentialPhragmen<
821		AccountId,
822		pallet_election_provider_multi_phase::SolutionAccuracyOf<Self>,
823		(),
824	>;
825	type BenchmarkingConfig = polkadot_runtime_common::elections::BenchmarkConfig;
826	type ForceOrigin = EnsureRoot<AccountId>;
827	type WeightInfo = ();
828	type ElectionBounds = ElectionBounds;
829}
830
831parameter_types! {
832	pub const SessionsPerEra: SessionIndex = 3;
833	pub const BondingDuration: sp_staking::EraIndex = 3;
834	pub const SlashDeferDuration: sp_staking::EraIndex = 1;
835	pub const MaxExposurePageSize: u32 = 64;
836	pub const MaxNominations: u32 = <NposCompactSolution16 as frame_election_provider_support::NposSolution>::LIMIT as u32;
837	pub const MaxControllersInDeprecationBatch: u32 = 751;
838}
839
840impl pallet_staking::Config for Runtime {
841	type OldCurrency = Balances;
842	type Currency = Balances;
843	type UnixTime = Timestamp;
844	type SessionInterface = Self;
845	type CurrencyBalance = Balance;
846	type RuntimeHoldReason = RuntimeHoldReason;
847	type CurrencyToVote = sp_staking::currency_to_vote::U128CurrencyToVote;
848	type RewardRemainder = ();
849	type RuntimeEvent = RuntimeEvent;
850	type Slash = ();
851	type Reward = ();
852	type SessionsPerEra = SessionsPerEra;
853	type BondingDuration = BondingDuration;
854	type SlashDeferDuration = SlashDeferDuration;
855	type AdminOrigin = EitherOf<EnsureRoot<AccountId>, StakingAdmin>;
856	type EraPayout = ();
857	type MaxExposurePageSize = MaxExposurePageSize;
858	type NextNewSession = Session;
859	type ElectionProvider = ElectionProviderMultiPhase;
860	type GenesisElectionProvider = onchain::OnChainExecution<OnChainSeqPhragmen>;
861	type VoterList = VoterList;
862	type TargetList = pallet_staking::UseValidatorsMap<Self>;
863	type MaxValidatorSet = MaxActiveValidators;
864	type NominationsQuota = pallet_staking::FixedNominationsQuota<{ MaxNominations::get() }>;
865	type MaxUnlockingChunks = frame_support::traits::ConstU32<32>;
866	type HistoryDepth = frame_support::traits::ConstU32<84>;
867	type MaxControllersInDeprecationBatch = MaxControllersInDeprecationBatch;
868	type BenchmarkingConfig = polkadot_runtime_common::StakingBenchmarkingConfig;
869	type EventListeners = ();
870	type WeightInfo = ();
871	type Filter = Nothing;
872}
873
874const THRESHOLDS: [VoteWeight; 9] = [10, 20, 30, 40, 50, 60, 1_000, 2_000, 10_000];
875
876parameter_types! {
877	pub const BagThresholds: &'static [sp_npos_elections::VoteWeight] = &THRESHOLDS;
878}
879
880type VoterBagsListInstance = pallet_bags_list::Instance1;
881impl pallet_bags_list::Config<VoterBagsListInstance> for Runtime {
882	type RuntimeEvent = RuntimeEvent;
883	type ScoreProvider = Staking;
884	type WeightInfo = ();
885	type BagThresholds = BagThresholds;
886	type Score = sp_npos_elections::VoteWeight;
887	type MaxAutoRebagPerBlock = ();
888}
889
890parameter_types! {
891	pub const SpendPeriod: BlockNumber = 6 * DAYS;
892	pub const Burn: Permill = Permill::from_perthousand(2);
893	pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
894	pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS;
895	// The asset's interior location for the paying account. This is the Treasury
896	// pallet instance (which sits at index 37).
897	pub TreasuryInteriorLocation: InteriorLocation = PalletInstance(37).into();
898
899	pub const TipCountdown: BlockNumber = 1 * DAYS;
900	pub const TipFindersFee: Percent = Percent::from_percent(20);
901	pub const TipReportDepositBase: Balance = 100 * CENTS;
902	pub const DataDepositPerByte: Balance = 1 * CENTS;
903	pub const MaxApprovals: u32 = 100;
904	pub const MaxAuthorities: u32 = 100_000;
905	pub const MaxKeys: u32 = 10_000;
906	pub const MaxPeerInHeartbeats: u32 = 10_000;
907	pub const MaxBalance: Balance = Balance::max_value();
908}
909
910impl pallet_treasury::Config for Runtime {
911	type PalletId = TreasuryPalletId;
912	type Currency = Balances;
913	type RejectOrigin = EitherOfDiverse<EnsureRoot<AccountId>, Treasurer>;
914	type RuntimeEvent = RuntimeEvent;
915	type SpendPeriod = SpendPeriod;
916	type Burn = Burn;
917	type BurnDestination = ();
918	type MaxApprovals = MaxApprovals;
919	type WeightInfo = weights::pallet_treasury::WeightInfo<Runtime>;
920	type SpendFunds = ();
921	type SpendOrigin = TreasurySpender;
922	type AssetKind = VersionedLocatableAsset;
923	type Beneficiary = VersionedLocation;
924	type BeneficiaryLookup = IdentityLookup<Self::Beneficiary>;
925	type Paymaster = PayOverXcm<
926		TreasuryInteriorLocation,
927		crate::xcm_config::XcmRouter,
928		crate::XcmPallet,
929		ConstU32<{ 6 * HOURS }>,
930		Self::Beneficiary,
931		Self::AssetKind,
932		LocatableAssetConverter,
933		VersionedLocationConverter,
934	>;
935	type BalanceConverter = UnityOrOuterConversion<
936		ContainsParts<
937			FromContains<
938				xcm_builder::IsChildSystemParachain<ParaId>,
939				xcm_builder::IsParentsOnly<ConstU8<1>>,
940			>,
941		>,
942		AssetRate,
943	>;
944	type PayoutPeriod = PayoutSpendPeriod;
945	type BlockNumberProvider = System;
946	#[cfg(feature = "runtime-benchmarks")]
947	type BenchmarkHelper = polkadot_runtime_common::impls::benchmarks::TreasuryArguments;
948}
949
950impl pallet_offences::Config for Runtime {
951	type RuntimeEvent = RuntimeEvent;
952	type IdentificationTuple = session_historical::IdentificationTuple<Self>;
953	type OnOffenceHandler = StakingAhClient;
954}
955
956impl pallet_authority_discovery::Config for Runtime {
957	type MaxAuthorities = MaxAuthorities;
958}
959
960parameter_types! {
961	pub const NposSolutionPriority: TransactionPriority = TransactionPriority::max_value() / 2;
962}
963
964parameter_types! {
965	pub const MaxSetIdSessionEntries: u32 = 1024;
966}
967
968impl pallet_grandpa::Config for Runtime {
969	type RuntimeEvent = RuntimeEvent;
970
971	type WeightInfo = ();
972	type MaxAuthorities = MaxAuthorities;
973	type MaxNominators = <Self as pallet_babe::Config>::MaxNominators;
974	type MaxSetIdSessionEntries = MaxSetIdSessionEntries;
975
976	type KeyOwnerProof = sp_session::MembershipProof;
977
978	type EquivocationReportSystem =
979		pallet_grandpa::EquivocationReportSystem<Self, Offences, Historical, ReportLongevity>;
980}
981
982impl frame_system::offchain::SigningTypes for Runtime {
983	type Public = <Signature as Verify>::Signer;
984	type Signature = Signature;
985}
986
987impl<C> frame_system::offchain::CreateTransactionBase<C> for Runtime
988where
989	RuntimeCall: From<C>,
990{
991	type RuntimeCall = RuntimeCall;
992	type Extrinsic = UncheckedExtrinsic;
993}
994
995impl<LocalCall> frame_system::offchain::CreateTransaction<LocalCall> for Runtime
996where
997	RuntimeCall: From<LocalCall>,
998{
999	type Extension = TxExtension;
1000
1001	fn create_transaction(call: RuntimeCall, extension: TxExtension) -> UncheckedExtrinsic {
1002		UncheckedExtrinsic::new_transaction(call, extension)
1003	}
1004}
1005
1006/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
1007/// format of the chain.
1008impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
1009where
1010	RuntimeCall: From<LocalCall>,
1011{
1012	fn create_signed_transaction<
1013		C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>,
1014	>(
1015		call: RuntimeCall,
1016		public: <Signature as Verify>::Signer,
1017		account: AccountId,
1018		nonce: <Runtime as frame_system::Config>::Nonce,
1019	) -> Option<UncheckedExtrinsic> {
1020		use sp_runtime::traits::StaticLookup;
1021		// take the biggest period possible.
1022		let period =
1023			BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64;
1024
1025		let current_block = System::block_number()
1026			.saturated_into::<u64>()
1027			// The `System::block_number` is initialized with `n+1`,
1028			// so the actual block number is `n`.
1029			.saturating_sub(1);
1030		let tip = 0;
1031		let tx_ext: TxExtension = (
1032			frame_system::CheckNonZeroSender::<Runtime>::new(),
1033			frame_system::CheckSpecVersion::<Runtime>::new(),
1034			frame_system::CheckTxVersion::<Runtime>::new(),
1035			frame_system::CheckGenesis::<Runtime>::new(),
1036			frame_system::CheckMortality::<Runtime>::from(generic::Era::mortal(
1037				period,
1038				current_block,
1039			)),
1040			frame_system::CheckNonce::<Runtime>::from(nonce),
1041			frame_system::CheckWeight::<Runtime>::new(),
1042			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
1043			frame_metadata_hash_extension::CheckMetadataHash::<Runtime>::new(true),
1044			frame_system::WeightReclaim::<Runtime>::new(),
1045		)
1046			.into();
1047		let raw_payload = SignedPayload::new(call, tx_ext)
1048			.map_err(|e| {
1049				log::warn!("Unable to create signed payload: {:?}", e);
1050			})
1051			.ok()?;
1052		let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?;
1053		let (call, tx_ext, _) = raw_payload.deconstruct();
1054		let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
1055		let transaction = UncheckedExtrinsic::new_signed(call, address, signature, tx_ext);
1056		Some(transaction)
1057	}
1058}
1059
1060impl<LocalCall> frame_system::offchain::CreateInherent<LocalCall> for Runtime
1061where
1062	RuntimeCall: From<LocalCall>,
1063{
1064	fn create_bare(call: RuntimeCall) -> UncheckedExtrinsic {
1065		UncheckedExtrinsic::new_bare(call)
1066	}
1067}
1068
1069parameter_types! {
1070	// Minimum 100 bytes/KSM deposited (1 CENT/byte)
1071	pub const BasicDeposit: Balance = 1000 * CENTS;       // 258 bytes on-chain
1072	pub const ByteDeposit: Balance = deposit(0, 1);
1073	pub const UsernameDeposit: Balance = deposit(0, 32);
1074	pub const SubAccountDeposit: Balance = 200 * CENTS;   // 53 bytes on-chain
1075	pub const MaxSubAccounts: u32 = 100;
1076	pub const MaxAdditionalFields: u32 = 100;
1077	pub const MaxRegistrars: u32 = 20;
1078}
1079
1080impl pallet_identity::Config for Runtime {
1081	type RuntimeEvent = RuntimeEvent;
1082	type Currency = Balances;
1083	type Slashed = ();
1084	type BasicDeposit = BasicDeposit;
1085	type ByteDeposit = ByteDeposit;
1086	type UsernameDeposit = UsernameDeposit;
1087	type SubAccountDeposit = SubAccountDeposit;
1088	type MaxSubAccounts = MaxSubAccounts;
1089	type IdentityInformation = IdentityInfo<MaxAdditionalFields>;
1090	type MaxRegistrars = MaxRegistrars;
1091	type ForceOrigin = EitherOf<EnsureRoot<Self::AccountId>, GeneralAdmin>;
1092	type RegistrarOrigin = EitherOf<EnsureRoot<Self::AccountId>, GeneralAdmin>;
1093	type OffchainSignature = Signature;
1094	type SigningPublicKey = <Signature as Verify>::Signer;
1095	type UsernameAuthorityOrigin = EnsureRoot<Self::AccountId>;
1096	type PendingUsernameExpiration = ConstU32<{ 7 * DAYS }>;
1097	type UsernameGracePeriod = ConstU32<{ 30 * DAYS }>;
1098	type MaxSuffixLength = ConstU32<7>;
1099	type MaxUsernameLength = ConstU32<32>;
1100	#[cfg(feature = "runtime-benchmarks")]
1101	type BenchmarkHelper = ();
1102	type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
1103}
1104
1105impl pallet_utility::Config for Runtime {
1106	type RuntimeEvent = RuntimeEvent;
1107	type RuntimeCall = RuntimeCall;
1108	type PalletsOrigin = OriginCaller;
1109	type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
1110}
1111
1112parameter_types! {
1113	// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
1114	pub const DepositBase: Balance = deposit(1, 88);
1115	// Additional storage item size of 32 bytes.
1116	pub const DepositFactor: Balance = deposit(0, 32);
1117	pub const MaxSignatories: u32 = 100;
1118}
1119
1120impl pallet_multisig::Config for Runtime {
1121	type RuntimeEvent = RuntimeEvent;
1122	type RuntimeCall = RuntimeCall;
1123	type Currency = Balances;
1124	type DepositBase = DepositBase;
1125	type DepositFactor = DepositFactor;
1126	type MaxSignatories = MaxSignatories;
1127	type WeightInfo = weights::pallet_multisig::WeightInfo<Runtime>;
1128	type BlockNumberProvider = frame_system::Pallet<Runtime>;
1129}
1130
1131parameter_types! {
1132	pub const ConfigDepositBase: Balance = 500 * CENTS;
1133	pub const FriendDepositFactor: Balance = 50 * CENTS;
1134	pub const MaxFriends: u16 = 9;
1135	pub const RecoveryDeposit: Balance = 500 * CENTS;
1136}
1137
1138impl pallet_recovery::Config for Runtime {
1139	type RuntimeEvent = RuntimeEvent;
1140	type WeightInfo = ();
1141	type RuntimeCall = RuntimeCall;
1142	type BlockNumberProvider = System;
1143	type Currency = Balances;
1144	type ConfigDepositBase = ConfigDepositBase;
1145	type FriendDepositFactor = FriendDepositFactor;
1146	type MaxFriends = MaxFriends;
1147	type RecoveryDeposit = RecoveryDeposit;
1148}
1149
1150parameter_types! {
1151	pub const MinVestedTransfer: Balance = 100 * CENTS;
1152	pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons =
1153		WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE);
1154}
1155
1156impl pallet_vesting::Config for Runtime {
1157	type RuntimeEvent = RuntimeEvent;
1158	type Currency = Balances;
1159	type BlockNumberToBalance = ConvertInto;
1160	type MinVestedTransfer = MinVestedTransfer;
1161	type WeightInfo = weights::pallet_vesting::WeightInfo<Runtime>;
1162	type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons;
1163	type BlockNumberProvider = System;
1164	const MAX_VESTING_SCHEDULES: u32 = 28;
1165}
1166
1167impl pallet_sudo::Config for Runtime {
1168	type RuntimeEvent = RuntimeEvent;
1169	type RuntimeCall = RuntimeCall;
1170	type WeightInfo = weights::pallet_sudo::WeightInfo<Runtime>;
1171}
1172
1173parameter_types! {
1174	// One storage item; key size 32, value size 8; .
1175	pub const ProxyDepositBase: Balance = deposit(1, 8);
1176	// Additional storage item size of 33 bytes.
1177	pub const ProxyDepositFactor: Balance = deposit(0, 33);
1178	pub const MaxProxies: u16 = 32;
1179	pub const AnnouncementDepositBase: Balance = deposit(1, 8);
1180	pub const AnnouncementDepositFactor: Balance = deposit(0, 66);
1181	pub const MaxPending: u16 = 32;
1182}
1183
1184/// The type used to represent the kinds of proxying allowed.
1185#[derive(
1186	Copy,
1187	Clone,
1188	Eq,
1189	PartialEq,
1190	Ord,
1191	PartialOrd,
1192	Encode,
1193	Decode,
1194	DecodeWithMemTracking,
1195	RuntimeDebug,
1196	MaxEncodedLen,
1197	TypeInfo,
1198)]
1199pub enum ProxyType {
1200	Any,
1201	NonTransfer,
1202	Governance,
1203	Staking,
1204	SudoBalances,
1205	IdentityJudgement,
1206	CancelProxy,
1207	Auction,
1208	NominationPools,
1209	ParaRegistration,
1210}
1211impl Default for ProxyType {
1212	fn default() -> Self {
1213		Self::Any
1214	}
1215}
1216impl InstanceFilter<RuntimeCall> for ProxyType {
1217	fn filter(&self, c: &RuntimeCall) -> bool {
1218		match self {
1219			ProxyType::Any => true,
1220			ProxyType::NonTransfer => matches!(
1221				c,
1222				RuntimeCall::System(..) |
1223				RuntimeCall::Babe(..) |
1224				RuntimeCall::Timestamp(..) |
1225				RuntimeCall::Indices(pallet_indices::Call::claim{..}) |
1226				RuntimeCall::Indices(pallet_indices::Call::free{..}) |
1227				RuntimeCall::Indices(pallet_indices::Call::freeze{..}) |
1228				// Specifically omitting Indices `transfer`, `force_transfer`
1229				// Specifically omitting the entire Balances pallet
1230				RuntimeCall::Session(..) |
1231				RuntimeCall::Grandpa(..) |
1232				RuntimeCall::Utility(..) |
1233				RuntimeCall::Identity(..) |
1234				RuntimeCall::ConvictionVoting(..) |
1235				RuntimeCall::Referenda(..) |
1236				RuntimeCall::Whitelist(..) |
1237				RuntimeCall::Recovery(pallet_recovery::Call::as_recovered{..}) |
1238				RuntimeCall::Recovery(pallet_recovery::Call::vouch_recovery{..}) |
1239				RuntimeCall::Recovery(pallet_recovery::Call::claim_recovery{..}) |
1240				RuntimeCall::Recovery(pallet_recovery::Call::close_recovery{..}) |
1241				RuntimeCall::Recovery(pallet_recovery::Call::remove_recovery{..}) |
1242				RuntimeCall::Recovery(pallet_recovery::Call::cancel_recovered{..}) |
1243				// Specifically omitting Recovery `create_recovery`, `initiate_recovery`
1244				RuntimeCall::Vesting(pallet_vesting::Call::vest{..}) |
1245				RuntimeCall::Vesting(pallet_vesting::Call::vest_other{..}) |
1246				// Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer`
1247				RuntimeCall::Scheduler(..) |
1248				// Specifically omitting Sudo pallet
1249				RuntimeCall::Proxy(..) |
1250				RuntimeCall::Multisig(..) |
1251				RuntimeCall::Registrar(paras_registrar::Call::register{..}) |
1252				RuntimeCall::Registrar(paras_registrar::Call::deregister{..}) |
1253				// Specifically omitting Registrar `swap`
1254				RuntimeCall::Registrar(paras_registrar::Call::reserve{..}) |
1255				RuntimeCall::Crowdloan(..) |
1256				RuntimeCall::Slots(..) |
1257				RuntimeCall::Auctions(..)
1258			),
1259			ProxyType::Staking => {
1260				matches!(c, RuntimeCall::Session(..) | RuntimeCall::Utility(..))
1261			},
1262			ProxyType::NominationPools => {
1263				matches!(c,| RuntimeCall::Utility(..))
1264			},
1265			ProxyType::SudoBalances => match c {
1266				RuntimeCall::Sudo(pallet_sudo::Call::sudo { call: ref x }) => {
1267					matches!(x.as_ref(), &RuntimeCall::Balances(..))
1268				},
1269				RuntimeCall::Utility(..) => true,
1270				_ => false,
1271			},
1272			ProxyType::Governance => matches!(
1273				c,
1274				// OpenGov calls
1275				RuntimeCall::ConvictionVoting(..) |
1276					RuntimeCall::Referenda(..) |
1277					RuntimeCall::Whitelist(..)
1278			),
1279			ProxyType::IdentityJudgement => matches!(
1280				c,
1281				RuntimeCall::Identity(pallet_identity::Call::provide_judgement { .. }) |
1282					RuntimeCall::Utility(..)
1283			),
1284			ProxyType::CancelProxy => {
1285				matches!(c, RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }))
1286			},
1287			ProxyType::Auction => matches!(
1288				c,
1289				RuntimeCall::Auctions(..) |
1290					RuntimeCall::Crowdloan(..) |
1291					RuntimeCall::Registrar(..) |
1292					RuntimeCall::Slots(..)
1293			),
1294			ProxyType::ParaRegistration => matches!(
1295				c,
1296				RuntimeCall::Registrar(paras_registrar::Call::reserve { .. }) |
1297					RuntimeCall::Registrar(paras_registrar::Call::register { .. }) |
1298					RuntimeCall::Utility(pallet_utility::Call::batch { .. }) |
1299					RuntimeCall::Utility(pallet_utility::Call::batch_all { .. }) |
1300					RuntimeCall::Utility(pallet_utility::Call::force_batch { .. }) |
1301					RuntimeCall::Proxy(pallet_proxy::Call::remove_proxy { .. })
1302			),
1303		}
1304	}
1305	fn is_superset(&self, o: &Self) -> bool {
1306		match (self, o) {
1307			(x, y) if x == y => true,
1308			(ProxyType::Any, _) => true,
1309			(_, ProxyType::Any) => false,
1310			(ProxyType::NonTransfer, _) => true,
1311			_ => false,
1312		}
1313	}
1314}
1315
1316impl pallet_proxy::Config for Runtime {
1317	type RuntimeEvent = RuntimeEvent;
1318	type RuntimeCall = RuntimeCall;
1319	type Currency = Balances;
1320	type ProxyType = ProxyType;
1321	type ProxyDepositBase = ProxyDepositBase;
1322	type ProxyDepositFactor = ProxyDepositFactor;
1323	type MaxProxies = MaxProxies;
1324	type WeightInfo = weights::pallet_proxy::WeightInfo<Runtime>;
1325	type MaxPending = MaxPending;
1326	type CallHasher = BlakeTwo256;
1327	type AnnouncementDepositBase = AnnouncementDepositBase;
1328	type AnnouncementDepositFactor = AnnouncementDepositFactor;
1329	type BlockNumberProvider = frame_system::Pallet<Runtime>;
1330}
1331
1332impl parachains_origin::Config for Runtime {}
1333
1334impl parachains_configuration::Config for Runtime {
1335	type WeightInfo = weights::polkadot_runtime_parachains_configuration::WeightInfo<Runtime>;
1336}
1337
1338impl parachains_shared::Config for Runtime {
1339	type DisabledValidators = Session;
1340}
1341
1342impl parachains_session_info::Config for Runtime {
1343	type ValidatorSet = Historical;
1344}
1345
1346impl parachains_inclusion::Config for Runtime {
1347	type RuntimeEvent = RuntimeEvent;
1348	type DisputesHandler = ParasDisputes;
1349	type RewardValidators =
1350		parachains_reward_points::RewardValidatorsWithEraPoints<Runtime, StakingAhClient>;
1351	type MessageQueue = MessageQueue;
1352	type WeightInfo = weights::polkadot_runtime_parachains_inclusion::WeightInfo<Runtime>;
1353}
1354
1355parameter_types! {
1356	pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
1357}
1358
1359impl parachains_paras::Config for Runtime {
1360	type RuntimeEvent = RuntimeEvent;
1361	type WeightInfo = weights::polkadot_runtime_parachains_paras::WeightInfo<Runtime>;
1362	type UnsignedPriority = ParasUnsignedPriority;
1363	type QueueFootprinter = ParaInclusion;
1364	type NextSessionRotation = Babe;
1365	type OnNewHead = ();
1366	type AssignCoretime = CoretimeAssignmentProvider;
1367	type Fungible = Balances;
1368	type CooldownRemovalMultiplier = ConstUint<1>;
1369	type AuthorizeCurrentCodeOrigin = EnsureRoot<AccountId>;
1370}
1371
1372parameter_types! {
1373	/// Amount of weight that can be spent per block to service messages.
1374	///
1375	/// # WARNING
1376	///
1377	/// This is not a good value for para-chains since the `Scheduler` already uses up to 80% block weight.
1378	pub MessageQueueServiceWeight: Weight = Perbill::from_percent(20) * BlockWeights::get().max_block;
1379	pub const MessageQueueHeapSize: u32 = 128 * 1024;
1380	pub const MessageQueueMaxStale: u32 = 48;
1381}
1382
1383/// Message processor to handle any messages that were enqueued into the `MessageQueue` pallet.
1384pub struct MessageProcessor;
1385impl ProcessMessage for MessageProcessor {
1386	type Origin = AggregateMessageOrigin;
1387
1388	fn process_message(
1389		message: &[u8],
1390		origin: Self::Origin,
1391		meter: &mut WeightMeter,
1392		id: &mut [u8; 32],
1393	) -> Result<bool, ProcessMessageError> {
1394		let para = match origin {
1395			AggregateMessageOrigin::Ump(UmpQueueId::Para(para)) => para,
1396		};
1397		xcm_builder::ProcessXcmMessage::<
1398			Junction,
1399			xcm_executor::XcmExecutor<xcm_config::XcmConfig>,
1400			RuntimeCall,
1401		>::process_message(message, Junction::Parachain(para.into()), meter, id)
1402	}
1403}
1404
1405impl pallet_message_queue::Config for Runtime {
1406	type RuntimeEvent = RuntimeEvent;
1407	type Size = u32;
1408	type HeapSize = MessageQueueHeapSize;
1409	type MaxStale = MessageQueueMaxStale;
1410	type ServiceWeight = MessageQueueServiceWeight;
1411	type IdleMaxServiceWeight = MessageQueueServiceWeight;
1412	#[cfg(not(feature = "runtime-benchmarks"))]
1413	type MessageProcessor = MessageProcessor;
1414	#[cfg(feature = "runtime-benchmarks")]
1415	type MessageProcessor =
1416		pallet_message_queue::mock_helpers::NoopMessageProcessor<AggregateMessageOrigin>;
1417	type QueueChangeHandler = ParaInclusion;
1418	type QueuePausedQuery = ();
1419	type WeightInfo = weights::pallet_message_queue::WeightInfo<Runtime>;
1420}
1421
1422impl parachains_dmp::Config for Runtime {}
1423
1424parameter_types! {
1425	pub const HrmpChannelSizeAndCapacityWithSystemRatio: Percent = Percent::from_percent(100);
1426}
1427
1428impl parachains_hrmp::Config for Runtime {
1429	type RuntimeOrigin = RuntimeOrigin;
1430	type RuntimeEvent = RuntimeEvent;
1431	type ChannelManager = EnsureRoot<AccountId>;
1432	type Currency = Balances;
1433	type DefaultChannelSizeAndCapacityWithSystem = ActiveConfigHrmpChannelSizeAndCapacityRatio<
1434		Runtime,
1435		HrmpChannelSizeAndCapacityWithSystemRatio,
1436	>;
1437	type VersionWrapper = crate::XcmPallet;
1438	type WeightInfo = weights::polkadot_runtime_parachains_hrmp::WeightInfo<Self>;
1439}
1440
1441impl parachains_paras_inherent::Config for Runtime {
1442	type WeightInfo = weights::polkadot_runtime_parachains_paras_inherent::WeightInfo<Runtime>;
1443}
1444
1445impl parachains_scheduler::Config for Runtime {
1446	// If you change this, make sure the `Assignment` type of the new provider is binary compatible,
1447	// otherwise provide a migration.
1448	type AssignmentProvider = CoretimeAssignmentProvider;
1449}
1450
1451parameter_types! {
1452	pub const BrokerId: u32 = BROKER_ID;
1453	pub const BrokerPalletId: PalletId = PalletId(*b"py/broke");
1454	pub const AssetHubId: u32 = ASSET_HUB_ID;	// TODO: replace with ASSET_HUB_NEXT_ID
1455	pub MaxXcmTransactWeight: Weight = Weight::from_parts(200_000_000, 20_000);
1456}
1457
1458pub struct BrokerPot;
1459impl Get<InteriorLocation> for AssetHubLocation {
1460	fn get() -> InteriorLocation {
1461		Junction::AccountId32 { network: None, id: BrokerPalletId::get().into_account_truncating() }
1462			.into()
1463	}
1464}
1465
1466impl coretime::Config for Runtime {
1467	type RuntimeOrigin = RuntimeOrigin;
1468	type RuntimeEvent = RuntimeEvent;
1469	type BrokerId = BrokerId;
1470	type BrokerPotLocation = AssetHubLocation;
1471	type WeightInfo = weights::polkadot_runtime_parachains_coretime::WeightInfo<Runtime>;
1472	type SendXcm = crate::xcm_config::XcmRouter;
1473	type AssetTransactor = crate::xcm_config::LocalAssetTransactor;
1474	type AccountToLocation = xcm_builder::AliasesIntoAccountId32<
1475		xcm_config::ThisNetwork,
1476		<Runtime as frame_system::Config>::AccountId,
1477	>;
1478	type MaxXcmTransactWeight = MaxXcmTransactWeight;
1479}
1480
1481parameter_types! {
1482	pub const OnDemandTrafficDefaultValue: FixedU128 = FixedU128::from_u32(1);
1483	// Keep 2 timeslices worth of revenue information.
1484	pub const MaxHistoricalRevenue: BlockNumber = 2 * TIMESLICE_PERIOD;
1485	pub const OnDemandPalletId: PalletId = PalletId(*b"py/ondmd");
1486}
1487
1488impl parachains_on_demand::Config for Runtime {
1489	type RuntimeEvent = RuntimeEvent;
1490	type Currency = Balances;
1491	type TrafficDefaultValue = OnDemandTrafficDefaultValue;
1492	type WeightInfo = weights::polkadot_runtime_parachains_on_demand::WeightInfo<Runtime>;
1493	type MaxHistoricalRevenue = MaxHistoricalRevenue;
1494	type PalletId = OnDemandPalletId;
1495}
1496
1497impl parachains_assigner_coretime::Config for Runtime {}
1498
1499impl parachains_initializer::Config for Runtime {
1500	type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
1501	type ForceOrigin = EnsureRoot<AccountId>;
1502	type WeightInfo = weights::polkadot_runtime_parachains_initializer::WeightInfo<Runtime>;
1503	type CoretimeOnNewSession = Coretime;
1504}
1505
1506impl paras_sudo_wrapper::Config for Runtime {}
1507
1508parameter_types! {
1509	pub const PermanentSlotLeasePeriodLength: u32 = 26;
1510	pub const TemporarySlotLeasePeriodLength: u32 = 1;
1511	pub const MaxTemporarySlotPerLeasePeriod: u32 = 5;
1512}
1513
1514impl assigned_slots::Config for Runtime {
1515	type RuntimeEvent = RuntimeEvent;
1516	type AssignSlotOrigin = EnsureRoot<AccountId>;
1517	type Leaser = Slots;
1518	type PermanentSlotLeasePeriodLength = PermanentSlotLeasePeriodLength;
1519	type TemporarySlotLeasePeriodLength = TemporarySlotLeasePeriodLength;
1520	type MaxTemporarySlotPerLeasePeriod = MaxTemporarySlotPerLeasePeriod;
1521	type WeightInfo = weights::polkadot_runtime_common_assigned_slots::WeightInfo<Runtime>;
1522}
1523
1524impl parachains_disputes::Config for Runtime {
1525	type RuntimeEvent = RuntimeEvent;
1526	type RewardValidators =
1527		parachains_reward_points::RewardValidatorsWithEraPoints<Runtime, StakingAhClient>;
1528	type SlashingHandler = parachains_slashing::SlashValidatorsForDisputes<ParasSlashing>;
1529	type WeightInfo = weights::polkadot_runtime_parachains_disputes::WeightInfo<Runtime>;
1530}
1531
1532impl parachains_slashing::Config for Runtime {
1533	type KeyOwnerProofSystem = Historical;
1534	type KeyOwnerProof =
1535		<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, ValidatorId)>>::Proof;
1536	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
1537		KeyTypeId,
1538		ValidatorId,
1539	)>>::IdentificationTuple;
1540	type HandleReports = parachains_slashing::SlashingReportHandler<
1541		Self::KeyOwnerIdentification,
1542		Offences,
1543		ReportLongevity,
1544	>;
1545	type WeightInfo = weights::polkadot_runtime_parachains_disputes_slashing::WeightInfo<Runtime>;
1546	type BenchmarkingConfig = parachains_slashing::BenchConfig<300>;
1547}
1548
1549parameter_types! {
1550	pub const ParaDeposit: Balance = 2000 * CENTS;
1551	pub const RegistrarDataDepositPerByte: Balance = deposit(0, 1);
1552}
1553
1554impl paras_registrar::Config for Runtime {
1555	type RuntimeOrigin = RuntimeOrigin;
1556	type RuntimeEvent = RuntimeEvent;
1557	type Currency = Balances;
1558	type OnSwap = (Crowdloan, Slots, SwapLeases);
1559	type ParaDeposit = ParaDeposit;
1560	type DataDepositPerByte = RegistrarDataDepositPerByte;
1561	type WeightInfo = weights::polkadot_runtime_common_paras_registrar::WeightInfo<Runtime>;
1562}
1563
1564parameter_types! {
1565	pub const LeasePeriod: BlockNumber = 28 * DAYS;
1566}
1567
1568impl slots::Config for Runtime {
1569	type RuntimeEvent = RuntimeEvent;
1570	type Currency = Balances;
1571	type Registrar = Registrar;
1572	type LeasePeriod = LeasePeriod;
1573	type LeaseOffset = ();
1574	type ForceOrigin = EitherOf<EnsureRoot<Self::AccountId>, LeaseAdmin>;
1575	type WeightInfo = weights::polkadot_runtime_common_slots::WeightInfo<Runtime>;
1576}
1577
1578parameter_types! {
1579	pub const CrowdloanId: PalletId = PalletId(*b"py/cfund");
1580	pub const SubmissionDeposit: Balance = 100 * 100 * CENTS;
1581	pub const MinContribution: Balance = 100 * CENTS;
1582	pub const RemoveKeysLimit: u32 = 500;
1583	// Allow 32 bytes for an additional memo to a crowdloan.
1584	pub const MaxMemoLength: u8 = 32;
1585}
1586
1587impl crowdloan::Config for Runtime {
1588	type RuntimeEvent = RuntimeEvent;
1589	type PalletId = CrowdloanId;
1590	type SubmissionDeposit = SubmissionDeposit;
1591	type MinContribution = MinContribution;
1592	type RemoveKeysLimit = RemoveKeysLimit;
1593	type Registrar = Registrar;
1594	type Auctioneer = Auctions;
1595	type MaxMemoLength = MaxMemoLength;
1596	type WeightInfo = weights::polkadot_runtime_common_crowdloan::WeightInfo<Runtime>;
1597}
1598
1599parameter_types! {
1600	// The average auction is 7 days long, so this will be 70% for ending period.
1601	// 5 Days = 72000 Blocks @ 6 sec per block
1602	pub const EndingPeriod: BlockNumber = 5 * DAYS;
1603	// ~ 1000 samples per day -> ~ 20 blocks per sample -> 2 minute samples
1604	pub const SampleLength: BlockNumber = 2 * MINUTES;
1605}
1606
1607impl auctions::Config for Runtime {
1608	type RuntimeEvent = RuntimeEvent;
1609	type Leaser = Slots;
1610	type Registrar = Registrar;
1611	type EndingPeriod = EndingPeriod;
1612	type SampleLength = SampleLength;
1613	type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
1614	type InitiateOrigin = EitherOf<EnsureRoot<Self::AccountId>, AuctionAdmin>;
1615	type WeightInfo = weights::polkadot_runtime_common_auctions::WeightInfo<Runtime>;
1616}
1617
1618impl identity_migrator::Config for Runtime {
1619	type RuntimeEvent = RuntimeEvent;
1620	type Reaper = EnsureSigned<AccountId>;
1621	type ReapIdentityHandler = ToParachainIdentityReaper<Runtime, Self::AccountId>;
1622	type WeightInfo = weights::polkadot_runtime_common_identity_migrator::WeightInfo<Runtime>;
1623}
1624
1625impl pallet_root_testing::Config for Runtime {
1626	type RuntimeEvent = RuntimeEvent;
1627}
1628
1629parameter_types! {
1630	pub MbmServiceWeight: Weight = Perbill::from_percent(80) * BlockWeights::get().max_block;
1631}
1632
1633impl pallet_migrations::Config for Runtime {
1634	type RuntimeEvent = RuntimeEvent;
1635	#[cfg(not(feature = "runtime-benchmarks"))]
1636	type Migrations = pallet_identity::migration::v2::LazyMigrationV1ToV2<Runtime>;
1637	// Benchmarks need mocked migrations to guarantee that they succeed.
1638	#[cfg(feature = "runtime-benchmarks")]
1639	type Migrations = pallet_migrations::mock_helpers::MockedMigrations;
1640	type CursorMaxLen = ConstU32<65_536>;
1641	type IdentifierMaxLen = ConstU32<256>;
1642	type MigrationStatusHandler = ();
1643	type FailedMigrationHandler = frame_support::migrations::FreezeChainOnFailedMigration;
1644	type MaxServiceWeight = MbmServiceWeight;
1645	type WeightInfo = weights::pallet_migrations::WeightInfo<Runtime>;
1646}
1647
1648parameter_types! {
1649	// 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)
1650	pub const MigrationSignedDepositPerItem: Balance = 1 * CENTS;
1651	pub const MigrationSignedDepositBase: Balance = 20 * CENTS * 100;
1652	pub const MigrationMaxKeyLen: u32 = 512;
1653}
1654
1655impl pallet_asset_rate::Config for Runtime {
1656	type WeightInfo = weights::pallet_asset_rate::WeightInfo<Runtime>;
1657	type RuntimeEvent = RuntimeEvent;
1658	type CreateOrigin = EnsureRoot<AccountId>;
1659	type RemoveOrigin = EnsureRoot<AccountId>;
1660	type UpdateOrigin = EnsureRoot<AccountId>;
1661	type Currency = Balances;
1662	type AssetKind = <Runtime as pallet_treasury::Config>::AssetKind;
1663	#[cfg(feature = "runtime-benchmarks")]
1664	type BenchmarkHelper = polkadot_runtime_common::impls::benchmarks::AssetRateArguments;
1665}
1666
1667// Notify `coretime` pallet when a lease swap occurs
1668pub struct SwapLeases;
1669impl OnSwap for SwapLeases {
1670	fn on_swap(one: ParaId, other: ParaId) {
1671		coretime::Pallet::<Runtime>::on_legacy_lease_swap(one, other);
1672	}
1673}
1674
1675#[frame_support::runtime(legacy_ordering)]
1676mod runtime {
1677	#[runtime::runtime]
1678	#[runtime::derive(
1679		RuntimeCall,
1680		RuntimeEvent,
1681		RuntimeError,
1682		RuntimeOrigin,
1683		RuntimeFreezeReason,
1684		RuntimeHoldReason,
1685		RuntimeSlashReason,
1686		RuntimeLockId,
1687		RuntimeTask,
1688		RuntimeViewFunction
1689	)]
1690	pub struct Runtime;
1691
1692	// Basic stuff; balances is uncallable initially.
1693	#[runtime::pallet_index(0)]
1694	pub type System = frame_system;
1695
1696	// Babe must be before session.
1697	#[runtime::pallet_index(1)]
1698	pub type Babe = pallet_babe;
1699
1700	#[runtime::pallet_index(2)]
1701	pub type Timestamp = pallet_timestamp;
1702	#[runtime::pallet_index(3)]
1703	pub type Indices = pallet_indices;
1704	#[runtime::pallet_index(4)]
1705	pub type Balances = pallet_balances;
1706	#[runtime::pallet_index(26)]
1707	pub type TransactionPayment = pallet_transaction_payment;
1708
1709	// Consensus support.
1710	// Authorship must be before session in order to note author in the correct session and era.
1711	#[runtime::pallet_index(5)]
1712	pub type Authorship = pallet_authorship;
1713	#[runtime::pallet_index(6)]
1714	pub type Staking = pallet_staking;
1715	#[runtime::pallet_index(7)]
1716	pub type Offences = pallet_offences;
1717	#[runtime::pallet_index(27)]
1718	pub type Historical = session_historical;
1719	#[runtime::pallet_index(70)]
1720	pub type Parameters = pallet_parameters;
1721
1722	#[runtime::pallet_index(8)]
1723	pub type Session = pallet_session;
1724	#[runtime::pallet_index(10)]
1725	pub type Grandpa = pallet_grandpa;
1726	#[runtime::pallet_index(12)]
1727	pub type AuthorityDiscovery = pallet_authority_discovery;
1728
1729	// Utility module.
1730	#[runtime::pallet_index(16)]
1731	pub type Utility = pallet_utility;
1732
1733	// Less simple identity module.
1734	#[runtime::pallet_index(17)]
1735	pub type Identity = pallet_identity;
1736
1737	// Social recovery module.
1738	#[runtime::pallet_index(18)]
1739	pub type Recovery = pallet_recovery;
1740
1741	// Vesting. Usable initially, but removed once all vesting is finished.
1742	#[runtime::pallet_index(19)]
1743	pub type Vesting = pallet_vesting;
1744
1745	// System scheduler.
1746	#[runtime::pallet_index(20)]
1747	pub type Scheduler = pallet_scheduler;
1748
1749	// Preimage registrar.
1750	#[runtime::pallet_index(28)]
1751	pub type Preimage = pallet_preimage;
1752
1753	// Sudo.
1754	#[runtime::pallet_index(21)]
1755	pub type Sudo = pallet_sudo;
1756
1757	// Proxy module. Late addition.
1758	#[runtime::pallet_index(22)]
1759	pub type Proxy = pallet_proxy;
1760
1761	// Multisig module. Late addition.
1762	#[runtime::pallet_index(23)]
1763	pub type Multisig = pallet_multisig;
1764
1765	// Election pallet. Only works with staking, but placed here to maintain indices.
1766	#[runtime::pallet_index(24)]
1767	pub type ElectionProviderMultiPhase = pallet_election_provider_multi_phase;
1768
1769	#[runtime::pallet_index(25)]
1770	pub type VoterList = pallet_bags_list<Instance1>;
1771
1772	// OpenGov
1773	#[runtime::pallet_index(31)]
1774	pub type ConvictionVoting = pallet_conviction_voting;
1775	#[runtime::pallet_index(32)]
1776	pub type Referenda = pallet_referenda;
1777	#[runtime::pallet_index(35)]
1778	pub type Origins = pallet_custom_origins;
1779	#[runtime::pallet_index(36)]
1780	pub type Whitelist = pallet_whitelist;
1781
1782	// Treasury
1783	#[runtime::pallet_index(37)]
1784	pub type Treasury = pallet_treasury;
1785
1786	// Parachains pallets. Start indices at 40 to leave room.
1787	#[runtime::pallet_index(41)]
1788	pub type ParachainsOrigin = parachains_origin;
1789	#[runtime::pallet_index(42)]
1790	pub type Configuration = parachains_configuration;
1791	#[runtime::pallet_index(43)]
1792	pub type ParasShared = parachains_shared;
1793	#[runtime::pallet_index(44)]
1794	pub type ParaInclusion = parachains_inclusion;
1795	#[runtime::pallet_index(45)]
1796	pub type ParaInherent = parachains_paras_inherent;
1797	#[runtime::pallet_index(46)]
1798	pub type ParaScheduler = parachains_scheduler;
1799	#[runtime::pallet_index(47)]
1800	pub type Paras = parachains_paras;
1801	#[runtime::pallet_index(48)]
1802	pub type Initializer = parachains_initializer;
1803	#[runtime::pallet_index(49)]
1804	pub type Dmp = parachains_dmp;
1805	// RIP Ump 50
1806	#[runtime::pallet_index(51)]
1807	pub type Hrmp = parachains_hrmp;
1808	#[runtime::pallet_index(52)]
1809	pub type ParaSessionInfo = parachains_session_info;
1810	#[runtime::pallet_index(53)]
1811	pub type ParasDisputes = parachains_disputes;
1812	#[runtime::pallet_index(54)]
1813	pub type ParasSlashing = parachains_slashing;
1814	#[runtime::pallet_index(56)]
1815	pub type OnDemandAssignmentProvider = parachains_on_demand;
1816	#[runtime::pallet_index(57)]
1817	pub type CoretimeAssignmentProvider = parachains_assigner_coretime;
1818
1819	// Parachain Onboarding Pallets. Start indices at 60 to leave room.
1820	#[runtime::pallet_index(60)]
1821	pub type Registrar = paras_registrar;
1822	#[runtime::pallet_index(61)]
1823	pub type Slots = slots;
1824	#[runtime::pallet_index(62)]
1825	pub type ParasSudoWrapper = paras_sudo_wrapper;
1826	#[runtime::pallet_index(63)]
1827	pub type Auctions = auctions;
1828	#[runtime::pallet_index(64)]
1829	pub type Crowdloan = crowdloan;
1830	#[runtime::pallet_index(65)]
1831	pub type AssignedSlots = assigned_slots;
1832	#[runtime::pallet_index(66)]
1833	pub type Coretime = coretime;
1834
1835	#[runtime::pallet_index(67)]
1836	pub type StakingAhClient = pallet_staking_async_ah_client;
1837
1838	// Migrations pallet
1839	#[runtime::pallet_index(98)]
1840	pub type MultiBlockMigrations = pallet_migrations;
1841
1842	// Pallet for sending XCM.
1843	#[runtime::pallet_index(99)]
1844	pub type XcmPallet = pallet_xcm;
1845
1846	// Generalized message queue
1847	#[runtime::pallet_index(100)]
1848	pub type MessageQueue = pallet_message_queue;
1849
1850	// Asset rate.
1851	#[runtime::pallet_index(101)]
1852	pub type AssetRate = pallet_asset_rate;
1853
1854	// Root testing pallet.
1855	#[runtime::pallet_index(102)]
1856	pub type RootTesting = pallet_root_testing;
1857
1858	// BEEFY Bridges support.
1859	#[runtime::pallet_index(200)]
1860	pub type Beefy = pallet_beefy;
1861	// MMR leaf construction must be after session in order to have a leaf's next_auth_set
1862	// refer to block<N>. See issue polkadot-fellows/runtimes#160 for details.
1863	#[runtime::pallet_index(201)]
1864	pub type Mmr = pallet_mmr;
1865	#[runtime::pallet_index(202)]
1866	pub type BeefyMmrLeaf = pallet_beefy_mmr;
1867
1868	// Pallet for migrating Identity to a parachain. To be removed post-migration.
1869	#[runtime::pallet_index(248)]
1870	pub type IdentityMigrator = identity_migrator;
1871}
1872
1873/// The address format for describing accounts.
1874pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
1875/// Block header type as expected by this runtime.
1876pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
1877/// Block type as expected by this runtime.
1878pub type Block = generic::Block<Header, UncheckedExtrinsic>;
1879/// A Block signed with a Justification
1880pub type SignedBlock = generic::SignedBlock<Block>;
1881/// `BlockId` type as expected by this runtime.
1882pub type BlockId = generic::BlockId<Block>;
1883/// The extension to the basic transaction logic.
1884pub type TxExtension = (
1885	frame_system::CheckNonZeroSender<Runtime>,
1886	frame_system::CheckSpecVersion<Runtime>,
1887	frame_system::CheckTxVersion<Runtime>,
1888	frame_system::CheckGenesis<Runtime>,
1889	frame_system::CheckMortality<Runtime>,
1890	frame_system::CheckNonce<Runtime>,
1891	frame_system::CheckWeight<Runtime>,
1892	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
1893	frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
1894	frame_system::WeightReclaim<Runtime>,
1895);
1896
1897parameter_types! {
1898	/// Bounding number of agent pot accounts to be migrated in a single block.
1899	pub const MaxAgentsToMigrate: u32 = 300;
1900}
1901
1902/// All migrations that will run on the next runtime upgrade.
1903///
1904/// This contains the combined migrations of the last 10 releases. It allows to skip runtime
1905/// upgrades in case governance decides to do so. THE ORDER IS IMPORTANT.
1906pub type Migrations = migrations::Unreleased;
1907
1908/// The runtime migrations per release.
1909#[allow(deprecated, missing_docs)]
1910pub mod migrations {
1911	use super::*;
1912
1913	/// Unreleased migrations. Add new ones here:
1914	pub type Unreleased = (
1915		parachains_shared::migration::MigrateToV1<Runtime>,
1916		parachains_scheduler::migration::MigrateV2ToV3<Runtime>,
1917		// permanent
1918		pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,
1919	);
1920}
1921
1922/// Unchecked extrinsic type as expected by this runtime.
1923pub type UncheckedExtrinsic =
1924	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
1925/// Unchecked signature payload type as expected by this runtime.
1926pub type UncheckedSignaturePayload =
1927	generic::UncheckedSignaturePayload<Address, Signature, TxExtension>;
1928
1929/// Executive: handles dispatch to the various modules.
1930pub type Executive = frame_executive::Executive<
1931	Runtime,
1932	Block,
1933	frame_system::ChainContext<Runtime>,
1934	Runtime,
1935	AllPalletsWithSystem,
1936	Migrations,
1937>;
1938/// The payload being signed in transactions.
1939pub type SignedPayload = generic::SignedPayload<RuntimeCall, TxExtension>;
1940
1941#[cfg(feature = "runtime-benchmarks")]
1942mod benches {
1943	frame_benchmarking::define_benchmarks!(
1944		// Polkadot
1945		// NOTE: Make sure to prefix these with `runtime_common::` so
1946		// the that path resolves correctly in the generated file.
1947		[polkadot_runtime_common::assigned_slots, AssignedSlots]
1948		[polkadot_runtime_common::auctions, Auctions]
1949		[polkadot_runtime_common::crowdloan, Crowdloan]
1950		[polkadot_runtime_common::identity_migrator, IdentityMigrator]
1951		[polkadot_runtime_common::paras_registrar, Registrar]
1952		[polkadot_runtime_common::slots, Slots]
1953		[polkadot_runtime_parachains::configuration, Configuration]
1954		[polkadot_runtime_parachains::disputes, ParasDisputes]
1955		[polkadot_runtime_parachains::disputes::slashing, ParasSlashing]
1956		[polkadot_runtime_parachains::hrmp, Hrmp]
1957		[polkadot_runtime_parachains::inclusion, ParaInclusion]
1958		[polkadot_runtime_parachains::initializer, Initializer]
1959		[polkadot_runtime_parachains::paras, Paras]
1960		[polkadot_runtime_parachains::paras_inherent, ParaInherent]
1961		[polkadot_runtime_parachains::on_demand, OnDemandAssignmentProvider]
1962		[polkadot_runtime_parachains::coretime, Coretime]
1963		// Substrate
1964		[pallet_bags_list, VoterList]
1965		[pallet_balances, Balances]
1966		[pallet_beefy_mmr, BeefyMmrLeaf]
1967		[pallet_conviction_voting, ConvictionVoting]
1968		[frame_election_provider_support, ElectionProviderBench::<Runtime>]
1969		[pallet_identity, Identity]
1970		[pallet_indices, Indices]
1971		[pallet_message_queue, MessageQueue]
1972		[pallet_migrations, MultiBlockMigrations]
1973		[pallet_mmr, Mmr]
1974		[pallet_multisig, Multisig]
1975		[pallet_offences, OffencesBench::<Runtime>]
1976		[pallet_parameters, Parameters]
1977		[pallet_preimage, Preimage]
1978		[pallet_proxy, Proxy]
1979		[pallet_recovery, Recovery]
1980		[pallet_referenda, Referenda]
1981		[pallet_scheduler, Scheduler]
1982		[pallet_session, SessionBench::<Runtime>]
1983		[pallet_sudo, Sudo]
1984		[frame_system, SystemBench::<Runtime>]
1985		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
1986		[pallet_timestamp, Timestamp]
1987		[pallet_transaction_payment, TransactionPayment]
1988		[pallet_treasury, Treasury]
1989		[pallet_utility, Utility]
1990		[pallet_vesting, Vesting]
1991		[pallet_whitelist, Whitelist]
1992		[pallet_asset_rate, AssetRate]
1993		// XCM
1994		[pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
1995		// NOTE: Make sure you point to the individual modules below.
1996		[pallet_xcm_benchmarks::fungible, XcmBalances]
1997		[pallet_xcm_benchmarks::generic, XcmGeneric]
1998	);
1999}
2000
2001sp_api::impl_runtime_apis! {
2002	impl sp_api::Core<Block> for Runtime {
2003		fn version() -> RuntimeVersion {
2004			VERSION
2005		}
2006
2007		fn execute_block(block: Block) {
2008			Executive::execute_block(block);
2009		}
2010
2011		fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
2012			Executive::initialize_block(header)
2013		}
2014	}
2015
2016	impl sp_api::Metadata<Block> for Runtime {
2017		fn metadata() -> OpaqueMetadata {
2018			OpaqueMetadata::new(Runtime::metadata().into())
2019		}
2020
2021		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
2022			Runtime::metadata_at_version(version)
2023		}
2024
2025		fn metadata_versions() -> alloc::vec::Vec<u32> {
2026			Runtime::metadata_versions()
2027		}
2028	}
2029
2030	impl frame_support::view_functions::runtime_api::RuntimeViewFunction<Block> for Runtime {
2031		fn execute_view_function(id: frame_support::view_functions::ViewFunctionId, input: Vec<u8>) -> Result<Vec<u8>, frame_support::view_functions::ViewFunctionDispatchError> {
2032			Runtime::execute_view_function(id, input)
2033		}
2034	}
2035
2036	impl sp_block_builder::BlockBuilder<Block> for Runtime {
2037		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
2038			Executive::apply_extrinsic(extrinsic)
2039		}
2040
2041		fn finalize_block() -> <Block as BlockT>::Header {
2042			Executive::finalize_block()
2043		}
2044
2045		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
2046			data.create_extrinsics()
2047		}
2048
2049		fn check_inherents(
2050			block: Block,
2051			data: sp_inherents::InherentData,
2052		) -> sp_inherents::CheckInherentsResult {
2053			data.check_extrinsics(&block)
2054		}
2055	}
2056
2057	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
2058		fn validate_transaction(
2059			source: TransactionSource,
2060			tx: <Block as BlockT>::Extrinsic,
2061			block_hash: <Block as BlockT>::Hash,
2062		) -> TransactionValidity {
2063			Executive::validate_transaction(source, tx, block_hash)
2064		}
2065	}
2066
2067	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
2068		fn offchain_worker(header: &<Block as BlockT>::Header) {
2069			Executive::offchain_worker(header)
2070		}
2071	}
2072
2073	#[api_version(13)]
2074	impl polkadot_primitives::runtime_api::ParachainHost<Block> for Runtime {
2075		fn validators() -> Vec<ValidatorId> {
2076			parachains_runtime_api_impl::validators::<Runtime>()
2077		}
2078
2079		fn validation_code_bomb_limit() -> u32 {
2080			parachains_staging_runtime_api_impl::validation_code_bomb_limit::<Runtime>()
2081		}
2082
2083		fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>) {
2084			parachains_runtime_api_impl::validator_groups::<Runtime>()
2085		}
2086
2087		fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>> {
2088			parachains_runtime_api_impl::availability_cores::<Runtime>()
2089		}
2090
2091		fn persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption)
2092			-> Option<PersistedValidationData<Hash, BlockNumber>> {
2093			parachains_runtime_api_impl::persisted_validation_data::<Runtime>(para_id, assumption)
2094		}
2095
2096		fn assumed_validation_data(
2097			para_id: ParaId,
2098			expected_persisted_validation_data_hash: Hash,
2099		) -> Option<(PersistedValidationData<Hash, BlockNumber>, ValidationCodeHash)> {
2100			parachains_runtime_api_impl::assumed_validation_data::<Runtime>(
2101				para_id,
2102				expected_persisted_validation_data_hash,
2103			)
2104		}
2105
2106		fn check_validation_outputs(
2107			para_id: ParaId,
2108			outputs: polkadot_primitives::CandidateCommitments,
2109		) -> bool {
2110			parachains_runtime_api_impl::check_validation_outputs::<Runtime>(para_id, outputs)
2111		}
2112
2113		fn session_index_for_child() -> SessionIndex {
2114			parachains_runtime_api_impl::session_index_for_child::<Runtime>()
2115		}
2116
2117		fn validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption)
2118			-> Option<ValidationCode> {
2119			parachains_runtime_api_impl::validation_code::<Runtime>(para_id, assumption)
2120		}
2121
2122		fn candidate_pending_availability(para_id: ParaId) -> Option<CommittedCandidateReceipt<Hash>> {
2123			#[allow(deprecated)]
2124			parachains_runtime_api_impl::candidate_pending_availability::<Runtime>(para_id)
2125		}
2126
2127		fn candidate_events() -> Vec<CandidateEvent<Hash>> {
2128			parachains_runtime_api_impl::candidate_events::<Runtime, _>(|ev| {
2129				match ev {
2130					RuntimeEvent::ParaInclusion(ev) => {
2131						Some(ev)
2132					}
2133					_ => None,
2134				}
2135			})
2136		}
2137
2138		fn session_info(index: SessionIndex) -> Option<SessionInfo> {
2139			parachains_runtime_api_impl::session_info::<Runtime>(index)
2140		}
2141
2142		fn session_executor_params(session_index: SessionIndex) -> Option<ExecutorParams> {
2143			parachains_runtime_api_impl::session_executor_params::<Runtime>(session_index)
2144		}
2145
2146		fn dmq_contents(recipient: ParaId) -> Vec<InboundDownwardMessage<BlockNumber>> {
2147			parachains_runtime_api_impl::dmq_contents::<Runtime>(recipient)
2148		}
2149
2150		fn inbound_hrmp_channels_contents(
2151			recipient: ParaId
2152		) -> BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>> {
2153			parachains_runtime_api_impl::inbound_hrmp_channels_contents::<Runtime>(recipient)
2154		}
2155
2156		fn validation_code_by_hash(hash: ValidationCodeHash) -> Option<ValidationCode> {
2157			parachains_runtime_api_impl::validation_code_by_hash::<Runtime>(hash)
2158		}
2159
2160		fn on_chain_votes() -> Option<ScrapedOnChainVotes<Hash>> {
2161			parachains_runtime_api_impl::on_chain_votes::<Runtime>()
2162		}
2163
2164		fn submit_pvf_check_statement(
2165			stmt: PvfCheckStatement,
2166			signature: ValidatorSignature,
2167		) {
2168			parachains_runtime_api_impl::submit_pvf_check_statement::<Runtime>(stmt, signature)
2169		}
2170
2171		fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
2172			parachains_runtime_api_impl::pvfs_require_precheck::<Runtime>()
2173		}
2174
2175		fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption)
2176			-> Option<ValidationCodeHash>
2177		{
2178			parachains_runtime_api_impl::validation_code_hash::<Runtime>(para_id, assumption)
2179		}
2180
2181		fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)> {
2182			parachains_runtime_api_impl::get_session_disputes::<Runtime>()
2183		}
2184
2185		fn unapplied_slashes(
2186		) -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)> {
2187			parachains_runtime_api_impl::unapplied_slashes::<Runtime>()
2188		}
2189
2190		fn key_ownership_proof(
2191			validator_id: ValidatorId,
2192		) -> Option<slashing::OpaqueKeyOwnershipProof> {
2193			use codec::Encode;
2194
2195			Historical::prove((PARACHAIN_KEY_TYPE_ID, validator_id))
2196				.map(|p| p.encode())
2197				.map(slashing::OpaqueKeyOwnershipProof::new)
2198		}
2199
2200		fn submit_report_dispute_lost(
2201			dispute_proof: slashing::DisputeProof,
2202			key_ownership_proof: slashing::OpaqueKeyOwnershipProof,
2203		) -> Option<()> {
2204			parachains_runtime_api_impl::submit_unsigned_slashing_report::<Runtime>(
2205				dispute_proof,
2206				key_ownership_proof,
2207			)
2208		}
2209
2210		fn minimum_backing_votes() -> u32 {
2211			parachains_runtime_api_impl::minimum_backing_votes::<Runtime>()
2212		}
2213
2214		fn para_backing_state(para_id: ParaId) -> Option<polkadot_primitives::vstaging::async_backing::BackingState> {
2215			#[allow(deprecated)]
2216			parachains_runtime_api_impl::backing_state::<Runtime>(para_id)
2217		}
2218
2219		fn async_backing_params() -> polkadot_primitives::AsyncBackingParams {
2220			#[allow(deprecated)]
2221			parachains_runtime_api_impl::async_backing_params::<Runtime>()
2222		}
2223
2224		fn approval_voting_params() -> ApprovalVotingParams {
2225			parachains_runtime_api_impl::approval_voting_params::<Runtime>()
2226		}
2227
2228		fn disabled_validators() -> Vec<ValidatorIndex> {
2229			parachains_runtime_api_impl::disabled_validators::<Runtime>()
2230		}
2231
2232		fn node_features() -> NodeFeatures {
2233			parachains_runtime_api_impl::node_features::<Runtime>()
2234		}
2235
2236		fn claim_queue() -> BTreeMap<CoreIndex, VecDeque<ParaId>> {
2237			parachains_runtime_api_impl::claim_queue::<Runtime>()
2238		}
2239
2240		fn candidates_pending_availability(para_id: ParaId) -> Vec<CommittedCandidateReceipt<Hash>> {
2241			parachains_runtime_api_impl::candidates_pending_availability::<Runtime>(para_id)
2242		}
2243
2244		fn backing_constraints(para_id: ParaId) -> Option<Constraints> {
2245			parachains_staging_runtime_api_impl::backing_constraints::<Runtime>(para_id)
2246		}
2247
2248		fn scheduling_lookahead() -> u32 {
2249			parachains_staging_runtime_api_impl::scheduling_lookahead::<Runtime>()
2250		}
2251	}
2252
2253	#[api_version(5)]
2254	impl sp_consensus_beefy::BeefyApi<Block, BeefyId> for Runtime {
2255		fn beefy_genesis() -> Option<BlockNumber> {
2256			pallet_beefy::GenesisBlock::<Runtime>::get()
2257		}
2258
2259		fn validator_set() -> Option<sp_consensus_beefy::ValidatorSet<BeefyId>> {
2260			Beefy::validator_set()
2261		}
2262
2263		fn submit_report_double_voting_unsigned_extrinsic(
2264			equivocation_proof: sp_consensus_beefy::DoubleVotingProof<
2265				BlockNumber,
2266				BeefyId,
2267				BeefySignature,
2268			>,
2269			key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof,
2270		) -> Option<()> {
2271			let key_owner_proof = key_owner_proof.decode()?;
2272
2273			Beefy::submit_unsigned_double_voting_report(
2274				equivocation_proof,
2275				key_owner_proof,
2276			)
2277		}
2278
2279		fn submit_report_fork_voting_unsigned_extrinsic(
2280			equivocation_proof:
2281				sp_consensus_beefy::ForkVotingProof<
2282					<Block as BlockT>::Header,
2283					BeefyId,
2284					sp_runtime::OpaqueValue
2285				>,
2286			key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof,
2287		) -> Option<()> {
2288			Beefy::submit_unsigned_fork_voting_report(
2289				equivocation_proof.try_into()?,
2290				key_owner_proof.decode()?,
2291			)
2292		}
2293
2294		fn submit_report_future_block_voting_unsigned_extrinsic(
2295			equivocation_proof: sp_consensus_beefy::FutureBlockVotingProof<BlockNumber, BeefyId>,
2296			key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof,
2297		) -> Option<()> {
2298			Beefy::submit_unsigned_future_block_voting_report(
2299				equivocation_proof,
2300				key_owner_proof.decode()?,
2301			)
2302		}
2303
2304		fn generate_key_ownership_proof(
2305			_set_id: sp_consensus_beefy::ValidatorSetId,
2306			authority_id: BeefyId,
2307		) -> Option<sp_consensus_beefy::OpaqueKeyOwnershipProof> {
2308			use codec::Encode;
2309
2310			Historical::prove((sp_consensus_beefy::KEY_TYPE, authority_id))
2311				.map(|p| p.encode())
2312				.map(sp_consensus_beefy::OpaqueKeyOwnershipProof::new)
2313		}
2314
2315		fn generate_ancestry_proof(
2316			prev_block_number: BlockNumber,
2317			best_known_block_number: Option<BlockNumber>,
2318		) -> Option<sp_runtime::OpaqueValue> {
2319			use sp_consensus_beefy::AncestryHelper;
2320
2321			BeefyMmrLeaf::generate_proof(prev_block_number, best_known_block_number)
2322				.map(|p| p.encode())
2323				.map(sp_runtime::OpaqueValue::new)
2324		}
2325	}
2326
2327	impl mmr::MmrApi<Block, Hash, BlockNumber> for Runtime {
2328		fn mmr_root() -> Result<mmr::Hash, mmr::Error> {
2329			Ok(pallet_mmr::RootHash::<Runtime>::get())
2330		}
2331
2332		fn mmr_leaf_count() -> Result<mmr::LeafIndex, mmr::Error> {
2333			Ok(pallet_mmr::NumberOfLeaves::<Runtime>::get())
2334		}
2335
2336		fn generate_proof(
2337			block_numbers: Vec<BlockNumber>,
2338			best_known_block_number: Option<BlockNumber>,
2339		) -> Result<(Vec<mmr::EncodableOpaqueLeaf>, mmr::LeafProof<mmr::Hash>), mmr::Error> {
2340			Mmr::generate_proof(block_numbers, best_known_block_number).map(
2341				|(leaves, proof)| {
2342					(
2343						leaves
2344							.into_iter()
2345							.map(|leaf| mmr::EncodableOpaqueLeaf::from_leaf(&leaf))
2346							.collect(),
2347						proof,
2348					)
2349				},
2350			)
2351		}
2352
2353		fn verify_proof(leaves: Vec<mmr::EncodableOpaqueLeaf>, proof: mmr::LeafProof<mmr::Hash>)
2354			-> Result<(), mmr::Error>
2355		{
2356			let leaves = leaves.into_iter().map(|leaf|
2357				leaf.into_opaque_leaf()
2358				.try_decode()
2359				.ok_or(mmr::Error::Verify)).collect::<Result<Vec<mmr::Leaf>, mmr::Error>>()?;
2360			Mmr::verify_leaves(leaves, proof)
2361		}
2362
2363		fn verify_proof_stateless(
2364			root: mmr::Hash,
2365			leaves: Vec<mmr::EncodableOpaqueLeaf>,
2366			proof: mmr::LeafProof<mmr::Hash>
2367		) -> Result<(), mmr::Error> {
2368			let nodes = leaves.into_iter().map(|leaf|mmr::DataOrHash::Data(leaf.into_opaque_leaf())).collect();
2369			pallet_mmr::verify_leaves_proof::<mmr::Hashing, _>(root, nodes, proof)
2370		}
2371	}
2372
2373	impl pallet_beefy_mmr::BeefyMmrApi<Block, Hash> for RuntimeApi {
2374		fn authority_set_proof() -> sp_consensus_beefy::mmr::BeefyAuthoritySet<Hash> {
2375			BeefyMmrLeaf::authority_set_proof()
2376		}
2377
2378		fn next_authority_set_proof() -> sp_consensus_beefy::mmr::BeefyNextAuthoritySet<Hash> {
2379			BeefyMmrLeaf::next_authority_set_proof()
2380		}
2381	}
2382
2383	impl fg_primitives::GrandpaApi<Block> for Runtime {
2384		fn grandpa_authorities() -> Vec<(GrandpaId, u64)> {
2385			Grandpa::grandpa_authorities()
2386		}
2387
2388		fn current_set_id() -> fg_primitives::SetId {
2389			pallet_grandpa::CurrentSetId::<Runtime>::get()
2390		}
2391
2392		fn submit_report_equivocation_unsigned_extrinsic(
2393			equivocation_proof: fg_primitives::EquivocationProof<
2394				<Block as BlockT>::Hash,
2395				sp_runtime::traits::NumberFor<Block>,
2396			>,
2397			key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,
2398		) -> Option<()> {
2399			let key_owner_proof = key_owner_proof.decode()?;
2400
2401			Grandpa::submit_unsigned_equivocation_report(
2402				equivocation_proof,
2403				key_owner_proof,
2404			)
2405		}
2406
2407		fn generate_key_ownership_proof(
2408			_set_id: fg_primitives::SetId,
2409			authority_id: fg_primitives::AuthorityId,
2410		) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {
2411			use codec::Encode;
2412
2413			Historical::prove((fg_primitives::KEY_TYPE, authority_id))
2414				.map(|p| p.encode())
2415				.map(fg_primitives::OpaqueKeyOwnershipProof::new)
2416		}
2417	}
2418
2419	impl sp_consensus_babe::BabeApi<Block> for Runtime {
2420		fn configuration() -> sp_consensus_babe::BabeConfiguration {
2421			let epoch_config = Babe::epoch_config().unwrap_or(BABE_GENESIS_EPOCH_CONFIG);
2422			sp_consensus_babe::BabeConfiguration {
2423				slot_duration: Babe::slot_duration(),
2424				epoch_length: EpochDuration::get(),
2425				c: epoch_config.c,
2426				authorities: Babe::authorities().to_vec(),
2427				randomness: Babe::randomness(),
2428				allowed_slots: epoch_config.allowed_slots,
2429			}
2430		}
2431
2432		fn current_epoch_start() -> sp_consensus_babe::Slot {
2433			Babe::current_epoch_start()
2434		}
2435
2436		fn current_epoch() -> sp_consensus_babe::Epoch {
2437			Babe::current_epoch()
2438		}
2439
2440		fn next_epoch() -> sp_consensus_babe::Epoch {
2441			Babe::next_epoch()
2442		}
2443
2444		fn generate_key_ownership_proof(
2445			_slot: sp_consensus_babe::Slot,
2446			authority_id: sp_consensus_babe::AuthorityId,
2447		) -> Option<sp_consensus_babe::OpaqueKeyOwnershipProof> {
2448			use codec::Encode;
2449
2450			Historical::prove((sp_consensus_babe::KEY_TYPE, authority_id))
2451				.map(|p| p.encode())
2452				.map(sp_consensus_babe::OpaqueKeyOwnershipProof::new)
2453		}
2454
2455		fn submit_report_equivocation_unsigned_extrinsic(
2456			equivocation_proof: sp_consensus_babe::EquivocationProof<<Block as BlockT>::Header>,
2457			key_owner_proof: sp_consensus_babe::OpaqueKeyOwnershipProof,
2458		) -> Option<()> {
2459			let key_owner_proof = key_owner_proof.decode()?;
2460
2461			Babe::submit_unsigned_equivocation_report(
2462				equivocation_proof,
2463				key_owner_proof,
2464			)
2465		}
2466	}
2467
2468	impl sp_authority_discovery::AuthorityDiscoveryApi<Block> for Runtime {
2469		fn authorities() -> Vec<AuthorityDiscoveryId> {
2470			parachains_runtime_api_impl::relevant_authority_ids::<Runtime>()
2471		}
2472	}
2473
2474	impl sp_session::SessionKeys<Block> for Runtime {
2475		fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
2476			SessionKeys::generate(seed)
2477		}
2478
2479		fn decode_session_keys(
2480			encoded: Vec<u8>,
2481		) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
2482			SessionKeys::decode_into_raw_public_keys(&encoded)
2483		}
2484	}
2485
2486	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
2487		fn account_nonce(account: AccountId) -> Nonce {
2488			System::account_nonce(account)
2489		}
2490	}
2491
2492	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
2493		Block,
2494		Balance,
2495	> for Runtime {
2496		fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
2497			TransactionPayment::query_info(uxt, len)
2498		}
2499		fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {
2500			TransactionPayment::query_fee_details(uxt, len)
2501		}
2502		fn query_weight_to_fee(weight: Weight) -> Balance {
2503			TransactionPayment::weight_to_fee(weight)
2504		}
2505		fn query_length_to_fee(length: u32) -> Balance {
2506			TransactionPayment::length_to_fee(length)
2507		}
2508	}
2509
2510	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
2511		for Runtime
2512	{
2513		fn query_call_info(call: RuntimeCall, len: u32) -> RuntimeDispatchInfo<Balance> {
2514			TransactionPayment::query_call_info(call, len)
2515		}
2516		fn query_call_fee_details(call: RuntimeCall, len: u32) -> FeeDetails<Balance> {
2517			TransactionPayment::query_call_fee_details(call, len)
2518		}
2519		fn query_weight_to_fee(weight: Weight) -> Balance {
2520			TransactionPayment::weight_to_fee(weight)
2521		}
2522		fn query_length_to_fee(length: u32) -> Balance {
2523			TransactionPayment::length_to_fee(length)
2524		}
2525	}
2526
2527	impl xcm_runtime_apis::fees::XcmPaymentApi<Block> for Runtime {
2528		fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
2529			let acceptable_assets = vec![AssetId(xcm_config::TokenLocation::get())];
2530			XcmPallet::query_acceptable_payment_assets(xcm_version, acceptable_assets)
2531		}
2532
2533		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
2534			let latest_asset_id: Result<AssetId, ()> = asset.clone().try_into();
2535			match latest_asset_id {
2536				Ok(asset_id) if asset_id.0 == xcm_config::TokenLocation::get() => {
2537					// for native token
2538					Ok(WeightToFee::weight_to_fee(&weight))
2539				},
2540				Ok(asset_id) => {
2541					log::trace!(target: "xcm::xcm_runtime_apis", "query_weight_to_asset_fee - unhandled asset_id: {asset_id:?}!");
2542					Err(XcmPaymentApiError::AssetNotFound)
2543				},
2544				Err(_) => {
2545					log::trace!(target: "xcm::xcm_runtime_apis", "query_weight_to_asset_fee - failed to convert asset: {asset:?}!");
2546					Err(XcmPaymentApiError::VersionedConversionFailed)
2547				}
2548			}
2549		}
2550
2551		fn query_xcm_weight(message: VersionedXcm<()>) -> Result<Weight, XcmPaymentApiError> {
2552			XcmPallet::query_xcm_weight(message)
2553		}
2554
2555		fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result<VersionedAssets, XcmPaymentApiError> {
2556			XcmPallet::query_delivery_fees(destination, message)
2557		}
2558	}
2559
2560	impl xcm_runtime_apis::dry_run::DryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
2561		fn dry_run_call(origin: OriginCaller, call: RuntimeCall, result_xcms_version: xcm::prelude::XcmVersion) -> Result<CallDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
2562			XcmPallet::dry_run_call::<Runtime, xcm_config::XcmRouter, OriginCaller, RuntimeCall>(origin, call, result_xcms_version)
2563		}
2564
2565		fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
2566			XcmPallet::dry_run_xcm::<Runtime, xcm_config::XcmRouter, RuntimeCall, xcm_config::XcmConfig>(origin_location, xcm)
2567		}
2568	}
2569
2570	impl xcm_runtime_apis::conversions::LocationToAccountApi<Block, AccountId> for Runtime {
2571		fn convert_location(location: VersionedLocation) -> Result<
2572			AccountId,
2573			xcm_runtime_apis::conversions::Error
2574		> {
2575			xcm_runtime_apis::conversions::LocationToAccountHelper::<
2576				AccountId,
2577				xcm_config::LocationConverter,
2578			>::convert_location(location)
2579		}
2580	}
2581
2582	#[cfg(feature = "try-runtime")]
2583	impl frame_try_runtime::TryRuntime<Block> for Runtime {
2584		fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
2585			log::info!("try-runtime::on_runtime_upgrade westend.");
2586			let weight = Executive::try_runtime_upgrade(checks).unwrap();
2587			(weight, BlockWeights::get().max_block)
2588		}
2589
2590		fn execute_block(
2591			block: Block,
2592			state_root_check: bool,
2593			signature_check: bool,
2594			select: frame_try_runtime::TryStateSelect,
2595		) -> Weight {
2596			// NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
2597			// have a backtrace here.
2598			Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()
2599		}
2600	}
2601
2602	#[cfg(feature = "runtime-benchmarks")]
2603	impl frame_benchmarking::Benchmark<Block> for Runtime {
2604		fn benchmark_metadata(extra: bool) -> (
2605			Vec<frame_benchmarking::BenchmarkList>,
2606			Vec<frame_support::traits::StorageInfo>,
2607		) {
2608			use frame_benchmarking::BenchmarkList;
2609			use frame_support::traits::StorageInfoTrait;
2610
2611			use pallet_session_benchmarking::Pallet as SessionBench;
2612			use pallet_offences_benchmarking::Pallet as OffencesBench;
2613			use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench;
2614			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
2615			use frame_system_benchmarking::Pallet as SystemBench;
2616			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
2617
2618			type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
2619			type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::<Runtime>;
2620
2621			let mut list = Vec::<BenchmarkList>::new();
2622			list_benchmarks!(list, extra);
2623
2624			let storage_info = AllPalletsWithSystem::storage_info();
2625			return (list, storage_info)
2626		}
2627
2628		#[allow(non_local_definitions)]
2629		fn dispatch_benchmark(
2630			config: frame_benchmarking::BenchmarkConfig,
2631		) -> Result<
2632			Vec<frame_benchmarking::BenchmarkBatch>,
2633			alloc::string::String,
2634		> {
2635			use frame_support::traits::WhitelistedStorageKeys;
2636			use frame_benchmarking::{BenchmarkBatch, BenchmarkError};
2637			use sp_storage::TrackedStorageKey;
2638			// Trying to add benchmarks directly to some pallets caused cyclic dependency issues.
2639			// To get around that, we separated the benchmarks into its own crate.
2640			use pallet_session_benchmarking::Pallet as SessionBench;
2641			use pallet_offences_benchmarking::Pallet as OffencesBench;
2642			use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench;
2643			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
2644			use frame_system_benchmarking::Pallet as SystemBench;
2645			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
2646
2647			impl pallet_session_benchmarking::Config for Runtime {}
2648			impl pallet_offences_benchmarking::Config for Runtime {}
2649			impl pallet_election_provider_support_benchmarking::Config for Runtime {}
2650
2651			use xcm_config::{AssetHub, TokenLocation};
2652
2653			use alloc::boxed::Box;
2654
2655			parameter_types! {
2656				pub ExistentialDepositAsset: Option<Asset> = Some((
2657					TokenLocation::get(),
2658					ExistentialDeposit::get()
2659				).into());
2660				pub AssetHubParaId: ParaId = pallet_staking_async_rc_runtime_constants::system_parachain::ASSET_HUB_ID.into();
2661				pub const RandomParaId: ParaId = ParaId::new(43211234);
2662			}
2663
2664			impl pallet_xcm::benchmarking::Config for Runtime {
2665				type DeliveryHelper = (
2666					polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
2667						xcm_config::XcmConfig,
2668						ExistentialDepositAsset,
2669						xcm_config::PriceForChildParachainDelivery,
2670						AssetHubParaId,
2671						Dmp,
2672					>,
2673					polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
2674						xcm_config::XcmConfig,
2675						ExistentialDepositAsset,
2676						xcm_config::PriceForChildParachainDelivery,
2677						RandomParaId,
2678						Dmp,
2679					>
2680				);
2681
2682				fn reachable_dest() -> Option<Location> {
2683					Some(crate::xcm_config::AssetHub::get())
2684				}
2685
2686				fn teleportable_asset_and_dest() -> Option<(Asset, Location)> {
2687					// Relay/native token can be teleported to/from AH.
2688					Some((
2689						Asset { fun: Fungible(ExistentialDeposit::get()), id: AssetId(Here.into()) },
2690						crate::xcm_config::AssetHub::get(),
2691					))
2692				}
2693
2694				fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
2695					// Relay can reserve transfer native token to some random parachain.
2696					Some((
2697						Asset {
2698							fun: Fungible(ExistentialDeposit::get()),
2699							id: AssetId(Here.into())
2700						},
2701						crate::Junction::Parachain(RandomParaId::get().into()).into(),
2702					))
2703				}
2704
2705				fn set_up_complex_asset_transfer(
2706				) -> Option<(Assets, u32, Location, Box<dyn FnOnce()>)> {
2707					// Relay supports only native token, either reserve transfer it to non-system parachains,
2708					// or teleport it to system parachain. Use the teleport case for benchmarking as it's
2709					// slightly heavier.
2710
2711					// Relay/native token can be teleported to/from AH.
2712					let native_location = Here.into();
2713					let dest = crate::xcm_config::AssetHub::get();
2714					pallet_xcm::benchmarking::helpers::native_teleport_as_asset_transfer::<Runtime>(
2715						native_location,
2716						dest
2717					)
2718				}
2719
2720				fn get_asset() -> Asset {
2721					Asset {
2722						id: AssetId(Location::here()),
2723						fun: Fungible(ExistentialDeposit::get()),
2724					}
2725				}
2726			}
2727			impl frame_system_benchmarking::Config for Runtime {}
2728			impl polkadot_runtime_parachains::disputes::slashing::benchmarking::Config for Runtime {}
2729
2730			use xcm::latest::{
2731				AssetId, Fungibility::*, InteriorLocation, Junction, Junctions::*,
2732				Asset, Assets, Location, NetworkId, Response,
2733			};
2734
2735			impl pallet_xcm_benchmarks::Config for Runtime {
2736				type XcmConfig = xcm_config::XcmConfig;
2737				type AccountIdConverter = xcm_config::LocationConverter;
2738				type DeliveryHelper = polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
2739					xcm_config::XcmConfig,
2740					ExistentialDepositAsset,
2741					xcm_config::PriceForChildParachainDelivery,
2742					AssetHubParaId,
2743					Dmp,
2744				>;
2745				fn valid_destination() -> Result<Location, BenchmarkError> {
2746					Ok(AssetHub::get())
2747				}
2748				fn worst_case_holding(_depositable_count: u32) -> Assets {
2749					// Westend only knows about WND.
2750					vec![Asset{
2751						id: AssetId(TokenLocation::get()),
2752						fun: Fungible(1_000_000 * UNITS),
2753					}].into()
2754				}
2755			}
2756
2757			parameter_types! {
2758				pub TrustedTeleporter: Option<(Location, Asset)> = Some((
2759					AssetHub::get(),
2760					Asset { fun: Fungible(1 * UNITS), id: AssetId(TokenLocation::get()) },
2761				));
2762				pub const TrustedReserve: Option<(Location, Asset)> = None;
2763			}
2764
2765			impl pallet_xcm_benchmarks::fungible::Config for Runtime {
2766				type TransactAsset = Balances;
2767
2768				type CheckedAccount = xcm_config::LocalCheckAccount;
2769				type TrustedTeleporter = TrustedTeleporter;
2770				type TrustedReserve = TrustedReserve;
2771
2772				fn get_asset() -> Asset {
2773					Asset {
2774						id: AssetId(TokenLocation::get()),
2775						fun: Fungible(1 * UNITS),
2776					}
2777				}
2778			}
2779
2780			impl pallet_xcm_benchmarks::generic::Config for Runtime {
2781				type TransactAsset = Balances;
2782				type RuntimeCall = RuntimeCall;
2783
2784				fn worst_case_response() -> (u64, Response) {
2785					(0u64, Response::Version(Default::default()))
2786				}
2787
2788				fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> {
2789					// Westend doesn't support asset exchanges
2790					Err(BenchmarkError::Skip)
2791				}
2792
2793				fn universal_alias() -> Result<(Location, Junction), BenchmarkError> {
2794					// The XCM executor of Westend doesn't have a configured `UniversalAliases`
2795					Err(BenchmarkError::Skip)
2796				}
2797
2798				fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> {
2799					Ok((AssetHub::get(), frame_system::Call::remark_with_event { remark: vec![] }.into()))
2800				}
2801
2802				fn subscribe_origin() -> Result<Location, BenchmarkError> {
2803					Ok(AssetHub::get())
2804				}
2805
2806				fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> {
2807					let origin = AssetHub::get();
2808					let assets: Assets = (AssetId(TokenLocation::get()), 1_000 * UNITS).into();
2809					let ticket = Location { parents: 0, interior: Here };
2810					Ok((origin, ticket, assets))
2811				}
2812
2813				fn worst_case_for_trader() -> Result<(Asset, WeightLimit), BenchmarkError> {
2814					Ok((Asset {
2815						id: AssetId(TokenLocation::get()),
2816						fun: Fungible(1_000_000 * UNITS),
2817					}, WeightLimit::Limited(Weight::from_parts(5000, 5000))))
2818				}
2819
2820				fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> {
2821					// Westend doesn't support asset locking
2822					Err(BenchmarkError::Skip)
2823				}
2824
2825				fn export_message_origin_and_destination(
2826				) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> {
2827					// Westend doesn't support exporting messages
2828					Err(BenchmarkError::Skip)
2829				}
2830
2831				fn alias_origin() -> Result<(Location, Location), BenchmarkError> {
2832					let origin = Location::new(0, [Parachain(1000)]);
2833					let target = Location::new(0, [Parachain(1000), AccountId32 { id: [128u8; 32], network: None }]);
2834					Ok((origin, target))
2835				}
2836			}
2837
2838			type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
2839			type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::<Runtime>;
2840
2841			let whitelist: Vec<TrackedStorageKey> = AllPalletsWithSystem::whitelisted_storage_keys();
2842
2843			let mut batches = Vec::<BenchmarkBatch>::new();
2844			let params = (&config, &whitelist);
2845
2846			add_benchmarks!(params, batches);
2847
2848			Ok(batches)
2849		}
2850	}
2851
2852	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
2853		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
2854			build_state::<RuntimeGenesisConfig>(config)
2855		}
2856
2857		fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
2858			get_preset::<RuntimeGenesisConfig>(id, &genesis_config_presets::get_preset)
2859		}
2860
2861		fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
2862			genesis_config_presets::preset_names()
2863		}
2864	}
2865
2866	impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
2867		fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
2868			XcmPallet::is_trusted_reserve(asset, location)
2869		}
2870		fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
2871			XcmPallet::is_trusted_teleporter(asset, location)
2872		}
2873	}
2874}