Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prime member selection (ElectionsPhragmen) migration #11

Merged
merged 4 commits into from
Jun 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
7 changes: 7 additions & 0 deletions frame/elections-phragmen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ use frame_system::{self as system, ensure_signed, ensure_root};
use frame_support::traits::MigrateAccount;

mod benchmarking;
mod migration;

/// The maximum votes allowed per voter.
pub const MAXIMUM_VOTE: usize = 16;
Expand Down Expand Up @@ -667,6 +668,12 @@ decl_module! {
// returns the correct weight.
Self::end_block(n)
}

fn on_runtime_upgrade() -> Weight {
migration::migrate::<T>();
// TODO: Find sensible weight
0
}
}
}

Expand Down
16 changes: 16 additions & 0 deletions frame/elections-phragmen/src/migration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use super::*;
use frame_support::{migration::{StorageKeyIterator, take_storage_item}, Twox64Concat};

pub fn migrate<T: Trait>() {
sp_runtime::print("🕊️ Migrating Election Phragmen.");
for (who, votes) in StorageKeyIterator
::<T::AccountId, Vec<T::AccountId>, Twox64Concat>
::new(b"PhragmenElection", b"VotesOf")
.drain()
{
if let Some(stake) = take_storage_item::<_, BalanceOf<T>, Twox64Concat>(b"PhragmenElection", b"StakeOf", &who) {
Voting::<T>::insert(who, (stake, votes));
}
sp_runtime::print("🕊️ Done Election Phragmen.");
}
}
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()
}
Loading