Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/clippy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
- name: Clippy
run: |
cargo clippy --version
cargo clippy --all-targets --locked --workspace --quiet
cargo clippy --all-targets --locked --workspace --quiet
cargo clippy --all-targets --locked --workspace --features try-runtime,runtime-benchmarks,std --quiet
cargo clippy --all-targets --locked --quiet --features try-runtime,runtime-benchmarks,std,kusama-ahm -p staging-kusama-runtime -p asset-hub-kusama-runtime
cargo clippy --all-targets --locked --quiet --features try-runtime,runtime-benchmarks,std,polkadot-ahm -p polkadot-runtime -p asset-hub-polkadot-runtime
Expand Down
12 changes: 12 additions & 0 deletions pallets/ah-migrator/src/account_translation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ impl<T: Config> Pallet<T> {
}

/// Translate the account if its a parachain sovereign account.
#[cfg(any(feature = "polkadot-ahm", feature = "kusama-ahm"))]
fn maybe_sovereign_translate(account: &T::AccountId) -> Option<T::AccountId> {
let Some(new) = crate::sovereign_account_translation::SOV_TRANSLATIONS
.binary_search_by_key(account, |((rc_acc, _), _)| rc_acc.clone())
Expand All @@ -64,7 +65,13 @@ impl<T: Config> Pallet<T> {
Some(new)
}

#[cfg(not(any(feature = "polkadot-ahm", feature = "kusama-ahm")))]
fn maybe_sovereign_translate(account: &T::AccountId) -> Option<T::AccountId> {
None
}

/// Translate the account if its derived from a parachain sovereign account.
#[cfg(any(feature = "polkadot-ahm", feature = "kusama-ahm"))]
fn maybe_derived_translate(account: &T::AccountId) -> Option<T::AccountId> {
let Some((new, idx)) = crate::sovereign_account_translation::DERIVED_TRANSLATIONS
.binary_search_by_key(account, |((rc_acc, _), _, _)| rc_acc.clone())
Expand All @@ -88,4 +95,9 @@ impl<T: Config> Pallet<T> {

Some(new.clone())
}

#[cfg(not(any(feature = "polkadot-ahm", feature = "kusama-ahm")))]
fn maybe_derived_translate(account: &T::AccountId) -> Option<T::AccountId> {
None
}
}
4 changes: 2 additions & 2 deletions pallets/ah-migrator/src/sovereign_account_translation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use sp_runtime::AccountId32;
// AUTOGENERATED BELOW
// RC snap path: ../../polkadot.snap
/// List of RC para to AH sibl sovereign account translation sorted by RC account.
#[cfg(not(feature = "kusama-ahm"))]
#[cfg(feature = "polkadot-ahm")]
pub const SOV_TRANSLATIONS: &[((AccountId32, &'static str), (AccountId32, &'static str))] = &[
// para 0
(
Expand Down Expand Up @@ -822,7 +822,7 @@ pub const SOV_TRANSLATIONS: &[((AccountId32, &'static str), (AccountId32, &'stat
];

/// List of RC para to AH sibl derived account translation sorted by RC account.
#[cfg(not(feature = "kusama-ahm"))]
#[cfg(feature = "polkadot-ahm")]
pub const DERIVED_TRANSLATIONS: &[(
(AccountId32, &'static str),
u16,
Expand Down
168 changes: 94 additions & 74 deletions pallets/ah-migrator/src/staking/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,16 @@

//! Checks that the staking migration succeeded.

use pallet_rc_migrator::staking::{
message::{PortableNominations, PortableUnappliedSlash},
RcData,
use codec::Encode;
use pallet_rc_migrator::{
staking::{
message::{PortableNominations, PortableUnappliedSlash},
RcData,
},
types::{SortByEncoded, TranslateAccounts},
};
use sp_runtime::{AccountId32, Perbill};
use sp_runtime::{AccountId32, Perbill, WeakBoundedVec};
use std::fmt::Debug;

impl<T: crate::Config> crate::types::AhMigrationCheck
for pallet_rc_migrator::staking::StakingMigratedCorrectly<T>
Expand All @@ -31,6 +36,8 @@ impl<T: crate::Config> crate::types::AhMigrationCheck
fn pre_check(_rc: Self::RcPrePayload) -> Self::AhPrePayload {}

fn post_check(rc: Self::RcPrePayload, _ah_pre_payload: Self::AhPrePayload) {
let t = crate::Pallet::<T>::translate_account_rc_to_ah;

// Storage Values
assert_eq!(rc.validator_count, pallet_staking_async::ValidatorCount::<T>::get());
// Min validator count is not migrated and instead configured via `MinimumValidatorSetSize`
Expand All @@ -56,99 +63,83 @@ impl<T: crate::Config> crate::types::AhMigrationCheck
assert_eq!(rc.chill_threshold, pallet_staking_async::ChillThreshold::<T>::get());

// Storage Maps
assert_eq!(rc.invulnerables, pallet_staking_async::Invulnerables::<T>::get().into_inner());
assert_eq!(rc.bonded, pallet_staking_async::Bonded::<T>::iter().collect::<Vec<_>>());
assert_eq!(
rc.ledger.into_iter().map(|(k, v)| (k, v.into())).collect::<Vec<_>>(),
pallet_staking_async::Ledger::<T>::iter().collect::<Vec<_>>()
assert_equal_items(rc.invulnerables, pallet_staking_async::Invulnerables::<T>::get());
assert_equal_items(
rc.bonded.into_iter().map(|(a, b)| (t(a), t(b))),
pallet_staking_async::Bonded::<T>::iter(),
);
assert_eq!(
rc.payee
.into_iter()
.map(|(k, v)| (k, translate_reward_destination(v)))
.collect::<Vec<_>>(),
pallet_staking_async::Payee::<T>::iter().collect::<Vec<_>>()
assert_equal_items(
rc.ledger.into_iter().map(|(k, v)| (t(k), v.translate_accounts(&t).into())),
pallet_staking_async::Ledger::<T>::iter(),
);
assert_eq!(
rc.validators
.into_iter()
.map(|(k, v)| (k, translate_validator_prefs(v)))
.collect::<Vec<_>>(),
pallet_staking_async::Validators::<T>::iter().collect::<Vec<_>>()
assert_equal_items(
rc.payee.into_iter().map(|(k, v)| (t(k), translate_reward_destination(v, &t))),
pallet_staking_async::Payee::<T>::iter(),
);
assert_eq!(
rc.nominators
.into_iter()
.map(|(k, v)| (k, translate_nominations(v)))
.collect::<Vec<_>>(),
pallet_staking_async::Nominators::<T>::iter().collect::<Vec<_>>()
assert_equal_items(
rc.validators.into_iter().map(|(k, v)| (k, translate_validator_prefs(v))),
pallet_staking_async::Validators::<T>::iter(),
);
assert_eq!(
rc.virtual_stakers,
pallet_staking_async::VirtualStakers::<T>::iter_keys().collect::<Vec<_>>()
assert_equal_items(
rc.nominators.into_iter().map(|(k, v)| (t(k), translate_nominations(v, &t))),
pallet_staking_async::Nominators::<T>::iter(),
);
assert_eq!(
rc.eras_stakers_overview
.into_iter()
.map(|(k1, k2, v)| (k1, k2, v.into()))
.collect::<Vec<_>>(),
pallet_staking_async::ErasStakersOverview::<T>::iter().collect::<Vec<_>>()
assert_equal_items(
rc.virtual_stakers.into_iter().map(t),
pallet_staking_async::VirtualStakers::<T>::iter_keys(),
);
assert_eq!(
assert_equal_items(
rc.eras_stakers_overview.into_iter().map(|(k1, k2, v)| (k1, t(k2), v.into())),
pallet_staking_async::ErasStakersOverview::<T>::iter(),
);
assert_equal_items(
rc.eras_stakers_paged
.into_iter()
.map(|(k, v)| (k, v.into()))
.collect::<Vec<_>>(),
pallet_staking_async::ErasStakersPaged::<T>::iter().collect::<Vec<_>>()
.map(|((k0, k1, k2), v)| ((k0, t(k1), k2), v.translate_accounts(&t).into())),
pallet_staking_async::ErasStakersPaged::<T>::iter(),
);
assert_eq!(
rc.claimed_rewards,
pallet_staking_async::ClaimedRewards::<T>::iter()
.map(|(k1, k2, v)| (k1, k2, v.into_inner()))
.collect::<Vec<_>>()
);
assert_eq!(
rc.eras_validator_prefs
assert_equal_items(
rc.claimed_rewards
.into_iter()
.map(|(k1, k2, v)| (k1, k2, v.into()))
.collect::<Vec<_>>(),
pallet_staking_async::ErasValidatorPrefs::<T>::iter().collect::<Vec<_>>()
.map(|(k0, k1, v)| (k0, t(k1), WeakBoundedVec::force_from(v, None))),
pallet_staking_async::ClaimedRewards::<T>::iter(),
);
assert_eq!(
assert_equal_items(
rc.eras_validator_prefs.into_iter().map(|(k1, k2, v)| (k1, t(k2), v.into())),
pallet_staking_async::ErasValidatorPrefs::<T>::iter(),
);
assert_equal_items(
rc.eras_validator_reward,
pallet_staking_async::ErasValidatorReward::<T>::iter().collect::<Vec<_>>()
pallet_staking_async::ErasValidatorReward::<T>::iter(),
);
assert_eq!(
assert_equal_items(
rc.eras_reward_points
.into_iter()
.map(|(k, v)| (k, v.into()))
.collect::<Vec<_>>(),
pallet_staking_async::ErasRewardPoints::<T>::iter().collect::<Vec<_>>()
.map(|(k, v)| (k, v.translate_accounts(&t).into())),
pallet_staking_async::ErasRewardPoints::<T>::iter(),
);
assert_eq!(
rc.eras_total_stake,
pallet_staking_async::ErasTotalStake::<T>::iter().collect::<Vec<_>>()
);
check_unapplied_slashes::<T>(rc.unapplied_slashes);
assert_eq!(rc.bonded_eras, pallet_staking_async::BondedEras::<T>::get().into_inner());
assert_eq!(
rc.validator_slash_in_era,
pallet_staking_async::ValidatorSlashInEra::<T>::iter().collect::<Vec<_>>()
assert_equal_items(rc.eras_total_stake, pallet_staking_async::ErasTotalStake::<T>::iter());
check_unapplied_slashes::<T>(rc.unapplied_slashes, &t);
assert_equal_items(rc.bonded_eras, pallet_staking_async::BondedEras::<T>::get());
assert_equal_items(
rc.validator_slash_in_era.into_iter().map(|(k0, k1, v)| (k0, t(k1), v)),
pallet_staking_async::ValidatorSlashInEra::<T>::iter(),
);
}
}

#[allow(deprecated)]
fn translate_reward_destination(
destination: pallet_staking::RewardDestination<AccountId32>,
t: &impl Fn(AccountId32) -> AccountId32,
) -> pallet_staking_async::RewardDestination<AccountId32> {
use pallet_staking_async::RewardDestination::*;

match destination {
pallet_staking::RewardDestination::Staked => Staked,
pallet_staking::RewardDestination::Stash => Stash,
pallet_staking::RewardDestination::Controller => Controller,
pallet_staking::RewardDestination::Account(account) => Account(account),
pallet_staking::RewardDestination::Account(account) => Account(t(account)),
pallet_staking::RewardDestination::None => None,
}
}
Expand All @@ -175,25 +166,54 @@ fn translate_validator_prefs(

fn translate_nominations<T: crate::Config>(
nominations: PortableNominations,
t: &impl Fn(AccountId32) -> AccountId32,
) -> pallet_staking_async::Nominations<T> {
pallet_staking_async::Nominations {
targets: nominations.targets.into_inner().try_into().expect("Must not truncate"),
targets: nominations
.targets
.into_inner()
.into_iter()
.map(t)
.collect::<Vec<_>>()
.try_into()
.expect("Must not truncate"),
submitted_in: nominations.submitted_in,
suppressed: nominations.suppressed,
}
}

fn check_unapplied_slashes<T: crate::Config>(rc: Vec<(u32, Vec<PortableUnappliedSlash>)>) {
let mut expected_slashes =
Vec::<(u32, (AccountId32, Perbill, u32), PortableUnappliedSlash)>::new();
fn check_unapplied_slashes<T: crate::Config>(
rc: Vec<(u32, Vec<PortableUnappliedSlash>)>,
t: &impl Fn(AccountId32) -> AccountId32,
) {
let mut expected_slashes = Vec::new();

for (era, slashes) in rc {
for slash in slashes {
// We insert all slashes with this special key
let key = (slash.validator.clone(), Perbill::from_percent(99), 9999);
expected_slashes.push((era, key, slash));
let key = (t(slash.clone().validator), Perbill::from_percent(99), 9999);
expected_slashes.push((era, key, slash.translate_accounts(t).into()));
}
}

// TODO assert
assert_equal_items(expected_slashes, pallet_staking_async::UnappliedSlashes::<T>::iter());
}

/// Assert that two iterators have the same elements, regardless of their order.
fn assert_equal_items<
V: Encode + PartialEq + Debug,
I: IntoIterator<Item = V>,
J: IntoIterator<Item = V>,
>(
rc: I,
ah: J,
) {
let mut rc: Vec<V> = rc.into_iter().collect::<Vec<_>>();
rc.sort_by_encoded();
let mut ah: Vec<V> = ah.into_iter().collect::<Vec<_>>();
ah.sort_by_encoded();

for (i, (r, a)) in rc.iter().zip(ah.iter()).enumerate() {
assert_eq!(r, a, "Entry #{i} mismatch: {r:?} != {a:?}");
}
}
7 changes: 6 additions & 1 deletion pallets/ah-migrator/src/staking/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
//! Pallet staking migration.

use crate::*;
use pallet_rc_migrator::{staking::PortableStakingMessage, types::DefensiveTruncateInto};
use pallet_rc_migrator::{
staking::PortableStakingMessage,
types::{DefensiveTruncateInto, TranslateAccounts},
};
use sp_runtime::Perbill;

impl<T: Config> Pallet<T> {
Expand Down Expand Up @@ -50,6 +53,8 @@ impl<T: Config> Pallet<T> {
fn do_receive_staking_message(message: PortableStakingMessage) -> Result<(), Error<T>> {
use PortableStakingMessage::*;

let message = message.translate_accounts(&Self::translate_account_rc_to_ah);

match message {
Values(values) => {
log::debug!(target: LOG_TARGET, "Integrating StakingValues");
Expand Down
Loading
Loading