Skip to content

Commit

Permalink
Add migration
Browse files Browse the repository at this point in the history
  • Loading branch information
AurevoirXavier committed Oct 30, 2024
1 parent 13fbdbd commit ec6db8b
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 150 deletions.
74 changes: 74 additions & 0 deletions pallet/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,80 @@
#![deny(missing_docs)]
#![allow(clippy::needless_borrows_for_generic_args)]

#[allow(missing_docs)]
pub mod migration {
// darwinia
use crate::*;
// polkadot-sdk
use frame_support::migration;

const PALLET: &[u8] = b"DarwiniaStaking";

pub fn migrate<T>() -> (u64, u64)
where
T: Config,
{
fn clear(item: &[u8], r: &mut u64, w: &mut u64) {
let res = migration::clear_storage_prefix(PALLET, item, &[], None, None);

*r += res.loops as u64;
*w += res.backend as u64;
}

let rw @ (mut r, mut w) = (1, 1);

clear(b"Collators", &mut r, &mut w);
clear(b"Nominators", &mut r, &mut w);
clear(b"ExposureCacheStates", &mut r, &mut w);
clear(b"ExposureCache0", &mut r, &mut w);
clear(b"ExposureCache1", &mut r, &mut w);
clear(b"ExposureCache2", &mut r, &mut w);
clear(b"CacheStates", &mut r, &mut w);
clear(b"CollatorsCache0", &mut r, &mut w);
clear(b"CollatorsCache1", &mut r, &mut w);
clear(b"CollatorsCache2", &mut r, &mut w);
clear(b"MigrationStartPoint", &mut r, &mut w);
clear(b"RateLimit", &mut r, &mut w);
clear(b"RateLimitState", &mut r, &mut w);

if let Some(abc) = migration::take_storage_value::<(
BlockNumberFor<T>,
BTreeMap<T::AccountId, BlockNumberFor<T>>,
)>(PALLET, b"AuthoredBlocksCount", &[])
{
<AuthoredBlockCount<T>>::put(abc);
}

rw
}

pub fn post_check<T>()
where
T: Config,
{
fn assert_is_none(item: &[u8]) {
assert!(!migration::have_storage_value(PALLET, item, &[]));
}

assert_is_none(b"Collators");
assert_is_none(b"Nominators");
assert_is_none(b"ExposureCacheStates");
assert_is_none(b"ExposureCache0");
assert_is_none(b"ExposureCache1");
assert_is_none(b"ExposureCache2");
assert_is_none(b"CacheStates");
assert_is_none(b"CollatorsCache0");
assert_is_none(b"CollatorsCache1");
assert_is_none(b"CollatorsCache2");
assert_is_none(b"MigrationStartPoint");
assert_is_none(b"RateLimit");
assert_is_none(b"RateLimitState");
assert_is_none(b"AuthoredBlocksCount");

assert!(<AuthoredBlockCount<T>>::exists());
}
}

#[cfg(test)]
mod mock;
#[cfg(test)]
Expand Down
150 changes: 1 addition & 149 deletions runtime/common/src/migration_helper.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
pub use frame_support::migration;

// crates.io
use codec::{Decode, Encode};
// darwinia
use dc_primitives::{AccountId, Balance};
// polkadot-sdk
use frame_support::traits::ReservableCurrency;
use sp_runtime::traits::AppendZerosInput;
use sp_std::prelude::*;
use frame_support::migration;

/// Pallet migration helper.
pub struct PalletCleaner {
Expand Down Expand Up @@ -37,145 +31,3 @@ impl PalletCleaner {
})
}
}

pub fn migrate_identity<C>() -> u64
where
C: ReservableCurrency<AccountId, Balance = Balance>,
{
let w = migration::clear_storage_prefix(b"AccountMigration", b"Identities", &[], None, None)
.backend;
let w1 = migration::storage_iter_with_suffix::<Registration>(b"Identity", b"IdentityOf", &[])
.drain()
.fold(0, |acc, (k, v)| {
if k.len() > 20 {
let mut who = [0u8; 20];

who.copy_from_slice(&k[k.len() - 20..]);

let who = AccountId::from(who);
let deposit = v.deposit
+ v.judgements
.iter()
.map(|(_, ref j)| if let Judgement::FeePaid(fee) = j { *fee } else { 0 })
.sum::<Balance>();

C::unreserve(&who, deposit);

acc + 3
} else {
acc
}
});

(w + w1) as _
}

#[cfg_attr(test, derive(Debug, PartialEq))]
#[derive(Encode)]
struct Registration {
judgements: Vec<(u32, Judgement)>,
deposit: Balance,
info: IdentityInfo,
}
impl Decode for Registration {
fn decode<I: codec::Input>(input: &mut I) -> sp_std::result::Result<Self, codec::Error> {
let (judgements, deposit, info) = Decode::decode(&mut AppendZerosInput::new(input))?;
Ok(Self { judgements, deposit, info })
}
}

#[cfg_attr(test, derive(Debug, PartialEq))]
#[derive(Encode, Decode)]
enum Judgement {
Unknown,
FeePaid(Balance),
Reasonable,
KnownGood,
OutOfDate,
LowQuality,
Erroneous,
}

#[cfg_attr(test, derive(Debug, PartialEq))]
#[derive(Encode, Decode)]
struct IdentityInfo {
additional: Vec<(Data, Data)>,
display: Data,
legal: Data,
web: Data,
riot: Data,
email: Data,
pgp_fingerprint: Option<[u8; 20]>,
image: Data,
twitter: Data,
}

#[cfg_attr(test, derive(Debug, PartialEq))]
enum Data {
None,
Raw(Vec<u8>),
BlakeTwo256([u8; 32]),
Sha256([u8; 32]),
Keccak256([u8; 32]),
ShaThree256([u8; 32]),
}
impl Decode for Data {
fn decode<I: codec::Input>(input: &mut I) -> sp_std::result::Result<Self, codec::Error> {
let b = input.read_byte()?;
Ok(match b {
0 => Data::None,
n @ 1..=33 => {
let mut r = vec![0u8; n as usize - 1];
input.read(&mut r[..])?;
Data::Raw(r)
},
34 => Data::BlakeTwo256(<[u8; 32]>::decode(input)?),
35 => Data::Sha256(<[u8; 32]>::decode(input)?),
36 => Data::Keccak256(<[u8; 32]>::decode(input)?),
37 => Data::ShaThree256(<[u8; 32]>::decode(input)?),
_ => return Err(codec::Error::from("invalid leading byte")),
})
}
}
impl Encode for Data {
fn encode(&self) -> Vec<u8> {
match self {
Data::None => vec![0u8; 1],
Data::Raw(ref x) => {
let l = x.len().min(32);
let mut r = vec![l as u8 + 1; l + 1];
r[1..].copy_from_slice(&x[..l]);
r
},
Data::BlakeTwo256(ref h) => core::iter::once(34u8).chain(h.iter().cloned()).collect(),
Data::Sha256(ref h) => core::iter::once(35u8).chain(h.iter().cloned()).collect(),
Data::Keccak256(ref h) => core::iter::once(36u8).chain(h.iter().cloned()).collect(),
Data::ShaThree256(ref h) => core::iter::once(37u8).chain(h.iter().cloned()).collect(),
}
}
}

#[test]
fn identity_codec_should_work() {
let chain_raw_data = "0x040100000003008044fe2307236c0500000000000000000f41757265766f69725861766965720b586176696572204c61752168747470733a2f2f6c696e6b74722e65652f61757265766f69727861766965721b4061757265766f69727861766965723a6d61747269782e6f72671078617669657240696e762e636166650000104041757265766f6972586176696572";
let encoded = array_bytes::hex2bytes_unchecked(chain_raw_data);
let decoded = Registration::decode(&mut &encoded[..]).unwrap();
let expected = Registration {
judgements: vec![(1, Judgement::KnownGood)],
deposit: 100_025_800_000_000_000_000,
info: IdentityInfo {
additional: Vec::new(),
display: Data::Raw(b"AurevoirXavier".to_vec()),
legal: Data::Raw(b"Xavier Lau".to_vec()),
web: Data::Raw(b"https://linktr.ee/aurevoirxavier".to_vec()),
riot: Data::Raw(b"@aurevoirxavier:matrix.org".to_vec()),
email: Data::Raw(b"xavier@inv.cafe".to_vec()),
pgp_fingerprint: None,
image: Data::None,
twitter: Data::Raw(b"@AurevoirXavier".to_vec()),
},
};

assert_eq!(decoded, expected);
assert_eq!(encoded, expected.encode())
}
6 changes: 5 additions & 1 deletion runtime/crab/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ impl frame_support::traits::OnRuntimeUpgrade for CustomOnRuntimeUpgrade {
fn post_upgrade(_state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
log::info!("post");

darwinia_staking::migration::post_check::<Runtime>();

Ok(())
}

Expand All @@ -49,5 +51,7 @@ fn migrate() -> frame_support::weights::Weight {
let _ = System::kill_storage(RuntimeOrigin::root(), vec![k]);
}

<Runtime as frame_system::Config>::DbWeight::get().reads_writes(0, 1)
let (r, w) = darwinia_staking::migration::migrate::<Runtime>();

<Runtime as frame_system::Config>::DbWeight::get().reads_writes(r, w + 1)
}
4 changes: 4 additions & 0 deletions runtime/darwinia/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ impl frame_support::traits::OnRuntimeUpgrade for CustomOnRuntimeUpgrade {
fn post_upgrade(_state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
log::info!("post");

darwinia_staking::migration::post_check::<Runtime>();

Ok(())
}

Expand All @@ -45,5 +47,7 @@ impl frame_support::traits::OnRuntimeUpgrade for CustomOnRuntimeUpgrade {
}

fn migrate() -> frame_support::weights::Weight {
let (r, w) = darwinia_staking::migration::migrate::<Runtime>();

<Runtime as frame_system::Config>::DbWeight::get().reads_writes(0, 0)
}
4 changes: 4 additions & 0 deletions runtime/koi/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ impl frame_support::traits::OnRuntimeUpgrade for CustomOnRuntimeUpgrade {
fn post_upgrade(_state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
log::info!("post");

darwinia_staking::migration::post_check::<Runtime>();

Ok(())
}

Expand All @@ -45,5 +47,7 @@ impl frame_support::traits::OnRuntimeUpgrade for CustomOnRuntimeUpgrade {
}

fn migrate() -> frame_support::weights::Weight {
let (r, w) = darwinia_staking::migration::migrate::<Runtime>();

<Runtime as frame_system::Config>::DbWeight::get().reads_writes(0, 0)
}

0 comments on commit ec6db8b

Please sign in to comment.