diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index bd99531542471..236b975817ffd 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -28,7 +28,7 @@ use sp_runtime::{ use frame_system::InitKind; use frame_support::{ parameter_types, - traits::{KeyOwnerProofSystem, OnInitialize}, + traits::{KeyOwnerProofSystem, OnInitialize, GenesisBuild}, }; use sp_io; use sp_core::{H256, U256, crypto::{IsWrappedBy, KeyTypeId, Pair}}; diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index df55f6037e303..752d94ce19085 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -24,7 +24,7 @@ use ::grandpa as finality_grandpa; use codec::Encode; use frame_support::{ parameter_types, - traits::{KeyOwnerProofSystem, OnFinalize, OnInitialize}, + traits::{KeyOwnerProofSystem, OnFinalize, OnInitialize, GenesisBuild}, }; use pallet_staking::EraIndex; use sp_core::{crypto::KeyTypeId, H256}; diff --git a/frame/offences/benchmarking/src/lib.rs b/frame/offences/benchmarking/src/lib.rs index e27c66c75a669..e7c61bfd989b4 100644 --- a/frame/offences/benchmarking/src/lib.rs +++ b/frame/offences/benchmarking/src/lib.rs @@ -42,7 +42,7 @@ use pallet_offences::{Config as OffencesConfig, Pallet as Offences}; use pallet_session::historical::{Config as HistoricalConfig, IdentificationTuple}; use pallet_session::{Config as SessionConfig, SessionManager}; use pallet_staking::{ - Module as Staking, Config as StakingConfig, RewardDestination, ValidatorPrefs, Exposure, + Pallet as Staking, Config as StakingConfig, RewardDestination, ValidatorPrefs, Exposure, IndividualExposure, Event as StakingEvent, }; diff --git a/frame/session/benchmarking/src/lib.rs b/frame/session/benchmarking/src/lib.rs index fff3717607f8f..d9a50b431f2e7 100644 --- a/frame/session/benchmarking/src/lib.rs +++ b/frame/session/benchmarking/src/lib.rs @@ -28,7 +28,6 @@ use sp_std::vec; use frame_benchmarking::{benchmarks, impl_benchmark_test_suite}; use frame_support::{ codec::Decode, - storage::StorageValue, traits::{KeyOwnerProofSystem, OnInitialize}, }; use frame_system::RawOrigin; @@ -59,7 +58,7 @@ benchmarks! { false, RewardDestination::Staked, )?; - let v_controller = pallet_staking::Module::::bonded(&v_stash).ok_or("not stash")?; + let v_controller = pallet_staking::Pallet::::bonded(&v_stash).ok_or("not stash")?; let keys = T::Keys::default(); let proof: Vec = vec![0,1,2,3]; // Whitelist controller account from further DB operations. @@ -75,7 +74,7 @@ benchmarks! { false, RewardDestination::Staked )?; - let v_controller = pallet_staking::Module::::bonded(&v_stash).ok_or("not stash")?; + let v_controller = pallet_staking::Pallet::::bonded(&v_stash).ok_or("not stash")?; let keys = T::Keys::default(); let proof: Vec = vec![0,1,2,3]; Session::::set_keys(RawOrigin::Signed(v_controller.clone()).into(), keys, proof)?; @@ -125,7 +124,7 @@ fn check_membership_proof_setup( (sp_runtime::KeyTypeId, &'static [u8; 32]), sp_session::MembershipProof, ) { - pallet_staking::ValidatorCount::put(n); + pallet_staking::ValidatorCount::::put(n); // create validators and set random session keys for (n, who) in create_validators::(n, 1000) @@ -137,7 +136,7 @@ fn check_membership_proof_setup( use rand::SeedableRng; let validator = T::Lookup::lookup(who).unwrap(); - let controller = pallet_staking::Module::::bonded(validator).unwrap(); + let controller = pallet_staking::Pallet::::bonded(validator).unwrap(); let keys = { let mut keys = [0u8; 128]; diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index 1d8a5c1fd6451..800d3379d7e3c 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -18,7 +18,7 @@ //! Staking pallet benchmarking. use super::*; -use crate::Module as Staking; +use crate::Pallet as Staking; use testing_utils::*; use sp_runtime::traits::One; @@ -88,7 +88,7 @@ pub fn create_validator_with_nominators( } } - ValidatorCount::put(1); + ValidatorCount::::put(1); // Start a new Era let new_validators = Staking::::new_era(SessionIndex::one()).unwrap(); @@ -102,7 +102,7 @@ pub fn create_validator_with_nominators( individual: points_individual.into_iter().collect(), }; - let current_era = CurrentEra::get().unwrap(); + let current_era = CurrentEra::::get().unwrap(); ErasRewardPoints::::insert(current_era, reward); // Create reward pool @@ -164,7 +164,7 @@ benchmarks! { add_slashing_spans::(&stash, s); let amount = T::Currency::minimum_balance() * 5u32.into(); // Half of total Staking::::unbond(RawOrigin::Signed(controller.clone()).into(), amount)?; - CurrentEra::put(EraIndex::max_value()); + CurrentEra::::put(EraIndex::max_value()); let ledger = Ledger::::get(&controller).ok_or("ledger not created before")?; let original_total: BalanceOf = ledger.total; whitelist_account!(controller); @@ -183,7 +183,7 @@ benchmarks! { add_slashing_spans::(&stash, s); let amount = T::Currency::minimum_balance() * 10u32.into(); Staking::::unbond(RawOrigin::Signed(controller.clone()).into(), amount)?; - CurrentEra::put(EraIndex::max_value()); + CurrentEra::::put(EraIndex::max_value()); let ledger = Ledger::::get(&controller).ok_or("ledger not created before")?; let original_total: BalanceOf = ledger.total; whitelist_account!(controller); @@ -303,17 +303,17 @@ benchmarks! { let validator_count = MAX_VALIDATORS; }: _(RawOrigin::Root, validator_count) verify { - assert_eq!(ValidatorCount::get(), validator_count); + assert_eq!(ValidatorCount::::get(), validator_count); } force_no_eras {}: _(RawOrigin::Root) - verify { assert_eq!(ForceEra::get(), Forcing::ForceNone); } + verify { assert_eq!(ForceEra::::get(), Forcing::ForceNone); } force_new_era {}: _(RawOrigin::Root) - verify { assert_eq!(ForceEra::get(), Forcing::ForceNew); } + verify { assert_eq!(ForceEra::::get(), Forcing::ForceNew); } force_new_era_always {}: _(RawOrigin::Root) - verify { assert_eq!(ForceEra::get(), Forcing::ForceAlways); } + verify { assert_eq!(ForceEra::::get(), Forcing::ForceAlways); } // Worst case scenario, the list of invulnerables is very long. set_invulnerables { @@ -361,7 +361,7 @@ benchmarks! { RewardDestination::Controller, )?; - let current_era = CurrentEra::get().unwrap(); + let current_era = CurrentEra::::get().unwrap(); // set the commission for this particular era as well. >::insert(current_era, validator.clone(), >::validators(&validator)); @@ -394,7 +394,7 @@ benchmarks! { RewardDestination::Staked, )?; - let current_era = CurrentEra::get().unwrap(); + let current_era = CurrentEra::::get().unwrap(); // set the commission for this particular era as well. >::insert(current_era, validator.clone(), >::validators(&validator)); @@ -444,8 +444,8 @@ benchmarks! { set_history_depth { let e in 1 .. 100; - HistoryDepth::put(e); - CurrentEra::put(e); + HistoryDepth::::put(e); + CurrentEra::::put(e); for i in 0 .. e { >::insert(i, T::AccountId::default(), Exposure::>::default()); >::insert(i, T::AccountId::default(), Exposure::>::default()); @@ -453,11 +453,11 @@ benchmarks! { >::insert(i, BalanceOf::::one()); >::insert(i, EraRewardPoints::::default()); >::insert(i, BalanceOf::::one()); - ErasStartSessionIndex::insert(i, i); + ErasStartSessionIndex::::insert(i, i); } }: _(RawOrigin::Root, EraIndex::zero(), u32::max_value()) verify { - assert_eq!(HistoryDepth::get(), 0); + assert_eq!(HistoryDepth::::get(), 0); } reap_stash { @@ -503,7 +503,7 @@ benchmarks! { let new_validators = Staking::::new_era(SessionIndex::one()).unwrap(); assert!(new_validators.len() == v as usize); - let current_era = CurrentEra::get().unwrap(); + let current_era = CurrentEra::::get().unwrap(); let mut points_total = 0; let mut points_individual = Vec::new(); let mut payout_calls_arg = Vec::new(); @@ -636,7 +636,7 @@ mod tests { assert_eq!(nominators.len() as u32, n); - let current_era = CurrentEra::get().unwrap(); + let current_era = CurrentEra::::get().unwrap(); let original_free_balance = Balances::free_balance(&validator_stash); assert_ok!(Staking::payout_stakers(Origin::signed(1337), validator_stash, current_era)); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 888601e307f35..49660350ba916 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -15,17 +15,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! # Staking Module +//! # Staking Pallet //! -//! The Staking module is used to manage funds at stake by network maintainers. +//! The Staking pallet is used to manage funds at stake by network maintainers. //! //! - [`Config`] //! - [`Call`] -//! - [`Module`] +//! - [`Pallet`] //! //! ## Overview //! -//! The Staking module is the means by which a set of network maintainers (known as _authorities_ in +//! The Staking pallet is the means by which a set of network maintainers (known as _authorities_ in //! some contexts and _validators_ in others) are chosen based upon those who voluntarily place //! funds under deposit. Under deposit, those funds are rewarded under normal operation but are held //! at pain of _slash_ (expropriation) should the staked maintainer be found not to be discharging @@ -59,7 +59,7 @@ //! //! #### Staking //! -//! Almost any interaction with the Staking module requires a process of _**bonding**_ (also known +//! Almost any interaction with the Staking pallet requires a process of _**bonding**_ (also known //! as being a _staker_). To become *bonded*, a fund-holding account known as the _stash account_, //! which holds some or all of the funds that become frozen in place as part of the staking process, //! is paired with an active **controller** account, which issues instructions on how they shall be @@ -102,7 +102,7 @@ //! //! #### Rewards and Slash //! -//! The **reward and slashing** procedure is the core of the Staking module, attempting to _embrace +//! The **reward and slashing** procedure is the core of the Staking pallet, attempting to _embrace //! valid behavior_ while _punishing any misbehavior or lack of availability_. //! //! Rewards must be claimed for each era before it gets too old by `$HISTORY_DEPTH` using the @@ -115,7 +115,7 @@ //! determined, a value is deducted from the balance of the validator and all the nominators who //! voted for this validator (values are deducted from the _stash_ account of the slashed entity). //! -//! Slashing logic is further described in the documentation of the `slashing` module. +//! Slashing logic is further described in the documentation of the `slashing` pallet. //! //! Similar to slashing, rewards are also shared among a validator and its associated nominators. //! Yet, the reward funds are not always transferred to the stash account and can be configured. See @@ -131,19 +131,19 @@ //! //! ### Session managing //! -//! The module implement the trait `SessionManager`. Which is the only API to query new validator +//! The pallet implement the trait `SessionManager`. Which is the only API to query new validator //! set and allowing these validator set to be rewarded once their era is ended. //! //! ## Interface //! //! ### Dispatchable Functions //! -//! The dispatchable functions of the Staking module enable the steps needed for entities to accept -//! and change their role, alongside some helper functions to get/set the metadata of the module. +//! The dispatchable functions of the Staking pallet enable the steps needed for entities to accept +//! and change their role, alongside some helper functions to get/set the metadata of the pallet. //! //! ### Public Functions //! -//! The Staking module contains many public storage items and (im)mutable functions. +//! The Staking pallet contains many public storage items and (im)mutable functions. //! //! ## Usage //! @@ -162,7 +162,7 @@ //! #[weight = 0] //! pub fn reward_myself(origin) -> dispatch::DispatchResult { //! let reported = ensure_signed(origin)?; -//! >::reward_by_ids(vec![(reported, 10)]); +//! >::reward_by_ids(vec![(reported, 10)]); //! Ok(()) //! } //! } @@ -198,9 +198,9 @@ //! //! Total reward is split among validators and their nominators depending on the number of points //! they received during the era. Points are added to a validator using -//! [`reward_by_ids`](Module::reward_by_ids). +//! [`reward_by_ids`](Pallet::reward_by_ids). //! -//! [`Module`] implements +//! [`Pallet`] implements //! [`pallet_authorship::EventHandler`] to add reward //! points to block producer and block producer of referenced uncles. //! @@ -255,14 +255,14 @@ //! //! ## GenesisConfig //! -//! The Staking module depends on the [`GenesisConfig`]. The +//! The Staking pallet depends on the [`GenesisConfig`]. The //! `GenesisConfig` is optional and allow to set some initial stakers. //! //! ## Related Modules //! //! - [Balances](../pallet_balances/index.html): Used to manage values at stake. //! - [Session](../pallet_session/index.html): Used to manage sessions. Also, a list of new -//! validators is stored in the Session module's `Validators` at the end of each era. +//! validators is stored in the Session pallet's `Validators` at the end of each era. #![recursion_limit = "128"] #![cfg_attr(not(feature = "std"), no_std)] @@ -288,13 +288,11 @@ use sp_std::{ }; use codec::{HasCompact, Encode, Decode}; use frame_support::{ - decl_module, decl_event, decl_storage, ensure, decl_error, + pallet_prelude::*, weights::{ Weight, WithPostDispatchInfo, constants::{WEIGHT_PER_MICROS, WEIGHT_PER_NANOS}, }, - storage::IterableStorageMap, - dispatch::{DispatchResult, DispatchResultWithPostInfo}, traits::{ Currency, LockIdentifier, LockableCurrency, WithdrawReasons, OnUnbalanced, Imbalance, Get, UnixTime, EstimateNextNewSession, EnsureOrigin, CurrencyToVote, @@ -314,11 +312,12 @@ use sp_staking::{ offence::{OnOffenceHandler, OffenceDetails, Offence, ReportOffence, OffenceError}, }; use frame_system::{ - self as system, ensure_signed, ensure_root, + ensure_signed, ensure_root, pallet_prelude::*, offchain::SendTransactionTypes, }; use frame_election_provider_support::{ElectionProvider, VoteWeight, Supports, data_provider}; pub use weights::WeightInfo; +pub use pallet::*; const STAKING_ID: LockIdentifier = *b"staking "; pub(crate) const LOG_TARGET: &'static str = "runtime::staking"; @@ -342,7 +341,7 @@ pub type EraIndex = u32; /// Counter for the number of "reward" points earned by a given validator. pub type RewardPoint = u32; -/// The balance type of this module. +/// The balance type of this pallet. pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; @@ -654,15 +653,15 @@ impl SessionInterface<::AccountId> for T w Convert<::AccountId, Option<::AccountId>>, { fn disable_validator(validator: &::AccountId) -> Result { - >::disable(validator) + >::disable(validator) } fn validators() -> Vec<::AccountId> { - >::validators() + >::validators() } fn prune_historical_up_to(up_to: SessionIndex) { - >::prune_up_to(up_to); + >::prune_up_to(up_to); } } @@ -713,82 +712,6 @@ impl< } } -pub trait Config: frame_system::Config + SendTransactionTypes> { - /// The staking balance. - type Currency: LockableCurrency; - - /// Time used for computing era duration. - /// - /// It is guaranteed to start being called from the first `on_finalize`. Thus value at genesis - /// is not used. - type UnixTime: UnixTime; - - /// Convert a balance into a number used for election calculation. This must fit into a `u64` - /// but is allowed to be sensibly lossy. The `u64` is used to communicate with the - /// [`sp_npos_elections`] crate which accepts u64 numbers and does operations in 128. - /// Consequently, the backward convert is used convert the u128s from sp-elections back to a - /// [`BalanceOf`]. - type CurrencyToVote: CurrencyToVote>; - - /// Something that provides the election functionality. - type ElectionProvider: frame_election_provider_support::ElectionProvider< - Self::AccountId, - Self::BlockNumber, - // we only accept an election provider that has staking as data provider. - DataProvider = Module, - >; - - /// Maximum number of nominations per nominator. - const MAX_NOMINATIONS: u32; - - /// Tokens have been minted and are unused for validator-reward. - /// See [Era payout](./index.html#era-payout). - type RewardRemainder: OnUnbalanced>; - - /// The overarching event type. - type Event: From> + Into<::Event>; - - /// Handler for the unbalanced reduction when slashing a staker. - type Slash: OnUnbalanced>; - - /// Handler for the unbalanced increment when rewarding a staker. - type Reward: OnUnbalanced>; - - /// Number of sessions per era. - type SessionsPerEra: Get; - - /// Number of eras that staked funds must remain bonded for. - type BondingDuration: Get; - - /// Number of eras that slashes are deferred by, after computation. - /// - /// This should be less than the bonding duration. Set to 0 if slashes - /// should be applied immediately, without opportunity for intervention. - type SlashDeferDuration: Get; - - /// The origin which can cancel a deferred slash. Root can always do this. - type SlashCancelOrigin: EnsureOrigin; - - /// Interface for interacting with a session module. - type SessionInterface: self::SessionInterface; - - /// The payout for validators and the system for the current era. - /// See [Era payout](./index.html#era-payout). - type EraPayout: EraPayout>; - - /// Something that can estimate the next session change, accurately or as a best effort guess. - type NextNewSession: EstimateNextNewSession; - - /// The maximum number of nominators rewarded for each validator. - /// - /// For each validator only the `$MaxNominatorRewardedPerValidator` biggest stakers can claim - /// their reward. This used to limit the i/o cost for the nominator payout. - type MaxNominatorRewardedPerValidator: Get; - - /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; -} - /// Mode of era-forcing. #[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] @@ -828,183 +751,447 @@ impl Default for Releases { } } -decl_storage! { - trait Store for Module as 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. - HistoryDepth get(fn history_depth) config(): u32 = 84; +pub mod migrations { + use super::*; - /// The ideal number of staking participants. - pub ValidatorCount get(fn validator_count) config(): u32; + pub mod v6 { + use super::*; + use frame_support::{traits::Get, weights::Weight, generate_storage_alias}; - /// Minimum number of staking participants before emergency conditions are imposed. - pub MinimumValidatorCount get(fn minimum_validator_count) config(): u32; + // NOTE: value type doesn't matter, we just set it to () here. + generate_storage_alias!(Staking, SnapshotValidators => Value<()>); + generate_storage_alias!(Staking, SnapshotNominators => Value<()>); + generate_storage_alias!(Staking, QueuedElected => Value<()>); + generate_storage_alias!(Staking, QueuedScore => Value<()>); + generate_storage_alias!(Staking, EraElectionStatus => Value<()>); + generate_storage_alias!(Staking, IsCurrentSessionFinal => Value<()>); - /// 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 Invulnerables get(fn invulnerables) config(): Vec; + /// check to execute prior to migration. + pub fn pre_migrate() -> Result<(), &'static str> { + // these may or may not exist. + log!(info, "SnapshotValidators.exits()? {:?}", SnapshotValidators::exists()); + log!(info, "SnapshotNominators.exits()? {:?}", SnapshotNominators::exists()); + log!(info, "QueuedElected.exits()? {:?}", QueuedElected::exists()); + log!(info, "QueuedScore.exits()? {:?}", QueuedScore::exists()); + // these must exist. + assert!(IsCurrentSessionFinal::exists(), "IsCurrentSessionFinal storage item not found!"); + assert!(EraElectionStatus::exists(), "EraElectionStatus storage item not found!"); + Ok(()) + } - /// Map from all locked "stash" accounts to the controller account. - pub Bonded get(fn bonded): map hasher(twox_64_concat) T::AccountId => Option; + /// Migrate storage to v6. + pub fn migrate() -> Weight { + log!(info, "Migrating staking to Releases::V6_0_0"); - /// Map from all (unlocked) "controller" accounts to the info regarding the staking. - pub Ledger get(fn ledger): - map hasher(blake2_128_concat) T::AccountId - => Option>>; + SnapshotValidators::kill(); + SnapshotNominators::kill(); + QueuedElected::kill(); + QueuedScore::kill(); + EraElectionStatus::kill(); + IsCurrentSessionFinal::kill(); - /// Where the reward payment should be made. Keyed by stash. - pub Payee get(fn payee): map hasher(twox_64_concat) T::AccountId => RewardDestination; + StorageVersion::::put(Releases::V6_0_0); + log!(info, "Done."); + T::DbWeight::get().writes(6 + 1) + } + } +} - /// The map from (wannabe) validator stash key to the preferences of that validator. - pub Validators get(fn validators): - map hasher(twox_64_concat) T::AccountId => ValidatorPrefs; +#[frame_support::pallet] +pub mod pallet { + use super::*; - /// The map from nominator stash key to the set of stash keys of all validators to nominate. - pub Nominators get(fn nominators): - map hasher(twox_64_concat) T::AccountId => Option>; + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); - /// 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 CurrentEra get(fn current_era): Option; + #[pallet::config] + pub trait Config: frame_system::Config + SendTransactionTypes> { + /// The staking balance. + type Currency: LockableCurrency; - /// The active era information, it holds index and start. + /// Time used for computing era duration. /// - /// The active era is the era being currently rewarded. Validator set of this era must be - /// equal to [`SessionInterface::validators`]. - pub ActiveEra get(fn active_era): Option; + /// It is guaranteed to start being called from the first `on_finalize`. Thus value at genesis + /// is not used. + type UnixTime: UnixTime; - /// The session index at which the era start for the last `HISTORY_DEPTH` eras. - /// - /// Note: This tracks the starting session (i.e. session index when era start being active) - /// for the eras in `[CurrentEra - HISTORY_DEPTH, CurrentEra]`. - pub ErasStartSessionIndex get(fn eras_start_session_index): - map hasher(twox_64_concat) EraIndex => Option; + /// Convert a balance into a number used for election calculation. This must fit into a `u64` + /// but is allowed to be sensibly lossy. The `u64` is used to communicate with the + /// [`sp_npos_elections`] crate which accepts u64 numbers and does operations in 128. + /// Consequently, the backward convert is used convert the u128s from sp-elections back to a + /// [`BalanceOf`]. + type CurrencyToVote: CurrencyToVote>; - /// Exposure of validator at era. - /// - /// This is keyed first 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. - pub ErasStakers get(fn eras_stakers): - double_map hasher(twox_64_concat) EraIndex, hasher(twox_64_concat) T::AccountId - => Exposure>; + /// Something that provides the election functionality. + type ElectionProvider: frame_election_provider_support::ElectionProvider< + Self::AccountId, + Self::BlockNumber, + // we only accept an election provider that has staking as data provider. + DataProvider = Pallet, + >; - /// 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. - pub ErasStakersClipped get(fn eras_stakers_clipped): - double_map hasher(twox_64_concat) EraIndex, hasher(twox_64_concat) T::AccountId - => Exposure>; + /// Maximum number of nominations per nominator. + const MAX_NOMINATIONS: u32; - /// 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. - // If prefs hasn't been set or has been removed then 0 commission is returned. - pub ErasValidatorPrefs get(fn eras_validator_prefs): - double_map hasher(twox_64_concat) EraIndex, hasher(twox_64_concat) T::AccountId - => ValidatorPrefs; + /// Tokens have been minted and are unused for validator-reward. + /// See [Era payout](./index.html#era-payout). + type RewardRemainder: OnUnbalanced>; - /// The total validator era payout for the last `HISTORY_DEPTH` eras. - /// - /// Eras that haven't finished yet or has been removed doesn't have reward. - pub ErasValidatorReward get(fn eras_validator_reward): - map hasher(twox_64_concat) EraIndex => Option>; + /// The overarching event type. + type Event: From> + IsType<::Event>; - /// Rewards for the last `HISTORY_DEPTH` eras. - /// If reward hasn't been set or has been removed then 0 reward is returned. - pub ErasRewardPoints get(fn eras_reward_points): - map hasher(twox_64_concat) EraIndex => EraRewardPoints; + /// Handler for the unbalanced reduction when slashing a staker. + type Slash: OnUnbalanced>; - /// The total amount staked for the last `HISTORY_DEPTH` eras. - /// If total hasn't been set or has been removed then 0 stake is returned. - pub ErasTotalStake get(fn eras_total_stake): - map hasher(twox_64_concat) EraIndex => BalanceOf; + /// Handler for the unbalanced increment when rewarding a staker. + type Reward: OnUnbalanced>; - /// Mode of era forcing. - pub ForceEra get(fn force_era) config(): Forcing; + /// Number of sessions per era. + #[pallet::constant] + type SessionsPerEra: Get; - /// The percentage of the slash that is distributed to reporters. + /// Number of eras that staked funds must remain bonded for. + #[pallet::constant] + type BondingDuration: Get; + + /// Number of eras that slashes are deferred by, after computation. /// - /// The rest of the slashed value is handled by the `Slash`. - pub SlashRewardFraction get(fn slash_reward_fraction) config(): Perbill; + /// This should be less than the bonding duration. Set to 0 if slashes + /// should be applied immediately, without opportunity for intervention. + #[pallet::constant] + type SlashDeferDuration: Get; + + /// The origin which can cancel a deferred slash. Root can always do this. + type SlashCancelOrigin: EnsureOrigin; - /// The amount of currency given to reporters of a slash event which was - /// canceled by extraordinary circumstances (e.g. governance). - pub CanceledSlashPayout get(fn canceled_payout) config(): BalanceOf; + /// Interface for interacting with a session pallet. + type SessionInterface: self::SessionInterface; - /// All unapplied slashes that are queued for later. - pub UnappliedSlashes: - map hasher(twox_64_concat) EraIndex => Vec>>; + /// The payout for validators and the system for the current era. + /// See [Era payout](./index.html#era-payout). + type EraPayout: EraPayout>; - /// A mapping from still-bonded eras to the first session index of that era. + /// Something that can estimate the next session change, accurately or as a best effort guess. + type NextNewSession: EstimateNextNewSession; + + /// The maximum number of nominators rewarded for each validator. /// - /// Must contains information for eras for the range: - /// `[active_era - bounding_duration; active_era]` - BondedEras: Vec<(EraIndex, SessionIndex)>; + /// For each validator only the `$MaxNominatorRewardedPerValidator` biggest stakers can claim + /// their reward. This used to limit the i/o cost for the nominator payout. + #[pallet::constant] + type MaxNominatorRewardedPerValidator: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::extra_constants] + impl Pallet { + //TODO: rename to snake case after https://github.com/paritytech/substrate/issues/8826 fixed. + #[allow(non_snake_case)] + fn MaxNominations() -> u32 { + T::MAX_NOMINATIONS + } + } - /// All slashing events on validators, mapped by era to the highest slash proportion - /// and slash value of the era. - ValidatorSlashInEra: - double_map hasher(twox_64_concat) EraIndex, hasher(twox_64_concat) T::AccountId - => Option<(Perbill, BalanceOf)>; + #[pallet::type_value] + pub(crate) fn HistoryDepthOnEmpty() -> u32 { 84u32 } - /// All slashing events on nominators, mapped by era to the highest slash value of the era. - NominatorSlashInEra: - double_map hasher(twox_64_concat) EraIndex, hasher(twox_64_concat) T::AccountId - => Option>; + /// 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. + #[pallet::storage] + #[pallet::getter(fn history_depth)] + pub(crate) type HistoryDepth = StorageValue<_, u32, ValueQuery, HistoryDepthOnEmpty>; + + /// The ideal number of staking participants. + #[pallet::storage] + #[pallet::getter(fn validator_count)] + pub type ValidatorCount = StorageValue<_, u32, ValueQuery>; + + /// Minimum number of staking participants before emergency conditions are imposed. + #[pallet::storage] + #[pallet::getter(fn minimum_validator_count)] + pub type MinimumValidatorCount = StorageValue<_, u32, ValueQuery>; + + /// 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. + #[pallet::storage] + #[pallet::getter(fn invulnerables)] + pub type Invulnerables = StorageValue<_, Vec, ValueQuery>; + + /// Map from all locked "stash" accounts to the controller account. + #[pallet::storage] + #[pallet::getter(fn bonded)] + pub type Bonded = StorageMap<_, Twox64Concat, T::AccountId, T::AccountId>; + + /// Map from all (unlocked) "controller" accounts to the info regarding the staking. + #[pallet::storage] + #[pallet::getter(fn ledger)] + pub type Ledger = StorageMap< + _, + Blake2_128Concat, T::AccountId, + StakingLedger>, + >; - /// Slashing spans for stash accounts. - SlashingSpans get(fn slashing_spans): map hasher(twox_64_concat) T::AccountId => Option; + /// Where the reward payment should be made. Keyed by stash. + #[pallet::storage] + #[pallet::getter(fn payee)] + pub type Payee = StorageMap< + _, + Twox64Concat, T::AccountId, + RewardDestination, + ValueQuery, + >; - /// Records information about the maximum slash of a stash within a slashing span, - /// as well as how much reward has been paid out. - SpanSlash: - map hasher(twox_64_concat) (T::AccountId, slashing::SpanIndex) - => slashing::SpanRecord>; + /// The map from (wannabe) validator stash key to the preferences of that validator. + #[pallet::storage] + #[pallet::getter(fn validators)] + pub type Validators = StorageMap<_, Twox64Concat, T::AccountId, ValidatorPrefs, ValueQuery>; - /// The earliest era for which we have a pending, unapplied slash. - EarliestUnappliedSlash: Option; + /// The map from nominator stash key to the set of stash keys of all validators to nominate. + #[pallet::storage] + #[pallet::getter(fn nominators)] + pub type Nominators = StorageMap<_, Twox64Concat, T::AccountId, Nominations>; - /// The last planned session scheduled by the session pallet. - /// - /// This is basically in sync with the call to [`SessionManager::new_session`]. - pub CurrentPlannedSession get(fn current_planned_session): SessionIndex; + /// 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. + #[pallet::storage] + #[pallet::getter(fn current_era)] + pub type CurrentEra = StorageValue<_, EraIndex>; - /// True if network has been upgraded to this version. - /// Storage version of the pallet. - /// - /// This is set to v6.0.0 for new networks. - StorageVersion build(|_: &GenesisConfig| Releases::V6_0_0): Releases; + /// The active era information, it holds index and start. + /// + /// The active era is the era being currently rewarded. Validator set of this era must be + /// equal to [`SessionInterface::validators`]. + #[pallet::storage] + #[pallet::getter(fn active_era)] + pub type ActiveEra = StorageValue<_, ActiveEraInfo>; + + /// The session index at which the era start for the last `HISTORY_DEPTH` eras. + /// + /// Note: This tracks the starting session (i.e. session index when era start being active) + /// for the eras in `[CurrentEra - HISTORY_DEPTH, CurrentEra]`. + #[pallet::storage] + #[pallet::getter(fn eras_start_session_index)] + pub type ErasStartSessionIndex = StorageMap<_, Twox64Concat, EraIndex, SessionIndex>; + + /// Exposure of validator at era. + /// + /// This is keyed first 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. + #[pallet::storage] + #[pallet::getter(fn eras_stakers)] + pub type ErasStakers = StorageDoubleMap< + _, + Twox64Concat, EraIndex, + Twox64Concat, T::AccountId, + Exposure>, + ValueQuery, + >; + + /// 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. + #[pallet::storage] + #[pallet::getter(fn eras_stakers_clipped)] + pub type ErasStakersClipped = StorageDoubleMap< + _, + Twox64Concat, EraIndex, + Twox64Concat, T::AccountId, + Exposure>, + ValueQuery, + >; + + /// 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. + // If prefs hasn't been set or has been removed then 0 commission is returned. + #[pallet::storage] + #[pallet::getter(fn eras_validator_prefs)] + pub type ErasValidatorPrefs = StorageDoubleMap< + _, + Twox64Concat, EraIndex, + Twox64Concat, T::AccountId, + ValidatorPrefs, + ValueQuery, + >; + + /// The total validator era payout for the last `HISTORY_DEPTH` eras. + /// + /// Eras that haven't finished yet or has been removed doesn't have reward. + #[pallet::storage] + #[pallet::getter(fn eras_validator_reward)] + pub type ErasValidatorReward = StorageMap<_, Twox64Concat, EraIndex, BalanceOf>; + + /// Rewards for the last `HISTORY_DEPTH` eras. + /// If reward hasn't been set or has been removed then 0 reward is returned. + #[pallet::storage] + #[pallet::getter(fn eras_reward_points)] + pub type ErasRewardPoints = StorageMap< + _, + Twox64Concat, EraIndex, + EraRewardPoints, + ValueQuery, + >; + + /// The total amount staked for the last `HISTORY_DEPTH` eras. + /// If total hasn't been set or has been removed then 0 stake is returned. + #[pallet::storage] + #[pallet::getter(fn eras_total_stake)] + pub type ErasTotalStake = StorageMap<_, Twox64Concat, EraIndex, BalanceOf, ValueQuery>; + + /// Mode of era forcing. + #[pallet::storage] + #[pallet::getter(fn force_era)] + pub type ForceEra = StorageValue<_, Forcing, ValueQuery>; + + /// The percentage of the slash that is distributed to reporters. + /// + /// The rest of the slashed value is handled by the `Slash`. + #[pallet::storage] + #[pallet::getter(fn slash_reward_fraction)] + pub type SlashRewardFraction = StorageValue<_, Perbill, ValueQuery>; + + /// The amount of currency given to reporters of a slash event which was + /// canceled by extraordinary circumstances (e.g. governance). + #[pallet::storage] + #[pallet::getter(fn canceled_payout)] + pub type CanceledSlashPayout = StorageValue<_, BalanceOf, ValueQuery>; + + /// All unapplied slashes that are queued for later. + #[pallet::storage] + pub type UnappliedSlashes = StorageMap< + _, + Twox64Concat, EraIndex, + Vec>>, + ValueQuery, + >; + + /// A mapping from still-bonded eras to the first session index of that era. + /// + /// Must contains information for eras for the range: + /// `[active_era - bounding_duration; active_era]` + #[pallet::storage] + pub(crate) type BondedEras = StorageValue<_, Vec<(EraIndex, SessionIndex)>, ValueQuery>; + + /// All slashing events on validators, mapped by era to the highest slash proportion + /// and slash value of the era. + #[pallet::storage] + pub(crate) type ValidatorSlashInEra = StorageDoubleMap< + _, + Twox64Concat, EraIndex, + Twox64Concat, T::AccountId, + (Perbill, BalanceOf), + >; + + /// All slashing events on nominators, mapped by era to the highest slash value of the era. + #[pallet::storage] + pub(crate) type NominatorSlashInEra = StorageDoubleMap< + _, + Twox64Concat, EraIndex, + Twox64Concat, T::AccountId, + BalanceOf, + >; + + /// Slashing spans for stash accounts. + #[pallet::storage] + pub(crate) type SlashingSpans = StorageMap<_, Twox64Concat, T::AccountId, slashing::SlashingSpans>; + + /// Records information about the maximum slash of a stash within a slashing span, + /// as well as how much reward has been paid out. + #[pallet::storage] + pub(crate) type SpanSlash = StorageMap< + _, + Twox64Concat, (T::AccountId, slashing::SpanIndex), + slashing::SpanRecord>, + ValueQuery, + >; + + /// The earliest era for which we have a pending, unapplied slash. + #[pallet::storage] + pub(crate) type EarliestUnappliedSlash = StorageValue<_, EraIndex>; + + /// The last planned session scheduled by the session pallet. + /// + /// This is basically in sync with the call to [`SessionManager::new_session`]. + #[pallet::storage] + #[pallet::getter(fn current_planned_session)] + pub type CurrentPlannedSession = StorageValue<_, SessionIndex, ValueQuery>; + + /// True if network has been upgraded to this version. + /// Storage version of the pallet. + /// + /// This is set to v6.0.0 for new networks. + #[pallet::storage] + pub(crate) type StorageVersion = StorageValue<_, Releases, ValueQuery>; + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub history_depth: u32, + pub validator_count: u32, + pub minimum_validator_count: u32, + pub invulnerables: Vec, + pub force_era: Forcing, + pub slash_reward_fraction: Perbill, + pub canceled_payout: BalanceOf, + pub stakers: Vec<(T::AccountId, T::AccountId, BalanceOf, StakerStatus)>, } - add_extra_genesis { - config(stakers): - Vec<(T::AccountId, T::AccountId, BalanceOf, StakerStatus)>; - build(|config: &GenesisConfig| { - for &(ref stash, ref controller, balance, ref status) in &config.stakers { + + #[cfg(feature = "std")] + impl Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { + history_depth: 84u32, + validator_count: Default::default(), + minimum_validator_count: Default::default(), + invulnerables: Default::default(), + force_era: Default::default(), + slash_reward_fraction: Default::default(), + canceled_payout: Default::default(), + stakers: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + HistoryDepth::::put(self.history_depth); + ValidatorCount::::put(self.validator_count); + MinimumValidatorCount::::put(self.minimum_validator_count); + Invulnerables::::put(&self.invulnerables); + ForceEra::::put(self.force_era); + CanceledSlashPayout::::put(self.canceled_payout); + SlashRewardFraction::::put(self.slash_reward_fraction); + StorageVersion::::put(Releases::V6_0_0); + + for &(ref stash, ref controller, balance, ref status) in &self.stakers { assert!( T::Currency::free_balance(&stash) >= balance, "Stash does not have enough balance to bond." ); - let _ = >::bond( + let _ = >::bond( T::Origin::from(Some(stash.clone()).into()), T::Lookup::unlookup(controller.clone()), balance, @@ -1012,80 +1199,35 @@ decl_storage! { ); let _ = match status { StakerStatus::Validator => { - >::validate( + >::validate( T::Origin::from(Some(controller.clone()).into()), Default::default(), ) }, StakerStatus::Nominator(votes) => { - >::nominate( + >::nominate( T::Origin::from(Some(controller.clone()).into()), votes.iter().map(|l| T::Lookup::unlookup(l.clone())).collect(), ) }, _ => Ok(()) }; } - }); - } -} - -pub mod migrations { - use super::*; - - pub mod v6 { - use super::*; - use frame_support::{traits::Get, weights::Weight, generate_storage_alias}; - - // NOTE: value type doesn't matter, we just set it to () here. - generate_storage_alias!(Staking, SnapshotValidators => Value<()>); - generate_storage_alias!(Staking, SnapshotNominators => Value<()>); - generate_storage_alias!(Staking, QueuedElected => Value<()>); - generate_storage_alias!(Staking, QueuedScore => Value<()>); - generate_storage_alias!(Staking, EraElectionStatus => Value<()>); - generate_storage_alias!(Staking, IsCurrentSessionFinal => Value<()>); - - /// check to execute prior to migration. - pub fn pre_migrate() -> Result<(), &'static str> { - // these may or may not exist. - log!(info, "SnapshotValidators.exits()? {:?}", SnapshotValidators::exists()); - log!(info, "SnapshotNominators.exits()? {:?}", SnapshotNominators::exists()); - log!(info, "QueuedElected.exits()? {:?}", QueuedElected::exists()); - log!(info, "QueuedScore.exits()? {:?}", QueuedScore::exists()); - // these must exist. - assert!(IsCurrentSessionFinal::exists(), "IsCurrentSessionFinal storage item not found!"); - assert!(EraElectionStatus::exists(), "EraElectionStatus storage item not found!"); - Ok(()) - } - - /// Migrate storage to v6. - pub fn migrate() -> Weight { - log!(info, "Migrating staking to Releases::V6_0_0"); - - SnapshotValidators::kill(); - SnapshotNominators::kill(); - QueuedElected::kill(); - QueuedScore::kill(); - EraElectionStatus::kill(); - IsCurrentSessionFinal::kill(); - - StorageVersion::put(Releases::V6_0_0); - log!(info, "Done."); - T::DbWeight::get().writes(6 + 1) } } -} -decl_event!( - pub enum Event where Balance = BalanceOf, ::AccountId { + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + #[pallet::metadata(T::AccountId = "AccountId", BalanceOf = "Balance")] + pub enum Event { /// The era payout has been set; the first balance is the validator-payout; the second is /// the remainder from the maximum amount of reward. /// \[era_index, validator_payout, remainder\] - EraPayout(EraIndex, Balance, Balance), + EraPayout(EraIndex, BalanceOf, BalanceOf), /// The staker has been rewarded by this amount. \[stash, amount\] - Reward(AccountId, Balance), + Reward(T::AccountId, BalanceOf), /// One validator (and its nominators) has been slashed by the given amount. /// \[validator, amount\] - Slash(AccountId, Balance), + Slash(T::AccountId, BalanceOf), /// An old slashing report from a prior era was discarded because it could /// not be processed. \[session_index\] OldSlashingReportDiscarded(SessionIndex), @@ -1095,20 +1237,18 @@ decl_event!( /// /// NOTE: This event is only emitted when funds are bonded via a dispatchable. Notably, /// it will not be emitted for staking rewards when they are added to stake. - Bonded(AccountId, Balance), + Bonded(T::AccountId, BalanceOf), /// An account has unbonded this amount. \[stash, amount\] - Unbonded(AccountId, Balance), + Unbonded(T::AccountId, BalanceOf), /// An account has called `withdraw_unbonded` and removed unbonding chunks worth `Balance` /// from the unlocking queue. \[stash, amount\] - Withdrawn(AccountId, Balance), + Withdrawn(T::AccountId, BalanceOf), /// A nominator has been kicked from a validator. \[nominator, stash\] - Kicked(AccountId, AccountId), + Kicked(T::AccountId, T::AccountId), } -); -decl_error! { - /// Error for the staking module. - pub enum Error for Module { + #[pallet::error] + pub enum Error { /// Not a controller account. NotController, /// Not a stash account. @@ -1150,73 +1290,51 @@ decl_error! { /// A nomination target was supplied that was blocked or otherwise not a validator. BadTarget, } -} - -decl_module! { - pub struct Module for enum Call where origin: T::Origin { - /// Number of sessions per era. - const SessionsPerEra: SessionIndex = T::SessionsPerEra::get(); - - /// Number of eras that staked funds must remain bonded for. - const BondingDuration: EraIndex = T::BondingDuration::get(); - - /// Number of eras that slashes are deferred by, after computation. - /// - /// This should be less than the bonding duration. - /// Set to 0 if slashes should be applied immediately, without opportunity for - /// intervention. - const SlashDeferDuration: EraIndex = T::SlashDeferDuration::get(); - - /// The maximum number of nominators rewarded for each validator. - /// - /// For each validator only the `$MaxNominatorRewardedPerValidator` biggest stakers can claim - /// their reward. This used to limit the i/o cost for the nominator payout. - const MaxNominatorRewardedPerValidator: u32 = T::MaxNominatorRewardedPerValidator::get(); - - /// Maximum number of nominations per nominator. - const MaxNominations: u32 = T::MAX_NOMINATIONS; - - type Error = Error; - - fn deposit_event() = default; + #[pallet::hooks] + impl Hooks> for Pallet { fn on_runtime_upgrade() -> Weight { - if StorageVersion::get() == Releases::V5_0_0 { + if StorageVersion::::get() == Releases::V5_0_0 { migrations::v6::migrate::() } else { T::DbWeight::get().reads(1) } } - fn on_initialize(_now: T::BlockNumber) -> Weight { + fn on_initialize(_now: BlockNumberFor) -> Weight { // just return the weight of the on_finalize. T::DbWeight::get().reads(1) } - fn on_finalize() { + fn on_finalize(_n: BlockNumberFor) { // Set the start of the first era. if let Some(mut active_era) = Self::active_era() { if active_era.start.is_none() { let now_as_millis_u64 = T::UnixTime::now().as_millis().saturated_into::(); active_era.start = Some(now_as_millis_u64); // This write only ever happens once, we don't include it in the weight in general - ActiveEra::put(active_era); + ActiveEra::::put(active_era); } } // `on_finalize` weight is tracked in `on_initialize` } fn integrity_test() { - sp_io::TestExternalities::new_empty().execute_with(|| - assert!( - T::SlashDeferDuration::get() < T::BondingDuration::get() || T::BondingDuration::get() == 0, - "As per documentation, slash defer duration ({}) should be less than bonding duration ({}).", - T::SlashDeferDuration::get(), - T::BondingDuration::get(), - ) - ); + sp_std::if_std! { + sp_io::TestExternalities::new_empty().execute_with(|| + assert!( + T::SlashDeferDuration::get() < T::BondingDuration::get() || T::BondingDuration::get() == 0, + "As per documentation, slash defer duration ({}) should be less than bonding duration ({}).", + T::SlashDeferDuration::get(), + T::BondingDuration::get(), + ) + ); + } } + } + #[pallet::call] + impl Pallet { /// Take the origin account as a stash and lock up `value` of its balance. `controller` will /// be the account that controls it. /// @@ -1239,12 +1357,13 @@ decl_module! { /// - Read: Bonded, Ledger, [Origin Account], Current Era, History Depth, Locks /// - Write: Bonded, Payee, [Origin Account], Locks, Ledger /// # - #[weight = T::WeightInfo::bond()] - pub fn bond(origin, + #[pallet::weight(T::WeightInfo::bond())] + pub fn bond( + origin: OriginFor, controller: ::Source, - #[compact] value: BalanceOf, + #[pallet::compact] value: BalanceOf, payee: RewardDestination, - ) { + ) -> DispatchResult { let stash = ensure_signed(origin)?; if >::contains_key(&stash) { @@ -1262,20 +1381,20 @@ decl_module! { Err(Error::::InsufficientValue)? } - system::Pallet::::inc_consumers(&stash).map_err(|_| Error::::BadState)?; + frame_system::Pallet::::inc_consumers(&stash).map_err(|_| Error::::BadState)?; // You're auto-bonded forever, here. We might improve this by only bonding when // you actually validate/nominate and remove once you unbond __everything__. >::insert(&stash, &controller); >::insert(&stash, payee); - let current_era = CurrentEra::get().unwrap_or(0); + let current_era = CurrentEra::::get().unwrap_or(0); let history_depth = Self::history_depth(); let last_reward_era = current_era.saturating_sub(history_depth); let stash_balance = T::Currency::free_balance(&stash); let value = value.min(stash_balance); - Self::deposit_event(RawEvent::Bonded(stash.clone(), value)); + Self::deposit_event(Event::::Bonded(stash.clone(), value)); let item = StakingLedger { stash, total: value, @@ -1284,6 +1403,7 @@ decl_module! { claimed_rewards: (last_reward_era..current_era).collect(), }; Self::update_ledger(&controller, &item); + Ok(()) } /// Add some extra amount that have appeared in the stash `free_balance` into the balance up @@ -1307,8 +1427,11 @@ decl_module! { /// - Read: Era Election Status, Bonded, Ledger, [Origin Account], Locks /// - Write: [Origin Account], Locks, Ledger /// # - #[weight = T::WeightInfo::bond_extra()] - fn bond_extra(origin, #[compact] max_additional: BalanceOf) { + #[pallet::weight(T::WeightInfo::bond_extra())] + pub fn bond_extra( + origin: OriginFor, + #[pallet::compact] max_additional: BalanceOf, + ) -> DispatchResult { let stash = ensure_signed(origin)?; let controller = Self::bonded(&stash).ok_or(Error::::NotStash)?; @@ -1322,9 +1445,10 @@ decl_module! { // last check: the new active amount of ledger must be more than ED. ensure!(ledger.active >= T::Currency::minimum_balance(), Error::::InsufficientValue); - Self::deposit_event(RawEvent::Bonded(stash, extra)); + Self::deposit_event(Event::::Bonded(stash, extra)); Self::update_ledger(&controller, &ledger); } + Ok(()) } /// Schedule a portion of the stash to be unlocked ready for transfer out after the bond @@ -1359,8 +1483,8 @@ decl_module! { /// - Read: EraElectionStatus, Ledger, CurrentEra, Locks, BalanceOf Stash, /// - Write: Locks, Ledger, BalanceOf Stash, /// - #[weight = T::WeightInfo::unbond()] - fn unbond(origin, #[compact] value: BalanceOf) { + #[pallet::weight(T::WeightInfo::unbond())] + pub fn unbond(origin: OriginFor, #[pallet::compact] value: BalanceOf) -> DispatchResult { let controller = ensure_signed(origin)?; let mut ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; ensure!( @@ -1383,8 +1507,9 @@ decl_module! { let era = Self::current_era().unwrap_or(0) + T::BondingDuration::get(); ledger.unlocking.push(UnlockChunk { value, era }); Self::update_ledger(&controller, &ledger); - Self::deposit_event(RawEvent::Unbonded(ledger.stash, value)); + Self::deposit_event(Event::::Unbonded(ledger.stash, value)); } + Ok(()) } /// Remove any unlocked chunks from the `unlocking` queue from our management. @@ -1418,8 +1543,11 @@ decl_module! { /// - Writes Each: SpanSlash * S /// NOTE: Weight annotation is the kill scenario, we refund otherwise. /// # - #[weight = T::WeightInfo::withdraw_unbonded_kill(*num_slashing_spans)] - fn withdraw_unbonded(origin, num_slashing_spans: u32) -> DispatchResultWithPostInfo { + #[pallet::weight(T::WeightInfo::withdraw_unbonded_kill(*num_slashing_spans))] + pub fn withdraw_unbonded( + origin: OriginFor, + num_slashing_spans: u32, + ) -> DispatchResultWithPostInfo { let controller = ensure_signed(origin)?; let mut ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let (stash, old_total) = (ledger.stash.clone(), ledger.total); @@ -1449,7 +1577,7 @@ decl_module! { if ledger.total < old_total { // Already checked that this won't overflow by entry condition. let value = old_total - ledger.total; - Self::deposit_event(RawEvent::Withdrawn(stash, value)); + Self::deposit_event(Event::::Withdrawn(stash, value)); } Ok(post_info_weight.into()) @@ -1472,13 +1600,14 @@ decl_module! { /// - Read: Era Election Status, Ledger /// - Write: Nominators, Validators /// # - #[weight = T::WeightInfo::validate()] - pub fn validate(origin, prefs: ValidatorPrefs) { + #[pallet::weight(T::WeightInfo::validate())] + pub fn validate(origin: OriginFor, prefs: ValidatorPrefs) -> DispatchResult { let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let stash = &ledger.stash; >::remove(stash); >::insert(stash, prefs); + Ok(()) } /// Declare the desire to nominate `targets` for the origin controller. @@ -1500,8 +1629,11 @@ decl_module! { /// - Reads: Era Election Status, Ledger, Current Era /// - Writes: Validators, Nominators /// # - #[weight = T::WeightInfo::nominate(targets.len() as u32)] - pub fn nominate(origin, targets: Vec<::Source>) { + #[pallet::weight(T::WeightInfo::nominate(targets.len() as u32))] + pub fn nominate( + origin: OriginFor, + targets: Vec<::Source>, + ) -> DispatchResult { let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let stash = &ledger.stash; @@ -1528,6 +1660,7 @@ decl_module! { >::remove(stash); >::insert(stash, &nominations); + Ok(()) } /// Declare no desire to either validate or nominate. @@ -1547,11 +1680,12 @@ decl_module! { /// - Read: EraElectionStatus, Ledger /// - Write: Validators, Nominators /// # - #[weight = T::WeightInfo::chill()] - fn chill(origin) { + #[pallet::weight(T::WeightInfo::chill())] + pub fn chill(origin: OriginFor) -> DispatchResult { let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; Self::chill_stash(&ledger.stash); + Ok(()) } /// (Re-)set the payment target for a controller. @@ -1570,12 +1704,16 @@ decl_module! { /// - Read: Ledger /// - Write: Payee /// # - #[weight = T::WeightInfo::set_payee()] - fn set_payee(origin, payee: RewardDestination) { + #[pallet::weight(T::WeightInfo::set_payee())] + pub fn set_payee( + origin: OriginFor, + payee: RewardDestination, + ) -> DispatchResult { let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let stash = &ledger.stash; >::insert(stash, payee); + Ok(()) } /// (Re-)set the controller of a stash. @@ -1594,8 +1732,11 @@ decl_module! { /// - Read: Bonded, Ledger New Controller, Ledger Old Controller /// - Write: Bonded, Ledger New Controller, Ledger Old Controller /// # - #[weight = T::WeightInfo::set_controller()] - fn set_controller(origin, controller: ::Source) { + #[pallet::weight(T::WeightInfo::set_controller())] + pub fn set_controller( + origin: OriginFor, + controller: ::Source, + ) -> DispatchResult { let stash = ensure_signed(origin)?; let old_controller = Self::bonded(&stash).ok_or(Error::::NotStash)?; let controller = T::Lookup::lookup(controller)?; @@ -1608,6 +1749,7 @@ decl_module! { >::insert(&controller, l); } } + Ok(()) } /// Sets the ideal number of validators. @@ -1618,10 +1760,14 @@ decl_module! { /// Weight: O(1) /// Write: Validator Count /// # - #[weight = T::WeightInfo::set_validator_count()] - fn set_validator_count(origin, #[compact] new: u32) { + #[pallet::weight(T::WeightInfo::set_validator_count())] + pub fn set_validator_count( + origin: OriginFor, + #[pallet::compact] new: u32, + ) -> DispatchResult { ensure_root(origin)?; - ValidatorCount::put(new); + ValidatorCount::::put(new); + Ok(()) } /// Increments the ideal number of validators. @@ -1631,10 +1777,14 @@ decl_module! { /// # /// Same as [`set_validator_count`]. /// # - #[weight = T::WeightInfo::set_validator_count()] - fn increase_validator_count(origin, #[compact] additional: u32) { + #[pallet::weight(T::WeightInfo::set_validator_count())] + pub fn increase_validator_count( + origin: OriginFor, + #[pallet::compact] additional: u32, + ) -> DispatchResult { ensure_root(origin)?; - ValidatorCount::mutate(|n| *n += additional); + ValidatorCount::::mutate(|n| *n += additional); + Ok(()) } /// Scale up the ideal number of validators by a factor. @@ -1644,10 +1794,11 @@ decl_module! { /// # /// Same as [`set_validator_count`]. /// # - #[weight = T::WeightInfo::set_validator_count()] - fn scale_validator_count(origin, factor: Percent) { + #[pallet::weight(T::WeightInfo::set_validator_count())] + pub fn scale_validator_count(origin: OriginFor, factor: Percent) -> DispatchResult { ensure_root(origin)?; - ValidatorCount::mutate(|n| *n += factor * *n); + ValidatorCount::::mutate(|n| *n += factor * *n); + Ok(()) } /// Force there to be no new eras indefinitely. @@ -1659,10 +1810,11 @@ decl_module! { /// - Weight: O(1) /// - Write: ForceEra /// # - #[weight = T::WeightInfo::force_no_eras()] - fn force_no_eras(origin) { + #[pallet::weight(T::WeightInfo::force_no_eras())] + pub fn force_no_eras(origin: OriginFor) -> DispatchResult { ensure_root(origin)?; - ForceEra::put(Forcing::ForceNone); + ForceEra::::put(Forcing::ForceNone); + Ok(()) } /// Force there to be a new era at the end of the next session. After this, it will be @@ -1675,10 +1827,11 @@ decl_module! { /// - Weight: O(1) /// - Write ForceEra /// # - #[weight = T::WeightInfo::force_new_era()] - fn force_new_era(origin) { + #[pallet::weight(T::WeightInfo::force_new_era())] + pub fn force_new_era(origin: OriginFor) -> DispatchResult { ensure_root(origin)?; - ForceEra::put(Forcing::ForceNew); + ForceEra::::put(Forcing::ForceNew); + Ok(()) } /// Set the validators who cannot be slashed (if any). @@ -1689,10 +1842,14 @@ decl_module! { /// - O(V) /// - Write: Invulnerables /// # - #[weight = T::WeightInfo::set_invulnerables(invulnerables.len() as u32)] - fn set_invulnerables(origin, invulnerables: Vec) { + #[pallet::weight(T::WeightInfo::set_invulnerables(invulnerables.len() as u32))] + pub fn set_invulnerables( + origin: OriginFor, + invulnerables: Vec, + ) -> DispatchResult { ensure_root(origin)?; >::put(invulnerables); + Ok(()) } /// Force a current staker to become completely unstaked, immediately. @@ -1705,8 +1862,12 @@ decl_module! { /// Writes: Bonded, Slashing Spans (if S > 0), Ledger, Payee, Validators, Nominators, Account, Locks /// Writes Each: SpanSlash * S /// # - #[weight = T::WeightInfo::force_unstake(*num_slashing_spans)] - fn force_unstake(origin, stash: T::AccountId, num_slashing_spans: u32) { + #[pallet::weight(T::WeightInfo::force_unstake(*num_slashing_spans))] + pub fn force_unstake( + origin: OriginFor, + stash: T::AccountId, + num_slashing_spans: u32, + ) -> DispatchResult { ensure_root(origin)?; // remove all staking-related information. @@ -1714,6 +1875,7 @@ decl_module! { // remove the lock. T::Currency::remove_lock(STAKING_ID, &stash); + Ok(()) } /// Force there to be a new era at the end of sessions indefinitely. @@ -1724,10 +1886,11 @@ decl_module! { /// - Weight: O(1) /// - Write: ForceEra /// # - #[weight = T::WeightInfo::force_new_era_always()] - fn force_new_era_always(origin) { + #[pallet::weight(T::WeightInfo::force_new_era_always())] + pub fn force_new_era_always(origin: OriginFor) -> DispatchResult { ensure_root(origin)?; - ForceEra::put(Forcing::ForceAlways); + ForceEra::::put(Forcing::ForceAlways); + Ok(()) } /// Cancel enactment of a deferred slash. @@ -1743,8 +1906,12 @@ decl_module! { /// - Read: Unapplied Slashes /// - Write: Unapplied Slashes /// # - #[weight = T::WeightInfo::cancel_deferred_slash(slash_indices.len() as u32)] - fn cancel_deferred_slash(origin, era: EraIndex, slash_indices: Vec) { + #[pallet::weight(T::WeightInfo::cancel_deferred_slash(slash_indices.len() as u32))] + pub fn cancel_deferred_slash( + origin: OriginFor, + era: EraIndex, + slash_indices: Vec, + ) -> DispatchResult { T::SlashCancelOrigin::ensure_origin(origin)?; ensure!(!slash_indices.is_empty(), Error::::EmptyTargets); @@ -1760,6 +1927,7 @@ decl_module! { } ::UnappliedSlashes::insert(&era, &unapplied); + Ok(()) } /// Pay out all the stakers behind a single validator for a single era. @@ -1790,8 +1958,12 @@ decl_module! { /// NOTE: weights are assuming that payouts are made to alive stash account (Staked). /// Paying even a dead controller is cheaper weight-wise. We don't do any refunds here. /// # - #[weight = T::WeightInfo::payout_stakers_alive_staked(T::MaxNominatorRewardedPerValidator::get())] - fn payout_stakers(origin, validator_stash: T::AccountId, era: EraIndex) -> DispatchResultWithPostInfo { + #[pallet::weight(T::WeightInfo::payout_stakers_alive_staked(T::MaxNominatorRewardedPerValidator::get()))] + pub(super) fn payout_stakers( + origin: OriginFor, + validator_stash: T::AccountId, + era: EraIndex, + ) -> DispatchResultWithPostInfo { ensure_signed(origin)?; Self::do_payout_stakers(validator_stash, era) } @@ -1810,8 +1982,11 @@ decl_module! { /// - Reads: EraElectionStatus, Ledger, Locks, [Origin Account] /// - Writes: [Origin Account], Locks, Ledger /// # - #[weight = T::WeightInfo::rebond(MAX_UNLOCKING_CHUNKS as u32)] - fn rebond(origin, #[compact] value: BalanceOf) -> DispatchResultWithPostInfo { + #[pallet::weight(T::WeightInfo::rebond(MAX_UNLOCKING_CHUNKS as u32))] + pub fn rebond( + origin: OriginFor, + #[pallet::compact] value: BalanceOf, + ) -> DispatchResultWithPostInfo { let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; ensure!(!ledger.unlocking.is_empty(), Error::::NoUnlockChunk); @@ -1820,7 +1995,7 @@ decl_module! { // last check: the new active amount of ledger must be more than ED. ensure!(ledger.active >= T::Currency::minimum_balance(), Error::::InsufficientValue); - Self::deposit_event(RawEvent::Bonded(ledger.stash.clone(), value)); + Self::deposit_event(Event::::Bonded(ledger.stash.clone(), value)); Self::update_ledger(&controller, &ledger); Ok(Some( 35 * WEIGHT_PER_MICROS @@ -1850,14 +2025,14 @@ decl_module! { /// - Clear Prefix Each: Era Stakers, EraStakersClipped, ErasValidatorPrefs /// - Writes Each: ErasValidatorReward, ErasRewardPoints, ErasTotalStake, ErasStartSessionIndex /// # - #[weight = T::WeightInfo::set_history_depth(*_era_items_deleted)] - fn set_history_depth(origin, - #[compact] new_history_depth: EraIndex, - #[compact] _era_items_deleted: u32, - ) { + #[pallet::weight(T::WeightInfo::set_history_depth(*_era_items_deleted))] + pub fn set_history_depth(origin: OriginFor, + #[pallet::compact] new_history_depth: EraIndex, + #[pallet::compact] _era_items_deleted: u32, + ) -> DispatchResult { ensure_root(origin)?; if let Some(current_era) = Self::current_era() { - HistoryDepth::mutate(|history_depth| { + HistoryDepth::::mutate(|history_depth| { let last_kept = current_era.checked_sub(*history_depth).unwrap_or(0); let new_last_kept = current_era.checked_sub(new_history_depth).unwrap_or(0); for era_index in last_kept..new_last_kept { @@ -1866,6 +2041,7 @@ decl_module! { *history_depth = new_history_depth }) } + Ok(()) } /// Remove all data structure concerning a staker/stash once its balance is at the minimum. @@ -1883,12 +2059,17 @@ decl_module! { /// - Writes: Bonded, Slashing Spans (if S > 0), Ledger, Payee, Validators, Nominators, Stash Account, Locks /// - Writes Each: SpanSlash * S /// # - #[weight = T::WeightInfo::reap_stash(*num_slashing_spans)] - fn reap_stash(_origin, stash: T::AccountId, num_slashing_spans: u32) { + #[pallet::weight(T::WeightInfo::reap_stash(*num_slashing_spans))] + pub fn reap_stash( + _origin: OriginFor, + stash: T::AccountId, + num_slashing_spans: u32, + ) -> DispatchResult { let at_minimum = T::Currency::total_balance(&stash) == T::Currency::minimum_balance(); ensure!(at_minimum, Error::::FundedTarget); Self::kill_stash(&stash, num_slashing_spans)?; T::Currency::remove_lock(STAKING_ID, &stash); + Ok(()) } /// Remove the given nominations from the calling validator. @@ -1904,8 +2085,8 @@ decl_module! { /// /// Note: Making this call only makes sense if you first set the validator preferences to /// block any further nominations. - #[weight = T::WeightInfo::kick(who.len() as u32)] - pub fn kick(origin, who: Vec<::Source>) -> DispatchResult { + #[pallet::weight(T::WeightInfo::kick(who.len() as u32))] + pub fn kick(origin: OriginFor, who: Vec<::Source>) -> DispatchResult { let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let stash = &ledger.stash; @@ -1918,7 +2099,7 @@ decl_module! { Nominators::::mutate(&nom_stash, |maybe_nom| if let Some(ref mut nom) = maybe_nom { if let Some(pos) = nom.targets.iter().position(|v| v == stash) { nom.targets.swap_remove(pos); - Self::deposit_event(RawEvent::Kicked(nom_stash.clone(), stash.clone())); + Self::deposit_event(Event::::Kicked(nom_stash.clone(), stash.clone())); } }); } @@ -1928,7 +2109,7 @@ decl_module! { } } -impl Module { +impl Pallet { /// The total balance that can be slashed from a stash account as of right now. pub fn slashable_balance_of(stash: &T::AccountId) -> BalanceOf { // Weight note: consider making the stake accessible through stash. @@ -1948,7 +2129,7 @@ impl Module { /// This prevents call sites from repeatedly requesting `total_issuance` from backend. But it is /// important to be only used while the total issuance is not changing. pub fn slashable_balance_of_fn() -> Box VoteWeight> { - // NOTE: changing this to unboxed `impl Fn(..)` return type and the module will still + // NOTE: changing this to unboxed `impl Fn(..)` return type and the pallet will still // compile, while some types in mock fail to resolve. let issuance = T::Currency::total_issuance(); Box::new(move |who: &T::AccountId| -> VoteWeight { @@ -1958,7 +2139,7 @@ impl Module { fn do_payout_stakers(validator_stash: T::AccountId, era: EraIndex) -> DispatchResultWithPostInfo { // Validate input data - let current_era = CurrentEra::get().ok_or( + let current_era = CurrentEra::::get().ok_or( Error::::InvalidEraToReward.with_weight(T::WeightInfo::payout_stakers_alive_staked(0)) )?; let history_depth = Self::history_depth(); @@ -2040,7 +2221,7 @@ impl Module { &ledger.stash, validator_staking_payout + validator_commission_payout ) { - Self::deposit_event(RawEvent::Reward(ledger.stash, imbalance.peek())); + Self::deposit_event(Event::::Reward(ledger.stash, imbalance.peek())); } // Track the number of payout ops to nominators. Note: `WeightInfo::payout_stakers_alive_staked` @@ -2060,7 +2241,7 @@ impl Module { if let Some(imbalance) = Self::make_payout(&nominator.who, nominator_reward) { // Note: this logic does not count payouts for `RewardDestination::None`. nominator_payout_count += 1; - Self::deposit_event(RawEvent::Reward(nominator.who.clone(), imbalance.peek())); + Self::deposit_event(Event::::Reward(nominator.who.clone(), imbalance.peek())); } } @@ -2131,9 +2312,9 @@ impl Module { let era_length = session_index.checked_sub(current_era_start_session_index) .unwrap_or(0); // Must never happen. - match ForceEra::get() { + match ForceEra::::get() { // Will set to default again, which is `NotForcing`. - Forcing::ForceNew => ForceEra::kill(), + Forcing::ForceNew => ForceEra::::kill(), // Short circuit to `new_era`. Forcing::ForceAlways => (), // Only go to `new_era` if deadline reached. @@ -2191,7 +2372,7 @@ impl Module { /// * reset `active_era.start`, /// * update `BondedEras` and apply slashes. fn start_era(start_session: SessionIndex) { - let active_era = ActiveEra::mutate(|active_era| { + let active_era = ActiveEra::::mutate(|active_era| { let new_index = active_era.as_ref().map(|info| info.index + 1).unwrap_or(0); *active_era = Some(ActiveEraInfo { index: new_index, @@ -2203,7 +2384,7 @@ impl Module { let bonding_duration = T::BondingDuration::get(); - BondedEras::mutate(|bonded| { + BondedEras::::mutate(|bonded| { bonded.push((active_era, start_session)); if active_era > bonding_duration { @@ -2239,7 +2420,7 @@ impl Module { let issuance = T::Currency::total_issuance(); let (validator_payout, rest) = T::EraPayout::era_payout(staked, issuance, era_duration); - Self::deposit_event(RawEvent::EraPayout(active_era.index, validator_payout, rest)); + Self::deposit_event(Event::::EraPayout(active_era.index, validator_payout, rest)); // Set ending era reward. >::insert(&active_era.index, validator_payout); @@ -2250,11 +2431,11 @@ impl Module { /// Plan a new era. Return the potential new staking set. fn new_era(start_session_index: SessionIndex) -> Option> { // Increment or set current era. - let current_era = CurrentEra::mutate(|s| { + let current_era = CurrentEra::::mutate(|s| { *s = Some(s.map(|s| s + 1).unwrap_or(0)); s.unwrap() }); - ErasStartSessionIndex::insert(¤t_era, &start_session_index); + ErasStartSessionIndex::::insert(¤t_era, &start_session_index); // Clean old era information. if let Some(old_era) = current_era.checked_sub(Self::history_depth() + 1) { @@ -2338,7 +2519,7 @@ impl Module { } // emit event - Self::deposit_event(RawEvent::StakingElection); + Self::deposit_event(Event::::StakingElection); if current_era > 0 { log!( @@ -2407,7 +2588,7 @@ impl Module { >::remove(stash); >::remove(stash); - system::Pallet::::dec_consumers(stash); + frame_system::Pallet::::dec_consumers(stash); Ok(()) } @@ -2420,7 +2601,7 @@ impl Module { >::remove(era_index); >::remove(era_index); >::remove(era_index); - ErasStartSessionIndex::remove(era_index); + ErasStartSessionIndex::::remove(era_index); } /// Apply previously-unapplied slashes on the beginning of a new era, after a delay. @@ -2465,9 +2646,9 @@ impl Module { /// Ensures that at the end of the current session there will be a new era. fn ensure_new_era() { - match ForceEra::get() { + match ForceEra::::get() { Forcing::ForceAlways | Forcing::ForceNew => (), - _ => ForceEra::put(Forcing::ForceNew), + _ => ForceEra::::put(Forcing::ForceNew), } } @@ -2482,7 +2663,7 @@ impl Module { #[cfg(feature = "runtime-benchmarks")] pub fn set_slash_reward_fraction(fraction: Perbill) { - SlashRewardFraction::put(fraction); + SlashRewardFraction::::put(fraction); } /// Get all of the voters that are eligible for the npos election. @@ -2534,7 +2715,7 @@ impl Module { } impl frame_election_provider_support::ElectionDataProvider - for Module + for Pallet { const MAXIMUM_VOTES_PER_VOTER: u32 = T::MAX_NOMINATIONS; fn desired_targets() -> data_provider::Result<(u32, Weight)> { @@ -2658,10 +2839,10 @@ impl frame_election_provider_support::ElectionDataProvider pallet_session::SessionManager for Module { +impl pallet_session::SessionManager for Pallet { fn new_session(new_index: SessionIndex) -> Option> { log!(trace, "planning new_session({})", new_index); - CurrentPlannedSession::put(new_index); + CurrentPlannedSession::::put(new_index); Self::new_session(new_index) } fn start_session(start_index: SessionIndex) { @@ -2675,7 +2856,7 @@ impl pallet_session::SessionManager for Module { } impl historical::SessionManager>> - for Module + for Pallet { fn new_session( new_index: SessionIndex, @@ -2703,7 +2884,7 @@ impl historical::SessionManager pallet_authorship::EventHandler for Module +impl pallet_authorship::EventHandler for Pallet where T: Config + pallet_authorship::Config + pallet_session::Config, { @@ -2724,7 +2905,7 @@ pub struct StashOf(sp_std::marker::PhantomData); impl Convert> for StashOf { fn convert(controller: T::AccountId) -> Option { - >::ledger(&controller).map(|l| l.stash) + >::ledger(&controller).map(|l| l.stash) } } @@ -2739,15 +2920,15 @@ impl Convert for ExposureOf { fn convert(validator: T::AccountId) -> Option>> { - >::active_era() - .map(|active_era| >::eras_stakers(active_era.index, &validator)) + >::active_era() + .map(|active_era| >::eras_stakers(active_era.index, &validator)) } } /// This is intended to be used with `FilterHistoricalOffences`. impl OnOffenceHandler, Weight> - for Module + for Pallet where T: pallet_session::Config::AccountId>, T: pallet_session::historical::Config< @@ -2769,7 +2950,7 @@ where slash_fraction: &[Perbill], slash_session: SessionIndex, ) -> Weight { - let reward_proportion = SlashRewardFraction::get(); + let reward_proportion = SlashRewardFraction::::get(); let mut consumed_weight: Weight = 0; let mut add_db_reads_writes = |reads, writes| { consumed_weight += T::DbWeight::get().reads_writes(reads, writes); @@ -2798,7 +2979,7 @@ where let slash_era = if slash_session >= active_era_start_session_index { active_era } else { - let eras = BondedEras::get(); + let eras = BondedEras::::get(); add_db_reads_writes(1, 0); // reverse because it's more likely to find reports from recent eras. @@ -2883,7 +3064,7 @@ pub struct FilterHistoricalOffences { } impl ReportOffence - for FilterHistoricalOffences, R> + for FilterHistoricalOffences, R> where T: Config, R: ReportOffence, @@ -2892,13 +3073,13 @@ where fn report_offence(reporters: Vec, offence: O) -> Result<(), OffenceError> { // disallow any slashing from before the current bonding period. let offence_session = offence.session_index(); - let bonded_eras = BondedEras::get(); + let bonded_eras = BondedEras::::get(); if bonded_eras.first().filter(|(_, start)| offence_session >= *start).is_some() { R::report_offence(reporters, offence) } else { - >::deposit_event( - RawEvent::OldSlashingReportDiscarded(offence_session) + >::deposit_event( + Event::::OldSlashingReportDiscarded(offence_session) ); Ok(()) } diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index b4ff35d0d6f90..211cc025300e0 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -21,9 +21,8 @@ use crate::*; use crate as staking; use frame_support::{ assert_ok, parameter_types, - traits::{Currency, FindAuthor, Get, OnFinalize, OnInitialize, OneSessionHandler}, + traits::{Currency, FindAuthor, Get, OnInitialize, OneSessionHandler}, weights::constants::RocksDbWeight, - IterableStorageMap, StorageDoubleMap, StorageMap, StorageValue, }; use sp_core::H256; use sp_io; @@ -194,7 +193,7 @@ impl pallet_authorship::Config for Test { type FindAuthor = Author11; type UncleGenerations = UncleGenerations; type FilterUncle = (); - type EventHandler = Module; + type EventHandler = Pallet; } parameter_types! { pub const MinimumPeriod: u64 = 5; @@ -459,7 +458,7 @@ impl ExtBuilder { ext.execute_with(|| { System::set_block_number(1); Session::on_initialize(1); - Staking::on_initialize(1); + >::on_initialize(1); Timestamp::set_timestamp(INIT_TIMESTAMP); }); } @@ -610,7 +609,7 @@ pub(crate) fn run_to_block(n: BlockNumber) { for b in (System::block_number() + 1)..=n { System::set_block_number(b); Session::on_initialize(b); - Staking::on_initialize(b); + >::on_initialize(b); Timestamp::set_timestamp(System::block_number() * BLOCK_TIME + INIT_TIMESTAMP); if b != n { Staking::on_finalize(System::block_number()); @@ -696,7 +695,7 @@ pub(crate) fn reward_all_elected() { .into_iter() .map(|v| (v, 1)); - >::reward_by_ids(rewards) + >::reward_by_ids(rewards) } pub(crate) fn validator_controllers() -> Vec { @@ -714,7 +713,7 @@ pub(crate) fn on_offence_in_era( slash_fraction: &[Perbill], era: EraIndex, ) { - let bonded_eras = crate::BondedEras::get(); + let bonded_eras = crate::BondedEras::::get(); for &(bonded_era, start_session) in bonded_eras.iter() { if bonded_era == era { let _ = Staking::on_offence(offenders, slash_fraction, start_session); diff --git a/frame/staking/src/slashing.rs b/frame/staking/src/slashing.rs index fd0a63b288ab2..50cab1103b95a 100644 --- a/frame/staking/src/slashing.rs +++ b/frame/staking/src/slashing.rs @@ -50,12 +50,12 @@ //! Based on research at use super::{ - EraIndex, Config, Module, Store, BalanceOf, Exposure, Perbill, SessionInterface, + EraIndex, Config, Pallet, Store, BalanceOf, Exposure, Perbill, SessionInterface, NegativeImbalanceOf, UnappliedSlash, Error, }; use sp_runtime::{traits::{Zero, Saturating}, RuntimeDebug, DispatchResult}; use frame_support::{ - StorageMap, StorageDoubleMap, ensure, + ensure, traits::{Currency, OnUnbalanced, Imbalance}, }; use sp_std::vec::Vec; @@ -239,7 +239,7 @@ pub(crate) fn compute_slash(params: SlashParams) return None; } - let (prior_slash_p, _era_slash) = as Store>::ValidatorSlashInEra::get( + let (prior_slash_p, _era_slash) = as Store>::ValidatorSlashInEra::get( &slash_era, stash, ).unwrap_or((Perbill::zero(), Zero::zero())); @@ -247,7 +247,7 @@ pub(crate) fn compute_slash(params: SlashParams) // compare slash proportions rather than slash values to avoid issues due to rounding // error. if slash.deconstruct() > prior_slash_p.deconstruct() { - as Store>::ValidatorSlashInEra::insert( + as Store>::ValidatorSlashInEra::insert( &slash_era, stash, &(slash, own_slash), @@ -285,12 +285,12 @@ pub(crate) fn compute_slash(params: SlashParams) // chill the validator - it misbehaved in the current span and should // not continue in the next election. also end the slashing span. spans.end_span(now); - >::chill_stash(stash); + >::chill_stash(stash); // make sure to disable validator till the end of this session if T::SessionInterface::disable_validator(stash).unwrap_or(false) { // force a new era, to select a new validator set - >::ensure_new_era() + >::ensure_new_era() } } } @@ -325,12 +325,12 @@ fn kick_out_if_recent( if spans.era_span(params.slash_era).map(|s| s.index) == Some(spans.span_index()) { spans.end_span(params.now); - >::chill_stash(params.stash); + >::chill_stash(params.stash); // make sure to disable validator till the end of this session if T::SessionInterface::disable_validator(params.stash).unwrap_or(false) { // force a new era, to select a new validator set - >::ensure_new_era() + >::ensure_new_era() } } } @@ -367,14 +367,14 @@ fn slash_nominators( let own_slash_by_validator = slash * nominator.value; let own_slash_difference = own_slash_by_validator.saturating_sub(own_slash_prior); - let mut era_slash = as Store>::NominatorSlashInEra::get( + let mut era_slash = as Store>::NominatorSlashInEra::get( &slash_era, stash, ).unwrap_or_else(|| Zero::zero()); era_slash += own_slash_difference; - as Store>::NominatorSlashInEra::insert( + as Store>::NominatorSlashInEra::insert( &slash_era, stash, &era_slash, @@ -437,9 +437,9 @@ fn fetch_spans<'a, T: Config + 'a>( slash_of: &'a mut BalanceOf, reward_proportion: Perbill, ) -> InspectingSpans<'a, T> { - let spans = as Store>::SlashingSpans::get(stash).unwrap_or_else(|| { + let spans = as Store>::SlashingSpans::get(stash).unwrap_or_else(|| { let spans = SlashingSpans::new(window_start); - as Store>::SlashingSpans::insert(stash, &spans); + as Store>::SlashingSpans::insert(stash, &spans); spans }); @@ -488,7 +488,7 @@ impl<'a, T: 'a + Config> InspectingSpans<'a, T> { ) -> Option { let target_span = self.era_span(slash_era)?; let span_slash_key = (self.stash.clone(), target_span.index); - let mut span_record = as Store>::SpanSlash::get(&span_slash_key); + let mut span_record = as Store>::SpanSlash::get(&span_slash_key); let mut changed = false; let reward = if span_record.slashed < slash { @@ -519,7 +519,7 @@ impl<'a, T: 'a + Config> InspectingSpans<'a, T> { if changed { self.dirty = true; - as Store>::SpanSlash::insert(&span_slash_key, &span_record); + as Store>::SpanSlash::insert(&span_slash_key, &span_record); } Some(target_span.index) @@ -533,18 +533,18 @@ impl<'a, T: 'a + Config> Drop for InspectingSpans<'a, T> { if let Some((start, end)) = self.spans.prune(self.window_start) { for span_index in start..end { - as Store>::SpanSlash::remove(&(self.stash.clone(), span_index)); + as Store>::SpanSlash::remove(&(self.stash.clone(), span_index)); } } - as Store>::SlashingSpans::insert(self.stash, &self.spans); + as Store>::SlashingSpans::insert(self.stash, &self.spans); } } /// Clear slashing metadata for an obsolete era. pub(crate) fn clear_era_metadata(obsolete_era: EraIndex) { - as Store>::ValidatorSlashInEra::remove_prefix(&obsolete_era); - as Store>::NominatorSlashInEra::remove_prefix(&obsolete_era); + as Store>::ValidatorSlashInEra::remove_prefix(&obsolete_era); + as Store>::NominatorSlashInEra::remove_prefix(&obsolete_era); } /// Clear slashing metadata for a dead account. @@ -552,14 +552,14 @@ pub(crate) fn clear_stash_metadata( stash: &T::AccountId, num_slashing_spans: u32, ) -> DispatchResult { - let spans = match as Store>::SlashingSpans::get(stash) { + let spans = match as Store>::SlashingSpans::get(stash) { None => return Ok(()), Some(s) => s, }; ensure!(num_slashing_spans as usize >= spans.iter().count(), Error::::IncorrectSlashingSpans); - as Store>::SlashingSpans::remove(stash); + as Store>::SlashingSpans::remove(stash); // kill slashing-span metadata for account. // @@ -567,7 +567,7 @@ pub(crate) fn clear_stash_metadata( // in that case, they may re-bond, but it would count again as span 0. Further ancient // slashes would slash into this new bond, since metadata has now been cleared. for span in spans.iter() { - as Store>::SpanSlash::remove(&(stash.clone(), span.index)); + as Store>::SpanSlash::remove(&(stash.clone(), span.index)); } Ok(()) @@ -582,12 +582,12 @@ pub fn do_slash( reward_payout: &mut BalanceOf, slashed_imbalance: &mut NegativeImbalanceOf, ) { - let controller = match >::bonded(stash) { + let controller = match >::bonded(stash) { None => return, // defensive: should always exist. Some(c) => c, }; - let mut ledger = match >::ledger(&controller) { + let mut ledger = match >::ledger(&controller) { Some(ledger) => ledger, None => return, // nothing to do. }; @@ -603,11 +603,11 @@ pub fn do_slash( *reward_payout = reward_payout.saturating_sub(missing); } - >::update_ledger(&controller, &ledger); + >::update_ledger(&controller, &ledger); // trigger the event - >::deposit_event( - super::RawEvent::Slash(stash.clone(), value) + >::deposit_event( + super::Event::::Slash(stash.clone(), value) ); } } diff --git a/frame/staking/src/testing_utils.rs b/frame/staking/src/testing_utils.rs index c4daf88098e75..185b96983ab94 100644 --- a/frame/staking/src/testing_utils.rs +++ b/frame/staking/src/testing_utils.rs @@ -19,7 +19,7 @@ //! bonding validators, nominators, and generating different types of solutions. use crate::*; -use crate::Module as Staking; +use crate::Pallet as Staking; use frame_benchmarking::account; use frame_system::RawOrigin; use sp_io::hashing::blake2_256; @@ -166,12 +166,12 @@ pub fn create_validators_with_nominators_for_era( Staking::::nominate(RawOrigin::Signed(n_controller.clone()).into(), selected_validators)?; } - ValidatorCount::put(validators); + ValidatorCount::::put(validators); Ok(validator_chosen) } /// get the current era. pub fn current_era() -> EraIndex { - >::current_era().unwrap_or(0) + >::current_era().unwrap_or(0) } diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index ec5a61d46885b..4473e89585002 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -17,7 +17,7 @@ //! Tests for the module. -use super::*; +use super::{*, Event}; use mock::*; use sp_runtime::{ assert_eq_error_rate, @@ -25,7 +25,7 @@ use sp_runtime::{ }; use sp_staking::offence::OffenceDetails; use frame_support::{ - assert_ok, assert_noop, StorageMap, + assert_ok, assert_noop, traits::{Currency, ReservableCurrency, OnInitialize}, weights::{extract_actual_weight, GetDispatchInfo}, }; @@ -187,10 +187,10 @@ fn rewards_should_work() { Payee::::insert(21, RewardDestination::Controller); Payee::::insert(101, RewardDestination::Controller); - >::reward_by_ids(vec![(11, 50)]); - >::reward_by_ids(vec![(11, 50)]); + >::reward_by_ids(vec![(11, 50)]); + >::reward_by_ids(vec![(11, 50)]); // This is the second validator of the current elected set. - >::reward_by_ids(vec![(21, 50)]); + >::reward_by_ids(vec![(21, 50)]); // Compute total payout now for whole duration of the session. let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); @@ -227,7 +227,7 @@ fn rewards_should_work() { ); assert_eq!( *mock::staking_events().last().unwrap(), - RawEvent::EraPayout(0, total_payout_0, maximum_payout - total_payout_0) + Event::EraPayout(0, total_payout_0, maximum_payout - total_payout_0) ); mock::make_all_reward_payment(0); @@ -253,7 +253,7 @@ fn rewards_should_work() { assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); assert_eq_uvec!(Session::validators(), vec![11, 21]); - >::reward_by_ids(vec![(11, 1)]); + >::reward_by_ids(vec![(11, 1)]); // Compute total payout now for whole duration as other parameter won't change let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); @@ -265,7 +265,7 @@ fn rewards_should_work() { ); assert_eq!( *mock::staking_events().last().unwrap(), - RawEvent::EraPayout(1, total_payout_1, maximum_payout - total_payout_1) + Event::EraPayout(1, total_payout_1, maximum_payout - total_payout_1) ); mock::make_all_reward_payment(1); @@ -482,8 +482,8 @@ fn nominating_and_rewards_should_work() { // the total reward for era 0 let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); - >::reward_by_ids(vec![(41, 1)]); - >::reward_by_ids(vec![(31, 1)]); + >::reward_by_ids(vec![(41, 1)]); + >::reward_by_ids(vec![(31, 1)]); mock::start_active_era(1); @@ -524,8 +524,8 @@ fn nominating_and_rewards_should_work() { // the total reward for era 1 let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); - >::reward_by_ids(vec![(21, 2)]); - >::reward_by_ids(vec![(11, 1)]); + >::reward_by_ids(vec![(21, 2)]); + >::reward_by_ids(vec![(11, 1)]); mock::start_active_era(2); @@ -779,7 +779,7 @@ fn forcing_new_era_works() { assert_eq!(active_era(), 1); // no era change. - ForceEra::put(Forcing::ForceNone); + ForceEra::::put(Forcing::ForceNone); start_session(4); assert_eq!(active_era(), 1); @@ -795,7 +795,7 @@ fn forcing_new_era_works() { // back to normal. // this immediately starts a new session. - ForceEra::put(Forcing::NotForcing); + ForceEra::::put(Forcing::NotForcing); start_session(8); assert_eq!(active_era(), 1); @@ -803,7 +803,7 @@ fn forcing_new_era_works() { start_session(9); assert_eq!(active_era(), 2); // forceful change - ForceEra::put(Forcing::ForceAlways); + ForceEra::::put(Forcing::ForceAlways); start_session(10); assert_eq!(active_era(), 2); @@ -815,10 +815,10 @@ fn forcing_new_era_works() { assert_eq!(active_era(), 4); // just one forceful change - ForceEra::put(Forcing::ForceNew); + ForceEra::::put(Forcing::ForceNew); start_session(13); assert_eq!(active_era(), 5); - assert_eq!(ForceEra::get(), Forcing::NotForcing); + assert_eq!(ForceEra::::get(), Forcing::NotForcing); start_session(14); assert_eq!(active_era(), 6); @@ -917,7 +917,7 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); - >::reward_by_ids(vec![(11, 1)]); + >::reward_by_ids(vec![(11, 1)]); mock::start_active_era(1); mock::make_all_reward_payment(0); @@ -940,7 +940,7 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); - >::reward_by_ids(vec![(11, 1)]); + >::reward_by_ids(vec![(11, 1)]); mock::start_active_era(2); mock::make_all_reward_payment(1); @@ -968,7 +968,7 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_2 = current_total_payout_for_duration(reward_time_per_era()); - >::reward_by_ids(vec![(11, 1)]); + >::reward_by_ids(vec![(11, 1)]); mock::start_active_era(3); mock::make_all_reward_payment(2); @@ -1015,7 +1015,7 @@ fn validator_payment_prefs_work() { // Compute total payout now for whole duration as other parameter won't change let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); let exposure_1 = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); - >::reward_by_ids(vec![(11, 1)]); + >::reward_by_ids(vec![(11, 1)]); mock::start_active_era(2); mock::make_all_reward_payment(1); @@ -1508,8 +1508,8 @@ fn reward_to_stake_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); - >::reward_by_ids(vec![(11, 1)]); - >::reward_by_ids(vec![(21, 1)]); + >::reward_by_ids(vec![(11, 1)]); + >::reward_by_ids(vec![(21, 1)]); // New era --> rewards are paid --> stakes are changed mock::start_active_era(1); @@ -2009,10 +2009,10 @@ fn reward_from_authorship_event_handler_works() { assert_eq!(>::author(), 11); - >::note_author(11); - >::note_uncle(21, 1); + >::note_author(11); + >::note_uncle(21, 1); // Rewarding the same two times works. - >::note_uncle(11, 1); + >::note_uncle(11, 1); // Not mandatory but must be coherent with rewards assert_eq_uvec!(Session::validators(), vec![11, 21]); @@ -2035,13 +2035,13 @@ fn add_reward_points_fns_works() { // Not mandatory but must be coherent with rewards assert_eq_uvec!(Session::validators(), vec![21, 11]); - >::reward_by_ids(vec![ + >::reward_by_ids(vec![ (21, 1), (11, 1), (11, 1), ]); - >::reward_by_ids(vec![ + >::reward_by_ids(vec![ (21, 1), (11, 1), (11, 1), @@ -2084,7 +2084,7 @@ fn era_is_always_same_length() { assert_eq!(Staking::eras_start_session_index(current_era()).unwrap(), session_per_era * 2u32); let session = Session::current_index(); - ForceEra::put(Forcing::ForceNew); + ForceEra::::put(Forcing::ForceNew); advance_session(); advance_session(); assert_eq!(current_era(), 3); @@ -2992,13 +2992,13 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { Payee::::insert(11, RewardDestination::Controller); Payee::::insert(101, RewardDestination::Controller); - >::reward_by_ids(vec![(11, 1)]); + >::reward_by_ids(vec![(11, 1)]); // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); mock::start_active_era(1); - >::reward_by_ids(vec![(11, 1)]); + >::reward_by_ids(vec![(11, 1)]); // Change total issuance in order to modify total payout let _ = Balances::deposit_creating(&999, 1_000_000_000); // Compute total payout now for whole duration as other parameter won't change @@ -3007,7 +3007,7 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { mock::start_active_era(2); - >::reward_by_ids(vec![(11, 1)]); + >::reward_by_ids(vec![(11, 1)]); // Change total issuance in order to modify total payout let _ = Balances::deposit_creating(&999, 1_000_000_000); // Compute total payout now for whole duration as other parameter won't change @@ -3168,7 +3168,7 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward( } mock::start_active_era(1); - >::reward_by_ids(vec![(11, 1)]); + >::reward_by_ids(vec![(11, 1)]); // compute and ensure the reward amount is greater than zero. let _ = current_total_payout_for_duration(reward_time_per_era()); @@ -3832,7 +3832,7 @@ fn do_not_die_when_active_is_ed() { fn on_finalize_weight_is_nonzero() { ExtBuilder::default().build_and_execute(|| { let on_finalize_weight = ::DbWeight::get().reads(1); - assert!(Staking::on_initialize(1) >= on_finalize_weight); + assert!(>::on_initialize(1) >= on_finalize_weight); }) } @@ -3954,7 +3954,7 @@ mod election_data_provider { assert_eq!(staking_events().len(), 1); assert_eq!( *staking_events().last().unwrap(), - RawEvent::StakingElection + Event::StakingElection ); for b in 21..45 { @@ -3968,7 +3968,7 @@ mod election_data_provider { assert_eq!(staking_events().len(), 3); assert_eq!( *staking_events().last().unwrap(), - RawEvent::StakingElection + Event::StakingElection ); }) }