1#![cfg_attr(not(feature = "std"), no_std)]
19
20#[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
56pub 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 array_bytes::hex_n_into_unchecked(
75 "f24ff3a9cf04c71dbc94d0b566f7a27b94566caceeeeeeeeeeeeeeeeeeeeeeee",
76 ),
77 array_bytes::hex_n_into_unchecked(
79 "3cd0a705a2dc65e5b1e1205896baa2be8a07c6e0eeeeeeeeeeeeeeeeeeeeeeee",
80 ),
81 ])
82 .collect::<Vec<_>>()
83 }
84
85 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 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 pub fn preset_names() -> Vec<PresetId> {
113 vec![PresetId::from(sp_genesis_builder::DEV_RUNTIME_PRESET)]
114 }
115}
116
117#[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#[cfg(feature = "std")]
132pub fn native_version() -> NativeVersion {
133 NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
134}
135
136pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
138pub type Block = sp_runtime::generic::Block<Header, UncheckedExtrinsic>;
140type TxExtension = (
142 frame_system::CheckNonZeroSender<Runtime>,
144 frame_system::CheckSpecVersion<Runtime>,
146 frame_system::CheckTxVersion<Runtime>,
148 frame_system::CheckGenesis<Runtime>,
150 frame_system::CheckEra<Runtime>,
152 frame_system::CheckNonce<Runtime>,
154 frame_system::CheckWeight<Runtime>,
156 pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
159 frame_system::WeightReclaim<Runtime>,
163);
164
165#[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#[frame_construct_runtime]
201mod runtime {
202 #[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 #[runtime::pallet_index(0)]
220 pub type System = frame_system::Pallet<Runtime>;
221
222 #[runtime::pallet_index(1)]
224 pub type Timestamp = pallet_timestamp::Pallet<Runtime>;
225
226 #[runtime::pallet_index(2)]
228 pub type Balances = pallet_balances::Pallet<Runtime>;
229
230 #[runtime::pallet_index(3)]
232 pub type Sudo = pallet_sudo::Pallet<Runtime>;
233
234 #[runtime::pallet_index(4)]
236 pub type TransactionPayment = pallet_transaction_payment::Pallet<Runtime>;
237
238 #[runtime::pallet_index(5)]
240 pub type Revive = pallet_revive::Pallet<Runtime>;
241}
242
243const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
246const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
249const 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 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#[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#[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#[derive_impl(pallet_sudo::config_preludes::TestDefaultConfig)]
300impl pallet_sudo::Config for Runtime {}
301
302#[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#[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);