referrerpolicy=no-referrer-when-downgrade

revive_dev_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#![cfg_attr(not(feature = "std"), no_std)]
19
20// Make the WASM binary available.
21#[cfg(feature = "std")]
22include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
23
24extern crate alloc;
25
26use alloc::{vec, vec::Vec};
27use currency::*;
28use frame_support::weights::{
29	constants::{BlockExecutionWeight, ExtrinsicBaseWeight, WEIGHT_REF_TIME_PER_SECOND},
30	Weight,
31};
32use frame_system::limits::BlockWeights;
33use pallet_revive::{evm::runtime::EthExtra, AccountId32Mapper};
34use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
35use polkadot_sdk::{
36	polkadot_sdk_frame::{
37		deps::sp_genesis_builder,
38		runtime::{apis, prelude::*},
39	},
40	*,
41};
42use sp_weights::{ConstantMultiplier, IdentityFee};
43
44pub use polkadot_sdk::{
45	parachains_common::{AccountId, Balance, BlockNumber, Hash, Header, Nonce, Signature},
46	polkadot_sdk_frame::runtime::types_common::OpaqueBlock,
47};
48
49pub mod currency {
50	use super::Balance;
51	pub const MILLICENTS: Balance = 1_000_000_000;
52	pub const CENTS: Balance = 1_000 * MILLICENTS;
53	pub const DOLLARS: Balance = 100 * CENTS;
54}
55
56/// Provides getters for genesis configuration presets.
57pub mod genesis_config_presets {
58	use super::*;
59	use crate::{
60		currency::DOLLARS, sp_keyring::Sr25519Keyring, Balance, BalancesConfig,
61		RuntimeGenesisConfig, SudoConfig,
62	};
63
64	use alloc::{vec, vec::Vec};
65	use serde_json::Value;
66
67	pub const ENDOWMENT: Balance = 1_001 * DOLLARS;
68
69	fn well_known_accounts() -> Vec<AccountId> {
70		Sr25519Keyring::well_known()
71			.map(|k| k.to_account_id())
72			.chain([
73				// subxt_signer::eth::dev::alith()
74				array_bytes::hex_n_into_unchecked(
75					"f24ff3a9cf04c71dbc94d0b566f7a27b94566caceeeeeeeeeeeeeeeeeeeeeeee",
76				),
77				// subxt_signer::eth::dev::baltathar()
78				array_bytes::hex_n_into_unchecked(
79					"3cd0a705a2dc65e5b1e1205896baa2be8a07c6e0eeeeeeeeeeeeeeeeeeeeeeee",
80				),
81			])
82			.collect::<Vec<_>>()
83	}
84
85	/// Returns a development genesis config preset.
86	pub fn development_config_genesis() -> Value {
87		frame_support::build_struct_json_patch!(RuntimeGenesisConfig {
88			balances: BalancesConfig {
89				balances: well_known_accounts()
90					.into_iter()
91					.map(|id| (id, ENDOWMENT))
92					.collect::<Vec<_>>(),
93			},
94			sudo: SudoConfig { key: Some(Sr25519Keyring::Alice.to_account_id()) },
95		})
96	}
97
98	/// Get the set of the available genesis config presets.
99	pub fn get_preset(id: &PresetId) -> Option<Vec<u8>> {
100		let patch = match id.as_ref() {
101			sp_genesis_builder::DEV_RUNTIME_PRESET => development_config_genesis(),
102			_ => return None,
103		};
104		Some(
105			serde_json::to_string(&patch)
106				.expect("serialization to json is expected to work. qed.")
107				.into_bytes(),
108		)
109	}
110
111	/// List of supported presets.
112	pub fn preset_names() -> Vec<PresetId> {
113		vec![PresetId::from(sp_genesis_builder::DEV_RUNTIME_PRESET)]
114	}
115}
116
117/// The runtime version.
118#[runtime_version]
119pub const VERSION: RuntimeVersion = RuntimeVersion {
120	spec_name: alloc::borrow::Cow::Borrowed("revive-dev-runtime"),
121	impl_name: alloc::borrow::Cow::Borrowed("revive-dev-runtime"),
122	authoring_version: 1,
123	spec_version: 0,
124	impl_version: 1,
125	apis: RUNTIME_API_VERSIONS,
126	transaction_version: 1,
127	system_version: 1,
128};
129
130/// The version information used to identify this runtime when compiled natively.
131#[cfg(feature = "std")]
132pub fn native_version() -> NativeVersion {
133	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
134}
135
136/// The address format for describing accounts.
137pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
138/// Block type as expected by this runtime.
139pub type Block = sp_runtime::generic::Block<Header, UncheckedExtrinsic>;
140/// The transaction extensions that are added to the runtime.
141type TxExtension = (
142	// Checks that the sender is not the zero address.
143	frame_system::CheckNonZeroSender<Runtime>,
144	// Checks that the runtime version is correct.
145	frame_system::CheckSpecVersion<Runtime>,
146	// Checks that the transaction version is correct.
147	frame_system::CheckTxVersion<Runtime>,
148	// Checks that the genesis hash is correct.
149	frame_system::CheckGenesis<Runtime>,
150	// Checks that the era is valid.
151	frame_system::CheckEra<Runtime>,
152	// Checks that the nonce is valid.
153	frame_system::CheckNonce<Runtime>,
154	// Checks that the weight is valid.
155	frame_system::CheckWeight<Runtime>,
156	// Ensures that the sender has enough funds to pay for the transaction
157	// and deducts the fee from the sender's account.
158	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
159	// Reclaim the unused weight from the block using post dispatch information.
160	// It must be last in the pipeline in order to catch the refund in previous transaction
161	// extensions
162	frame_system::WeightReclaim<Runtime>,
163);
164
165/// Default extensions applied to Ethereum transactions.
166#[derive(Clone, PartialEq, Eq, Debug)]
167pub struct EthExtraImpl;
168
169impl EthExtra for EthExtraImpl {
170	type Config = Runtime;
171	type Extension = TxExtension;
172
173	fn get_eth_extension(nonce: u32, tip: Balance) -> Self::Extension {
174		(
175			frame_system::CheckNonZeroSender::<Runtime>::new(),
176			frame_system::CheckSpecVersion::<Runtime>::new(),
177			frame_system::CheckTxVersion::<Runtime>::new(),
178			frame_system::CheckGenesis::<Runtime>::new(),
179			frame_system::CheckMortality::from(sp_runtime::generic::Era::Immortal),
180			frame_system::CheckNonce::<Runtime>::from(nonce),
181			frame_system::CheckWeight::<Runtime>::new(),
182			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
183			frame_system::WeightReclaim::<Runtime>::new(),
184		)
185	}
186}
187
188pub type UncheckedExtrinsic =
189	pallet_revive::evm::runtime::UncheckedExtrinsic<Address, Signature, EthExtraImpl>;
190
191type Executive = frame_executive::Executive<
192	Runtime,
193	Block,
194	frame_system::ChainContext<Runtime>,
195	Runtime,
196	AllPalletsWithSystem,
197>;
198
199// Composes the runtime by adding all the used pallets and deriving necessary types.
200#[frame_construct_runtime]
201mod runtime {
202	/// The main runtime type.
203	#[runtime::runtime]
204	#[runtime::derive(
205		RuntimeCall,
206		RuntimeEvent,
207		RuntimeError,
208		RuntimeOrigin,
209		RuntimeFreezeReason,
210		RuntimeHoldReason,
211		RuntimeSlashReason,
212		RuntimeLockId,
213		RuntimeTask,
214		RuntimeViewFunction
215	)]
216	pub struct Runtime;
217
218	/// Mandatory system pallet that should always be included in a FRAME runtime.
219	#[runtime::pallet_index(0)]
220	pub type System = frame_system::Pallet<Runtime>;
221
222	/// Provides a way for consensus systems to set and check the onchain time.
223	#[runtime::pallet_index(1)]
224	pub type Timestamp = pallet_timestamp::Pallet<Runtime>;
225
226	/// Provides the ability to keep track of balances.
227	#[runtime::pallet_index(2)]
228	pub type Balances = pallet_balances::Pallet<Runtime>;
229
230	/// Provides a way to execute privileged functions.
231	#[runtime::pallet_index(3)]
232	pub type Sudo = pallet_sudo::Pallet<Runtime>;
233
234	/// Provides the ability to charge for extrinsic execution.
235	#[runtime::pallet_index(4)]
236	pub type TransactionPayment = pallet_transaction_payment::Pallet<Runtime>;
237
238	/// Provides the ability to execute Smart Contracts.
239	#[runtime::pallet_index(5)]
240	pub type Revive = pallet_revive::Pallet<Runtime>;
241}
242
243/// We assume that ~10% of the block weight is consumed by `on_initialize` handlers.
244/// This is used to limit the maximal weight of a single extrinsic.
245const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
246/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used
247/// by  Operational  extrinsics.
248const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
249/// We allow for 2 seconds of compute with a 6 second average block time, with maximum proof size.
250const MAXIMUM_BLOCK_WEIGHT: Weight =
251	Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX);
252
253parameter_types! {
254	pub const Version: RuntimeVersion = VERSION;
255	pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
256		.base_block(BlockExecutionWeight::get())
257		.for_class(DispatchClass::all(), |weights| {
258			weights.base_extrinsic = ExtrinsicBaseWeight::get();
259		})
260		.for_class(DispatchClass::Normal, |weights| {
261			weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
262		})
263		.for_class(DispatchClass::Operational, |weights| {
264			weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
265			// Operational transactions have some extra reserved space, so that they
266			// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
267			weights.reserved = Some(
268				MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
269			);
270		})
271		.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
272		.build_or_panic();
273}
274
275/// Implements the types required for the system pallet.
276#[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)]
277impl frame_system::Config for Runtime {
278	type Block = Block;
279	type Version = Version;
280	type AccountId = AccountId;
281	type Hash = Hash;
282	type Nonce = Nonce;
283	type AccountData = pallet_balances::AccountData<<Runtime as pallet_balances::Config>::Balance>;
284}
285
286parameter_types! {
287	pub const ExistentialDeposit: Balance = DOLLARS;
288}
289
290// Implements the types required for the balances pallet.
291#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)]
292impl pallet_balances::Config for Runtime {
293	type AccountStore = System;
294	type Balance = Balance;
295	type ExistentialDeposit = ExistentialDeposit;
296}
297
298// Implements the types required for the sudo pallet.
299#[derive_impl(pallet_sudo::config_preludes::TestDefaultConfig)]
300impl pallet_sudo::Config for Runtime {}
301
302// Implements the types required for the sudo pallet.
303#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig)]
304impl pallet_timestamp::Config for Runtime {}
305
306parameter_types! {
307	pub const TransactionByteFee: Balance = 10 * MILLICENTS;
308}
309
310// Implements the types required for the transaction payment pallet.
311#[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig)]
312impl pallet_transaction_payment::Config for Runtime {
313	type OnChargeTransaction = pallet_transaction_payment::FungibleAdapter<Balances, ()>;
314	type WeightToFee = IdentityFee<Balance>;
315	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
316}
317
318parameter_types! {
319	pub CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(30);
320}
321
322#[derive_impl(pallet_revive::config_preludes::TestDefaultConfig)]
323impl pallet_revive::Config for Runtime {
324	type AddressMapper = AccountId32Mapper<Self>;
325	type ChainId = ConstU64<420_420_420>;
326	type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
327	type Currency = Balances;
328	type NativeToEthRatio = ConstU32<1_000_000>;
329	type UploadOrigin = EnsureSigned<Self::AccountId>;
330	type InstantiateOrigin = EnsureSigned<Self::AccountId>;
331	type Time = Timestamp;
332}
333
334pallet_revive::impl_runtime_apis_plus_revive!(
335	Runtime,
336	Executive,
337	EthExtraImpl,
338
339	impl apis::Core<Block> for Runtime {
340		fn version() -> RuntimeVersion {
341			VERSION
342		}
343
344		fn execute_block(block: Block) {
345			Executive::execute_block(block)
346		}
347
348		fn initialize_block(header: &Header) -> ExtrinsicInclusionMode {
349			Executive::initialize_block(header)
350		}
351	}
352
353	impl apis::Metadata<Block> for Runtime {
354		fn metadata() -> OpaqueMetadata {
355			OpaqueMetadata::new(Runtime::metadata().into())
356		}
357
358		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
359			Runtime::metadata_at_version(version)
360		}
361
362		fn metadata_versions() -> Vec<u32> {
363			Runtime::metadata_versions()
364		}
365	}
366
367	impl apis::BlockBuilder<Block> for Runtime {
368		fn apply_extrinsic(extrinsic: ExtrinsicFor<Runtime>) -> ApplyExtrinsicResult {
369			Executive::apply_extrinsic(extrinsic)
370		}
371
372		fn finalize_block() -> HeaderFor<Runtime> {
373			Executive::finalize_block()
374		}
375
376		fn inherent_extrinsics(data: InherentData) -> Vec<ExtrinsicFor<Runtime>> {
377			data.create_extrinsics()
378		}
379
380		fn check_inherents(
381			block: Block,
382			data: InherentData,
383		) -> CheckInherentsResult {
384			data.check_extrinsics(&block)
385		}
386	}
387
388	impl apis::TaggedTransactionQueue<Block> for Runtime {
389		fn validate_transaction(
390			source: TransactionSource,
391			tx: ExtrinsicFor<Runtime>,
392			block_hash: <Runtime as frame_system::Config>::Hash,
393		) -> TransactionValidity {
394			Executive::validate_transaction(source, tx, block_hash)
395		}
396	}
397
398	impl apis::OffchainWorkerApi<Block> for Runtime {
399		fn offchain_worker(header: &HeaderFor<Runtime>) {
400			Executive::offchain_worker(header)
401		}
402	}
403
404	impl apis::SessionKeys<Block> for Runtime {
405		fn generate_session_keys(_seed: Option<Vec<u8>>) -> Vec<u8> {
406			Default::default()
407		}
408
409		fn decode_session_keys(
410			_encoded: Vec<u8>,
411		) -> Option<Vec<(Vec<u8>, apis::KeyTypeId)>> {
412			Default::default()
413		}
414	}
415
416	impl apis::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
417		fn account_nonce(account: AccountId) -> Nonce {
418			System::account_nonce(account)
419		}
420	}
421
422	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
423		Block,
424		Balance,
425	> for Runtime {
426		fn query_info(uxt: ExtrinsicFor<Runtime>, len: u32) -> RuntimeDispatchInfo<Balance> {
427			TransactionPayment::query_info(uxt, len)
428		}
429		fn query_fee_details(uxt: ExtrinsicFor<Runtime>, len: u32) -> FeeDetails<Balance> {
430			TransactionPayment::query_fee_details(uxt, len)
431		}
432		fn query_weight_to_fee(weight: Weight) -> Balance {
433			TransactionPayment::weight_to_fee(weight)
434		}
435		fn query_length_to_fee(length: u32) -> Balance {
436			TransactionPayment::length_to_fee(length)
437		}
438	}
439
440	impl apis::GenesisBuilder<Block> for Runtime {
441		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
442			build_state::<RuntimeGenesisConfig>(config)
443		}
444
445		fn get_preset(id: &Option<PresetId>) -> Option<Vec<u8>> {
446			get_preset::<RuntimeGenesisConfig>(id, self::genesis_config_presets::get_preset)
447		}
448
449		fn preset_names() -> Vec<PresetId> {
450			self::genesis_config_presets::preset_names()
451		}
452	}
453);