//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm. #![cfg_attr(not(feature = "std"), no_std)] // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. #![recursion_limit="256"] // Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); use rstd::prelude::*; use primitives::{OpaqueMetadata, crypto::key_types}; use sr_primitives::{ ApplyResult, transaction_validity::TransactionValidity, generic, create_runtime_str, impl_opaque_keys, AnySignature }; use sr_primitives::traits::{NumberFor, BlakeTwo256, Block as BlockT, DigestFor, StaticLookup, Verify, ConvertInto}; use sr_primitives::weights::Weight; use babe::{AuthorityId as BabeId}; use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight}; use grandpa::fg_primitives::{self, ScheduledChange}; use client::{ block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api}, runtime_api as client_api, impl_runtime_apis }; use version::RuntimeVersion; #[cfg(feature = "std")] use version::NativeVersion; // A few exports that help ease life for downstream crates. #[cfg(any(feature = "std", test))] pub use sr_primitives::BuildStorage; pub use timestamp::Call as TimestampCall; pub use balances::Call as BalancesCall; pub use sr_primitives::{Permill, Perbill}; pub use support::{StorageValue, construct_runtime, parameter_types}; /// An index to a block. pub type BlockNumber = u32; /// Alias to 512-bit hash when used in the context of a transaction signature on the chain. pub type Signature = AnySignature; /// Some way of identifying an account on the chain. We intentionally make it equivalent /// to the public key of our transaction signing scheme. pub type AccountId = ::Signer; /// The type for looking up accounts. We don't expect more than 4 billion of them, but you /// never know... pub type AccountIndex = u32; /// Balance of an account. pub type Balance = u128; /// Index of a transaction in the chain. pub type Index = u32; /// A hash of some data used by the chain. pub type Hash = primitives::H256; /// Digest item type. pub type DigestItem = generic::DigestItem; /// Used for the module template in `./template.rs` mod template; /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know /// the specifics of the runtime. They can then be made to be agnostic over specific formats /// of data like extrinsics, allowing for them to continue syncing the network through upgrades /// to even the core datastructures. pub mod opaque { use super::*; pub use sr_primitives::OpaqueExtrinsic as UncheckedExtrinsic; /// Opaque block header type. pub type Header = generic::Header; /// Opaque block type. pub type Block = generic::Block; /// Opaque block identifier type. pub type BlockId = generic::BlockId; pub type SessionHandlers = (Grandpa, Babe); impl_opaque_keys! { pub struct SessionKeys { #[id(key_types::GRANDPA)] pub grandpa: GrandpaId, #[id(key_types::BABE)] pub babe: BabeId, } } } /// This runtime version. pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("node-template"), impl_name: create_runtime_str!("node-template"), authoring_version: 3, spec_version: 4, impl_version: 4, apis: RUNTIME_API_VERSIONS, }; /// Constants for Babe. /// Since BABE is probabilistic this is the average expected block time that /// we are targetting. Blocks will be produced at a minimum duration defined /// by `SLOT_DURATION`, but some slots will not be allocated to any /// authority and hence no block will be produced. We expect to have this /// block time on average following the defined slot duration and the value /// of `c` configured for BABE (where `1 - c` represents the probability of /// a slot being empty). /// This value is only used indirectly to define the unit constants below /// that are expressed in blocks. The rest of the code should use /// `SLOT_DURATION` instead (like the timestamp module for calculating the /// minimum period). /// pub const MILLISECS_PER_BLOCK: u64 = 6000; pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; pub const EPOCH_DURATION_IN_BLOCKS: u32 = 10 * MINUTES; // These time units are defined in number of blocks. pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); pub const HOURS: BlockNumber = MINUTES * 60; pub const DAYS: BlockNumber = HOURS * 24; // 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks. pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); /// The version infromation used to identify this runtime when compiled natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { NativeVersion { runtime_version: VERSION, can_author_with: Default::default(), } } parameter_types! { pub const BlockHashCount: BlockNumber = 250; pub const MaximumBlockWeight: Weight = 1_000_000; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; pub const Version: RuntimeVersion = VERSION; } impl system::Trait for Runtime { /// The identifier used to distinguish between accounts. type AccountId = AccountId; /// The aggregated dispatch type that is available for extrinsics. type Call = Call; /// The lookup mechanism to get account ID from whatever is passed in dispatchers. type Lookup = Indices; /// The index type for storing how many extrinsics an account has signed. type Index = Index; /// The index type for blocks. type BlockNumber = BlockNumber; /// The type for hashing blocks and tries. type Hash = Hash; /// The hashing algorithm used. type Hashing = BlakeTwo256; /// The header type. type Header = generic::Header; /// The ubiquitous event type. type Event = Event; /// Update weight (to fee) multiplier per-block. type WeightMultiplierUpdate = (); /// The ubiquitous origin type. type Origin = Origin; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount = BlockHashCount; /// Maximum weight of each block. With a default weight system of 1byte == 1weight, 4mb is ok. type MaximumBlockWeight = MaximumBlockWeight; /// Maximum size of all encoded transactions (in bytes) that are allowed in one block. type MaximumBlockLength = MaximumBlockLength; /// Portion of the block weight that is available to all normal transactions. type AvailableBlockRatio = AvailableBlockRatio; type Version = Version; } parameter_types! { pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64; pub const ExpectedBlockTime: u64 = MILLISECS_PER_BLOCK; } impl babe::Trait for Runtime { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; } impl grandpa::Trait for Runtime { type Event = Event; } impl indices::Trait for Runtime { /// The type for recording indexing into the account enumeration. If this ever overflows, there /// will be problems! type AccountIndex = u32; /// Use the standard means of resolving an index hint from an id. type ResolveHint = indices::SimpleResolveHint; /// Determine whether an account is dead. type IsDeadAccount = Balances; /// The ubiquitous event type. type Event = Event; } parameter_types! { pub const MinimumPeriod: u64 = 5000; } impl timestamp::Trait for Runtime { /// A timestamp: milliseconds since the unix epoch. type Moment = u64; type OnTimestampSet = Babe; type MinimumPeriod = MinimumPeriod; } parameter_types! { pub const ExistentialDeposit: u128 = 500; pub const TransferFee: u128 = 0; pub const CreationFee: u128 = 0; pub const TransactionBaseFee: u128 = 0; pub const TransactionByteFee: u128 = 1; } impl balances::Trait for Runtime { /// The type for recording an account's balance. type Balance = Balance; /// What to do if an account's free balance gets zeroed. type OnFreeBalanceZero = (); /// What to do if a new account is created. type OnNewAccount = Indices; /// The ubiquitous event type. type Event = Event; type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; type WeightToFee = ConvertInto; } impl sudo::Trait for Runtime { type Event = Event; type Proposal = Call; } /// Used for the module template in `./template.rs` impl template::Trait for Runtime { type Event = Event; } construct_runtime!( pub enum Runtime where Block = Block, NodeBlock = opaque::Block, UncheckedExtrinsic = UncheckedExtrinsic { System: system::{Module, Call, Storage, Config, Event}, Timestamp: timestamp::{Module, Call, Storage, Inherent}, Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, Grandpa: grandpa::{Module, Call, Storage, Config, Event}, Indices: indices::{default, Config}, Balances: balances, Sudo: sudo, // Used for the module template in `./template.rs` TemplateModule: template::{Module, Call, Storage, Event}, } ); /// The address format for describing accounts. pub type Address = ::Source; /// Block header type as expected by this runtime. pub type Header = generic::Header; /// Block type as expected by this runtime. pub type Block = generic::Block; /// A Block signed with a Justification pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; /// The SignedExtension to the basic transaction logic. pub type SignedExtra = ( system::CheckVersion, system::CheckGenesis, system::CheckEra, system::CheckNonce, system::CheckWeight, balances::TakeFees ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// Extrinsic type that has already been checked. pub type CheckedExtrinsic = generic::CheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = executive::Executive, Runtime, AllModules>; impl_runtime_apis! { impl client_api::Core for Runtime { fn version() -> RuntimeVersion { VERSION } fn execute_block(block: Block) { Executive::execute_block(block) } fn initialize_block(header: &::Header) { Executive::initialize_block(header) } } impl client_api::Metadata for Runtime { fn metadata() -> OpaqueMetadata { Runtime::metadata().into() } } impl block_builder_api::BlockBuilder for Runtime { fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyResult { Executive::apply_extrinsic(extrinsic) } fn finalize_block() -> ::Header { Executive::finalize_block() } fn inherent_extrinsics(data: InherentData) -> Vec<::Extrinsic> { data.create_extrinsics() } fn check_inherents(block: Block, data: InherentData) -> CheckInherentsResult { data.check_extrinsics(&block) } fn random_seed() -> ::Hash { System::random_seed() } } impl client_api::TaggedTransactionQueue for Runtime { fn validate_transaction(tx: ::Extrinsic) -> TransactionValidity { Executive::validate_transaction(tx) } } impl offchain_primitives::OffchainWorkerApi for Runtime { fn offchain_worker(number: NumberFor) { Executive::offchain_worker(number) } } impl fg_primitives::GrandpaApi for Runtime { fn grandpa_pending_change(digest: &DigestFor) -> Option>> { Grandpa::pending_change(digest) } fn grandpa_forced_change(digest: &DigestFor) -> Option<(NumberFor, ScheduledChange>)> { Grandpa::forced_change(digest) } fn grandpa_authorities() -> Vec<(GrandpaId, GrandpaWeight)> { Grandpa::grandpa_authorities() } } impl babe_primitives::BabeApi for Runtime { fn startup_data() -> babe_primitives::BabeConfiguration { // The choice of `c` parameter (where `1 - c` represents the // probability of a slot being empty), is done in accordance to the // slot duration and expected target block time, for safely // resisting network delays of maximum two seconds. // babe_primitives::BabeConfiguration { median_required_blocks: 1000, slot_duration: Babe::slot_duration(), c: PRIMARY_PROBABILITY, } } fn epoch() -> babe_primitives::Epoch { babe_primitives::Epoch { start_slot: Babe::epoch_start_slot(), authorities: Babe::authorities(), epoch_index: Babe::epoch_index(), randomness: Babe::randomness(), duration: EpochDuration::get(), secondary_slots: Babe::secondary_slots().0, } } } impl substrate_session::SessionKeys for Runtime { fn generate_session_keys(seed: Option>) -> Vec { let seed = seed.as_ref().map(|s| rstd::str::from_utf8(&s).expect("Seed is an utf8 string")); opaque::SessionKeys::generate(seed) } } }