Skip to main content

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