contracts_parachain_runtime/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
3#![recursion_limit = "256"]
4
5// Make the WASM binary available.
6#[cfg(feature = "std")]
7include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
8
9mod assets_config;
10mod contracts_config;
11mod revive_config;
12mod weights;
13mod xcm_config;
14
15extern crate alloc;
16
17use alloc::vec::Vec;
18use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases;
19use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery;
20use smallvec::smallvec;
21use sp_api::impl_runtime_apis;
22use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
23use sp_runtime::{
24	create_runtime_str, generic, impl_opaque_keys,
25	traits::{BlakeTwo256, Block as BlockT, IdentifyAccount, Verify},
26	transaction_validity::{TransactionSource, TransactionValidity},
27	ApplyExtrinsicResult, MultiSignature,
28};
29
30use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
31use frame_support::{
32	derive_impl,
33	dispatch::DispatchClass,
34	genesis_builder_helper::{build_state, get_preset},
35	parameter_types,
36	traits::{ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, TransformOrigin},
37	weights::{
38		constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, Weight, WeightToFeeCoefficient,
39		WeightToFeeCoefficients, WeightToFeePolynomial,
40	},
41	PalletId,
42};
43use frame_system::{
44	limits::{BlockLength, BlockWeights},
45	EnsureRoot,
46};
47use pallet_xcm::{EnsureXcm, IsVoiceOfBody};
48use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling};
49pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
50pub use sp_runtime::{MultiAddress, Perbill, Permill};
51#[cfg(feature = "std")]
52use sp_version::NativeVersion;
53use sp_version::RuntimeVersion;
54use xcm_config::{RelayLocation, XcmOriginToTransactDispatchOrigin};
55
56#[cfg(any(feature = "std", test))]
57pub use sp_runtime::BuildStorage;
58
59// Polkadot imports
60use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
61
62use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};
63
64// XCM Imports
65use xcm::latest::prelude::BodyId;
66
67/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
68pub type Signature = MultiSignature;
69
70/// Some way of identifying an account on the chain. We intentionally make it equivalent
71/// to the public key of our transaction signing scheme.
72pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
73
74/// Balance of an account.
75pub type Balance = u128;
76
77/// Index of a transaction in the chain.
78pub type Nonce = u32;
79
80/// A hash of some data used by the chain.
81pub type Hash = sp_core::H256;
82
83/// An index to a block.
84pub type BlockNumber = u32;
85
86/// The address format for describing accounts.
87pub type Address = MultiAddress<AccountId, ()>;
88
89/// Block header type as expected by this runtime.
90pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
91
92/// Block type as expected by this runtime.
93pub type Block = generic::Block<Header, UncheckedExtrinsic>;
94
95/// A Block signed with a Justification
96pub type SignedBlock = generic::SignedBlock<Block>;
97
98/// BlockId type as expected by this runtime.
99pub type BlockId = generic::BlockId<Block>;
100
101type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
102	Runtime,
103	RELAY_CHAIN_SLOT_DURATION_MILLIS,
104	BLOCK_PROCESSING_VELOCITY,
105	UNINCLUDED_SEGMENT_CAPACITY,
106>;
107
108/// The SignedExtension to the basic transaction logic.
109pub type SignedExtra = (
110	frame_system::CheckNonZeroSender<Runtime>,
111	frame_system::CheckSpecVersion<Runtime>,
112	frame_system::CheckTxVersion<Runtime>,
113	frame_system::CheckGenesis<Runtime>,
114	frame_system::CheckEra<Runtime>,
115	frame_system::CheckNonce<Runtime>,
116	frame_system::CheckWeight<Runtime>,
117	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
118);
119
120/// Unchecked extrinsic type as expected by this runtime.
121pub type UncheckedExtrinsic =
122	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
123
124/// Executive: handles dispatch to the various modules.
125pub type Executive = frame_executive::Executive<
126	Runtime,
127	Block,
128	frame_system::ChainContext<Runtime>,
129	Runtime,
130	AllPalletsWithSystem,
131>;
132
133/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the
134/// node's balance type.
135///
136/// This should typically create a mapping between the following ranges:
137///   - `[0, MAXIMUM_BLOCK_WEIGHT]`
138///   - `[Balance::min, Balance::max]`
139///
140/// Yet, it can be used for any other sort of change to weight-fee. Some examples being:
141///   - Setting it to `0` will essentially disable the weight fee.
142///   - Setting it to `1` will cause the literal `#[weight = x]` values to be charged.
143pub struct WeightToFee;
144impl WeightToFeePolynomial for WeightToFee {
145	type Balance = Balance;
146	fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
147		// in Rococo, extrinsic base weight (smallest non-zero weight) is mapped to 1 MILLIUNIT:
148		// We map to 1/10 of that, or 1/10 MILLIUNIT
149		let p = MILLIUNIT / 10;
150		let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
151		smallvec![WeightToFeeCoefficient {
152			degree: 1,
153			negative: false,
154			coeff_frac: Perbill::from_rational(p % q, q),
155			coeff_integer: p / q,
156		}]
157	}
158}
159
160/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
161/// the specifics of the runtime. They can then be made to be agnostic over specific formats
162/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
163/// to even the core data structures.
164pub mod opaque {
165	use super::*;
166	use sp_runtime::{
167		generic,
168		traits::{BlakeTwo256, Hash as HashT},
169	};
170
171	pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
172	/// Opaque block header type.
173	pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
174	/// Opaque block type.
175	pub type Block = generic::Block<Header, UncheckedExtrinsic>;
176	/// Opaque block identifier type.
177	pub type BlockId = generic::BlockId<Block>;
178	/// Opaque block hash type.
179	pub type Hash = <BlakeTwo256 as HashT>::Output;
180}
181
182impl_opaque_keys! {
183	pub struct SessionKeys {
184		pub aura: Aura,
185	}
186}
187
188#[sp_version::runtime_version]
189pub const VERSION: RuntimeVersion = RuntimeVersion {
190	spec_name: create_runtime_str!("contracts-parachain"),
191	impl_name: create_runtime_str!("contracts-parachain"),
192	authoring_version: 1,
193	spec_version: 1,
194	impl_version: 0,
195	apis: RUNTIME_API_VERSIONS,
196	transaction_version: 1,
197	state_version: 1,
198};
199
200mod block_times {
201	/// This determines the average expected block time that we are targeting. Blocks will be
202	/// produced at a minimum duration defined by `SLOT_DURATION`. `SLOT_DURATION` is picked up by
203	/// `pallet_timestamp` which is in turn picked up by `pallet_aura` to implement `fn
204	/// slot_duration()`.
205	///
206	/// Change this to adjust the block time.
207	pub const MILLISECS_PER_BLOCK: u64 = 6000;
208
209	// NOTE: Currently it is not possible to change the slot duration after the chain has started.
210	// Attempting to do so will brick block production.
211	pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
212}
213pub use block_times::*;
214
215// Time is measured by number of blocks.
216pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
217pub const HOURS: BlockNumber = MINUTES * 60;
218pub const DAYS: BlockNumber = HOURS * 24;
219
220// Unit = the base number of indivisible units for balances
221pub const UNIT: Balance = 1_000_000_000_000;
222pub const MILLIUNIT: Balance = 1_000_000_000;
223pub const MICROUNIT: Balance = 1_000_000;
224
225/// The existential deposit. Set to 1/10 of the Connected Relay Chain.
226pub const EXISTENTIAL_DEPOSIT: Balance = MILLIUNIT;
227
228/// We assume that ~5% of the block weight is consumed by `on_initialize` handlers. This is
229/// used to limit the maximal weight of a single extrinsic.
230const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5);
231
232/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used by
233/// `Operational` extrinsics.
234const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
235
236/// We allow for 2 seconds of compute with a 6 second average block time.
237const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(
238	WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2),
239	cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64,
240);
241
242mod async_backing_params {
243	/// Maximum number of blocks simultaneously accepted by the Runtime, not yet included
244	/// into the relay chain.
245	pub(crate) const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3;
246	/// How many parachain blocks are processed by the relay chain per parent. Limits the
247	/// number of blocks authored per slot.
248	pub(crate) const BLOCK_PROCESSING_VELOCITY: u32 = 1;
249	/// Relay chain slot duration, in milliseconds.
250	pub(crate) const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000;
251}
252pub(crate) use async_backing_params::*;
253
254/// The version information used to identify this runtime when compiled natively.
255#[cfg(feature = "std")]
256pub fn native_version() -> NativeVersion {
257	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
258}
259
260parameter_types! {
261	pub const Version: RuntimeVersion = VERSION;
262
263	// This part is copied from Substrate's `bin/node/runtime/src/lib.rs`.
264	//  The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the
265	// `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize
266	// the lazy contract deletion.
267	pub RuntimeBlockLength: BlockLength =
268		BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
269	pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
270		.base_block(BlockExecutionWeight::get())
271		.for_class(DispatchClass::all(), |weights| {
272			weights.base_extrinsic = ExtrinsicBaseWeight::get();
273		})
274		.for_class(DispatchClass::Normal, |weights| {
275			weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
276		})
277		.for_class(DispatchClass::Operational, |weights| {
278			weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
279			// Operational transactions have some extra reserved space, so that they
280			// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
281			weights.reserved = Some(
282				MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
283			);
284		})
285		.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
286		.build_or_panic();
287	pub const SS58Prefix: u16 = 42;
288}
289
290/// The default types are being injected by [`derive_impl`](`frame_support::derive_impl`) from
291/// [`ParaChainDefaultConfig`](`struct@frame_system::config_preludes::ParaChainDefaultConfig`),
292/// but overridden as needed.
293#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig)]
294impl frame_system::Config for Runtime {
295	/// The identifier used to distinguish between accounts.
296	type AccountId = AccountId;
297	/// The index type for storing how many extrinsics an account has signed.
298	type Nonce = Nonce;
299	/// The type for hashing blocks and tries.
300	type Hash = Hash;
301	/// The block type.
302	type Block = Block;
303	/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
304	type BlockHashCount = BlockHashCount;
305	/// Runtime version.
306	type Version = Version;
307	/// The data to be stored in an account.
308	type AccountData = pallet_balances::AccountData<Balance>;
309	/// The weight of database operations that the runtime can invoke.
310	type DbWeight = RocksDbWeight;
311	/// Block & extrinsics weights: base values and limits.
312	type BlockWeights = RuntimeBlockWeights;
313	/// The maximum length of a block (in bytes).
314	type BlockLength = RuntimeBlockLength;
315	/// This is used as an identifier of the chain. 42 is the generic substrate prefix.
316	type SS58Prefix = SS58Prefix;
317	/// The action to take on a Runtime Upgrade
318	type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
319	type MaxConsumers = frame_support::traits::ConstU32<16>;
320}
321
322impl pallet_timestamp::Config for Runtime {
323	/// A timestamp: milliseconds since the unix epoch.
324	type Moment = u64;
325	type OnTimestampSet = Aura;
326	type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>;
327	type WeightInfo = ();
328}
329
330impl pallet_authorship::Config for Runtime {
331	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
332	type EventHandler = (CollatorSelection,);
333}
334
335parameter_types! {
336	pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
337}
338
339impl pallet_balances::Config for Runtime {
340	type MaxLocks = ConstU32<50>;
341	/// The type for recording an account's balance.
342	type Balance = Balance;
343	/// The ubiquitous event type.
344	type RuntimeEvent = RuntimeEvent;
345	type DustRemoval = ();
346	type ExistentialDeposit = ExistentialDeposit;
347	type AccountStore = System;
348	type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
349	type MaxReserves = ConstU32<50>;
350	type ReserveIdentifier = [u8; 8];
351	type RuntimeHoldReason = RuntimeHoldReason;
352	type RuntimeFreezeReason = RuntimeFreezeReason;
353	type FreezeIdentifier = ();
354	type MaxFreezes = ConstU32<50>;
355}
356
357parameter_types! {
358	/// Relay Chain `TransactionByteFee` / 10
359	pub const TransactionByteFee: Balance = 10 * MICROUNIT;
360}
361
362impl pallet_transaction_payment::Config for Runtime {
363	type RuntimeEvent = RuntimeEvent;
364	type OnChargeTransaction = pallet_transaction_payment::FungibleAdapter<Balances, ()>;
365	type WeightToFee = WeightToFee;
366	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
367	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
368	type OperationalFeeMultiplier = ConstU8<5>;
369}
370
371impl pallet_sudo::Config for Runtime {
372	type RuntimeEvent = RuntimeEvent;
373	type RuntimeCall = RuntimeCall;
374	type WeightInfo = ();
375}
376
377parameter_types! {
378	pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
379	pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
380	pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
381}
382
383impl cumulus_pallet_parachain_system::Config for Runtime {
384	type WeightInfo = ();
385	type RuntimeEvent = RuntimeEvent;
386	type OnSystemEvent = ();
387	type SelfParaId = parachain_info::Pallet<Runtime>;
388	type OutboundXcmpMessageSource = XcmpQueue;
389	type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
390	type ReservedDmpWeight = ReservedDmpWeight;
391	type XcmpMessageHandler = XcmpQueue;
392	type ReservedXcmpWeight = ReservedXcmpWeight;
393	type CheckAssociatedRelayNumber = RelayNumberStrictlyIncreases;
394	type ConsensusHook = ConsensusHook;
395}
396
397impl parachain_info::Config for Runtime {}
398
399parameter_types! {
400	pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block;
401}
402
403impl pallet_message_queue::Config for Runtime {
404	type RuntimeEvent = RuntimeEvent;
405	type WeightInfo = ();
406	#[cfg(feature = "runtime-benchmarks")]
407	type MessageProcessor = pallet_message_queue::mock_helpers::NoopMessageProcessor<
408		cumulus_primitives_core::AggregateMessageOrigin,
409	>;
410	#[cfg(not(feature = "runtime-benchmarks"))]
411	type MessageProcessor = xcm_builder::ProcessXcmMessage<
412		AggregateMessageOrigin,
413		xcm_executor::XcmExecutor<xcm_config::XcmConfig>,
414		RuntimeCall,
415	>;
416	type Size = u32;
417	// The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin:
418	type QueueChangeHandler = NarrowOriginToSibling<XcmpQueue>;
419	type QueuePausedQuery = NarrowOriginToSibling<XcmpQueue>;
420	type HeapSize = ConstU32<{ 64 * 1024 }>;
421	type MaxStale = ConstU32<8>;
422	type ServiceWeight = MessageQueueServiceWeight;
423	type IdleMaxServiceWeight = ();
424}
425
426impl cumulus_pallet_aura_ext::Config for Runtime {}
427
428impl cumulus_pallet_xcmp_queue::Config for Runtime {
429	type RuntimeEvent = RuntimeEvent;
430	type ChannelInfo = ParachainSystem;
431	type VersionWrapper = ();
432	// Enqueue XCMP messages from siblings for later processing.
433	type XcmpQueue = TransformOrigin<MessageQueue, AggregateMessageOrigin, ParaId, ParaIdToSibling>;
434	type MaxInboundSuspended = ConstU32<1_000>;
435	type MaxActiveOutboundChannels = ConstU32<128>;
436	type MaxPageSize = ConstU32<{ 1 << 16 }>;
437	type ControllerOrigin = EnsureRoot<AccountId>;
438	type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
439	type WeightInfo = ();
440	type PriceForSiblingDelivery = NoPriceForMessageDelivery<ParaId>;
441}
442
443parameter_types! {
444	pub const Period: u32 = 6 * HOURS;
445	pub const Offset: u32 = 0;
446}
447
448impl pallet_session::Config for Runtime {
449	type RuntimeEvent = RuntimeEvent;
450	type ValidatorId = <Self as frame_system::Config>::AccountId;
451	// we don't have stash and controller, thus we don't need the convert as well.
452	type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
453	type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
454	type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
455	type SessionManager = CollatorSelection;
456	// Essentially just Aura, but let's be pedantic.
457	type SessionHandler = <SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
458	type Keys = SessionKeys;
459	type WeightInfo = ();
460}
461
462impl pallet_aura::Config for Runtime {
463	type AuthorityId = AuraId;
464	type DisabledValidators = ();
465	type MaxAuthorities = ConstU32<100_000>;
466	type AllowMultipleBlocksPerSlot = ConstBool<false>;
467	type SlotDuration = pallet_aura::MinimumPeriodTimesTwo<Self>;
468}
469
470parameter_types! {
471	pub const PotId: PalletId = PalletId(*b"PotStake");
472	pub const SessionLength: BlockNumber = 6 * HOURS;
473	// StakingAdmin pluralistic body.
474	pub const StakingAdminBodyId: BodyId = BodyId::Defense;
475}
476
477/// We allow root and the StakingAdmin to execute privileged collator selection operations.
478pub type CollatorSelectionUpdateOrigin = EitherOfDiverse<
479	EnsureRoot<AccountId>,
480	EnsureXcm<IsVoiceOfBody<RelayLocation, StakingAdminBodyId>>,
481>;
482
483impl pallet_collator_selection::Config for Runtime {
484	type RuntimeEvent = RuntimeEvent;
485	type Currency = Balances;
486	type UpdateOrigin = CollatorSelectionUpdateOrigin;
487	type PotId = PotId;
488	type MaxCandidates = ConstU32<100>;
489	type MinEligibleCollators = ConstU32<4>;
490	type MaxInvulnerables = ConstU32<20>;
491	// should be a multiple of session or things will get inconsistent
492	type KickThreshold = Period;
493	type ValidatorId = <Self as frame_system::Config>::AccountId;
494	type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
495	type ValidatorRegistration = Session;
496	type WeightInfo = ();
497}
498
499pub use pallet_balances::Call as BalancesCall;
500impl pallet_insecure_randomness_collective_flip::Config for Runtime {}
501impl pallet_utility::Config for Runtime {
502	type RuntimeEvent = RuntimeEvent;
503	type RuntimeCall = RuntimeCall;
504	type PalletsOrigin = OriginCaller;
505	type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
506}
507
508// Create the runtime by composing the FRAME pallets that were previously configured.
509#[frame_support::runtime]
510mod runtime {
511
512	#[runtime::runtime]
513	#[runtime::derive(
514		RuntimeCall,
515		RuntimeEvent,
516		RuntimeError,
517		RuntimeOrigin,
518		RuntimeFreezeReason,
519		RuntimeHoldReason,
520		RuntimeSlashReason,
521		RuntimeLockId,
522		RuntimeTask
523	)]
524	pub struct Runtime;
525
526	// Order should match with Runtime defined in runtime/src/lib.rs
527	#[runtime::pallet_index(0)]
528	pub type System = frame_system;
529	#[runtime::pallet_index(1)]
530	pub type RandomnessCollectiveFlip = pallet_insecure_randomness_collective_flip;
531	#[runtime::pallet_index(2)]
532	pub type Utility = pallet_utility;
533	#[runtime::pallet_index(3)]
534	pub type Timestamp = pallet_timestamp;
535	#[runtime::pallet_index(4)]
536	pub type Balances = pallet_balances;
537	#[runtime::pallet_index(5)]
538	pub type Authorship = pallet_authorship;
539	#[runtime::pallet_index(6)]
540	pub type TransactionPayment = pallet_transaction_payment;
541	#[runtime::pallet_index(7)]
542	pub type Sudo = pallet_sudo;
543	#[runtime::pallet_index(8)]
544	pub type Contracts = pallet_contracts;
545	#[runtime::pallet_index(9)]
546	pub type Revive = pallet_revive;
547	#[runtime::pallet_index(10)]
548	pub type Assets = pallet_assets;
549	// Parachain support.
550	#[runtime::pallet_index(11)]
551	pub type ParachainSystem = cumulus_pallet_parachain_system;
552	#[runtime::pallet_index(12)]
553	pub type ParachainInfo = parachain_info;
554
555	// Collator support. The order of these 4 are important and shall not change.
556	#[runtime::pallet_index(13)]
557	pub type CollatorSelection = pallet_collator_selection;
558	#[runtime::pallet_index(14)]
559	pub type Session = pallet_session;
560	#[runtime::pallet_index(15)]
561	pub type Aura = pallet_aura;
562	#[runtime::pallet_index(16)]
563	pub type AuraExt = cumulus_pallet_aura_ext;
564	// XCM helpers.
565	#[runtime::pallet_index(17)]
566	pub type XcmpQueue = cumulus_pallet_xcmp_queue;
567	#[runtime::pallet_index(18)]
568	pub type PolkadotXcm = pallet_xcm;
569	#[runtime::pallet_index(19)]
570	pub type CumulusXcm = cumulus_pallet_xcm;
571	#[runtime::pallet_index(20)]
572	pub type MessageQueue = pallet_message_queue;
573}
574
575#[cfg(feature = "runtime-benchmarks")]
576mod benches {
577	frame_benchmarking::define_benchmarks!(
578		[frame_system, SystemBench::<Runtime>]
579		[pallet_balances, Balances]
580		[pallet_session, SessionBench::<Runtime>]
581		[pallet_timestamp, Timestamp]
582		[pallet_message_queue, MessageQueue]
583		[pallet_sudo, Sudo]
584		[pallet_collator_selection, CollatorSelection]
585		[cumulus_pallet_parachain_system, ParachainSystem]
586		[cumulus_pallet_xcmp_queue, XcmpQueue]
587	);
588}
589
590type EventRecord = frame_system::EventRecord<
591	<Runtime as frame_system::Config>::RuntimeEvent,
592	<Runtime as frame_system::Config>::Hash,
593>;
594
595// Prints debug output of the `revive` pallet to stdout if the node is
596// started with `-lruntime::revive=trace` or `-lruntime::contracts=debug`.
597const CONTRACTS_DEBUG_OUTPUT: pallet_contracts::DebugInfo =
598	pallet_contracts::DebugInfo::UnsafeDebug;
599const CONTRACTS_EVENTS: pallet_contracts::CollectEvents =
600	pallet_contracts::CollectEvents::UnsafeCollect;
601const REVIVE_DEBUG_OUTPUT: pallet_revive::DebugInfo = pallet_revive::DebugInfo::UnsafeDebug;
602const REVIVE_EVENTS: pallet_revive::CollectEvents = pallet_revive::CollectEvents::UnsafeCollect;
603
604impl_runtime_apis! {
605	impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
606		fn slot_duration() -> sp_consensus_aura::SlotDuration {
607			sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION)
608		}
609
610		fn authorities() -> Vec<AuraId> {
611			pallet_aura::Authorities::<Runtime>::get().into_inner()
612		}
613	}
614
615	impl cumulus_primitives_aura::AuraUnincludedSegmentApi<Block> for Runtime {
616		fn can_build_upon(
617			included_hash: <Block as BlockT>::Hash,
618			slot: cumulus_primitives_aura::Slot
619		) -> bool {
620			ConsensusHook::can_build_upon(included_hash, slot)
621		}
622	}
623
624	impl sp_api::Core<Block> for Runtime {
625		fn version() -> RuntimeVersion {
626			VERSION
627		}
628
629		fn execute_block(block: Block) {
630			Executive::execute_block(block)
631		}
632
633		fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
634			Executive::initialize_block(header)
635		}
636	}
637
638	impl sp_api::Metadata<Block> for Runtime {
639		fn metadata() -> OpaqueMetadata {
640			OpaqueMetadata::new(Runtime::metadata().into())
641		}
642
643		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
644			Runtime::metadata_at_version(version)
645		}
646
647		fn metadata_versions() -> Vec<u32> {
648			Runtime::metadata_versions()
649		}
650	}
651
652	impl sp_block_builder::BlockBuilder<Block> for Runtime {
653		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
654			Executive::apply_extrinsic(extrinsic)
655		}
656
657		fn finalize_block() -> <Block as BlockT>::Header {
658			Executive::finalize_block()
659		}
660
661		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
662			data.create_extrinsics()
663		}
664
665		fn check_inherents(
666			block: Block,
667			data: sp_inherents::InherentData,
668		) -> sp_inherents::CheckInherentsResult {
669			data.check_extrinsics(&block)
670		}
671	}
672
673	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
674		fn validate_transaction(
675			source: TransactionSource,
676			tx: <Block as BlockT>::Extrinsic,
677			block_hash: <Block as BlockT>::Hash,
678		) -> TransactionValidity {
679			Executive::validate_transaction(source, tx, block_hash)
680		}
681	}
682
683	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
684		fn offchain_worker(header: &<Block as BlockT>::Header) {
685			Executive::offchain_worker(header)
686		}
687	}
688
689	impl sp_session::SessionKeys<Block> for Runtime {
690		fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
691			SessionKeys::generate(seed)
692		}
693
694		fn decode_session_keys(
695			encoded: Vec<u8>,
696		) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
697			SessionKeys::decode_into_raw_public_keys(&encoded)
698		}
699	}
700
701	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
702		fn account_nonce(account: AccountId) -> Nonce {
703			System::account_nonce(account)
704		}
705	}
706
707	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
708		fn query_info(
709			uxt: <Block as BlockT>::Extrinsic,
710			len: u32,
711		) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
712			TransactionPayment::query_info(uxt, len)
713		}
714		fn query_fee_details(
715			uxt: <Block as BlockT>::Extrinsic,
716			len: u32,
717		) -> pallet_transaction_payment::FeeDetails<Balance> {
718			TransactionPayment::query_fee_details(uxt, len)
719		}
720		fn query_weight_to_fee(weight: Weight) -> Balance {
721			TransactionPayment::weight_to_fee(weight)
722		}
723		fn query_length_to_fee(length: u32) -> Balance {
724			TransactionPayment::length_to_fee(length)
725		}
726	}
727
728	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
729		for Runtime
730	{
731		fn query_call_info(
732			call: RuntimeCall,
733			len: u32,
734		) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
735			TransactionPayment::query_call_info(call, len)
736		}
737		fn query_call_fee_details(
738			call: RuntimeCall,
739			len: u32,
740		) -> pallet_transaction_payment::FeeDetails<Balance> {
741			TransactionPayment::query_call_fee_details(call, len)
742		}
743		fn query_weight_to_fee(weight: Weight) -> Balance {
744			TransactionPayment::weight_to_fee(weight)
745		}
746		fn query_length_to_fee(length: u32) -> Balance {
747			TransactionPayment::length_to_fee(length)
748		}
749	}
750
751	impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
752		fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
753			ParachainSystem::collect_collation_info(header)
754		}
755	}
756
757	#[cfg(feature = "try-runtime")]
758	impl frame_try_runtime::TryRuntime<Block> for Runtime {
759		fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
760			let weight = Executive::try_runtime_upgrade(checks).unwrap();
761			(weight, RuntimeBlockWeights::get().max_block)
762		}
763
764		fn execute_block(
765			block: Block,
766			state_root_check: bool,
767			signature_check: bool,
768			select: frame_try_runtime::TryStateSelect,
769		) -> Weight {
770			// NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
771			// have a backtrace here.
772			Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()
773		}
774	}
775
776	#[cfg(feature = "runtime-benchmarks")]
777	impl frame_benchmarking::Benchmark<Block> for Runtime {
778		fn benchmark_metadata(extra: bool) -> (
779			Vec<frame_benchmarking::BenchmarkList>,
780			Vec<frame_support::traits::StorageInfo>,
781		) {
782			use frame_benchmarking::{Benchmarking, BenchmarkList};
783			use frame_support::traits::StorageInfoTrait;
784			use frame_system_benchmarking::Pallet as SystemBench;
785			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
786
787			let mut list = Vec::<BenchmarkList>::new();
788			list_benchmarks!(list, extra);
789
790			let storage_info = AllPalletsWithSystem::storage_info();
791			(list, storage_info)
792		}
793
794		fn dispatch_benchmark(
795			config: frame_benchmarking::BenchmarkConfig
796		) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {
797			use frame_benchmarking::{BenchmarkError, Benchmarking, BenchmarkBatch};
798
799			use frame_system_benchmarking::Pallet as SystemBench;
800			impl frame_system_benchmarking::Config for Runtime {
801				fn setup_set_code_requirements(code: &Vec<u8>) -> Result<(), BenchmarkError> {
802					ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
803					Ok(())
804				}
805
806				fn verify_set_code() {
807					System::assert_last_event(cumulus_pallet_parachain_system::Event::<Runtime>::ValidationFunctionStored.into());
808				}
809			}
810
811			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
812			impl cumulus_pallet_session_benchmarking::Config for Runtime {}
813
814			use frame_support::traits::WhitelistedStorageKeys;
815			let whitelist = AllPalletsWithSystem::whitelisted_storage_keys();
816
817			let mut batches = Vec::<BenchmarkBatch>::new();
818			let params = (&config, &whitelist);
819			add_benchmarks!(params, batches);
820
821			if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
822			Ok(batches)
823		}
824	}
825
826	impl pallet_revive::ReviveApi<Block, AccountId, Balance, BlockNumber, Hash, EventRecord> for Runtime
827	{
828		fn call(
829			origin: AccountId,
830			dest: AccountId,
831			value: Balance,
832			gas_limit: Option<Weight>,
833			storage_deposit_limit: Option<Balance>,
834			input_data: Vec<u8>,
835		) -> pallet_revive::ContractExecResult<Balance, EventRecord> {
836			Revive::bare_call(
837				RuntimeOrigin::signed(origin),
838				dest,
839				value,
840				gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block),
841				storage_deposit_limit.unwrap_or(u128::MAX),
842				input_data,
843				REVIVE_DEBUG_OUTPUT,
844				REVIVE_EVENTS,
845			)
846		}
847
848		fn instantiate(
849			origin: AccountId,
850			value: Balance,
851			gas_limit: Option<Weight>,
852			storage_deposit_limit: Option<Balance>,
853			code: pallet_revive::Code<Hash>,
854			data: Vec<u8>,
855			salt: Vec<u8>,
856		) -> pallet_revive::ContractInstantiateResult<AccountId, Balance, EventRecord>
857		{
858			Revive::bare_instantiate(
859				RuntimeOrigin::signed(origin),
860				value,
861				gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block),
862				storage_deposit_limit.unwrap_or(u128::MAX),
863				code,
864				data,
865				salt,
866				REVIVE_DEBUG_OUTPUT,
867				REVIVE_EVENTS,
868			)
869		}
870
871		fn upload_code(
872			origin: AccountId,
873			code: Vec<u8>,
874			storage_deposit_limit: Option<Balance>,
875		) -> pallet_revive::CodeUploadResult<Hash, Balance>
876		{
877			Revive::bare_upload_code(
878				RuntimeOrigin::signed(origin),
879				code,
880				storage_deposit_limit.unwrap_or(u128::MAX),
881			)
882		}
883
884		fn get_storage(
885			address: AccountId,
886			key: Vec<u8>,
887		) -> pallet_revive::GetStorageResult {
888			Revive::get_storage(
889				address,
890				key
891			)
892		}
893	}
894
895	impl pallet_contracts::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash, EventRecord>
896		for Runtime
897	{
898		fn call(
899			origin: AccountId,
900			dest: AccountId,
901			value: Balance,
902			gas_limit: Option<Weight>,
903			storage_deposit_limit: Option<Balance>,
904			input_data: Vec<u8>,
905		) -> pallet_contracts::ContractExecResult<Balance, EventRecord> {
906			let gas_limit = gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block);
907			Contracts::bare_call(
908				origin,
909				dest,
910				value,
911				gas_limit,
912				storage_deposit_limit,
913				input_data,
914				CONTRACTS_DEBUG_OUTPUT,
915				CONTRACTS_EVENTS,
916				pallet_contracts::Determinism::Enforced,
917			)
918		}
919
920		fn instantiate(
921			origin: AccountId,
922			value: Balance,
923			gas_limit: Option<Weight>,
924			storage_deposit_limit: Option<Balance>,
925			code: pallet_contracts::Code<Hash>,
926			data: Vec<u8>,
927			salt: Vec<u8>,
928		) -> pallet_contracts::ContractInstantiateResult<AccountId, Balance, EventRecord>
929		{
930			let gas_limit = gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block);
931			Contracts::bare_instantiate(
932				origin,
933				value,
934				gas_limit,
935				storage_deposit_limit,
936				code,
937				data,
938				salt,
939				CONTRACTS_DEBUG_OUTPUT,
940				CONTRACTS_EVENTS,
941			)
942		}
943
944		fn upload_code(
945			origin: AccountId,
946			code: Vec<u8>,
947			storage_deposit_limit: Option<Balance>,
948			determinism: pallet_contracts::Determinism,
949		) -> pallet_contracts::CodeUploadResult<Hash, Balance>
950		{
951			Contracts::bare_upload_code(origin, code, storage_deposit_limit, determinism)
952		}
953
954		fn get_storage(
955			address: AccountId,
956			key: Vec<u8>,
957		) -> pallet_contracts::GetStorageResult {
958			Contracts::get_storage(address, key)
959		}
960	}
961
962
963	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
964		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
965			build_state::<RuntimeGenesisConfig>(config)
966		}
967
968		fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
969			get_preset::<RuntimeGenesisConfig>(id, |_| None)
970		}
971
972		fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
973			Default::default()
974		}
975	}
976}
977
978cumulus_pallet_parachain_system::register_validate_block! {
979	Runtime = Runtime,
980	BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
981}