Skip to content

Commit

Permalink
Merge pull request #10 from hicommonwealth/apopiak-staking-migration
Browse files Browse the repository at this point in the history
Add staking migration
  • Loading branch information
apopiak authored Jun 29, 2020
2 parents fee4052 + 39a031b commit e1ff57d
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 39 deletions.
1 change: 1 addition & 0 deletions frame/atomic-swap/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ impl frame_system::Trait for Test {
type Version = ();
type ModuleToIndex = ();
type AccountData = pallet_balances::AccountData<u64>;
type MigrateAccount = ();
type OnNewAccount = ();
type OnKilledAccount = ();
}
Expand Down
6 changes: 3 additions & 3 deletions frame/balances/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub fn on_runtime_upgrade<T: Trait<I>, I: Instance>() -> Weight {

// Upgrade from the pre-#4649 balances/vesting into the new balances.
fn upgrade_v1_to_v2<T: Trait<I>, I: Instance>() -> Weight {
sp_runtime::print("Upgrading Account Balances...");
sp_runtime::print("🕊️ Migrating Account Balances...");
// First, migrate from old FreeBalance to new Account.
// We also move all locks across since only accounts with FreeBalance values have locks.
// FreeBalance: map T::AccountId => T::Balance
Expand Down Expand Up @@ -139,7 +139,7 @@ fn upgrade_v1_to_v2<T: Trait<I>, I: Instance>() -> Weight {

StorageVersion::<I>::put(Releases::V2_0_0);

sp_runtime::print("Done Account Balances.");
// TODO determine actual weight
sp_runtime::print("🕊️ Done Account Balances.");
// TODO determine actual weight?
T::MaximumBlockWeight::get()
}
4 changes: 2 additions & 2 deletions frame/contracts/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub fn on_runtime_upgrade<T: Trait>() -> Weight {
// upgraded, nothing here will happen anyway.

fn change_name_contract_to_contracts<T: Trait>() -> Weight {
sp_runtime::print("Migrating Contracts.");
sp_runtime::print("🕊️ Migrating Contracts.");

let mut weight = 0;
let db = T::DbWeight::get();
Expand Down Expand Up @@ -76,6 +76,6 @@ fn change_name_contract_to_contracts<T: Trait>() -> Weight {
}
weight += db.reads(1);

sp_runtime::print("Done Contracts.");
sp_runtime::print("🕊️ Done Contracts.");
weight
}
9 changes: 8 additions & 1 deletion frame/democracy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ impl<T: Trait> MigrateAccount<T::AccountId> for Module<T> {
mod migration {
use super::*;

pub fn migrate<T: Trait>() {
pub fn migrate<T: Trait>() -> Weight {
mod deprecated {
use super::*;

Expand Down Expand Up @@ -660,6 +660,9 @@ mod migration {
DepositOf::<T>::migrate_key_from_blake(p);
Preimages::<T>::migrate_key_from_blake(h);
}

// TODO: figure out actual weight
0
}
}

Expand Down Expand Up @@ -697,6 +700,10 @@ decl_module! {

fn deposit_event() = default;

fn on_runtime_upgrade() -> Weight {
migration::migrate::<T>()
}

/// Propose a sensitive action to be taken.
///
/// The dispatch origin of this call must be _Signed_ and the sender must
Expand Down
4 changes: 2 additions & 2 deletions frame/finality-tracker/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub fn on_runtime_upgrade<T: Trait>() -> Weight {
// upgraded, nothing here will happen anyway.

fn change_name_timestamp_to_finality_tracker<T:Trait>() -> Weight {
sp_runtime::print("Migrating Finality Tracker.");
sp_runtime::print("🕊️ Migrating Finality Tracker.");

let mut reads = 0;
let mut writes = 0;
Expand Down Expand Up @@ -65,6 +65,6 @@ fn change_name_timestamp_to_finality_tracker<T:Trait>() -> Weight {
}
reads += 1;

sp_runtime::print("Done Finality Tracker.");
sp_runtime::print("🕊️ Done Finality Tracker.");
T::DbWeight::get().reads_writes(reads, writes)
}
4 changes: 2 additions & 2 deletions frame/identity/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub fn on_runtime_upgrade<T: Trait>() -> Weight {
// upgraded, nothing here will happen anyway.

fn change_name_sudo_to_identity<T: Trait>() -> Weight {
sp_runtime::print("Migrating Identity.");
sp_runtime::print("🕊️ Migrating Identity.");

let mut weight = 0;
let db = T::DbWeight::get();
Expand All @@ -56,6 +56,6 @@ fn change_name_sudo_to_identity<T: Trait>() -> Weight {
}
weight += db.reads(1);

sp_runtime::print("Done Identity.");
sp_runtime::print("🕊️ Done Identity.");
weight
}
27 changes: 4 additions & 23 deletions frame/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,8 @@ pub mod slashing;
pub mod offchain_election;
pub mod inflation;

pub mod migration;

use sp_std::{
result,
prelude::*,
Expand Down Expand Up @@ -1380,7 +1382,7 @@ decl_module! {
}

fn on_runtime_upgrade() -> Weight {
migrate::<T>();
migrate_hasher::<T>();
// TODO: determine actual weight
0
}
Expand Down Expand Up @@ -2228,7 +2230,7 @@ impl<T: Trait> MigrateAccount<T::AccountId> for Module<T> {
}
}

fn migrate<T: Trait>() {
fn migrate_hasher<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 {
Expand All @@ -2240,27 +2242,6 @@ fn migrate<T: Trait>() {
}
}

fn remove_migrate_era<T: Trait>() -> Weight {
#[allow(dead_code)]
mod inner {
pub struct Module<T>(sp_std::marker::PhantomData<T>);
frame_support::decl_storage! {
trait Store for Module<T: super::Trait> as Staking {
pub MigrateEra: Option<super::EraIndex>;
}
}
}

if let Releases::V3_0_0 = StorageVersion::get() {
StorageVersion::put(Releases::V4_0_0);
inner::MigrateEra::kill();

T::DbWeight::get().reads_writes(1, 1)
} else {
T::DbWeight::get().reads(1)
}
}

impl<T: Trait> Module<T> {
/// The total balance that can be slashed from a stash account as of right now.
pub fn slashable_balance_of(stash: &T::AccountId) -> BalanceOf<T> {
Expand Down
151 changes: 151 additions & 0 deletions frame/staking/src/migration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
use super::*;

use frame_support::weights::Weight;

/// Deprecated storages used for migration only.
mod deprecated {
use crate::{Trait, BalanceOf, SessionIndex, Exposure};
use codec::{Encode, Decode};
use frame_support::{decl_module, decl_storage};
use sp_std::prelude::*;

// edgeware uses `u64` for `Moment`
type Moment = u64;

/// 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>,
}

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: Moment;

/// 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(opaque_blake2_256) T::AccountId => Exposure<T::AccountId, BalanceOf<T>>;
}
}
}

#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)]
struct OldStakingLedger<AccountId, Balance: HasCompact> {
pub stash: AccountId,
#[codec(compact)]
pub total: Balance,
#[codec(compact)]
pub active: Balance,
pub unlocking: Vec<UnlockChunk<Balance>>,
}

/// Update storages to current version
///
/// 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
pub fn migrate_to_simple_payouts<T: Trait>() -> Weight {
sp_runtime::print("🕊️ Migrating Staking...");
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::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 &current_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: OldStakingLedger<T::AccountId, BalanceOf<T>>| StakingLedger {
stash: old.stash,
total: old.total,
active: old.active,
unlocking: old.unlocking,
claimed_rewards: vec![],
}
);
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::kill();
deprecated::CurrentEraStartSessionIndex::kill();
deprecated::CurrentEraPointsEarned::kill();

sp_runtime::print("🕊️ Done Staking.");
// TODO: determine actual weight?
T::MaximumBlockWeight::get()
}
8 changes: 4 additions & 4 deletions frame/system/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub fn migrate_block_hash<T: Trait>() -> Weight {
let db = T::DbWeight::get();
let block_num = Number::<T>::get();
if block_num > One::one() {
sp_runtime::print("Migrating BlockHashes...");
sp_runtime::print("🕊️ Migrating BlockHashes...");
BlockHash::<T>::migrate_key_from_blake(T::BlockNumber::zero());
let mut n = block_num - One::one() - One::one();
let mut migrations = 1;
Expand All @@ -26,7 +26,7 @@ pub fn migrate_block_hash<T: Trait>() -> Weight {
}
n -= One::one();
}
sp_runtime::print("Done BlockHashes");
sp_runtime::print("🕊️ Done BlockHashes");
db.reads_writes(migrations + 1, migrations)
} else {
sp_runtime::print("No BlockHashes to migrate...");
Expand All @@ -35,7 +35,7 @@ pub fn migrate_block_hash<T: Trait>() -> Weight {
}

pub fn migrate_accounts<T: Trait>() -> Weight {
sp_runtime::print("Migrating Accounts...");
sp_runtime::print("🕊️ Migrating Accounts...");
let mut count = 0u32;
if let Ok(accounts) = Vec::<T::AccountId>::decode(&mut &include_bytes!("accounts.scale")[..]) {
for a in &accounts {
Expand All @@ -50,6 +50,6 @@ pub fn migrate_accounts<T: Trait>() -> Weight {
}
}
sp_runtime::print(count);
sp_runtime::print("Done Accounts.");
sp_runtime::print("🕊️ Done Accounts.");
T::MaximumBlockWeight::get()
}
4 changes: 4 additions & 0 deletions frame/transaction-payment/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ decl_module! {
).unwrap(),
);
}

fn on_runtime_upgrade() -> Weight {
migration::on_runtime_upgrade::<T>()
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions frame/transaction-payment/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub fn on_runtime_upgrade<T: Trait>() -> Weight {
// upgraded, nothing here will happen anyway.

fn rename_and_convert<T: Trait>() -> Weight {
sp_runtime::print("Migrating Transaction Payment.");
sp_runtime::print("🕊️ Migrating Transaction Payment.");

let mut reads = 0;
let mut writes = 0;
Expand All @@ -49,6 +49,6 @@ fn rename_and_convert<T: Trait>() -> Weight {
}
reads += 1;

sp_runtime::print("Done Transaction Payment.");
sp_runtime::print("🕊️ Done Transaction Payment.");
T::DbWeight::get().reads_writes(reads, writes)
}

0 comments on commit e1ff57d

Please sign in to comment.