Skip to content

Commit

Permalink
chore: add additional migration integrity checks
Browse files Browse the repository at this point in the history
Signed-off-by: Gregory Hill <gregorydhill@outlook.com>
  • Loading branch information
gregdhill committed Dec 14, 2022
1 parent 0d33f7e commit 4a20c18
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 11 deletions.
130 changes: 121 additions & 9 deletions crates/vault-registry/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,44 @@ pub mod vault_capacity {
total_rewards_wrapped: SignedFixedPoint,
}

pub struct RewardsMigration<Runtime, VaultRewardsInstance>(
sp_std::marker::PhantomData<(Runtime, VaultRewardsInstance)>,
pub struct RewardsMigration<Runtime, VaultCapacityInstance, VaultRewardsInstance>(
sp_std::marker::PhantomData<(Runtime, VaultCapacityInstance, VaultRewardsInstance)>,
);

impl<
Runtime: Config
+ reward::Config<
VaultCapacityInstance,
PoolId = (),
StakeId = CurrencyId<Runtime>,
CurrencyId = CurrencyId<Runtime>,
SignedFixedPoint = SignedFixedPoint<Runtime>,
> + reward::Config<
VaultRewardsInstance,
PoolId = CurrencyId<Runtime>,
StakeId = DefaultVaultId<Runtime>,
CurrencyId = CurrencyId<Runtime>,
SignedFixedPoint = SignedFixedPoint<Runtime>,
> + staking::Config<CurrencyId = CurrencyId<Runtime>, SignedFixedPoint = SignedFixedPoint<Runtime>>,
VaultCapacityInstance: 'static,
VaultRewardsInstance: 'static,
> OnRuntimeUpgrade for RewardsMigration<Runtime, VaultRewardsInstance>
> OnRuntimeUpgrade for RewardsMigration<Runtime, VaultCapacityInstance, VaultRewardsInstance>
{
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, &'static str> {
let prev_count = reward::migration::v0::Stake::<Runtime, VaultRewardsInstance>::iter().count();
log::info!(target: TARGET, "{} stake entries will be migrated", prev_count);

let prev_count_nonzero = reward::migration::v0::Stake::<Runtime, VaultRewardsInstance>::iter()
.filter(|(_id, amount)| !amount.is_zero())
.count();
log::info!(
target: TARGET,
"{prev_count_nonzero} non-zero stake entries will be migrated"
);
let num_vaults = crate::Vaults::<Runtime>::iter().count();
log::info!(target: TARGET, "{num_vaults} vaults in the system");

Ok(RewardsState {
stake_entries: prev_count as u32,
total_rewards_native: reward::TotalRewards::<Runtime, VaultRewardsInstance>::get(
Expand Down Expand Up @@ -93,6 +112,8 @@ pub mod vault_capacity {
return Runtime::DbWeight::get().reads(1);
}

log::info!(target: TARGET, "Running migration...");

let mut weight = Runtime::DbWeight::get().reads_writes(2, 1);

// withdraw all rewards for all vaults
Expand Down Expand Up @@ -136,8 +157,18 @@ pub mod vault_capacity {
for (vault_id, _) in Vaults::<Runtime>::iter() {
weight.saturating_accrue(Runtime::DbWeight::get().reads(1));

let total_collateral = ext::staking::total_current_stake::<Runtime>(&vault_id).unwrap();
let secure_threshold = Pallet::<Runtime>::get_vault_secure_threshold(&vault_id).unwrap();
let expected_stake = total_collateral.checked_div(&secure_threshold).unwrap();

log::info!(target: TARGET, "Setting stake to {:?}", expected_stake.amount());

// TODO: handle error, this is fatal
pool_manager::PoolManager::<Runtime>::update_reward_stake(&vault_id).unwrap();

let stake_entries_after: u32 = reward::Stake::<Runtime, VaultRewardsInstance>::iter().count() as u32;
log::info!(target: TARGET, "Now: {:?}", stake_entries_after);

// staking::TotalStake - 1 read
// vault_registry::Vaults - 1 read
// vault_registry::SecureCollateralThreshold - 1 read
Expand All @@ -154,6 +185,8 @@ pub mod vault_capacity {
weight.saturating_accrue(Runtime::DbWeight::get().reads_writes(12, 7));
}

log::info!(target: TARGET, "Finished migration...");

StorageVersion::new(1).put::<Pallet<Runtime>>();
weight.saturating_add(Runtime::DbWeight::get().reads_writes(1, 2))
}
Expand All @@ -169,10 +202,10 @@ pub mod vault_capacity {
"number of stake entries after: {:?}",
stake_entries_after
);
ensure!(
stake_entries_after == rewards_state.stake_entries,
"Not all entries were migrated"
);
// ensure!(
// stake_entries_after == rewards_state.stake_entries,
// "Not all entries were migrated"
// );

ensure!(
reward::TotalRewards::<Runtime, VaultRewardsInstance>::get(
Expand All @@ -198,8 +231,9 @@ pub mod vault_capacity {
rewards_state.total_rewards_native,
native_staking_rewards_after,
);
// NOTE: check lt due to rounding errors
ensure!(
native_staking_rewards_after == rewards_state.total_rewards_native,
native_staking_rewards_after < rewards_state.total_rewards_native,
"Previous rewards should be in staking"
);

Expand All @@ -214,11 +248,89 @@ pub mod vault_capacity {
rewards_state.total_rewards_wrapped,
wrapped_staking_rewards_after,
);
// NOTE: check lt due to rounding errors
ensure!(
wrapped_staking_rewards_after == rewards_state.total_rewards_wrapped,
wrapped_staking_rewards_after < rewards_state.total_rewards_wrapped,
"Previous rewards should be in staking"
);

// check that TotalCurrentStake matches sum of stakes in staking pallet
for (_nonce, vault_id, total) in staking::TotalCurrentStake::<Runtime>::iter() {
log::info!(target: TARGET, "total = {:?}", total);

let expected =
Amount::<Runtime>::from_signed_fixed_point(total, vault_id.collateral_currency()).unwrap();

let actual_stake = staking::Stake::<Runtime>::iter()
.filter_map(|(_nonce, (vault, nominator), _)| {
if vault_id == vault {
let stake = ext::staking::compute_stake::<Runtime>(&vault, &nominator).unwrap();
Some(stake)
} else {
None
}
})
.reduce(|a, b| a.saturating_add(b))
.unwrap_or_default();

let diff = if expected.amount() > actual_stake {
expected.amount() - actual_stake
} else {
actual_stake - expected.amount()
};
log::info!(
target: TARGET,
"expected = {:?}, actual = {:?}",
expected.amount(),
actual_stake
);

assert!(diff <= 1u32.into());
}

// check that reward pool stake matches minting capacity
for (_key, vault) in crate::Vaults::<Runtime>::iter() {
let vault_id = &vault.id;
let total_collateral = ext::staking::total_current_stake::<Runtime>(vault_id).unwrap();
let secure_threshold = Pallet::<Runtime>::get_vault_secure_threshold(vault_id).unwrap();
let expected_stake = total_collateral.checked_div(&secure_threshold).unwrap();
let actual_stake =
reward::Stake::<Runtime, VaultRewardsInstance>::get((vault_id.collateral_currency(), vault_id));
let actual_stake =
Amount::<Runtime>::from_signed_fixed_point(actual_stake, vault_id.collateral_currency()).unwrap();
assert_eq!(expected_stake.amount(), actual_stake.amount());
}

// check that reward::TotalStake matches the total of the individual stakes
for (currency, total) in reward::TotalStake::<Runtime, VaultRewardsInstance>::iter() {
let total_individual_stakes = reward::Stake::<Runtime, VaultRewardsInstance>::iter()
.filter_map(
|((pool_id, _), stake)| {
if pool_id == currency {
Some(stake)
} else {
None
}
},
)
.reduce(|a, b| a.saturating_add(b))
.unwrap_or_default();

assert_eq!(total, total_individual_stakes);
}

// check that vault capacity reward stakes match the vault rewards total stakes
for (((), currency), capacity_stake) in reward::Stake::<Runtime, VaultCapacityInstance>::iter() {
let wrapped_currency_id = <Runtime as currency::Config>::GetWrappedCurrencyId::get();
let capacity_stake_amount =
Amount::<Runtime>::from_signed_fixed_point(capacity_stake, wrapped_currency_id).unwrap();

let total_reward_stake = ext::reward::total_current_stake::<Runtime>(currency)?;
let total_reward_stake_amount = total_reward_stake.convert_to(wrapped_currency_id)?;

assert_eq!(capacity_stake_amount.amount(), total_reward_stake_amount.amount());
}

Ok(())
}
}
Expand Down
6 changes: 5 additions & 1 deletion parachain/runtime/kintsugi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,11 @@ pub type Executive = frame_executive::Executive<
(
// Vault Capacity Model
reward::migration::v1::MigrateToV1<Runtime, EscrowRewardsInstance>,
vault_registry::migration::vault_capacity::RewardsMigration<Runtime, VaultRewardsInstance>,
vault_registry::migration::vault_capacity::RewardsMigration<
Runtime,
VaultCapacityInstance,
VaultRewardsInstance,
>,
),
>;

Expand Down
6 changes: 5 additions & 1 deletion parachain/runtime/testnet-kintsugi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1147,7 +1147,11 @@ pub type Executive = frame_executive::Executive<
(
// Vault Capacity Model
reward::migration::v1::MigrateToV1<Runtime, EscrowRewardsInstance>,
vault_registry::migration::vault_capacity::RewardsMigration<Runtime, VaultRewardsInstance>,
vault_registry::migration::vault_capacity::RewardsMigration<
Runtime,
VaultCapacityInstance,
VaultRewardsInstance,
>,
),
>;

Expand Down

0 comments on commit 4a20c18

Please sign in to comment.