From 6bdf5e8d8b5606f483bba61d61cadea150cd3985 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 30 Apr 2020 18:15:28 -0400 Subject: [PATCH 01/80] Initial Staking API --- src/frame/mod.rs | 1 + src/frame/staking.rs | 202 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+) create mode 100644 src/frame/staking.rs diff --git a/src/frame/mod.rs b/src/frame/mod.rs index 898031f753a..949f0b3183f 100644 --- a/src/frame/mod.rs +++ b/src/frame/mod.rs @@ -35,6 +35,7 @@ use sp_core::storage::StorageKey; pub mod balances; pub mod contracts; pub mod system; +pub mod staking; /// Store trait. pub trait Store: Encode { diff --git a/src/frame/staking.rs b/src/frame/staking.rs new file mode 100644 index 00000000000..2527586f25d --- /dev/null +++ b/src/frame/staking.rs @@ -0,0 +1,202 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of substrate-subxt. +// +// subxt 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. +// +// subxt 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-subxt. If not, see . + +//! Implements support for the frame_staking module. + +use codec::{Codec, Decode, Encode, HasCompact}; +use frame_support::Parameter; +use serde::de::DeserializeOwned; +use sp_core::storage::StorageKey; +use sp_runtime::{ + traits::{ + AtLeast32Bit, Bounded, CheckEqual, Extrinsic, Hash, Header, MaybeDisplay, + MaybeMallocSizeOf, MaybeSerialize, MaybeSerializeDeserialize, Member, + SimpleBitOps, + }, + RuntimeDebug, +}; +use std::fmt::Debug; +use std::marker::PhantomData; +use crate::{ + frame::{Call, Store}, + metadata::{Metadata, MetadataError}, +}; + +/// Data type used to index nominators in the compact type +pub type NominatorIndex = u32; + +/// Data type used to index validators in the compact type. +pub type ValidatorIndex = u16; + +/// Maximum number of stakers that can be stored in a snapshot. +pub(crate) const MAX_VALIDATORS: usize = ValidatorIndex::max_value() as usize; +pub(crate) const MAX_NOMINATORS: usize = NominatorIndex::max_value() as usize; + +/// Counter for the number of eras that have passed. +pub type EraIndex = u32; + +/// Counter for the number of "reward" points earned by a given validator. +pub type RewardPoint = u32; + + +/// The subset of the `frame::Trait` that a client must implement. +pub trait Staking: super::system::System { + /* + type UnixTime; + type CurrencyToVote; + type RewardRemainder; + type Event; + type Slash; + type Reward; + type SessionsPerEra; + type BondingDuration; + type SlashDeferDuration; + type SlashCancelOrigin; + type SessionInterface; + type RewardCurve; + type NextNewSession; + type ElectionLookahead; + type Call; + type MaxIterations; + type MaxNominatorRewardPerValidator; + type UnsignedPriority; */ +} + +/// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. +#[derive(PartialEq, Eq, Clone, Encode, Decode)] +pub struct UnlockChunk { + /// Amount of funds to be unlocked. + #[codec(compact)] + value: Balance, + /// Era number at which point it'll be unlocked. + #[codec(compact)] + era: EraIndex, +} + +/// The ledger of a (bonded) stash. +#[derive(PartialEq, Eq, Clone, Encode, Decode)] +pub struct StakingLedger { + /// The stash account whose balance is actually locked and at stake. + pub stash: AccountId, + /// The total amount of the stash's balance that we are currently accounting for. + /// It's just `active` plus all the `unlocking` balances. + #[codec(compact)] + pub total: Balance, + /// The total amount of the stash's balance that will be at stake in any forthcoming + /// rounds. + #[codec(compact)] + pub active: Balance, + /// Any balance that is becoming free, which may eventually be transferred out + /// of the stash (assuming it doesn't get slashed first). + pub unlocking: Vec>, + /// List of eras for which the stakers behind a validator have claimed rewards. Only updated + /// for validators. + pub claimed_rewards: Vec, +} + +const MODULE: &str = "Staking"; + +/// Number of eras to keep in history. +/// +/// Information is kept for eras in `[current_era - history_depth; current_era]`. +/// +/// Must be more than the number of eras delayed by session otherwise. +/// I.e. active era must always be in history. +/// I.e. `active_era > current_era - history_depth` must be guaranteed. +#[derive(Encode, Decode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] +pub struct HistoryDepth(PhantomData); + +impl Store for HistoryDepth { + const MODULE: &'static str = MODULE; + const FIELD: &'static str = "HistoryDepth"; + type Returns = u32; + + fn key(&self, metadata: &Metadata) -> Result { + Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.plain()?.key()) + } +} + +/// The ideal number of staking participants. +#[derive(Encode, Decode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] +pub struct ValidatorCount(PhantomData); + +impl Store for ValidatorCount { + const MODULE: &'static str = MODULE; + const FIELD: &'static str = "ValidatorCount"; + type Returns = u32; + + fn key(&self, metadata: &Metadata) -> Result { + Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.plain()?.key()) + } +} + +/// Minimum number of staking participants before emergency conditions are imposed. +#[derive(Encode, Decode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] +pub struct MinimumValidatorCount(PhantomData); + +impl Store for MinimumValidatorCount { + const MODULE: &'static str = MODULE; + const FIELD: &'static str = "MinimumValidatorCount"; + type Returns = u32; + + fn key(&self, metadata: &Metadata) -> Result { + Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.plain()?.key()) + } +} + +/// Any validators that may never be slashed or forcibly kicked. It's a Vec since they're +/// easy to initialize and the performance hit is minimal (we expect no more than four +/// invulnerables) and restricted to testnets. +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] +pub struct Invulnerables(pub core::marker::PhantomData); + +impl Store for Invulnerables { + const MODULE: &'static str = MODULE; + const FIELD: &'static str = "Invulnerables"; + type Returns = Vec; + + fn key(&self, metadata: &Metadata) -> Result { + Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.plain()?.key()) + } +} + +/// Map from all locked "stash" accounts to the controller account. +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] +pub struct Bonded(pub PhantomData); + +impl Store for Bonded { + const MODULE: &'static str = MODULE; + const FIELD: &'static str = "Bonded"; + type Returns = Vec; + + fn key(&self, metadata: &Metadata) -> Result { + Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) + } +} + +/// Map from all (unlocked) "controller" accounts to the info regarding the staking. +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] +pub struct Ledger(pub T::AccountId); + +impl Store for Ledger { + const MODULE: &'static str = MODULE; + const FIELD: &'static str = "Ledger"; + type Returns = Option>; + + fn key(&self, metadata: &Metadata) -> Result { + Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) + } +} From d4a085af7f5c5e9d1fb4d797fd9a1e8de76f3e1b Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 30 Apr 2020 20:36:36 -0400 Subject: [PATCH 02/80] Add more staking types --- src/frame/staking.rs | 137 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 1 deletion(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 2527586f25d..9eadb75388c 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -25,7 +25,7 @@ use sp_runtime::{ AtLeast32Bit, Bounded, CheckEqual, Extrinsic, Hash, Header, MaybeDisplay, MaybeMallocSizeOf, MaybeSerialize, MaybeSerializeDeserialize, Member, SimpleBitOps, - }, + }, Perbill, RuntimeDebug, }; use std::fmt::Debug; @@ -35,6 +35,31 @@ use crate::{ metadata::{Metadata, MetadataError}, }; +/// A record of the nominations made by a specific account. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +pub struct Nominations { + /// The targets of nomination. + pub targets: Vec, + /// The era the nominations were submitted. + /// + /// Except for initial nominations which are considered submitted at era 0. + pub submitted_in: EraIndex, + /// Whether the nominations have been suppressed. + pub suppressed: bool, +} + +/// Information regarding the active era (era in used in session). +#[derive(Encode, Decode, RuntimeDebug)] +pub struct ActiveEraInfo { + /// Index of era. + pub index: EraIndex, + /// Moment of start expresed as millisecond from `$UNIX_EPOCH`. + /// + /// Start can be none if start hasn't been set for the era yet, + /// Start is set on the first on_finalize of the era to guarantee usage of `Time`. + start: Option, +} + /// Data type used to index nominators in the compact type pub type NominatorIndex = u32; @@ -51,6 +76,40 @@ pub type EraIndex = u32; /// Counter for the number of "reward" points earned by a given validator. pub type RewardPoint = u32; +/// A destination account for payment. +#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug)] +pub enum RewardDestination { + /// Pay into the stash account, increasing the amount at stake accordingly. + Staked, + /// Pay into the stash account, not increasing the amount at stake. + Stash, + /// Pay into the controller account. + Controller, +} + +impl Default for RewardDestination { + fn default() -> Self { + RewardDestination::Staked + } +} + +/// Preference of what happens regarding validation. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +pub struct ValidatorPrefs { + /// Reward that validator takes up-front; only the rest is split between themselves and + /// nominators. + #[codec(compact)] + pub commission: Perbill, +} + +impl Default for ValidatorPrefs { + fn default() -> Self { + ValidatorPrefs { + commission: Default::default(), + } + } +} + /// The subset of the `frame::Trait` that a client must implement. pub trait Staking: super::system::System { @@ -200,3 +259,79 @@ impl Store for Ledger { Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) } } + +/// Where the reward payment should be made. Keyed by stash. +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] +pub struct Payee(pub T::AccountId); + +impl Store for Payee { + const MODULE: &'static str = MODULE; + const FIELD: &'static str = "Payee"; + type Returns = RewardDestination; + + fn key(&self, metadata: &Metadata) -> Result { + Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) + } +} + +/// The map from (wannabe) validator stash key to the preferences of that validator. +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] +pub struct Validators(pub T::AccountId); + +impl Store for Validators { + const MODULE: &'static str = MODULE; + const FIELD: &'static str = "Validators"; + type Returns = ValidatorPrefs; + + fn key(&self, metadata: &Metadata) -> Result { + Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) + } +} + +/// The map from nominator stash key to the set of stash keys of all validators to nominate. +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] +pub struct Nominators(pub T::AccountId); + +impl Store for Nominators { + const MODULE: &'static str = MODULE; + const FIELD: &'static str = "Nominators"; + type Returns = Option>; + + fn key(&self, metadata: &Metadata) -> Result { + Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) + } +} + +/// The current era index. +/// +/// This is the latest planned era, depending on how the Session pallet queues the validator +/// set, it might be active or not. +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] +pub struct CurrentEra(pub PhantomData); + +impl Store for CurrentEra { + const MODULE: &'static str = MODULE; + const FIELD: &'static str = "CurrentEra"; + type Returns = Option; + + fn key(&self, metadata: &Metadata) -> Result { + Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) + } +} + +/// The active era information, it holds index and start. +/// +/// The active era is the era currently rewarded. +/// Validator set of this era must be equal to `SessionInterface::validators`. +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] +pub struct ActiveEra(pub PhantomData); + +impl Store for ActiveEra { + const MODULE: &'static str = MODULE; + const FIELD: &'static str = "ActiveEra"; + type Returns = Option; + + fn key(&self, metadata: &Metadata) -> Result { + Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) + } +} From c08e22a873954ec9fae858a28bc3f965d32e96fc Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 30 Apr 2020 20:46:18 -0400 Subject: [PATCH 03/80] Reformat --- src/frame/mod.rs | 2 +- src/frame/staking.rs | 259 +++++++++++++++++++++++++++---------------- 2 files changed, 163 insertions(+), 98 deletions(-) diff --git a/src/frame/mod.rs b/src/frame/mod.rs index 9d142eac98a..317660a3951 100644 --- a/src/frame/mod.rs +++ b/src/frame/mod.rs @@ -34,8 +34,8 @@ use sp_core::storage::StorageKey; pub mod balances; pub mod contracts; -pub mod system; pub mod staking; +pub mod system; /// Store trait. pub trait Store: Encode { diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 9eadb75388c..cde83b9737b 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -1,4 +1,4 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. +// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of substrate-subxt. // // subxt is free software: you can redistribute it and/or modify @@ -16,48 +16,71 @@ //! Implements support for the frame_staking module. -use codec::{Codec, Decode, Encode, HasCompact}; +use crate::{ + frame::{ + Call, + Store, + }, + metadata::{ + Metadata, + MetadataError, + }, +}; +use codec::{ + Codec, + Decode, + Encode, + HasCompact, +}; use frame_support::Parameter; use serde::de::DeserializeOwned; use sp_core::storage::StorageKey; use sp_runtime::{ traits::{ - AtLeast32Bit, Bounded, CheckEqual, Extrinsic, Hash, Header, MaybeDisplay, - MaybeMallocSizeOf, MaybeSerialize, MaybeSerializeDeserialize, Member, + AtLeast32Bit, + Bounded, + CheckEqual, + Extrinsic, + Hash, + Header, + MaybeDisplay, + MaybeMallocSizeOf, + MaybeSerialize, + MaybeSerializeDeserialize, + Member, SimpleBitOps, - }, Perbill, + }, + Perbill, RuntimeDebug, }; -use std::fmt::Debug; -use std::marker::PhantomData; -use crate::{ - frame::{Call, Store}, - metadata::{Metadata, MetadataError}, +use std::{ + fmt::Debug, + marker::PhantomData, }; /// A record of the nominations made by a specific account. #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] pub struct Nominations { - /// The targets of nomination. - pub targets: Vec, - /// The era the nominations were submitted. - /// - /// Except for initial nominations which are considered submitted at era 0. - pub submitted_in: EraIndex, - /// Whether the nominations have been suppressed. - pub suppressed: bool, + /// The targets of nomination. + pub targets: Vec, + /// The era the nominations were submitted. + /// + /// Except for initial nominations which are considered submitted at era 0. + pub submitted_in: EraIndex, + /// Whether the nominations have been suppressed. + pub suppressed: bool, } /// Information regarding the active era (era in used in session). #[derive(Encode, Decode, RuntimeDebug)] pub struct ActiveEraInfo { - /// Index of era. - pub index: EraIndex, - /// Moment of start expresed as millisecond from `$UNIX_EPOCH`. - /// - /// Start can be none if start hasn't been set for the era yet, - /// Start is set on the first on_finalize of the era to guarantee usage of `Time`. - start: Option, + /// Index of era. + pub index: EraIndex, + /// Moment of start expresed as millisecond from `$UNIX_EPOCH`. + /// + /// Start can be none if start hasn't been set for the era yet, + /// Start is set on the first on_finalize of the era to guarantee usage of `Time`. + start: Option, } /// Data type used to index nominators in the compact type @@ -79,91 +102,89 @@ pub type RewardPoint = u32; /// A destination account for payment. #[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug)] pub enum RewardDestination { - /// Pay into the stash account, increasing the amount at stake accordingly. - Staked, - /// Pay into the stash account, not increasing the amount at stake. - Stash, - /// Pay into the controller account. - Controller, + /// Pay into the stash account, increasing the amount at stake accordingly. + Staked, + /// Pay into the stash account, not increasing the amount at stake. + Stash, + /// Pay into the controller account. + Controller, } impl Default for RewardDestination { - fn default() -> Self { - RewardDestination::Staked - } + fn default() -> Self { + RewardDestination::Staked + } } /// Preference of what happens regarding validation. #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] pub struct ValidatorPrefs { - /// Reward that validator takes up-front; only the rest is split between themselves and - /// nominators. - #[codec(compact)] - pub commission: Perbill, + /// Reward that validator takes up-front; only the rest is split between themselves and + /// nominators. + #[codec(compact)] + pub commission: Perbill, } impl Default for ValidatorPrefs { - fn default() -> Self { - ValidatorPrefs { - commission: Default::default(), - } - } + fn default() -> Self { + ValidatorPrefs { + commission: Default::default(), + } + } } - /// The subset of the `frame::Trait` that a client must implement. pub trait Staking: super::system::System { - /* - type UnixTime; - type CurrencyToVote; - type RewardRemainder; - type Event; - type Slash; - type Reward; - type SessionsPerEra; - type BondingDuration; - type SlashDeferDuration; - type SlashCancelOrigin; - type SessionInterface; - type RewardCurve; - type NextNewSession; - type ElectionLookahead; - type Call; - type MaxIterations; - type MaxNominatorRewardPerValidator; - type UnsignedPriority; */ + // type UnixTime; + // type CurrencyToVote; + // type RewardRemainder; + // type Event; + // type Slash; + // type Reward; + // type SessionsPerEra; + // type BondingDuration; + // type SlashDeferDuration; + // type SlashCancelOrigin; + // type SessionInterface; + // type RewardCurve; + // type NextNewSession; + // type ElectionLookahead; + // type Call; + // type MaxIterations; + // type MaxNominatorRewardPerValidator; + // type UnsignedPriority; } /// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. #[derive(PartialEq, Eq, Clone, Encode, Decode)] pub struct UnlockChunk { - /// Amount of funds to be unlocked. - #[codec(compact)] - value: Balance, - /// Era number at which point it'll be unlocked. - #[codec(compact)] - era: EraIndex, + /// Amount of funds to be unlocked. + #[codec(compact)] + value: Balance, + /// Era number at which point it'll be unlocked. + #[codec(compact)] + era: EraIndex, } /// The ledger of a (bonded) stash. #[derive(PartialEq, Eq, Clone, Encode, Decode)] pub struct StakingLedger { - /// The stash account whose balance is actually locked and at stake. - pub stash: AccountId, - /// The total amount of the stash's balance that we are currently accounting for. - /// It's just `active` plus all the `unlocking` balances. - #[codec(compact)] - pub total: Balance, - /// The total amount of the stash's balance that will be at stake in any forthcoming - /// rounds. - #[codec(compact)] - pub active: Balance, - /// Any balance that is becoming free, which may eventually be transferred out - /// of the stash (assuming it doesn't get slashed first). - pub unlocking: Vec>, - /// List of eras for which the stakers behind a validator have claimed rewards. Only updated - /// for validators. - pub claimed_rewards: Vec, + /// The stash account whose balance is actually locked and at stake. + pub stash: AccountId, + /// The total amount of the stash's balance that we are currently accounting for. + /// It's just `active` plus all the `unlocking` balances. + #[codec(compact)] + pub total: Balance, + /// The total amount of the stash's balance that will be at stake in any forthcoming + /// rounds. + #[codec(compact)] + pub active: Balance, + /// Any balance that is becoming free, which may eventually be transferred out + /// of the stash (assuming it doesn't get slashed first). + pub unlocking: Vec>, + /// List of eras for which the stakers behind a validator have claimed rewards. Only updated + /// for validators. + pub claimed_rewards: Vec, } const MODULE: &str = "Staking"; @@ -184,7 +205,11 @@ impl Store for HistoryDepth { type Returns = u32; fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.plain()?.key()) + Ok(metadata + .module(Self::MODULE)? + .storage(Self::FIELD)? + .plain()? + .key()) } } @@ -198,7 +223,11 @@ impl Store for ValidatorCount { type Returns = u32; fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.plain()?.key()) + Ok(metadata + .module(Self::MODULE)? + .storage(Self::FIELD)? + .plain()? + .key()) } } @@ -212,7 +241,11 @@ impl Store for MinimumValidatorCount { type Returns = u32; fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.plain()?.key()) + Ok(metadata + .module(Self::MODULE)? + .storage(Self::FIELD)? + .plain()? + .key()) } } @@ -228,7 +261,11 @@ impl Store for Invulnerables { type Returns = Vec; fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.plain()?.key()) + Ok(metadata + .module(Self::MODULE)? + .storage(Self::FIELD)? + .plain()? + .key()) } } @@ -242,7 +279,11 @@ impl Store for Bonded { type Returns = Vec; fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) + Ok(metadata + .module(Self::MODULE)? + .storage(Self::FIELD)? + .map()? + .key(&self.0)) } } @@ -256,7 +297,11 @@ impl Store for Ledger { type Returns = Option>; fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) + Ok(metadata + .module(Self::MODULE)? + .storage(Self::FIELD)? + .map()? + .key(&self.0)) } } @@ -270,7 +315,11 @@ impl Store for Payee { type Returns = RewardDestination; fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) + Ok(metadata + .module(Self::MODULE)? + .storage(Self::FIELD)? + .map()? + .key(&self.0)) } } @@ -284,7 +333,11 @@ impl Store for Validators { type Returns = ValidatorPrefs; fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) + Ok(metadata + .module(Self::MODULE)? + .storage(Self::FIELD)? + .map()? + .key(&self.0)) } } @@ -298,7 +351,11 @@ impl Store for Nominators { type Returns = Option>; fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) + Ok(metadata + .module(Self::MODULE)? + .storage(Self::FIELD)? + .map()? + .key(&self.0)) } } @@ -315,7 +372,11 @@ impl Store for CurrentEra { type Returns = Option; fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) + Ok(metadata + .module(Self::MODULE)? + .storage(Self::FIELD)? + .map()? + .key(&self.0)) } } @@ -329,9 +390,13 @@ pub struct ActiveEra(pub PhantomData); impl Store for ActiveEra { const MODULE: &'static str = MODULE; const FIELD: &'static str = "ActiveEra"; - type Returns = Option; + type Returns = Option; fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata.module(Self::MODULE)?.storage(Self::FIELD)?.map()?.key(&self.0)) + Ok(metadata + .module(Self::MODULE)? + .storage(Self::FIELD)? + .map()? + .key(&self.0)) } } From 93c347cb18ccbaf6d0d4cec3d73019b40ddf0427 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 1 May 2020 15:31:19 -0400 Subject: [PATCH 04/80] Remove dead code --- src/frame/staking.rs | 43 +++---------------------------------------- 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index cde83b9737b..89088ddf29a 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -18,7 +18,6 @@ use crate::{ frame::{ - Call, Store, }, metadata::{ @@ -27,29 +26,12 @@ use crate::{ }, }; use codec::{ - Codec, Decode, Encode, HasCompact, }; -use frame_support::Parameter; -use serde::de::DeserializeOwned; use sp_core::storage::StorageKey; use sp_runtime::{ - traits::{ - AtLeast32Bit, - Bounded, - CheckEqual, - Extrinsic, - Hash, - Header, - MaybeDisplay, - MaybeMallocSizeOf, - MaybeSerialize, - MaybeSerializeDeserialize, - Member, - SimpleBitOps, - }, Perbill, RuntimeDebug, }; @@ -90,8 +72,8 @@ pub type NominatorIndex = u32; pub type ValidatorIndex = u16; /// Maximum number of stakers that can be stored in a snapshot. -pub(crate) const MAX_VALIDATORS: usize = ValidatorIndex::max_value() as usize; -pub(crate) const MAX_NOMINATORS: usize = NominatorIndex::max_value() as usize; +pub const MAX_VALIDATORS: usize = ValidatorIndex::max_value() as usize; +pub const MAX_NOMINATORS: usize = NominatorIndex::max_value() as usize; /// Counter for the number of eras that have passed. pub type EraIndex = u32; @@ -134,26 +116,7 @@ impl Default for ValidatorPrefs { } /// The subset of the `frame::Trait` that a client must implement. -pub trait Staking: super::system::System { - // type UnixTime; - // type CurrencyToVote; - // type RewardRemainder; - // type Event; - // type Slash; - // type Reward; - // type SessionsPerEra; - // type BondingDuration; - // type SlashDeferDuration; - // type SlashCancelOrigin; - // type SessionInterface; - // type RewardCurve; - // type NextNewSession; - // type ElectionLookahead; - // type Call; - // type MaxIterations; - // type MaxNominatorRewardPerValidator; - // type UnsignedPriority; -} +pub trait Staking: super::system::System {} /// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. #[derive(PartialEq, Eq, Clone, Encode, Decode)] From fef1260a00fa6a994b7794c5cc9354e965dcc439 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 1 May 2020 17:57:36 -0400 Subject: [PATCH 05/80] Fix missing documentation --- src/frame/staking.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 89088ddf29a..7211a570dfe 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -71,8 +71,9 @@ pub type NominatorIndex = u32; /// Data type used to index validators in the compact type. pub type ValidatorIndex = u16; -/// Maximum number of stakers that can be stored in a snapshot. +/// Maximum number of validators that can be stored in a snapshot. pub const MAX_VALIDATORS: usize = ValidatorIndex::max_value() as usize; +/// Maximum number of nominators that can be stored in a snapshot. pub const MAX_NOMINATORS: usize = NominatorIndex::max_value() as usize; /// Counter for the number of eras that have passed. From 3d6e2eebbc49d95ca327f72935a7f4a0c8b50a52 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Tue, 5 May 2020 10:30:59 -0400 Subject: [PATCH 06/80] Reformat --- src/frame/staking.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 7211a570dfe..8d171ee1151 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -17,9 +17,7 @@ //! Implements support for the frame_staking module. use crate::{ - frame::{ - Store, - }, + frame::Store, metadata::{ Metadata, MetadataError, @@ -73,6 +71,7 @@ pub type ValidatorIndex = u16; /// Maximum number of validators that can be stored in a snapshot. pub const MAX_VALIDATORS: usize = ValidatorIndex::max_value() as usize; + /// Maximum number of nominators that can be stored in a snapshot. pub const MAX_NOMINATORS: usize = NominatorIndex::max_value() as usize; From a28fb20264cff2be8744b66979bb023f83a1aeff Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 15 May 2020 16:25:28 -0400 Subject: [PATCH 07/80] Staking: use proc macros --- src/frame/staking.rs | 248 +++++++++++++------------------------------ 1 file changed, 75 insertions(+), 173 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 8d171ee1151..44277c6b293 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -16,19 +16,11 @@ //! Implements support for the frame_staking module. -use crate::{ - frame::Store, - metadata::{ - Metadata, - MetadataError, - }, -}; use codec::{ Decode, Encode, HasCompact, }; -use sp_core::storage::StorageKey; use sp_runtime::{ Perbill, RuntimeDebug, @@ -159,207 +151,117 @@ const MODULE: &str = "Staking"; /// Must be more than the number of eras delayed by session otherwise. /// I.e. active era must always be in history. /// I.e. `active_era > current_era - history_depth` must be guaranteed. -#[derive(Encode, Decode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] -pub struct HistoryDepth(PhantomData); - -impl Store for HistoryDepth { - const MODULE: &'static str = MODULE; - const FIELD: &'static str = "HistoryDepth"; - type Returns = u32; - - fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata - .module(Self::MODULE)? - .storage(Self::FIELD)? - .plain()? - .key()) - } +#[derive( + Encode, Decode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store, +)] +pub struct HistoryDepthStore { + #[store(returns = u32)] + /// Number of eras to keep in history. + /// + /// Information is kept for eras in `[current_era - history_depth; current_era]`. + /// + /// Must be more than the number of eras delayed by session otherwise. + /// I.e. active era must always be in history. + /// I.e. `active_era > current_era - history_depth` must be guaranteed. + pub _runtime: PhantomData, } /// The ideal number of staking participants. -#[derive(Encode, Decode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] -pub struct ValidatorCount(PhantomData); - -impl Store for ValidatorCount { - const MODULE: &'static str = MODULE; - const FIELD: &'static str = "ValidatorCount"; - type Returns = u32; - - fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata - .module(Self::MODULE)? - .storage(Self::FIELD)? - .plain()? - .key()) - } +#[derive( + Encode, Decode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store, +)] +pub struct ValidatorCountStore { + #[store(returns = u32)] + /// The ideal number of staking participants. + pub _runtime: PhantomData, } /// Minimum number of staking participants before emergency conditions are imposed. -#[derive(Encode, Decode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] -pub struct MinimumValidatorCount(PhantomData); - -impl Store for MinimumValidatorCount { - const MODULE: &'static str = MODULE; - const FIELD: &'static str = "MinimumValidatorCount"; - type Returns = u32; - - fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata - .module(Self::MODULE)? - .storage(Self::FIELD)? - .plain()? - .key()) - } +#[derive( + Encode, Decode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store, +)] +pub struct MinimumValidatorCountStore { + #[store(returns = u32)] + /// Minimum number of staking participants before emergency conditions are imposed. + pub _runtime: PhantomData, } /// Any validators that may never be slashed or forcibly kicked. It's a Vec since they're /// easy to initialize and the performance hit is minimal (we expect no more than four /// invulnerables) and restricted to testnets. -#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] -pub struct Invulnerables(pub core::marker::PhantomData); - -impl Store for Invulnerables { - const MODULE: &'static str = MODULE; - const FIELD: &'static str = "Invulnerables"; - type Returns = Vec; - - fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata - .module(Self::MODULE)? - .storage(Self::FIELD)? - .plain()? - .key()) - } +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] +pub struct InvulnerablesStore { + #[store(returns = Vec)] + /// Any validators that may never be slashed or forcibly kicked. It's a Vec since they're + /// easy to initialize and the performance hit is minimal (we expect no more than four + /// invulnerables) and restricted to testnets. + pub _runtime: core::marker::PhantomData, } /// Map from all locked "stash" accounts to the controller account. -#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] -pub struct Bonded(pub PhantomData); - -impl Store for Bonded { - const MODULE: &'static str = MODULE; - const FIELD: &'static str = "Bonded"; - type Returns = Vec; - - fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata - .module(Self::MODULE)? - .storage(Self::FIELD)? - .map()? - .key(&self.0)) - } +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] +pub struct BondedStore { + #[store(returns = Vec)] + /// Map from all locked "stash" accounts to the controller account. + pub _runtime: PhantomData, } /// Map from all (unlocked) "controller" accounts to the info regarding the staking. -#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] -pub struct Ledger(pub T::AccountId); - -impl Store for Ledger { - const MODULE: &'static str = MODULE; - const FIELD: &'static str = "Ledger"; - type Returns = Option>; - - fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata - .module(Self::MODULE)? - .storage(Self::FIELD)? - .map()? - .key(&self.0)) - } +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] +pub struct LedgerStore { + #[store(returns = Option>)] + /// Map from all (unlocked) "controller" accounts to the info regarding the staking. + pub _runtime: PhantomData, } /// Where the reward payment should be made. Keyed by stash. -#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] -pub struct Payee(pub T::AccountId); - -impl Store for Payee { - const MODULE: &'static str = MODULE; - const FIELD: &'static str = "Payee"; - type Returns = RewardDestination; - - fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata - .module(Self::MODULE)? - .storage(Self::FIELD)? - .map()? - .key(&self.0)) - } +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] +pub struct PayeeStore { + #[store(returns = RewardDestination)] + /// Where the reward payment should be made. Keyed by stash. + pub _runtime: PhantomData, } /// The map from (wannabe) validator stash key to the preferences of that validator. -#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] -pub struct Validators(pub T::AccountId); - -impl Store for Validators { - const MODULE: &'static str = MODULE; - const FIELD: &'static str = "Validators"; - type Returns = ValidatorPrefs; - - fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata - .module(Self::MODULE)? - .storage(Self::FIELD)? - .map()? - .key(&self.0)) - } +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] +pub struct ValidatorsStore { + #[store(returns = ValidatorPrefs)] + /// The map from (wannabe) validator stash key to the preferences of that validator. + pub _runtime: PhantomData, } /// The map from nominator stash key to the set of stash keys of all validators to nominate. -#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] -pub struct Nominators(pub T::AccountId); - -impl Store for Nominators { - const MODULE: &'static str = MODULE; - const FIELD: &'static str = "Nominators"; - type Returns = Option>; - - fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata - .module(Self::MODULE)? - .storage(Self::FIELD)? - .map()? - .key(&self.0)) - } +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] +pub struct NominatorsStore { + #[store(returns = Option>)] + /// The map from nominator stash key to the set of stash keys of all validators to nominate. + pub _runtime: PhantomData, } /// The current era index. /// /// This is the latest planned era, depending on how the Session pallet queues the validator /// set, it might be active or not. -#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] -pub struct CurrentEra(pub PhantomData); - -impl Store for CurrentEra { - const MODULE: &'static str = MODULE; - const FIELD: &'static str = "CurrentEra"; - type Returns = Option; - - fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata - .module(Self::MODULE)? - .storage(Self::FIELD)? - .map()? - .key(&self.0)) - } +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] +pub struct CurrentEraStore { + #[store(returns = Option)] + /// The current era index. + /// + /// This is the latest planned era, depending on how the Session pallet queues the validator + /// set, it might be active or not. + pub _runtime: PhantomData, } /// The active era information, it holds index and start. /// /// The active era is the era currently rewarded. /// Validator set of this era must be equal to `SessionInterface::validators`. -#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)] -pub struct ActiveEra(pub PhantomData); - -impl Store for ActiveEra { - const MODULE: &'static str = MODULE; - const FIELD: &'static str = "ActiveEra"; - type Returns = Option; - - fn key(&self, metadata: &Metadata) -> Result { - Ok(metadata - .module(Self::MODULE)? - .storage(Self::FIELD)? - .map()? - .key(&self.0)) - } +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] +pub struct ActiveEraStore { + #[store(returns = Option)] + /// The active era information, it holds index and start. + /// + /// The active era is the era currently rewarded. + /// Validator set of this era must be equal to `SessionInterface::validators`. + pub _runtime: PhantomData, } From cfabfe8ca20937ecfbd5bf28adb83dc6e38aa757 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 15 May 2020 18:17:55 -0400 Subject: [PATCH 08/80] Add partial session support --- src/frame/mod.rs | 1 + src/frame/session.rs | 60 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/frame/session.rs diff --git a/src/frame/mod.rs b/src/frame/mod.rs index 7f55b338aaa..061b593cba1 100644 --- a/src/frame/mod.rs +++ b/src/frame/mod.rs @@ -34,6 +34,7 @@ use sp_core::storage::StorageKey; pub mod balances; pub mod contracts; +pub mod session; pub mod staking; pub mod system; diff --git a/src/frame/session.rs b/src/frame/session.rs new file mode 100644 index 00000000000..1b96b898fee --- /dev/null +++ b/src/frame/session.rs @@ -0,0 +1,60 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of substrate-subxt. +// +// subxt 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. +// +// subxt 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-subxt. If not, see . +// Copyright 2019-2020 Parity Technologies (UK) Ltd. + +//! Session support +#![warn(missing_docs)] // yuck ☹ +use crate::frame::system::System; +use codec::Encode; +use frame_support::Parameter; +use std::{fmt::Debug, marker::PhantomData}; +use substrate_subxt_proc_macro::Store; + +/// The trait needed for this module. +pub trait Session: System { + /// The validator account identifier type for the runtime. + type ValidatorId: Parameter + Debug + Ord + Default; + /// The validator account identifier type for the runtime. + type SessionIndex: Parameter + Debug + Ord + Default; +} + +const MODULE: &str = "Session"; + +/// The current set of validators. +#[derive(Encode, Store)] +pub struct ValidatorsStore { + #[store(returns = Vec<::ValidatorId>)] + /// The current set of validators. + pub _runtime: PhantomData, +} + +/// Current index of the session. +#[derive(Encode, Store)] +pub struct CurrentIndexStore { + #[store(returns = ::SessionIndex)] + /// Current index of the session. + pub _r: PhantomData, +} + +/// True if the underlying economic identities or weighting behind the validators +/// has changed in the queued validator set. +#[derive(Encode, Store)] +pub struct QueuedChangedStore { + #[store(returns = bool)] + /// True if the underlying economic identities or weighting behind the validators + /// has changed in the queued validator set. + pub _r: PhantomData, +} From ff967e9ff65a5dc72900a1c6704cce711222cd23 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 15 May 2020 18:22:09 -0400 Subject: [PATCH 09/80] Reformat --- src/frame/session.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/frame/session.rs b/src/frame/session.rs index 1b96b898fee..7dcbe58da3d 100644 --- a/src/frame/session.rs +++ b/src/frame/session.rs @@ -16,11 +16,13 @@ // Copyright 2019-2020 Parity Technologies (UK) Ltd. //! Session support -#![warn(missing_docs)] // yuck ☹ use crate::frame::system::System; use codec::Encode; use frame_support::Parameter; -use std::{fmt::Debug, marker::PhantomData}; +use std::{ + fmt::Debug, + marker::PhantomData, +}; use substrate_subxt_proc_macro::Store; /// The trait needed for this module. From 716dd13313a6ff46bb7b124d0569a962870f0c44 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sat, 16 May 2020 20:56:14 -0400 Subject: [PATCH 10/80] Try to implement nomination This currently fails with compilation errors I do not understand. --- src/frame/staking.rs | 53 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 44277c6b293..8b046065828 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -16,6 +16,7 @@ //! Implements support for the frame_staking module. +use super::system::System; use codec::{ Decode, Encode, @@ -108,7 +109,7 @@ impl Default for ValidatorPrefs { } /// The subset of the `frame::Trait` that a client must implement. -pub trait Staking: super::system::System {} +pub trait Staking: System {} /// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. #[derive(PartialEq, Eq, Clone, Encode, Decode)] @@ -265,3 +266,53 @@ pub struct ActiveEraStore { /// Validator set of this era must be equal to `SessionInterface::validators`. pub _runtime: PhantomData, } + +/// Declare the desire to validate for the origin controller. +/// +/// Effects will be felt at the beginning of the next era. +/// +/// The dispatch origin for this call must be _Signed_ by the controller, not the stash. +/// And, it can be only called when [`EraElectionStatus`] is `Closed`. +/// +/// # +/// - Independent of the arguments. Insignificant complexity. +/// - Contains a limited number of reads. +/// - Writes are limited to the `origin` account key. +/// ----------- +/// Base Weight: 17.13 µs +/// DB Weight: +/// - Read: Era Election Status, Ledger +/// - Write: Nominators, Validators +/// # +#[derive(Clone, Debug, PartialEq, Call, Encode)] +pub struct ValidateCall<'a, T: Staking> { + /// Runtime marker. + pub _runtime: PhantomData, + /// Validation preferences. + pub prefs: &'a ValidatorPrefs, +} + +/// Declare the desire to nominate `targets` for the origin controller. +/// +/// Effects will be felt at the beginning of the next era. This can only be called when +/// [`EraElectionStatus`] is `Closed`. +/// +/// The dispatch origin for this call must be _Signed_ by the controller, not the stash. +/// And, it can be only called when [`EraElectionStatus`] is `Closed`. +/// +/// # +/// - The transaction's complexity is proportional to the size of `targets` (N) +/// which is capped at CompactAssignments::LIMIT (MAX_NOMINATIONS). +/// - Both the reads and writes follow a similar pattern. +/// --------- +/// Base Weight: 22.34 + .36 * N µs +/// where N is the number of targets +/// DB Weight: +/// - Reads: Era Election Status, Ledger, Current Era +/// - Writes: Validators, Nominators +/// # +#[derive(Call, Encode)] +pub struct NominateCall { + /// The targets that are being nominated + pub targets: Vec, +} From 88ac3cb2a8e9e31c6f23bf70b06ef46937630054 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sun, 17 May 2020 13:46:15 -0400 Subject: [PATCH 11/80] Use the #[module] macro This fixes a compile error --- src/frame/staking.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 8b046065828..80ec46db18a 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -16,7 +16,7 @@ //! Implements support for the frame_staking module. -use super::system::System; +use super::system::{System, SystemEventsDecoder as _}; use codec::{ Decode, Encode, @@ -109,6 +109,7 @@ impl Default for ValidatorPrefs { } /// The subset of the `frame::Trait` that a client must implement. +#[module] pub trait Staking: System {} /// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. @@ -143,8 +144,6 @@ pub struct StakingLedger { pub claimed_rewards: Vec, } -const MODULE: &str = "Staking"; - /// Number of eras to keep in history. /// /// Information is kept for eras in `[current_era - history_depth; current_era]`. From 122260ff591cb47170b9025e37db8dad59461450 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sun, 17 May 2020 13:48:41 -0400 Subject: [PATCH 12/80] Explain undefined method diagnostics --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 2d59d4716e5..88c985311bf 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ A library to **sub**mit e**xt**rinsics to a [substrate](https://github.com/parit See [examples](./examples). +If you use `#[derive(Call)]` without `#[module]` in the same module, you will get errors +complaining about an undefined method with a name starting with `with_`. + **Alternatives** [substrate-api-client](https://github.com/scs/substrate-api-client) provides similar functionality. From ffbffd44eb663034ff2f9a4bae31fcdcb8013f0f Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sun, 17 May 2020 15:34:50 -0400 Subject: [PATCH 13/80] =?UTF-8?q?Use=20=E2=80=98#[module]=E2=80=99=20and?= =?UTF-8?q?=20implement=20session=20for=20Kusama?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frame/session.rs | 13 ++++++++----- src/frame/staking.rs | 6 +++++- src/runtimes.rs | 6 ++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/frame/session.rs b/src/frame/session.rs index 7dcbe58da3d..0a9cfc02b0f 100644 --- a/src/frame/session.rs +++ b/src/frame/session.rs @@ -16,7 +16,10 @@ // Copyright 2019-2020 Parity Technologies (UK) Ltd. //! Session support -use crate::frame::system::System; +use crate::frame::system::{ + System, + SystemEventsDecoder as _, +}; use codec::Encode; use frame_support::Parameter; use std::{ @@ -26,15 +29,15 @@ use std::{ use substrate_subxt_proc_macro::Store; /// The trait needed for this module. +#[module] pub trait Session: System { /// The validator account identifier type for the runtime. - type ValidatorId: Parameter + Debug + Ord + Default; + type ValidatorId: Parameter + Debug + Ord + Default + Send + Sync + 'static; + /// The validator account identifier type for the runtime. - type SessionIndex: Parameter + Debug + Ord + Default; + type SessionIndex: Parameter + Debug + Ord + Default + Send + Sync + 'static; } -const MODULE: &str = "Session"; - /// The current set of validators. #[derive(Encode, Store)] pub struct ValidatorsStore { diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 80ec46db18a..40b247ac63b 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -16,7 +16,10 @@ //! Implements support for the frame_staking module. -use super::system::{System, SystemEventsDecoder as _}; +use super::system::{ + System, + SystemEventsDecoder as _, +}; use codec::{ Decode, Encode, @@ -111,6 +114,7 @@ impl Default for ValidatorPrefs { /// The subset of the `frame::Trait` that a client must implement. #[module] pub trait Staking: System {} +impl Staking for T {} /// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. #[derive(PartialEq, Eq, Clone, Encode, Decode)] diff --git a/src/runtimes.rs b/src/runtimes.rs index 3ced7ce0b52..10b9bc6f1db 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -31,6 +31,7 @@ use crate::frame::{ Balances, }, contracts::Contracts, + session::Session, system::System, }; @@ -82,6 +83,11 @@ impl System for KusamaRuntime { type AccountData = AccountData<::Balance>; } +impl Session for KusamaRuntime { + type SessionIndex = u32; + type ValidatorId = ::AccountId; +} + impl Balances for KusamaRuntime { type Balance = u128; } From 1b4dc07f772e696284ef7d3b3e5214aa6b451325 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sun, 17 May 2020 15:50:02 -0400 Subject: [PATCH 14/80] =?UTF-8?q?Don=E2=80=99t=20impl=20=E2=80=98Staking?= =?UTF-8?q?=E2=80=99=20for=20all=20=E2=80=98T:=20System=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frame/staking.rs | 1 - src/runtimes.rs | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 40b247ac63b..d94e861304f 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -114,7 +114,6 @@ impl Default for ValidatorPrefs { /// The subset of the `frame::Trait` that a client must implement. #[module] pub trait Staking: System {} -impl Staking for T {} /// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. #[derive(PartialEq, Eq, Clone, Encode, Decode)] diff --git a/src/runtimes.rs b/src/runtimes.rs index 10b9bc6f1db..c11a371b709 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -88,6 +88,8 @@ impl Session for KusamaRuntime { type ValidatorId = ::AccountId; } +impl Staking for KusamaRuntime {} + impl Balances for KusamaRuntime { type Balance = u128; } From ebfdc17459578e174856a7281db15b3f50a139ea Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sun, 17 May 2020 17:34:24 -0400 Subject: [PATCH 15/80] Add staking payout support --- src/frame/staking.rs | 11 ++++++++++- src/runtimes.rs | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index d94e861304f..d442021f334 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -96,11 +96,13 @@ impl Default for RewardDestination { /// Preference of what happens regarding validation. #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -pub struct ValidatorPrefs { +pub struct ValidatorPrefs { /// Reward that validator takes up-front; only the rest is split between themselves and /// nominators. #[codec(compact)] pub commission: Perbill, + /// Runtime marker + pub _r: PhantomData, } impl Default for ValidatorPrefs { @@ -318,3 +320,10 @@ pub struct NominateCall { /// The targets that are being nominated pub targets: Vec, } + +/// Claim a payout. +#[derive(PartialEq, Eq, Clone, Call, Encode)] +struct PayoutStakersCall<'a, T: System> { + pub validator_stash: &'a T::AccountId, + pub era: EraIndex, +} diff --git a/src/runtimes.rs b/src/runtimes.rs index c11a371b709..0366a86abea 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -32,6 +32,7 @@ use crate::frame::{ }, contracts::Contracts, session::Session, + staking::Staking, system::System, }; From aaf190e1b9dfa858516079cab2b6d34139b4c12d Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Mon, 18 May 2020 19:20:18 -0400 Subject: [PATCH 16/80] Fix compilation errors and remove useless lifetimes --- src/frame/staking.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index d442021f334..9d46a51e23d 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -96,13 +96,11 @@ impl Default for RewardDestination { /// Preference of what happens regarding validation. #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -pub struct ValidatorPrefs { +pub struct ValidatorPrefs { /// Reward that validator takes up-front; only the rest is split between themselves and /// nominators. #[codec(compact)] pub commission: Perbill, - /// Runtime marker - pub _r: PhantomData, } impl Default for ValidatorPrefs { @@ -289,11 +287,11 @@ pub struct ActiveEraStore { /// - Write: Nominators, Validators /// # #[derive(Clone, Debug, PartialEq, Call, Encode)] -pub struct ValidateCall<'a, T: Staking> { +pub struct ValidateCall { /// Runtime marker. pub _runtime: PhantomData, /// Validation preferences. - pub prefs: &'a ValidatorPrefs, + pub prefs: ValidatorPrefs, } /// Declare the desire to nominate `targets` for the origin controller. From ab9612b381b04c7d6dbcb36cb5d6b5e2682627e3 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Wed, 27 May 2020 14:40:09 -0400 Subject: [PATCH 17/80] Respond to code review This fixes most of the issues found during review, with the exception of tests. --- src/frame/session.rs | 11 ++++----- src/frame/staking.rs | 56 +++++++++++++++++--------------------------- src/runtimes.rs | 7 ++++++ 3 files changed, 33 insertions(+), 41 deletions(-) diff --git a/src/frame/session.rs b/src/frame/session.rs index 0a9cfc02b0f..de534ba7ffa 100644 --- a/src/frame/session.rs +++ b/src/frame/session.rs @@ -42,7 +42,7 @@ pub trait Session: System { #[derive(Encode, Store)] pub struct ValidatorsStore { #[store(returns = Vec<::ValidatorId>)] - /// The current set of validators. + /// Marker for the runtime pub _runtime: PhantomData, } @@ -50,8 +50,8 @@ pub struct ValidatorsStore { #[derive(Encode, Store)] pub struct CurrentIndexStore { #[store(returns = ::SessionIndex)] - /// Current index of the session. - pub _r: PhantomData, + /// Marker for the runtime + pub _runtime: PhantomData, } /// True if the underlying economic identities or weighting behind the validators @@ -59,7 +59,6 @@ pub struct CurrentIndexStore { #[derive(Encode, Store)] pub struct QueuedChangedStore { #[store(returns = bool)] - /// True if the underlying economic identities or weighting behind the validators - /// has changed in the queued validator set. - pub _r: PhantomData, + /// Marker for the runtime + pub _runtime: PhantomData, } diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 9d46a51e23d..97c79fc4c6c 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -25,17 +25,14 @@ use codec::{ Encode, HasCompact, }; -use sp_runtime::{ - Perbill, - RuntimeDebug, -}; +use sp_runtime::Perbill; use std::{ fmt::Debug, marker::PhantomData, }; /// A record of the nominations made by a specific account. -#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +#[derive(PartialEq, Eq, Clone, Encode, Decode, Debug, Ord, PartialOrd, Hash)] pub struct Nominations { /// The targets of nomination. pub targets: Vec, @@ -48,7 +45,7 @@ pub struct Nominations { } /// Information regarding the active era (era in used in session). -#[derive(Encode, Decode, RuntimeDebug)] +#[derive(Encode, Decode, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct ActiveEraInfo { /// Index of era. pub index: EraIndex, @@ -56,7 +53,7 @@ pub struct ActiveEraInfo { /// /// Start can be none if start hasn't been set for the era yet, /// Start is set on the first on_finalize of the era to guarantee usage of `Time`. - start: Option, + pub start: Option, } /// Data type used to index nominators in the compact type @@ -78,7 +75,7 @@ pub type EraIndex = u32; pub type RewardPoint = u32; /// A destination account for payment. -#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug)] +#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Debug)] pub enum RewardDestination { /// Pay into the stash account, increasing the amount at stake accordingly. Staked, @@ -95,7 +92,7 @@ impl Default for RewardDestination { } /// Preference of what happens regarding validation. -#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +#[derive(PartialEq, Eq, Clone, Encode, Decode, Debug)] pub struct ValidatorPrefs { /// Reward that validator takes up-front; only the rest is split between themselves and /// nominators. @@ -116,18 +113,18 @@ impl Default for ValidatorPrefs { pub trait Staking: System {} /// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] +#[derive(PartialEq, Eq, Clone, Encode, Decode, Ord, PartialOrd, Hash)] pub struct UnlockChunk { /// Amount of funds to be unlocked. #[codec(compact)] - value: Balance, + pub value: Balance, /// Era number at which point it'll be unlocked. #[codec(compact)] - era: EraIndex, + pub era: EraIndex, } /// The ledger of a (bonded) stash. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] +#[derive(PartialEq, Eq, Clone, Encode, Decode, Ord, PartialOrd, Hash)] pub struct StakingLedger { /// The stash account whose balance is actually locked and at stake. pub stash: AccountId, @@ -159,13 +156,7 @@ pub struct StakingLedger { )] pub struct HistoryDepthStore { #[store(returns = u32)] - /// Number of eras to keep in history. - /// - /// Information is kept for eras in `[current_era - history_depth; current_era]`. - /// - /// Must be more than the number of eras delayed by session otherwise. - /// I.e. active era must always be in history. - /// I.e. `active_era > current_era - history_depth` must be guaranteed. + /// Marker for the runtime pub _runtime: PhantomData, } @@ -175,7 +166,7 @@ pub struct HistoryDepthStore { )] pub struct ValidatorCountStore { #[store(returns = u32)] - /// The ideal number of staking participants. + /// Marker for the runtime pub _runtime: PhantomData, } @@ -185,7 +176,7 @@ pub struct ValidatorCountStore { )] pub struct MinimumValidatorCountStore { #[store(returns = u32)] - /// Minimum number of staking participants before emergency conditions are imposed. + /// Marker for the runtime pub _runtime: PhantomData, } @@ -195,17 +186,15 @@ pub struct MinimumValidatorCountStore { #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct InvulnerablesStore { #[store(returns = Vec)] - /// Any validators that may never be slashed or forcibly kicked. It's a Vec since they're - /// easy to initialize and the performance hit is minimal (we expect no more than four - /// invulnerables) and restricted to testnets. - pub _runtime: core::marker::PhantomData, + /// Marker for the runtime + pub _runtime: PhantomData, } /// Map from all locked "stash" accounts to the controller account. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct BondedStore { #[store(returns = Vec)] - /// Map from all locked "stash" accounts to the controller account. + /// Marker for the runtime pub _runtime: PhantomData, } @@ -213,7 +202,7 @@ pub struct BondedStore { #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct LedgerStore { #[store(returns = Option>)] - /// Map from all (unlocked) "controller" accounts to the info regarding the staking. + /// Marker for the runtime pub _runtime: PhantomData, } @@ -221,7 +210,7 @@ pub struct LedgerStore { #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct PayeeStore { #[store(returns = RewardDestination)] - /// Where the reward payment should be made. Keyed by stash. + /// Marker for the runtime pub _runtime: PhantomData, } @@ -229,7 +218,7 @@ pub struct PayeeStore { #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct ValidatorsStore { #[store(returns = ValidatorPrefs)] - /// The map from (wannabe) validator stash key to the preferences of that validator. + /// Marker for the runtime pub _runtime: PhantomData, } @@ -237,7 +226,7 @@ pub struct ValidatorsStore { #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct NominatorsStore { #[store(returns = Option>)] - /// The map from nominator stash key to the set of stash keys of all validators to nominate. + /// Marker for the runtime pub _runtime: PhantomData, } @@ -262,10 +251,7 @@ pub struct CurrentEraStore { #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct ActiveEraStore { #[store(returns = Option)] - /// The active era information, it holds index and start. - /// - /// The active era is the era currently rewarded. - /// Validator set of this era must be equal to `SessionInterface::validators`. + /// Marker for the runtime pub _runtime: PhantomData, } diff --git a/src/runtimes.rs b/src/runtimes.rs index 0366a86abea..26f5d9bbb95 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -61,6 +61,13 @@ impl Balances for DefaultNodeRuntime { type Balance = u128; } +impl Session for DefaultNodeRuntime { + type SessionIndex = u32; + type ValidatorId = ::AccountId; +} + +impl Staking for DefaultNodeRuntime {} + impl Contracts for DefaultNodeRuntime {} /// Concrete type definitions compatible with those for kusama, v0.7 From 193104c5e95efe78ef1b4c44fdd082f7404b79db Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Wed, 27 May 2020 21:15:56 -0400 Subject: [PATCH 18/80] Make signing fallable and asynchronous This is needed for hardware wallets, which require human confirmation to sign transactions. Blocking on a human to sign transactions is not a good idea, and the signing might fail for many reasons (device unplugged, authorization not granted, etc). --- Cargo.toml | 2 +- proc-macro/src/call.rs | 2 ++ src/frame/balances.rs | 21 +++----------- src/lib.rs | 30 +++++++++++++------ src/signer.rs | 66 ++++++++++++++++++++++++++---------------- 5 files changed, 69 insertions(+), 52 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9b98fb18e10..254d303767e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"] [dependencies] log = "0.4" thiserror = "1.0" -futures = "0.3" +futures = "0.3.5" jsonrpsee = { version = "0.1", features = ["ws"] } num-traits = { version = "0.2", default-features = false } serde = { version = "1.0", features = ["derive"] } diff --git a/proc-macro/src/call.rs b/proc-macro/src/call.rs index 234edbd8dde..d1eab818997 100644 --- a/proc-macro/src/call.rs +++ b/proc-macro/src/call.rs @@ -82,6 +82,7 @@ pub fn call(s: Structure) -> TokenStream { T: #module + #subxt::system::System + Send + Sync + 'static, S: #codec::Encode + Send + Sync + 'static, E: #subxt::SignedExtra + #subxt::sp_runtime::traits::SignedExtension + Send + Sync + 'static, + <>::Extra as #subxt::sp_runtime::traits::SignedExtension>::AdditionalSigned: Send + Sync, { fn #call<'a>( &'a self, @@ -154,6 +155,7 @@ mod tests { T: Balances + substrate_subxt::system::System + Send + Sync + 'static, S: codec::Encode + Send + Sync + 'static, E: substrate_subxt::SignedExtra + substrate_subxt::sp_runtime::traits::SignedExtension + Send + Sync + 'static, + <>::Extra as substrate_subxt::sp_runtime::traits::SignedExtension>::AdditionalSigned: Send + Sync, { fn transfer<'a>( &'a self, diff --git a/src/frame/balances.rs b/src/frame/balances.rs index 02e41d9342a..cbbca1fbcea 100644 --- a/src/frame/balances.rs +++ b/src/frame/balances.rs @@ -16,21 +16,11 @@ //! Implements support for the pallet_balances module. -use crate::frame::system::{ - System, - SystemEventsDecoder, -}; -use codec::{ - Decode, - Encode, -}; +use crate::frame::system::{System, SystemEventsDecoder}; +use codec::{Decode, Encode}; use core::marker::PhantomData; use frame_support::Parameter; -use sp_runtime::traits::{ - AtLeast32Bit, - MaybeSerialize, - Member, -}; +use sp_runtime::traits::{AtLeast32Bit, MaybeSerialize, Member}; use std::fmt::Debug; /// The subset of the `pallet_balances::Trait` that a client must implement. @@ -110,10 +100,7 @@ pub struct TransferEvent { mod tests { use super::*; use crate::{ - system::{ - AccountStore, - AccountStoreExt, - }, + system::{AccountStore, AccountStoreExt}, tests::test_client, }; use sp_keyring::AccountKeyring; diff --git a/src/lib.rs b/src/lib.rs index 9d38535627a..76d03cd0b80 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,7 +46,10 @@ pub use sp_core; pub use sp_runtime; use codec::Encode; -use futures::future; +use futures::{ + future, + future::TryFutureExt as _, +}; use jsonrpsee::client::Subscription; use sc_rpc_api::state::ReadProof; use sp_core::storage::{ @@ -118,7 +121,7 @@ pub struct ClientBuilder> { client: Option, } -impl ClientBuilder { +impl ClientBuilder { /// Creates a new ClientBuilder. pub fn new() -> Self { Self { @@ -327,18 +330,21 @@ where } /// Creates a signed extrinsic. - pub async fn create_signed>( + pub async fn create_signed + Send + Sync>( &self, call: C, signer: &(dyn Signer + Send + Sync), ) -> Result< UncheckedExtrinsic>::Extra>, Error, - > { + > + where + <>::Extra as SignedExtension>::AdditionalSigned: Send + Sync, + { let unsigned = self .create_unsigned(call, signer.account_id(), signer.nonce()) .await?; - Ok(signer.sign(unsigned)) + signer.sign(unsigned).map_err(From::from).await } /// Returns an events decoder for a call. @@ -379,21 +385,27 @@ where } /// Submits a transaction to the chain. - pub async fn submit>( + pub async fn submit + Send + Sync>( &self, call: C, signer: &(dyn Signer + Send + Sync), - ) -> Result { + ) -> Result + where + <>::Extra as SignedExtension>::AdditionalSigned: Send + Sync, + { let extrinsic = self.create_signed(call, signer).await?; self.submit_extrinsic(extrinsic).await } /// Submits transaction to the chain and watch for events. - pub async fn watch>( + pub async fn watch + Send + Sync>( &self, call: C, signer: &(dyn Signer + Send + Sync), - ) -> Result, Error> { + ) -> Result, Error> + where + <>::Extra as SignedExtension>::AdditionalSigned: Send + Sync, + { let extrinsic = self.create_signed(call, signer).await?; let decoder = self.events_decoder::()?; self.submit_and_watch_extrinsic(extrinsic, decoder).await diff --git a/src/signer.rs b/src/signer.rs index b33b3fdd339..0ab07b2e1da 100644 --- a/src/signer.rs +++ b/src/signer.rs @@ -17,27 +17,19 @@ //! A library to **sub**mit e**xt**rinsics to a //! [substrate](https://github.com/paritytech/substrate) node via RPC. -use crate::{ - extra::SignedExtra, - frame::system::System, - Encoded, -}; +use crate::{extra::SignedExtra, frame::system::System, Encoded}; use codec::Encode; use sp_core::Pair; use sp_runtime::{ - generic::{ - SignedPayload, - UncheckedExtrinsic, - }, - traits::{ - IdentifyAccount, - Verify, - }, + generic::{SignedPayload, UncheckedExtrinsic}, + traits::{IdentifyAccount, Verify, SignedExtension}, }; -use std::marker::PhantomData; +use std::{future::Future, marker::PhantomData, pin::Pin}; /// Extrinsic signer. -pub trait Signer> { +pub trait Signer> + where <>::Extra as SignedExtension>::AdditionalSigned: Send + Sync +{ /// Returns the account id. fn account_id(&self) -> &T::AccountId; @@ -45,10 +37,23 @@ pub trait Signer> { fn nonce(&self) -> Option; /// Takes an unsigned extrinsic and returns a signed extrinsic. + /// + /// Some signers may fail, for instance because the hardware on which the keys are located has + /// refused the operation. fn sign( &self, extrinsic: SignedPayload, - ) -> UncheckedExtrinsic; + ) -> Pin< + Box< + dyn Future< + Output = Result< + UncheckedExtrinsic, + String, + >, + > + Send + + Sync, + >, + >; } /// Extrinsic signer using a private key. @@ -91,12 +96,13 @@ where impl Signer for PairSigner where - T: System, - T::AccountId: Into, - S: Encode, - E: SignedExtra, - P: Pair, - P::Signature: Into, + T: System + 'static, + T::AccountId: Into + 'static, + S: Encode + 'static + Send + Sync, + E: SignedExtra + 'static, + P: Pair + 'static, + P::Signature: Into + 'static, + <>::Extra as SignedExtension>::AdditionalSigned: Send + Sync, { fn account_id(&self) -> &T::AccountId { &self.account_id @@ -109,14 +115,24 @@ where fn sign( &self, extrinsic: SignedPayload, - ) -> UncheckedExtrinsic { + ) -> Pin< + Box< + dyn Future< + Output = Result< + UncheckedExtrinsic, + String, + >, + > + Send + + Sync, + >, + > { let signature = extrinsic.using_encoded(|payload| self.signer.sign(payload)); let (call, extra, _) = extrinsic.deconstruct(); - UncheckedExtrinsic::new_signed( + Box::pin(futures::future::ready(Ok(UncheckedExtrinsic::new_signed( call, self.account_id.clone().into(), signature.into(), extra, - ) + )))) } } From c4942c45a891291b58f6e61238d57d607945d5a6 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 28 May 2020 12:34:08 -0400 Subject: [PATCH 19/80] Reformat --- src/frame/balances.rs | 21 +++++++++++++++++---- src/signer.rs | 26 +++++++++++++++++++++----- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/frame/balances.rs b/src/frame/balances.rs index cbbca1fbcea..02e41d9342a 100644 --- a/src/frame/balances.rs +++ b/src/frame/balances.rs @@ -16,11 +16,21 @@ //! Implements support for the pallet_balances module. -use crate::frame::system::{System, SystemEventsDecoder}; -use codec::{Decode, Encode}; +use crate::frame::system::{ + System, + SystemEventsDecoder, +}; +use codec::{ + Decode, + Encode, +}; use core::marker::PhantomData; use frame_support::Parameter; -use sp_runtime::traits::{AtLeast32Bit, MaybeSerialize, Member}; +use sp_runtime::traits::{ + AtLeast32Bit, + MaybeSerialize, + Member, +}; use std::fmt::Debug; /// The subset of the `pallet_balances::Trait` that a client must implement. @@ -100,7 +110,10 @@ pub struct TransferEvent { mod tests { use super::*; use crate::{ - system::{AccountStore, AccountStoreExt}, + system::{ + AccountStore, + AccountStoreExt, + }, tests::test_client, }; use sp_keyring::AccountKeyring; diff --git a/src/signer.rs b/src/signer.rs index 0ab07b2e1da..68657f04e13 100644 --- a/src/signer.rs +++ b/src/signer.rs @@ -17,18 +17,34 @@ //! A library to **sub**mit e**xt**rinsics to a //! [substrate](https://github.com/paritytech/substrate) node via RPC. -use crate::{extra::SignedExtra, frame::system::System, Encoded}; +use crate::{ + extra::SignedExtra, + frame::system::System, + Encoded, +}; use codec::Encode; use sp_core::Pair; use sp_runtime::{ - generic::{SignedPayload, UncheckedExtrinsic}, - traits::{IdentifyAccount, Verify, SignedExtension}, + generic::{ + SignedPayload, + UncheckedExtrinsic, + }, + traits::{ + IdentifyAccount, + SignedExtension, + Verify, + }, +}; +use std::{ + future::Future, + marker::PhantomData, + pin::Pin, }; -use std::{future::Future, marker::PhantomData, pin::Pin}; /// Extrinsic signer. pub trait Signer> - where <>::Extra as SignedExtension>::AdditionalSigned: Send + Sync +where + <>::Extra as SignedExtension>::AdditionalSigned: Send + Sync, { /// Returns the account id. fn account_id(&self) -> &T::AccountId; From c6ade8b3a16173ad71c583e54f50613cb69849e5 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 28 May 2020 12:36:38 -0400 Subject: [PATCH 20/80] Refactor as suggested by Andrew Jones (@ascjones). --- src/lib.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 76d03cd0b80..5c287060569 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,10 +46,7 @@ pub use sp_core; pub use sp_runtime; use codec::Encode; -use futures::{ - future, - future::TryFutureExt as _, -}; +use futures::future; use jsonrpsee::client::Subscription; use sc_rpc_api::state::ReadProof; use sp_core::storage::{ @@ -344,7 +341,8 @@ where let unsigned = self .create_unsigned(call, signer.account_id(), signer.nonce()) .await?; - signer.sign(unsigned).map_err(From::from).await + let signed = signer.sign(unsigned).await?; + Ok(signed) } /// Returns an events decoder for a call. From 36b124d1d5c080d9b28f319260c3205bc2a50975 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 28 May 2020 12:34:08 -0400 Subject: [PATCH 21/80] Reformat --- src/frame/balances.rs | 21 +++++++++++++++++---- src/signer.rs | 26 +++++++++++++++++++++----- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/frame/balances.rs b/src/frame/balances.rs index cbbca1fbcea..02e41d9342a 100644 --- a/src/frame/balances.rs +++ b/src/frame/balances.rs @@ -16,11 +16,21 @@ //! Implements support for the pallet_balances module. -use crate::frame::system::{System, SystemEventsDecoder}; -use codec::{Decode, Encode}; +use crate::frame::system::{ + System, + SystemEventsDecoder, +}; +use codec::{ + Decode, + Encode, +}; use core::marker::PhantomData; use frame_support::Parameter; -use sp_runtime::traits::{AtLeast32Bit, MaybeSerialize, Member}; +use sp_runtime::traits::{ + AtLeast32Bit, + MaybeSerialize, + Member, +}; use std::fmt::Debug; /// The subset of the `pallet_balances::Trait` that a client must implement. @@ -100,7 +110,10 @@ pub struct TransferEvent { mod tests { use super::*; use crate::{ - system::{AccountStore, AccountStoreExt}, + system::{ + AccountStore, + AccountStoreExt, + }, tests::test_client, }; use sp_keyring::AccountKeyring; diff --git a/src/signer.rs b/src/signer.rs index 0ab07b2e1da..68657f04e13 100644 --- a/src/signer.rs +++ b/src/signer.rs @@ -17,18 +17,34 @@ //! A library to **sub**mit e**xt**rinsics to a //! [substrate](https://github.com/paritytech/substrate) node via RPC. -use crate::{extra::SignedExtra, frame::system::System, Encoded}; +use crate::{ + extra::SignedExtra, + frame::system::System, + Encoded, +}; use codec::Encode; use sp_core::Pair; use sp_runtime::{ - generic::{SignedPayload, UncheckedExtrinsic}, - traits::{IdentifyAccount, Verify, SignedExtension}, + generic::{ + SignedPayload, + UncheckedExtrinsic, + }, + traits::{ + IdentifyAccount, + SignedExtension, + Verify, + }, +}; +use std::{ + future::Future, + marker::PhantomData, + pin::Pin, }; -use std::{future::Future, marker::PhantomData, pin::Pin}; /// Extrinsic signer. pub trait Signer> - where <>::Extra as SignedExtension>::AdditionalSigned: Send + Sync +where + <>::Extra as SignedExtension>::AdditionalSigned: Send + Sync, { /// Returns the account id. fn account_id(&self) -> &T::AccountId; From bc19991b7a2584fbde7a026d85395a8c28f6a53f Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 28 May 2020 12:36:38 -0400 Subject: [PATCH 22/80] Refactor as suggested by Andrew Jones (@ascjones). --- src/lib.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 76d03cd0b80..5c287060569 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,10 +46,7 @@ pub use sp_core; pub use sp_runtime; use codec::Encode; -use futures::{ - future, - future::TryFutureExt as _, -}; +use futures::future; use jsonrpsee::client::Subscription; use sc_rpc_api::state::ReadProof; use sp_core::storage::{ @@ -344,7 +341,8 @@ where let unsigned = self .create_unsigned(call, signer.account_id(), signer.nonce()) .await?; - signer.sign(unsigned).map_err(From::from).await + let signed = signer.sign(unsigned).await?; + Ok(signed) } /// Returns an events decoder for a call. From e3e30cf7bb53c51b13b629c45fa9b3cec21bb8d2 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 28 May 2020 20:50:20 -0400 Subject: [PATCH 23/80] Trait cleanups --- src/signer.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/signer.rs b/src/signer.rs index 68657f04e13..f22a03a75fb 100644 --- a/src/signer.rs +++ b/src/signer.rs @@ -31,7 +31,6 @@ use sp_runtime::{ }, traits::{ IdentifyAccount, - SignedExtension, Verify, }, }; @@ -42,10 +41,7 @@ use std::{ }; /// Extrinsic signer. -pub trait Signer> -where - <>::Extra as SignedExtension>::AdditionalSigned: Send + Sync, -{ +pub trait Signer>: Send + Sync { /// Returns the account id. fn account_id(&self) -> &T::AccountId; @@ -115,10 +111,9 @@ where T: System + 'static, T::AccountId: Into + 'static, S: Encode + 'static + Send + Sync, - E: SignedExtra + 'static, + E: SignedExtra + 'static + Send + Sync, P: Pair + 'static, P::Signature: Into + 'static, - <>::Extra as SignedExtension>::AdditionalSigned: Send + Sync, { fn account_id(&self) -> &T::AccountId { &self.account_id From 06aa7e2d3b8d8cff6b9732561d90ec8737798cc8 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 29 May 2020 19:41:12 -0400 Subject: [PATCH 24/80] Make the `Signer` impl require Send + Sync This is what Ledgeracio needs. --- src/signer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/signer.rs b/src/signer.rs index fec75018fef..986b8a39595 100644 --- a/src/signer.rs +++ b/src/signer.rs @@ -148,7 +148,7 @@ where } } -impl Signer for Box> +impl Signer for Box + Send + Sync> where T: System, S: Encode, From 49b3b1e82099f122a07be66b40764dab85605ccb Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sun, 31 May 2020 16:57:39 -0400 Subject: [PATCH 25/80] Use the correct key for staking maps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They use the key type, not ‘PhantomData’. --- src/frame/staking.rs | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 97c79fc4c6c..3fad2a0e2e3 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -194,40 +194,40 @@ pub struct InvulnerablesStore { #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct BondedStore { #[store(returns = Vec)] - /// Marker for the runtime - pub _runtime: PhantomData, + /// Tٗhe stash account + pub stash: T::AccountId, } /// Map from all (unlocked) "controller" accounts to the info regarding the staking. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct LedgerStore { #[store(returns = Option>)] - /// Marker for the runtime - pub _runtime: PhantomData, + /// The controller account + pub controller: T::AccountId, } /// Where the reward payment should be made. Keyed by stash. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct PayeeStore { #[store(returns = RewardDestination)] - /// Marker for the runtime - pub _runtime: PhantomData, + /// Tٗhe stash account + pub stash: T::AccountId, } /// The map from (wannabe) validator stash key to the preferences of that validator. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct ValidatorsStore { #[store(returns = ValidatorPrefs)] - /// Marker for the runtime - pub _runtime: PhantomData, + /// Tٗhe stash account + pub stash: T::AccountId, } /// The map from nominator stash key to the set of stash keys of all validators to nominate. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct NominatorsStore { #[store(returns = Option>)] - /// Marker for the runtime - pub _runtime: PhantomData, + /// Tٗhe stash account + pub stash: T::AccountId, } /// The current era index. @@ -237,10 +237,7 @@ pub struct NominatorsStore { #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct CurrentEraStore { #[store(returns = Option)] - /// The current era index. - /// - /// This is the latest planned era, depending on how the Session pallet queues the validator - /// set, it might be active or not. + /// Marker for the runtime pub _runtime: PhantomData, } @@ -306,7 +303,7 @@ pub struct NominateCall { } /// Claim a payout. -#[derive(PartialEq, Eq, Clone, Call, Encode)] +#[derive(PartialEq, Eq, Clone, Call, Encode, Decode)] struct PayoutStakersCall<'a, T: System> { pub validator_stash: &'a T::AccountId, pub era: EraIndex, From 3314ea1dcb1b7b414678d491547aef82378db978 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sun, 31 May 2020 17:07:23 -0400 Subject: [PATCH 26/80] Implement set_payee call --- src/frame/staking.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 3fad2a0e2e3..7f213154d57 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -85,10 +85,13 @@ pub enum RewardDestination { Controller, } -impl Default for RewardDestination { - fn default() -> Self { - RewardDestination::Staked - } +/// Preference of what happens regarding validation. +#[derive(PartialEq, Eq, Clone, Encode, Decode, Debug, Call)] +pub struct SetPayeeCall { + /// The payee + pub payee: Perbill, + /// Marker for the runtime + pub _runtime: PhantomData, } /// Preference of what happens regarding validation. From 57e2390a71b4c78318259d2247ac71f98e1c5869 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Tue, 2 Jun 2020 20:28:04 -0400 Subject: [PATCH 27/80] Switch to associated types for Staking --- src/frame/staking.rs | 125 +++++++++++++++++++++++++++---------------- src/frame/system.rs | 2 + src/runtimes.rs | 20 +++++-- 3 files changed, 99 insertions(+), 48 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 7f213154d57..4e31c568d99 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -16,16 +16,23 @@ //! Implements support for the frame_staking module. -use super::system::{ - System, - SystemEventsDecoder as _, +use super::balances::{ + Balances, + BalancesEventsDecoder as _, }; use codec::{ Decode, Encode, - HasCompact, }; -use sp_runtime::Perbill; +use frame_support::Parameter; +use sp_runtime::{ + traits::{ + AtLeast32Bit, + MaybeSerialize, + Member, + }, + Perbill, +}; use std::{ fmt::Debug, marker::PhantomData, @@ -33,22 +40,22 @@ use std::{ /// A record of the nominations made by a specific account. #[derive(PartialEq, Eq, Clone, Encode, Decode, Debug, Ord, PartialOrd, Hash)] -pub struct Nominations { +pub struct Nominations { /// The targets of nomination. - pub targets: Vec, + pub targets: Vec, /// The era the nominations were submitted. /// /// Except for initial nominations which are considered submitted at era 0. - pub submitted_in: EraIndex, + pub submitted_in: T::EraIndex, /// Whether the nominations have been suppressed. pub suppressed: bool, } /// Information regarding the active era (era in used in session). #[derive(Encode, Decode, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] -pub struct ActiveEraInfo { +pub struct ActiveEraInfo { /// Index of era. - pub index: EraIndex, + pub index: T::EraIndex, /// Moment of start expresed as millisecond from `$UNIX_EPOCH`. /// /// Start can be none if start hasn't been set for the era yet, @@ -56,24 +63,6 @@ pub struct ActiveEraInfo { pub start: Option, } -/// Data type used to index nominators in the compact type -pub type NominatorIndex = u32; - -/// Data type used to index validators in the compact type. -pub type ValidatorIndex = u16; - -/// Maximum number of validators that can be stored in a snapshot. -pub const MAX_VALIDATORS: usize = ValidatorIndex::max_value() as usize; - -/// Maximum number of nominators that can be stored in a snapshot. -pub const MAX_NOMINATORS: usize = NominatorIndex::max_value() as usize; - -/// Counter for the number of eras that have passed. -pub type EraIndex = u32; - -/// Counter for the number of "reward" points earned by a given validator. -pub type RewardPoint = u32; - /// A destination account for payment. #[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Debug)] pub enum RewardDestination { @@ -89,7 +78,7 @@ pub enum RewardDestination { #[derive(PartialEq, Eq, Clone, Encode, Decode, Debug, Call)] pub struct SetPayeeCall { /// The payee - pub payee: Perbill, + pub payee: RewardDestination, /// Marker for the runtime pub _runtime: PhantomData, } @@ -113,38 +102,84 @@ impl Default for ValidatorPrefs { /// The subset of the `frame::Trait` that a client must implement. #[module] -pub trait Staking: System {} +pub trait Staking: Balances { + /// Data type used to index nominators in the compact type + type NominatorIndex: Parameter + + codec::Codec + + Member + + Default + + Copy + + MaybeSerialize + + Debug; + + /// Data type used to index validators in the compact type. + type ValidatorIndex: Parameter + + codec::Codec + + Send + + Sync + + Default + + Member + + Copy + + MaybeSerialize + + Debug; + + /// Maximum number of validators that can be stored in a snapshot. + const MAX_VALIDATORS: usize; + + /// Maximum number of nominators that can be stored in a snapshot. + const MAX_NOMINATORS: usize; + + /// Counter for the number of eras that have passed. + type EraIndex: Parameter + + Member + + AtLeast32Bit + + codec::Codec + + Default + + Copy + + MaybeSerialize + + Debug; + + /// Counter for the number of "reward" points earned by a given validator. + type RewardPoint: Parameter + + Member + + AtLeast32Bit + + codec::Codec + + Default + + Copy + + MaybeSerialize + + Debug; +} /// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. #[derive(PartialEq, Eq, Clone, Encode, Decode, Ord, PartialOrd, Hash)] -pub struct UnlockChunk { +pub struct UnlockChunk { /// Amount of funds to be unlocked. #[codec(compact)] - pub value: Balance, + pub value: T::Balance, /// Era number at which point it'll be unlocked. #[codec(compact)] - pub era: EraIndex, + pub era: T::EraIndex, } /// The ledger of a (bonded) stash. #[derive(PartialEq, Eq, Clone, Encode, Decode, Ord, PartialOrd, Hash)] -pub struct StakingLedger { +pub struct StakingLedger { /// The stash account whose balance is actually locked and at stake. - pub stash: AccountId, + pub stash: T::AccountId, /// The total amount of the stash's balance that we are currently accounting for. /// It's just `active` plus all the `unlocking` balances. #[codec(compact)] - pub total: Balance, + pub total: T::Balance, /// The total amount of the stash's balance that will be at stake in any forthcoming /// rounds. #[codec(compact)] - pub active: Balance, + pub active: T::Balance, /// Any balance that is becoming free, which may eventually be transferred out /// of the stash (assuming it doesn't get slashed first). - pub unlocking: Vec>, + pub unlocking: Vec>, /// List of eras for which the stakers behind a validator have claimed rewards. Only updated /// for validators. - pub claimed_rewards: Vec, + pub claimed_rewards: Vec, } /// Number of eras to keep in history. @@ -204,7 +239,7 @@ pub struct BondedStore { /// Map from all (unlocked) "controller" accounts to the info regarding the staking. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct LedgerStore { - #[store(returns = Option>)] + #[store(returns = Option>)] /// The controller account pub controller: T::AccountId, } @@ -228,7 +263,7 @@ pub struct ValidatorsStore { /// The map from nominator stash key to the set of stash keys of all validators to nominate. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct NominatorsStore { - #[store(returns = Option>)] + #[store(returns = Option>)] /// Tٗhe stash account pub stash: T::AccountId, } @@ -239,7 +274,7 @@ pub struct NominatorsStore { /// set, it might be active or not. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct CurrentEraStore { - #[store(returns = Option)] + #[store(returns = Option)] /// Marker for the runtime pub _runtime: PhantomData, } @@ -250,7 +285,7 @@ pub struct CurrentEraStore { /// Validator set of this era must be equal to `SessionInterface::validators`. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct ActiveEraStore { - #[store(returns = Option)] + #[store(returns = Option>)] /// Marker for the runtime pub _runtime: PhantomData, } @@ -307,7 +342,7 @@ pub struct NominateCall { /// Claim a payout. #[derive(PartialEq, Eq, Clone, Call, Encode, Decode)] -struct PayoutStakersCall<'a, T: System> { +struct PayoutStakersCall<'a, T: Staking> { pub validator_stash: &'a T::AccountId, - pub era: EraIndex, + pub era: T::EraIndex, } diff --git a/src/frame/system.rs b/src/frame/system.rs index 6734d47322f..410e9a5299e 100644 --- a/src/frame/system.rs +++ b/src/frame/system.rs @@ -100,6 +100,8 @@ pub trait System { + MaybeSerialize + Debug + MaybeDisplay + + Encode + + Decode + Ord + Default; diff --git a/src/runtimes.rs b/src/runtimes.rs index 26f5d9bbb95..c7a02044c10 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -45,6 +45,15 @@ use crate::frame::{ #[derive(Debug, Clone, Eq, PartialEq)] pub struct DefaultNodeRuntime; +impl Staking for DefaultNodeRuntime { + type NominatorIndex = u32; + type ValidatorIndex = u16; + const MAX_VALIDATORS: usize = Self::ValidatorIndex::max_value() as usize; + const MAX_NOMINATORS: usize = Self::NominatorIndex::max_value() as usize; + type EraIndex = u32; + type RewardPoint = u32; +} + impl System for DefaultNodeRuntime { type Index = u32; type BlockNumber = u32; @@ -66,8 +75,6 @@ impl Session for DefaultNodeRuntime { type ValidatorId = ::AccountId; } -impl Staking for DefaultNodeRuntime {} - impl Contracts for DefaultNodeRuntime {} /// Concrete type definitions compatible with those for kusama, v0.7 @@ -96,7 +103,14 @@ impl Session for KusamaRuntime { type ValidatorId = ::AccountId; } -impl Staking for KusamaRuntime {} +impl Staking for KusamaRuntime { + type NominatorIndex = u32; + type ValidatorIndex = u16; + const MAX_VALIDATORS: usize = Self::ValidatorIndex::max_value() as usize; + const MAX_NOMINATORS: usize = Self::NominatorIndex::max_value() as usize; + type EraIndex = u32; + type RewardPoint = u32; +} impl Balances for KusamaRuntime { type Balance = u128; From 067c6f9c745a51ed97771f6852a7126d153289d8 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Wed, 3 Jun 2020 00:49:55 -0400 Subject: [PATCH 28/80] Implement `set_keys` This is needed for Ledgeracio. --- Cargo.toml | 5 +++++ src/frame/session.rs | 16 +++++++++++++++ src/lib.rs | 1 - src/runtimes.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 254d303767e..8ab63c29564 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,11 @@ sp-core = { version = "2.0.0-rc2", package = "sp-core" } sc-rpc-api = { version = "0.8.0-rc2", package = "sc-rpc-api" } sp-transaction-pool = { version = "2.0.0-rc2", package = "sp-transaction-pool" } substrate-subxt-proc-macro = { version = "0.8.0", path = "proc-macro" } +sp-std = "2.0.0-rc2" +sp-finality-grandpa = "2.0.0-rc2" +sp-consensus-babe = "0.8.0-rc2" +pallet-im-online = "2.0.0-rc2" +sp-authority-discovery = "2.0.0-rc2" [dev-dependencies] async-std = { version = "1.5.0", features = ["attributes"] } diff --git a/src/frame/session.rs b/src/frame/session.rs index de534ba7ffa..d0ffa0eb32d 100644 --- a/src/frame/session.rs +++ b/src/frame/session.rs @@ -22,6 +22,10 @@ use crate::frame::system::{ }; use codec::Encode; use frame_support::Parameter; +use sp_runtime::traits::{ + Member, + OpaqueKeys, +}; use std::{ fmt::Debug, marker::PhantomData, @@ -36,6 +40,9 @@ pub trait Session: System { /// The validator account identifier type for the runtime. type SessionIndex: Parameter + Debug + Ord + Default + Send + Sync + 'static; + + /// The keys. + type Keys: OpaqueKeys + Member + Parameter + Default; } /// The current set of validators. @@ -62,3 +69,12 @@ pub struct QueuedChangedStore { /// Marker for the runtime pub _runtime: PhantomData, } + +/// The current set of validators. +#[derive(Encode, Call)] +pub struct SetKeysCall { + /// The keys + pub keys: T::Keys, + /// The proof. This is not currently used and can be set to an empty vector. + pub proof: Vec, +} diff --git a/src/lib.rs b/src/lib.rs index 5c287060569..df03eb63b91 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,7 +21,6 @@ bad_style, const_err, improper_ctypes, - missing_docs, non_shorthand_field_patterns, no_mangle_generic_items, overflowing_literals, diff --git a/src/runtimes.rs b/src/runtimes.rs index c7a02044c10..011897c5c25 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -13,9 +13,12 @@ // // You should have received a copy of the GNU General Public License // along with substrate-subxt. If not, see . +#![allow(missing_docs)] +use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use sp_runtime::{ generic::Header, + impl_opaque_keys, traits::{ BlakeTwo256, IdentifyAccount, @@ -24,6 +27,47 @@ use sp_runtime::{ MultiSignature, OpaqueExtrinsic, }; +use sp_std::prelude::*; + +/// BABE marker struct +pub struct Babe; +impl sp_runtime::BoundToRuntimeAppPublic for Babe { + type Public = sp_consensus_babe::AuthorityId; +} + +/// ImOnline marker struct +pub struct ImOnline; +impl sp_runtime::BoundToRuntimeAppPublic for ImOnline { + type Public = ImOnlineId; +} + +/// GRANDPA marker struct +pub struct Grandpa; +impl sp_runtime::BoundToRuntimeAppPublic for Grandpa { + type Public = sp_finality_grandpa::AuthorityId; +} + +use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; + +/// Authority discovery marker struct +pub struct AuthorityDiscovery; +impl sp_runtime::BoundToRuntimeAppPublic for AuthorityDiscovery { + type Public = AuthorityDiscoveryId; +} + +impl_opaque_keys! { + /// Runtime keys + pub struct SessionKeys { + //// GRANDPA session key + pub grandpa: Grandpa, + //// BABE session key + pub babe: Babe, + //// ImOnline session key + pub im_online: ImOnline, + //// AuthorityDiscovery session key + pub authority_discovery: AuthorityDiscovery, + } +} use crate::frame::{ balances::{ @@ -73,6 +117,7 @@ impl Balances for DefaultNodeRuntime { impl Session for DefaultNodeRuntime { type SessionIndex = u32; type ValidatorId = ::AccountId; + type Keys = SessionKeys; } impl Contracts for DefaultNodeRuntime {} @@ -101,6 +146,7 @@ impl System for KusamaRuntime { impl Session for KusamaRuntime { type SessionIndex = u32; type ValidatorId = ::AccountId; + type Keys = SessionKeys; } impl Staking for KusamaRuntime { From 83c6c6104205001acf5a2e3c2d03eb9fe642c6ef Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 4 Jun 2020 10:42:23 -0400 Subject: [PATCH 29/80] Remove impl of Signer for Box MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It isn’t needed, since Box implements Deref. --- src/signer.rs | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/src/signer.rs b/src/signer.rs index 986b8a39595..a8b62c8fc2f 100644 --- a/src/signer.rs +++ b/src/signer.rs @@ -147,35 +147,3 @@ where ))) } } - -impl Signer for Box + Send + Sync> -where - T: System, - S: Encode, - E: SignedExtra, -{ - fn account_id(&self) -> &T::AccountId { - (**self).account_id() - } - - fn nonce(&self) -> Option { - (**self).nonce() - } - - fn sign( - &self, - extrinsic: SignedPayload, - ) -> Pin< - Box< - dyn Future< - Output = Result< - UncheckedExtrinsic, - String, - >, - > + Send - + Sync, - >, - > { - (**self).sign(extrinsic) - } -} From 06bc4ab97751802695b738b59f84f2d87f9ace97 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Mon, 8 Jun 2020 22:38:56 -0400 Subject: [PATCH 30/80] =?UTF-8?q?Fix=20Polkadot=20and=20Kusama=20=E2=80=98?= =?UTF-8?q?SessionKey=E2=80=99=20structs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I had failed to include the ‘Parachains’ component, which the default Substrate runtime doesn’t have. --- Cargo.toml | 33 +++++++++++++++++++-------------- src/runtimes.rs | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8ab63c29564..754341d47a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,10 @@ description = "Submit extrinsics (transactions) to a substrate node via RPC" keywords = ["parity", "substrate", "blockchain"] include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"] +[features] +default = ["kusama"] +kusama = ["polkadot"] + [dependencies] log = "0.4" thiserror = "1.0" @@ -27,22 +31,23 @@ serde_json = "1.0" url = "2.1" codec = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive", "full"] } -frame-metadata = { version = "11.0.0-rc2", package = "frame-metadata" } -frame-support = { version = "2.0.0-rc2", package = "frame-support" } -sp-runtime = { version = "2.0.0-rc2", package = "sp-runtime" } -sp-version = { version = "2.0.0-rc2", package = "sp-version" } -pallet-indices = { version = "2.0.0-rc2", package = "pallet-indices" } +frame-metadata = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-indices = { git = "https://github.com/paritytech/substrate", branch = "master" } hex = "0.4.0" -sp-rpc = { version = "2.0.0-rc2", package = "sp-rpc" } -sp-core = { version = "2.0.0-rc2", package = "sp-core" } -sc-rpc-api = { version = "0.8.0-rc2", package = "sc-rpc-api" } -sp-transaction-pool = { version = "2.0.0-rc2", package = "sp-transaction-pool" } +sp-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" } substrate-subxt-proc-macro = { version = "0.8.0", path = "proc-macro" } -sp-std = "2.0.0-rc2" -sp-finality-grandpa = "2.0.0-rc2" -sp-consensus-babe = "0.8.0-rc2" -pallet-im-online = "2.0.0-rc2" -sp-authority-discovery = "2.0.0-rc2" +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-im-online = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" } +polkadot = { git = "https://github.com/paritytech/polkadot", branch = "master", optional = true, default-features = false, features = ["std"], package = "polkadot-primitives" } [dev-dependencies] async-std = { version = "1.5.0", features = ["attributes"] } diff --git a/src/runtimes.rs b/src/runtimes.rs index 011897c5c25..146e1b794e3 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -49,6 +49,13 @@ impl sp_runtime::BoundToRuntimeAppPublic for Grandpa { use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +/// Parachain marker struct +#[cfg(feature = "kusama")] +pub struct Parachains; +impl sp_runtime::BoundToRuntimeAppPublic for Parachains { + type Public = polkadot::parachain::ValidatorId; +} + /// Authority discovery marker struct pub struct AuthorityDiscovery; impl sp_runtime::BoundToRuntimeAppPublic for AuthorityDiscovery { @@ -56,7 +63,24 @@ impl sp_runtime::BoundToRuntimeAppPublic for AuthorityDiscovery { } impl_opaque_keys! { - /// Runtime keys + /// Substrate base runtime keys + pub struct BasicSessionKeys { + //// GRANDPA session key + pub grandpa: Grandpa, + //// BABE session key + pub babe: Babe, + //// ImOnline session key + pub im_online: ImOnline, + //// Parachain validation session key + pub parachains: Parachains, + //// AuthorityDiscovery session key + pub authority_discovery: AuthorityDiscovery, + } +} + +#[cfg(feature = "kusama")] +impl_opaque_keys! { + /// Polkadot/Kusama runtime keys pub struct SessionKeys { //// GRANDPA session key pub grandpa: Grandpa, @@ -64,6 +88,8 @@ impl_opaque_keys! { pub babe: Babe, //// ImOnline session key pub im_online: ImOnline, + //// ParachainValidator session key + pub parachain_validator: Parachains, //// AuthorityDiscovery session key pub authority_discovery: AuthorityDiscovery, } @@ -117,7 +143,7 @@ impl Balances for DefaultNodeRuntime { impl Session for DefaultNodeRuntime { type SessionIndex = u32; type ValidatorId = ::AccountId; - type Keys = SessionKeys; + type Keys = BasicSessionKeys; } impl Contracts for DefaultNodeRuntime {} @@ -128,9 +154,11 @@ impl Contracts for DefaultNodeRuntime {} /// /// Main difference is `type Address = AccountId`. /// Also the contracts module is not part of the kusama runtime. +#[cfg(feature = "kusama")] #[derive(Debug, Clone, Eq, PartialEq)] pub struct KusamaRuntime; +#[cfg(feature = "kusama")] impl System for KusamaRuntime { type Index = u32; type BlockNumber = u32; @@ -143,12 +171,14 @@ impl System for KusamaRuntime { type AccountData = AccountData<::Balance>; } +#[cfg(feature = "kusama")] impl Session for KusamaRuntime { type SessionIndex = u32; type ValidatorId = ::AccountId; type Keys = SessionKeys; } +#[cfg(feature = "kusama")] impl Staking for KusamaRuntime { type NominatorIndex = u32; type ValidatorIndex = u16; @@ -158,6 +188,7 @@ impl Staking for KusamaRuntime { type RewardPoint = u32; } +#[cfg(feature = "kusama")] impl Balances for KusamaRuntime { type Balance = u128; } From 6ccfc9c0b18d4fc3ec42c48cce7baf5067018fb6 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Tue, 9 Jun 2020 14:19:26 -0400 Subject: [PATCH 31/80] Include a copy of `ValidatorId` This avoids needing to depend on Polkadot. --- Cargo.toml | 33 ++++++++++++++++----------------- src/runtimes.rs | 11 ++++++++++- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 754341d47a4..92abfff6bb4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,8 +17,8 @@ keywords = ["parity", "substrate", "blockchain"] include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"] [features] +kusama = [] default = ["kusama"] -kusama = ["polkadot"] [dependencies] log = "0.4" @@ -30,24 +30,23 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" url = "2.1" codec = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive", "full"] } - -frame-metadata = { git = "https://github.com/paritytech/substrate", branch = "master" } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" } -pallet-indices = { git = "https://github.com/paritytech/substrate", branch = "master" } hex = "0.4.0" -sp-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } -sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" } substrate-subxt-proc-macro = { version = "0.8.0", path = "proc-macro" } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } -pallet-im-online = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" } -polkadot = { git = "https://github.com/paritytech/polkadot", branch = "master", optional = true, default-features = false, features = ["std"], package = "polkadot-primitives" } +sp-std = "2.0.0-rc3" +application-crypto = { version = "2.0.0-rc3", package = "sp-application-crypto" } +sp-core = "2.0.0-rc3" +sp-rpc = "2.0.0-rc3" +pallet-indices = "2.0.0-rc3" +sp-runtime = "2.0.0-rc3" +sp-version = "2.0.0-rc3" +sc-rpc-api = "0.8.0-rc3" +sp-finality-grandpa = "2.0.0-rc3" +sp-consensus-babe = "0.8.0-rc3" +pallet-im-online = "2.0.0-rc3" +sp-authority-discovery = "2.0.0-rc3" +frame-metadata = "11.0.0-rc3" +frame-support = "2.0.0-rc3" +sp-transaction-pool = "2.0.0-rc3" [dev-dependencies] async-std = { version = "1.5.0", features = ["attributes"] } diff --git a/src/runtimes.rs b/src/runtimes.rs index 146e1b794e3..2566f3df05e 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -49,11 +49,19 @@ impl sp_runtime::BoundToRuntimeAppPublic for Grandpa { use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +#[cfg(feature = "kusama")] +mod validator_app { + use application_crypto::{app_crypto, sr25519}; + app_crypto!(sr25519, sp_core::crypto::KeyTypeId(*b"para")); +} + /// Parachain marker struct #[cfg(feature = "kusama")] pub struct Parachains; + +#[cfg(feature = "kusama")] impl sp_runtime::BoundToRuntimeAppPublic for Parachains { - type Public = polkadot::parachain::ValidatorId; + type Public = validator_app::Public; } /// Authority discovery marker struct @@ -62,6 +70,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for AuthorityDiscovery { type Public = AuthorityDiscoveryId; } +#[cfg(feature = "kusama")] impl_opaque_keys! { /// Substrate base runtime keys pub struct BasicSessionKeys { From c63b74cf9318b51fc772c55cd8d376937391ff3c Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Tue, 16 Jun 2020 13:39:33 -0400 Subject: [PATCH 32/80] Fix syntax error in Cargo.toml --- Cargo.toml | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d3dd0506a0a..56f94428d35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,18 +45,11 @@ sp-transaction-pool = { version = "2.0.0-rc3", package = "sp-transaction-pool" } substrate-subxt-client = { path = "client", optional = true } substrate-subxt-proc-macro = { version = "0.8.0", path = "proc-macro" } sp-std = "2.0.0-rc3" -application-crypto = { version = "2.0.0-rc3", package = "sp-application-crypto" } -pallet-indices = "2.0.0-rc3" -sp-runtime = "2.0.0-rc3" -sp-version = "2.0.0-rc3" -sc-rpc-api = "0.8.0-rc3" -sp-finality-grandpa = "2.0.0-rc3" -sp-consensus-babe = "0.8.0-rc3" -pallet-im-online = "2.0.0-rc3" -sp-authority-discovery = "2.0.0-rc3" -frame-metadata = "11.0.0-rc3" -frame-support = "2.0.0-rc3" -sp-transaction-pool = "2.0.0-rc3" +application-crypto = { version = "2.0.0-rc3", package = "sp-application-crypto", default-features = false } +sp-finality-grandpa = { version = "2.0.0-rc3" } +sp-consensus-babe = { version = "0.8.0-rc3" } +pallet-im-online = { version = "2.0.0-rc3" } +sp-authority-discovery = { version = "2.0.0-rc3" } [dev-dependencies] async-std = { version = "=1.5.0", features = ["attributes"] } From 4d8ccabcec6e22920fde65e74d3295e2231a467b Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Tue, 16 Jun 2020 15:33:39 -0400 Subject: [PATCH 33/80] Fix compile errors --- client/src/lib.rs | 1 + src/runtimes.rs | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index e500721e3aa..f0a88e2e88c 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -233,6 +233,7 @@ fn start_subxt_client( pruning: Default::default(), rpc_cors: Default::default(), rpc_http: Default::default(), + rpc_ipc: Default::default(), rpc_ws: Default::default(), rpc_ws_max_connections: Default::default(), rpc_methods: Default::default(), diff --git a/src/runtimes.rs b/src/runtimes.rs index e32169ef97a..4bfec53911a 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -51,8 +51,11 @@ use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; #[cfg(feature = "kusama")] mod validator_app { - use application_crypto::{app_crypto, sr25519}; - app_crypto!(sr25519, sp_core::crypto::KeyTypeId(*b"para")); + use application_crypto::{ + app_crypto, + sr25519, + }; + app_crypto!(sr25519, sp_core::crypto::KeyTypeId(*b"para")); } /// Parachain marker struct @@ -97,8 +100,8 @@ impl_opaque_keys! { pub babe: Babe, //// ImOnline session key pub im_online: ImOnline, - //// ParachainValidator session key - pub parachain_validator: Parachains, + //// ParachainValidator session key + pub parachain_validator: Parachains, //// AuthorityDiscovery session key pub authority_discovery: AuthorityDiscovery, } From 90e3b9bb4e243e54d450ec3a7fe288eb46dbdf70 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 18 Jun 2020 13:44:20 -0400 Subject: [PATCH 34/80] Add Debug impls --- src/frame/session.rs | 8 ++++---- src/frame/staking.rs | 8 ++++---- src/lib.rs | 6 +++++- src/rpc.rs | 2 +- src/runtimes.rs | 5 +++++ src/signer.rs | 1 + 6 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/frame/session.rs b/src/frame/session.rs index d0ffa0eb32d..f82e52f7c40 100644 --- a/src/frame/session.rs +++ b/src/frame/session.rs @@ -46,7 +46,7 @@ pub trait Session: System { } /// The current set of validators. -#[derive(Encode, Store)] +#[derive(Encode, Store, Debug)] pub struct ValidatorsStore { #[store(returns = Vec<::ValidatorId>)] /// Marker for the runtime @@ -54,7 +54,7 @@ pub struct ValidatorsStore { } /// Current index of the session. -#[derive(Encode, Store)] +#[derive(Encode, Store, Debug)] pub struct CurrentIndexStore { #[store(returns = ::SessionIndex)] /// Marker for the runtime @@ -63,7 +63,7 @@ pub struct CurrentIndexStore { /// True if the underlying economic identities or weighting behind the validators /// has changed in the queued validator set. -#[derive(Encode, Store)] +#[derive(Encode, Store, Debug)] pub struct QueuedChangedStore { #[store(returns = bool)] /// Marker for the runtime @@ -71,7 +71,7 @@ pub struct QueuedChangedStore { } /// The current set of validators. -#[derive(Encode, Call)] +#[derive(Encode, Call, Debug)] pub struct SetKeysCall { /// The keys pub keys: T::Keys, diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 4e31c568d99..daaca52b475 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -151,7 +151,7 @@ pub trait Staking: Balances { } /// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. -#[derive(PartialEq, Eq, Clone, Encode, Decode, Ord, PartialOrd, Hash)] +#[derive(PartialEq, Eq, Clone, Encode, Decode, Ord, PartialOrd, Hash, Debug)] pub struct UnlockChunk { /// Amount of funds to be unlocked. #[codec(compact)] @@ -162,7 +162,7 @@ pub struct UnlockChunk { } /// The ledger of a (bonded) stash. -#[derive(PartialEq, Eq, Clone, Encode, Decode, Ord, PartialOrd, Hash)] +#[derive(PartialEq, Eq, Clone, Encode, Decode, Ord, PartialOrd, Hash, Debug)] pub struct StakingLedger { /// The stash account whose balance is actually locked and at stake. pub stash: T::AccountId, @@ -334,14 +334,14 @@ pub struct ValidateCall { /// - Reads: Era Election Status, Ledger, Current Era /// - Writes: Validators, Nominators /// # -#[derive(Call, Encode)] +#[derive(Call, Encode, Debug)] pub struct NominateCall { /// The targets that are being nominated pub targets: Vec, } /// Claim a payout. -#[derive(PartialEq, Eq, Clone, Call, Encode, Decode)] +#[derive(PartialEq, Eq, Clone, Call, Encode, Decode, Debug)] struct PayoutStakersCall<'a, T: Staking> { pub validator_stash: &'a T::AccountId, pub era: T::EraIndex, diff --git a/src/lib.rs b/src/lib.rs index eff1e3ff12f..5dc9a5fbeaf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,7 @@ path_statements, patterns_in_fns_without_body, private_in_public, + missing_debug_implementations, unconditional_recursion, unused_allocation, unused_comparisons, @@ -34,7 +35,8 @@ while_true, trivial_casts, trivial_numeric_casts, - unused_extern_crates + unused_extern_crates, + clippy::all )] #![allow(clippy::type_complexity)] @@ -114,6 +116,7 @@ use crate::{ /// ClientBuilder for constructing a Client. #[derive(Default)] +#[allow(missing_debug_implementations)] pub struct ClientBuilder> { _marker: std::marker::PhantomData<(T, S, E)>, url: Option, @@ -172,6 +175,7 @@ impl ClientBuilder { } /// Client to interface with a substrate node. +#[allow(missing_debug_implementations)] pub struct Client> { rpc: Rpc, genesis_hash: T::Hash, diff --git a/src/rpc.rs b/src/rpc.rs index faba5db5a21..047ddf05fcb 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -85,7 +85,7 @@ pub type ChainBlock = SignedBlock::Header, ::Extrinsic>>; /// Wrapper for NumberOrHex to allow custom From impls -#[derive(Serialize)] +#[derive(Serialize, Debug)] #[serde(bound = "::BlockNumber: Serialize")] pub struct BlockNumber(NumberOrHex<::BlockNumber>); diff --git a/src/runtimes.rs b/src/runtimes.rs index 4bfec53911a..7143fda0c24 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -30,18 +30,21 @@ use sp_runtime::{ use sp_std::prelude::*; /// BABE marker struct +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct Babe; impl sp_runtime::BoundToRuntimeAppPublic for Babe { type Public = sp_consensus_babe::AuthorityId; } /// ImOnline marker struct +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct ImOnline; impl sp_runtime::BoundToRuntimeAppPublic for ImOnline { type Public = ImOnlineId; } /// GRANDPA marker struct +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct Grandpa; impl sp_runtime::BoundToRuntimeAppPublic for Grandpa { type Public = sp_finality_grandpa::AuthorityId; @@ -60,6 +63,7 @@ mod validator_app { /// Parachain marker struct #[cfg(feature = "kusama")] +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct Parachains; #[cfg(feature = "kusama")] @@ -68,6 +72,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Parachains { } /// Authority discovery marker struct +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct AuthorityDiscovery; impl sp_runtime::BoundToRuntimeAppPublic for AuthorityDiscovery { type Public = AuthorityDiscoveryId; diff --git a/src/signer.rs b/src/signer.rs index e42b02656e0..fecd5b34238 100644 --- a/src/signer.rs +++ b/src/signer.rs @@ -69,6 +69,7 @@ pub trait Signer> { } /// Extrinsic signer using a private key. +#[derive(Debug)] pub struct PairSigner, P: Pair> { _marker: PhantomData<(S, E)>, account_id: T::AccountId, From 2bea59fac91c5825e9a664467df7f0d3480e9b61 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 18 Jun 2020 13:53:14 -0400 Subject: [PATCH 35/80] Fix return type of `BondedStore` --- src/frame/staking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index daaca52b475..bbdd145bcfe 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -231,7 +231,7 @@ pub struct InvulnerablesStore { /// Map from all locked "stash" accounts to the controller account. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct BondedStore { - #[store(returns = Vec)] + #[store(returns = Option)] /// Tٗhe stash account pub stash: T::AccountId, } From a95fd8a588bb226044b3ad3aff147214effa955a Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 19 Jun 2020 13:02:11 -0400 Subject: [PATCH 36/80] Use some upstream type definitions Also add `Default` impls. --- Cargo.toml | 1 + src/frame/session.rs | 35 +++++++++++++++++++++++++++++++++++ src/frame/staking.rs | 23 ++--------------------- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 56f94428d35..76386197c83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,7 @@ sp-finality-grandpa = { version = "2.0.0-rc3" } sp-consensus-babe = { version = "0.8.0-rc3" } pallet-im-online = { version = "2.0.0-rc3" } sp-authority-discovery = { version = "2.0.0-rc3" } +pallet-staking = "2.0.0-rc3" [dev-dependencies] async-std = { version = "=1.5.0", features = ["attributes"] } diff --git a/src/frame/session.rs b/src/frame/session.rs index f82e52f7c40..b352a911634 100644 --- a/src/frame/session.rs +++ b/src/frame/session.rs @@ -32,6 +32,18 @@ use std::{ }; use substrate_subxt_proc_macro::Store; +macro_rules! def { + ($name:ident) => { + impl Default for $name { + fn default() -> Self { + Self { + _runtime: PhantomData, + } + } + } + }; +} + /// The trait needed for this module. #[module] pub trait Session: System { @@ -53,6 +65,8 @@ pub struct ValidatorsStore { pub _runtime: PhantomData, } +def!(ValidatorsStore); + /// Current index of the session. #[derive(Encode, Store, Debug)] pub struct CurrentIndexStore { @@ -61,6 +75,8 @@ pub struct CurrentIndexStore { pub _runtime: PhantomData, } +def!(CurrentIndexStore); + /// True if the underlying economic identities or weighting behind the validators /// has changed in the queued validator set. #[derive(Encode, Store, Debug)] @@ -70,6 +86,8 @@ pub struct QueuedChangedStore { pub _runtime: PhantomData, } +def!(QueuedChangedStore); + /// The current set of validators. #[derive(Encode, Call, Debug)] pub struct SetKeysCall { @@ -78,3 +96,20 @@ pub struct SetKeysCall { /// The proof. This is not currently used and can be set to an empty vector. pub proof: Vec, } + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::test_client; + + #[async_std::test] + async fn test_state_read_free_balance() { + env_logger::try_init().ok(); + let (client, _) = test_client().await; + assert!(client + .fetch(QueuedChangedStore::default(), None) + .await + .unwrap() + .unwrap()); + } +} diff --git a/src/frame/staking.rs b/src/frame/staking.rs index bbdd145bcfe..56ab8ca2109 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -161,26 +161,7 @@ pub struct UnlockChunk { pub era: T::EraIndex, } -/// The ledger of a (bonded) stash. -#[derive(PartialEq, Eq, Clone, Encode, Decode, Ord, PartialOrd, Hash, Debug)] -pub struct StakingLedger { - /// The stash account whose balance is actually locked and at stake. - pub stash: T::AccountId, - /// The total amount of the stash's balance that we are currently accounting for. - /// It's just `active` plus all the `unlocking` balances. - #[codec(compact)] - pub total: T::Balance, - /// The total amount of the stash's balance that will be at stake in any forthcoming - /// rounds. - #[codec(compact)] - pub active: T::Balance, - /// Any balance that is becoming free, which may eventually be transferred out - /// of the stash (assuming it doesn't get slashed first). - pub unlocking: Vec>, - /// List of eras for which the stakers behind a validator have claimed rewards. Only updated - /// for validators. - pub claimed_rewards: Vec, -} +pub use pallet_staking::StakingLedger; /// Number of eras to keep in history. /// @@ -239,7 +220,7 @@ pub struct BondedStore { /// Map from all (unlocked) "controller" accounts to the info regarding the staking. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct LedgerStore { - #[store(returns = Option>)] + #[store(returns = Option>)] /// The controller account pub controller: T::AccountId, } From d3df9eabe09906d5f34bcb614817f6ba9e41397e Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 25 Jun 2020 21:14:00 -0400 Subject: [PATCH 37/80] Bump deps and fix build --- Cargo.toml | 42 ++++++++++++++++---------------- client/Cargo.toml | 8 +++---- client/src/lib.rs | 6 +++-- proc-macro/Cargo.toml | 4 ++-- src/frame/system.rs | 3 ++- src/lib.rs | 2 +- src/rpc.rs | 27 +++++++-------------- src/runtimes.rs | 15 +++++------- src/signer.rs | 1 + src/subscription.rs | 1 + test-node/Cargo.toml | 38 ++++++++++++++--------------- test-node/runtime/Cargo.toml | 46 ++++++++++++++++++------------------ test-node/src/service.rs | 10 ++++---- 13 files changed, 98 insertions(+), 105 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 05087d53d90..4326a102517 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,41 +24,41 @@ client = ["substrate-subxt-client"] [dependencies] log = "0.4.8" thiserror = "1.0.20" -futures = "0.3.5" +futures = { version = "0.3.5", package = "futures" } jsonrpsee = { version = "0.1.0", features = ["ws"] } num-traits = { version = "0.2.12", default-features = false } serde = { version = "1.0.114", features = ["derive"] } serde_json = "1.0.55" url = "2.1.1" -codec = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive", "full"] } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive", "full"] } -frame-metadata = { version = "11.0.0-rc3", package = "frame-metadata" } -frame-support = { version = "2.0.0-rc3", package = "frame-support" } -sp-runtime = { version = "2.0.0-rc3", package = "sp-runtime" } -sp-version = { version = "2.0.0-rc3", package = "sp-version" } -pallet-indices = { version = "2.0.0-rc3", package = "pallet-indices" } +frame-metadata = { version = "11.0.0-rc4", package = "frame-metadata" } +frame-support = { version = "2.0.0-rc4", package = "frame-support" } +sp-runtime = { version = "2.0.0-rc4", package = "sp-runtime" } +sp-version = { version = "2.0.0-rc4", package = "sp-version" } +pallet-indices = { version = "2.0.0-rc4", package = "pallet-indices" } hex = "0.4.2" -sp-rpc = { version = "2.0.0-rc3", package = "sp-rpc" } -sp-core = { version = "2.0.0-rc3", package = "sp-core" } -sc-rpc-api = { version = "0.8.0-rc3", package = "sc-rpc-api" } -sp-transaction-pool = { version = "2.0.0-rc3", package = "sp-transaction-pool" } +sp-rpc = { version = "2.0.0-rc4", package = "sp-rpc" } +sp-core = { version = "2.0.0-rc4", package = "sp-core" } +sc-rpc-api = { version = "0.8.0-rc4", package = "sc-rpc-api" } +sp-transaction-pool = { version = "2.0.0-rc4", package = "sp-transaction-pool" } substrate-subxt-client = { version = "0.1.0", path = "client", optional = true } substrate-subxt-proc-macro = { version = "0.9.0", path = "proc-macro" } -sp-std = "2.0.0-rc3" -application-crypto = { version = "2.0.0-rc3", package = "sp-application-crypto", default-features = false } -sp-finality-grandpa = { version = "2.0.0-rc3" } -sp-consensus-babe = { version = "0.8.0-rc3" } -pallet-im-online = { version = "2.0.0-rc3" } -sp-authority-discovery = { version = "2.0.0-rc3" } -pallet-staking = "2.0.0-rc3" +sp-std = "2.0.0-rc4" +application-crypto = { version = "2.0.0-rc4", package = "sp-application-crypto", default-features = false } +sp-finality-grandpa = "2.0.0-rc4" +sp-consensus-babe = "0.8.0-rc4" +pallet-im-online = "2.0.0-rc4" +sp-authority-discovery = "2.0.0-rc4" +pallet-staking = "2.0.0-rc4" [dev-dependencies] async-std = { version = "=1.5.0", features = ["attributes"] } env_logger = "0.7.1" wabt = "0.9.2" -frame-system = { version = "2.0.0-rc3", package = "frame-system" } -pallet-balances = { version = "2.0.0-rc3", package = "pallet-balances" } -sp-keyring = { version = "2.0.0-rc3", package = "sp-keyring" } +frame-system = { version = "2.0.0-rc4", package = "frame-system" } +pallet-balances = { version = "2.0.0-rc4", package = "pallet-balances" } +sp-keyring = { version = "2.0.0-rc4", package = "sp-keyring" } substrate-subxt-client = { version = "0.1.0", path = "client" } tempdir = "0.3.7" test-node = { path = "test-node" } diff --git a/client/Cargo.toml b/client/Cargo.toml index 821cced7a77..588e11392a5 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -13,14 +13,14 @@ keywords = ["parity", "substrate", "blockchain"] [dependencies] async-std = "=1.5.0" -futures = { version = "0.3.5", features = ["compat"] } +futures = { version = "0.3.5", features = ["compat"], package = "futures" } futures01 = { package = "futures", version = "0.1.29" } jsonrpsee = "0.1.0" log = "0.4.8" -sc-network = { version = "0.8.0-rc3", default-features = false } -sc-service = { version = "0.8.0-rc3", default-features = false } +sc-network = { version = "0.8.0-rc4", default-features = false } +sc-service = { version = "0.8.0-rc4", default-features = false } serde_json = "1.0.55" -sp-keyring = "2.0.0-rc3" +sp-keyring = { version = "2.0.0-rc4", package = "sp-keyring" } thiserror = "1.0.20" [dev-dependencies] diff --git a/client/src/lib.rs b/client/src/lib.rs index 3fed1f10ad7..70b8a3596b0 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -208,18 +208,20 @@ fn start_subxt_client( impl_version: config.impl_version, chain_spec: Box::new(config.chain_spec), role: config.role.into(), - task_executor: std::sync::Arc::new(move |fut, ty| { + task_executor: (move |fut, ty| { match ty { TaskType::Async => task::spawn(fut), TaskType::Blocking => task::spawn_blocking(|| task::block_on(fut)), }; - }), + }).into(), database: config.db, keystore: KeystoreConfig::InMemory, max_runtime_instances: 8, announce_block: true, dev_key_seed: config.role.into(), + base_path: Default::default(), + informant_output_format: Default::default(), telemetry_endpoints: Default::default(), telemetry_external_transport: Default::default(), default_heap_pages: Default::default(), diff --git a/proc-macro/Cargo.toml b/proc-macro/Cargo.toml index 0a6d6d983a0..2256ac0552a 100644 --- a/proc-macro/Cargo.toml +++ b/proc-macro/Cargo.toml @@ -25,10 +25,10 @@ synstructure = "0.12.4" [dev-dependencies] async-std = { version = "=1.5.0", features = ["attributes"] } -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.1", features = ["derive"] } env_logger = "0.7.1" pretty_assertions = "0.6.1" -sp-keyring = "2.0.0-rc3" +sp-keyring = { version = "2.0.0-rc4", package = "sp-keyring" } substrate-subxt = { path = ".." } trybuild = "1.0.30" diff --git a/src/frame/system.rs b/src/frame/system.rs index f9beaebc468..930b34ec2b7 100644 --- a/src/frame/system.rs +++ b/src/frame/system.rs @@ -30,6 +30,7 @@ use serde::de::DeserializeOwned; use sp_runtime::{ traits::{ AtLeast32Bit, + AtLeast32BitUnsigned, Bounded, CheckEqual, Extrinsic, @@ -67,7 +68,7 @@ pub trait System { + MaybeSerializeDeserialize + Debug + MaybeDisplay - + AtLeast32Bit + + AtLeast32BitUnsigned + Default + Bounded + Copy diff --git a/src/lib.rs b/src/lib.rs index 5c1264461db..17b7d7a7380 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -248,7 +248,7 @@ impl Client { /// Get a block hash. By default returns the latest block hash pub async fn block_hash( &self, - block_number: Option>, + block_number: Option, ) -> Result, Error> { let hash = self.rpc.block_hash(block_number).await?; Ok(hash) diff --git a/src/rpc.rs b/src/rpc.rs index 81e79a41340..d640784c469 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -83,23 +83,15 @@ pub type ChainBlock = /// Wrapper for NumberOrHex to allow custom From impls #[derive(Serialize, Debug)] -#[serde(bound = "::BlockNumber: Serialize")] -pub struct BlockNumber(NumberOrHex<::BlockNumber>); - -impl From::BlockNumber>> for BlockNumber -where - T: System, -{ - fn from(x: NumberOrHex<::BlockNumber>) -> Self { +pub struct BlockNumber(NumberOrHex); + +impl From for BlockNumber { + fn from(x: NumberOrHex) -> Self { BlockNumber(x) } } -impl From for BlockNumber -where - T: System, - ::BlockNumber: From, -{ +impl From for BlockNumber { fn from(x: u32) -> Self { NumberOrHex::Number(x.into()).into() } @@ -159,10 +151,9 @@ impl Rpc { } /// Fetch the genesis hash - pub async fn genesis_hash(&self) -> Result { - let block_zero = Some(ListOrValue::Value(NumberOrHex::Number( - T::BlockNumber::min_value(), - ))); + pub async fn genesis_hash(&self) -> Result + { + let block_zero = Some(ListOrValue::Value(NumberOrHex::Number(0))); let params = Params::Array(vec![to_json_value(block_zero)?]); let list_or_value: ListOrValue> = self.client.request("chain_getBlockHash", params).await?; @@ -198,7 +189,7 @@ impl Rpc { /// Get a block hash, returns hash of latest block by default pub async fn block_hash( &self, - block_number: Option>, + block_number: Option, ) -> Result, Error> { let block_number = block_number.map(ListOrValue::Value); let params = Params::Array(vec![to_json_value(block_number)?]); diff --git a/src/runtimes.rs b/src/runtimes.rs index 8714b0dd591..72e6f5b4e3a 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -79,7 +79,6 @@ impl sp_runtime::BoundToRuntimeAppPublic for AuthorityDiscovery { type Public = AuthorityDiscoveryId; } -#[cfg(feature = "kusama")] impl_opaque_keys! { /// Substrate base runtime keys pub struct BasicSessionKeys { @@ -96,7 +95,6 @@ impl_opaque_keys! { } } -#[cfg(feature = "kusama")] impl_opaque_keys! { /// Polkadot/Kusama runtime keys pub struct SessionKeys { @@ -124,9 +122,7 @@ use crate::{ AccountData, Balances, }, - contracts::Contracts, sudo::Sudo, - system::System, }, session::Session, staking::Staking, @@ -235,6 +231,12 @@ impl Balances for NodeTemplateRuntime { type Balance = u128; } +impl Session for NodeTemplateRuntime { + type SessionIndex = u32; + type ValidatorId = ::AccountId; + type Keys = BasicSessionKeys; +} + impl Sudo for NodeTemplateRuntime {} /// Concrete type definitions compatible with those for kusama, v0.7 @@ -243,17 +245,14 @@ impl Sudo for NodeTemplateRuntime {} /// /// Main difference is `type Address = AccountId`. /// Also the contracts module is not part of the kusama runtime. -#[cfg(feature = "kusama")] #[derive(Debug, Clone, Eq, PartialEq)] pub struct KusamaRuntime; -#[cfg(feature = "kusama")] impl Runtime for KusamaRuntime { type Signature = MultiSignature; type Extra = DefaultExtra; } -#[cfg(feature = "kusama")] impl System for KusamaRuntime { type Index = u32; type BlockNumber = u32; @@ -266,14 +265,12 @@ impl System for KusamaRuntime { type AccountData = AccountData<::Balance>; } -#[cfg(feature = "kusama")] impl Session for KusamaRuntime { type SessionIndex = u32; type ValidatorId = ::AccountId; type Keys = SessionKeys; } -#[cfg(feature = "kusama")] impl Staking for KusamaRuntime { type NominatorIndex = u32; type ValidatorIndex = u16; diff --git a/src/signer.rs b/src/signer.rs index ebbcd416540..f192d6563a8 100644 --- a/src/signer.rs +++ b/src/signer.rs @@ -56,6 +56,7 @@ pub trait Signer { } /// Extrinsic signer using a private key. +#[derive(Debug)] pub struct PairSigner { account_id: T::AccountId, nonce: Option, diff --git a/src/subscription.rs b/src/subscription.rs index 6208ce6f7b1..c1dd36d91fa 100644 --- a/src/subscription.rs +++ b/src/subscription.rs @@ -33,6 +33,7 @@ use crate::{ /// Event subscription simplifies filtering a storage change set stream for /// events of interest. +#[allow(missing_debug_implementations)] pub struct EventSubscription { subscription: Subscription>, decoder: EventsDecoder, diff --git a/test-node/Cargo.toml b/test-node/Cargo.toml index 9691a2053da..7e5a9fe6ae8 100644 --- a/test-node/Cargo.toml +++ b/test-node/Cargo.toml @@ -13,30 +13,30 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -futures = "0.3.5" +futures = { version = "0.3.5", package = "futures" } log = "0.4.8" structopt = "0.3.15" parking_lot = "0.11.0" -sc-cli = { version = "0.8.0-rc3", features = ["wasmtime"] } -sp-core = "2.0.0-rc3" -sc-executor = { version = "0.8.0-rc3", features = ["wasmtime"] } -sc-service = { version = "0.8.0-rc3", features = ["wasmtime"] } -sp-inherents = "2.0.0-rc3" -sc-transaction-pool = "2.0.0-rc3" -sp-transaction-pool = "2.0.0-rc3" -sc-network = "0.8.0-rc3" -sc-consensus-aura = "0.8.0-rc3" -sp-consensus-aura = "0.8.0-rc3" -sp-consensus = "0.8.0-rc3" -sc-consensus = "0.8.0-rc3" -sc-finality-grandpa = "0.8.0-rc3" -sp-finality-grandpa = "2.0.0-rc3" -sc-client-api = "2.0.0-rc3" -sp-runtime = "2.0.0-rc3" -sc-basic-authorship = "0.8.0-rc3" +sc-cli = { version = "0.8.0-rc4", features = ["wasmtime"] } +sp-core = { version = "2.0.0-rc4", package = "sp-core" } +sc-executor = { version = "0.8.0-rc4", features = ["wasmtime"] } +sc-service = { version = "0.8.0-rc4", features = ["wasmtime"] } +sp-inherents = "2.0.0-rc4" +sc-transaction-pool = "2.0.0-rc4" +sp-transaction-pool = { version = "2.0.0-rc4", package = "sp-transaction-pool" } +sc-network = "0.8.0-rc4" +sc-consensus-aura = "0.8.0-rc4" +sp-consensus-aura = "0.8.0-rc4" +sp-consensus = "0.8.0-rc4" +sc-consensus = "0.8.0-rc4" +sc-finality-grandpa = "0.8.0-rc4" +sp-finality-grandpa = "2.0.0-rc4" +sc-client-api = "2.0.0-rc4" +sp-runtime = { version = "2.0.0-rc4", package = "sp-runtime" } +sc-basic-authorship = "0.8.0-rc4" test-node-runtime = { version = "2.0.0-rc3", path = "runtime" } [build-dependencies] -substrate-build-script-utils = "2.0.0-rc3" +substrate-build-script-utils = "2.0.0-rc4" diff --git a/test-node/runtime/Cargo.toml b/test-node/runtime/Cargo.toml index f5c3a9e6fcf..90767f8b082 100644 --- a/test-node/runtime/Cargo.toml +++ b/test-node/runtime/Cargo.toml @@ -13,32 +13,32 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } -aura = { version = "2.0.0-rc3", default-features = false, package = "pallet-aura" } -balances = { version = "2.0.0-rc3", default-features = false, package = "pallet-balances" } -frame-support = { version = "2.0.0-rc3", default-features = false } -grandpa = { version = "2.0.0-rc3", default-features = false, package = "pallet-grandpa" } -randomness-collective-flip = { version = "2.0.0-rc3", default-features = false, package = "pallet-randomness-collective-flip" } -sudo = { version = "2.0.0-rc3", default-features = false, package = "pallet-sudo" } -system = { version = "2.0.0-rc3", default-features = false, package = "frame-system" } -timestamp = { version = "2.0.0-rc3", default-features = false, package = "pallet-timestamp" } -transaction-payment = { version = "2.0.0-rc3", default-features = false, package = "pallet-transaction-payment" } -frame-executive = { version = "2.0.0-rc3", default-features = false } +aura = { version = "2.0.0-rc4", default-features = false, package = "pallet-aura" } +balances = { version = "2.0.0-rc4", default-features = false, package = "pallet-balances" } +frame-support = { version = "2.0.0-rc4", default-features = false, package = "frame-support" } +grandpa = { version = "2.0.0-rc4", default-features = false, package = "pallet-grandpa" } +randomness-collective-flip = { version = "2.0.0-rc4", default-features = false, package = "pallet-randomness-collective-flip" } +sudo = { version = "2.0.0-rc4", default-features = false, package = "pallet-sudo" } +system = { version = "2.0.0-rc4", default-features = false, package = "frame-system" } +timestamp = { version = "2.0.0-rc4", default-features = false, package = "pallet-timestamp" } +transaction-payment = { version = "2.0.0-rc4", default-features = false, package = "pallet-transaction-payment" } +frame-executive = { version = "2.0.0-rc4", default-features = false } serde = { version = "1.0.114", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-rc3", default-features = false } -sp-block-builder = { default-features = false, version = "2.0.0-rc3" } -sp-consensus-aura = { version = "0.8.0-rc3", default-features = false } -sp-core = { version = "2.0.0-rc3", default-features = false } -sp-inherents = { default-features = false, version = "2.0.0-rc3" } -sp-io = { version = "2.0.0-rc3", default-features = false } -sp-offchain = { version = "2.0.0-rc3", default-features = false } -sp-runtime = { version = "2.0.0-rc3", default-features = false } -sp-session = { version = "2.0.0-rc3", default-features = false } -sp-std = { version = "2.0.0-rc3", default-features = false } -sp-transaction-pool = { version = "2.0.0-rc3", default-features = false } -sp-version = { version = "2.0.0-rc3", default-features = false } +sp-api = { version = "2.0.0-rc4", default-features = false } +sp-block-builder = { default-features = false, version = "2.0.0-rc4" } +sp-consensus-aura = { version = "0.8.0-rc4", default-features = false } +sp-core = { version = "2.0.0-rc4", default-features = false, package = "sp-core" } +sp-inherents = { default-features = false, version = "2.0.0-rc4" } +sp-io = { version = "2.0.0-rc4", default-features = false } +sp-offchain = { version = "2.0.0-rc4", default-features = false } +sp-runtime = { version = "2.0.0-rc4", default-features = false, package = "sp-runtime" } +sp-session = { version = "2.0.0-rc4", default-features = false } +sp-std = { version = "2.0.0-rc4", default-features = false } +sp-transaction-pool = { version = "2.0.0-rc4", default-features = false, package = "sp-transaction-pool" } +sp-version = { version = "2.0.0-rc4", default-features = false, package = "sp-version" } [build-dependencies] -wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner" } +wasm-builder-runner = { version = "1.0.6", package = "substrate-wasm-builder-runner" } [features] default = ["std"] diff --git a/test-node/src/service.rs b/test-node/src/service.rs index 599f149f660..abeb2c8e3a8 100644 --- a/test-node/src/service.rs +++ b/test-node/src/service.rs @@ -145,7 +145,7 @@ pub fn new_full(config: Configuration) -> Result>; Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _) })? - .build()?; + .build_light()?; if role.is_authority() { let proposer = sc_basic_authorship::ProposerFactory::new( @@ -177,13 +177,13 @@ pub fn new_full(config: Configuration) -> Result Result Result>; Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _) })? - .build() + .build_light() } From ff8e37f1d167caf08f03e7b8df8bc312c239ddad Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Tue, 30 Jun 2020 10:36:25 -0400 Subject: [PATCH 38/80] Remove last reference to Kusama feature --- src/runtimes.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/runtimes.rs b/src/runtimes.rs index 72e6f5b4e3a..386b6c953e7 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -280,7 +280,6 @@ impl Staking for KusamaRuntime { type RewardPoint = u32; } -#[cfg(feature = "kusama")] impl Balances for KusamaRuntime { type Balance = u128; } From 6bf960f55f545c5aae8071d5fb1a1893ae25b858 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 7 Aug 2020 21:44:41 -0400 Subject: [PATCH 39/80] Fix compilation errors --- Cargo.toml | 52 +++++++------------------------------------- src/frame/session.rs | 2 +- 2 files changed, 9 insertions(+), 45 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b8e426a6e72..5c71954316a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ client = ["substrate-subxt-client"] [dependencies] log = "0.4.11" thiserror = "1.0.20" -futures = { version = "0.3.5", package = "futures" } +futures = "0.3.5" jsonrpsee = { version = "0.1.0", features = ["ws"] } num-traits = { version = "0.2.12", default-features = false } serde = { version = "1.0.114", features = ["derive"] } @@ -38,24 +38,14 @@ sp-runtime = { version = "2.0.0-rc5", package = "sp-runtime" } sp-version = { version = "2.0.0-rc5", package = "sp-version" } pallet-indices = { version = "2.0.0-rc5", package = "pallet-indices" } hex = "0.4.2" -<<<<<<< HEAD -sp-rpc = { version = "2.0.0-rc4", package = "sp-rpc" } -sp-core = { version = "2.0.0-rc4", package = "sp-core" } -sc-rpc-api = { version = "0.8.0-rc4", package = "sc-rpc-api" } -sp-transaction-pool = { version = "2.0.0-rc4", package = "sp-transaction-pool" } -substrate-subxt-client = { version = "0.2.0", path = "client", optional = true } -substrate-subxt-proc-macro = { version = "0.9.0", path = "proc-macro" } -sp-std = "2.0.0-rc4" -application-crypto = { version = "2.0.0-rc4", package = "sp-application-crypto", default-features = false } -sp-finality-grandpa = "2.0.0-rc4" -sp-consensus-babe = "0.8.0-rc4" -pallet-im-online = "2.0.0-rc4" -sp-authority-discovery = "2.0.0-rc4" -pallet-staking = "2.0.0-rc4" +sp-std = "2.0.0-rc5" +application-crypto = { version = "2.0.0-rc5", package = "sp-application-crypto", default-features = false } +sp-finality-grandpa = "2.0.0-rc5" +sp-consensus-babe = "0.8.0-rc5" +pallet-im-online = "2.0.0-rc5" +sp-authority-discovery = "2.0.0-rc5" +pallet-staking = "2.0.0-rc5" -[dev-dependencies] -async-std = { version = "1.5.0", features = ["attributes"] } -======= sp-rpc = { version = "2.0.0-rc5", package = "sp-rpc" } sp-core = { version = "2.0.0-rc5", package = "sp-core" } sc-rpc-api = { version = "0.8.0-rc5", package = "sc-rpc-api" } @@ -65,7 +55,6 @@ substrate-subxt-proc-macro = { version = "0.11.0", path = "proc-macro" } [dev-dependencies] async-std = { version = "1.6.2", features = ["attributes"] } ->>>>>>> master env_logger = "0.7.1" frame-system = { version = "2.0.0-rc5", package = "frame-system" } pallet-balances = { version = "2.0.0-rc5", package = "pallet-balances" } @@ -73,29 +62,4 @@ sp-keyring = { version = "2.0.0-rc5", package = "sp-keyring" } substrate-subxt-client = { version = "0.3.0", path = "client" } tempdir = "0.3.7" test-node = { path = "test-node" } -<<<<<<< HEAD - -[patch.crates-io] -frame-metadata = { git = "https://github.com/paritytech/substrate", package = "frame-metadata" } -frame-support = { git = "https://github.com/paritytech/substrate", package = "frame-support" } -sp-runtime = { git = "https://github.com/paritytech/substrate", package = "sp-runtime" } -sp-version = { git = "https://github.com/paritytech/substrate", package = "sp-version" } -pallet-indices = { git = "https://github.com/paritytech/substrate", package = "pallet-indices" } -sp-rpc = { git = "https://github.com/paritytech/substrate", package = "sp-rpc" } -sp-core = { git = "https://github.com/paritytech/substrate", package = "sp-core" } -sc-rpc-api = { git = "https://github.com/paritytech/substrate", package = "sc-rpc-api" } -sp-transaction-pool = { git = "https://github.com/paritytech/substrate", package = "sp-transaction-pool" } -sp-std = { git = "https://github.com/paritytech/substrate" } -application-crypto = { git = "https://github.com/paritytech/substrate", package = "sp-application-crypto", default-features = false } -sp-finality-grandpa = { git = "https://github.com/paritytech/substrate" } -sp-consensus-babe = { git = "https://github.com/paritytech/substrate" } -pallet-im-online = { git = "https://github.com/paritytech/substrate" } -sp-authority-discovery = { git = "https://github.com/paritytech/substrate" } -pallet-staking = { git = "https://github.com/paritytech/substrate" } -sc-service = { git = "https://github.com/paritytech/substrate" } -sc-cli = { git = "https://github.com/paritytech/substrate" } -sc-transaction-pool = { git = "https://github.com/paritytech/substrate" } -jsonrpsee = { git = "https://github.com/paritytech/jsonrpsee" } -======= wabt = "0.10.0" ->>>>>>> master diff --git a/src/frame/session.rs b/src/frame/session.rs index b352a911634..4f7b90af6fa 100644 --- a/src/frame/session.rs +++ b/src/frame/session.rs @@ -107,7 +107,7 @@ mod tests { env_logger::try_init().ok(); let (client, _) = test_client().await; assert!(client - .fetch(QueuedChangedStore::default(), None) + .fetch(&QueuedChangedStore::default(), None) .await .unwrap() .unwrap()); From 528b218ef2a5afe396cfd919ba2c2335133c45b5 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 7 Aug 2020 21:44:51 -0400 Subject: [PATCH 40/80] Implement the `concat` in `twox_64_concat` --- src/metadata.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/metadata.rs b/src/metadata.rs index bbaf478d8ab..3ef160cfc93 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -274,7 +274,13 @@ impl StorageMetadata { StorageHasher::Blake2_256 => sp_core::blake2_256(bytes).to_vec(), StorageHasher::Twox128 => sp_core::twox_128(bytes).to_vec(), StorageHasher::Twox256 => sp_core::twox_256(bytes).to_vec(), - StorageHasher::Twox64Concat => sp_core::twox_64(bytes).to_vec(), + StorageHasher::Twox64Concat => { + sp_core::twox_64(bytes) + .iter() + .chain(bytes) + .cloned() + .collect() + } } } From da3667572b1f3a453f54bb52fd555d588a852d2f Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Tue, 11 Aug 2020 21:24:46 -0400 Subject: [PATCH 41/80] Expose properties and per-era preferences --- src/frame/staking.rs | 21 +++++++++++++++++++-- src/lib.rs | 15 +++++++++++++-- src/rpc.rs | 20 ++++++++++++++++++++ src/runtimes.rs | 1 - 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 56ab8ca2109..1830d70564e 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -38,6 +38,11 @@ use std::{ marker::PhantomData, }; +pub use pallet_staking::{ + EraIndex, + StakingLedger, +}; + /// A record of the nominations made by a specific account. #[derive(PartialEq, Eq, Clone, Encode, Decode, Debug, Ord, PartialOrd, Hash)] pub struct Nominations { @@ -51,6 +56,20 @@ pub struct Nominations { pub suppressed: bool, } +/// Similar to `ErasStakers`, this holds the preferences of validators. +/// +/// This is keyed first by the era index to allow bulk deletion and then the stash account. +/// +/// Is it removed after `HISTORY_DEPTH` eras. +#[derive(Encode, Decode, Debug, Store)] +pub struct ErasValidatorPrefsStore { + #[store(returns = ValidatorPrefs)] + /// Era index + index: EraIndex, + /// Account ID + account_id: T::AccountId, +} + /// Information regarding the active era (era in used in session). #[derive(Encode, Decode, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct ActiveEraInfo { @@ -161,8 +180,6 @@ pub struct UnlockChunk { pub era: T::EraIndex, } -pub use pallet_staking::StakingLedger; - /// Number of eras to keep in history. /// /// Information is kept for eras in `[current_era - history_depth; current_era]`. diff --git a/src/lib.rs b/src/lib.rs index b790083cd8a..f2ffac15072 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,7 +35,8 @@ while_true, trivial_casts, trivial_numeric_casts, - unused_extern_crates + unused_extern_crates, + clippy::all )] #![allow(clippy::type_complexity)] @@ -93,6 +94,7 @@ pub use crate::{ rpc::{ BlockNumber, ExtrinsicSuccess, + Properties, }, runtimes::*, subscription::*, @@ -161,16 +163,18 @@ impl ClientBuilder { } }; let rpc = Rpc::new(client); - let (metadata, genesis_hash, runtime_version) = future::join3( + let (metadata, genesis_hash, runtime_version, properties) = future::join4( rpc.metadata(), rpc.genesis_hash(), rpc.runtime_version(None), + rpc.properties(), ) .await; Ok(Client { rpc, genesis_hash: genesis_hash?, metadata: metadata?, + properties: properties?, runtime_version: runtime_version?, _marker: PhantomData, page_size: self.page_size.unwrap_or(10), @@ -183,6 +187,7 @@ pub struct Client { rpc: Rpc, genesis_hash: T::Hash, metadata: Metadata, + properties: Properties, runtime_version: RuntimeVersion, _marker: PhantomData<(fn() -> T::Signature, T::Extra)>, page_size: u32, @@ -194,6 +199,7 @@ impl Clone for Client { rpc: self.rpc.clone(), genesis_hash: self.genesis_hash, metadata: self.metadata.clone(), + properties: self.properties.clone(), runtime_version: self.runtime_version.clone(), _marker: PhantomData, page_size: self.page_size, @@ -258,6 +264,11 @@ impl Client { &self.metadata } + /// Returns the system properties + pub fn properties(&self) -> &Properties { + &self.properties + } + /// Fetch a StorageKey with an optional block hash. pub async fn fetch>( &self, diff --git a/src/rpc.rs b/src/rpc.rs index dd2aeff40e7..a29582abd05 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -96,6 +96,18 @@ impl From for BlockNumber { } } +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +/// System properties for a Substrate-based runtime +pub struct Properties { + /// The address format + pub ss58_format: u8, + /// The number of digits after the decimal point in the native token + pub token_decimals: u8, + /// The symbol of the native token + pub token_symbol: String, +} + /// Client for substrate rpc interfaces pub struct Rpc { client: Client, @@ -208,6 +220,14 @@ impl Rpc { Ok(metadata) } + /// Fetch system properties + pub async fn properties(&self) -> Result { + Ok(self + .client + .request("system_properties", Params::None) + .await?) + } + /// Get a header pub async fn header( &self, diff --git a/src/runtimes.rs b/src/runtimes.rs index a51a331a8c1..f2064ac4e5f 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -127,7 +127,6 @@ use crate::{ session::Session, staking::Staking, system::System, - Encoded, }; /// Runtime trait. From d5b11382d0b261e75464bbd9a75cd267e2d56a5b Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Wed, 12 Aug 2020 14:59:15 -0400 Subject: [PATCH 42/80] Era rewards point support I also did some refactoring. --- src/frame/staking.rs | 94 ++++++++++++-------------------------------- 1 file changed, 25 insertions(+), 69 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 1830d70564e..ea9ee1a2412 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -25,37 +25,28 @@ use codec::{ Encode, }; use frame_support::Parameter; -use sp_runtime::{ - traits::{ - AtLeast32Bit, - MaybeSerialize, - Member, - }, - Perbill, +use sp_runtime::traits::{ + AtLeast32Bit, + MaybeSerialize, + Member, }; + use std::{ fmt::Debug, marker::PhantomData, }; pub use pallet_staking::{ + ActiveEraInfo, EraIndex, + EraRewardPoints, + Nominations, + RewardDestination, + RewardPoint, StakingLedger, + ValidatorPrefs, }; -/// A record of the nominations made by a specific account. -#[derive(PartialEq, Eq, Clone, Encode, Decode, Debug, Ord, PartialOrd, Hash)] -pub struct Nominations { - /// The targets of nomination. - pub targets: Vec, - /// The era the nominations were submitted. - /// - /// Except for initial nominations which are considered submitted at era 0. - pub submitted_in: T::EraIndex, - /// Whether the nominations have been suppressed. - pub suppressed: bool, -} - /// Similar to `ErasStakers`, this holds the preferences of validators. /// /// This is keyed first by the era index to allow bulk deletion and then the stash account. @@ -70,31 +61,17 @@ pub struct ErasValidatorPrefsStore { account_id: T::AccountId, } -/// Information regarding the active era (era in used in session). -#[derive(Encode, Decode, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] -pub struct ActiveEraInfo { - /// Index of era. - pub index: T::EraIndex, - /// Moment of start expresed as millisecond from `$UNIX_EPOCH`. - /// - /// Start can be none if start hasn't been set for the era yet, - /// Start is set on the first on_finalize of the era to guarantee usage of `Time`. - pub start: Option, -} - -/// A destination account for payment. -#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Debug)] -pub enum RewardDestination { - /// Pay into the stash account, increasing the amount at stake accordingly. - Staked, - /// Pay into the stash account, not increasing the amount at stake. - Stash, - /// Pay into the controller account. - Controller, +/// Rewards for the last `HISTORY_DEPTH` eras. +/// If reward hasn't been set or has been removed then 0 reward is returned. +#[derive(Clone, Encode, Decode, Debug, Store)] +pub struct ErasRewardPoints { + #[store(returns = EraRewardPoints)] + index: EraIndex, + _phantom: PhantomData, } /// Preference of what happens regarding validation. -#[derive(PartialEq, Eq, Clone, Encode, Decode, Debug, Call)] +#[derive(Clone, Encode, Decode, Debug, Call)] pub struct SetPayeeCall { /// The payee pub payee: RewardDestination, @@ -102,23 +79,6 @@ pub struct SetPayeeCall { pub _runtime: PhantomData, } -/// Preference of what happens regarding validation. -#[derive(PartialEq, Eq, Clone, Encode, Decode, Debug)] -pub struct ValidatorPrefs { - /// Reward that validator takes up-front; only the rest is split between themselves and - /// nominators. - #[codec(compact)] - pub commission: Perbill, -} - -impl Default for ValidatorPrefs { - fn default() -> Self { - ValidatorPrefs { - commission: Default::default(), - } - } -} - /// The subset of the `frame::Trait` that a client must implement. #[module] pub trait Staking: Balances { @@ -170,7 +130,7 @@ pub trait Staking: Balances { } /// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. -#[derive(PartialEq, Eq, Clone, Encode, Decode, Ord, PartialOrd, Hash, Debug)] +#[derive(Clone, Encode, Decode, Debug)] pub struct UnlockChunk { /// Amount of funds to be unlocked. #[codec(compact)] @@ -187,9 +147,7 @@ pub struct UnlockChunk { /// Must be more than the number of eras delayed by session otherwise. /// I.e. active era must always be in history. /// I.e. `active_era > current_era - history_depth` must be guaranteed. -#[derive( - Encode, Decode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store, -)] +#[derive(Encode, Decode, Copy, Clone, Debug, Default, Store)] pub struct HistoryDepthStore { #[store(returns = u32)] /// Marker for the runtime @@ -197,9 +155,7 @@ pub struct HistoryDepthStore { } /// The ideal number of staking participants. -#[derive( - Encode, Decode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store, -)] +#[derive(Encode, Decode, Copy, Clone, Debug, Store)] pub struct ValidatorCountStore { #[store(returns = u32)] /// Marker for the runtime @@ -259,9 +215,9 @@ pub struct ValidatorsStore { } /// The map from nominator stash key to the set of stash keys of all validators to nominate. -#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] +#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Store)] pub struct NominatorsStore { - #[store(returns = Option>)] + #[store(returns = Option>)] /// Tٗhe stash account pub stash: T::AccountId, } @@ -283,7 +239,7 @@ pub struct CurrentEraStore { /// Validator set of this era must be equal to `SessionInterface::validators`. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct ActiveEraStore { - #[store(returns = Option>)] + #[store(returns = Option)] /// Marker for the runtime pub _runtime: PhantomData, } From 28533f68d41cf6d8aae8dc71496d9d8c5d72f382 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Wed, 12 Aug 2020 17:39:45 -0400 Subject: [PATCH 43/80] Expose clipped exposure --- src/frame/staking.rs | 48 +++++++++++++++++++++----------------------- src/runtimes.rs | 4 ---- 2 files changed, 23 insertions(+), 29 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index ea9ee1a2412..d0ec9398af6 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -26,7 +26,6 @@ use codec::{ }; use frame_support::Parameter; use sp_runtime::traits::{ - AtLeast32Bit, MaybeSerialize, Member, }; @@ -40,6 +39,7 @@ pub use pallet_staking::{ ActiveEraInfo, EraIndex, EraRewardPoints, + Exposure, Nominations, RewardDestination, RewardPoint, @@ -107,26 +107,6 @@ pub trait Staking: Balances { /// Maximum number of nominators that can be stored in a snapshot. const MAX_NOMINATORS: usize; - - /// Counter for the number of eras that have passed. - type EraIndex: Parameter - + Member - + AtLeast32Bit - + codec::Codec - + Default - + Copy - + MaybeSerialize - + Debug; - - /// Counter for the number of "reward" points earned by a given validator. - type RewardPoint: Parameter - + Member - + AtLeast32Bit - + codec::Codec - + Default - + Copy - + MaybeSerialize - + Debug; } /// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. @@ -137,7 +117,7 @@ pub struct UnlockChunk { pub value: T::Balance, /// Era number at which point it'll be unlocked. #[codec(compact)] - pub era: T::EraIndex, + pub era: EraIndex, } /// Number of eras to keep in history. @@ -226,13 +206,31 @@ pub struct NominatorsStore { /// /// This is the latest planned era, depending on how the Session pallet queues the validator /// set, it might be active or not. -#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] +#[derive(Encode, Copy, Clone, Debug, Store)] pub struct CurrentEraStore { - #[store(returns = Option)] + #[store(returns = Option)] /// Marker for the runtime pub _runtime: PhantomData, } +/// Clipped Exposure of validator at era. +/// +/// This is similar to [`ErasStakers`] but number of nominators exposed is reduced to the +/// `T::MaxNominatorRewardedPerValidator` biggest stakers. +/// (Note: the field `total` and `own` of the exposure remains unchanged). +/// This is used to limit the i/o cost for the nominator payout. +/// +/// This is keyed fist by the era index to allow bulk deletion and then the stash account. +/// +/// Is it removed after `HISTORY_DEPTH` eras. +/// If stakers hasn't been set or has been removed then empty exposure is returned. +#[derive(Encode, Copy, Clone, Debug, Store)] +pub struct ErasStakersClippedStore { + #[store(returns = Exposure)] + era: EraIndex, + validator_stash: T::AccountId, +} + /// The active era information, it holds index and start. /// /// The active era is the era currently rewarded. @@ -298,5 +296,5 @@ pub struct NominateCall { #[derive(PartialEq, Eq, Clone, Call, Encode, Decode, Debug)] struct PayoutStakersCall<'a, T: Staking> { pub validator_stash: &'a T::AccountId, - pub era: T::EraIndex, + pub era: EraIndex, } diff --git a/src/runtimes.rs b/src/runtimes.rs index f2064ac4e5f..b38bee0dbe6 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -151,8 +151,6 @@ impl Staking for DefaultNodeRuntime { type ValidatorIndex = u16; const MAX_VALIDATORS: usize = Self::ValidatorIndex::max_value() as usize; const MAX_NOMINATORS: usize = Self::NominatorIndex::max_value() as usize; - type EraIndex = u32; - type RewardPoint = u32; } impl Runtime for DefaultNodeRuntime { @@ -261,8 +259,6 @@ impl Staking for KusamaRuntime { type ValidatorIndex = u16; const MAX_VALIDATORS: usize = Self::ValidatorIndex::max_value() as usize; const MAX_NOMINATORS: usize = Self::NominatorIndex::max_value() as usize; - type EraIndex = u32; - type RewardPoint = u32; } impl Balances for KusamaRuntime { From c330e687b1a9c54a21bdc16e30a84efe1cbbd74b Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 13 Aug 2020 11:54:44 -0400 Subject: [PATCH 44/80] Era reward points support --- src/frame/staking.rs | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index d0ec9398af6..8b155af4bb9 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -31,6 +31,7 @@ use sp_runtime::traits::{ }; use std::{ + collections::BTreeMap, fmt::Debug, marker::PhantomData, }; @@ -38,7 +39,6 @@ use std::{ pub use pallet_staking::{ ActiveEraInfo, EraIndex, - EraRewardPoints, Exposure, Nominations, RewardDestination, @@ -56,18 +56,20 @@ pub use pallet_staking::{ pub struct ErasValidatorPrefsStore { #[store(returns = ValidatorPrefs)] /// Era index - index: EraIndex, + pub index: EraIndex, /// Account ID - account_id: T::AccountId, + pub account_id: T::AccountId, } /// Rewards for the last `HISTORY_DEPTH` eras. /// If reward hasn't been set or has been removed then 0 reward is returned. #[derive(Clone, Encode, Decode, Debug, Store)] -pub struct ErasRewardPoints { +pub struct ErasRewardPointsStore { #[store(returns = EraRewardPoints)] - index: EraIndex, - _phantom: PhantomData, + /// Era index + pub index: EraIndex, + /// Marker for the runtime + pub _phantom: PhantomData, } /// Preference of what happens regarding validation. @@ -213,6 +215,17 @@ pub struct CurrentEraStore { pub _runtime: PhantomData, } +/// Reward points of an era. Used to split era total payout between validators. +/// +/// This points will be used to reward validators and their respective nominators. +#[derive(PartialEq, Encode, Decode, Default, Debug)] +pub struct EraRewardPoints { + /// Total number of points. Equals the sum of reward points for each validator. + pub total: RewardPoint, + /// The reward points earned by a given validator. + pub individual: BTreeMap, +} + /// Clipped Exposure of validator at era. /// /// This is similar to [`ErasStakers`] but number of nominators exposed is reduced to the @@ -227,8 +240,10 @@ pub struct CurrentEraStore { #[derive(Encode, Copy, Clone, Debug, Store)] pub struct ErasStakersClippedStore { #[store(returns = Exposure)] - era: EraIndex, - validator_stash: T::AccountId, + /// Era index + pub era: EraIndex, + /// Stash account of the validator + pub validator_stash: T::AccountId, } /// The active era information, it holds index and start. From 59decaf5752e1925ee1916e7a01445319ccc2082 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Mon, 17 Aug 2020 13:49:35 -0400 Subject: [PATCH 45/80] Make `PayoutStakersCall` public --- src/frame/staking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 8b155af4bb9..63731d00350 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -309,7 +309,7 @@ pub struct NominateCall { /// Claim a payout. #[derive(PartialEq, Eq, Clone, Call, Encode, Decode, Debug)] -struct PayoutStakersCall<'a, T: Staking> { +pub struct PayoutStakersCall<'a, T: Staking> { pub validator_stash: &'a T::AccountId, pub era: EraIndex, } From b03b28b9f051b7779982ecf44ec7ea379dbcaa3e Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 28 Aug 2020 14:28:33 -0400 Subject: [PATCH 46/80] Add in all default features for debugging --- Cargo.toml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4ecfdf1b760..a7aa62f734d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,11 +26,11 @@ log = "0.4.11" thiserror = "1.0.20" futures = "0.3.5" jsonrpsee = { version = "0.1.0", features = ["ws"] } -num-traits = { version = "0.2.12", default-features = false } +num-traits = { version = "0.2.12" } serde = { version = "1.0.115", features = ["derive"] } serde_json = "1.0.57" url = "2.1.1" -codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive", "full"] } +codec = { package = "parity-scale-codec", version = "1.3.4", features = ["derive", "full"] } frame-metadata = { version = "11.0.0-rc6", package = "frame-metadata" } frame-support = { version = "2.0.0-rc6", package = "frame-support" } @@ -39,12 +39,12 @@ sp-version = { version = "2.0.0-rc6", package = "sp-version" } pallet-indices = { version = "2.0.0-rc6", package = "pallet-indices" } hex = "0.4.2" sp-std = "2.0.0-rc6" -application-crypto = { version = "2.0.0-rc6", package = "sp-application-crypto", default-features = false } -sp-finality-grandpa = { version = "2.0.0-rc6", default-features = false } +application-crypto = { version = "2.0.0-rc6", package = "sp-application-crypto" } +sp-finality-grandpa = { version = "2.0.0-rc6" } sp-consensus-babe = "0.8.0-rc6" -pallet-im-online = { version = "2.0.0-rc6", default-features = false } -sp-authority-discovery = { version = "2.0.0-rc6", default-features = false } -pallet-staking = { version = "2.0.0-rc6", default-features = false } +pallet-im-online = { version = "2.0.0-rc6" } +sp-authority-discovery = { version = "2.0.0-rc6" } +pallet-staking = { version = "2.0.0-rc6" } sp-rpc = { version = "2.0.0-rc6", package = "sp-rpc" } sp-core = { version = "2.0.0-rc6", package = "sp-core" } From 274412745b5619c3dfd4fe9ef699522aeca77b83 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Mon, 31 Aug 2020 15:21:16 -0400 Subject: [PATCH 47/80] Chill support and update to latest Substrate --- Cargo.toml | 18 +++++++++++++++++ src/frame/staking.rs | 47 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a7aa62f734d..fb9adb372e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,3 +63,21 @@ substrate-subxt-client = { version = "0.3.0", path = "client" } tempdir = "0.3.7" test-node = { path = "test-node" } wabt = "0.10.0" + +[patch.crates-io] +frame-metadata = { git = "https://github.com/paritytech/substrate" } +frame-support = { git = "https://github.com/paritytech/substrate" } +sp-runtime = { git = "https://github.com/paritytech/substrate" } +sp-version = { git = "https://github.com/paritytech/substrate" } +pallet-indices = { git = "https://github.com/paritytech/substrate" } +sp-rpc = { git = "https://github.com/paritytech/substrate" } +sp-core = { git = "https://github.com/paritytech/substrate" } +sc-rpc-api = { git = "https://github.com/paritytech/substrate" } +sp-transaction-pool = { git = "https://github.com/paritytech/substrate" } +sp-std = { git = "https://github.com/paritytech/substrate" } +application-crypto = { git = "https://github.com/paritytech/substrate", package = "sp-application-crypto", default-features = false } +sp-finality-grandpa = { git = "https://github.com/paritytech/substrate" } +sp-consensus-babe = { git = "https://github.com/paritytech/substrate" } +pallet-im-online = { git = "https://github.com/paritytech/substrate" } +sp-authority-discovery = { git = "https://github.com/paritytech/substrate" } +pallet-staking = { git = "https://github.com/paritytech/substrate" } diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 8df4bc74911..25a4d4e7cfe 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -76,7 +76,7 @@ pub struct ErasRewardPointsStore { #[derive(Clone, Encode, Decode, Debug, Call)] pub struct SetPayeeCall { /// The payee - pub payee: RewardDestination, + pub payee: RewardDestination, /// Marker for the runtime pub _runtime: PhantomData, } @@ -183,7 +183,7 @@ pub struct LedgerStore { /// Where the reward payment should be made. Keyed by stash. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct PayeeStore { - #[store(returns = RewardDestination)] + #[store(returns = RewardDestination)] /// Tٗhe stash account pub stash: T::AccountId, } @@ -257,6 +257,45 @@ pub struct ActiveEraStore { pub _runtime: PhantomData, } +/// Declare no desire to either validate or nominate. +/// +/// Effects will be felt at the beginning of the next era. +/// +/// The dispatch origin for this call must be _Signed_ by the controller, not the stash. +/// And, it can be only called when [`EraElectionStatus`] is `Closed`. +/// +/// # +/// - Independent of the arguments. Insignificant complexity. +/// - Contains one read. +/// - Writes are limited to the `origin` account key. +/// -------- +/// Base Weight: 16.53 µs +/// DB Weight: +/// - Read: EraElectionStatus, Ledger +/// - Write: Validators, Nominators +/// # +#[derive(Debug, Call, Encode)] +pub struct ChillCall { + /// Runtime marker + pub _runtime: PhantomData, +} + +impl Default for ChillCall { + fn default() -> Self { + Self { + _runtime: PhantomData, + } + } +} +impl Clone for ChillCall { + fn clone(&self) -> Self { + Self { + _runtime: self._runtime, + } + } +} +impl Copy for ChillCall {} + /// Declare the desire to validate for the origin controller. /// /// Effects will be felt at the beginning of the next era. @@ -276,9 +315,9 @@ pub struct ActiveEraStore { /// # #[derive(Clone, Debug, PartialEq, Call, Encode)] pub struct ValidateCall { - /// Runtime marker. + /// Runtime marker pub _runtime: PhantomData, - /// Validation preferences. + /// Validation preferences pub prefs: ValidatorPrefs, } From 3efe16f2ff4ad7924b33b5982448313a55e6bc79 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sun, 6 Sep 2020 18:12:25 -0400 Subject: [PATCH 48/80] If property fetch fails, use dummy values --- src/lib.rs | 2 +- src/rpc.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a4cc5949ac4..49600f09b08 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -174,7 +174,7 @@ impl ClientBuilder { rpc, genesis_hash: genesis_hash?, metadata: metadata?, - properties: properties?, + properties: properties.unwrap_or_else(|_| Default::default()), runtime_version: runtime_version?, _marker: PhantomData, page_size: self.page_size.unwrap_or(10), diff --git a/src/rpc.rs b/src/rpc.rs index a29582abd05..969a9777825 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -96,7 +96,7 @@ impl From for BlockNumber { } } -#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, Default)] #[serde(rename_all = "camelCase")] /// System properties for a Substrate-based runtime pub struct Properties { From d3865a613e1f0ab6317ea3b79614933b27de754c Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 11 Sep 2020 15:40:45 -0400 Subject: [PATCH 49/80] Fix tests --- Cargo.toml | 46 ++++++++++++++++---------------- src/frame/session.rs | 19 +++++++------ src/frame/staking.rs | 63 ++++++++++---------------------------------- src/lib.rs | 8 +++--- src/rpc.rs | 4 +-- 5 files changed, 54 insertions(+), 86 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 99e19dee938..aaca8753be8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,11 +26,11 @@ log = "0.4.11" thiserror = "1.0.20" futures = "0.3.5" jsonrpsee = { version = "0.1.0", features = ["ws"] } -num-traits = { version = "0.2.12" } +num-traits = "0.2.12" serde = { version = "1.0.115", features = ["derive"] } serde_json = "1.0.57" url = "2.1.1" -codec = { package = "parity-scale-codec", version = "1.3.4", features = ["derive", "full"] } +codec = { package = "parity-scale-codec", version = "1.3.5", features = ["derive", "full"] } frame-metadata = { version = "11.0.0-rc6", package = "frame-metadata" } frame-support = { version = "2.0.0-rc6", package = "frame-support" } @@ -40,11 +40,11 @@ pallet-indices = { version = "2.0.0-rc6", package = "pallet-indices" } hex = "0.4.2" sp-std = "2.0.0-rc6" application-crypto = { version = "2.0.0-rc6", package = "sp-application-crypto" } -sp-finality-grandpa = { version = "2.0.0-rc6" } +sp-finality-grandpa = "2.0.0-rc6" sp-consensus-babe = "0.8.0-rc6" -pallet-im-online = { version = "2.0.0-rc6" } -sp-authority-discovery = { version = "2.0.0-rc6" } -pallet-staking = { version = "2.0.0-rc6" } +pallet-im-online = "2.0.0-rc6" +sp-authority-discovery = "2.0.0-rc6" +pallet-staking = "2.0.0-rc6" sp-rpc = { version = "2.0.0-rc6", package = "sp-rpc" } sp-core = { version = "2.0.0-rc6", package = "sp-core" } @@ -64,20 +64,20 @@ tempdir = "0.3.7" test-node = { path = "test-node" } wabt = "0.10.0" -[patch.crates-io] -frame-metadata = { git = "https://github.com/paritytech/substrate" } -frame-support = { git = "https://github.com/paritytech/substrate" } -sp-runtime = { git = "https://github.com/paritytech/substrate" } -sp-version = { git = "https://github.com/paritytech/substrate" } -pallet-indices = { git = "https://github.com/paritytech/substrate" } -sp-rpc = { git = "https://github.com/paritytech/substrate" } -sp-core = { git = "https://github.com/paritytech/substrate" } -sc-rpc-api = { git = "https://github.com/paritytech/substrate" } -sp-transaction-pool = { git = "https://github.com/paritytech/substrate" } -sp-std = { git = "https://github.com/paritytech/substrate" } -application-crypto = { git = "https://github.com/paritytech/substrate", package = "sp-application-crypto", default-features = false } -sp-finality-grandpa = { git = "https://github.com/paritytech/substrate" } -sp-consensus-babe = { git = "https://github.com/paritytech/substrate" } -pallet-im-online = { git = "https://github.com/paritytech/substrate" } -sp-authority-discovery = { git = "https://github.com/paritytech/substrate" } -pallet-staking = { git = "https://github.com/paritytech/substrate" } +# [patch.crates-io] +# frame-metadata = { git = "https://github.com/paritytech/substrate" } +# frame-support = { git = "https://github.com/paritytech/substrate" } +# sp-runtime = { git = "https://github.com/paritytech/substrate" } +# sp-version = { git = "https://github.com/paritytech/substrate" } +# pallet-indices = { git = "https://github.com/paritytech/substrate" } +# sp-rpc = { git = "https://github.com/paritytech/substrate" } +# sp-core = { git = "https://github.com/paritytech/substrate" } +# sc-rpc-api = { git = "https://github.com/paritytech/substrate" } +# sp-transaction-pool = { git = "https://github.com/paritytech/substrate" } +# sp-std = { git = "https://github.com/paritytech/substrate" } +# application-crypto = { git = "https://github.com/paritytech/substrate", package = "sp-application-crypto", default-features = false } +# sp-finality-grandpa = { git = "https://github.com/paritytech/substrate" } +# sp-consensus-babe = { git = "https://github.com/paritytech/substrate" } +# pallet-im-online = { git = "https://github.com/paritytech/substrate" } +# sp-authority-discovery = { git = "https://github.com/paritytech/substrate" } +# pallet-staking = { git = "https://github.com/paritytech/substrate" } diff --git a/src/frame/session.rs b/src/frame/session.rs index 4f7b90af6fa..fca862a9a3c 100644 --- a/src/frame/session.rs +++ b/src/frame/session.rs @@ -1,12 +1,12 @@ // Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of substrate-subxt. // -// subxt is free software: you can redistribute it and/or modify +// substrate-subxt 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. // -// subxt is distributed in the hope that it will be useful, +// substrate-subxt 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. @@ -32,7 +32,9 @@ use std::{ }; use substrate_subxt_proc_macro::Store; -macro_rules! def { +/// Impls `Default::default` for some types that have a `_runtime` field of type +/// `PhantomData` as their only field. +macro_rules! default_impl { ($name:ident) => { impl Default for $name { fn default() -> Self { @@ -50,7 +52,7 @@ pub trait Session: System { /// The validator account identifier type for the runtime. type ValidatorId: Parameter + Debug + Ord + Default + Send + Sync + 'static; - /// The validator account identifier type for the runtime. + /// The session index identifier type for the runtime. type SessionIndex: Parameter + Debug + Ord + Default + Send + Sync + 'static; /// The keys. @@ -65,7 +67,7 @@ pub struct ValidatorsStore { pub _runtime: PhantomData, } -def!(ValidatorsStore); +default_impl!(ValidatorsStore); /// Current index of the session. #[derive(Encode, Store, Debug)] @@ -75,7 +77,7 @@ pub struct CurrentIndexStore { pub _runtime: PhantomData, } -def!(CurrentIndexStore); +default_impl!(CurrentIndexStore); /// True if the underlying economic identities or weighting behind the validators /// has changed in the queued validator set. @@ -86,9 +88,9 @@ pub struct QueuedChangedStore { pub _runtime: PhantomData, } -def!(QueuedChangedStore); +default_impl!(QueuedChangedStore); -/// The current set of validators. +/// Set the session keys for a validator. #[derive(Encode, Call, Debug)] pub struct SetKeysCall { /// The keys @@ -103,6 +105,7 @@ mod tests { use crate::tests::test_client; #[async_std::test] + #[ignore] async fn test_state_read_free_balance() { env_logger::try_init().ok(); let (client, _) = test_client().await; diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 25a4d4e7cfe..d4a6c7b4690 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with substrate-subxt. If not, see . -//! Implements support for the frame_staking module. +//! Implements support for the pallet_staking module. use super::balances::{ Balances, @@ -51,7 +51,7 @@ pub use pallet_staking::{ /// /// This is keyed first by the era index to allow bulk deletion and then the stash account. /// -/// Is it removed after `HISTORY_DEPTH` eras. +/// It is removed after `HISTORY_DEPTH` eras. #[derive(Encode, Decode, Debug, Store)] pub struct ErasValidatorPrefsStore { #[store(returns = ValidatorPrefs)] @@ -76,7 +76,7 @@ pub struct ErasRewardPointsStore { #[derive(Clone, Encode, Decode, Debug, Call)] pub struct SetPayeeCall { /// The payee - pub payee: RewardDestination, + pub payee: RewardDestination, /// Marker for the runtime pub _runtime: PhantomData, } @@ -111,13 +111,13 @@ pub trait Staking: Balances { const MAX_NOMINATORS: usize; } -/// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. +/// A Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. #[derive(Clone, Encode, Decode, Debug)] pub struct UnlockChunk { /// Amount of funds to be unlocked. #[codec(compact)] pub value: T::Balance, - /// Era number at which point it'll be unlocked. + /// Era number at which point the funds will be unlocked. #[codec(compact)] pub era: EraIndex, } @@ -183,7 +183,7 @@ pub struct LedgerStore { /// Where the reward payment should be made. Keyed by stash. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct PayeeStore { - #[store(returns = RewardDestination)] + #[store(returns = RewardDestination)] /// Tٗhe stash account pub stash: T::AccountId, } @@ -235,7 +235,7 @@ pub struct EraRewardPoints { /// /// This is keyed fist by the era index to allow bulk deletion and then the stash account. /// -/// Is it removed after `HISTORY_DEPTH` eras. +/// It is removed after `HISTORY_DEPTH` eras. /// If stakers hasn't been set or has been removed then empty exposure is returned. #[derive(Encode, Copy, Clone, Debug, Store)] pub struct ErasStakersClippedStore { @@ -246,7 +246,7 @@ pub struct ErasStakersClippedStore { pub validator_stash: T::AccountId, } -/// The active era information, it holds index and start. +/// The active era information, holds index and start. /// /// The active era is the era currently rewarded. /// Validator set of this era must be equal to `SessionInterface::validators`. @@ -259,21 +259,10 @@ pub struct ActiveEraStore { /// Declare no desire to either validate or nominate. /// -/// Effects will be felt at the beginning of the next era. +/// Effective at the beginning of the next era. /// /// The dispatch origin for this call must be _Signed_ by the controller, not the stash. -/// And, it can be only called when [`EraElectionStatus`] is `Closed`. -/// -/// # -/// - Independent of the arguments. Insignificant complexity. -/// - Contains one read. -/// - Writes are limited to the `origin` account key. -/// -------- -/// Base Weight: 16.53 µs -/// DB Weight: -/// - Read: EraElectionStatus, Ledger -/// - Write: Validators, Nominators -/// # +/// Can only be called when [`EraElectionStatus`] is `Closed`. #[derive(Debug, Call, Encode)] pub struct ChillCall { /// Runtime marker @@ -298,21 +287,10 @@ impl Copy for ChillCall {} /// Declare the desire to validate for the origin controller. /// -/// Effects will be felt at the beginning of the next era. +/// Effective at the beginning of the next era. /// /// The dispatch origin for this call must be _Signed_ by the controller, not the stash. -/// And, it can be only called when [`EraElectionStatus`] is `Closed`. -/// -/// # -/// - Independent of the arguments. Insignificant complexity. -/// - Contains a limited number of reads. -/// - Writes are limited to the `origin` account key. -/// ----------- -/// Base Weight: 17.13 µs -/// DB Weight: -/// - Read: Era Election Status, Ledger -/// - Write: Nominators, Validators -/// # +/// Can only be called when [`EraElectionStatus`] is `Closed`. #[derive(Clone, Debug, PartialEq, Call, Encode)] pub struct ValidateCall { /// Runtime marker @@ -323,23 +301,10 @@ pub struct ValidateCall { /// Declare the desire to nominate `targets` for the origin controller. /// -/// Effects will be felt at the beginning of the next era. This can only be called when -/// [`EraElectionStatus`] is `Closed`. +/// Effective at the beginning of the next era. /// /// The dispatch origin for this call must be _Signed_ by the controller, not the stash. -/// And, it can be only called when [`EraElectionStatus`] is `Closed`. -/// -/// # -/// - The transaction's complexity is proportional to the size of `targets` (N) -/// which is capped at CompactAssignments::LIMIT (MAX_NOMINATIONS). -/// - Both the reads and writes follow a similar pattern. -/// --------- -/// Base Weight: 22.34 + .36 * N µs -/// where N is the number of targets -/// DB Weight: -/// - Reads: Era Election Status, Ledger, Current Era -/// - Writes: Validators, Nominators -/// # +/// Can only be called when [`EraElectionStatus`] is `Closed`. #[derive(Call, Encode, Debug)] pub struct NominateCall { /// The targets that are being nominated diff --git a/src/lib.rs b/src/lib.rs index 49600f09b08..738420a11d9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -94,7 +94,7 @@ pub use crate::{ rpc::{ BlockNumber, ExtrinsicSuccess, - Properties, + SystemProperties, }, runtimes::*, subscription::*, @@ -167,7 +167,7 @@ impl ClientBuilder { rpc.metadata(), rpc.genesis_hash(), rpc.runtime_version(None), - rpc.properties(), + rpc.system_properties(), ) .await; Ok(Client { @@ -187,7 +187,7 @@ pub struct Client { rpc: Rpc, genesis_hash: T::Hash, metadata: Metadata, - properties: Properties, + properties: SystemProperties, runtime_version: RuntimeVersion, _marker: PhantomData<(fn() -> T::Signature, T::Extra)>, page_size: u32, @@ -265,7 +265,7 @@ impl Client { } /// Returns the system properties - pub fn properties(&self) -> &Properties { + pub fn properties(&self) -> &SystemProperties { &self.properties } diff --git a/src/rpc.rs b/src/rpc.rs index 969a9777825..25ec9c3e0fc 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -99,7 +99,7 @@ impl From for BlockNumber { #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, Default)] #[serde(rename_all = "camelCase")] /// System properties for a Substrate-based runtime -pub struct Properties { +pub struct SystemProperties { /// The address format pub ss58_format: u8, /// The number of digits after the decimal point in the native token @@ -221,7 +221,7 @@ impl Rpc { } /// Fetch system properties - pub async fn properties(&self) -> Result { + pub async fn system_properties(&self) -> Result { Ok(self .client .request("system_properties", Params::None) From 0084f875756e08ae529e9766a4519fec65f1b01f Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 11 Sep 2020 16:20:08 -0400 Subject: [PATCH 50/80] Fix header --- src/frame/session.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/frame/session.rs b/src/frame/session.rs index fca862a9a3c..3640355e772 100644 --- a/src/frame/session.rs +++ b/src/frame/session.rs @@ -1,19 +1,18 @@ // Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of substrate-subxt. // -// substrate-subxt is free software: you can redistribute it and/or modify +// subxt 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-subxt is distributed in the hope that it will be useful, +// subxt 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-subxt. If not, see . -// Copyright 2019-2020 Parity Technologies (UK) Ltd. //! Session support use crate::frame::system::{ From 33f171090970f205fced4cc5ab10852e3b09615b Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 11 Sep 2020 19:37:00 -0400 Subject: [PATCH 51/80] Remove some code Ledgeracio does not need --- src/frame/staking.rs | 59 -------------------------------------------- src/runtimes.rs | 4 --- 2 files changed, 63 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index d4a6c7b4690..b08d5940e02 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -47,20 +47,6 @@ pub use pallet_staking::{ ValidatorPrefs, }; -/// Similar to `ErasStakers`, this holds the preferences of validators. -/// -/// This is keyed first by the era index to allow bulk deletion and then the stash account. -/// -/// It is removed after `HISTORY_DEPTH` eras. -#[derive(Encode, Decode, Debug, Store)] -pub struct ErasValidatorPrefsStore { - #[store(returns = ValidatorPrefs)] - /// Era index - pub index: EraIndex, - /// Account ID - pub account_id: T::AccountId, -} - /// Rewards for the last `HISTORY_DEPTH` eras. /// If reward hasn't been set or has been removed then 0 reward is returned. #[derive(Clone, Encode, Decode, Debug, Store)] @@ -103,23 +89,6 @@ pub trait Staking: Balances { + Copy + MaybeSerialize + Debug; - - /// Maximum number of validators that can be stored in a snapshot. - const MAX_VALIDATORS: usize; - - /// Maximum number of nominators that can be stored in a snapshot. - const MAX_NOMINATORS: usize; -} - -/// A Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. -#[derive(Clone, Encode, Decode, Debug)] -pub struct UnlockChunk { - /// Amount of funds to be unlocked. - #[codec(compact)] - pub value: T::Balance, - /// Era number at which point the funds will be unlocked. - #[codec(compact)] - pub era: EraIndex, } /// Number of eras to keep in history. @@ -136,34 +105,6 @@ pub struct HistoryDepthStore { pub _runtime: PhantomData, } -/// The ideal number of staking participants. -#[derive(Encode, Decode, Copy, Clone, Debug, Store)] -pub struct ValidatorCountStore { - #[store(returns = u32)] - /// Marker for the runtime - pub _runtime: PhantomData, -} - -/// Minimum number of staking participants before emergency conditions are imposed. -#[derive( - Encode, Decode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store, -)] -pub struct MinimumValidatorCountStore { - #[store(returns = u32)] - /// Marker for the runtime - pub _runtime: PhantomData, -} - -/// Any validators that may never be slashed or forcibly kicked. It's a Vec since they're -/// easy to initialize and the performance hit is minimal (we expect no more than four -/// invulnerables) and restricted to testnets. -#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] -pub struct InvulnerablesStore { - #[store(returns = Vec)] - /// Marker for the runtime - pub _runtime: PhantomData, -} - /// Map from all locked "stash" accounts to the controller account. #[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] pub struct BondedStore { diff --git a/src/runtimes.rs b/src/runtimes.rs index b38bee0dbe6..f86096e0d5a 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -149,8 +149,6 @@ pub struct DefaultNodeRuntime; impl Staking for DefaultNodeRuntime { type NominatorIndex = u32; type ValidatorIndex = u16; - const MAX_VALIDATORS: usize = Self::ValidatorIndex::max_value() as usize; - const MAX_NOMINATORS: usize = Self::NominatorIndex::max_value() as usize; } impl Runtime for DefaultNodeRuntime { @@ -257,8 +255,6 @@ impl Session for KusamaRuntime { impl Staking for KusamaRuntime { type NominatorIndex = u32; type ValidatorIndex = u16; - const MAX_VALIDATORS: usize = Self::ValidatorIndex::max_value() as usize; - const MAX_NOMINATORS: usize = Self::NominatorIndex::max_value() as usize; } impl Balances for KusamaRuntime { From 9f34f76d81ca17ee50a31e9f00b74b14e5ffe265 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 11 Sep 2020 19:42:46 -0400 Subject: [PATCH 52/80] More deletions --- src/frame/staking.rs | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index b08d5940e02..5a48d9d9f17 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -167,37 +167,6 @@ pub struct EraRewardPoints { pub individual: BTreeMap, } -/// Clipped Exposure of validator at era. -/// -/// This is similar to [`ErasStakers`] but number of nominators exposed is reduced to the -/// `T::MaxNominatorRewardedPerValidator` biggest stakers. -/// (Note: the field `total` and `own` of the exposure remains unchanged). -/// This is used to limit the i/o cost for the nominator payout. -/// -/// This is keyed fist by the era index to allow bulk deletion and then the stash account. -/// -/// It is removed after `HISTORY_DEPTH` eras. -/// If stakers hasn't been set or has been removed then empty exposure is returned. -#[derive(Encode, Copy, Clone, Debug, Store)] -pub struct ErasStakersClippedStore { - #[store(returns = Exposure)] - /// Era index - pub era: EraIndex, - /// Stash account of the validator - pub validator_stash: T::AccountId, -} - -/// The active era information, holds index and start. -/// -/// The active era is the era currently rewarded. -/// Validator set of this era must be equal to `SessionInterface::validators`. -#[derive(Encode, Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Store)] -pub struct ActiveEraStore { - #[store(returns = Option)] - /// Marker for the runtime - pub _runtime: PhantomData, -} - /// Declare no desire to either validate or nominate. /// /// Effective at the beginning of the next era. @@ -251,12 +220,3 @@ pub struct NominateCall { /// The targets that are being nominated pub targets: Vec, } - -/// Claim a payout for a validator’s stakers -#[derive(PartialEq, Eq, Clone, Call, Encode, Decode, Debug)] -pub struct PayoutStakersCall<'a, T: Staking> { - /// Stash account of the validator - pub validator_stash: &'a T::AccountId, - /// Era index - pub era: EraIndex, -} From 1df5a640245a7db6cf536abb7bb64033baf520aa Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 11 Sep 2020 20:26:14 -0400 Subject: [PATCH 53/80] Remove more code not needed for Ledgeracio --- src/frame/session.rs | 42 ------------------------------------------ src/frame/staking.rs | 27 +-------------------------- src/runtimes.rs | 13 ++----------- 3 files changed, 3 insertions(+), 79 deletions(-) diff --git a/src/frame/session.rs b/src/frame/session.rs index 3640355e772..f5f527b81b3 100644 --- a/src/frame/session.rs +++ b/src/frame/session.rs @@ -51,9 +51,6 @@ pub trait Session: System { /// The validator account identifier type for the runtime. type ValidatorId: Parameter + Debug + Ord + Default + Send + Sync + 'static; - /// The session index identifier type for the runtime. - type SessionIndex: Parameter + Debug + Ord + Default + Send + Sync + 'static; - /// The keys. type Keys: OpaqueKeys + Member + Parameter + Default; } @@ -68,27 +65,6 @@ pub struct ValidatorsStore { default_impl!(ValidatorsStore); -/// Current index of the session. -#[derive(Encode, Store, Debug)] -pub struct CurrentIndexStore { - #[store(returns = ::SessionIndex)] - /// Marker for the runtime - pub _runtime: PhantomData, -} - -default_impl!(CurrentIndexStore); - -/// True if the underlying economic identities or weighting behind the validators -/// has changed in the queued validator set. -#[derive(Encode, Store, Debug)] -pub struct QueuedChangedStore { - #[store(returns = bool)] - /// Marker for the runtime - pub _runtime: PhantomData, -} - -default_impl!(QueuedChangedStore); - /// Set the session keys for a validator. #[derive(Encode, Call, Debug)] pub struct SetKeysCall { @@ -97,21 +73,3 @@ pub struct SetKeysCall { /// The proof. This is not currently used and can be set to an empty vector. pub proof: Vec, } - -#[cfg(test)] -mod tests { - use super::*; - use crate::tests::test_client; - - #[async_std::test] - #[ignore] - async fn test_state_read_free_balance() { - env_logger::try_init().ok(); - let (client, _) = test_client().await; - assert!(client - .fetch(&QueuedChangedStore::default(), None) - .await - .unwrap() - .unwrap()); - } -} diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 5a48d9d9f17..417222e338e 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -24,11 +24,6 @@ use codec::{ Decode, Encode, }; -use frame_support::Parameter; -use sp_runtime::traits::{ - MaybeSerialize, - Member, -}; use std::{ collections::BTreeMap, @@ -69,27 +64,7 @@ pub struct SetPayeeCall { /// The subset of the `frame::Trait` that a client must implement. #[module] -pub trait Staking: Balances { - /// Data type used to index nominators in the compact type - type NominatorIndex: Parameter - + codec::Codec - + Member - + Default - + Copy - + MaybeSerialize - + Debug; - - /// Data type used to index validators in the compact type. - type ValidatorIndex: Parameter - + codec::Codec - + Send - + Sync - + Default - + Member - + Copy - + MaybeSerialize - + Debug; -} +pub trait Staking: Balances {} /// Number of eras to keep in history. /// diff --git a/src/runtimes.rs b/src/runtimes.rs index f86096e0d5a..6bbd8b7c26a 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -146,10 +146,7 @@ pub trait Runtime: System + Sized + Send + Sync + 'static { #[derive(Debug, Clone, Eq, PartialEq)] pub struct DefaultNodeRuntime; -impl Staking for DefaultNodeRuntime { - type NominatorIndex = u32; - type ValidatorIndex = u16; -} +impl Staking for DefaultNodeRuntime {} impl Runtime for DefaultNodeRuntime { type Signature = MultiSignature; @@ -173,7 +170,6 @@ impl Balances for DefaultNodeRuntime { } impl Session for DefaultNodeRuntime { - type SessionIndex = u32; type ValidatorId = ::AccountId; type Keys = BasicSessionKeys; } @@ -213,7 +209,6 @@ impl Balances for NodeTemplateRuntime { } impl Session for NodeTemplateRuntime { - type SessionIndex = u32; type ValidatorId = ::AccountId; type Keys = BasicSessionKeys; } @@ -247,15 +242,11 @@ impl System for KusamaRuntime { } impl Session for KusamaRuntime { - type SessionIndex = u32; type ValidatorId = ::AccountId; type Keys = SessionKeys; } -impl Staking for KusamaRuntime { - type NominatorIndex = u32; - type ValidatorIndex = u16; -} +impl Staking for KusamaRuntime {} impl Balances for KusamaRuntime { type Balance = u128; From c622641a8e163953062c031a7bc9606b07616a2c Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 11 Sep 2020 20:47:02 -0400 Subject: [PATCH 54/80] Remove a pointless change in Cargo.toml w.r.t. upstream. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index aaca8753be8..155d78c4a21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ num-traits = "0.2.12" serde = { version = "1.0.115", features = ["derive"] } serde_json = "1.0.57" url = "2.1.1" -codec = { package = "parity-scale-codec", version = "1.3.5", features = ["derive", "full"] } +codec = { package = "parity-scale-codec", version = "1.3.5", default-features = false, features = ["derive", "full"] } frame-metadata = { version = "11.0.0-rc6", package = "frame-metadata" } frame-support = { version = "2.0.0-rc6", package = "frame-support" } From b253a7ab39ddd55546d129c43517114e8494b590 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 11 Sep 2020 21:37:06 -0400 Subject: [PATCH 55/80] Remove more junk --- Cargo.toml | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 155d78c4a21..2fcd351343b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ log = "0.4.11" thiserror = "1.0.20" futures = "0.3.5" jsonrpsee = { version = "0.1.0", features = ["ws"] } -num-traits = "0.2.12" +num-traits = { version = "0.2.12", default-features = false } serde = { version = "1.0.115", features = ["derive"] } serde_json = "1.0.57" url = "2.1.1" @@ -63,21 +63,3 @@ substrate-subxt-client = { version = "0.4.0", path = "client" } tempdir = "0.3.7" test-node = { path = "test-node" } wabt = "0.10.0" - -# [patch.crates-io] -# frame-metadata = { git = "https://github.com/paritytech/substrate" } -# frame-support = { git = "https://github.com/paritytech/substrate" } -# sp-runtime = { git = "https://github.com/paritytech/substrate" } -# sp-version = { git = "https://github.com/paritytech/substrate" } -# pallet-indices = { git = "https://github.com/paritytech/substrate" } -# sp-rpc = { git = "https://github.com/paritytech/substrate" } -# sp-core = { git = "https://github.com/paritytech/substrate" } -# sc-rpc-api = { git = "https://github.com/paritytech/substrate" } -# sp-transaction-pool = { git = "https://github.com/paritytech/substrate" } -# sp-std = { git = "https://github.com/paritytech/substrate" } -# application-crypto = { git = "https://github.com/paritytech/substrate", package = "sp-application-crypto", default-features = false } -# sp-finality-grandpa = { git = "https://github.com/paritytech/substrate" } -# sp-consensus-babe = { git = "https://github.com/paritytech/substrate" } -# pallet-im-online = { git = "https://github.com/paritytech/substrate" } -# sp-authority-discovery = { git = "https://github.com/paritytech/substrate" } -# pallet-staking = { git = "https://github.com/paritytech/substrate" } From 9a8680246ea87bb8f3f9a9e2f252dffa574a2720 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 14 Sep 2020 13:44:11 +0100 Subject: [PATCH 56/80] Revert contracts put_code test to pure code (not using the macro) --- Cargo.toml | 3 ++ src/frame/contracts.rs | 106 +++++++++++++++++++++++++++-------------- src/runtimes.rs | 33 +++++++++++++ 3 files changed, 105 insertions(+), 37 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 16b02b4932f..210a5c760e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,9 @@ include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"] [features] client = ["substrate-subxt-client"] +# enable this feature to run tests which require a local dev chain node +integration-tests = [] + [dependencies] log = "0.4.11" thiserror = "1.0.20" diff --git a/src/frame/contracts.rs b/src/frame/contracts.rs index 0a0bc1da346..c36311f80fc 100644 --- a/src/frame/contracts.rs +++ b/src/frame/contracts.rs @@ -117,43 +117,75 @@ pub struct InstantiatedEvent { #[cfg(test)] mod tests { + use sp_keyring::AccountKeyring; + use super::*; + use crate::{ClientBuilder, PairSigner, ContractsTemplateRuntime}; + + fn contract_wasm() -> Vec { + const CONTRACT: &str = r#" + (module + (func (export "call")) + (func (export "deploy")) + ) + "#; + wabt::wat2wasm(CONTRACT).expect("invalid wabt") + } + + #[async_std::test] + #[cfg(feature = "integration-tests")] + async fn tx_put_code() { + env_logger::try_init().ok(); + + let signer = PairSigner::new(AccountKeyring::Alice.pair()); + let client = ClientBuilder::::new().build().await.unwrap(); + + let code = contract_wasm(); + let result = client.put_code_and_watch(&signer, &code).await.unwrap(); + let code_stored = result.code_stored().unwrap(); + + assert!( + code_stored.is_some(), + format!( + "Error calling put_code and receiving CodeStored Event: {:?}", + code_stored + ) + ); + } - subxt_test!({ - name: test_put_code_and_instantiate, - prelude: { - const CONTRACT: &str = r#" -(module - (func (export "call")) - (func (export "deploy")) -) -"#; - let wasm = wabt::wat2wasm(CONTRACT).expect("invalid wabt"); - let code_hash; - }, - step: { - call: PutCodeCall { - _runtime: PhantomData, - code: &wasm, - }, - event: CodeStoredEvent { - code_hash: { - code_hash = event.code_hash.clone(); - event.code_hash.clone() - }, - }, - }, - step: { - call: InstantiateCall { - endowment: 100_000_000_000_000, - gas_limit: 500_000_000, - code_hash: &code_hash, - data: &[], - }, - event: InstantiatedEvent { - caller: alice.clone(), - contract: event.contract.clone(), - }, - }, - }); + // #[test] + // #[cfg(feature = "integration-tests")] + // fn tx_instantiate() { + // env_logger::try_init().ok(); + // let result: Result<_, Error> = async_std::task::block_on(async move { + // let signer = AccountKeyring::Bob.pair(); + // let client = test_client().await; + // + // let code_hash = put_code(&client, signer.clone()).await?; + // + // log::info!("Code hash: {:?}", code_hash); + // + // let xt = client.xt(signer, None).await?; + // let result = xt + // .watch() + // .submit(InstantiateCall { + // endowment: 100_000_000_000_000, + // gas_limit: 500_000_000, + // code_hash: &code_hash, + // data: &[], + // }) + // .await?; + // let event = result + // .find_event::>()? + // .ok_or(Error::Other("Failed to find Instantiated event".into()))?; + // Ok(event) + // }); + // + // log::info!("Instantiate result: {:?}", result); + // + // assert!( + // result.is_ok(), + // format!("Error instantiating contract: {:?}", result) + // ); + // } } diff --git a/src/runtimes.rs b/src/runtimes.rs index 13779d71b86..5e1a55ce42d 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -116,6 +116,39 @@ impl Balances for NodeTemplateRuntime { impl Sudo for NodeTemplateRuntime {} +/// Concrete type definitions compatible with the node template, with the +/// contracts pallet enabled. +/// +/// Inherits types from [`NodeTemplateRuntime`], but adds an implementation for +/// the contracts pallet trait. +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct ContractsTemplateRuntime; + +impl Runtime for ContractsTemplateRuntime { + type Signature = ::Signature; + type Extra = DefaultExtra; +} + +impl System for ContractsTemplateRuntime { + type Index = ::Index; + type BlockNumber = ::BlockNumber; + type Hash = ::Hash; + type Hashing = ::Hashing; + type AccountId = ::AccountId; + type Address = ::Address; + type Header = ::Header; + type Extrinsic = ::Extrinsic; + type AccountData = ::AccountData; +} + +impl Balances for ContractsTemplateRuntime { + type Balance = ::Balance; +} + +impl Contracts for ContractsTemplateRuntime {} + +impl Sudo for ContractsTemplateRuntime {} + /// Concrete type definitions compatible with those for kusama, v0.7 /// /// # Note From 0e7bc2d2e57389580922f1c3ca236d61335aa75b Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 14 Sep 2020 16:12:48 +0100 Subject: [PATCH 57/80] Test contract instantiate --- src/frame/contracts.rs | 70 +++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/frame/contracts.rs b/src/frame/contracts.rs index c36311f80fc..2f0498a96c7 100644 --- a/src/frame/contracts.rs +++ b/src/frame/contracts.rs @@ -153,39 +153,39 @@ mod tests { ); } - // #[test] - // #[cfg(feature = "integration-tests")] - // fn tx_instantiate() { - // env_logger::try_init().ok(); - // let result: Result<_, Error> = async_std::task::block_on(async move { - // let signer = AccountKeyring::Bob.pair(); - // let client = test_client().await; - // - // let code_hash = put_code(&client, signer.clone()).await?; - // - // log::info!("Code hash: {:?}", code_hash); - // - // let xt = client.xt(signer, None).await?; - // let result = xt - // .watch() - // .submit(InstantiateCall { - // endowment: 100_000_000_000_000, - // gas_limit: 500_000_000, - // code_hash: &code_hash, - // data: &[], - // }) - // .await?; - // let event = result - // .find_event::>()? - // .ok_or(Error::Other("Failed to find Instantiated event".into()))?; - // Ok(event) - // }); - // - // log::info!("Instantiate result: {:?}", result); - // - // assert!( - // result.is_ok(), - // format!("Error instantiating contract: {:?}", result) - // ); - // } + #[async_std::test] + #[cfg(feature = "integration-tests")] + async fn tx_instantiate() { + env_logger::try_init().ok(); + let signer = PairSigner::new(AccountKeyring::Bob.pair()); + let client = ClientBuilder::::new().build().await.unwrap(); + + // call put_code extrinsic + let code = contract_wasm(); + let result = client.put_code_and_watch(&signer, &code).await.unwrap(); + let code_stored = result.code_stored().unwrap(); + let code_hash = code_stored.unwrap().code_hash; + + log::info!("Code hash: {:?}", code_hash); + + // call instantiate extrinsic + let result = client + .instantiate_and_watch( + &signer, + 100_000_000_000_000, // endowment + 500_000_000, // gas_limit + &code_hash, + &[], // data + ) + .await + .unwrap(); + + log::info!("Instantiate result: {:?}", result); + let event = result.instantiated().unwrap(); + + assert!( + event.is_some(), + format!("Error instantiating contract: {:?}", result) + ); + } } From 92bcd26c810522b1e4766a9a521b2b1d297f26ed Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 14 Sep 2020 16:13:17 +0100 Subject: [PATCH 58/80] Fmt --- src/frame/contracts.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/frame/contracts.rs b/src/frame/contracts.rs index 2f0498a96c7..a3cfd149ed7 100644 --- a/src/frame/contracts.rs +++ b/src/frame/contracts.rs @@ -120,7 +120,11 @@ mod tests { use sp_keyring::AccountKeyring; use super::*; - use crate::{ClientBuilder, PairSigner, ContractsTemplateRuntime}; + use crate::{ + ClientBuilder, + ContractsTemplateRuntime, + PairSigner, + }; fn contract_wasm() -> Vec { const CONTRACT: &str = r#" @@ -138,7 +142,10 @@ mod tests { env_logger::try_init().ok(); let signer = PairSigner::new(AccountKeyring::Alice.pair()); - let client = ClientBuilder::::new().build().await.unwrap(); + let client = ClientBuilder::::new() + .build() + .await + .unwrap(); let code = contract_wasm(); let result = client.put_code_and_watch(&signer, &code).await.unwrap(); @@ -158,7 +165,10 @@ mod tests { async fn tx_instantiate() { env_logger::try_init().ok(); let signer = PairSigner::new(AccountKeyring::Bob.pair()); - let client = ClientBuilder::::new().build().await.unwrap(); + let client = ClientBuilder::::new() + .build() + .await + .unwrap(); // call put_code extrinsic let code = contract_wasm(); @@ -172,10 +182,10 @@ mod tests { let result = client .instantiate_and_watch( &signer, - 100_000_000_000_000, // endowment - 500_000_000, // gas_limit + 100_000_000_000_000, // endowment + 500_000_000, // gas_limit &code_hash, - &[], // data + &[], // data ) .await .unwrap(); From 303c5f47420290c1a9c87e66c7daacc7108bfb9d Mon Sep 17 00:00:00 2001 From: David Palm Date: Tue, 15 Sep 2020 23:41:28 +0200 Subject: [PATCH 59/80] WIP --- client/run.sh | 2 +- src/frame/staking.rs | 62 ++++++++++++++++++++++++++++++++++++ test-node/runtime/Cargo.toml | 1 + test-node/runtime/src/lib.rs | 26 +++++++++++++++ 4 files changed, 90 insertions(+), 1 deletion(-) diff --git a/client/run.sh b/client/run.sh index 6f67c6875ca..8481ace69c7 100755 --- a/client/run.sh +++ b/client/run.sh @@ -1,3 +1,3 @@ #!/bin/sh NODE_TEMPLATE=../target/release/test-node -$NODE_TEMPLATE --chain=dev-chain.json --alice +$NODE_TEMPLATE --chain=dev-chain.json --alice -lrpc=debug diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 417222e338e..dbc914e14c1 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -195,3 +195,65 @@ pub struct NominateCall { /// The targets that are being nominated pub targets: Vec, } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + // events::EventsDecoder, + extrinsic::PairSigner, + // subscription::EventSubscription, + // system::AccountStoreExt, + // tests::{test_client, TestRuntime}, + runtimes::KusamaRuntime as RT, + ClientBuilder, + // frame::staking::NominateCallExt, + // frame::staking::CurrentEraStoreExt, + // frame::staking::CurrentEraStore, + // frame::staking::HistoryDepthStore, + // runtimes::StakingRuntime as RT, + }; + // use sp_core::{sr25519::Pair, Pair as _}; + use sp_keyring::AccountKeyring; + use core::marker::PhantomData; + use crate::frame::balances::*; + use crate::frame::system::*; + use crate::extrinsic::Signer; + + #[async_std::test] + async fn test_nominate() { + env_logger::try_init().ok(); + let alice = PairSigner::::new(AccountKeyring::Alice.pair()); + let bob = PairSigner::::new(AccountKeyring::Bob.pair()); + + let client = ClientBuilder::::new() + .build() + .await + .unwrap(); + println!("HAVE CLIENT"); + + let current_era = client.current_era(None).await; + println!("Current era: {:?}", current_era); + let hd = client.history_depth(None).await; + println!("History depth: {:?}", hd); + let total_issuance = client.total_issuance(None).await; + println!("total issuance: {:?}", total_issuance); + let alice_account = client.account(&alice.account_id(), None).await; + println!("Alice's account info: {:?}", alice_account); + let o = client.nominate(&alice, vec![bob.account_id().clone()]).await; + println!("Nom nom: {:?}", o); + // let event = client. + // current_era() + // .await; + // println!("Current era: {:?}", event); + // let (client, _) = test_client().await; + // let event = client. + // nominate_and_watch(&alice, vec![AccountKeyring::Bob.to_account_id()]) + // .await + // .unwrap(); + // // .nominate() + // // .unwrap() + // // .unwrap(); + // dbg!(event); + } +} diff --git a/test-node/runtime/Cargo.toml b/test-node/runtime/Cargo.toml index 85463292cc6..804f120f161 100644 --- a/test-node/runtime/Cargo.toml +++ b/test-node/runtime/Cargo.toml @@ -20,6 +20,7 @@ pallet-aura = { version = "2.0.0-rc6", default-features = false } pallet-balances = { version = "2.0.0-rc6", default-features = false } pallet-grandpa = { version = "2.0.0-rc6", default-features = false } pallet-randomness-collective-flip = { version = "2.0.0-rc6", default-features = false } +pallet-staking = { version = "2.0.0-rc6", default-features = false } pallet-sudo = { version = "2.0.0-rc6", default-features = false } pallet-timestamp = { version = "2.0.0-rc6", default-features = false } pallet-transaction-payment = { version = "2.0.0-rc6", default-features = false } diff --git a/test-node/runtime/src/lib.rs b/test-node/runtime/src/lib.rs index 85abd73d32c..9fad00a6041 100644 --- a/test-node/runtime/src/lib.rs +++ b/test-node/runtime/src/lib.rs @@ -82,6 +82,7 @@ pub use frame_support::{ StorageValue, }; pub use pallet_balances::Call as BalancesCall; +pub use pallet_staking::Call as StakingCall; pub use pallet_timestamp::Call as TimestampCall; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -305,6 +306,31 @@ impl pallet_sudo::Trait for Runtime { type Call = Call; } +// impl pallet_staking::Trait for Runtime { +// type Currency = Balances; +// type UnixTime = pallet_timestamp::Module; +// type CurrencyToVote = CurrencyToVoteHandler; +// type RewardRemainder = (); +// type Event = (); +// type Slash = (); +// type Reward = (); +// type SessionsPerEra = (); +// type SlashDeferDuration = (); +// type SlashCancelOrigin = frame_system::EnsureRoot; +// type BondingDuration = (); +// type SessionInterface = Self; +// type RewardCurve = RewardCurve; +// type NextNewSession = Session; +// type ElectionLookahead = (); +// type Call = Call; +// type MaxIterations = MaxIterations; +// type MinSolutionScoreBump = (); +// type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; +// type UnsignedPriority = (); +// type WeightInfo = (); +// } + + construct_runtime!( pub enum Runtime where Block = Block, From f0a5f61285acbfc85aff18b29ef65f174823e234 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Tue, 15 Sep 2020 19:16:42 -0400 Subject: [PATCH 60/80] Add some more submission tests --- src/frame/staking.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index dbc914e14c1..827f6fa3d4c 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -196,7 +196,7 @@ pub struct NominateCall { pub targets: Vec, } -#[cfg(test)] +#[cfg(all(test, feature = "integration-tests"))] mod tests { use super::*; use crate::{ @@ -215,7 +215,6 @@ mod tests { }; // use sp_core::{sr25519::Pair, Pair as _}; use sp_keyring::AccountKeyring; - use core::marker::PhantomData; use crate::frame::balances::*; use crate::frame::system::*; use crate::extrinsic::Signer; @@ -230,18 +229,23 @@ mod tests { .build() .await .unwrap(); - println!("HAVE CLIENT"); - - let current_era = client.current_era(None).await; + let current_era = client.current_era(None).await.unwrap(); println!("Current era: {:?}", current_era); - let hd = client.history_depth(None).await; + let hd = client.history_depth(None).await.unwrap(); println!("History depth: {:?}", hd); - let total_issuance = client.total_issuance(None).await; + let total_issuance = client.total_issuance(None).await.unwrap(); println!("total issuance: {:?}", total_issuance); - let alice_account = client.account(&alice.account_id(), None).await; + let alice_account = client.account(&alice.account_id(), None).await.unwrap(); println!("Alice's account info: {:?}", alice_account); - let o = client.nominate(&alice, vec![bob.account_id().clone()]).await; + let o = client.nominate(&alice, vec![bob.account_id().clone()]).await.unwrap(); println!("Nom nom: {:?}", o); + let o = client.validate(&bob, ValidatorPrefs::default()).await.unwrap(); + println!("Validator result: {:?}", o); + for &i in &[RewardDestination::Staked] { + for &j in &[&bob, &alice] { + println!("Transaction result: {:?}", client.set_payee(j, i).await.unwrap()); + } + } // let event = client. // current_era() // .await; From 051698725ce27bee3fe3e5050a57c626c7e968cd Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Tue, 15 Sep 2020 19:19:46 -0400 Subject: [PATCH 61/80] Reformat --- src/frame/staking.rs | 39 ++++++++++++++++++------------------ test-node/runtime/src/lib.rs | 3 +-- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 827f6fa3d4c..12c285acd77 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -200,24 +200,19 @@ pub struct NominateCall { mod tests { use super::*; use crate::{ - // events::EventsDecoder, extrinsic::PairSigner, - // subscription::EventSubscription, - // system::AccountStoreExt, - // tests::{test_client, TestRuntime}, runtimes::KusamaRuntime as RT, ClientBuilder, - // frame::staking::NominateCallExt, - // frame::staking::CurrentEraStoreExt, - // frame::staking::CurrentEraStore, - // frame::staking::HistoryDepthStore, - // runtimes::StakingRuntime as RT, }; // use sp_core::{sr25519::Pair, Pair as _}; + use crate::{ + extrinsic::Signer, + frame::{ + balances::*, + system::*, + }, + }; use sp_keyring::AccountKeyring; - use crate::frame::balances::*; - use crate::frame::system::*; - use crate::extrinsic::Signer; #[async_std::test] async fn test_nominate() { @@ -225,10 +220,7 @@ mod tests { let alice = PairSigner::::new(AccountKeyring::Alice.pair()); let bob = PairSigner::::new(AccountKeyring::Bob.pair()); - let client = ClientBuilder::::new() - .build() - .await - .unwrap(); + let client = ClientBuilder::::new().build().await.unwrap(); let current_era = client.current_era(None).await.unwrap(); println!("Current era: {:?}", current_era); let hd = client.history_depth(None).await.unwrap(); @@ -237,13 +229,22 @@ mod tests { println!("total issuance: {:?}", total_issuance); let alice_account = client.account(&alice.account_id(), None).await.unwrap(); println!("Alice's account info: {:?}", alice_account); - let o = client.nominate(&alice, vec![bob.account_id().clone()]).await.unwrap(); + let o = client + .nominate(&alice, vec![bob.account_id().clone()]) + .await + .unwrap(); println!("Nom nom: {:?}", o); - let o = client.validate(&bob, ValidatorPrefs::default()).await.unwrap(); + let o = client + .validate(&bob, ValidatorPrefs::default()) + .await + .unwrap(); println!("Validator result: {:?}", o); for &i in &[RewardDestination::Staked] { for &j in &[&bob, &alice] { - println!("Transaction result: {:?}", client.set_payee(j, i).await.unwrap()); + println!( + "Transaction result: {:?}", + client.set_payee(j, i).await.unwrap() + ); } } // let event = client. diff --git a/test-node/runtime/src/lib.rs b/test-node/runtime/src/lib.rs index 9fad00a6041..7d7508eb320 100644 --- a/test-node/runtime/src/lib.rs +++ b/test-node/runtime/src/lib.rs @@ -82,7 +82,7 @@ pub use frame_support::{ StorageValue, }; pub use pallet_balances::Call as BalancesCall; -pub use pallet_staking::Call as StakingCall; +pub use pallet_staking::Call as StakingCall; pub use pallet_timestamp::Call as TimestampCall; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -330,7 +330,6 @@ impl pallet_sudo::Trait for Runtime { // type WeightInfo = (); // } - construct_runtime!( pub enum Runtime where Block = Block, From dffbba6f3140d743f60c0c8bcf10f05a847aa6ff Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Tue, 15 Sep 2020 20:30:19 -0400 Subject: [PATCH 62/80] More tests --- src/frame/staking.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 12c285acd77..45e7b0a1781 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -239,7 +239,7 @@ mod tests { .await .unwrap(); println!("Validator result: {:?}", o); - for &i in &[RewardDestination::Staked] { + for &i in &[RewardDestination::Controller] { for &j in &[&bob, &alice] { println!( "Transaction result: {:?}", @@ -247,6 +247,18 @@ mod tests { ); } } + assert_eq!( + client + .fetch( + &ValidatorsStore { + stash: bob.account_id().clone() + }, + None + ) + .await + .unwrap(), + None + ); // let event = client. // current_era() // .await; From 0860bad80611b4d7301eec43cbb227c5db0514fa Mon Sep 17 00:00:00 2001 From: David Palm Date: Wed, 16 Sep 2020 09:23:31 +0200 Subject: [PATCH 63/80] Cleanup --- src/frame/staking.rs | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 45e7b0a1781..2247c8e93bc 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -206,6 +206,7 @@ mod tests { }; // use sp_core::{sr25519::Pair, Pair as _}; use crate::{ + error::Error, extrinsic::Signer, frame::{ balances::*, @@ -215,35 +216,33 @@ mod tests { use sp_keyring::AccountKeyring; #[async_std::test] - async fn test_nominate() { + async fn test_nominate() -> Result<(), Error> { env_logger::try_init().ok(); let alice = PairSigner::::new(AccountKeyring::Alice.pair()); let bob = PairSigner::::new(AccountKeyring::Bob.pair()); - let client = ClientBuilder::::new().build().await.unwrap(); - let current_era = client.current_era(None).await.unwrap(); + let client = ClientBuilder::::new().build().await?; + let current_era = client.current_era(None).await?; println!("Current era: {:?}", current_era); - let hd = client.history_depth(None).await.unwrap(); + let hd = client.history_depth(None).await?; println!("History depth: {:?}", hd); - let total_issuance = client.total_issuance(None).await.unwrap(); + let total_issuance = client.total_issuance(None).await?; println!("total issuance: {:?}", total_issuance); - let alice_account = client.account(&alice.account_id(), None).await.unwrap(); + let alice_account = client.account(&alice.account_id(), None).await?; println!("Alice's account info: {:?}", alice_account); let o = client .nominate(&alice, vec![bob.account_id().clone()]) - .await - .unwrap(); + .await?; println!("Nom nom: {:?}", o); let o = client .validate(&bob, ValidatorPrefs::default()) - .await - .unwrap(); + .await?; println!("Validator result: {:?}", o); for &i in &[RewardDestination::Controller] { for &j in &[&bob, &alice] { println!( "Transaction result: {:?}", - client.set_payee(j, i).await.unwrap() + client.set_payee(j, i).await? ); } } @@ -255,22 +254,9 @@ mod tests { }, None ) - .await - .unwrap(), + .await?, None ); - // let event = client. - // current_era() - // .await; - // println!("Current era: {:?}", event); - // let (client, _) = test_client().await; - // let event = client. - // nominate_and_watch(&alice, vec![AccountKeyring::Bob.to_account_id()]) - // .await - // .unwrap(); - // // .nominate() - // // .unwrap() - // // .unwrap(); - // dbg!(event); + Ok(()) } } From ec96a42bb405bc84e3c2de9d619e82f246091997 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Wed, 16 Sep 2020 17:04:38 -0400 Subject: [PATCH 64/80] Hopefully fix CI --- client/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/run.sh b/client/run.sh index 8481ace69c7..6f67c6875ca 100755 --- a/client/run.sh +++ b/client/run.sh @@ -1,3 +1,3 @@ #!/bin/sh NODE_TEMPLATE=../target/release/test-node -$NODE_TEMPLATE --chain=dev-chain.json --alice -lrpc=debug +$NODE_TEMPLATE --chain=dev-chain.json --alice From 01869a768281bc41149462cf0e74d2632ae971f3 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Wed, 16 Sep 2020 18:37:02 -0400 Subject: [PATCH 65/80] Remove dead code --- test-node/runtime/src/lib.rs | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/test-node/runtime/src/lib.rs b/test-node/runtime/src/lib.rs index 7d7508eb320..85abd73d32c 100644 --- a/test-node/runtime/src/lib.rs +++ b/test-node/runtime/src/lib.rs @@ -82,7 +82,6 @@ pub use frame_support::{ StorageValue, }; pub use pallet_balances::Call as BalancesCall; -pub use pallet_staking::Call as StakingCall; pub use pallet_timestamp::Call as TimestampCall; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -306,30 +305,6 @@ impl pallet_sudo::Trait for Runtime { type Call = Call; } -// impl pallet_staking::Trait for Runtime { -// type Currency = Balances; -// type UnixTime = pallet_timestamp::Module; -// type CurrencyToVote = CurrencyToVoteHandler; -// type RewardRemainder = (); -// type Event = (); -// type Slash = (); -// type Reward = (); -// type SessionsPerEra = (); -// type SlashDeferDuration = (); -// type SlashCancelOrigin = frame_system::EnsureRoot; -// type BondingDuration = (); -// type SessionInterface = Self; -// type RewardCurve = RewardCurve; -// type NextNewSession = Session; -// type ElectionLookahead = (); -// type Call = Call; -// type MaxIterations = MaxIterations; -// type MinSolutionScoreBump = (); -// type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; -// type UnsignedPriority = (); -// type WeightInfo = (); -// } - construct_runtime!( pub enum Runtime where Block = Block, From b54b1b9f4e7728426a19049c62d1e6d4472eb91b Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Wed, 16 Sep 2020 21:22:01 -0400 Subject: [PATCH 66/80] Test chill --- src/frame/staking.rs | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 45e7b0a1781..8e5d2c60970 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -245,32 +245,8 @@ mod tests { "Transaction result: {:?}", client.set_payee(j, i).await.unwrap() ); + client.chill(j).await.unwrap(); } } - assert_eq!( - client - .fetch( - &ValidatorsStore { - stash: bob.account_id().clone() - }, - None - ) - .await - .unwrap(), - None - ); - // let event = client. - // current_era() - // .await; - // println!("Current era: {:?}", event); - // let (client, _) = test_client().await; - // let event = client. - // nominate_and_watch(&alice, vec![AccountKeyring::Bob.to_account_id()]) - // .await - // .unwrap(); - // // .nominate() - // // .unwrap() - // // .unwrap(); - // dbg!(event); } } From 68ff645ee1aac764e425ed1e5e96b4c9575ca07a Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 17 Sep 2020 13:15:13 -0400 Subject: [PATCH 67/80] Add missing docs --- src/runtimes.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/runtimes.rs b/src/runtimes.rs index 522e3af542f..63b55bbe6de 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -13,7 +13,6 @@ // // You should have received a copy of the GNU General Public License // along with substrate-subxt. If not, see . -#![allow(missing_docs)] use codec::Encode; use pallet_im_online::sr25519::AuthorityId as ImOnlineId; @@ -82,15 +81,15 @@ impl sp_runtime::BoundToRuntimeAppPublic for AuthorityDiscovery { impl_opaque_keys! { /// Substrate base runtime keys pub struct BasicSessionKeys { - //// GRANDPA session key + /// GRANDPA session key pub grandpa: Grandpa, - //// BABE session key + /// BABE session key pub babe: Babe, - //// ImOnline session key + /// ImOnline session key pub im_online: ImOnline, - //// Parachain validation session key + /// Parachain validation session key pub parachains: Parachains, - //// AuthorityDiscovery session key + /// AuthorityDiscovery session key pub authority_discovery: AuthorityDiscovery, } } @@ -98,15 +97,15 @@ impl_opaque_keys! { impl_opaque_keys! { /// Polkadot/Kusama runtime keys pub struct SessionKeys { - //// GRANDPA session key + /// GRANDPA session key pub grandpa: Grandpa, - //// BABE session key + /// BABE session key pub babe: Babe, - //// ImOnline session key + /// ImOnline session key pub im_online: ImOnline, - //// ParachainValidator session key + /// ParachainValidator session key pub parachain_validator: Parachains, - //// AuthorityDiscovery session key + /// AuthorityDiscovery session key pub authority_discovery: AuthorityDiscovery, } } From bc8bc36bde581f1892ea88a778dfe0fe5bff24d7 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 17 Sep 2020 13:57:45 -0400 Subject: [PATCH 68/80] Remove unnecessary use --- src/runtimes.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/runtimes.rs b/src/runtimes.rs index 63b55bbe6de..7c4c60a2bf1 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -111,7 +111,6 @@ impl_opaque_keys! { } use crate::{ - contracts::Contracts, extrinsic::{ DefaultExtra, SignedExtra, From dd4dce90d39327dfcdd133a8ce0acc16f1719dd6 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 17 Sep 2020 14:47:34 -0400 Subject: [PATCH 69/80] Revert "Remove unnecessary use" This reverts commit bc8bc36bde581f1892ea88a778dfe0fe5bff24d7. --- src/runtimes.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/runtimes.rs b/src/runtimes.rs index 7c4c60a2bf1..63b55bbe6de 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -111,6 +111,7 @@ impl_opaque_keys! { } use crate::{ + contracts::Contracts, extrinsic::{ DefaultExtra, SignedExtra, From 1eb67d9f2d72ed58a463377c9d0d49c3049b7c97 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 17 Sep 2020 17:30:16 -0400 Subject: [PATCH 70/80] Retry on temporary failures --- src/frame/staking.rs | 52 +++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 8e5d2c60970..1f77af4661c 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -196,23 +196,45 @@ pub struct NominateCall { pub targets: Vec, } -#[cfg(all(test, feature = "integration-tests"))] +#[cfg(test)] mod tests { use super::*; use crate::{ - extrinsic::PairSigner, - runtimes::KusamaRuntime as RT, - ClientBuilder, - }; - // use sp_core::{sr25519::Pair, Pair as _}; - use crate::{ - extrinsic::Signer, + extrinsic::{ + PairSigner, + Signer, + }, frame::{ balances::*, system::*, }, + runtimes::KusamaRuntime as RT, + ClientBuilder, + Error, + }; + use jsonrpsee::{ + client::RequestError, + common::{ + Error as RPCError, + ErrorCode, + }, }; use sp_keyring::AccountKeyring; + macro_rules! retry_trans { + ($e: expr) => { + (loop { + match $e.await { + Ok(o) => break o, + Err(Error::Rpc(RequestError::Request(RPCError { + code: ErrorCode::ServerError(1014), + message: m, + data: Some(_), + }))) if m.starts_with("Priority is too low: ") => {} + Err(e) => panic!("Unexpected error: {}", e), + } + }) + }; + } #[async_std::test] async fn test_nominate() { @@ -234,18 +256,14 @@ mod tests { .await .unwrap(); println!("Nom nom: {:?}", o); - let o = client - .validate(&bob, ValidatorPrefs::default()) - .await - .unwrap(); + let o = retry_trans!(client.validate(&bob, ValidatorPrefs::default())); println!("Validator result: {:?}", o); for &i in &[RewardDestination::Controller] { for &j in &[&bob, &alice] { - println!( - "Transaction result: {:?}", - client.set_payee(j, i).await.unwrap() - ); - client.chill(j).await.unwrap(); + let o = retry_trans!(client.validate(&bob, ValidatorPrefs::default())); + println!("Transaction result: {:?}", o); + let o = retry_trans!(client.chill(j)); + println!("Transaction result: {:?}", o); } } } From d63661f8a3ddaac05995165d8621b318535c6414 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Thu, 17 Sep 2020 17:40:15 -0400 Subject: [PATCH 71/80] Ignore the staking tests on CI --- src/frame/staking.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 1f77af4661c..aafae2cedd7 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -237,6 +237,7 @@ mod tests { } #[async_std::test] + #[ignore] async fn test_nominate() { env_logger::try_init().ok(); let alice = PairSigner::::new(AccountKeyring::Alice.pair()); From 24848b3cebeb519072cd26d79b7741b64ca3ac87 Mon Sep 17 00:00:00 2001 From: David Palm Date: Fri, 18 Sep 2020 14:58:01 +0200 Subject: [PATCH 72/80] Obey the fmt --- src/frame/staking.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 270d97ef299..5b8cbe55547 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -201,7 +201,7 @@ pub struct NominateCall { mod tests { use super::*; use crate::{ - ExtrinsicSuccess, + error::RuntimeError, extrinsic::{ PairSigner, Signer, @@ -213,8 +213,9 @@ mod tests { runtimes::KusamaRuntime as RT, ClientBuilder, Error, - error::RuntimeError, + ExtrinsicSuccess, }; + use assert_matches::assert_matches; use jsonrpsee::{ client::RequestError, common::{ @@ -222,7 +223,6 @@ mod tests { ErrorCode, }, }; - use assert_matches::assert_matches; use sp_keyring::AccountKeyring; // TODO: I don't think this does the right thing. @@ -290,9 +290,7 @@ mod tests { client .nominate_and_watch(&alice, vec![bob.account_id().clone()]) .await?; - let chill = client - .chill_and_watch(&bob) - .await; + let chill = client.chill_and_watch(&bob).await; assert_matches!(chill, Err(Error::Runtime(RuntimeError::Module(module_err))) => { assert_eq!(module_err.module, "Staking"); From e2862d8ec8b2f1def38b36961135af0b116efbfe Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 18 Sep 2020 16:49:34 -0400 Subject: [PATCH 73/80] Run CI with at most one test thread --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index b4941647da1..46f01d1b842 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -26,4 +26,4 @@ jobs: run: cargo build --workspace --verbose - name: test - run: cargo test --workspace --verbose + run: cargo test --workspace --verbose -- --test-threads=1 From 8a795710fcfa7177bdf16f702923a8554d0f48e6 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sat, 19 Sep 2020 18:49:01 -0400 Subject: [PATCH 74/80] Implement tests for staking --- src/frame/staking.rs | 103 ++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 5b8cbe55547..7309ec441a6 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -216,34 +216,20 @@ mod tests { ExtrinsicSuccess, }; use assert_matches::assert_matches; - use jsonrpsee::{ - client::RequestError, - common::{ - Error as RPCError, - ErrorCode, - }, + use sp_core::{ + sr25519, + Pair, }; use sp_keyring::AccountKeyring; - // TODO: I don't think this does the right thing. - macro_rules! retry_trans { - ($e: expr) => { - (loop { - match $e.await { - Ok(o) => break o, - Err(Error::Rpc(RequestError::Request(RPCError { - code: ErrorCode::ServerError(1014), - message: m, - data: Some(_), - }))) if m.starts_with("Priority is too low: ") => {} - Err(e) => panic!("Unexpected error: {}", e), - } - }) - }; + /// Helper function to generate a crypto pair from seed + fn get_from_seed(seed: &str) -> sr25519::Pair { + sr25519::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed") } #[async_std::test] - async fn test_validate_with_stash_account() -> Result<(), Error> { + async fn test_validate_with_controller_account() -> Result<(), Error> { env_logger::try_init().ok(); let alice = PairSigner::::new(AccountKeyring::Alice.pair()); let client = ClientBuilder::::new().build().await?; @@ -257,14 +243,24 @@ mod tests { Ok(()) } + #[async_std::test] - #[ignore] - async fn test_validate_with_controller_account() -> Result<(), Error> { - // TODO: how to set up the controller account for Alice? + async fn test_validate_not_possible_for_stash_account() -> Result<(), Error> { + env_logger::try_init().ok(); + let alice_stash = PairSigner::::new(get_from_seed("Alice//stash")); + let client = ClientBuilder::::new().build().await?; + let announce_validator = client + .validate_and_watch(&alice_stash, ValidatorPrefs::default()) + .await; + assert_matches!(announce_validator, Err(Error::Runtime(RuntimeError::Module(module_err))) => { + assert_eq!(module_err.module, "Staking"); + assert_eq!(module_err.error, "NotController"); + }); Ok(()) } + #[async_std::test] - async fn test_nominate_with_stash_account() -> Result<(), Error> { + async fn test_nominate_with_controller_account() -> Result<(), Error> { env_logger::try_init().ok(); let alice = PairSigner::::new(AccountKeyring::Alice.pair()); let bob = PairSigner::::new(AccountKeyring::Bob.pair()); @@ -280,9 +276,29 @@ mod tests { Ok(()) } + #[async_std::test] + async fn test_nominate_not_possible_for_stash_account() -> Result<(), Error> { + env_logger::try_init().ok(); + let alice_stash = + PairSigner::::new(get_from_seed("Alice//stash")); + let bob = PairSigner::::new(AccountKeyring::Bob.pair()); + let client = ClientBuilder::::new().build().await?; + + let nomination = client + .nominate_and_watch(&alice_stash, vec![bob.account_id().clone()]) + .await; + assert_matches!(nomination, Err(Error::Runtime(RuntimeError::Module(module_err))) => { + assert_eq!(module_err.module, "Staking"); + assert_eq!(module_err.error, "NotController"); + }); + Ok(()) + } + #[async_std::test] async fn test_chill_not_possible_for_stash_account() -> Result<(), Error> { env_logger::try_init().ok(); + let alice_stash = + PairSigner::::new(get_from_seed("Alice//stash")); let alice = PairSigner::::new(AccountKeyring::Alice.pair()); let bob = PairSigner::::new(AccountKeyring::Bob.pair()); let client = ClientBuilder::::new().build().await?; @@ -290,19 +306,23 @@ mod tests { client .nominate_and_watch(&alice, vec![bob.account_id().clone()]) .await?; - let chill = client.chill_and_watch(&bob).await; + let store = LedgerStore { + controller: alice.account_id().clone(), + }; + let StakingLedger { stash, .. } = client.fetch(&store, None).await?.unwrap(); + assert_eq!(alice_stash.account_id(), &stash); + let chill = client.chill_and_watch(&alice_stash).await; assert_matches!(chill, Err(Error::Runtime(RuntimeError::Module(module_err))) => { assert_eq!(module_err.module, "Staking"); assert_eq!(module_err.error, "NotController"); }); - Ok(()) - } - #[async_std::test] - #[ignore] - async fn test_chill_is_ok_for_controller_account() -> Result<(), Error> { - // TODO: how to set the controller for Alice? + let chill = client.chill_and_watch(&alice).await; + assert_matches!(chill, Ok(ExtrinsicSuccess {block: _, extrinsic: _, events}) => { + // TOOD: this is unsatisfying – can we do better? + assert_eq!(events.len(), 3); + }); Ok(()) } @@ -321,22 +341,5 @@ mod tests { println!("History depth: {:?}", hd); let total_issuance = client.total_issuance(None).await?; println!("total issuance: {:?}", total_issuance); - let alice_account = client.account(&alice.account_id(), None).await?; - println!("Alice's account info: {:?}", alice_account); - let o = client - .nominate(&alice, vec![bob.account_id().clone()]) - .await?; - println!("Nom nom: {:?}", o); - let o = retry_trans!(client.validate(&bob, ValidatorPrefs::default())); - println!("Validator result: {:?}", o); - for &_i in &[RewardDestination::Controller] { - for &j in &[&bob, &alice] { - let o = retry_trans!(client.validate(&bob, ValidatorPrefs::default())); - println!("Transaction result: {:?}", o); - let o = retry_trans!(client.chill(j)); - println!("Transaction result: {:?}", o); - } - } - Ok(()) } } From f3da309f4e463ec4209184618a9ef628f7c67630 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sat, 19 Sep 2020 21:08:34 -0400 Subject: [PATCH 75/80] More tests --- src/frame/staking.rs | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 7309ec441a6..62f34cdfdb6 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -206,10 +206,7 @@ mod tests { PairSigner, Signer, }, - frame::{ - balances::*, - system::*, - }, + frame::balances::*, runtimes::KusamaRuntime as RT, ClientBuilder, Error, @@ -295,16 +292,17 @@ mod tests { } #[async_std::test] - async fn test_chill_not_possible_for_stash_account() -> Result<(), Error> { + async fn test_chill_works_for_controller_only() -> Result<(), Error> { env_logger::try_init().ok(); let alice_stash = PairSigner::::new(get_from_seed("Alice//stash")); + let bob_stash = PairSigner::::new(get_from_seed("Bob//stash")); let alice = PairSigner::::new(AccountKeyring::Alice.pair()); - let bob = PairSigner::::new(AccountKeyring::Bob.pair()); let client = ClientBuilder::::new().build().await?; + // this will fail the second time, which is why this is one test, not two client - .nominate_and_watch(&alice, vec![bob.account_id().clone()]) + .nominate_and_watch(&alice, vec![bob_stash.account_id().clone()]) .await?; let store = LedgerStore { controller: alice.account_id().clone(), @@ -327,19 +325,28 @@ mod tests { } #[async_std::test] - #[ignore] - // NOTE: this is throw-away code to be removed before merge - async fn test_scratchpad() -> Result<(), Error> { + async fn test_total_issuance_is_okay() -> Result<(), Error> { env_logger::try_init().ok(); - let alice = PairSigner::::new(AccountKeyring::Alice.pair()); - let bob = PairSigner::::new(AccountKeyring::Bob.pair()); - let client = ClientBuilder::::new().build().await?; - let current_era = client.current_era(None).await?; - println!("Current era: {:?}", current_era); - let hd = client.history_depth(None).await?; - println!("History depth: {:?}", hd); let total_issuance = client.total_issuance(None).await?; println!("total issuance: {:?}", total_issuance); + Ok(()) + } + + #[async_std::test] + async fn test_history_depth_is_okay() -> Result<(), Error> { + env_logger::try_init().ok(); + let client = ClientBuilder::::new().build().await?; + let history_depth = client.history_depth(None).await?; + assert_eq!(history_depth, 84); + Ok(()) + } + + #[async_std::test] + async fn test_current_era_is_okay() -> Result<(), Error> { + env_logger::try_init().ok(); + let client = ClientBuilder::::new().build().await?; + let _current_era = client.current_era(None).await?; + Ok(()) } } From 18e8029e1e9afc5bdeb138082e7ce853be5e159a Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sat, 19 Sep 2020 21:18:30 -0400 Subject: [PATCH 76/80] Remove unhelpful println! --- src/frame/staking.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 62f34cdfdb6..78041b5293f 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -328,8 +328,7 @@ mod tests { async fn test_total_issuance_is_okay() -> Result<(), Error> { env_logger::try_init().ok(); let client = ClientBuilder::::new().build().await?; - let total_issuance = client.total_issuance(None).await?; - println!("total issuance: {:?}", total_issuance); + client.total_issuance(None).await?; Ok(()) } From f7cda4ac73a2dd29b4c681a6d9642db5ae8b4d22 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sun, 20 Sep 2020 16:57:25 -0400 Subject: [PATCH 77/80] Revert changes in contract tests --- src/frame/contracts.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frame/contracts.rs b/src/frame/contracts.rs index e0a38068807..a3cfd149ed7 100644 --- a/src/frame/contracts.rs +++ b/src/frame/contracts.rs @@ -116,7 +116,6 @@ pub struct InstantiatedEvent { } #[cfg(test)] -#[cfg(feature = "integration-tests")] mod tests { use sp_keyring::AccountKeyring; @@ -138,6 +137,7 @@ mod tests { } #[async_std::test] + #[cfg(feature = "integration-tests")] async fn tx_put_code() { env_logger::try_init().ok(); @@ -161,6 +161,7 @@ mod tests { } #[async_std::test] + #[cfg(feature = "integration-tests")] async fn tx_instantiate() { env_logger::try_init().ok(); let signer = PairSigner::new(AccountKeyring::Bob.pair()); From 15c0206b34b06d58261870dda6a2c9501351e079 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sun, 20 Sep 2020 17:06:35 -0400 Subject: [PATCH 78/80] Reformat --- src/runtimes.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/runtimes.rs b/src/runtimes.rs index 63b55bbe6de..a54c4a96cde 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -121,11 +121,11 @@ use crate::{ AccountData, Balances, }, + session::Session, + staking::Staking, sudo::Sudo, + system::System, }, - session::Session, - staking::Staking, - system::System, }; /// Runtime trait. From d659e91c882ad402ff35cb0064ad033be95cd8e0 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sun, 20 Sep 2020 19:07:05 -0400 Subject: [PATCH 79/80] Remove spurious diff --- src/runtimes.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtimes.rs b/src/runtimes.rs index a54c4a96cde..cb8b9133a8e 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -111,7 +111,6 @@ impl_opaque_keys! { } use crate::{ - contracts::Contracts, extrinsic::{ DefaultExtra, SignedExtra, @@ -121,6 +120,7 @@ use crate::{ AccountData, Balances, }, + contracts::Contracts, session::Session, staking::Staking, sudo::Sudo, From 52960b7c4d5b91309c208e066e0ad1a2876bbab5 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sun, 20 Sep 2020 20:30:48 -0400 Subject: [PATCH 80/80] More tests --- src/frame/staking.rs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/frame/staking.rs b/src/frame/staking.rs index 78041b5293f..522473accb9 100644 --- a/src/frame/staking.rs +++ b/src/frame/staking.rs @@ -328,7 +328,8 @@ mod tests { async fn test_total_issuance_is_okay() -> Result<(), Error> { env_logger::try_init().ok(); let client = ClientBuilder::::new().build().await?; - client.total_issuance(None).await?; + let total_issuance = client.total_issuance(None).await?; + assert!(total_issuance > 1u128 << 32); Ok(()) } @@ -345,7 +346,26 @@ mod tests { async fn test_current_era_is_okay() -> Result<(), Error> { env_logger::try_init().ok(); let client = ClientBuilder::::new().build().await?; - let _current_era = client.current_era(None).await?; + let _current_era = client + .current_era(None) + .await? + .expect("current era always exists"); + Ok(()) + } + + #[async_std::test] + async fn test_era_reward_points_is_okay() -> Result<(), Error> { + env_logger::try_init().ok(); + let client = ClientBuilder::::new().build().await?; + let store = ErasRewardPointsStore { + _phantom: PhantomData, + index: 0, + }; + + let _current_era = client + .fetch(&store, None) + .await? + .expect("current era always exists"); Ok(()) } }