referrerpolicy=no-referrer-when-downgrade

minimal_template_runtime/
lib.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! A minimal runtime that includes the template [`pallet`](`pallet_minimal_template`).
19
20#![cfg_attr(not(feature = "std"), no_std)]
21
22// Make the WASM binary available.
23#[cfg(feature = "std")]
24include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
25
26extern crate alloc;
27
28use alloc::vec::Vec;
29use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
30use polkadot_sdk::{
31	polkadot_sdk_frame::{
32		self as frame,
33		deps::sp_genesis_builder,
34		runtime::{apis, prelude::*},
35	},
36	*,
37};
38
39/// Provides getters for genesis configuration presets.
40pub mod genesis_config_presets {
41	use super::*;
42	use crate::{
43		interface::{Balance, MinimumBalance},
44		sp_keyring::Sr25519Keyring,
45		BalancesConfig, RuntimeGenesisConfig, SudoConfig,
46	};
47
48	use alloc::{vec, vec::Vec};
49	use serde_json::Value;
50
51	/// Returns a development genesis config preset.
52	pub fn development_config_genesis() -> Value {
53		let endowment = <MinimumBalance as Get<Balance>>::get().max(1) * 1000;
54		frame_support::build_struct_json_patch!(RuntimeGenesisConfig {
55			balances: BalancesConfig {
56				balances: Sr25519Keyring::iter()
57					.map(|a| (a.to_account_id(), endowment))
58					.collect::<Vec<_>>(),
59			},
60			sudo: SudoConfig { key: Some(Sr25519Keyring::Alice.to_account_id()) },
61		})
62	}
63
64	/// Get the set of the available genesis config presets.
65	pub fn get_preset(id: &PresetId) -> Option<Vec<u8>> {
66		let patch = match id.as_ref() {
67			sp_genesis_builder::DEV_RUNTIME_PRESET => development_config_genesis(),
68			_ => return None,
69		};
70		Some(
71			serde_json::to_string(&patch)
72				.expect("serialization to json is expected to work. qed.")
73				.into_bytes(),
74		)
75	}
76
77	/// List of supported presets.
78	pub fn preset_names() -> Vec<PresetId> {
79		vec![PresetId::from(sp_genesis_builder::DEV_RUNTIME_PRESET)]
80	}
81}
82
83/// The runtime version.
84#[runtime_version]
85pub const VERSION: RuntimeVersion = RuntimeVersion {
86	spec_name: alloc::borrow::Cow::Borrowed("minimal-template-runtime"),
87	impl_name: alloc::borrow::Cow::Borrowed("minimal-template-runtime"),
88	authoring_version: 1,
89	spec_version: 0,
90	impl_version: 1,
91	apis: RUNTIME_API_VERSIONS,
92	transaction_version: 1,
93	system_version: 1,
94};
95
96/// The version information used to identify this runtime when compiled natively.
97#[cfg(feature = "std")]
98pub fn native_version() -> NativeVersion {
99	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
100}
101
102/// The transaction extensions that are added to the runtime.
103type TxExtension = (
104	// Authorize calls that validate themselves.
105	frame_system::AuthorizeCall<Runtime>,
106	// Checks that the sender is not the zero address.
107	frame_system::CheckNonZeroSender<Runtime>,
108	// Checks that the runtime version is correct.
109	frame_system::CheckSpecVersion<Runtime>,
110	// Checks that the transaction version is correct.
111	frame_system::CheckTxVersion<Runtime>,
112	// Checks that the genesis hash is correct.
113	frame_system::CheckGenesis<Runtime>,
114	// Checks that the era is valid.
115	frame_system::CheckEra<Runtime>,
116	// Checks that the nonce is valid.
117	frame_system::CheckNonce<Runtime>,
118	// Checks that the weight is valid.
119	frame_system::CheckWeight<Runtime>,
120	// Ensures that the sender has enough funds to pay for the transaction
121	// and deducts the fee from the sender's account.
122	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
123	// Reclaim the unused weight from the block using post dispatch information.
124	// It must be last in the pipeline in order to catch the refund in previous transaction
125	// extensions
126	frame_system::WeightReclaim<Runtime>,
127);
128
129// Composes the runtime by adding all the used pallets and deriving necessary types.
130#[frame_construct_runtime]
131mod runtime {
132	/// The main runtime type.
133	#[runtime::runtime]
134	#[runtime::derive(
135		RuntimeCall,
136		RuntimeEvent,
137		RuntimeError,
138		RuntimeOrigin,
139		RuntimeFreezeReason,
140		RuntimeHoldReason,
141		RuntimeSlashReason,
142		RuntimeLockId,
143		RuntimeTask,
144		RuntimeViewFunction
145	)]
146	pub struct Runtime;
147
148	/// Mandatory system pallet that should always be included in a FRAME runtime.
149	#[runtime::pallet_index(0)]
150	pub type System = frame_system::Pallet<Runtime>;
151
152	/// Provides a way for consensus systems to set and check the onchain time.
153	#[runtime::pallet_index(1)]
154	pub type Timestamp = pallet_timestamp::Pallet<Runtime>;
155
156	/// Provides the ability to keep track of balances.
157	#[runtime::pallet_index(2)]
158	pub type Balances = pallet_balances::Pallet<Runtime>;
159
160	/// Provides a way to execute privileged functions.
161	#[runtime::pallet_index(3)]
162	pub type Sudo = pallet_sudo::Pallet<Runtime>;
163
164	/// Provides the ability to charge for extrinsic execution.
165	#[runtime::pallet_index(4)]
166	pub type TransactionPayment = pallet_transaction_payment::Pallet<Runtime>;
167
168	/// A minimal pallet template.
169	#[runtime::pallet_index(5)]
170	pub type Template = pallet_minimal_template::Pallet<Runtime>;
171}
172
173parameter_types! {
174	pub const Version: RuntimeVersion = VERSION;
175}
176
177/// Implements the types required for the system pallet.
178#[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)]
179impl frame_system::Config for Runtime {
180	type Block = Block;
181	type Version = Version;
182	// Use the account data from the balances pallet
183	type AccountData = pallet_balances::AccountData<<Runtime as pallet_balances::Config>::Balance>;
184}
185
186// Implements the types required for the balances pallet.
187#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)]
188impl pallet_balances::Config for Runtime {
189	type AccountStore = System;
190}
191
192// Implements the types required for the sudo pallet.
193#[derive_impl(pallet_sudo::config_preludes::TestDefaultConfig)]
194impl pallet_sudo::Config for Runtime {}
195
196// Implements the types required for the sudo pallet.
197#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig)]
198impl pallet_timestamp::Config for Runtime {}
199
200// Implements the types required for the transaction payment pallet.
201#[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig)]
202impl pallet_transaction_payment::Config for Runtime {
203	type OnChargeTransaction = pallet_transaction_payment::FungibleAdapter<Balances, ()>;
204	// Setting fee as independent of the weight of the extrinsic for demo purposes
205	type WeightToFee = NoFee<<Self as pallet_balances::Config>::Balance>;
206	// Setting fee as fixed for any length of the call data for demo purposes
207	type LengthToFee = FixedFee<1, <Self as pallet_balances::Config>::Balance>;
208}
209
210// Implements the types required for the template pallet.
211impl pallet_minimal_template::Config for Runtime {}
212
213type Block = frame::runtime::types_common::BlockOf<Runtime, TxExtension>;
214type Header = HeaderFor<Runtime>;
215
216type RuntimeExecutive =
217	Executive<Runtime, Block, frame_system::ChainContext<Runtime>, Runtime, AllPalletsWithSystem>;
218
219impl_runtime_apis! {
220	impl apis::Core<Block> for Runtime {
221		fn version() -> RuntimeVersion {
222			VERSION
223		}
224
225		fn execute_block(block: Block) {
226			RuntimeExecutive::execute_block(block)
227		}
228
229		fn initialize_block(header: &Header) -> ExtrinsicInclusionMode {
230			RuntimeExecutive::initialize_block(header)
231		}
232	}
233	impl apis::Metadata<Block> for Runtime {
234		fn metadata() -> OpaqueMetadata {
235			OpaqueMetadata::new(Runtime::metadata().into())
236		}
237
238		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
239			Runtime::metadata_at_version(version)
240		}
241
242		fn metadata_versions() -> Vec<u32> {
243			Runtime::metadata_versions()
244		}
245	}
246
247	impl apis::BlockBuilder<Block> for Runtime {
248		fn apply_extrinsic(extrinsic: ExtrinsicFor<Runtime>) -> ApplyExtrinsicResult {
249			RuntimeExecutive::apply_extrinsic(extrinsic)
250		}
251
252		fn finalize_block() -> HeaderFor<Runtime> {
253			RuntimeExecutive::finalize_block()
254		}
255
256		fn inherent_extrinsics(data: InherentData) -> Vec<ExtrinsicFor<Runtime>> {
257			data.create_extrinsics()
258		}
259
260		fn check_inherents(
261			block: Block,
262			data: InherentData,
263		) -> CheckInherentsResult {
264			data.check_extrinsics(&block)
265		}
266	}
267
268	impl apis::TaggedTransactionQueue<Block> for Runtime {
269		fn validate_transaction(
270			source: TransactionSource,
271			tx: ExtrinsicFor<Runtime>,
272			block_hash: <Runtime as frame_system::Config>::Hash,
273		) -> TransactionValidity {
274			RuntimeExecutive::validate_transaction(source, tx, block_hash)
275		}
276	}
277
278	impl apis::OffchainWorkerApi<Block> for Runtime {
279		fn offchain_worker(header: &HeaderFor<Runtime>) {
280			RuntimeExecutive::offchain_worker(header)
281		}
282	}
283
284	impl apis::SessionKeys<Block> for Runtime {
285		fn generate_session_keys(_seed: Option<Vec<u8>>) -> Vec<u8> {
286			Default::default()
287		}
288
289		fn decode_session_keys(
290			_encoded: Vec<u8>,
291		) -> Option<Vec<(Vec<u8>, apis::KeyTypeId)>> {
292			Default::default()
293		}
294	}
295
296	impl apis::AccountNonceApi<Block, interface::AccountId, interface::Nonce> for Runtime {
297		fn account_nonce(account: interface::AccountId) -> interface::Nonce {
298			System::account_nonce(account)
299		}
300	}
301
302	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
303		Block,
304		interface::Balance,
305	> for Runtime {
306		fn query_info(uxt: ExtrinsicFor<Runtime>, len: u32) -> RuntimeDispatchInfo<interface::Balance> {
307			TransactionPayment::query_info(uxt, len)
308		}
309		fn query_fee_details(uxt: ExtrinsicFor<Runtime>, len: u32) -> FeeDetails<interface::Balance> {
310			TransactionPayment::query_fee_details(uxt, len)
311		}
312		fn query_weight_to_fee(weight: Weight) -> interface::Balance {
313			TransactionPayment::weight_to_fee(weight)
314		}
315		fn query_length_to_fee(length: u32) -> interface::Balance {
316			TransactionPayment::length_to_fee(length)
317		}
318	}
319
320	impl apis::GenesisBuilder<Block> for Runtime {
321		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
322			build_state::<RuntimeGenesisConfig>(config)
323		}
324
325		fn get_preset(id: &Option<PresetId>) -> Option<Vec<u8>> {
326			get_preset::<RuntimeGenesisConfig>(id, self::genesis_config_presets::get_preset)
327		}
328
329		fn preset_names() -> Vec<PresetId> {
330			self::genesis_config_presets::preset_names()
331		}
332	}
333}
334
335/// Some re-exports that the node side code needs to know. Some are useful in this context as well.
336///
337/// Other types should preferably be private.
338// TODO: this should be standardized in some way, see:
339// https://github.com/paritytech/substrate/issues/10579#issuecomment-1600537558
340pub mod interface {
341	use super::Runtime;
342	use polkadot_sdk::{polkadot_sdk_frame as frame, *};
343
344	pub type Block = super::Block;
345	pub use frame::runtime::types_common::OpaqueBlock;
346	pub type AccountId = <Runtime as frame_system::Config>::AccountId;
347	pub type Nonce = <Runtime as frame_system::Config>::Nonce;
348	pub type Hash = <Runtime as frame_system::Config>::Hash;
349	pub type Balance = <Runtime as pallet_balances::Config>::Balance;
350	pub type MinimumBalance = <Runtime as pallet_balances::Config>::ExistentialDeposit;
351}