mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-09 23:28:00 +00:00
Update to latest Substrate (#340)
* Update Substrate * Update Substrate again * Integrate weight/fee stuff. * Add new files.
This commit is contained in:
Generated
+630
-692
File diff suppressed because it is too large
Load Diff
@@ -450,7 +450,7 @@ pub fn run_collator<P, E>(
|
||||
mod tests {
|
||||
use std::collections::HashMap;
|
||||
use polkadot_primitives::parachain::{OutgoingMessage, FeeSchedule};
|
||||
use keyring::AuthorityKeyring;
|
||||
use keyring::Ed25519Keyring;
|
||||
use super::*;
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
@@ -540,7 +540,7 @@ mod tests {
|
||||
},
|
||||
context.clone(),
|
||||
DummyParachainContext,
|
||||
AuthorityKeyring::Alice.pair().into(),
|
||||
Ed25519Keyring::Alice.pair().into(),
|
||||
).wait().unwrap();
|
||||
|
||||
// ascending order by root.
|
||||
|
||||
@@ -23,7 +23,7 @@ use crate::gossip::GossipMessage;
|
||||
use substrate_network::Context as NetContext;
|
||||
use substrate_network::consensus_gossip::TopicNotification;
|
||||
use substrate_primitives::{NativeOrEncoded, ExecutionContext};
|
||||
use substrate_keyring::AuthorityKeyring;
|
||||
use substrate_keyring::Ed25519Keyring;
|
||||
use crate::PolkadotProtocol;
|
||||
|
||||
use polkadot_validation::{SharedTable, MessagesFrom, Network};
|
||||
@@ -399,8 +399,8 @@ impl IngressBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_table(data: &ApiData, local_key: &AuthorityKeyring, parent_hash: Hash) -> Arc<SharedTable> {
|
||||
use ::av_store::Store;
|
||||
fn make_table(data: &ApiData, local_key: &Ed25519Keyring, parent_hash: Hash) -> Arc<SharedTable> {
|
||||
use av_store::Store;
|
||||
|
||||
let store = Store::new_in_memory();
|
||||
let (group_info, _) = ::polkadot_validation::make_group_info(
|
||||
|
||||
@@ -20,12 +20,7 @@
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
use rstd::prelude::*;
|
||||
use runtime_primitives::{generic, traits::Extrinsic, AnySignature};
|
||||
use parity_codec::{Encode, Decode};
|
||||
use runtime_primitives::{generic, AnySignature};
|
||||
use primitives::ed25519;
|
||||
|
||||
pub use runtime_primitives::traits::{BlakeTwo256, Hash as HashT, Verify};
|
||||
@@ -34,9 +29,6 @@ pub mod parachain;
|
||||
|
||||
pub use parity_codec::Compact;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use primitives::bytes;
|
||||
|
||||
/// An index to a block.
|
||||
/// 32-bits will allow for 136 years of blocks assuming 1 block per second.
|
||||
/// TODO: switch to u32 (https://github.com/paritytech/polkadot/issues/221)
|
||||
@@ -92,8 +84,4 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
pub type BlockId = generic::BlockId<Block>;
|
||||
|
||||
/// Opaque, encoded, unchecked extrinsic.
|
||||
#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub struct UncheckedExtrinsic(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
impl Extrinsic for UncheckedExtrinsic {}
|
||||
pub use runtime_primitives::OpaqueExtrinsic as UncheckedExtrinsic;
|
||||
|
||||
@@ -24,8 +24,11 @@ use system::ensure_none;
|
||||
use parity_codec::{Encode, Decode};
|
||||
#[cfg(feature = "std")]
|
||||
use sr_primitives::traits::Zero;
|
||||
use sr_primitives::traits::ValidateUnsigned;
|
||||
use sr_primitives::transaction_validity::{TransactionLongevity, TransactionValidity};
|
||||
use sr_primitives::{
|
||||
weights::SimpleDispatchInfo,
|
||||
traits::ValidateUnsigned,
|
||||
transaction_validity::{TransactionLongevity, TransactionValidity, ValidTransaction},
|
||||
};
|
||||
use system;
|
||||
|
||||
type BalanceOf<T> = <<T as Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance;
|
||||
@@ -97,6 +100,7 @@ decl_module! {
|
||||
fn deposit_event<T>() = default;
|
||||
|
||||
/// Make a claim.
|
||||
#[weight = SimpleDispatchInfo::FixedNormal(1_000_000)]
|
||||
fn claim(origin, dest: T::AccountId, ethereum_signature: EcdsaSignature) {
|
||||
ensure_none(origin)?;
|
||||
|
||||
@@ -171,13 +175,13 @@ impl<T: Trait> ValidateUnsigned for Module<T> {
|
||||
return TransactionValidity::Invalid(SIGNER_HAS_NO_CLAIM);
|
||||
}
|
||||
|
||||
TransactionValidity::Valid {
|
||||
TransactionValidity::Valid(ValidTransaction {
|
||||
priority: PRIORITY,
|
||||
requires: vec![],
|
||||
provides: vec![],
|
||||
longevity: TransactionLongevity::max_value(),
|
||||
propagate: true,
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => TransactionValidity::Invalid(INVALID_CALL)
|
||||
}
|
||||
@@ -196,9 +200,7 @@ mod tests {
|
||||
use parity_codec::{Decode, Encode};
|
||||
// The testing primitives are very useful for avoiding having to work with signatures
|
||||
// or public keys. `u64` is used as the `AccountId` and no `Signature`s are required.
|
||||
use sr_primitives::{
|
||||
traits::{BlakeTwo256, IdentityLookup}, testing::Header
|
||||
};
|
||||
use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup, ConvertInto}, testing::Header};
|
||||
use balances;
|
||||
use srml_support::{impl_outer_origin, assert_ok, assert_err, assert_noop, parameter_types};
|
||||
|
||||
@@ -213,6 +215,9 @@ mod tests {
|
||||
pub struct Test;
|
||||
parameter_types! {
|
||||
pub const BlockHashCount: u64 = 250;
|
||||
pub const MaximumBlockWeight: u32 = 4 * 1024 * 1024;
|
||||
pub const MaximumBlockLength: u32 = 4 * 1024 * 1024;
|
||||
pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
|
||||
}
|
||||
impl system::Trait for Test {
|
||||
type Origin = Origin;
|
||||
@@ -222,9 +227,13 @@ mod tests {
|
||||
type Hashing = BlakeTwo256;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<u64>;
|
||||
type WeightMultiplierUpdate = ();
|
||||
type Header = Header;
|
||||
type Event = ();
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type MaximumBlockWeight = MaximumBlockWeight;
|
||||
type AvailableBlockRatio = AvailableBlockRatio;
|
||||
type MaximumBlockLength = MaximumBlockLength;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
@@ -248,6 +257,7 @@ mod tests {
|
||||
type CreationFee = CreationFee;
|
||||
type TransactionBaseFee = TransactionBaseFee;
|
||||
type TransactionByteFee = TransactionByteFee;
|
||||
type WeightToFee = ConvertInto;
|
||||
}
|
||||
|
||||
parameter_types!{
|
||||
@@ -369,13 +379,13 @@ mod tests {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
assert_eq!(
|
||||
<Module<Test>>::validate_unsigned(&Call::claim(1, alice_sig(&1u64.encode()))),
|
||||
TransactionValidity::Valid {
|
||||
TransactionValidity::Valid(ValidTransaction {
|
||||
priority: 100,
|
||||
requires: vec![],
|
||||
provides: vec![],
|
||||
longevity: TransactionLongevity::max_value(),
|
||||
propagate: true,
|
||||
}
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
<Module<Test>>::validate_unsigned(&Call::claim(0, EcdsaSignature::from_blob(&[0; 65]))),
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright 2019 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/>.
|
||||
|
||||
/// Money matters.
|
||||
pub mod currency {
|
||||
use primitives::Balance;
|
||||
|
||||
pub const DOTS: Balance = 1_000_000_000_000;
|
||||
pub const BUCKS: Balance = DOTS / 100;
|
||||
pub const CENTS: Balance = BUCKS / 100;
|
||||
pub const MILLICENTS: Balance = CENTS / 1_000;
|
||||
}
|
||||
|
||||
/// Time.
|
||||
pub mod time {
|
||||
pub const SECS_PER_BLOCK: u64 = 6;
|
||||
pub const MINUTES: u64 = 60 / SECS_PER_BLOCK;
|
||||
pub const HOURS: u64 = MINUTES * 60;
|
||||
pub const DAYS: u64 = HOURS * 24;
|
||||
}
|
||||
|
||||
/// Fee-related.
|
||||
pub mod fee {
|
||||
pub use sr_primitives::Perbill;
|
||||
|
||||
/// The block saturation level. Fees will be updates based on this value.
|
||||
pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25);
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
use {grandpa, system};
|
||||
use parity_codec::Decode;
|
||||
use sr_primitives::traits::{Hash as HashT, BlakeTwo256, Zero};
|
||||
use sr_primitives::weights::SimpleDispatchInfo;
|
||||
use rstd::prelude::*;
|
||||
use srml_support::{decl_storage, decl_module};
|
||||
|
||||
@@ -37,6 +38,7 @@ decl_module! {
|
||||
/// curated GRANDPA set.
|
||||
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
|
||||
/// Changes the GRANDPA voter set.
|
||||
#[weight = SimpleDispatchInfo::FixedOperational(10_000)]
|
||||
fn set_voters(origin, voters: Vec<(grandpa::AuthorityId, u64)>) {
|
||||
system::ensure_root(origin)?;
|
||||
grandpa::Module::<T>::schedule_change(voters, T::BlockNumber::zero(), None)?;
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
// Copyright 2019 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/>.
|
||||
|
||||
//! Auxillary struct/enums for polkadot runtime.
|
||||
|
||||
use primitives::Balance;
|
||||
use sr_primitives::weights::{Weight, WeightMultiplier};
|
||||
use sr_primitives::traits::{Convert, Saturating};
|
||||
use sr_primitives::Fixed64;
|
||||
use srml_support::traits::{OnUnbalanced, Currency};
|
||||
use crate::{Balances, Authorship, MaximumBlockWeight, NegativeImbalance};
|
||||
use crate::constants::fee::TARGET_BLOCK_FULLNESS;
|
||||
|
||||
/// Logic for the author to get a portion of fees.
|
||||
pub struct ToAuthor;
|
||||
|
||||
impl OnUnbalanced<NegativeImbalance> for ToAuthor {
|
||||
fn on_unbalanced(amount: NegativeImbalance) {
|
||||
Balances::resolve_creating(&Authorship::author(), amount);
|
||||
}
|
||||
}
|
||||
|
||||
/// Converter for currencies to votes.
|
||||
pub struct CurrencyToVoteHandler;
|
||||
|
||||
impl CurrencyToVoteHandler {
|
||||
fn factor() -> u128 { (Balances::total_issuance() / u64::max_value() as u128).max(1) }
|
||||
}
|
||||
|
||||
impl Convert<u128, u64> for CurrencyToVoteHandler {
|
||||
fn convert(x: u128) -> u64 { (x / Self::factor()) as u64 }
|
||||
}
|
||||
|
||||
impl Convert<u128, u128> for CurrencyToVoteHandler {
|
||||
fn convert(x: u128) -> u128 { x * Self::factor() }
|
||||
}
|
||||
|
||||
/// 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 Convert<Weight, Balance> for WeightToFee {
|
||||
fn convert(x: Weight) -> Balance {
|
||||
// in Polkadot a weight of 10_000 (smallest non-zero weight) to be mapped to 10^7 units of
|
||||
// fees (1/10 CENT), hence:
|
||||
Balance::from(x).saturating_mul(1_000)
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct that updates the weight multiplier based on the saturation level of the previous block.
|
||||
/// This should typically be called once per-block.
|
||||
///
|
||||
/// This assumes that weight is a numeric value in the u32 range.
|
||||
///
|
||||
/// Given `TARGET_BLOCK_FULLNESS = 1/2`, a block saturation greater than 1/2 will cause the system
|
||||
/// fees to slightly grow and the opposite for block saturations less than 1/2.
|
||||
///
|
||||
/// Formula:
|
||||
/// diff = (target_weight - current_block_weight)
|
||||
/// v = 0.00004
|
||||
/// next_weight = weight * (1 + (v . diff) + (v . diff)^2 / 2)
|
||||
///
|
||||
/// https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#relay-chain-transaction-fees
|
||||
pub struct WeightMultiplierUpdateHandler;
|
||||
|
||||
impl Convert<(Weight, WeightMultiplier), WeightMultiplier> for WeightMultiplierUpdateHandler {
|
||||
fn convert(previous_state: (Weight, WeightMultiplier)) -> WeightMultiplier {
|
||||
let (block_weight, multiplier) = previous_state;
|
||||
let max_weight = MaximumBlockWeight::get();
|
||||
let target_weight = (TARGET_BLOCK_FULLNESS * max_weight) as u128;
|
||||
let block_weight = block_weight as u128;
|
||||
|
||||
// determines if the first_term is positive
|
||||
let positive = block_weight >= target_weight;
|
||||
let diff_abs = block_weight.max(target_weight) - block_weight.min(target_weight);
|
||||
// diff is within u32, safe.
|
||||
let diff = Fixed64::from_rational(diff_abs as i64, max_weight as u64);
|
||||
let diff_squared = diff.saturating_mul(diff);
|
||||
|
||||
// 0.00004 = 4/100_000 = 40_000/10^9
|
||||
let v = Fixed64::from_rational(4, 100_000);
|
||||
// 0.00004^2 = 16/10^10 ~= 2/10^9. Taking the future /2 into account, then it is just 1 parts
|
||||
// from a billionth.
|
||||
let v_squared_2 = Fixed64::from_rational(1, 1_000_000_000);
|
||||
|
||||
let first_term = v.saturating_mul(diff);
|
||||
// It is very unlikely that this will exist (in our poor perbill estimate) but we are giving
|
||||
// it a shot.
|
||||
let second_term = v_squared_2.saturating_mul(diff_squared);
|
||||
|
||||
if positive {
|
||||
// Note: this is merely bounded by how big the multiplier and the inner value can go,
|
||||
// not by any economical reasoning.
|
||||
let excess = first_term.saturating_add(second_term);
|
||||
multiplier.saturating_add(WeightMultiplier::from_fixed(excess))
|
||||
} else {
|
||||
// first_term > second_term
|
||||
let negative = first_term - second_term;
|
||||
multiplier.saturating_sub(WeightMultiplier::from_fixed(negative))
|
||||
// despite the fact that apply_to saturates weight (final fee cannot go below 0)
|
||||
// it is crucially important to stop here and don't further reduce the weight fee
|
||||
// multiplier. While at -1, it means that the network is so un-congested that all
|
||||
// transactions have no weight fee. We stop here and only increase if the network
|
||||
// became more busy.
|
||||
.max(WeightMultiplier::from_rational(-1, 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
+36
-44
@@ -38,7 +38,8 @@ use client::{
|
||||
};
|
||||
use sr_primitives::{
|
||||
ApplyResult, generic, transaction_validity::TransactionValidity, create_runtime_str, key_types,
|
||||
traits::{BlakeTwo256, Block as BlockT, DigestFor, StaticLookup, Convert}, impl_opaque_keys
|
||||
traits::{BlakeTwo256, Block as BlockT, DigestFor, StaticLookup},
|
||||
impl_opaque_keys, weights::Weight,
|
||||
};
|
||||
use version::RuntimeVersion;
|
||||
use grandpa::{AuthorityId as GrandpaId, fg_primitives::{self, ScheduledChange}};
|
||||
@@ -47,7 +48,7 @@ use elections::VoteIndex;
|
||||
use version::NativeVersion;
|
||||
use substrate_primitives::OpaqueMetadata;
|
||||
use srml_support::{
|
||||
parameter_types, construct_runtime, traits::{SplitTwoWays, Currency, OnUnbalanced}
|
||||
parameter_types, construct_runtime, traits::{SplitTwoWays, Currency}
|
||||
};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@@ -60,6 +61,14 @@ pub use parachains::{Call as ParachainsCall, INHERENT_IDENTIFIER as PARACHAIN_IN
|
||||
pub use sr_primitives::{Permill, Perbill};
|
||||
pub use srml_support::StorageValue;
|
||||
|
||||
/// Implementations of some helper traits passed into runtime modules as associated types.
|
||||
pub mod impls;
|
||||
use impls::{CurrencyToVoteHandler, WeightMultiplierUpdateHandler, ToAuthor, WeightToFee};
|
||||
|
||||
/// Constant values used within the runtime.
|
||||
pub mod constants;
|
||||
use constants::{time::*, currency::*};
|
||||
|
||||
// Make the WASM binary available.
|
||||
#[cfg(feature = "std")]
|
||||
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
|
||||
@@ -83,17 +92,13 @@ pub fn native_version() -> NativeVersion {
|
||||
}
|
||||
}
|
||||
|
||||
pub const MILLICENTS: Balance = 1_000_000_000;
|
||||
pub const CENTS: Balance = 1_000 * MILLICENTS; // assume this is worth about a cent.
|
||||
pub const DOLLARS: Balance = 100 * CENTS;
|
||||
|
||||
pub const SECS_PER_BLOCK: BlockNumber = 6;
|
||||
pub const MINUTES: BlockNumber = 60 / SECS_PER_BLOCK;
|
||||
pub const HOURS: BlockNumber = MINUTES * 60;
|
||||
pub const DAYS: BlockNumber = HOURS * 24;
|
||||
type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
|
||||
|
||||
parameter_types! {
|
||||
pub const BlockHashCount: u64 = 250;
|
||||
pub const MaximumBlockWeight: Weight = 1_000_000_000;
|
||||
pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
|
||||
pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
|
||||
}
|
||||
|
||||
impl system::Trait for Runtime {
|
||||
@@ -105,8 +110,12 @@ impl system::Trait for Runtime {
|
||||
type AccountId = AccountId;
|
||||
type Lookup = Indices;
|
||||
type Header = generic::Header<BlockNumber, BlakeTwo256>;
|
||||
type WeightMultiplierUpdate = WeightMultiplierUpdateHandler;
|
||||
type Event = Event;
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type MaximumBlockWeight = MaximumBlockWeight;
|
||||
type MaximumBlockLength = MaximumBlockLength;
|
||||
type AvailableBlockRatio = AvailableBlockRatio;
|
||||
}
|
||||
|
||||
impl aura::Trait for Runtime {
|
||||
@@ -122,24 +131,13 @@ impl indices::Trait for Runtime {
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const ExistentialDeposit: Balance = 1 * DOLLARS;
|
||||
pub const ExistentialDeposit: Balance = 10 * CENTS;
|
||||
pub const TransferFee: Balance = 1 * CENTS;
|
||||
pub const CreationFee: Balance = 1 * CENTS;
|
||||
pub const TransactionBaseFee: Balance = 1 * CENTS;
|
||||
pub const TransactionByteFee: Balance = 10 * MILLICENTS;
|
||||
}
|
||||
|
||||
|
||||
/// Logic for the author to get a portion of fees.
|
||||
pub struct ToAuthor;
|
||||
|
||||
type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
|
||||
impl OnUnbalanced<NegativeImbalance> for ToAuthor {
|
||||
fn on_unbalanced(amount: NegativeImbalance) {
|
||||
Balances::resolve_creating(&Authorship::author(), amount);
|
||||
}
|
||||
}
|
||||
|
||||
/// Splits fees 80/20 between treasury and block author.
|
||||
pub type DealWithFees = SplitTwoWays<
|
||||
Balance,
|
||||
@@ -161,6 +159,7 @@ impl balances::Trait for Runtime {
|
||||
type CreationFee = CreationFee;
|
||||
type TransactionBaseFee = TransactionBaseFee;
|
||||
type TransactionByteFee = TransactionByteFee;
|
||||
type WeightToFee = WeightToFee;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
@@ -220,21 +219,6 @@ impl session::historical::Trait for Runtime {
|
||||
type FullIdentificationOf = staking::ExposureOf<Self>;
|
||||
}
|
||||
|
||||
/// Converter for currencies to votes.
|
||||
pub struct CurrencyToVoteHandler;
|
||||
|
||||
impl CurrencyToVoteHandler {
|
||||
fn factor() -> u128 { (Balances::total_issuance() / u64::max_value() as u128).max(1) }
|
||||
}
|
||||
|
||||
impl Convert<u128, u64> for CurrencyToVoteHandler {
|
||||
fn convert(x: u128) -> u64 { (x / Self::factor()) as u64 }
|
||||
}
|
||||
|
||||
impl Convert<u128, u128> for CurrencyToVoteHandler {
|
||||
fn convert(x: u128) -> u128 { x * Self::factor() }
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const SessionsPerEra: session::SessionIndex = 6;
|
||||
pub const BondingDuration: staking::EraIndex = 24 * 28;
|
||||
@@ -250,13 +234,14 @@ impl staking::Trait for Runtime {
|
||||
type SessionsPerEra = SessionsPerEra;
|
||||
type BondingDuration = BondingDuration;
|
||||
type SessionInterface = Self;
|
||||
type Time = Timestamp;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const LaunchPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
|
||||
pub const VotingPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
|
||||
pub const EmergencyVotingPeriod: BlockNumber = 3 * 24 * 60 * MINUTES;
|
||||
pub const MinimumDeposit: Balance = 100 * DOLLARS;
|
||||
pub const MinimumDeposit: Balance = 100 * BUCKS;
|
||||
pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
|
||||
pub const CooloffPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
|
||||
}
|
||||
@@ -287,9 +272,9 @@ impl collective::Trait<CouncilInstance> for Runtime {
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const CandidacyBond: Balance = 10 * DOLLARS;
|
||||
pub const VotingBond: Balance = 1 * DOLLARS;
|
||||
pub const VotingFee: Balance = 2 * DOLLARS;
|
||||
pub const CandidacyBond: Balance = 10 * BUCKS;
|
||||
pub const VotingBond: Balance = 1 * BUCKS;
|
||||
pub const VotingFee: Balance = 2 * BUCKS;
|
||||
pub const PresentSlashPerVoter: Balance = 1 * CENTS;
|
||||
pub const CarryCount: u32 = 6;
|
||||
// one additional vote should go by before an inactive voter can be reaped.
|
||||
@@ -325,7 +310,7 @@ impl collective::Trait<TechnicalInstance> for Runtime {
|
||||
|
||||
parameter_types! {
|
||||
pub const ProposalBond: Permill = Permill::from_percent(5);
|
||||
pub const ProposalBondMinimum: Balance = 1 * DOLLARS;
|
||||
pub const ProposalBondMinimum: Balance = 1 * BUCKS;
|
||||
pub const SpendPeriod: BlockNumber = 1 * DAYS;
|
||||
pub const Burn: Permill = Permill::from_percent(50);
|
||||
}
|
||||
@@ -422,12 +407,19 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
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 = (
|
||||
system::CheckEra<Runtime>,
|
||||
system::CheckNonce<Runtime>,
|
||||
system::CheckWeight<Runtime>,
|
||||
balances::TakeFees<Runtime>
|
||||
);
|
||||
/// Unchecked extrinsic type as expected by this runtime.
|
||||
pub type UncheckedExtrinsic = generic::UncheckedMortalCompactExtrinsic<Address, Nonce, Call, Signature>;
|
||||
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 = executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Balances, Runtime, AllModules>;
|
||||
pub type Executive = executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;
|
||||
|
||||
impl_runtime_apis! {
|
||||
impl client_api::Core<Block> for Runtime {
|
||||
|
||||
@@ -23,6 +23,7 @@ use srml_support::{decl_storage, decl_module, fail, ensure};
|
||||
|
||||
use bitvec::{bitvec, BigEndian};
|
||||
use sr_primitives::traits::{Hash as HashT, BlakeTwo256, Member, CheckedConversion, Saturating, One};
|
||||
use sr_primitives::weights::SimpleDispatchInfo;
|
||||
use primitives::{Hash, Balance, parachain::{
|
||||
self, Id as ParaId, Chain, DutyRoster, AttestedCandidate, Statement, AccountIdConversion,
|
||||
ParachainDispatchOrigin, UpwardMessage, BlockIngressRoots,
|
||||
@@ -265,6 +266,7 @@ decl_module! {
|
||||
/// Parachains module.
|
||||
pub struct Module<T: Trait> for enum Call where origin: <T as system::Trait>::Origin {
|
||||
/// Provide candidate receipts for parachains, in ascending order by id.
|
||||
#[weight = SimpleDispatchInfo::FixedNormal(1_000_000)]
|
||||
fn set_heads(origin, heads: Vec<AttestedCandidate>) -> Result {
|
||||
ensure_none(origin)?;
|
||||
ensure!(!<DidUpdate>::exists(), "Parachain heads must be updated only once in the block");
|
||||
@@ -329,12 +331,14 @@ decl_module! {
|
||||
|
||||
/// Register a parachain with given code.
|
||||
/// Fails if given ID is already used.
|
||||
#[weight = SimpleDispatchInfo::FixedOperational(5_000_000)]
|
||||
pub fn register_parachain(origin, id: ParaId, code: Vec<u8>, initial_head_data: Vec<u8>) -> Result {
|
||||
ensure_root(origin)?;
|
||||
<Self as ParachainRegistrar<T::AccountId>>::register_parachain(id, code, initial_head_data)
|
||||
}
|
||||
|
||||
/// Deregister a parachain with given id
|
||||
#[weight = SimpleDispatchInfo::FixedOperational(10_000)]
|
||||
pub fn deregister_parachain(origin, id: ParaId) -> Result {
|
||||
ensure_root(origin)?;
|
||||
<Self as ParachainRegistrar<T::AccountId>>::deregister_parachain(id)
|
||||
@@ -818,14 +822,15 @@ mod tests {
|
||||
use substrate_primitives::{H256, Blake2Hasher};
|
||||
use substrate_trie::NodeCodec;
|
||||
use sr_primitives::{
|
||||
traits::{BlakeTwo256, IdentityLookup},
|
||||
Perbill,
|
||||
traits::{BlakeTwo256, IdentityLookup, ConvertInto},
|
||||
testing::{UintAuthorityId, Header},
|
||||
};
|
||||
use primitives::{
|
||||
parachain::{CandidateReceipt, HeadData, ValidityAttestation, ValidatorIndex}, SessionKey,
|
||||
BlockNumber, AuraId,
|
||||
};
|
||||
use keyring::{AuthorityKeyring, AccountKeyring};
|
||||
use keyring::Ed25519Keyring;
|
||||
use srml_support::{
|
||||
impl_outer_origin, impl_outer_dispatch, assert_ok, assert_err, parameter_types,
|
||||
};
|
||||
@@ -847,6 +852,9 @@ mod tests {
|
||||
pub struct Test;
|
||||
parameter_types! {
|
||||
pub const BlockHashCount: u64 = 250;
|
||||
pub const MaximumBlockWeight: u32 = 4 * 1024 * 1024;
|
||||
pub const MaximumBlockLength: u32 = 4 * 1024 * 1024;
|
||||
pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
|
||||
}
|
||||
impl system::Trait for Test {
|
||||
type Origin = Origin;
|
||||
@@ -857,8 +865,12 @@ mod tests {
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<u64>;
|
||||
type Header = Header;
|
||||
type WeightMultiplierUpdate = ();
|
||||
type Event = ();
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type MaximumBlockWeight = MaximumBlockWeight;
|
||||
type MaximumBlockLength = MaximumBlockLength;
|
||||
type AvailableBlockRatio = AvailableBlockRatio;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
@@ -917,6 +929,7 @@ mod tests {
|
||||
type CreationFee = CreationFee;
|
||||
type TransactionBaseFee = TransactionBaseFee;
|
||||
type TransactionByteFee = TransactionByteFee;
|
||||
type WeightToFee = ConvertInto;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
@@ -934,6 +947,7 @@ mod tests {
|
||||
type SessionsPerEra = SessionsPerEra;
|
||||
type BondingDuration = BondingDuration;
|
||||
type SessionInterface = Self;
|
||||
type Time = timestamp::Module<Test>;
|
||||
}
|
||||
|
||||
impl Trait for Test {
|
||||
@@ -948,24 +962,14 @@ mod tests {
|
||||
fn new_test_ext(parachains: Vec<(ParaId, Vec<u8>, Vec<u8>)>) -> TestExternalities<Blake2Hasher> {
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap().0;
|
||||
let authority_keys = [
|
||||
AuthorityKeyring::Alice,
|
||||
AuthorityKeyring::Bob,
|
||||
AuthorityKeyring::Charlie,
|
||||
AuthorityKeyring::Dave,
|
||||
AuthorityKeyring::Eve,
|
||||
AuthorityKeyring::Ferdie,
|
||||
AuthorityKeyring::One,
|
||||
AuthorityKeyring::Two,
|
||||
];
|
||||
let validator_keys = [
|
||||
AccountKeyring::Alice,
|
||||
AccountKeyring::Bob,
|
||||
AccountKeyring::Charlie,
|
||||
AccountKeyring::Dave,
|
||||
AccountKeyring::Eve,
|
||||
AccountKeyring::Ferdie,
|
||||
AccountKeyring::One,
|
||||
AccountKeyring::Two,
|
||||
Ed25519Keyring::Alice,
|
||||
Ed25519Keyring::Bob,
|
||||
Ed25519Keyring::Charlie,
|
||||
Ed25519Keyring::Dave,
|
||||
Ed25519Keyring::Eve,
|
||||
Ed25519Keyring::Ferdie,
|
||||
Ed25519Keyring::One,
|
||||
Ed25519Keyring::Two,
|
||||
];
|
||||
|
||||
t.extend(session::GenesisConfig::<Test>{
|
||||
@@ -994,7 +998,7 @@ mod tests {
|
||||
|
||||
let authorities = crate::Aura::authorities();
|
||||
let extract_key = |public: SessionKey| {
|
||||
AuthorityKeyring::from_raw_public(public.0).unwrap()
|
||||
Ed25519Keyring::from_raw_public(public.0).unwrap()
|
||||
};
|
||||
|
||||
let validation_entries = duty_roster.validator_duty.iter()
|
||||
|
||||
@@ -20,9 +20,12 @@
|
||||
|
||||
use rstd::{prelude::*, mem::swap, convert::TryInto};
|
||||
use sr_primitives::traits::{CheckedSub, StaticLookup, Zero, One, CheckedConversion, Hash};
|
||||
use sr_primitives::weights::SimpleDispatchInfo;
|
||||
use parity_codec::{Encode, Decode};
|
||||
use srml_support::{decl_module, decl_storage, decl_event, StorageValue, StorageMap, ensure,
|
||||
traits::{Currency, ReservableCurrency, WithdrawReason, ExistenceRequirement, Get}};
|
||||
use srml_support::{
|
||||
decl_module, decl_storage, decl_event, StorageValue, StorageMap, ensure,
|
||||
traits::{Currency, ReservableCurrency, WithdrawReason, ExistenceRequirement, Get}
|
||||
};
|
||||
use primitives::parachain::AccountIdConversion;
|
||||
use crate::parachains::ParachainRegistrar;
|
||||
use system::{ensure_signed, ensure_root};
|
||||
@@ -242,6 +245,7 @@ decl_module! {
|
||||
/// This can only happen when there isn't already an auction in progress and may only be
|
||||
/// called by the root origin. Accepts the `duration` of this auction and the
|
||||
/// `lease_period_index` of the initial lease period of the four that are to be auctioned.
|
||||
#[weight = SimpleDispatchInfo::FixedOperational(100_000)]
|
||||
fn new_auction(
|
||||
origin,
|
||||
#[compact] duration: T::BlockNumber,
|
||||
@@ -277,6 +281,7 @@ decl_module! {
|
||||
/// absolute lease period index value, not an auction-specific offset.
|
||||
/// - `amount` is the amount to bid to be held as deposit for the parachain should the
|
||||
/// bid win. This amount is held throughout the range.
|
||||
#[weight = SimpleDispatchInfo::FixedNormal(500_000)]
|
||||
fn bid(
|
||||
origin,
|
||||
#[compact] sub: SubId,
|
||||
@@ -305,6 +310,7 @@ decl_module! {
|
||||
/// absolute lease period index value, not an auction-specific offset.
|
||||
/// - `amount` is the amount to bid to be held as deposit for the parachain should the
|
||||
/// bid win. This amount is held throughout the range.
|
||||
#[weight = SimpleDispatchInfo::FixedNormal(500_000)]
|
||||
fn bid_renew(
|
||||
origin,
|
||||
#[compact] auction_index: AuctionIndex,
|
||||
@@ -324,6 +330,7 @@ decl_module! {
|
||||
/// The origin *must* be a parachain account.
|
||||
///
|
||||
/// - `dest` is the destination account to receive the parachain's deposit.
|
||||
#[weight = SimpleDispatchInfo::FixedNormal(1_000_000)]
|
||||
fn set_offboarding(origin, dest: <T::Lookup as StaticLookup>::Source) {
|
||||
let who = ensure_signed(origin)?;
|
||||
let dest = T::Lookup::lookup(dest)?;
|
||||
@@ -339,6 +346,7 @@ decl_module! {
|
||||
/// - `para_id` is the parachain ID allotted to the winning bidder.
|
||||
/// - `code_hash` is the hash of the parachain's Wasm validation function.
|
||||
/// - `initial_head_data` is the parachain's initial head data.
|
||||
#[weight = SimpleDispatchInfo::FixedNormal(500_000)]
|
||||
fn fix_deploy_data(
|
||||
origin,
|
||||
#[compact] sub: SubId,
|
||||
@@ -370,6 +378,7 @@ decl_module! {
|
||||
/// - `_origin` is irrelevant.
|
||||
/// - `para_id` is the parachain ID whose code will be elaborated.
|
||||
/// - `code` is the preimage of the registered `code_hash` of `para_id`.
|
||||
#[weight = SimpleDispatchInfo::FixedNormal(5_000_000)]
|
||||
fn elaborate_deploy_data(_origin, #[compact] para_id: ParaIdOf<T>, code: Vec<u8>) {
|
||||
let (starts, details) = <Onboarding<T>>::get(¶_id)
|
||||
.ok_or("parachain id not in onboarding")?;
|
||||
@@ -786,7 +795,9 @@ mod tests {
|
||||
use substrate_primitives::{Blake2Hasher, H256};
|
||||
use sr_io::with_externalities;
|
||||
use sr_primitives::{
|
||||
testing::Header, traits::{BlakeTwo256, Hash, IdentityLookup, OnInitialize, OnFinalize},
|
||||
Perbill,
|
||||
testing::Header,
|
||||
traits::{ConvertInto, BlakeTwo256, Hash, IdentityLookup, OnInitialize, OnFinalize},
|
||||
};
|
||||
use srml_support::{impl_outer_origin, parameter_types, assert_ok, assert_noop};
|
||||
use balances;
|
||||
@@ -803,6 +814,9 @@ mod tests {
|
||||
pub struct Test;
|
||||
parameter_types! {
|
||||
pub const BlockHashCount: u64 = 250;
|
||||
pub const MaximumBlockWeight: u32 = 4 * 1024 * 1024;
|
||||
pub const MaximumBlockLength: u32 = 4 * 1024 * 1024;
|
||||
pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
|
||||
}
|
||||
impl system::Trait for Test {
|
||||
type Origin = Origin;
|
||||
@@ -812,9 +826,13 @@ mod tests {
|
||||
type Hashing = BlakeTwo256;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<Self::AccountId>;
|
||||
type WeightMultiplierUpdate = ();
|
||||
type Header = Header;
|
||||
type Event = ();
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type MaximumBlockWeight = MaximumBlockWeight;
|
||||
type MaximumBlockLength = MaximumBlockLength;
|
||||
type AvailableBlockRatio = AvailableBlockRatio;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
@@ -838,6 +856,7 @@ mod tests {
|
||||
type CreationFee = CreationFee;
|
||||
type TransactionBaseFee = TransactionBaseFee;
|
||||
type TransactionByteFee = TransactionByteFee;
|
||||
type WeightToFee = ConvertInto;
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
|
||||
@@ -21,8 +21,9 @@ use polkadot_primitives::{AccountId, SessionKey};
|
||||
use polkadot_runtime::{
|
||||
GenesisConfig, CouncilConfig, ElectionsConfig, DemocracyConfig, SystemConfig, AuraConfig,
|
||||
SessionConfig, StakingConfig, BalancesConfig, Perbill, SessionKeys, TechnicalCommitteeConfig,
|
||||
GrandpaConfig, SudoConfig, IndicesConfig, CuratedGrandpaConfig, StakerStatus, WASM_BINARY, DAYS, DOLLARS,
|
||||
GrandpaConfig, SudoConfig, IndicesConfig, CuratedGrandpaConfig, StakerStatus, WASM_BINARY,
|
||||
};
|
||||
use polkadot_runtime::constants::{currency::DOTS, time::*};
|
||||
use telemetry::TelemetryEndpoints;
|
||||
use hex_literal::hex;
|
||||
|
||||
@@ -62,8 +63,8 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
hex!["8abecfa66704176be23df099bf441ea65444992d63b3ced3e76a17a4d38b0b0e"].unchecked_into(), // 5FCd9Y7RLNyxz5wnCAErfsLbXGG34L2BaZRHzhiJcMUMd5zd
|
||||
)];
|
||||
|
||||
const ENDOWMENT: u128 = 10_000_000 * DOLLARS;
|
||||
const STASH: u128 = 100 * DOLLARS;
|
||||
const ENDOWMENT: u128 = 1_000_000 * DOTS;
|
||||
const STASH: u128 = 100 * DOTS;
|
||||
|
||||
GenesisConfig {
|
||||
system: Some(SystemConfig {
|
||||
@@ -91,8 +92,6 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
staking: Some(StakingConfig {
|
||||
current_era: 0,
|
||||
offline_slash: Perbill::from_parts(1_000_000),
|
||||
session_reward: Perbill::from_parts(2_065),
|
||||
current_session_reward: 0,
|
||||
validator_count: 7,
|
||||
offline_slash_grace: 4,
|
||||
minimum_validator_count: 4,
|
||||
@@ -191,8 +190,8 @@ pub fn testnet_genesis(
|
||||
]
|
||||
});
|
||||
|
||||
const ENDOWMENT: u128 = 10_000_000 * DOLLARS;
|
||||
const STASH: u128 = 100 * DOLLARS;
|
||||
const ENDOWMENT: u128 = 1_000_000 * DOTS;
|
||||
const STASH: u128 = 100 * DOTS;
|
||||
|
||||
let desired_seats = (endowed_accounts.len() / 2 - initial_authorities.len()) as u32;
|
||||
|
||||
@@ -219,8 +218,6 @@ pub fn testnet_genesis(
|
||||
minimum_validator_count: 1,
|
||||
validator_count: 2,
|
||||
offline_slash: Perbill::zero(),
|
||||
session_reward: Perbill::zero(),
|
||||
current_session_reward: 0,
|
||||
offline_slash_grace: 0,
|
||||
stakers: initial_authorities.iter()
|
||||
.map(|x| (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator))
|
||||
@@ -244,7 +241,7 @@ pub fn testnet_genesis(
|
||||
).map(|a| (a.clone(), 1000000)).collect(),
|
||||
presentation_duration: 10,
|
||||
term_duration: 1000000,
|
||||
desired_seats: desired_seats,
|
||||
desired_seats,
|
||||
}),
|
||||
parachains: Some(Default::default()),
|
||||
sudo: Some(SudoConfig {
|
||||
|
||||
@@ -22,6 +22,7 @@ use client::LongestChain;
|
||||
use consensus_common::SelectChain;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use grandpa_primitives::AuthorityPair as GrandpaPair;
|
||||
use polkadot_primitives::{parachain, Block, Hash, BlockId, AuraPair};
|
||||
use polkadot_runtime::{GenesisConfig, RuntimeApi};
|
||||
use polkadot_network::gossip::{self as network_gossip, Known};
|
||||
@@ -149,6 +150,8 @@ impl PolkadotService for Service<LightComponents<Factory>> {
|
||||
service::construct_service_factory! {
|
||||
struct Factory {
|
||||
Block = Block,
|
||||
ConsensusPair = AuraPair,
|
||||
FinalityPair = GrandpaPair,
|
||||
RuntimeApi = RuntimeApi,
|
||||
NetworkProtocol = PolkadotProtocol {
|
||||
|config: &Configuration| Ok(PolkadotProtocol::new(config.custom.collating_for.clone()))
|
||||
@@ -175,7 +178,7 @@ service::construct_service_factory! {
|
||||
let grandpa_key = if service.config.disable_grandpa {
|
||||
None
|
||||
} else {
|
||||
service.authority_key::<grandpa_primitives::AuthorityPair>()
|
||||
service.authority_key()
|
||||
};
|
||||
|
||||
let config = grandpa::Config {
|
||||
@@ -228,7 +231,7 @@ service::construct_service_factory! {
|
||||
};
|
||||
|
||||
// run authorship only if authority.
|
||||
let aura_key = match service.authority_key::<AuraPair>() {
|
||||
let aura_key = match service.authority_key() {
|
||||
Some(key) => Arc::new(key),
|
||||
None => return Ok(service),
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
futures = "0.1.17"
|
||||
futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] }
|
||||
futures-timer = "0.2.1"
|
||||
parking_lot = "0.7.1"
|
||||
tokio = "0.1.7"
|
||||
derive_more = "0.14.0"
|
||||
|
||||
@@ -61,7 +61,7 @@ impl DynamicInclusion {
|
||||
/// would be enough, or `None` if it is sufficient now.
|
||||
///
|
||||
/// Panics if `now` is earlier than the `start`.
|
||||
pub fn acceptable_in(&self, now: Instant, included: usize) -> Option<Instant> {
|
||||
pub fn acceptable_in(&self, now: Instant, included: usize) -> Option<Duration> {
|
||||
let elapsed = now.duration_since(self.start);
|
||||
let elapsed = duration_to_micros(&elapsed);
|
||||
|
||||
@@ -70,8 +70,7 @@ impl DynamicInclusion {
|
||||
if elapsed >= valid_after {
|
||||
None
|
||||
} else {
|
||||
let until = Duration::from_millis((valid_after - elapsed) as u64 / 1000);
|
||||
Some(now + until)
|
||||
Some(Duration::from_millis((valid_after - elapsed) as u64 / 1000))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,7 +104,7 @@ mod tests {
|
||||
Duration::from_millis(4000),
|
||||
);
|
||||
|
||||
assert_eq!(dynamic.acceptable_in(now, 5), Some(now + Duration::from_millis(2000)));
|
||||
assert_eq!(dynamic.acceptable_in(now, 5), Some(Duration::from_millis(2000)));
|
||||
assert!(dynamic.acceptable_in(now + Duration::from_millis(2000), 5).is_none());
|
||||
assert!(dynamic.acceptable_in(now + Duration::from_millis(3000), 5).is_none());
|
||||
assert!(dynamic.acceptable_in(now + Duration::from_millis(4000), 5).is_none());
|
||||
|
||||
@@ -44,7 +44,7 @@ pub enum Error {
|
||||
PrematureDestruction,
|
||||
/// Timer failed
|
||||
#[display(fmt = "Timer failed: {}", _0)]
|
||||
Timer(tokio::timer::Error),
|
||||
Timer(std::io::Error),
|
||||
/// Unable to dispatch agreement future
|
||||
#[display(fmt = "Unable to dispatch agreement future: {:?}", _0)]
|
||||
Executor(futures::future::ExecuteErrorKind),
|
||||
|
||||
@@ -29,9 +29,7 @@
|
||||
//!
|
||||
//! Groups themselves may be compromised by malicious authorities.
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::Arc;
|
||||
use std::time::{self, Duration, Instant};
|
||||
use std::{collections::{HashMap, HashSet}, pin::Pin, sync::Arc, time::{self, Duration, Instant}};
|
||||
|
||||
use aura::{SlotDuration, AuraApi};
|
||||
use client::{BlockchainEvents, BlockBody};
|
||||
@@ -44,19 +42,19 @@ use parking_lot::Mutex;
|
||||
use polkadot_primitives::{Hash, Block, BlockId, BlockNumber, Header, SessionKey, AuraId};
|
||||
use polkadot_primitives::parachain::{
|
||||
Id as ParaId, Chain, DutyRoster, Extrinsic as ParachainExtrinsic, CandidateReceipt,
|
||||
ParachainHost, AttestedCandidate, Statement as PrimitiveStatement, Message, OutgoingMessage, CollatorSignature,
|
||||
Collation, PoVBlock,
|
||||
ParachainHost, AttestedCandidate, Statement as PrimitiveStatement, Message, OutgoingMessage,
|
||||
CollatorSignature, Collation, PoVBlock,
|
||||
};
|
||||
use primitives::{Pair, ed25519};
|
||||
use runtime_primitives::{
|
||||
traits::{ProvideRuntimeApi, Header as HeaderT, DigestFor}, ApplyError
|
||||
};
|
||||
use tokio::timer::{Delay, Interval};
|
||||
use futures_timer::{Delay, Interval};
|
||||
use transaction_pool::txpool::{Pool, ChainApi as PoolChainApi};
|
||||
|
||||
use attestation_service::ServiceHandle;
|
||||
use futures::prelude::*;
|
||||
use futures::future::{self, Either};
|
||||
use futures03::{future::{self, Either, FutureExt}, task::Context, stream::StreamExt};
|
||||
use collation::CollationFetch;
|
||||
use dynamic_inclusion::DynamicInclusion;
|
||||
use inherents::InherentData;
|
||||
@@ -575,7 +573,7 @@ impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
|
||||
C::Api: ParachainHost<Block> + BlockBuilderApi<Block>,
|
||||
{
|
||||
type Error = Error;
|
||||
type Create = Either<CreateProposal<C, TxApi>, future::FutureResult<Block, Error>>;
|
||||
type Create = Either<CreateProposal<C, TxApi>, future::Ready<Result<Block, Error>>>;
|
||||
|
||||
fn propose(&self,
|
||||
inherent_data: InherentData,
|
||||
@@ -597,11 +595,11 @@ impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
|
||||
let enough_candidates = dynamic_inclusion.acceptable_in(
|
||||
now,
|
||||
initial_included,
|
||||
).unwrap_or_else(|| now + Duration::from_millis(1));
|
||||
).unwrap_or_else(|| Duration::from_millis(1));
|
||||
|
||||
let believed_timestamp = match inherent_data.timestamp_inherent_data() {
|
||||
Ok(timestamp) => timestamp,
|
||||
Err(e) => return Either::B(future::err(Error::InherentError(e))),
|
||||
Err(e) => return Either::Right(future::err(Error::InherentError(e))),
|
||||
};
|
||||
|
||||
// set up delay until next allowed timestamp.
|
||||
@@ -609,20 +607,18 @@ impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
|
||||
let delay_future = if current_timestamp >= believed_timestamp {
|
||||
None
|
||||
} else {
|
||||
Some(Delay::new(
|
||||
Instant::now() + Duration::from_secs(current_timestamp - believed_timestamp)
|
||||
))
|
||||
Some(Delay::new(Duration::from_secs(current_timestamp - believed_timestamp)))
|
||||
};
|
||||
|
||||
let timing = ProposalTiming {
|
||||
minimum: delay_future,
|
||||
attempt_propose: Interval::new(now + ATTEMPT_PROPOSE_EVERY, ATTEMPT_PROPOSE_EVERY),
|
||||
attempt_propose: Interval::new(ATTEMPT_PROPOSE_EVERY),
|
||||
enough_candidates: Delay::new(enough_candidates),
|
||||
dynamic_inclusion,
|
||||
last_included: initial_included,
|
||||
};
|
||||
|
||||
Either::A(CreateProposal {
|
||||
Either::Left(CreateProposal {
|
||||
parent_hash: self.parent_hash.clone(),
|
||||
parent_number: self.parent_number.clone(),
|
||||
parent_id: self.parent_id.clone(),
|
||||
@@ -632,7 +628,7 @@ impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
|
||||
believed_minimum_timestamp: believed_timestamp,
|
||||
timing,
|
||||
inherent_data: Some(inherent_data),
|
||||
inherent_digests: inherent_digests,
|
||||
inherent_digests,
|
||||
// leave some time for the proposal finalisation
|
||||
deadline: Instant::now() + max_duration - max_duration / 3,
|
||||
})
|
||||
@@ -657,26 +653,26 @@ struct ProposalTiming {
|
||||
impl ProposalTiming {
|
||||
// whether it's time to attempt a proposal.
|
||||
// shouldn't be called outside of the context of a task.
|
||||
fn poll(&mut self, included: usize) -> Poll<(), Error> {
|
||||
fn poll(&mut self, cx: &mut Context, included: usize) -> futures03::Poll<Result<(), Error>> {
|
||||
// first drain from the interval so when the minimum delay is up
|
||||
// we don't have any notifications built up.
|
||||
//
|
||||
// this interval is just meant to produce periodic task wakeups
|
||||
// that lead to the `dynamic_inclusion` getting updated as necessary.
|
||||
while let Async::Ready(x) = self.attempt_propose.poll().map_err(Error::Timer)? {
|
||||
while let futures03::Poll::Ready(x) = self.attempt_propose.poll_next_unpin(cx) {
|
||||
x.expect("timer still alive; intervals never end; qed");
|
||||
}
|
||||
|
||||
// wait until the minimum time has passed.
|
||||
if let Some(mut minimum) = self.minimum.take() {
|
||||
if let Async::NotReady = minimum.poll().map_err(Error::Timer)? {
|
||||
if let futures03::Poll::Pending = minimum.poll_unpin(cx) {
|
||||
self.minimum = Some(minimum);
|
||||
return Ok(Async::NotReady);
|
||||
return futures03::Poll::Pending;
|
||||
}
|
||||
}
|
||||
|
||||
if included == self.last_included {
|
||||
return self.enough_candidates.poll().map_err(Error::Timer);
|
||||
return self.enough_candidates.poll_unpin(cx).map_err(Error::Timer);
|
||||
}
|
||||
|
||||
// the amount of includable candidates has changed. schedule a wakeup
|
||||
@@ -685,9 +681,9 @@ impl ProposalTiming {
|
||||
Some(instant) => {
|
||||
self.last_included = included;
|
||||
self.enough_candidates.reset(instant);
|
||||
self.enough_candidates.poll().map_err(Error::Timer)
|
||||
self.enough_candidates.poll_unpin(cx).map_err(Error::Timer)
|
||||
}
|
||||
None => Ok(Async::Ready(())),
|
||||
None => futures03::Poll::Ready(Ok(())),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -792,41 +788,40 @@ impl<C, TxApi> CreateProposal<C, TxApi> where
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, TxApi> Future for CreateProposal<C, TxApi> where
|
||||
impl<C, TxApi> futures03::Future for CreateProposal<C, TxApi> where
|
||||
TxApi: PoolChainApi<Block=Block>,
|
||||
C: ProvideRuntimeApi + HeaderBackend<Block> + Send + Sync,
|
||||
C::Api: ParachainHost<Block> + BlockBuilderApi<Block>,
|
||||
{
|
||||
type Item = Block;
|
||||
type Error = Error;
|
||||
type Output = Result<Block, Error>;
|
||||
|
||||
fn poll(&mut self) -> Poll<Block, Error> {
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> futures03::Poll<Self::Output> {
|
||||
// 1. try to propose if we have enough includable candidates and other
|
||||
// delays have concluded.
|
||||
let included = self.table.includable_count();
|
||||
futures::try_ready!(self.timing.poll(included));
|
||||
futures03::ready!(self.timing.poll(cx, included))?;
|
||||
|
||||
// 2. propose
|
||||
let proposed_candidates = self.table.proposed_set();
|
||||
|
||||
self.propose_with(proposed_candidates).map(Async::Ready)
|
||||
futures03::Poll::Ready(self.propose_with(proposed_candidates))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use substrate_keyring::AuthorityKeyring;
|
||||
use substrate_keyring::Ed25519Keyring;
|
||||
|
||||
#[test]
|
||||
fn sign_and_check_statement() {
|
||||
let statement: Statement = GenericStatement::Valid([1; 32].into());
|
||||
let parent_hash = [2; 32].into();
|
||||
|
||||
let sig = sign_table_statement(&statement, &AuthorityKeyring::Alice.pair(), &parent_hash);
|
||||
let sig = sign_table_statement(&statement, &Ed25519Keyring::Alice.pair(), &parent_hash);
|
||||
|
||||
assert!(check_statement(&statement, &sig, AuthorityKeyring::Alice.into(), &parent_hash));
|
||||
assert!(!check_statement(&statement, &sig, AuthorityKeyring::Alice.into(), &[0xff; 32].into()));
|
||||
assert!(!check_statement(&statement, &sig, AuthorityKeyring::Bob.into(), &parent_hash));
|
||||
assert!(check_statement(&statement, &sig, Ed25519Keyring::Alice.into(), &parent_hash));
|
||||
assert!(!check_statement(&statement, &sig, Ed25519Keyring::Alice.into(), &[0xff; 32].into()));
|
||||
assert!(!check_statement(&statement, &sig, Ed25519Keyring::Bob.into(), &parent_hash));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -571,7 +571,7 @@ impl SharedTable {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use substrate_keyring::AuthorityKeyring;
|
||||
use substrate_keyring::Ed25519Keyring;
|
||||
use primitives::crypto::UncheckedInto;
|
||||
use polkadot_primitives::parachain::{BlockData, ConsolidatedIngress};
|
||||
use futures::future;
|
||||
@@ -604,10 +604,10 @@ mod tests {
|
||||
let para_id = ParaId::from(1);
|
||||
let parent_hash = Default::default();
|
||||
|
||||
let local_key = Arc::new(AuthorityKeyring::Alice.pair());
|
||||
let local_key = Arc::new(Ed25519Keyring::Alice.pair());
|
||||
let local_id = local_key.public();
|
||||
|
||||
let validity_other_key = AuthorityKeyring::Bob.pair();
|
||||
let validity_other_key = Ed25519Keyring::Bob.pair();
|
||||
let validity_other = validity_other_key.public();
|
||||
let validity_other_index = 1;
|
||||
|
||||
@@ -658,10 +658,10 @@ mod tests {
|
||||
let para_id = ParaId::from(1);
|
||||
let parent_hash = Default::default();
|
||||
|
||||
let local_key = Arc::new(AuthorityKeyring::Alice.pair());
|
||||
let local_key = Arc::new(Ed25519Keyring::Alice.pair());
|
||||
let local_id = local_key.public();
|
||||
|
||||
let validity_other_key = AuthorityKeyring::Bob.pair();
|
||||
let validity_other_key = Ed25519Keyring::Bob.pair();
|
||||
let validity_other = validity_other_key.public();
|
||||
let validity_other_index = 1;
|
||||
|
||||
@@ -793,10 +793,10 @@ mod tests {
|
||||
let para_id = ParaId::from(1);
|
||||
let parent_hash = Default::default();
|
||||
|
||||
let local_key = Arc::new(AuthorityKeyring::Alice.pair());
|
||||
let local_key = Arc::new(Ed25519Keyring::Alice.pair());
|
||||
let local_id = local_key.public();
|
||||
|
||||
let validity_other_key = AuthorityKeyring::Bob.pair();
|
||||
let validity_other_key = Ed25519Keyring::Bob.pair();
|
||||
let validity_other = validity_other_key.public();
|
||||
let validity_other_index = 1;
|
||||
|
||||
@@ -859,10 +859,10 @@ mod tests {
|
||||
let extrinsic = Extrinsic { outgoing_messages: Vec::new() };
|
||||
let parent_hash = Default::default();
|
||||
|
||||
let local_key = Arc::new(AuthorityKeyring::Alice.pair());
|
||||
let local_key = Arc::new(Ed25519Keyring::Alice.pair());
|
||||
let local_id = local_key.public();
|
||||
|
||||
let validity_other_key = AuthorityKeyring::Bob.pair();
|
||||
let validity_other_key = Ed25519Keyring::Bob.pair();
|
||||
let validity_other = validity_other_key.public();
|
||||
|
||||
groups.insert(para_id, GroupInfo {
|
||||
@@ -911,18 +911,18 @@ mod tests {
|
||||
fn index_mapping_from_authorities() {
|
||||
let authorities_set: &[&[_]] = &[
|
||||
&[],
|
||||
&[AuthorityKeyring::Alice.pair().public()],
|
||||
&[AuthorityKeyring::Alice.pair().public(), AuthorityKeyring::Bob.pair().public()],
|
||||
&[AuthorityKeyring::Bob.pair().public(), AuthorityKeyring::Alice.pair().public()],
|
||||
&[AuthorityKeyring::Alice.pair().public(), AuthorityKeyring::Bob.pair().public(), AuthorityKeyring::Charlie.pair().public()],
|
||||
&[AuthorityKeyring::Charlie.pair().public(), AuthorityKeyring::Bob.pair().public(), AuthorityKeyring::Alice.pair().public()],
|
||||
&[Ed25519Keyring::Alice.pair().public()],
|
||||
&[Ed25519Keyring::Alice.pair().public(), Ed25519Keyring::Bob.pair().public()],
|
||||
&[Ed25519Keyring::Bob.pair().public(), Ed25519Keyring::Alice.pair().public()],
|
||||
&[Ed25519Keyring::Alice.pair().public(), Ed25519Keyring::Bob.pair().public(), Ed25519Keyring::Charlie.pair().public()],
|
||||
&[Ed25519Keyring::Charlie.pair().public(), Ed25519Keyring::Bob.pair().public(), Ed25519Keyring::Alice.pair().public()],
|
||||
];
|
||||
|
||||
for authorities in authorities_set {
|
||||
let shared_table = SharedTable::new(
|
||||
authorities,
|
||||
HashMap::new(),
|
||||
Arc::new(AuthorityKeyring::Alice.pair()),
|
||||
Arc::new(Ed25519Keyring::Alice.pair()),
|
||||
Default::default(),
|
||||
ExtrinsicStore::new_in_memory(),
|
||||
None,
|
||||
|
||||
Reference in New Issue
Block a user