Newer
Older
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! The Polkadot 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"]
use sp_std::prelude::*;
use polkadot_runtime_parachains::configuration as parachains_configuration;
use polkadot_runtime_parachains::inclusion as parachains_inclusion;
use polkadot_runtime_parachains::inclusion_inherent as parachains_inclusion_inherent;
use polkadot_runtime_parachains::initializer as parachains_initializer;
use polkadot_runtime_parachains::paras as parachains_paras;
use polkadot_runtime_parachains::dmp as parachains_dmp;
use polkadot_runtime_parachains::ump as parachains_ump;
use polkadot_runtime_parachains::hrmp as parachains_hrmp;
use polkadot_runtime_parachains::scheduler as parachains_scheduler;
use polkadot_runtime_parachains::runtime_api_impl::v1 as runtime_impl;
AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt,
CoreState, GroupRotationInfo, Hash as HashT, Id as ParaId, Moment, Nonce, OccupiedCoreAssumption,
PersistedValidationData, Signature, ValidationCode, ValidationData, ValidatorId, ValidatorIndex,
Bastian Köcher
committed
claims, SlowAdjustingFeeUpdate, paras_sudo_wrapper,
BlockHashCount, MaximumBlockWeight, AvailableBlockRatio,
MaximumBlockLength, BlockExecutionWeight, ExtrinsicBaseWeight,
};
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
ApplyExtrinsicResult, Perbill, KeyTypeId,
TransactionValidity, TransactionSource, TransactionPriority,
traits::{
BlakeTwo256, Block as BlockT, StaticLookup, OpaqueKeys, ConvertInto,
Extrinsic as ExtrinsicT, SaturatedConversion, Verify,
},
use sp_version::RuntimeVersion;
use pallet_grandpa::{AuthorityId as GrandpaId, fg_primitives};
#[cfg(any(feature = "std", test))]
use sp_core::OpaqueMetadata;
use sp_staking::SessionIndex;
use frame_support::{
parameter_types, construct_runtime, debug,
Peter Goodspeed-Niklaus
committed
traits::{KeyOwnerProofSystem, Randomness},
weights::Weight,
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
use pallet_session::historical as session_historical;
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
pub use pallet_timestamp::Call as TimestampCall;
pub use pallet_balances::Call as BalancesCall;
Bastian Köcher
committed
pub use paras_sudo_wrapper::Call as ParasSudoWrapperCall;
pub use pallet_sudo::Call as SudoCall;
/// Constant values used within the runtime.
pub mod constants;
use constants::{time::*, currency::*, fee::*};
// Make the WASM binary available.
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("polkadot-test-runtime"),
impl_name: create_runtime_str!("parity-polkadot-test-runtime"),
authoring_version: 2,
};
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
NativeVersion {
runtime_version: VERSION,
can_author_with: Default::default(),
}
}
sp_api::decl_runtime_apis! {
pub trait GetLastTimestamp {
/// Returns the last timestamp of a runtime.
fn get_last_timestamp() -> u64;
}
}
parameter_types! {
pub const Version: RuntimeVersion = VERSION;
}
impl frame_system::Trait for Runtime {
thiolliere
committed
type BaseCallFilter = ();
type Origin = Origin;
type Call = Call;
type Index = Nonce;
type BlockNumber = BlockNumber;
type Hash = HashT;
type Hashing = BlakeTwo256;
type AccountId = AccountId;
type Lookup = Indices;
type Header = generic::Header<BlockNumber, BlakeTwo256>;
type Event = Event;
type BlockHashCount = BlockHashCount;
type MaximumBlockWeight = MaximumBlockWeight;
type DbWeight = ();
type BlockExecutionWeight = BlockExecutionWeight;
type ExtrinsicBaseWeight = ExtrinsicBaseWeight;
type MaximumExtrinsicWeight = MaximumBlockWeight;
type MaximumBlockLength = MaximumBlockLength;
type AvailableBlockRatio = AvailableBlockRatio;
type Version = Version;
type PalletInfo = PalletInfo;
type AccountData = pallet_balances::AccountData<Balance>;
type SystemWeightInfo = ();
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime where
Call: From<C>,
{
type OverarchingCall = Call;
type Extrinsic = UncheckedExtrinsic;
}
pub storage EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
pub storage ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
type EpochDuration = EpochDuration;
type ExpectedBlockTime = ExpectedBlockTime;
// session module is the trigger
type EpochChangeTrigger = pallet_babe::ExternalTrigger;
type KeyOwnerProofSystem = ();
type KeyOwnerProof = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
KeyTypeId,
)>>::Proof;
type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
KeyTypeId,
)>>::IdentificationTuple;
type HandleEquivocation = ();
type WeightInfo = ();
pub storage IndexDeposit: Balance = 1 * DOLLARS;
impl pallet_indices::Trait for Runtime {
type AccountIndex = AccountIndex;
type Currency = Balances;
type Deposit = IndexDeposit;
type Event = Event;
pub storage ExistentialDeposit: Balance = 1 * CENTS;
pub storage MaxLocks: u32 = 50;
impl pallet_balances::Trait for Runtime {
type Balance = Balance;
type DustRemoval = ();
type Event = Event;
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type MaxLocks = MaxLocks;
pub storage TransactionByteFee: Balance = 10 * MILLICENTS;
impl pallet_transaction_payment::Trait for Runtime {
type OnChargeTransaction = CurrencyAdapter<Balances, ()>;
type TransactionByteFee = TransactionByteFee;
type WeightToFee = WeightToFee;
type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
pub storage SlotDuration: u64 = SLOT_DURATION;
pub storage MinimumPeriod: u64 = SlotDuration::get() / 2;
impl pallet_timestamp::Trait for Runtime {
type Moment = u64;
type OnTimestampSet = Babe;
type MinimumPeriod = MinimumPeriod;
pub storage UncleGenerations: u32 = 0;
}
// TODO: substrate#2986 implement this properly
impl pallet_authorship::Trait for Runtime {
type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
type UncleGenerations = UncleGenerations;
type FilterUncle = ();
type EventHandler = Staking;
}
parameter_types! {
pub storage Period: BlockNumber = 10 * MINUTES;
pub storage Offset: BlockNumber = 0;
}
impl_opaque_keys! {
pub struct SessionKeys {
pub grandpa: Grandpa,
pub babe: Babe,
pub parachain_validator: Initializer,
pub authority_discovery: AuthorityDiscovery,
}
}
parameter_types! {
pub storage DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
impl pallet_session::Trait for Runtime {
type Event = Event;
type ValidatorId = AccountId;
type ValidatorIdOf = pallet_staking::StashOf<Self>;
type SessionManager = Staking;
type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
type Keys = SessionKeys;
type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
impl pallet_session::historical::Trait for Runtime {
type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
}
pallet_staking_reward_curve::build! {
const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
min_inflation: 0_025_000,
max_inflation: 0_100_000,
ideal_stake: 0_500_000,
falloff: 0_050_000,
max_piece_count: 40,
test_precision: 0_005_000,
);
}
parameter_types! {
// Six sessions in an era (6 hours).
pub storage SessionsPerEra: SessionIndex = 6;
// 28 eras for unbonding (7 days).
pub storage BondingDuration: pallet_staking::EraIndex = 28;
// 27 eras in which slashes can be cancelled (a bit less than 7 days).
pub storage SlashDeferDuration: pallet_staking::EraIndex = 27;
pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
pub storage MaxNominatorRewardedPerValidator: u32 = 64;
pub storage ElectionLookahead: BlockNumber = 0;
pub storage StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2;
pub storage MaxIterations: u32 = 10;
pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
impl pallet_staking::Trait for Runtime {
type UnixTime = Timestamp;
type CurrencyToVote = frame_support::traits::U128CurrencyToVote;
type RewardRemainder = ();
type Event = Event;
type Slash = ();
type Reward = ();
type SessionsPerEra = SessionsPerEra;
type BondingDuration = BondingDuration;
type SlashDeferDuration = SlashDeferDuration;
// A majority of the council can cancel the slash.
type SlashCancelOrigin = frame_system::EnsureNever<()>;
type SessionInterface = Self;
type RewardCurve = RewardCurve;
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type NextNewSession = Session;
type ElectionLookahead = ElectionLookahead;
type Call = Call;
type UnsignedPriority = StakingUnsignedPriority;
type OffchainSolutionWeightLimit = MaximumBlockWeight;
type MinSolutionScoreBump = MinSolutionScoreBump;
type WeightInfo = ();
impl pallet_grandpa::Trait for Runtime {
type Call = Call;
type KeyOwnerProofSystem = ();
type KeyOwnerProof =
<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
KeyTypeId,
GrandpaId,
)>>::IdentificationTuple;
type HandleEquivocation = ();
type WeightInfo = ();
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime where
Call: From<LocalCall>,
{
fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
call: Call,
public: <Signature as Verify>::Signer,
account: AccountId,
nonce: <Runtime as frame_system::Trait>::Index,
) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
let period = BlockHashCount::get()
.checked_next_power_of_two()
.map(|c| c / 2)
.unwrap_or(2) as u64;
let current_block = System::block_number()
.saturated_into::<u64>()
.saturating_sub(1);
let tip = 0;
let extra: SignedExtra = (
frame_system::CheckSpecVersion::<Runtime>::new(),
frame_system::CheckTxVersion::<Runtime>::new(),
frame_system::CheckGenesis::<Runtime>::new(),
frame_system::CheckMortality::<Runtime>::from(generic::Era::mortal(period, current_block)),
frame_system::CheckNonce::<Runtime>::from(nonce),
frame_system::CheckWeight::<Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
);
let raw_payload = SignedPayload::new(call, extra).map_err(|e| {
debug::warn!("Unable to create signed payload: {:?}", e);
let signature = raw_payload.using_encoded(|payload| {
C::sign(payload, public)
})?;
let (call, extra, _) = raw_payload.deconstruct();
let address = Indices::unlookup(account);
Some((call, (address, signature, extra)))
}
impl frame_system::offchain::SigningTypes for Runtime {
type Public = <Signature as Verify>::Signer;
type Signature = Signature;
}
parameter_types! {
pub storage OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get();
impl pallet_offences::Trait for Runtime {
type Event = Event;
type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
type OnOffenceHandler = Staking;
type WeightSoftLimit = OffencesWeightSoftLimit;
impl pallet_authority_discovery::Trait for Runtime {}
pub storage LeasePeriod: BlockNumber = 100_000;
pub storage EndingPeriod: BlockNumber = 1000;
pub Prefix: &'static [u8] = b"Pay KSMs to the Kusama account:";
}
impl claims::Trait for Runtime {
type Event = Event;
type VestingSchedule = Vesting;
type Prefix = Prefix;
type MoveClaimOrigin = frame_system::EnsureRoot<AccountId>;
pub storage MinVestedTransfer: Balance = 100 * DOLLARS;
impl pallet_vesting::Trait for Runtime {
type Event = Event;
type Currency = Balances;
type BlockNumberToBalance = ConvertInto;
type MinVestedTransfer = MinVestedTransfer;
type Event = Event;
type Call = Call;
}
impl parachains_configuration::Trait for Runtime {}
type Event = Event;
}
impl parachains_inclusion_inherent::Trait for Runtime {}
type Randomness = RandomnessCollectiveFlip;
}
type Origin = Origin;
}
impl parachains_dmp::Trait for Runtime {}
impl parachains_ump::Trait for Runtime {
type UmpSink = ();
}
impl parachains_hrmp::Trait for Runtime {
type Origin = Origin;
}
Bastian Köcher
committed
impl paras_sudo_wrapper::Trait for Runtime {}
construct_runtime! {
pub enum Runtime where
Block = Block,
NodeBlock = primitives::v1::Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
// Basic stuff; balances is uncallable initially.
System: frame_system::{Module, Call, Storage, Config, Event<T>},
RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Storage},
// Must be before session.
Babe: pallet_babe::{Module, Call, Storage, Config, Inherent},
Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent},
Indices: pallet_indices::{Module, Call, Storage, Config<T>, Event<T>},
Balances: pallet_balances::{Module, Call, Storage, Config<T>, Event<T>},
TransactionPayment: pallet_transaction_payment::{Module, Storage},
Authorship: pallet_authorship::{Module, Call, Storage},
Staking: pallet_staking::{Module, Call, Storage, Config<T>, Event<T>, ValidateUnsigned},
Offences: pallet_offences::{Module, Call, Storage, Event},
Historical: session_historical::{Module},
Session: pallet_session::{Module, Call, Storage, Event, Config<T>},
Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event},
AuthorityDiscovery: pallet_authority_discovery::{Module, Call, Config},
// Claims. Usable initially.
Claims: claims::{Module, Call, Storage, Event<T>, Config<T>, ValidateUnsigned},
// Vesting. Usable initially, but removed once all vesting is finished.
Vesting: pallet_vesting::{Module, Call, Storage, Event<T>, Config<T>},
// Parachains runtime modules
ParachainsConfiguration: parachains_configuration::{Module, Call, Storage, Config<T>},
Inclusion: parachains_inclusion::{Module, Call, Storage, Event<T>},
InclusionInherent: parachains_inclusion_inherent::{Module, Call, Storage, Inherent},
Initializer: parachains_initializer::{Module, Call, Storage},
Paras: parachains_paras::{Module, Call, Storage, Origin},
Scheduler: parachains_scheduler::{Module, Call, Storage},
Bastian Köcher
committed
ParasSudoWrapper: paras_sudo_wrapper::{Module, Call},
Sudo: pallet_sudo::{Module, Call, Storage, Config<T>, Event<T>},
}
}
/// The address format for describing accounts.
pub type Address = <Indices as StaticLookup>::Source;
/// Block header type as expected by this runtime.
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
/// A Block signed with a Justification
pub type SignedBlock = generic::SignedBlock<Block>;
/// BlockId type as expected by this runtime.
pub type BlockId = generic::BlockId<Block>;
/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
frame_system::CheckSpecVersion<Runtime>,
frame_system::CheckTxVersion<Runtime>,
frame_system::CheckGenesis<Runtime>,
frame_system::CheckMortality<Runtime>,
frame_system::CheckNonce<Runtime>,
frame_system::CheckWeight<Runtime>,
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>,
);
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
/// Extrinsic type that has already been checked.
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Nonce, Call>;
/// Executive: handles dispatch to the various modules.
pub type Executive = frame_executive::Executive<Runtime, Block, frame_system::ChainContext<Runtime>, Runtime, AllModules>;
/// The payload being signed in transactions.
pub type SignedPayload = generic::SignedPayload<Call, SignedExtra>;
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
pub type Hash = <Block as BlockT>::Hash;
pub type Extrinsic = <Block as BlockT>::Extrinsic;
sp_api::impl_runtime_apis! {
impl sp_api::Core<Block> for Runtime {
fn version() -> RuntimeVersion {
VERSION
}
fn execute_block(block: Block) {
Executive::execute_block(block)
}
fn initialize_block(header: &<Block as BlockT>::Header) {
Executive::initialize_block(header)
}
}
impl sp_api::Metadata<Block> for Runtime {
fn metadata() -> OpaqueMetadata {
Runtime::metadata().into()
}
}
impl block_builder_api::BlockBuilder<Block> for Runtime {
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
Executive::apply_extrinsic(extrinsic)
}
fn finalize_block() -> <Block as BlockT>::Header {
Executive::finalize_block()
}
fn inherent_extrinsics(data: inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
data.create_extrinsics()
}
fn check_inherents(
block: Block,
data: inherents::InherentData,
) -> inherents::CheckInherentsResult {
data.check_extrinsics(&block)
}
fn random_seed() -> <Block as BlockT>::Hash {
RandomnessCollectiveFlip::random_seed()
}
}
impl tx_pool_api::runtime_api::TaggedTransactionQueue<Block> for Runtime {
fn validate_transaction(
source: TransactionSource,
tx: <Block as BlockT>::Extrinsic,
) -> TransactionValidity {
Executive::validate_transaction(source, tx)
impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
fn offchain_worker(header: &<Block as BlockT>::Header) {
Executive::offchain_worker(header)
}
}
impl authority_discovery_primitives::AuthorityDiscoveryApi<Block> for Runtime {
fn authorities() -> Vec<AuthorityDiscoveryId> {
AuthorityDiscovery::authorities()
impl primitives::v1::ParachainHost<Block, Hash, BlockNumber> for Runtime {
fn validators() -> Vec<ValidatorId> {
runtime_impl::validators::<Runtime>()
fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>) {
runtime_impl::validator_groups::<Runtime>()
fn availability_cores() -> Vec<CoreState<BlockNumber>> {
runtime_impl::availability_cores::<Runtime>()
fn full_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption)
-> Option<ValidationData<BlockNumber>>
{
runtime_impl::full_validation_data::<Runtime>(para_id, assumption)
}
fn persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption)
-> Option<PersistedValidationData<BlockNumber>>
{
runtime_impl::persisted_validation_data::<Runtime>(para_id, assumption)
}
fn check_validation_outputs(
para_id: ParaId,
outputs: primitives::v1::ValidationOutputs,
) -> bool {
runtime_impl::check_validation_outputs::<Runtime>(para_id, outputs)
}
fn session_index_for_child() -> SessionIndex {
runtime_impl::session_index_for_child::<Runtime>()
fn validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption)
-> Option<ValidationCode>
{
runtime_impl::validation_code::<Runtime>(para_id, assumption)
}
fn historical_validation_code(para_id: ParaId, context_height: BlockNumber)
-> Option<ValidationCode>
{
runtime_impl::historical_validation_code::<Runtime>(para_id, context_height)
}
fn candidate_pending_availability(para_id: ParaId) -> Option<CommittedCandidateReceipt<Hash>> {
runtime_impl::candidate_pending_availability::<Runtime>(para_id)
fn candidate_events() -> Vec<CandidateEvent<Hash>> {
use core::convert::TryInto;
runtime_impl::candidate_events::<Runtime, _>(|trait_event| trait_event.try_into().ok())
}
fn validator_discovery(validators: Vec<ValidatorId>) -> Vec<Option<AuthorityDiscoveryId>> {
runtime_impl::validator_discovery::<Runtime>(validators)
fn dmq_contents(
recipient: ParaId,
) -> Vec<InboundDownwardMessage<BlockNumber>> {
runtime_impl::dmq_contents::<Runtime>(recipient)
}
fn inbound_hrmp_channels_contents(
recipient: ParaId,
) -> BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>> {
runtime_impl::inbound_hrmp_channels_contents::<Runtime>(recipient)
}
}
impl fg_primitives::GrandpaApi<Block> for Runtime {
fn grandpa_authorities() -> Vec<(GrandpaId, u64)> {
Grandpa::grandpa_authorities()
}
fn submit_report_equivocation_unsigned_extrinsic(
_equivocation_proof: fg_primitives::EquivocationProof<
<Block as BlockT>::Hash,
sp_runtime::traits::NumberFor<Block>,
>,
_key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,
) -> Option<()> {
None
}
fn generate_key_ownership_proof(
_set_id: fg_primitives::SetId,
_authority_id: fg_primitives::AuthorityId,
) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {
None
}
}
impl babe_primitives::BabeApi<Block> for Runtime {
fn configuration() -> babe_primitives::BabeGenesisConfiguration {
// 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.
// <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
babe_primitives::BabeGenesisConfiguration {
slot_duration: Babe::slot_duration(),
epoch_length: EpochDuration::get(),
c: PRIMARY_PROBABILITY,
genesis_authorities: Babe::authorities(),
randomness: Babe::randomness(),
allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryPlainSlots,
}
}
fn current_epoch_start() -> babe_primitives::SlotNumber {
Babe::current_epoch_start()
}
fn generate_key_ownership_proof(
_slot_number: babe_primitives::SlotNumber,
_authority_id: babe_primitives::AuthorityId,
) -> Option<babe_primitives::OpaqueKeyOwnershipProof> {
None
}
fn submit_report_equivocation_unsigned_extrinsic(
_equivocation_proof: babe_primitives::EquivocationProof<<Block as BlockT>::Header>,
_key_owner_proof: babe_primitives::OpaqueKeyOwnershipProof,
) -> Option<()> {
None
}
}
impl sp_session::SessionKeys<Block> for Runtime {
fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
SessionKeys::generate(seed)
}
fn decode_session_keys(
encoded: Vec<u8>,
) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
SessionKeys::decode_into_raw_public_keys(&encoded)
}
}
impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
fn account_nonce(account: AccountId) -> Nonce {
System::account_nonce(account)
}
}
impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
Block,
Balance,
> for Runtime {
fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
TransactionPayment::query_info(uxt, len)
}
}
impl crate::GetLastTimestamp<Block> for Runtime {
fn get_last_timestamp() -> u64 {
Timestamp::now()
}
}