diff --git a/polkadot/Cargo.lock b/polkadot/Cargo.lock index fbcd505887..402247bd12 100644 --- a/polkadot/Cargo.lock +++ b/polkadot/Cargo.lock @@ -5993,6 +5993,53 @@ dependencies = [ "librocksdb-sys", ] +[[package]] +name = "rococo-runtime" +version = "0.8.19" +dependencies = [ + "frame-executive", + "frame-support", + "frame-system", + "frame-system-rpc-runtime-api", + "pallet-authority-discovery", + "pallet-authorship", + "pallet-babe", + "pallet-balances", + "pallet-grandpa", + "pallet-im-online", + "pallet-indices", + "pallet-offences", + "pallet-session", + "pallet-staking", + "pallet-staking-reward-curve", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "parity-scale-codec", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-runtime-common", + "polkadot-runtime-parachains", + "serde", + "serde_derive", + "smallvec 1.4.1", + "sp-api", + "sp-authority-discovery", + "sp-block-builder", + "sp-consensus-babe", + "sp-core", + "sp-inherents", + "sp-io", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", + "sp-transaction-pool", + "sp-version", + "substrate-wasm-builder-runner 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rpassword" version = "4.0.5" diff --git a/polkadot/Cargo.toml b/polkadot/Cargo.toml index 7fb7d7d535..a3f9b295bd 100644 --- a/polkadot/Cargo.toml +++ b/polkadot/Cargo.toml @@ -35,6 +35,7 @@ members = [ "runtime/parachains", "runtime/polkadot", "runtime/kusama", + "runtime/rococo", "runtime/westend", "runtime/test-runtime", "runtime/test-runtime/client", diff --git a/polkadot/primitives/src/v0.rs b/polkadot/primitives/src/v0.rs index 3fcb31193a..11d62a4c2e 100644 --- a/polkadot/primitives/src/v0.rs +++ b/polkadot/primitives/src/v0.rs @@ -815,7 +815,7 @@ impl EncodeAs for T { /// /// Note that the internal fields are not public; they are all accessable by immutable getters. /// This reduces the chance that they are accidentally mutated, invalidating the signature. -#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)] +#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] pub struct Signed { /// The payload is part of the signed data. The rest is the signing context, /// which is known both at signing and at validation. diff --git a/polkadot/primitives/src/v1.rs b/polkadot/primitives/src/v1.rs index 8b4130fe9d..67926f2ab3 100644 --- a/polkadot/primitives/src/v1.rs +++ b/polkadot/primitives/src/v1.rs @@ -304,8 +304,7 @@ impl PoV { } /// A bitfield concerning availability of backed candidates. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] pub struct AvailabilityBitfield(pub BitVec); impl From> for AvailabilityBitfield { diff --git a/polkadot/runtime/parachains/src/lib.rs b/polkadot/runtime/parachains/src/lib.rs index eb279ad19c..5abc2fa32c 100644 --- a/polkadot/runtime/parachains/src/lib.rs +++ b/polkadot/runtime/parachains/src/lib.rs @@ -20,13 +20,16 @@ //! particular the `Initializer` module, as it is responsible for initializing the state //! of the other modules. -mod configuration; -mod inclusion; -mod inclusion_inherent; -mod initializer; -mod paras; -mod scheduler; -mod validity; + +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod configuration; +pub mod inclusion; +pub mod inclusion_inherent; +pub mod initializer; +pub mod paras; +pub mod scheduler; +pub mod validity; pub mod runtime_api_impl; diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/v1.rs b/polkadot/runtime/parachains/src/runtime_api_impl/v1.rs index 7f4a9093d4..a3bb6afff6 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/v1.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/v1.rs @@ -17,6 +17,7 @@ //! Runtimes implementing the v1 runtime API are recommended to forward directly to these //! functions. +use sp_std::prelude::*; use primitives::v1::{ ValidatorId, ValidatorIndex, GroupRotationInfo, CoreState, GlobalValidationData, Id as ParaId, OccupiedCoreAssumption, LocalValidationData, SessionIndex, ValidationCode, @@ -239,9 +240,11 @@ pub fn candidate_pending_availability(para_id: ParaId) /// Implementation for the `candidate_events` function of the runtime API. // NOTE: this runs without block initialization, as it accesses events. // this means it can run in a different session than other runtime APIs at the same block. -pub fn candidate_events( - extract_event: impl Fn(::Event) -> Option>, -) -> Vec> { +pub fn candidate_events(extract_event: F) -> Vec> +where + T: initializer::Trait, + F: Fn(::Event) -> Option>, +{ use inclusion::Event as RawEvent; >::events().into_iter() diff --git a/polkadot/runtime/rococo/Cargo.toml b/polkadot/runtime/rococo/Cargo.toml new file mode 100644 index 0000000000..be75f7a794 --- /dev/null +++ b/polkadot/runtime/rococo/Cargo.toml @@ -0,0 +1,106 @@ +[package] +name = "rococo-runtime" +version = "0.8.19" +authors = ["Parity Technologies "] +edition = "2018" +build = "build.rs" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +serde = { version = "1.0.102", default-features = false } +serde_derive = { version = "1.0.102", optional = true } +smallvec = "1.4.1" + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +version = { package = "sp-version", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +tx-pool-api = { package = "sp-transaction-pool", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +block-builder-api = { package = "sp-block-builder", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +offchain-primitives = { package = "sp-offchain", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +authority-discovery = { package = "pallet-authority-discovery", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +authorship = { package = "pallet-authorship", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +babe = { package = "pallet-babe", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +babe-primitives = { package = "sp-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +balances = { package = "pallet-balances", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +session = { package = "pallet-session", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +im-online = { package = "pallet-im-online", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +indices = { package = "pallet-indices", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +transaction-payment = { package = "pallet-transaction-payment", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +transaction-payment-rpc-runtime-api = { package = "pallet-transaction-payment-rpc-runtime-api", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +staking = { package = "pallet-staking", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-staking-reward-curve = { package = "pallet-staking-reward-curve", git = "https://github.com/paritytech/substrate", branch = "master" } +executive = { package = "frame-executive", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +grandpa = { package = "pallet-grandpa", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +timestamp = { package = "pallet-timestamp", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +offences = { package = "pallet-offences", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +authority-discovery-primitives = { package = "sp-authority-discovery", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +system = { package = "frame-system", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +system_rpc_runtime_api = { package = "frame-system-rpc-runtime-api", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +runtime-common = { package = "polkadot-runtime-common", path = "../common", default-features = false } +primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false } +polkadot-parachain = { path = "../../parachain", default-features = false } +runtime-parachains = { package = "polkadot-runtime-parachains", path = "../parachains", default-features = false } + +[build-dependencies] +wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.6" } + +[features] +default = ["std"] +no_std = [] +std = [ + "authority-discovery-primitives/std", + "authority-discovery/std", + "authorship/std", + "babe/std", + "babe-primitives/std", + "balances/std", + "codec/std", + "executive/std", + "grandpa/std", + "indices/std", + "im-online/std", + "inherents/std", + "frame-support/std", + "polkadot-parachain/std", + "primitives/std", + "runtime-common/std", + "runtime-parachains/std", + "session/std", + "sp-api/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "sp-session/std", + "sp-staking/std", + "sp-std/std", + "staking/std", + "system/std", + "system_rpc_runtime_api/std", + "offchain-primitives/std", + "offences/std", + "timestamp/std", + "transaction-payment/std", + "transaction-payment-rpc-runtime-api/std", + "block-builder-api/std", + "tx-pool-api/std", + "version/std", + "serde_derive", + "serde/std", +] +# When enabled, the runtime api will not be build. +# +# This is required by Cumulus to access certain types of the +# runtime without clashing with the runtime api exported functions +# in WASM. +disable-runtime-api = [] diff --git a/polkadot/runtime/rococo/build.rs b/polkadot/runtime/rococo/build.rs new file mode 100644 index 0000000000..dff1419829 --- /dev/null +++ b/polkadot/runtime/rococo/build.rs @@ -0,0 +1,26 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use wasm_builder_runner::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .with_wasm_builder_from_crates("2.0.0") + .import_memory() + .export_heap_base() + .build() +} diff --git a/polkadot/runtime/rococo/src/constants.rs b/polkadot/runtime/rococo/src/constants.rs new file mode 100644 index 0000000000..de95703fcc --- /dev/null +++ b/polkadot/runtime/rococo/src/constants.rs @@ -0,0 +1,113 @@ +// Copyright 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 . + +/// Money matters. +pub mod currency { + use primitives::v0::Balance; + + pub const DOTS: Balance = 1_000_000_000_000; + pub const DOLLARS: Balance = DOTS; + pub const CENTS: Balance = DOLLARS / 100; + pub const MILLICENTS: Balance = CENTS / 1_000; + + pub const fn deposit(items: u32, bytes: u32) -> Balance { + items as Balance * 1 * DOLLARS + (bytes as Balance) * 5 * MILLICENTS + } +} + +/// Time and blocks. +pub mod time { + use primitives::v0::{Moment, BlockNumber}; + pub const MILLISECS_PER_BLOCK: Moment = 6000; + pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; + pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 1 * HOURS; + + // 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); +} + +/// Fee-related. +pub mod fee { + pub use sp_runtime::Perbill; + use primitives::v0::Balance; + use runtime_common::ExtrinsicBaseWeight; + use frame_support::weights::{ + WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, + }; + use smallvec::smallvec; + + /// The block saturation level. Fees will be updates based on this value. + pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); + + /// Handles converting a weight scalar to a fee value, based on the scale and granularity of the + /// node's balance type. + /// + /// This should typically create a mapping between the following ranges: + /// - [0, system::MaximumBlockWeight] + /// - [Balance::min, Balance::max] + /// + /// Yet, it can be used for any other sort of change to weight-fee. Some examples being: + /// - Setting it to `0` will essentially disable the weight fee. + /// - Setting it to `1` will cause the literal `#[weight = x]` values to be charged. + pub struct WeightToFee; + impl WeightToFeePolynomial for WeightToFee { + type Balance = Balance; + fn polynomial() -> WeightToFeeCoefficients { + // in Westend, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT: + let p = super::currency::CENTS; + let q = 10 * Balance::from(ExtrinsicBaseWeight::get()); + smallvec![WeightToFeeCoefficient { + degree: 1, + negative: false, + coeff_frac: Perbill::from_rational_approximation(p % q, q), + coeff_integer: p / q, + }] + } + } +} + +#[cfg(test)] +mod tests { + use frame_support::weights::WeightToFeePolynomial; + use runtime_common::{MaximumBlockWeight, ExtrinsicBaseWeight}; + use super::fee::WeightToFee; + use super::currency::{CENTS, DOLLARS, MILLICENTS}; + + #[test] + // This function tests that the fee for `MaximumBlockWeight` of weight is correct + fn full_block_fee_is_correct() { + // A full block should cost 16 DOLLARS + println!("Base: {}", ExtrinsicBaseWeight::get()); + let x = WeightToFee::calc(&MaximumBlockWeight::get()); + let y = 16 * DOLLARS; + assert!(x.max(y) - x.min(y) < MILLICENTS); + } + + #[test] + // This function tests that the fee for `ExtrinsicBaseWeight` of weight is correct + fn extrinsic_base_fee_is_correct() { + // `ExtrinsicBaseWeight` should cost 1/10 of a CENT + println!("Base: {}", ExtrinsicBaseWeight::get()); + let x = WeightToFee::calc(&ExtrinsicBaseWeight::get()); + let y = CENTS / 10; + assert!(x.max(y) - x.min(y) < MILLICENTS); + } +} diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs new file mode 100644 index 0000000000..af530354dd --- /dev/null +++ b/polkadot/runtime/rococo/src/lib.rs @@ -0,0 +1,725 @@ +// Copyright 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 . + +//! The Rococo runtime. + +#![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 codec::Encode; +use primitives::v1::{ + AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, + GroupRotationInfo, CoreState, Id, GlobalValidationData, ValidationCode, CandidateEvent, + ValidatorId, ValidatorIndex, CommittedCandidateReceipt, OccupiedCoreAssumption, + LocalValidationData, +}; +use runtime_common::{ + SlowAdjustingFeeUpdate, + impls::{CurrencyToVoteHandler, ToAuthor}, + BlockHashCount, MaximumBlockWeight, AvailableBlockRatio, MaximumBlockLength, + BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, MaximumExtrinsicWeight, +}; +use runtime_parachains::{ + self, + runtime_api_impl::v1 as runtime_api_impl, +}; +use frame_support::{ + parameter_types, construct_runtime, debug, + traits::{KeyOwnerProofSystem, Filter}, + weights::Weight, +}; +use sp_runtime::{ + create_runtime_str, generic, impl_opaque_keys, + ApplyExtrinsicResult, KeyTypeId, Perbill, curve::PiecewiseLinear, + transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority}, + traits::{ + BlakeTwo256, Block as BlockT, OpaqueKeys, IdentityLookup, + Extrinsic as ExtrinsicT, SaturatedConversion, Verify, + }, +}; +use im_online::sr25519::AuthorityId as ImOnlineId; +use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; +use version::RuntimeVersion; +use transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; +use grandpa::{AuthorityId as GrandpaId, fg_primitives}; +use sp_core::OpaqueMetadata; +use sp_staking::SessionIndex; +use session::historical as session_historical; +use system::EnsureRoot; + +use runtime_parachains::configuration as parachains_configuration; +use runtime_parachains::inclusion as parachains_inclusion; +use runtime_parachains::inclusion_inherent as parachains_inclusion_inherent; +use runtime_parachains::initializer as parachains_initializer; +use runtime_parachains::paras as parachains_paras; +use runtime_parachains::scheduler as parachains_scheduler; + +pub use balances::Call as BalancesCall; + +/// 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")); + +/// The address format for describing accounts. +pub type Address = AccountId; +/// 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::CheckSpecVersion, + system::CheckTxVersion, + system::CheckGenesis, + system::CheckMortality, + system::CheckNonce, + system::CheckWeight, + transaction_payment::ChargeTransactionPayment, +); + +#[cfg(not(feature = "disable-runtime-api"))] +sp_api::impl_runtime_apis! { + impl sp_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 sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + Runtime::metadata().into() + } + } + + impl block_builder_api::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: inherents::InherentData, + ) -> inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + + fn random_seed() -> ::Hash { + Babe::randomness().into() + } + } + + impl tx_pool_api::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx) + } + } + + impl offchain_primitives::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl primitives::v1::ParachainHost for Runtime { + fn validators() -> Vec { + runtime_api_impl::validators::() + } + + fn validator_groups() -> (Vec>, GroupRotationInfo) { + runtime_api_impl::validator_groups::() + } + + fn availability_cores() -> Vec> { + runtime_api_impl::availability_cores::() + } + + fn global_validation_data() -> GlobalValidationData { + runtime_api_impl::global_validation_data::() + } + + fn local_validation_data(para_id: Id, assumption: OccupiedCoreAssumption) + -> Option> { + runtime_api_impl::local_validation_data::(para_id, assumption) + } + + fn session_index_for_child() -> SessionIndex { + runtime_api_impl::session_index_for_child::() + } + + fn validation_code(para_id: Id, assumption: OccupiedCoreAssumption) + -> Option { + runtime_api_impl::validation_code::(para_id, assumption) + } + + fn candidate_pending_availability(para_id: Id) -> Option> { + runtime_api_impl::candidate_pending_availability::(para_id) + } + + fn candidate_events() -> Vec> { + runtime_api_impl::candidate_events::(|ev| { + match ev { + Event::parachains_inclusion(ev) => { + Some(ev) + } + _ => None, + } + }) + } + } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> Vec<(GrandpaId, u64)> { + Grandpa::grandpa_authorities() + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: fg_primitives::EquivocationProof< + ::Hash, + sp_runtime::traits::NumberFor, + >, + key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Grandpa::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } + + fn generate_key_ownership_proof( + _set_id: fg_primitives::SetId, + authority_id: fg_primitives::AuthorityId, + ) -> Option { + use codec::Encode; + + Historical::prove((fg_primitives::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(fg_primitives::OpaqueKeyOwnershipProof::new) + } + } + + impl babe_primitives::BabeApi 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. + // + 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 { + use codec::Encode; + + Historical::prove((babe_primitives::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(babe_primitives::OpaqueKeyOwnershipProof::new) + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: babe_primitives::EquivocationProof<::Header>, + key_owner_proof: babe_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Babe::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } + } + + impl authority_discovery_primitives::AuthorityDiscoveryApi for Runtime { + fn authorities() -> Vec { + AuthorityDiscovery::authorities() + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) + } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, sp_core::crypto::KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } + } + + impl system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Nonce { + System::account_nonce(account) + } + } + + impl transaction_payment_rpc_runtime_api::TransactionPaymentApi< + Block, + Balance, + UncheckedExtrinsic, + > for Runtime { + fn query_info(uxt: UncheckedExtrinsic, len: u32) -> RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + } +} +/// 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>; +/// The payload being signed in transactions. +pub type SignedPayload = generic::SignedPayload; + +impl_opaque_keys! { + pub struct SessionKeys { + pub babe: Babe, + pub im_online: ImOnline, + pub parachain_validator: Initializer, + } +} + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = primitives::v1::Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system::{Module, Call, Storage, Config, Event}, + + // Must be before session. + Babe: babe::{Module, Call, Storage, Config, Inherent, ValidateUnsigned}, + + Timestamp: timestamp::{Module, Call, Storage, Inherent}, + Indices: indices::{Module, Call, Storage, Config, Event}, + Balances: balances::{Module, Call, Storage, Config, Event}, + TransactionPayment: transaction_payment::{Module, Storage}, + + // Consensus support. + Authorship: authorship::{Module, Call, Storage}, + Staking: staking::{Module, Call, Storage, Config, Event, ValidateUnsigned}, + Offences: offences::{Module, Call, Storage, Event}, + Historical: session_historical::{Module}, + Session: session::{Module, Call, Storage, Event, Config}, + Grandpa: grandpa::{Module, Call, Storage, Config, Event, ValidateUnsigned}, + ImOnline: im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, + AuthorityDiscovery: authority_discovery::{Module, Call, Config}, + + // Parachains modules. + Config: parachains_configuration::{Module, Call, Storage}, + Inclusion: parachains_inclusion::{Module, Call, Storage, Event}, + InclusionInherent: parachains_inclusion_inherent::{Module, Call, Storage}, + Scheduler: parachains_scheduler::{Module, Call, Storage}, + Paras: parachains_paras::{Module, Call, Storage}, + Initializer: parachains_initializer::{Module, Call, Storage}, + } +} + +pub struct BaseFilter; +impl Filter for BaseFilter { + fn filter(_call: &Call) -> bool { + true + } +} + +/// Runtime version (Rococo). +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("rococo"), + impl_name: create_runtime_str!("parity-rococo"), + authoring_version: 0, + spec_version: 1, + impl_version: 0, + #[cfg(not(feature = "disable-runtime-api"))] + apis: RUNTIME_API_VERSIONS, + #[cfg(feature = "disable-runtime-api")] + apis: version::create_apis_vec![[]], + transaction_version: 2, +}; + +parameter_types! { + pub const Version: RuntimeVersion = VERSION; +} + +impl system::Trait for Runtime { + type BaseCallFilter = BaseFilter; + type Origin = Origin; + type Call = Call; + type Index = Nonce; + type BlockNumber = BlockNumber; + type Hash = Hash; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = generic::Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = RocksDbWeight; + type BlockExecutionWeight = BlockExecutionWeight; + type ExtrinsicBaseWeight = ExtrinsicBaseWeight; + type MaximumExtrinsicWeight = MaximumExtrinsicWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = Version; + type ModuleToIndex = ModuleToIndex; + type AccountData = balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} + +parameter_types! { + pub const MaxCodeSize: u32 = 10 * 1024 * 1024; // 10 MB + pub const MaxHeadDataSize: u32 = 20 * 1024; // 20 KB + pub const ValidationUpgradeFrequency: BlockNumber = 2 * DAYS; + pub const ValidationUpgradeDelay: BlockNumber = 8 * HOURS; + pub const SlashPeriod: BlockNumber = 7 * DAYS; +} + +/// Submits a transaction with the node's public and signature type. Adheres to the signed extension +/// format of the chain. +impl system::offchain::CreateSignedTransaction for Runtime where + Call: From, +{ + fn create_transaction>( + call: Call, + public: ::Signer, + account: AccountId, + nonce: ::Index, + ) -> Option<(Call, ::SignaturePayload)> { + // take the biggest period possible. + 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::() + // The `System::block_number` is initialized with `n+1`, + // so the actual block number is `n`. + .saturating_sub(1); + let tip = 0; + let extra: SignedExtra = ( + system::CheckSpecVersion::::new(), + system::CheckTxVersion::::new(), + system::CheckGenesis::::new(), + system::CheckMortality::::from(generic::Era::mortal(period, current_block)), + system::CheckNonce::::from(nonce), + system::CheckWeight::::new(), + transaction_payment::ChargeTransactionPayment::::from(tip), + ); + let raw_payload = SignedPayload::new(call, extra).map_err(|e| { + debug::warn!("Unable to create signed payload: {:?}", e); + }).ok()?; + let signature = raw_payload.using_encoded(|payload| { + C::sign(payload, public) + })?; + let (call, extra, _) = raw_payload.deconstruct(); + Some((call, (account, signature, extra))) + } +} + +impl system::offchain::SigningTypes for Runtime { + type Public = ::Signer; + type Signature = Signature; +} + +impl session::historical::Trait for Runtime { + type FullIdentification = staking::Exposure; + type FullIdentificationOf = staking::ExposureOf; +} + +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 const SessionsPerEra: SessionIndex = 6; + // 28 eras for unbonding (7 days). + pub const BondingDuration: staking::EraIndex = 28; + // 27 eras in which slashes can be cancelled (~7 days). + pub const SlashDeferDuration: staking::EraIndex = 27; + pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; + pub const MaxNominatorRewardedPerValidator: u32 = 64; + // quarter of the last session will be for election. + pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 4; + pub const MaxIterations: u32 = 10; + pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000); +} + +parameter_types! { + pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_BLOCKS as _; +} + +parameter_types! { + pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2; + pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); +} + +impl im_online::Trait for Runtime { + type AuthorityId = ImOnlineId; + type Event = Event; + type ReportUnresponsiveness = Offences; + type SessionDuration = SessionDuration; + type UnsignedPriority = StakingUnsignedPriority; + type WeightInfo = (); +} + +impl staking::Trait for Runtime { + type Currency = Balances; + type UnixTime = Timestamp; + type CurrencyToVote = CurrencyToVoteHandler; + 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 = EnsureRoot; + type SessionInterface = Self; + type RewardCurve = RewardCurve; + type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; + type NextNewSession = Session; + type ElectionLookahead = ElectionLookahead; + type Call = Call; + type UnsignedPriority = StakingUnsignedPriority; + type MaxIterations = MaxIterations; + type MinSolutionScoreBump = MinSolutionScoreBump; + type WeightInfo = (); +} + +parameter_types! { + pub const ExistentialDeposit: Balance = 1 * CENTS; +} + +impl balances::Trait for Runtime { + type Balance = Balance; + type DustRemoval = (); + type Event = Event; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); +} + +impl system::offchain::SendTransactionTypes for Runtime where + Call: From, +{ + type OverarchingCall = Call; + type Extrinsic = UncheckedExtrinsic; +} + +parameter_types! { + pub const ParathreadDeposit: Balance = 5 * DOLLARS; + pub const QueueSize: usize = 2; + pub const MaxRetries: u32 = 3; +} + +parameter_types! { + pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); +} + +impl offences::Trait for Runtime { + type Event = Event; + type IdentificationTuple = session::historical::IdentificationTuple; + type OnOffenceHandler = Staking; + type WeightSoftLimit = OffencesWeightSoftLimit; + type WeightInfo = (); +} + +impl authority_discovery::Trait for Runtime {} + +parameter_types! { + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; +} +impl timestamp::Trait for Runtime { + type Moment = u64; + type OnTimestampSet = Babe; + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +parameter_types! { + pub const TransactionByteFee: Balance = 10 * MILLICENTS; +} + +impl transaction_payment::Trait for Runtime { + type Currency = Balances; + type OnTransactionPayment = ToAuthor; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = WeightToFee; + type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; +} + +parameter_types! { + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17); +} + +impl session::Trait for Runtime { + type Event = Event; + type ValidatorId = AccountId; + type ValidatorIdOf = staking::StashOf; + type ShouldEndSession = Babe; + type NextSessionRotation = Babe; + type SessionManager = session::historical::NoteHistoricalRoot; + type SessionHandler = ::KeyTypeIdProviders; + type Keys = SessionKeys; + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type WeightInfo = (); +} + +parameter_types! { + pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64; + pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; +} + +impl babe::Trait for Runtime { + type EpochDuration = EpochDuration; + type ExpectedBlockTime = ExpectedBlockTime; + + // session module is the trigger + type EpochChangeTrigger = babe::ExternalTrigger; + + type KeyOwnerProofSystem = Historical; + + type KeyOwnerProof = >::Proof; + + type KeyOwnerIdentification = >::IdentificationTuple; + + type HandleEquivocation = + babe::EquivocationHandler; +} + +parameter_types! { + pub const IndexDeposit: Balance = 1 * DOLLARS; +} + +impl indices::Trait for Runtime { + type AccountIndex = AccountIndex; + type Currency = Balances; + type Deposit = IndexDeposit; + type Event = Event; + type WeightInfo = (); +} + +parameter_types! { + pub const AttestationPeriod: BlockNumber = 50; +} + +impl grandpa::Trait for Runtime { + type Event = Event; + type Call = Call; + + type KeyOwnerProofSystem = Historical; + + type KeyOwnerProof = + >::Proof; + + type KeyOwnerIdentification = >::IdentificationTuple; + + type HandleEquivocation = grandpa::EquivocationHandler; +} + +parameter_types! { + pub const UncleGenerations: u32 = 0; +} + +// TODO: substrate#2986 implement this properly +impl authorship::Trait for Runtime { + type FindAuthor = session::FindAccountFromAuthorIndex; + type UncleGenerations = UncleGenerations; + type FilterUncle = (); + type EventHandler = (Staking, ImOnline); +} + +impl parachains_configuration::Trait for Runtime { } + +impl parachains_inclusion::Trait for Runtime { + type Event = Event; +} + +impl parachains_paras::Trait for Runtime { } + +impl parachains_inclusion_inherent::Trait for Runtime { } + +impl parachains_scheduler::Trait for Runtime { } + +impl parachains_initializer::Trait for Runtime { + type Randomness = Babe; +}