idn_runtime/
lib.rs

1/*
2 * Copyright 2025 by Ideal Labs, LLC
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#![cfg_attr(not(feature = "std"), no_std)]
18// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
19#![recursion_limit = "256"]
20
21// Make the WASM binary available.
22#[cfg(feature = "std")]
23include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
24
25pub mod apis;
26#[cfg(feature = "runtime-benchmarks")]
27mod benchmarks;
28pub mod configs;
29pub mod constants;
30mod genesis_config_presets;
31mod weights;
32
33extern crate alloc;
34
35use smallvec::smallvec;
36use sp_runtime::{generic, impl_opaque_keys, traits::BlakeTwo256, Cow};
37
38use sp_std::prelude::*;
39#[cfg(feature = "std")]
40use sp_version::NativeVersion;
41use sp_version::RuntimeVersion;
42
43use frame_support::weights::{
44	constants::WEIGHT_REF_TIME_PER_SECOND, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients,
45	WeightToFeePolynomial,
46};
47pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
48pub use sp_runtime::{MultiAddress, Perbill, Permill};
49
50#[cfg(any(feature = "std", test))]
51pub use sp_runtime::BuildStorage;
52
53use weights::ExtrinsicBaseWeight;
54
55pub use bp_idn::types::{AccountId, Balance, BlockNumber, Signature, TreasuryAccount};
56
57/// Index of a transaction in the chain.
58pub type Nonce = u32;
59
60/// A hash of some data used by the chain.
61pub type Hash = sp_core::H256;
62
63/// The address format for describing accounts.
64pub type Address = MultiAddress<AccountId, ()>;
65
66/// Block header type as expected by this runtime.
67pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
68
69/// Block type as expected by this runtime.
70pub type Block = generic::Block<Header, UncheckedExtrinsic>;
71
72/// A Block signed with a Justification
73pub type SignedBlock = generic::SignedBlock<Block>;
74
75/// BlockId type as expected by this runtime.
76pub type BlockId = generic::BlockId<Block>;
77
78// Export pallet_balances::Call for use in contracts pallet
79pub use pallet_balances::Call as BalancesCall;
80
81/// The SignedExtension to the basic transaction logic.
82#[docify::export(template_signed_extra)]
83pub type TxExtension = (
84	frame_system::CheckNonZeroSender<Runtime>,
85	frame_system::CheckSpecVersion<Runtime>,
86	frame_system::CheckTxVersion<Runtime>,
87	frame_system::CheckGenesis<Runtime>,
88	frame_system::CheckEra<Runtime>,
89	frame_system::CheckNonce<Runtime>,
90	frame_system::CheckWeight<Runtime>,
91	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
92	frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
93	frame_system::WeightReclaim<Runtime>,
94);
95
96/// Unchecked extrinsic type as expected by this runtime.
97pub type UncheckedExtrinsic =
98	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
99
100/// Migrations to apply on runtime upgrade.
101pub type Migrations = pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>;
102
103/// Executive: handles dispatch to the various modules.
104pub type Executive = frame_executive::Executive<
105	Runtime,
106	Block,
107	frame_system::ChainContext<Runtime>,
108	Runtime,
109	AllPalletsWithSystem,
110	Migrations,
111>;
112
113/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the
114/// node's balance type.
115///
116/// This should typically create a mapping between the following ranges:
117///   - `[0, MAXIMUM_BLOCK_WEIGHT]`
118///   - `[Balance::min, Balance::max]`
119///
120/// Yet, it can be used for any other sort of change to weight-fee. Some examples being:
121///   - Setting it to `0` will essentially disable the weight fee.
122///   - Setting it to `1` will cause the literal `#[weight = x]` values to be charged.
123pub struct WeightToFee;
124impl WeightToFeePolynomial for WeightToFee {
125	type Balance = Balance;
126	fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
127		// in Rococo, extrinsic base weight (smallest non-zero weight) is mapped to 1 MILLIUNIT:
128		// in our template, we map to 1/10 of that, or 1/10 MILLIUNIT
129		let p = MILLIUNIT / 10;
130		let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
131		smallvec![WeightToFeeCoefficient {
132			degree: 1,
133			negative: false,
134			coeff_frac: Perbill::from_rational(p % q, q),
135			coeff_integer: p / q,
136		}]
137	}
138}
139
140/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
141/// the specifics of the runtime. They can then be made to be agnostic over specific formats
142/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
143/// to even the core data structures.
144pub mod opaque {
145	use super::*;
146	use sp_runtime::{
147		generic,
148		traits::{BlakeTwo256, Hash as HashT},
149	};
150
151	pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
152	/// Opaque block header type.
153	pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
154	/// Opaque block type.
155	pub type Block = generic::Block<Header, UncheckedExtrinsic>;
156	/// Opaque block identifier type.
157	pub type BlockId = generic::BlockId<Block>;
158	/// Opaque block hash type.
159	pub type Hash = <BlakeTwo256 as HashT>::Output;
160}
161
162impl_opaque_keys! {
163	pub struct SessionKeys {
164		pub aura: Aura,
165	}
166}
167
168#[sp_version::runtime_version]
169pub const VERSION: RuntimeVersion = RuntimeVersion {
170	spec_name: Cow::Borrowed("idn-runtime"),
171	impl_name: Cow::Borrowed("idn-runtime"),
172	authoring_version: 1,
173	spec_version: 7,
174	impl_version: 0,
175	apis: apis::RUNTIME_API_VERSIONS,
176	transaction_version: 1,
177	system_version: 1,
178};
179
180/// This determines the average expected block time that we are targeting.
181/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`.
182/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked
183/// up by `pallet_aura` to implement `fn slot_duration()`.
184///
185/// Change this to adjust the block time.
186pub const MILLISECS_PER_BLOCK: u64 = 6000;
187
188// NOTE: Currently it is not possible to change the slot duration after the chain has started.
189//       Attempting to do so will brick block production.
190pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
191
192// Time is measured by number of blocks.
193pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
194pub const HOURS: BlockNumber = MINUTES * 60;
195pub const DAYS: BlockNumber = HOURS * 24;
196
197// Unit = the base number of indivisible units for balances
198pub const UNIT: Balance = 1_000_000_000_000;
199pub const CENTIUNIT: Balance = 10_000_000_000;
200pub const MILLIUNIT: Balance = 1_000_000_000;
201pub const MICROUNIT: Balance = 1_000_000;
202
203/// The existential deposit. Set to 1/10 of the Connected Relay Chain.
204pub const EXISTENTIAL_DEPOSIT: Balance = MILLIUNIT;
205
206/// We assume that ~5% of the block weight is consumed by `on_initialize` handlers. This is
207/// used to limit the maximal weight of a single extrinsic.
208const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5);
209
210/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used by
211/// `Operational` extrinsics.
212const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
213
214/// We allow for 2 seconds of compute with a 6-second average block.
215const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(
216	WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2),
217	cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64,
218);
219
220/// Maximum number of blocks simultaneously accepted by the Runtime, not yet included
221/// into the relay chain.
222const 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.
225const BLOCK_PROCESSING_VELOCITY: u32 = 1;
226/// Relay chain slot duration, in milliseconds.
227const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000;
228
229/// Aura consensus hook
230type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
231	Runtime,
232	RELAY_CHAIN_SLOT_DURATION_MILLIS,
233	BLOCK_PROCESSING_VELOCITY,
234	UNINCLUDED_SEGMENT_CAPACITY,
235>;
236
237/// The version information used to identify this runtime when compiled natively.
238#[cfg(feature = "std")]
239pub fn native_version() -> NativeVersion {
240	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
241}
242
243#[frame_support::runtime]
244mod runtime {
245	// Create the runtime by composing the FRAME pallets that were previously configured.
246	#[runtime::runtime]
247	#[runtime::derive(
248		RuntimeCall,
249		RuntimeEvent,
250		RuntimeError,
251		RuntimeOrigin,
252		RuntimeFreezeReason,
253		RuntimeHoldReason,
254		RuntimeSlashReason,
255		RuntimeLockId,
256		RuntimeTask
257	)]
258	pub struct Runtime;
259
260	// System support stuff.
261	#[runtime::pallet_index(0)]
262	pub type System = frame_system::Pallet<Runtime>;
263	#[runtime::pallet_index(1)]
264	pub type ParachainSystem = cumulus_pallet_parachain_system::Pallet<Runtime>;
265	#[runtime::pallet_index(2)]
266	pub type Timestamp = pallet_timestamp::Pallet<Runtime>;
267	#[runtime::pallet_index(3)]
268	pub type ParachainInfo = parachain_info::Pallet<Runtime>;
269
270	// Monetary stuff.
271	#[runtime::pallet_index(10)]
272	pub type Balances = pallet_balances::Pallet<Runtime>;
273	#[runtime::pallet_index(11)]
274	pub type TransactionPayment = pallet_transaction_payment::Pallet<Runtime>;
275
276	// Governance
277	#[runtime::pallet_index(15)]
278	pub type Sudo = pallet_sudo;
279
280	// Collator support. The order of these 4 are important and shall not change.
281	#[runtime::pallet_index(20)]
282	pub type Authorship = pallet_authorship::Pallet<Runtime>;
283	#[runtime::pallet_index(21)]
284	pub type CollatorSelection = pallet_collator_selection::Pallet<Runtime>;
285	#[runtime::pallet_index(22)]
286	pub type Session = pallet_session::Pallet<Runtime>;
287	#[runtime::pallet_index(23)]
288	pub type Aura = pallet_aura::Pallet<Runtime>;
289	#[runtime::pallet_index(24)]
290	pub type AuraExt = cumulus_pallet_aura_ext;
291
292	// XCM helpers.
293	#[runtime::pallet_index(30)]
294	pub type XcmpQueue = cumulus_pallet_xcmp_queue::Pallet<Runtime>;
295	#[runtime::pallet_index(31)]
296	pub type PolkadotXcm = pallet_xcm::Pallet<Runtime>;
297	#[runtime::pallet_index(32)]
298	pub type CumulusXcm = cumulus_pallet_xcm::Pallet<Runtime>;
299	#[runtime::pallet_index(33)]
300	pub type MessageQueue = pallet_message_queue::Pallet<Runtime>;
301
302	// IDN
303	// This index must be the same as the one defined in the
304	// [`bp_idn::Call::IdnManager`]
305	#[runtime::pallet_index(40)]
306	pub type IdnManager = pallet_idn_manager::Pallet<Runtime>;
307	#[runtime::pallet_index(41)]
308	pub type RandBeacon = pallet_randomness_beacon::Pallet<Runtime>;
309
310	// Contracts
311	#[runtime::pallet_index(50)]
312	pub type Contracts = pallet_contracts::Pallet<Runtime>;
313	#[runtime::pallet_index(51)]
314	pub type RandomnessCollectiveFlip = pallet_insecure_randomness_collective_flip::Pallet<Runtime>;
315}
316
317type EventRecord = frame_system::EventRecord<
318	<Runtime as frame_system::Config>::RuntimeEvent,
319	<Runtime as frame_system::Config>::Hash,
320>;
321
322// Defines debug output of the `revive` pallet to stdout if the node is
323// started with `-lruntime::revive=trace` or `-lruntime::contracts=debug`.
324const CONTRACTS_DEBUG_OUTPUT: pallet_contracts::DebugInfo = pallet_contracts::DebugInfo::Skip;
325const CONTRACTS_EVENTS: pallet_contracts::CollectEvents = pallet_contracts::CollectEvents::Skip;
326
327cumulus_pallet_parachain_system::register_validate_block! {
328	Runtime = Runtime,
329	BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
330}