Skip to content

Commit

Permalink
migration code
Browse files Browse the repository at this point in the history
  • Loading branch information
Ank4n committed Jul 18, 2024
1 parent 41c01e6 commit 85498be
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 5 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 8 additions & 3 deletions polkadot/runtime/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1662,6 +1662,7 @@ parameter_types! {
// a concern, it is recommended to set to (existing pools + 10) to also account for any new
// pools getting created before the migration is actually executed.
pub const MaxPoolsToMigrate: u32 = 250;
pub const MaxAgentsToMigrate: u32 = 300;
}

/// All migrations that will run on the next runtime upgrade.
Expand Down Expand Up @@ -1697,11 +1698,15 @@ pub mod migrations {
pub type Unreleased = (
// Migrate NominationPools to `DelegateStake` adapter. This is unversioned upgrade and
// should not be applied yet in Kusama/Polkadot.
pallet_nomination_pools::migration::unversioned::DelegationStakeMigration<
// pallet_nomination_pools::migration::unversioned::DelegationStakeMigration<
// Runtime,
// MaxPoolsToMigrate,
// >,
// pallet_staking::migrations::v15::MigrateV14ToV15<Runtime>,
pallet_delegated_staking::migration::unversioned::ProxyDelegatorMigration<
Runtime,
MaxPoolsToMigrate,
MaxAgentsToMigrate,
>,
pallet_staking::migrations::v15::MigrateV14ToV15<Runtime>,
);
}

Expand Down
2 changes: 2 additions & 0 deletions substrate/frame/delegated-staking/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ sp-std = { workspace = true }
sp-runtime = { workspace = true }
sp-staking = { workspace = true }
sp-io = { workspace = true }
log = { workspace = true }

[dev-dependencies]
sp-core = { workspace = true, default-features = true }
Expand All @@ -40,6 +41,7 @@ std = [
"frame-election-provider-support/std",
"frame-support/std",
"frame-system/std",
"log/std",
"pallet-balances/std",
"pallet-nomination-pools/std",
"pallet-staking/std",
Expand Down
17 changes: 15 additions & 2 deletions substrate/frame/delegated-staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
#![deny(rustdoc::broken_intra_doc_links)]

mod impls;
pub mod migration;
#[cfg(test)]
mod mock;
#[cfg(test)]
Expand All @@ -149,14 +150,26 @@ use frame_support::{
Defensive, DefensiveOption, Imbalance, OnUnbalanced,
},
};
use sp_io::hashing::blake2_256;
use sp_runtime::{
traits::{CheckedAdd, CheckedSub, Zero, TrailingZeroInput},
traits::{CheckedAdd, CheckedSub, TrailingZeroInput, Zero},
ArithmeticError, DispatchResult, Perbill, RuntimeDebug, Saturating,
};
use sp_staking::{Agent, Delegator, EraIndex, StakingInterface, StakingUnchecked};
use sp_std::{convert::TryInto, prelude::*};
use sp_io::hashing::blake2_256;

/// The log target of this pallet.
pub const LOG_TARGET: &str = "runtime::delegated-staking";
// syntactic sugar for logging.
#[macro_export]
macro_rules! log {
($level:tt, $patter:expr $(, $values:expr)* $(,)?) => {
log::$level!(
target: $crate::LOG_TARGET,
concat!("[{:?}] 🏊‍♂️ ", $patter), <frame_system::Pallet<T>>::block_number() $(, $values)*
)
};
}
pub type BalanceOf<T> =
<<T as Config>::Currency as FunInspect<<T as frame_system::Config>::AccountId>>::Balance;

Expand Down
107 changes: 107 additions & 0 deletions substrate/frame/delegated-staking/src/migration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use super::*;
use frame_support::traits::{OnRuntimeUpgrade, UncheckedOnRuntimeUpgrade};
use sp_std::vec::Vec;

#[cfg(feature = "try-runtime")]
use sp_runtime::TryRuntimeError;

pub mod unversioned {
use super::*;
use frame_support::traits::tokens::Fortitude::Force;
use sp_runtime::traits::AccountIdConversion;

/// Migrates delegation from older derivation of [`AccountType::ProxyDelegator`] accounts
/// to the new one for all agents.
pub struct ProxyDelegatorMigration<T, MaxAgents>(sp_std::marker::PhantomData<(T, MaxAgents)>);

impl<T: Config, MaxAgents: Get<u32>> OnRuntimeUpgrade for ProxyDelegatorMigration<T, MaxAgents> {
fn on_runtime_upgrade() -> Weight {
let mut weight = Weight::zero();
let old_proxy_delegator = |agent: T::AccountId| {
T::PalletId::get()
.into_sub_account_truncating((AccountType::ProxyDelegator, agent.clone()))
};

Agents::<T>::iter_keys().take(MaxAgents::get() as usize).for_each(|agent| {
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 0));

let old_proxy = old_proxy_delegator(agent.clone());
Delegation::<T>::get(&old_proxy).map(|delegation| {
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 0));

let new_proxy =
Pallet::<T>::generate_proxy_delegator(Agent::from(agent.clone()));

// accrue read writes for `do_migrate_delegation`
weight.saturating_accrue(T::DbWeight::get().reads_writes(8, 8));
let _ = Pallet::<T>::do_migrate_delegation(
Delegator::from(old_proxy.clone()),
Delegator::from(new_proxy.clone()),
delegation.amount,
)
.map_err(|e| {
log!(
error,
"Failed to migrate old proxy delegator {:?} to new proxy {:?} for agent {:?} with error: {:?}",
old_proxy,
new_proxy,
agent,
e,
);
});
});
});

log!(info, "Finished migrating old proxy delegator accounts to new ones",);

weight
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(data: Vec<u8>) -> Result<(), TryRuntimeError> {
let mut unmigrated_count = 0;
let old_proxy_delegator = |agent: T::AccountId| {
T::PalletId::get()
.into_sub_account_truncating((AccountType::ProxyDelegator, agent.clone()))
};

Agents::<T>::iter_keys().take(MaxAgents::get() as usize).for_each(|agent| {
let old_proxy: T::AccountId = old_proxy_delegator(agent.clone());
let held_balance = Pallet::<T>::held_balance_of(Delegator::from(old_proxy.clone()));
let delegation = Delegation::<T>::get(&old_proxy);
if delegation.is_some() || !held_balance.is_zero() {
log!(
error,
"Old proxy delegator {:?} for agent {:?} is not migrated.",
old_proxy,
agent,
);
unmigrated_count = unmigrated_count + 1;
}
});

if unmigrated_count > 0 {
Err(TryRuntimeError::Other("Some old proxy delegator accounts are not migrated."))
} else {
Ok(())
}
}
}
}

0 comments on commit 85498be

Please sign in to comment.