1#![cfg_attr(not(feature = "std"), no_std)]
2#![recursion_limit = "256"]
4
5#[cfg(feature = "std")]
7include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
8
9mod assets_config;
10mod contracts_config;
11mod revive_config;
12
13extern crate alloc;
14use alloc::vec::Vec;
15use frame_support::{
16 derive_impl,
17 dispatch::DispatchClass,
18 genesis_builder_helper::{build_state, get_preset},
19};
20use frame_system::limits::{BlockLength, BlockWeights};
21use polkadot_runtime_common::SlowAdjustingFeeUpdate;
22use sp_api::impl_runtime_apis;
23use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
24use sp_runtime::{
25 create_runtime_str, generic, impl_opaque_keys,
26 traits::{BlakeTwo256, Block as BlockT, IdentifyAccount, Verify},
27 transaction_validity::{TransactionSource, TransactionValidity},
28 ApplyExtrinsicResult, MultiSignature,
29};
30#[cfg(feature = "std")]
31use sp_version::NativeVersion;
32use sp_version::RuntimeVersion;
33
34pub use frame_support::{
36 construct_runtime, parameter_types,
37 traits::{
38 AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU8, KeyOwnerProofSystem,
39 Randomness, StorageInfo,
40 },
41 weights::{
42 constants::{
43 BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND,
44 },
45 IdentityFee, Weight,
46 },
47 StorageValue,
48};
49pub use frame_system::Call as SystemCall;
50pub use pallet_balances::Call as BalancesCall;
51pub use pallet_timestamp::Call as TimestampCall;
52use pallet_transaction_payment::FungibleAdapter;
53#[cfg(any(feature = "std", test))]
54pub use sp_runtime::BuildStorage;
55pub use sp_runtime::{Perbill, Permill};
56
57pub type BlockNumber = u32;
59
60pub type Signature = MultiSignature;
62
63pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
66
67pub type Balance = u128;
69
70pub type Nonce = u32;
72
73pub type Hash = sp_core::H256;
75
76pub mod opaque {
81 use super::*;
82
83 pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
84
85 pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
87 pub type Block = generic::Block<Header, UncheckedExtrinsic>;
89 pub type BlockId = generic::BlockId<Block>;
91
92 impl_opaque_keys! {
93 pub struct SessionKeys {}
94 }
95}
96#[sp_version::runtime_version]
99pub const VERSION: RuntimeVersion = RuntimeVersion {
100 spec_name: create_runtime_str!("substrate-contracts-node"),
101 impl_name: create_runtime_str!("substrate-contracts-node"),
102 authoring_version: 1,
103 spec_version: 100,
109 impl_version: 1,
110 apis: RUNTIME_API_VERSIONS,
111 transaction_version: 1,
112 state_version: 1,
113};
114
115#[cfg(feature = "std")]
117pub fn native_version() -> NativeVersion {
118 NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
119}
120
121const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
122
123const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
126
127const MAXIMUM_BLOCK_WEIGHT: Weight =
129 Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX);
130
131const CONTRACTS_DEBUG_OUTPUT: pallet_contracts::DebugInfo =
134 pallet_contracts::DebugInfo::UnsafeDebug;
135const CONTRACTS_EVENTS: pallet_contracts::CollectEvents =
136 pallet_contracts::CollectEvents::UnsafeCollect;
137const REVIVE_DEBUG_OUTPUT: pallet_revive::DebugInfo = pallet_revive::DebugInfo::UnsafeDebug;
138const REVIVE_EVENTS: pallet_revive::CollectEvents = pallet_revive::CollectEvents::UnsafeCollect;
139
140const MILLIUNIT: Balance = 1_000_000_000;
142pub const EXISTENTIAL_DEPOSIT: Balance = MILLIUNIT;
143
144impl pallet_insecure_randomness_collective_flip::Config for Runtime {}
145
146parameter_types! {
147 pub const BlockHashCount: BlockNumber = 2400;
148 pub const Version: RuntimeVersion = VERSION;
149
150 pub RuntimeBlockLength: BlockLength =
155 BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
156 pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
157 .base_block(BlockExecutionWeight::get())
158 .for_class(DispatchClass::all(), |weights| {
159 weights.base_extrinsic = ExtrinsicBaseWeight::get();
160 })
161 .for_class(DispatchClass::Normal, |weights| {
162 weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
163 })
164 .for_class(DispatchClass::Operational, |weights| {
165 weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
166 weights.reserved = Some(
169 MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
170 );
171 })
172 .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
173 .build_or_panic();
174
175 pub const SS58Prefix: u8 = 42;
176}
177
178#[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)]
181impl frame_system::Config for Runtime {
182 type Block = Block;
184 type BlockWeights = RuntimeBlockWeights;
186 type BlockLength = RuntimeBlockLength;
188 type AccountId = AccountId;
190 type Nonce = Nonce;
192 type Hash = Hash;
194 type BlockHashCount = BlockHashCount;
196 type DbWeight = RocksDbWeight;
198 type Version = Version;
200 type AccountData = pallet_balances::AccountData<Balance>;
202 type SS58Prefix = SS58Prefix;
204 type MaxConsumers = frame_support::traits::ConstU32<16>;
205}
206
207parameter_types! {
208 pub const UncleGenerations: u32 = 0;
209}
210
211impl pallet_authorship::Config for Runtime {
212 type FindAuthor = ();
213 type EventHandler = ();
214}
215
216parameter_types! {
217 pub const MinimumPeriod: u64 = 5;
218}
219
220impl pallet_timestamp::Config for Runtime {
221 type Moment = u64;
223 type OnTimestampSet = ();
224 type MinimumPeriod = MinimumPeriod;
225 type WeightInfo = ();
226}
227
228parameter_types! {
229 pub const MaxLocks: u32 = 50;
230 pub const MaxReserves: u32 = 50;
231}
232
233impl pallet_balances::Config for Runtime {
234 type MaxLocks = MaxLocks;
235 type MaxReserves = MaxReserves;
236 type ReserveIdentifier = [u8; 8];
237 type Balance = Balance;
239 type RuntimeEvent = RuntimeEvent;
241 type DustRemoval = ();
242 type ExistentialDeposit = ConstU128<EXISTENTIAL_DEPOSIT>;
243 type AccountStore = System;
244 type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
245 type FreezeIdentifier = ();
246 type MaxFreezes = ();
247 type RuntimeHoldReason = RuntimeHoldReason;
248 type RuntimeFreezeReason = RuntimeFreezeReason;
249}
250
251impl pallet_transaction_payment::Config for Runtime {
252 type RuntimeEvent = RuntimeEvent;
253 type OnChargeTransaction = FungibleAdapter<Balances, ()>;
254 type OperationalFeeMultiplier = ConstU8<5>;
255 type WeightToFee = IdentityFee<Balance>;
256 type LengthToFee = IdentityFee<Balance>;
257 type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
258}
259
260impl pallet_sudo::Config for Runtime {
261 type RuntimeEvent = RuntimeEvent;
262 type RuntimeCall = RuntimeCall;
263 type WeightInfo = pallet_sudo::weights::SubstrateWeight<Runtime>;
264}
265
266impl pallet_utility::Config for Runtime {
267 type RuntimeEvent = RuntimeEvent;
268 type RuntimeCall = RuntimeCall;
269 type PalletsOrigin = OriginCaller;
270 type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
271}
272
273#[frame_support::runtime]
275mod runtime {
276 #[runtime::runtime]
277 #[runtime::derive(
278 RuntimeCall,
279 RuntimeEvent,
280 RuntimeError,
281 RuntimeOrigin,
282 RuntimeFreezeReason,
283 RuntimeHoldReason,
284 RuntimeSlashReason,
285 RuntimeLockId,
286 RuntimeTask
287 )]
288 pub struct Runtime;
289 #[runtime::pallet_index(0)]
290 pub type System = frame_system;
291 #[runtime::pallet_index(1)]
292 pub type RandomnessCollectiveFlip = pallet_insecure_randomness_collective_flip;
293 #[runtime::pallet_index(2)]
294 pub type Utility = pallet_utility;
295 #[runtime::pallet_index(3)]
296 pub type Timestamp = pallet_timestamp;
297 #[runtime::pallet_index(4)]
298 pub type Balances = pallet_balances;
299 #[runtime::pallet_index(5)]
300 pub type Authorship = pallet_authorship;
301 #[runtime::pallet_index(6)]
302 pub type TransactionPayment = pallet_transaction_payment;
303 #[runtime::pallet_index(7)]
304 pub type Sudo = pallet_sudo;
305 #[runtime::pallet_index(8)]
306 pub type Contracts = pallet_contracts;
307 #[runtime::pallet_index(9)]
308 pub type Revive = pallet_revive;
309 #[runtime::pallet_index(10)]
310 pub type Assets = pallet_assets;
311}
312
313pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
315pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
317pub type Block = generic::Block<Header, UncheckedExtrinsic>;
319pub type SignedExtra = (
321 frame_system::CheckNonZeroSender<Runtime>,
322 frame_system::CheckSpecVersion<Runtime>,
323 frame_system::CheckTxVersion<Runtime>,
324 frame_system::CheckGenesis<Runtime>,
325 frame_system::CheckEra<Runtime>,
326 frame_system::CheckNonce<Runtime>,
327 frame_system::CheckWeight<Runtime>,
328 pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
329);
330pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
332pub type UncheckedExtrinsic =
334 generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
335pub type Executive = frame_executive::Executive<
337 Runtime,
338 Block,
339 frame_system::ChainContext<Runtime>,
340 Runtime,
341 AllPalletsWithSystem,
342>;
343
344type EventRecord = frame_system::EventRecord<
345 <Runtime as frame_system::Config>::RuntimeEvent,
346 <Runtime as frame_system::Config>::Hash,
347>;
348
349impl_runtime_apis! {
350 impl sp_api::Core<Block> for Runtime {
351 fn version() -> RuntimeVersion {
352 VERSION
353 }
354
355 fn execute_block(block: Block) {
356 Executive::execute_block(block);
357 }
358
359 fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
360 Executive::initialize_block(header)
361 }
362 }
363
364 impl sp_api::Metadata<Block> for Runtime {
365 fn metadata() -> OpaqueMetadata {
366 OpaqueMetadata::new(Runtime::metadata().into())
367 }
368 fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
369 Runtime::metadata_at_version(version)
370 }
371
372 fn metadata_versions() -> Vec<u32> {
373 Runtime::metadata_versions()
374 }
375 }
376
377 impl sp_block_builder::BlockBuilder<Block> for Runtime {
378 fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
379 Executive::apply_extrinsic(extrinsic)
380 }
381
382 fn finalize_block() -> <Block as BlockT>::Header {
383 Executive::finalize_block()
384 }
385
386 fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
387 data.create_extrinsics()
388 }
389
390 fn check_inherents(
391 block: Block,
392 data: sp_inherents::InherentData,
393 ) -> sp_inherents::CheckInherentsResult {
394 data.check_extrinsics(&block)
395 }
396 }
397
398 impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
399 fn validate_transaction(
400 source: TransactionSource,
401 tx: <Block as BlockT>::Extrinsic,
402 block_hash: <Block as BlockT>::Hash,
403 ) -> TransactionValidity {
404 Executive::validate_transaction(source, tx, block_hash)
405 }
406 }
407
408 impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
409 fn offchain_worker(header: &<Block as BlockT>::Header) {
410 Executive::offchain_worker(header)
411 }
412 }
413
414 impl sp_session::SessionKeys<Block> for Runtime {
415 fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
416 opaque::SessionKeys::generate(seed)
417 }
418
419 fn decode_session_keys(
420 encoded: Vec<u8>,
421 ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
422 opaque::SessionKeys::decode_into_raw_public_keys(&encoded)
423 }
424 }
425
426 impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
427 fn account_nonce(account: AccountId) -> Nonce {
428 System::account_nonce(account)
429 }
430 }
431
432 impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
433 fn query_info(
434 uxt: <Block as BlockT>::Extrinsic,
435 len: u32,
436 ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
437 TransactionPayment::query_info(uxt, len)
438 }
439 fn query_fee_details(
440 uxt: <Block as BlockT>::Extrinsic,
441 len: u32,
442 ) -> pallet_transaction_payment::FeeDetails<Balance> {
443 TransactionPayment::query_fee_details(uxt, len)
444 }
445 fn query_weight_to_fee(weight: Weight) -> Balance {
446 TransactionPayment::weight_to_fee(weight)
447 }
448 fn query_length_to_fee(length: u32) -> Balance {
449 TransactionPayment::length_to_fee(length)
450 }
451 }
452
453 impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall> for Runtime {
454 fn query_call_info(
455 call: RuntimeCall,
456 len: u32,
457 ) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
458 TransactionPayment::query_call_info(call, len)
459 }
460 fn query_call_fee_details(
461 call: RuntimeCall,
462 len: u32,
463 ) -> pallet_transaction_payment::FeeDetails<Balance> {
464 TransactionPayment::query_call_fee_details(call, len)
465 }
466 fn query_weight_to_fee(weight: Weight) -> Balance {
467 TransactionPayment::weight_to_fee(weight)
468 }
469 fn query_length_to_fee(length: u32) -> Balance {
470 TransactionPayment::length_to_fee(length)
471 }
472 }
473
474 impl pallet_contracts::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash, EventRecord>
475 for Runtime
476 {
477 fn call(
478 origin: AccountId,
479 dest: AccountId,
480 value: Balance,
481 gas_limit: Option<Weight>,
482 storage_deposit_limit: Option<Balance>,
483 input_data: Vec<u8>,
484 ) -> pallet_contracts::ContractExecResult<Balance, EventRecord> {
485 let gas_limit = gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block);
486 Contracts::bare_call(
487 origin,
488 dest,
489 value,
490 gas_limit,
491 storage_deposit_limit,
492 input_data,
493 CONTRACTS_DEBUG_OUTPUT,
494 CONTRACTS_EVENTS,
495 pallet_contracts::Determinism::Enforced,
496 )
497 }
498
499 fn instantiate(
500 origin: AccountId,
501 value: Balance,
502 gas_limit: Option<Weight>,
503 storage_deposit_limit: Option<Balance>,
504 code: pallet_contracts::Code<Hash>,
505 data: Vec<u8>,
506 salt: Vec<u8>,
507 ) -> pallet_contracts::ContractInstantiateResult<AccountId, Balance, EventRecord>
508 {
509 let gas_limit = gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block);
510 Contracts::bare_instantiate(
511 origin,
512 value,
513 gas_limit,
514 storage_deposit_limit,
515 code,
516 data,
517 salt,
518 CONTRACTS_DEBUG_OUTPUT,
519 CONTRACTS_EVENTS,
520 )
521 }
522
523 fn upload_code(
524 origin: AccountId,
525 code: Vec<u8>,
526 storage_deposit_limit: Option<Balance>,
527 determinism: pallet_contracts::Determinism,
528 ) -> pallet_contracts::CodeUploadResult<Hash, Balance>
529 {
530 Contracts::bare_upload_code(origin, code, storage_deposit_limit, determinism)
531 }
532
533 fn get_storage(
534 address: AccountId,
535 key: Vec<u8>,
536 ) -> pallet_contracts::GetStorageResult {
537 Contracts::get_storage(address, key)
538 }
539 }
540
541 impl pallet_revive::ReviveApi<Block, AccountId, Balance, BlockNumber, Hash, EventRecord> for Runtime
542 {
543 fn call(
544 origin: AccountId,
545 dest: AccountId,
546 value: Balance,
547 gas_limit: Option<Weight>,
548 storage_deposit_limit: Option<Balance>,
549 input_data: Vec<u8>,
550 ) -> pallet_revive::ContractExecResult<Balance, EventRecord> {
551 Revive::bare_call(
552 RuntimeOrigin::signed(origin),
553 dest,
554 value,
555 gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block),
556 storage_deposit_limit.unwrap_or(u128::MAX),
557 input_data,
558 REVIVE_DEBUG_OUTPUT,
559 REVIVE_EVENTS,
560 )
561 }
562
563 fn instantiate(
564 origin: AccountId,
565 value: Balance,
566 gas_limit: Option<Weight>,
567 storage_deposit_limit: Option<Balance>,
568 code: pallet_revive::Code<Hash>,
569 data: Vec<u8>,
570 salt: Vec<u8>,
571 ) -> pallet_revive::ContractInstantiateResult<AccountId, Balance, EventRecord>
572 {
573 Revive::bare_instantiate(
574 RuntimeOrigin::signed(origin),
575 value,
576 gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block),
577 storage_deposit_limit.unwrap_or(u128::MAX),
578 code,
579 data,
580 salt,
581 REVIVE_DEBUG_OUTPUT,
582 REVIVE_EVENTS,
583 )
584 }
585
586 fn upload_code(
587 origin: AccountId,
588 code: Vec<u8>,
589 storage_deposit_limit: Option<Balance>,
590 ) -> pallet_revive::CodeUploadResult<Hash, Balance>
591 {
592 Revive::bare_upload_code(
593 RuntimeOrigin::signed(origin),
594 code,
595 storage_deposit_limit.unwrap_or(u128::MAX),
596 )
597 }
598
599 fn get_storage(
600 address: AccountId,
601 key: Vec<u8>,
602 ) -> pallet_revive::GetStorageResult {
603 Revive::get_storage(
604 address,
605 key
606 )
607 }
608 }
609
610 impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
611 fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
612 build_state::<RuntimeGenesisConfig>(config)
613 }
614
615 fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
616 get_preset::<RuntimeGenesisConfig>(id, |_| None)
617 }
618
619 fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
620 Default::default()
621 }
622 }
623}