referrerpolicy=no-referrer-when-downgrade

parachain_template_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
9pub mod apis;
10#[cfg(feature = "runtime-benchmarks")]
11mod benchmarks;
12pub mod configs;
13mod genesis_config_presets;
14mod weights;
15
16extern crate alloc;
17use alloc::vec::Vec;
18use smallvec::smallvec;
19
20use polkadot_sdk::{staging_parachain_info as parachain_info, *};
21
22use sp_runtime::{
23	generic, impl_opaque_keys,
24	traits::{BlakeTwo256, IdentifyAccount, Verify},
25	MultiSignature,
26};
27
28#[cfg(feature = "std")]
29use sp_version::NativeVersion;
30use sp_version::RuntimeVersion;
31
32use frame_support::weights::{
33	constants::WEIGHT_REF_TIME_PER_SECOND, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients,
34	WeightToFeePolynomial,
35};
36pub use genesis_config_presets::PARACHAIN_ID;
37pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
38pub use sp_runtime::{MultiAddress, Perbill, Permill};
39
40use weights::ExtrinsicBaseWeight;
41
42/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
43pub type Signature = MultiSignature;
44
45/// Some way of identifying an account on the chain. We intentionally make it equivalent
46/// to the public key of our transaction signing scheme.
47pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
48
49/// Balance of an account.
50pub type Balance = u128;
51
52/// Index of a transaction in the chain.
53pub type Nonce = u32;
54
55/// A hash of some data used by the chain.
56pub type Hash = sp_core::H256;
57
58/// An index to a block.
59pub type BlockNumber = u32;
60
61/// The address format for describing accounts.
62pub type Address = MultiAddress<AccountId, ()>;
63
64/// Block header type as expected by this runtime.
65pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
66
67/// Block type as expected by this runtime.
68pub type Block = generic::Block<Header, UncheckedExtrinsic>;
69
70/// A Block signed with a Justification
71pub type SignedBlock = generic::SignedBlock<Block>;
72
73/// BlockId type as expected by this runtime.
74pub type BlockId = generic::BlockId<Block>;
75
76/// The extension to the basic transaction logic.
77#[docify::export(template_signed_extra)]
78pub type TxExtension = cumulus_pallet_weight_reclaim::StorageWeightReclaim<
79	Runtime,
80	(
81		frame_system::AuthorizeCall<Runtime>,
82		frame_system::CheckNonZeroSender<Runtime>,
83		frame_system::CheckSpecVersion<Runtime>,
84		frame_system::CheckTxVersion<Runtime>,
85		frame_system::CheckGenesis<Runtime>,
86		frame_system::CheckEra<Runtime>,
87		frame_system::CheckNonce<Runtime>,
88		frame_system::CheckWeight<Runtime>,
89		pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
90		frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
91	),
92>;
93
94/// Unchecked extrinsic type as expected by this runtime.
95pub type UncheckedExtrinsic =
96	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
97
98/// Executive: handles dispatch to the various modules.
99pub type Executive = frame_executive::Executive<
100	Runtime,
101	Block,
102	frame_system::ChainContext<Runtime>,
103	Runtime,
104	AllPalletsWithSystem,
105>;
106
107/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the
108/// node's balance type.
109///
110/// This should typically create a mapping between the following ranges:
111///   - `[0, MAXIMUM_BLOCK_WEIGHT]`
112///   - `[Balance::min, Balance::max]`
113///
114/// Yet, it can be used for any other sort of change to weight-fee. Some examples being:
115///   - Setting it to `0` will essentially disable the weight fee.
116///   - Setting it to `1` will cause the literal `#[weight = x]` values to be charged.
117pub struct WeightToFee;
118impl WeightToFeePolynomial for WeightToFee {
119	type Balance = Balance;
120	fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
121		// in Rococo, extrinsic base weight (smallest non-zero weight) is mapped to 1 MILLI_UNIT:
122		// in our template, we map to 1/10 of that, or 1/10 MILLI_UNIT
123		let p = MILLI_UNIT / 10;
124		let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
125		smallvec![WeightToFeeCoefficient {
126			degree: 1,
127			negative: false,
128			coeff_frac: Perbill::from_rational(p % q, q),
129			coeff_integer: p / q,
130		}]
131	}
132}
133
134/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
135/// the specifics of the runtime. They can then be made to be agnostic over specific formats
136/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
137/// to even the core data structures.
138pub mod opaque {
139	use super::*;
140	pub use polkadot_sdk::sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
141	use polkadot_sdk::sp_runtime::{
142		generic,
143		traits::{BlakeTwo256, Hash as HashT},
144	};
145
146	/// Opaque block header type.
147	pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
148	/// Opaque block type.
149	pub type Block = generic::Block<Header, UncheckedExtrinsic>;
150	/// Opaque block identifier type.
151	pub type BlockId = generic::BlockId<Block>;
152	/// Opaque block hash type.
153	pub type Hash = <BlakeTwo256 as HashT>::Output;
154}
155
156impl_opaque_keys! {
157	pub struct SessionKeys {
158		pub aura: Aura,
159	}
160}
161
162#[sp_version::runtime_version]
163pub const VERSION: RuntimeVersion = RuntimeVersion {
164	spec_name: alloc::borrow::Cow::Borrowed("parachain-template-runtime"),
165	impl_name: alloc::borrow::Cow::Borrowed("parachain-template-runtime"),
166	authoring_version: 1,
167	spec_version: 1,
168	impl_version: 0,
169	apis: apis::RUNTIME_API_VERSIONS,
170	transaction_version: 1,
171	system_version: 1,
172};
173
174#[docify::export]
175mod block_times {
176	/// This determines the average expected block time that we are targeting. Blocks will be
177	/// produced at a minimum duration defined by `SLOT_DURATION`. `SLOT_DURATION` is picked up by
178	/// `pallet_timestamp` which is in turn picked up by `pallet_aura` to implement `fn
179	/// slot_duration()`.
180	///
181	/// Change this to adjust the block time.
182	pub const MILLI_SECS_PER_BLOCK: u64 = 6000;
183
184	// NOTE: Currently it is not possible to change the slot duration after the chain has started.
185	// Attempting to do so will brick block production.
186	pub const SLOT_DURATION: u64 = MILLI_SECS_PER_BLOCK;
187}
188pub use block_times::*;
189
190// Time is measured by number of blocks.
191pub const MINUTES: BlockNumber = 60_000 / (MILLI_SECS_PER_BLOCK as BlockNumber);
192pub const HOURS: BlockNumber = MINUTES * 60;
193pub const DAYS: BlockNumber = HOURS * 24;
194
195// Unit = the base number of indivisible units for balances
196pub const UNIT: Balance = 1_000_000_000_000;
197pub const MILLI_UNIT: Balance = 1_000_000_000;
198pub const MICRO_UNIT: Balance = 1_000_000;
199
200/// The existential deposit. Set to 1/10 of the Connected Relay Chain.
201pub const EXISTENTIAL_DEPOSIT: Balance = MILLI_UNIT;
202
203/// We assume that ~5% of the block weight is consumed by `on_initialize` handlers. This is
204/// used to limit the maximal weight of a single extrinsic.
205const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5);
206
207/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used by
208/// `Operational` extrinsics.
209const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
210
211#[docify::export(max_block_weight)]
212/// We allow for 2 seconds of compute with a 6 second average block time.
213const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(
214	WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2),
215	cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64,
216);
217
218#[docify::export]
219mod async_backing_params {
220	/// Maximum number of blocks simultaneously accepted by the Runtime, not yet included
221	/// into the relay chain.
222	pub(crate) const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3;
223	/// How many parachain blocks are processed by the relay chain per parent. Limits the
224	/// number of blocks authored per slot.
225	pub(crate) const BLOCK_PROCESSING_VELOCITY: u32 = 1;
226	/// Relay chain slot duration, in milliseconds.
227	pub(crate) const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000;
228}
229pub(crate) use async_backing_params::*;
230
231#[docify::export]
232/// Aura consensus hook
233type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
234	Runtime,
235	RELAY_CHAIN_SLOT_DURATION_MILLIS,
236	BLOCK_PROCESSING_VELOCITY,
237	UNINCLUDED_SEGMENT_CAPACITY,
238>;
239
240/// The version information used to identify this runtime when compiled natively.
241#[cfg(feature = "std")]
242pub fn native_version() -> NativeVersion {
243	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
244}
245
246// Create the runtime by composing the FRAME pallets that were previously configured.
247#[frame_support::runtime]
248mod runtime {
249	#[runtime::runtime]
250	#[runtime::derive(
251		RuntimeCall,
252		RuntimeEvent,
253		RuntimeError,
254		RuntimeOrigin,
255		RuntimeFreezeReason,
256		RuntimeHoldReason,
257		RuntimeSlashReason,
258		RuntimeLockId,
259		RuntimeTask,
260		RuntimeViewFunction
261	)]
262	pub struct Runtime;
263
264	#[runtime::pallet_index(0)]
265	pub type System = frame_system;
266	#[runtime::pallet_index(1)]
267	pub type ParachainSystem = cumulus_pallet_parachain_system;
268	#[runtime::pallet_index(2)]
269	pub type Timestamp = pallet_timestamp;
270	#[runtime::pallet_index(3)]
271	pub type ParachainInfo = parachain_info;
272	#[runtime::pallet_index(4)]
273	pub type WeightReclaim = cumulus_pallet_weight_reclaim;
274
275	// Monetary stuff.
276	#[runtime::pallet_index(10)]
277	pub type Balances = pallet_balances;
278	#[runtime::pallet_index(11)]
279	pub type TransactionPayment = pallet_transaction_payment;
280
281	// Governance
282	#[runtime::pallet_index(15)]
283	pub type Sudo = pallet_sudo;
284
285	// Collator support. The order of these 4 are important and shall not change.
286	#[runtime::pallet_index(20)]
287	pub type Authorship = pallet_authorship;
288	#[runtime::pallet_index(21)]
289	pub type CollatorSelection = pallet_collator_selection;
290	#[runtime::pallet_index(22)]
291	pub type Session = pallet_session;
292	#[runtime::pallet_index(23)]
293	pub type Aura = pallet_aura;
294	#[runtime::pallet_index(24)]
295	pub type AuraExt = cumulus_pallet_aura_ext;
296
297	// XCM helpers.
298	#[runtime::pallet_index(30)]
299	pub type XcmpQueue = cumulus_pallet_xcmp_queue;
300	#[runtime::pallet_index(31)]
301	pub type PolkadotXcm = pallet_xcm;
302	#[runtime::pallet_index(32)]
303	pub type CumulusXcm = cumulus_pallet_xcm;
304	#[runtime::pallet_index(33)]
305	pub type MessageQueue = pallet_message_queue;
306
307	// Template
308	#[runtime::pallet_index(50)]
309	pub type TemplatePallet = pallet_parachain_template;
310}
311
312#[docify::export(register_validate_block)]
313cumulus_pallet_parachain_system::register_validate_block! {
314	Runtime = Runtime,
315	BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
316}