-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: Replace StakesInfo per era stakes with latest staked amount (…
…#254) * Modify StakesInfo to store last staked value * Refactor runtime to work with last staked value * Add migration for creator-staking pallet * Refactor tests for creator-staking pallet * Update spec_version to 40 --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
- Loading branch information
1 parent
c525607
commit 01fb722
Showing
9 changed files
with
222 additions
and
221 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
// Copyright (C) DAPPFORCE PTE. LTD. | ||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0. | ||
// | ||
// Full notice is available at https://github.com/dappforce/subsocial-parachain/blob/main/COPYRIGHT | ||
// Full license is available at https://github.com/dappforce/subsocial-parachain/blob/main/LICENSE | ||
|
||
use codec::{Decode, Encode}; | ||
use frame_support::{ | ||
ensure, log, | ||
pallet_prelude::{Get, GetStorageVersion}, | ||
traits::OnRuntimeUpgrade, | ||
weights::Weight, | ||
}; | ||
use sp_runtime::traits::Zero; | ||
use sp_std::vec::Vec; | ||
|
||
use crate::{migration::old::OldStakesInfo, types::BalanceOf, Config, Pallet, StakesInfo}; | ||
|
||
const LOG_TARGET: &'static str = "runtime::creator-staking"; | ||
|
||
mod old { | ||
use codec::MaxEncodedLen; | ||
use frame_support::{ | ||
dispatch::TypeInfo, pallet_prelude::ValueQuery, storage_alias, Blake2_128Concat, | ||
BoundedVec, RuntimeDebug, | ||
}; | ||
use sp_arithmetic::traits::AtLeast32BitUnsigned; | ||
|
||
use crate::{CreatorId, EraStake}; | ||
|
||
use super::*; | ||
|
||
pub(super) type OldStakesInfoOf<T> = | ||
OldStakesInfo<BalanceOf<T>, <T as Config>::MaxEraStakeItems>; | ||
|
||
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] | ||
#[scale_info(skip_type_params(MaxEraStakeItems))] | ||
pub(super) struct OldStakesInfo< | ||
Balance: AtLeast32BitUnsigned + Copy + MaxEncodedLen, | ||
MaxEraStakeItems: Get<u32>, | ||
> { | ||
pub(crate) stakes: BoundedVec<EraStake<Balance>, MaxEraStakeItems>, | ||
} | ||
|
||
impl<Balance, MaxEraStakeItems> Default for OldStakesInfo<Balance, MaxEraStakeItems> | ||
where | ||
Balance: AtLeast32BitUnsigned + Copy + MaxEncodedLen, | ||
MaxEraStakeItems: Get<u32>, | ||
{ | ||
fn default() -> Self { | ||
Self { stakes: BoundedVec::<EraStake<Balance>, MaxEraStakeItems>::default() } | ||
} | ||
} | ||
|
||
#[storage_alias] | ||
pub(super) type BackerStakesByCreator<T: Config> = StorageDoubleMap< | ||
Pallet<T>, | ||
Blake2_128Concat, | ||
<T as frame_system::Config>::AccountId, | ||
Blake2_128Concat, | ||
CreatorId, | ||
OldStakesInfoOf<T>, | ||
ValueQuery, | ||
>; | ||
} | ||
|
||
pub struct MigrateToV1<T>(sp_std::marker::PhantomData<T>); | ||
|
||
impl<T: Config> OnRuntimeUpgrade for MigrateToV1<T> { | ||
fn on_runtime_upgrade() -> Weight { | ||
let current_version = Pallet::<T>::current_storage_version(); | ||
let onchain_version = Pallet::<T>::on_chain_storage_version(); | ||
|
||
log::info!( | ||
target: LOG_TARGET, | ||
"Running migration with current storage version {:?} / onchain {:?}", | ||
current_version, | ||
onchain_version | ||
); | ||
|
||
if onchain_version == 0 && current_version == 1 { | ||
let mut translated: usize = 0; | ||
|
||
crate::BackerStakesByCreator::<T>::translate_values( | ||
|old: OldStakesInfo<BalanceOf<T>, <T as Config>::MaxEraStakeItems>| { | ||
let last_staked = old.stakes.last().map_or(Zero::zero(), |s| s.staked); | ||
|
||
let new_stakes = StakesInfo { stakes: old.stakes, staked: last_staked }; | ||
translated += 1; | ||
Some(new_stakes) | ||
}, | ||
); | ||
|
||
current_version.put::<Pallet<T>>(); | ||
|
||
log::info!( | ||
target: LOG_TARGET, | ||
"Upgraded {} BackerStakesByCreator records, storage updated to version {:?}", | ||
translated, | ||
current_version | ||
); | ||
T::DbWeight::get().reads_writes((translated + 1) as u64, (translated + 1) as u64) | ||
} else { | ||
log::info!( | ||
target: LOG_TARGET, | ||
"Migration did not execute. This probably should be removed" | ||
); | ||
T::DbWeight::get().reads(1) | ||
} | ||
} | ||
|
||
#[cfg(feature = "try-runtime")] | ||
fn pre_upgrade() -> Result<Vec<u8>, &'static str> { | ||
let current_version = Pallet::<T>::current_storage_version(); | ||
let onchain_version = Pallet::<T>::on_chain_storage_version(); | ||
ensure!(onchain_version == 0 && current_version == 1, "migration from version 0 to 1."); | ||
let prev_count = old::BackerStakesByCreator::<T>::iter().count(); | ||
Ok((prev_count as u32).encode()) | ||
} | ||
|
||
#[cfg(feature = "try-runtime")] | ||
fn post_upgrade(prev_count: Vec<u8>) -> Result<(), &'static str> { | ||
let prev_count: u32 = Decode::decode(&mut prev_count.as_slice()) | ||
.expect("the state parameter should be something that was generated by pre_upgrade"); | ||
let post_count = crate::BackerStakesByCreator::<T>::iter().count() as u32; | ||
ensure!( | ||
prev_count == post_count, | ||
"the records count before and after the migration should be the same" | ||
); | ||
|
||
let conflicts_count = crate::BackerStakesByCreator::<T>::iter() | ||
.filter_map(|(_, _, backer_stakes)| { | ||
if backer_stakes.stakes.last().map_or(Zero::zero(), |s| s.staked) == backer_stakes.staked { | ||
None | ||
} else { | ||
Some(()) | ||
} | ||
}).count(); | ||
|
||
ensure!(conflicts_count.is_zero(), "latest staked value was migrated incorrectly"); | ||
|
||
ensure!(Pallet::<T>::on_chain_storage_version() == 1, "wrong storage version"); | ||
|
||
Ok(()) | ||
} | ||
} |
Oops, something went wrong.