mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 20:31:13 +00:00
Refactor away from opaque hashes (#5226)
* System.BlockHash * Fix hash * Introduce K/V iteration in all _concat maps Also move across: - System.Account (blake2_128_concat) - Balances.Locks (twox_64_concat) - ElectionsPhragmen.VotesOf (twox_64_concat) - ElectionsPhragmen.StakeOf (twox_64_concat) - Identity.IdentityOf (twox_64_concat) - Identity.SubsOf (twox_64_concat) - Society.Payouts (twox_64_concat) - Session.NextKeys (twox_64_concat) - Identity.SuperOf (blake2_128_concat) - Session.KeyOwner (blake2_128_concat) - Society.SuspendedCandidates (twox_64_concat) - Society.SuspendedMembers (twox_64_concat) - Society.Vouching (twox_64_concat) - Society.Strikes (twox_64_concat) - System.EventTopics - Balances.Account * Build fixes * Ensure migration happens in correct order * Staking.* * Vesting.* Offences.* * Democracy.* * Babe.* Collective.* * Grandpa.* * Assets.* Benchmark.* Contracts.* Elections.* Asset.* Nicks.* Also introduce real account list * ImOnline.* * Treasury.* * Recovery.* * Final bits. * Docs * Fix one test * Fix test * All passing except the UI tests * Remove linked_map part 1 * Remove linked_map * Some iterator utils for double maps. * Remove old migrations * Introduce tombstone for LinkedMap type * Migration for genesis hash * Fix build * Fix hash * Rename Map is_linked -> unused, keeping backwards compat (#5256) * Update frame/balances/src/lib.rs Co-Authored-By: Shawn Tabrizi <shawntabrizi@gmail.com> * Update frame/elections/src/lib.rs Co-Authored-By: Shawn Tabrizi <shawntabrizi@gmail.com> * Remove old migration code. * Update frame/system/src/lib.rs Co-Authored-By: Shawn Tabrizi <shawntabrizi@gmail.com> * Update bin/node/runtime/src/lib.rs Co-Authored-By: Shawn Tabrizi <shawntabrizi@gmail.com> * Fix hash * fix session migration * Fix watning Co-authored-by: Jaco Greeff <jacogr@gmail.com> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: Robert Habermeier <rphmeier@gmail.com>
This commit is contained in:
@@ -254,19 +254,16 @@ mod mock;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
mod slashing;
|
||||
mod migration;
|
||||
|
||||
pub mod inflation;
|
||||
|
||||
use sp_std::{prelude::*, result, collections::btree_map::BTreeMap};
|
||||
use codec::{HasCompact, Encode, Decode};
|
||||
use frame_support::{
|
||||
decl_module, decl_event, decl_storage, ensure, decl_error,
|
||||
weights::SimpleDispatchInfo,
|
||||
dispatch::DispatchResult,
|
||||
traits::{
|
||||
Currency, LockIdentifier, LockableCurrency,
|
||||
WithdrawReasons, OnUnbalanced, Imbalance, Get, Time
|
||||
decl_module, decl_event, decl_storage, ensure, decl_error, weights::SimpleDispatchInfo,
|
||||
dispatch::DispatchResult, storage::IterableStorageMap, traits::{
|
||||
Currency, LockIdentifier, LockableCurrency, WithdrawReasons, OnUnbalanced, Imbalance, Get,
|
||||
Time
|
||||
}
|
||||
};
|
||||
use pallet_session::historical::SessionManager;
|
||||
@@ -287,6 +284,7 @@ use sp_runtime::{Serialize, Deserialize};
|
||||
use frame_system::{self as system, ensure_signed, ensure_root};
|
||||
|
||||
use sp_phragmen::ExtendedBalance;
|
||||
use frame_support::traits::MigrateAccount;
|
||||
|
||||
const DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4;
|
||||
const MAX_NOMINATIONS: usize = 16;
|
||||
@@ -685,13 +683,13 @@ impl Default for Forcing {
|
||||
// storage migration logic. This should match directly with the semantic versions of the Rust crate.
|
||||
#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug)]
|
||||
enum Releases {
|
||||
V1_0_0,
|
||||
V1_0_0Ancient,
|
||||
V2_0_0,
|
||||
}
|
||||
|
||||
impl Default for Releases {
|
||||
fn default() -> Self {
|
||||
Releases::V1_0_0
|
||||
Releases::V2_0_0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -719,23 +717,23 @@ decl_storage! {
|
||||
pub Invulnerables get(fn invulnerables) config(): Vec<T::AccountId>;
|
||||
|
||||
/// Map from all locked "stash" accounts to the controller account.
|
||||
pub Bonded get(fn bonded): map hasher(blake2_256) T::AccountId => Option<T::AccountId>;
|
||||
pub Bonded get(fn bonded): map hasher(twox_64_concat) T::AccountId => Option<T::AccountId>;
|
||||
|
||||
/// Map from all (unlocked) "controller" accounts to the info regarding the staking.
|
||||
pub Ledger get(fn ledger):
|
||||
map hasher(blake2_256) T::AccountId
|
||||
map hasher(blake2_128_concat) T::AccountId
|
||||
=> Option<StakingLedger<T::AccountId, BalanceOf<T>>>;
|
||||
|
||||
/// Where the reward payment should be made. Keyed by stash.
|
||||
pub Payee get(fn payee): map hasher(blake2_256) T::AccountId => RewardDestination;
|
||||
pub Payee get(fn payee): map hasher(twox_64_concat) T::AccountId => RewardDestination;
|
||||
|
||||
/// The map from (wannabe) validator stash key to the preferences of that validator.
|
||||
pub Validators get(fn validators):
|
||||
linked_map hasher(blake2_256) T::AccountId => ValidatorPrefs;
|
||||
map hasher(twox_64_concat) T::AccountId => ValidatorPrefs;
|
||||
|
||||
/// The map from nominator stash key to the set of stash keys of all validators to nominate.
|
||||
pub Nominators get(fn nominators):
|
||||
linked_map hasher(blake2_256) T::AccountId => Option<Nominations<T::AccountId>>;
|
||||
map hasher(twox_64_concat) T::AccountId => Option<Nominations<T::AccountId>>;
|
||||
|
||||
/// The current era index.
|
||||
///
|
||||
@@ -751,7 +749,7 @@ decl_storage! {
|
||||
|
||||
/// The session index at which the era start for the last `HISTORY_DEPTH` eras
|
||||
pub ErasStartSessionIndex get(fn eras_start_session_index):
|
||||
map hasher(blake2_256) EraIndex => Option<SessionIndex>;
|
||||
map hasher(twox_64_concat) EraIndex => Option<SessionIndex>;
|
||||
|
||||
/// Exposure of validator at era.
|
||||
///
|
||||
@@ -780,7 +778,7 @@ decl_storage! {
|
||||
|
||||
/// Similarly to `ErasStakers` this holds the preferences of validators.
|
||||
///
|
||||
/// This is keyed fist by the era index to allow bulk deletion and then the stash account.
|
||||
/// 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.
|
||||
@@ -792,17 +790,17 @@ decl_storage! {
|
||||
///
|
||||
/// Eras that haven't finished yet or has been removed doesn't have reward.
|
||||
pub ErasValidatorReward get(fn eras_validator_reward):
|
||||
map hasher(blake2_256) EraIndex => Option<BalanceOf<T>>;
|
||||
map hasher(twox_64_concat) EraIndex => Option<BalanceOf<T>>;
|
||||
|
||||
/// 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(blake2_256) EraIndex => EraRewardPoints<T::AccountId>;
|
||||
map hasher(twox_64_concat) EraIndex => EraRewardPoints<T::AccountId>;
|
||||
|
||||
/// 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(blake2_256) EraIndex => BalanceOf<T>;
|
||||
map hasher(twox_64_concat) EraIndex => BalanceOf<T>;
|
||||
|
||||
/// True if the next session change will be a new era regardless of index.
|
||||
pub ForceEra get(fn force_era) config(): Forcing;
|
||||
@@ -818,7 +816,7 @@ decl_storage! {
|
||||
|
||||
/// All unapplied slashes that are queued for later.
|
||||
pub UnappliedSlashes:
|
||||
map hasher(blake2_256) EraIndex => Vec<UnappliedSlash<T::AccountId, BalanceOf<T>>>;
|
||||
map hasher(twox_64_concat) EraIndex => Vec<UnappliedSlash<T::AccountId, BalanceOf<T>>>;
|
||||
|
||||
/// A mapping from still-bonded eras to the first session index of that era.
|
||||
///
|
||||
@@ -829,21 +827,21 @@ decl_storage! {
|
||||
/// All slashing events on validators, mapped by era to the highest slash proportion
|
||||
/// and slash value of the era.
|
||||
ValidatorSlashInEra:
|
||||
double_map hasher(blake2_256) EraIndex, hasher(twox_128) T::AccountId
|
||||
double_map hasher(twox_64_concat) EraIndex, hasher(twox_64_concat) T::AccountId
|
||||
=> Option<(Perbill, BalanceOf<T>)>;
|
||||
|
||||
/// All slashing events on nominators, mapped by era to the highest slash value of the era.
|
||||
NominatorSlashInEra:
|
||||
double_map hasher(blake2_256) EraIndex, hasher(twox_128) T::AccountId
|
||||
double_map hasher(twox_64_concat) EraIndex, hasher(twox_64_concat) T::AccountId
|
||||
=> Option<BalanceOf<T>>;
|
||||
|
||||
/// Slashing spans for stash accounts.
|
||||
SlashingSpans: map hasher(blake2_256) T::AccountId => Option<slashing::SlashingSpans>;
|
||||
SlashingSpans: map hasher(twox_64_concat) T::AccountId => Option<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.
|
||||
SpanSlash:
|
||||
map hasher(blake2_256) (T::AccountId, slashing::SpanIndex)
|
||||
map hasher(twox_64_concat) (T::AccountId, slashing::SpanIndex)
|
||||
=> slashing::SpanRecord<BalanceOf<T>>;
|
||||
|
||||
/// The earliest era for which we have a pending, unapplied slash.
|
||||
@@ -957,7 +955,7 @@ decl_module! {
|
||||
fn deposit_event() = default;
|
||||
|
||||
fn on_runtime_upgrade() {
|
||||
migration::on_runtime_upgrade::<T>();
|
||||
migrate::<T>();
|
||||
}
|
||||
|
||||
fn on_finalize() {
|
||||
@@ -1480,6 +1478,30 @@ decl_module! {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> MigrateAccount<T::AccountId> for Module<T> {
|
||||
fn migrate_account(a: &T::AccountId) {
|
||||
if let Some(controller) = Bonded::<T>::migrate_key_from_blake(a) {
|
||||
Ledger::<T>::migrate_key_from_blake(controller);
|
||||
Payee::<T>::migrate_key_from_blake(a);
|
||||
Validators::<T>::migrate_key_from_blake(a);
|
||||
Nominators::<T>::migrate_key_from_blake(a);
|
||||
SlashingSpans::<T>::migrate_key_from_blake(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn migrate<T: Trait>() {
|
||||
if let Some(current_era) = CurrentEra::get() {
|
||||
let history_depth = HistoryDepth::get();
|
||||
for era in current_era.saturating_sub(history_depth)..=current_era {
|
||||
ErasStartSessionIndex::migrate_key_from_blake(era);
|
||||
ErasValidatorReward::<T>::migrate_key_from_blake(era);
|
||||
ErasRewardPoints::<T>::migrate_key_from_blake(era);
|
||||
ErasTotalStake::<T>::migrate_key_from_blake(era);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> Module<T> {
|
||||
// PUBLIC IMMUTABLES
|
||||
|
||||
@@ -1823,14 +1845,14 @@ impl<T: Trait> Module<T> {
|
||||
let mut all_nominators: Vec<(T::AccountId, Vec<T::AccountId>)> = Vec::new();
|
||||
let mut all_validators_and_prefs = BTreeMap::new();
|
||||
let mut all_validators = Vec::new();
|
||||
for (validator, preference) in <Validators<T>>::enumerate() {
|
||||
for (validator, preference) in <Validators<T>>::iter() {
|
||||
let self_vote = (validator.clone(), vec![validator.clone()]);
|
||||
all_nominators.push(self_vote);
|
||||
all_validators_and_prefs.insert(validator.clone(), preference);
|
||||
all_validators.push(validator);
|
||||
}
|
||||
|
||||
let nominator_votes = <Nominators<T>>::enumerate().map(|(nominator, nominations)| {
|
||||
let nominator_votes = <Nominators<T>>::iter().map(|(nominator, nominations)| {
|
||||
let Nominations { submitted_in, mut targets, suppressed: _ } = nominations;
|
||||
|
||||
// Filter out nomination targets which were nominated before the most recent
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
// Copyright 2020 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Substrate is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Substrate is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/// Deprecated storages used for migration from v1.0.0 to v2.0.0 only.
|
||||
|
||||
use crate::{Trait, BalanceOf, MomentOf, SessionIndex, Exposure, UnlockChunk};
|
||||
use codec::{Encode, Decode, HasCompact};
|
||||
use frame_support::{decl_module, decl_storage};
|
||||
use sp_std::prelude::*;
|
||||
|
||||
/// Reward points of an era. Used to split era total payout between validators.
|
||||
#[derive(Encode, Decode, Default)]
|
||||
pub struct EraPoints {
|
||||
/// Total number of points. Equals the sum of reward points for each validator.
|
||||
pub total: u32,
|
||||
/// The reward points earned by a given validator. The index of this vec corresponds to the
|
||||
/// index into the current validator set.
|
||||
pub individual: Vec<u32>,
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode)]
|
||||
pub struct OldStakingLedger<AccountId, Balance: HasCompact> {
|
||||
pub stash: AccountId,
|
||||
#[codec(compact)]
|
||||
pub total: Balance,
|
||||
#[codec(compact)]
|
||||
pub active: Balance,
|
||||
pub unlocking: Vec<UnlockChunk<Balance>>,
|
||||
}
|
||||
|
||||
decl_module! {
|
||||
pub struct Module<T: Trait> for enum Call where origin: T::Origin { }
|
||||
}
|
||||
|
||||
decl_storage! {
|
||||
pub trait Store for Module<T: Trait> as Staking {
|
||||
pub SlotStake: BalanceOf<T>;
|
||||
|
||||
/// The currently elected validator set keyed by stash account ID.
|
||||
pub CurrentElected: Vec<T::AccountId>;
|
||||
|
||||
/// The start of the current era.
|
||||
pub CurrentEraStart: MomentOf<T>;
|
||||
|
||||
/// The session index at which the current era started.
|
||||
pub CurrentEraStartSessionIndex: SessionIndex;
|
||||
|
||||
/// Rewards for the current era. Using indices of current elected set.
|
||||
pub CurrentEraPointsEarned: EraPoints;
|
||||
|
||||
/// Nominators for a particular account that is in action right now. You can't iterate
|
||||
/// through validators here, but you can find them in the Session module.
|
||||
///
|
||||
/// This is keyed by the stash account.
|
||||
pub Stakers: map hasher(blake2_256) T::AccountId => Exposure<T::AccountId, BalanceOf<T>>;
|
||||
|
||||
/// Old upgrade flag.
|
||||
pub IsUpgraded: bool;
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
// Copyright 2020 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Substrate is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Substrate is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Update storage from v1.0.0 to v2.0.0
|
||||
//!
|
||||
//! In old version the staking module has several issue about handling session delay, the
|
||||
//! current era was always considered the active one.
|
||||
//!
|
||||
//! After the migration the current era will still be considered the active one for the era of
|
||||
//! the upgrade. And the delay issue will be fixed when planning the next era.
|
||||
// * create:
|
||||
// * ActiveEraStart
|
||||
// * ErasRewardPoints
|
||||
// * ActiveEra
|
||||
// * ErasStakers
|
||||
// * ErasStakersClipped
|
||||
// * ErasValidatorPrefs
|
||||
// * ErasTotalStake
|
||||
// * ErasStartSessionIndex
|
||||
// * translate StakingLedger
|
||||
// * removal of:
|
||||
// * Stakers
|
||||
// * SlotStake
|
||||
// * CurrentElected
|
||||
// * CurrentEraStart
|
||||
// * CurrentEraStartSessionIndex
|
||||
// * CurrentEraPointsEarned
|
||||
|
||||
use super::*;
|
||||
mod deprecated;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
#[cfg(test)]
|
||||
mod test_upgrade_from_master_dataset;
|
||||
|
||||
pub fn on_runtime_upgrade<T: Trait>() {
|
||||
match StorageVersion::get() {
|
||||
Releases::V2_0_0 => return,
|
||||
Releases::V1_0_0 => upgrade_v1_to_v2::<T>(),
|
||||
}
|
||||
}
|
||||
|
||||
fn upgrade_v1_to_v2<T: Trait>() {
|
||||
deprecated::IsUpgraded::kill();
|
||||
|
||||
let current_era_start_index = deprecated::CurrentEraStartSessionIndex::get();
|
||||
let current_era = <Module<T> as Store>::CurrentEra::get().unwrap_or(0);
|
||||
let current_era_start = deprecated::CurrentEraStart::<T>::get();
|
||||
<Module<T> as Store>::ErasStartSessionIndex::insert(current_era, current_era_start_index);
|
||||
<Module<T> as Store>::ActiveEra::put(ActiveEraInfo {
|
||||
index: current_era,
|
||||
start: Some(current_era_start),
|
||||
});
|
||||
|
||||
let current_elected = deprecated::CurrentElected::<T>::get();
|
||||
let mut current_total_stake = <BalanceOf<T>>::zero();
|
||||
for validator in ¤t_elected {
|
||||
let exposure = deprecated::Stakers::<T>::get(validator);
|
||||
current_total_stake += exposure.total;
|
||||
<Module<T> as Store>::ErasStakers::insert(current_era, validator, &exposure);
|
||||
|
||||
let mut exposure_clipped = exposure;
|
||||
let clipped_max_len = T::MaxNominatorRewardedPerValidator::get() as usize;
|
||||
if exposure_clipped.others.len() > clipped_max_len {
|
||||
exposure_clipped.others.sort_unstable_by(|a, b| a.value.cmp(&b.value).reverse());
|
||||
exposure_clipped.others.truncate(clipped_max_len);
|
||||
}
|
||||
<Module<T> as Store>::ErasStakersClipped::insert(current_era, validator, exposure_clipped);
|
||||
|
||||
let pref = <Module<T> as Store>::Validators::get(validator);
|
||||
<Module<T> as Store>::ErasValidatorPrefs::insert(current_era, validator, pref);
|
||||
}
|
||||
<Module<T> as Store>::ErasTotalStake::insert(current_era, current_total_stake);
|
||||
|
||||
let points = deprecated::CurrentEraPointsEarned::get();
|
||||
<Module<T> as Store>::ErasRewardPoints::insert(current_era, EraRewardPoints {
|
||||
total: points.total,
|
||||
individual: current_elected.iter().cloned().zip(points.individual.iter().cloned()).collect(),
|
||||
});
|
||||
|
||||
let res = <Module<T> as Store>::Ledger::translate_values(
|
||||
|old: deprecated::OldStakingLedger<T::AccountId, BalanceOf<T>>| StakingLedger {
|
||||
stash: old.stash,
|
||||
total: old.total,
|
||||
active: old.active,
|
||||
unlocking: old.unlocking,
|
||||
last_reward: None,
|
||||
}
|
||||
);
|
||||
if let Err(e) = res {
|
||||
frame_support::print("Encountered error in migration of Staking::Ledger map.");
|
||||
frame_support::print("The number of removed key/value is:");
|
||||
frame_support::print(e);
|
||||
}
|
||||
|
||||
|
||||
// Kill old storages
|
||||
deprecated::Stakers::<T>::remove_all();
|
||||
deprecated::SlotStake::<T>::kill();
|
||||
deprecated::CurrentElected::<T>::kill();
|
||||
deprecated::CurrentEraStart::<T>::kill();
|
||||
deprecated::CurrentEraStartSessionIndex::kill();
|
||||
deprecated::CurrentEraPointsEarned::kill();
|
||||
|
||||
StorageVersion::put(Releases::V2_0_0);
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,220 +0,0 @@
|
||||
use crate::*;
|
||||
use crate::mock::*;
|
||||
use frame_support::storage::migration::*;
|
||||
use sp_core::hashing::blake2_256;
|
||||
use super::test_upgrade_from_master_dataset;
|
||||
use sp_runtime::traits::OnRuntimeUpgrade;
|
||||
|
||||
#[test]
|
||||
fn upgrade_works() {
|
||||
ExtBuilder::default().build().execute_with(|| {
|
||||
start_era(3);
|
||||
|
||||
assert_eq!(Session::validators(), vec![21, 11]);
|
||||
|
||||
// Insert fake data to check the migration
|
||||
put_storage_value::<Vec<AccountId>>(b"Staking", b"CurrentElected", b"", vec![21, 31]);
|
||||
put_storage_value::<SessionIndex>(b"Staking", b"CurrentEraStartSessionIndex", b"", 5);
|
||||
put_storage_value::<MomentOf<Test>>(b"Staking", b"CurrentEraStart", b"", 777);
|
||||
put_storage_value(
|
||||
b"Staking", b"Stakers", &blake2_256(&11u64.encode()),
|
||||
Exposure::<AccountId, Balance> {
|
||||
total: 10,
|
||||
own: 10,
|
||||
others: vec![],
|
||||
}
|
||||
);
|
||||
put_storage_value(
|
||||
b"Staking", b"Stakers", &blake2_256(&21u64.encode()),
|
||||
Exposure::<AccountId, Balance> {
|
||||
total: 20,
|
||||
own: 20,
|
||||
others: vec![],
|
||||
}
|
||||
);
|
||||
put_storage_value(
|
||||
b"Staking", b"Stakers", &blake2_256(&31u64.encode()),
|
||||
Exposure::<AccountId, Balance> {
|
||||
total: 30,
|
||||
own: 30,
|
||||
others: vec![],
|
||||
}
|
||||
);
|
||||
put_storage_value::<(u32, Vec<u32>)>(b"Staking", b"CurrentEraPointsEarned", b"", (12, vec![2, 10]));
|
||||
<Staking as Store>::ErasStakers::remove_all();
|
||||
<Staking as Store>::ErasStakersClipped::remove_all();
|
||||
|
||||
<Staking as Store>::StorageVersion::put(Releases::V1_0_0);
|
||||
|
||||
// Perform upgrade
|
||||
Staking::on_runtime_upgrade();
|
||||
|
||||
assert_eq!(<Staking as Store>::StorageVersion::get(), Releases::V2_0_0);
|
||||
|
||||
// Check migration
|
||||
assert_eq!(<Staking as Store>::ErasStartSessionIndex::get(3).unwrap(), 5);
|
||||
assert_eq!(<Staking as Store>::ErasRewardPoints::get(3), EraRewardPoints {
|
||||
total: 12,
|
||||
individual: vec![(21, 2), (31, 10)].into_iter().collect(),
|
||||
});
|
||||
assert_eq!(<Staking as Store>::ActiveEra::get().unwrap().index, 3);
|
||||
assert_eq!(<Staking as Store>::ActiveEra::get().unwrap().start, Some(777));
|
||||
assert_eq!(<Staking as Store>::CurrentEra::get().unwrap(), 3);
|
||||
assert_eq!(<Staking as Store>::ErasStakers::get(3, 11), Exposure {
|
||||
total: 0,
|
||||
own: 0,
|
||||
others: vec![],
|
||||
});
|
||||
assert_eq!(<Staking as Store>::ErasStakers::get(3, 21), Exposure {
|
||||
total: 20,
|
||||
own: 20,
|
||||
others: vec![],
|
||||
});
|
||||
assert_eq!(<Staking as Store>::ErasStakers::get(3, 31), Exposure {
|
||||
total: 30,
|
||||
own: 30,
|
||||
others: vec![],
|
||||
});
|
||||
assert_eq!(<Staking as Store>::ErasStakersClipped::get(3, 11), Exposure {
|
||||
total: 0,
|
||||
own: 0,
|
||||
others: vec![],
|
||||
});
|
||||
assert_eq!(<Staking as Store>::ErasStakersClipped::get(3, 21), Exposure {
|
||||
total: 20,
|
||||
own: 20,
|
||||
others: vec![],
|
||||
});
|
||||
assert_eq!(<Staking as Store>::ErasStakersClipped::get(3, 31), Exposure {
|
||||
total: 30,
|
||||
own: 30,
|
||||
others: vec![],
|
||||
});
|
||||
assert_eq!(<Staking as Store>::ErasValidatorPrefs::get(3, 21), Staking::validators(21));
|
||||
assert_eq!(<Staking as Store>::ErasValidatorPrefs::get(3, 31), Staking::validators(31));
|
||||
assert_eq!(<Staking as Store>::ErasTotalStake::get(3), 50);
|
||||
})
|
||||
}
|
||||
|
||||
// Test that an upgrade from previous test environment works.
|
||||
#[test]
|
||||
fn test_upgrade_from_master_works() {
|
||||
let data_sets = &[
|
||||
test_upgrade_from_master_dataset::_0,
|
||||
test_upgrade_from_master_dataset::_1,
|
||||
test_upgrade_from_master_dataset::_2,
|
||||
test_upgrade_from_master_dataset::_3,
|
||||
test_upgrade_from_master_dataset::_4,
|
||||
test_upgrade_from_master_dataset::_5,
|
||||
test_upgrade_from_master_dataset::_6,
|
||||
test_upgrade_from_master_dataset::_7,
|
||||
test_upgrade_from_master_dataset::_8,
|
||||
];
|
||||
for data_set in data_sets.iter() {
|
||||
let mut storage = sp_runtime::Storage::default();
|
||||
for (key, value) in data_set.iter() {
|
||||
storage.top.insert(key.to_vec(), value.to_vec());
|
||||
}
|
||||
let mut ext = sp_io::TestExternalities::from(storage);
|
||||
ext.execute_with(|| {
|
||||
let old_stakers =
|
||||
get_storage_value::<Vec<AccountId>>(b"Staking", b"CurrentElected", b"").unwrap();
|
||||
let old_staker_0 = old_stakers[0];
|
||||
let old_staker_1 = old_stakers[1];
|
||||
let old_current_era =
|
||||
get_storage_value::<EraIndex>(b"Staking", b"CurrentEra", b"").unwrap();
|
||||
let old_staker_0_exposure = get_storage_value::<Exposure<AccountId, Balance>>(
|
||||
b"Staking", b"Stakers", &blake2_256(&old_staker_0.encode())
|
||||
).unwrap();
|
||||
let old_staker_1_exposure = get_storage_value::<Exposure<AccountId, Balance>>(
|
||||
b"Staking", b"Stakers", &blake2_256(&old_staker_1.encode())
|
||||
).unwrap();
|
||||
let (
|
||||
old_era_points_earned_total,
|
||||
old_era_points_earned_individual
|
||||
) = get_storage_value::<(u32, Vec<u32>)>(b"Staking", b"CurrentEraPointsEarned", b"")
|
||||
.unwrap_or((0, vec![]));
|
||||
|
||||
Staking::on_runtime_upgrade();
|
||||
assert!(<Staking as Store>::StorageVersion::get() == Releases::V2_0_0);
|
||||
|
||||
// Check ActiveEra and CurrentEra
|
||||
let active_era = Staking::active_era().unwrap().index;
|
||||
let current_era = Staking::current_era().unwrap();
|
||||
assert!(current_era == active_era);
|
||||
assert!(current_era == old_current_era);
|
||||
|
||||
// Check ErasStartSessionIndex
|
||||
let active_era_start = Staking::eras_start_session_index(active_era).unwrap();
|
||||
let current_era_start = Staking::eras_start_session_index(current_era).unwrap();
|
||||
let current_session_index = Session::current_index();
|
||||
assert!(current_era_start == active_era_start);
|
||||
assert!(active_era_start <= current_session_index);
|
||||
assert_eq!(<Staking as Store>::ErasStartSessionIndex::iter().count(), 1);
|
||||
|
||||
// Check ErasStakers
|
||||
assert_eq!(<Staking as Store>::ErasStakers::iter().count(), 2);
|
||||
assert_eq!(
|
||||
<Staking as Store>::ErasStakers::get(current_era, old_staker_0),
|
||||
old_staker_0_exposure
|
||||
);
|
||||
assert_eq!(
|
||||
<Staking as Store>::ErasStakers::get(current_era, old_staker_1),
|
||||
old_staker_1_exposure
|
||||
);
|
||||
|
||||
// Check ErasStakersClipped
|
||||
assert_eq!(<Staking as Store>::ErasStakersClipped::iter().count(), 2);
|
||||
assert!(<Staking as Store>::ErasStakersClipped::iter().all(|exposure_clipped| {
|
||||
let max = <Test as Trait>::MaxNominatorRewardedPerValidator::get() as usize;
|
||||
exposure_clipped.others.len() <= max
|
||||
}));
|
||||
assert_eq!(
|
||||
<Staking as Store>::ErasStakersClipped::get(current_era, old_staker_0),
|
||||
old_staker_0_exposure
|
||||
);
|
||||
assert_eq!(
|
||||
<Staking as Store>::ErasStakersClipped::get(current_era, old_staker_1),
|
||||
old_staker_1_exposure
|
||||
);
|
||||
|
||||
// Check ErasValidatorPrefs
|
||||
assert_eq!(<Staking as Store>::ErasValidatorPrefs::iter().count(), 2);
|
||||
assert_eq!(
|
||||
<Staking as Store>::ErasValidatorPrefs::get(current_era, old_staker_0),
|
||||
Staking::validators(old_staker_0)
|
||||
);
|
||||
assert_eq!(
|
||||
<Staking as Store>::ErasValidatorPrefs::get(current_era, old_staker_1),
|
||||
Staking::validators(old_staker_1)
|
||||
);
|
||||
|
||||
// Check ErasTotalStake
|
||||
assert_eq!(<Staking as Store>::ErasTotalStake::iter().count(), 1);
|
||||
assert_eq!(
|
||||
<Staking as Store>::ErasTotalStake::get(current_era),
|
||||
old_staker_0_exposure.total + old_staker_1_exposure.total
|
||||
);
|
||||
|
||||
// Check ErasRewardPoints
|
||||
assert_eq!(<Staking as Store>::ErasRewardPoints::iter().count(), 1);
|
||||
let mut individual = BTreeMap::new();
|
||||
if let Some(p) = old_era_points_earned_individual.get(0) {
|
||||
individual.insert(old_staker_0, p.clone());
|
||||
}
|
||||
if let Some(p) = old_era_points_earned_individual.get(1) {
|
||||
individual.insert(old_staker_1, p.clone());
|
||||
}
|
||||
assert_eq!(
|
||||
<Staking as Store>::ErasRewardPoints::get(current_era),
|
||||
EraRewardPoints {
|
||||
total: old_era_points_earned_total,
|
||||
individual,
|
||||
}
|
||||
);
|
||||
|
||||
// Check ErasValidatorReward
|
||||
assert_eq!(<Staking as Store>::ErasValidatorReward::iter().count(), 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -25,10 +25,8 @@ use sp_staking::{SessionIndex, offence::{OffenceDetails, OnOffenceHandler}};
|
||||
use sp_core::{H256, crypto::key_types};
|
||||
use sp_io;
|
||||
use frame_support::{
|
||||
assert_ok, impl_outer_origin, parameter_types, StorageLinkedMap, StorageValue, StorageMap,
|
||||
StorageDoubleMap,
|
||||
traits::{Currency, Get, FindAuthor},
|
||||
weights::Weight,
|
||||
assert_ok, impl_outer_origin, parameter_types, StorageValue, StorageMap,
|
||||
StorageDoubleMap, IterableStorageMap, traits::{Currency, Get, FindAuthor}, weights::Weight,
|
||||
};
|
||||
use crate::{
|
||||
EraIndex, GenesisConfig, Module, Trait, StakerStatus, ValidatorPrefs, RewardDestination,
|
||||
@@ -140,7 +138,7 @@ impl frame_system::Trait for Test {
|
||||
type Version = ();
|
||||
type ModuleToIndex = ();
|
||||
type AccountData = pallet_balances::AccountData<u64>;
|
||||
type OnNewAccount = ();
|
||||
type MigrateAccount = (); type OnNewAccount = ();
|
||||
type OnKilledAccount = ();
|
||||
}
|
||||
impl pallet_balances::Trait for Test {
|
||||
@@ -373,7 +371,7 @@ pub fn check_exposure_all(era: EraIndex) {
|
||||
}
|
||||
|
||||
pub fn check_nominator_all(era: EraIndex) {
|
||||
<Nominators<Test>>::enumerate()
|
||||
<Nominators<Test>>::iter()
|
||||
.for_each(|(acc, _)| check_nominator_exposure(era, acc));
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ fn basic_setup_works() {
|
||||
assert_eq!(Staking::ledger(&1), None);
|
||||
|
||||
// ValidatorPrefs are default
|
||||
assert_eq!(<Validators<Test>>::enumerate().collect::<Vec<_>>(), vec![
|
||||
assert_eq!(<Validators<Test>>::iter().collect::<Vec<_>>(), vec![
|
||||
(31, ValidatorPrefs::default()),
|
||||
(21, ValidatorPrefs::default()),
|
||||
(11, ValidatorPrefs::default())
|
||||
@@ -2769,7 +2769,7 @@ fn slash_kicks_validators_not_nominators() {
|
||||
|
||||
// This is the best way to check that the validator was chilled; `get` will
|
||||
// return default value.
|
||||
for (stash, _) in <Staking as Store>::Validators::enumerate() {
|
||||
for (stash, _) in <Staking as Store>::Validators::iter() {
|
||||
assert!(stash != 11);
|
||||
}
|
||||
|
||||
@@ -2869,7 +2869,7 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() {
|
||||
// Fail: Era not finished yet
|
||||
Error::<Test>::InvalidEraToReward
|
||||
);
|
||||
|
||||
|
||||
// Era 0 can't be rewarded anymore and current era can't be rewarded yet
|
||||
// only era 1 and 2 can be rewarded.
|
||||
|
||||
@@ -2909,7 +2909,7 @@ fn zero_slash_keeps_nominators() {
|
||||
|
||||
// This is the best way to check that the validator was chilled; `get` will
|
||||
// return default value.
|
||||
for (stash, _) in <Staking as Store>::Validators::enumerate() {
|
||||
for (stash, _) in <Staking as Store>::Validators::iter() {
|
||||
assert!(stash != 11);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user