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
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.

2 changes: 2 additions & 0 deletions integration-tests/ahm/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ type RcChecks = (
pallet_rc_migrator::staking::fast_unstake::FastUnstakeMigrator<Polkadot>,
pallet_rc_migrator::conviction_voting::ConvictionVotingMigrator<Polkadot>,
pallet_rc_migrator::asset_rate::AssetRateMigrator<Polkadot>,
pallet_rc_migrator::staking::nom_pools::NomPoolsMigrator<Polkadot>,
pallet_rc_migrator::referenda::ReferendaMigrator<Polkadot>,
RcPolkadotChecks,
// other checks go here (if available on Polkadot, Kusama and Westend)
Expand Down Expand Up @@ -121,6 +122,7 @@ type AhChecks = (
pallet_rc_migrator::staking::fast_unstake::FastUnstakeMigrator<AssetHub>,
pallet_rc_migrator::conviction_voting::ConvictionVotingMigrator<AssetHub>,
pallet_rc_migrator::asset_rate::AssetRateMigrator<AssetHub>,
pallet_rc_migrator::staking::nom_pools::NomPoolsMigrator<AssetHub>,
pallet_rc_migrator::referenda::ReferendaMigrator<AssetHub>,
AhPolkadotChecks,
// other checks go here (if available on Polkadot, Kusama and Westend)
Expand Down
3 changes: 3 additions & 0 deletions pallets/ah-migrator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ sp-core = { workspace = true }
sp-io = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }
sp-staking = { workspace = true }
hex-literal = { workspace = true }
hex = { workspace = true }
xcm = { workspace = true }
Expand Down Expand Up @@ -106,6 +107,7 @@ std = [
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
"sp-staking/std",
"sp-std/std",
"xcm-builder/std",
"xcm-builder/std",
Expand Down Expand Up @@ -148,6 +150,7 @@ runtime-benchmarks = [
"polkadot-runtime-constants/runtime-benchmarks",
"runtime-parachains/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"sp-staking/runtime-benchmarks",
"xcm-builder/runtime-benchmarks",
"xcm-executor/runtime-benchmarks",
# "asset-hub-polkadot-runtime/runtime-benchmarks"
Expand Down
2 changes: 1 addition & 1 deletion pallets/ah-migrator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ use pallet_rc_migrator::{
types::MigrationFinishedData,
vesting::RcVestingSchedule,
};
use pallet_referenda::{ReferendumInfo, TrackIdOf};
use pallet_referenda::TrackIdOf;
use polkadot_runtime_common::{claims as pallet_claims, impls::VersionedLocatableAsset};
use referenda::RcReferendumInfoOf;
use scheduler::RcSchedulerMessageOf;
Expand Down
240 changes: 240 additions & 0 deletions pallets/ah-migrator/src/staking/nom_pools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
use crate::*;
use frame_support::traits::DefensiveSaturating;
use pallet_nomination_pools::BondedPoolInner;
#[cfg(feature = "std")]
use pallet_rc_migrator::staking::nom_pools::tests;
use pallet_rc_migrator::staking::nom_pools::{BalanceOf, NomPoolsMigrator};
use sp_runtime::{
traits::{CheckedSub, One},
Saturating,
Expand Down Expand Up @@ -141,3 +144,240 @@ impl<T: Config> Pallet<T> {
}
}
}

#[cfg(feature = "std")]
impl<T: Config> crate::types::AhMigrationCheck for NomPoolsMigrator<T> {
type RcPrePayload = Vec<
tests::GenericNomPoolsMessage<
BalanceOf<T>,
T::RewardCounter,
<T as frame_system::Config>::AccountId,
BlockNumberFor<T>,
>,
>;
type AhPrePayload = ();

fn pre_check(_: Self::RcPrePayload) -> Self::AhPrePayload {
assert!(
pallet_nomination_pools::TotalValueLocked::<T>::get().is_zero(),
"Assert storage 'NominationPools::TotalValueLocked::ah_pre::empty'"
);
assert!(
pallet_nomination_pools::MinJoinBond::<T>::get().is_zero(),
"Assert storage 'NominationPools::MinJoinBond::ah_pre::empty'"
);
assert!(
pallet_nomination_pools::MinCreateBond::<T>::get().is_zero(),
"Assert storage 'NominationPools::MinCreateBond::ah_pre::empty'"
);
assert!(
pallet_nomination_pools::MaxPools::<T>::get().is_none(),
"Assert storage 'NominationPools::MaxPools::ah_pre::empty'"
);
assert!(
pallet_nomination_pools::MaxPoolMembers::<T>::get().is_none(),
"Assert storage 'NominationPools::MaxPoolMembers::ah_pre::empty'"
);
assert!(
pallet_nomination_pools::MaxPoolMembersPerPool::<T>::get().is_none(),
"Assert storage 'NominationPools::MaxPoolMembersPerPool::ah_pre::empty'"
);
assert!(
pallet_nomination_pools::GlobalMaxCommission::<T>::get().is_none(),
"Assert storage 'NominationPools::GlobalMaxCommission::ah_pre::empty'"
);
assert!(
pallet_nomination_pools::LastPoolId::<T>::get().is_zero(),
"Assert storage 'NominationPools::LastPoolId::ah_pre::empty'"
);
assert!(
pallet_nomination_pools::PoolMembers::<T>::iter().next().is_none(),
"Assert storage 'NominationPools::PoolMembers::ah_pre::empty'"
);
assert!(
pallet_nomination_pools::BondedPools::<T>::iter().next().is_none(),
"Assert storage 'NominationPools::BondedPools::ah_pre::empty'"
);
assert!(
pallet_rc_migrator::staking::nom_pools_alias::RewardPools::<T>::iter()
.next()
.is_none(),
"Assert storage 'NominationPools::RewardPools::ah_pre::empty'"
);
assert!(
pallet_rc_migrator::staking::nom_pools_alias::SubPoolsStorage::<T>::iter()
.next()
.is_none(),
"Assert storage 'NominationPools::SubPoolsStorage::ah_pre::empty'"
);
assert!(
pallet_nomination_pools::Metadata::<T>::iter().next().is_none(),
"Assert storage 'NominationPools::Metadata::ah_pre::empty'"
);
assert!(
pallet_nomination_pools::ReversePoolIdLookup::<T>::iter().next().is_none(),
"Assert storage 'NominationPools::ReversePoolIdLookup::ah_pre::empty'"
);
assert!(
pallet_nomination_pools::ClaimPermissions::<T>::iter().next().is_none(),
"Assert storage 'NominationPools::ClaimPermissions::ah_pre::empty'"
);
}

fn post_check(rc_pre_payload: Self::RcPrePayload, _: Self::AhPrePayload) {
let mut ah_messages = Vec::new();

// Collect storage values from AH
let values = NomPoolsStorageValues {
total_value_locked: pallet_nomination_pools::TotalValueLocked::<T>::get(),
min_join_bond: pallet_nomination_pools::MinJoinBond::<T>::get(),
min_create_bond: pallet_nomination_pools::MinCreateBond::<T>::get(),
max_pools: pallet_nomination_pools::MaxPools::<T>::get(),
max_pool_members: pallet_nomination_pools::MaxPoolMembers::<T>::get(),
max_pool_members_per_pool: pallet_nomination_pools::MaxPoolMembersPerPool::<T>::get(),
global_max_commission: pallet_nomination_pools::GlobalMaxCommission::<T>::get(),
last_pool_id: pallet_nomination_pools::LastPoolId::<T>::get(),
};
ah_messages.push(tests::GenericNomPoolsMessage::StorageValues { values });

// Collect all other storage items from AH
for (who, member) in pallet_nomination_pools::PoolMembers::<T>::iter() {
let generic_member = tests::GenericPoolMember {
pool_id: member.pool_id,
points: member.points,
last_recorded_reward_counter: member.last_recorded_reward_counter,
unbonding_eras: member.unbonding_eras.into_inner(),
};
ah_messages
.push(tests::GenericNomPoolsMessage::PoolMembers { member: (who, generic_member) });
}

for (pool_id, pool) in pallet_nomination_pools::BondedPools::<T>::iter() {
let generic_pool = tests::GenericBondedPoolInner {
commission: tests::GenericCommission {
current: pool.commission.current,
max: pool.commission.max,
change_rate: pool.commission.change_rate,
throttle_from: pool.commission.throttle_from,
claim_permission: pool.commission.claim_permission,
},
member_counter: pool.member_counter,
points: pool.points,
roles: pool.roles,
state: pool.state,
};
ah_messages
.push(tests::GenericNomPoolsMessage::BondedPools { pool: (pool_id, generic_pool) });
}

for (pool_id, rewards) in
pallet_rc_migrator::staking::nom_pools_alias::RewardPools::<T>::iter()
{
let generic_rewards = tests::GenericRewardPool {
last_recorded_reward_counter: rewards.last_recorded_reward_counter,
last_recorded_total_payouts: rewards.last_recorded_total_payouts,
total_rewards_claimed: rewards.total_rewards_claimed,
total_commission_pending: rewards.total_commission_pending,
total_commission_claimed: rewards.total_commission_claimed,
};
ah_messages.push(tests::GenericNomPoolsMessage::RewardPools {
rewards: (pool_id, generic_rewards),
});
}

for (pool_id, sub_pools) in
pallet_rc_migrator::staking::nom_pools_alias::SubPoolsStorage::<T>::iter()
{
let generic_sub_pools = tests::GenericSubPools {
no_era: tests::GenericUnbondPool {
points: sub_pools.no_era.points,
balance: sub_pools.no_era.balance,
},
with_era: sub_pools
.with_era
.into_inner()
.into_iter()
.map(|(era, pool)| {
(
era,
tests::GenericUnbondPool { points: pool.points, balance: pool.balance },
)
})
.collect(),
};
ah_messages.push(tests::GenericNomPoolsMessage::SubPoolsStorage {
sub_pools: (pool_id, generic_sub_pools),
});
}

for (pool_id, meta) in pallet_nomination_pools::Metadata::<T>::iter() {
let meta_converted = BoundedVec::<u8, ConstU32<256>>::try_from(meta.into_inner())
.expect("Metadata length is known to be within bounds; qed");
ah_messages
.push(tests::GenericNomPoolsMessage::Metadata { meta: (pool_id, meta_converted) });
}

for (who, pool_id) in pallet_nomination_pools::ReversePoolIdLookup::<T>::iter() {
ah_messages.push(tests::GenericNomPoolsMessage::ReversePoolIdLookup {
lookups: (who, pool_id),
});
}

for (who, perms) in pallet_nomination_pools::ClaimPermissions::<T>::iter() {
ah_messages
.push(tests::GenericNomPoolsMessage::ClaimPermissions { perms: (who, perms) });
}

let ah_filtered: Vec<_> = ah_messages
.into_iter()
.map(|msg| match msg {
// If the message is of type BondedPools, we remove the throttle_from value
// from the commission. This is necessary because in AssetHub, the value of
// throttle_from is calculated dynamically using block_number(),
// and it cannot be correctly obtained during the postcheck. By removing
// this value, we avoid conflicts and ensure that the AH system functions as
// intended.
tests::GenericNomPoolsMessage::BondedPools { pool: (id, mut inner) } => {
inner.commission.throttle_from = None;
tests::GenericNomPoolsMessage::BondedPools { pool: (id, inner) }
},
other => other,
})
.collect();

// Assert storage "NominationPools::TotalValueLocked::ah_post::correct"
// Assert storage "NominationPools::TotalValueLocked::ah_post::consistent"
// Assert storage "NominationPools::MinJoinBond::ah_post::correct"
// Assert storage "NominationPools::MinJoinBond::ah_post::consistent"
// Assert storage "NominationPools::MinCreateBond::ah_post::correct"
// Assert storage "NominationPools::MinCreateBond::ah_post::consistent"
// Assert storage "NominationPools::MaxPools::ah_post::correct"
// Assert storage "NominationPools::MaxPools::ah_post::consistent"
// Assert storage "NominationPools::MaxPoolMembers::ah_post::correct"
// Assert storage "NominationPools::MaxPoolMembers::ah_post::consistent"
// Assert storage "NominationPools::MaxPoolMembersPerPool::ah_post::correct"
// Assert storage "NominationPools::MaxPoolMembersPerPool::ah_post::consistent"
// Assert storage "NominationPools::GlobalMaxCommission::ah_post::correct"
// Assert storage "NominationPools::GlobalMaxCommission::ah_post::consistent"
// Assert storage "NominationPools::LastPoolId::ah_post::correct"
// Assert storage "NominationPools::LastPoolId::ah_post::consistent"
// Assert storage "NominationPools::PoolMembers::ah_post::correct"
// Assert storage "NominationPools::PoolMembers::ah_post::consistent"
// Assert storage "NominationPools::BondedPools::ah_post::correct"
// Assert storage "NominationPools::BondedPools::ah_post::consistent"
// Assert storage "NominationPools::RewardPools::ah_post::correct"
// Assert storage "NominationPools::RewardPools::ah_post::consistent"
// Assert storage "NominationPools::SubPoolsStorage::ah_post::correct"
// Assert storage "NominationPools::SubPoolsStorage::ah_post::consistent"
// Assert storage "NominationPools::Metadata::ah_post::correct"
// Assert storage "NominationPools::Metadata::ah_post::consistent"
// Assert storage "NominationPools::ReversePoolIdLookup::ah_post::correct"
// Assert storage "NominationPools::ReversePoolIdLookup::ah_post::consistent"
// Assert storage "NominationPools::ClaimPermissions::ah_post::correct"
// Assert storage "NominationPools::ClaimPermissions::ah_post::consistent"
assert_eq!(
rc_pre_payload, ah_filtered,
"Assert storage 'NominationPools::Metadata::ah_post::correct'"
);
}
}
2 changes: 1 addition & 1 deletion pallets/ah-migrator/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub trait AhMigrationCheck {
fn post_check(rc_pre_payload: Self::RcPrePayload, ah_pre_payload: Self::AhPrePayload);
}

#[impl_trait_for_tuples::impl_for_tuples(16)]
#[impl_trait_for_tuples::impl_for_tuples(24)]
impl AhMigrationCheck for Tuple {
for_tuples! { type RcPrePayload = (#( Tuple::RcPrePayload ),* ); }
for_tuples! { type AhPrePayload = (#( Tuple::AhPrePayload ),* ); }
Expand Down
Loading