Skip to content

Commit

Permalink
Correct migration logic
Browse files Browse the repository at this point in the history
  • Loading branch information
ntn-x2 committed Apr 11, 2023
1 parent 3021f01 commit 6187dc9
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 269 deletions.
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.

3 changes: 3 additions & 0 deletions runtimes/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ frame-support.workspace = true
frame-system.workspace = true
pallet-authorship.workspace = true
pallet-balances.workspace = true
pallet-insecure-randomness-collective-flip.workspace = true
pallet-membership.workspace = true
pallet-transaction-payment.workspace = true
sp-consensus-aura.workspace = true
Expand Down Expand Up @@ -85,6 +86,7 @@ std = [
"log/std",
"pallet-authorship/std",
"pallet-balances/std",
"pallet-insecure-randomness-collective-flip/std",
"pallet-membership/std",
"pallet-transaction-payment/std",
"parachain-staking/std",
Expand All @@ -111,6 +113,7 @@ try-runtime = [
"pallet-balances/try-runtime",
"pallet-did-lookup",
"pallet-inflation",
"pallet-insecure-randomness-collective-flip/try-runtime",
"pallet-membership/try-runtime",
"pallet-transaction-payment/try-runtime",
"parachain-staking/try-runtime",
Expand Down
293 changes: 35 additions & 258 deletions runtimes/common/src/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,276 +16,53 @@

// If you feel like getting in touch with us, you can do so at [email protected]

use frame_support::traits::{GetStorageVersion, OnRuntimeUpgrade};
use sp_runtime::traits::{Get, Zero};
use frame_support::{
storage::unhashed::clear_prefix, traits::OnRuntimeUpgrade, weights::Weight, StorageHasher, Twox128,
};
use sp_core::Get;
use sp_io::MultiRemovalResults;
use sp_std::marker::PhantomData;

use ctype::{CtypeCreatorOf, CtypeEntryOf};
const PALLET_RUNTIME_NAME: &[u8] = b"RandomnessCollectiveFlip";
const PALLET_STORAGE_NAME: &[u8] = b"RandomMaterial";

#[cfg(feature = "try-runtime")]
use sp_std::vec::Vec;
pub struct RemoveInsecureRandomnessPallet<T>(PhantomData<T>);

pub struct AddCTypeBlockNumber<R>(PhantomData<R>);

impl<T: ctype::Config> OnRuntimeUpgrade for AddCTypeBlockNumber<T> {
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, &'static str> {
// Missed the migration when v1 was introduced, so now Spiritnet and Peregrine
// are on v0 although they should be on v1.
assert!(ctype::Pallet::<T>::on_chain_storage_version() <= 1,);

// Use iter_keys() on new storage so it won't try to decode values.
let ctypes_to_migrate = ctype::Ctypes::<T>::iter_keys().count() as u64;

log::info!("🪪 CType pallet pre check: {:?} CTypes to migrate", ctypes_to_migrate);
Ok(ctypes_to_migrate.to_be_bytes().into())
}

fn on_runtime_upgrade() -> frame_support::weights::Weight {
let current = ctype::Pallet::<T>::current_storage_version();
let onchain = ctype::Pallet::<T>::on_chain_storage_version();

log::info!(
"💰 Running CType migration with current storage version {:?} / onchain {:?}",
current,
onchain
);

let mut num_translations = 0u64;
let default_block_number = <T as frame_system::Config>::BlockNumber::zero();

ctype::Ctypes::<T>::translate_values(|old: CtypeCreatorOf<T>| {
num_translations = num_translations.saturating_add(1);
Some(CtypeEntryOf::<T> {
creator: old,
created_at: default_block_number,
})
});
current.put::<ctype::Pallet<T>>();

// Num translations + old version read and new version write
T::DbWeight::get().reads_writes(num_translations.saturating_add(1), num_translations.saturating_add(1))
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(state: Vec<u8>) -> Result<(), &'static str> {
assert_eq!(ctype::Pallet::<T>::on_chain_storage_version(), 2);

let initial_ctype_count = u64::from_be_bytes(state.try_into().expect("input state should be 8 bytes"));
assert_eq!(initial_ctype_count, ctype::Ctypes::<T>::iter().count() as u64);
// Verify all migrated ctypes can be decoded under the new type.
ctype::Ctypes::<T>::iter_values().for_each(|v| assert!(v.created_at.is_zero()));

log::info!(
"🪪 CType pallet post checks ok, all {:} CTypes have been migrated ✅",
initial_ctype_count
);
Ok(())
}
}

pub struct MigrateToNewStorageVersion<R>(PhantomData<R>);

impl<R> MigrateToNewStorageVersion<R>
where
R: attestation::Config + pallet_web3_names::Config + public_credentials::Config,
{
fn migrate() -> frame_support::weights::Weight {
type AttestationPallet<R> = attestation::Pallet<R>;
type Web3NamesPallet<R> = pallet_web3_names::Pallet<R>;
type PublicCredentialsPallet<R> = public_credentials::Pallet<R>;

AttestationPallet::<R>::current_storage_version().put::<AttestationPallet<R>>();
// Not an issue with Peregrine, but it is with Spiritnet.
Web3NamesPallet::<R>::current_storage_version().put::<Web3NamesPallet<R>>();
PublicCredentialsPallet::<R>::current_storage_version().put::<PublicCredentialsPallet<R>>();

<R as frame_system::Config>::DbWeight::get().writes(3)
}
}

#[cfg(feature = "try-runtime")]
impl<R> OnRuntimeUpgrade for MigrateToNewStorageVersion<R>
impl<T> OnRuntimeUpgrade for RemoveInsecureRandomnessPallet<T>
where
R: attestation::Config
+ ctype::Config
+ delegation::Config
+ did::Config
+ pallet_did_lookup::Config
+ pallet_inflation::Config
+ pallet_web3_names::Config
+ parachain_staking::Config
+ public_credentials::Config,
T: frame_system::Config,
{
fn pre_upgrade() -> Result<Vec<u8>, &'static str> {
type AttestationPallet<R> = attestation::Pallet<R>;
type DelegationPallet<R> = delegation::Pallet<R>;
type DidPallet<R> = did::Pallet<R>;
type LookupPallet<R> = pallet_did_lookup::Pallet<R>;
type InflationPallet<R> = pallet_inflation::Pallet<R>;
type Web3NamesPallet<R> = pallet_web3_names::Pallet<R>;
type ParachainStakingPallet<R> = parachain_staking::Pallet<R>;
type PublicCredentialsPallet<R> = public_credentials::Pallet<R>;

log::info!("💿 Storage version pre checks");

if AttestationPallet::<R>::on_chain_storage_version() != AttestationPallet::<R>::current_storage_version() {
log::warn!(
"🚨 Attestation pallet on chain version {:?} != declared storage version {:?}.",
AttestationPallet::<R>::on_chain_storage_version(),
AttestationPallet::<R>::current_storage_version()
)
}
if DelegationPallet::<R>::on_chain_storage_version() != DelegationPallet::<R>::current_storage_version() {
log::warn!(
"🚨 Delegation pallet on chain version {:?} != declared storage version {:?}.",
DelegationPallet::<R>::on_chain_storage_version(),
DelegationPallet::<R>::current_storage_version()
)
}
if DidPallet::<R>::on_chain_storage_version() != DidPallet::<R>::current_storage_version() {
log::warn!(
"🚨 Did pallet on chain version {:?} != declared storage version {:?}.",
DidPallet::<R>::on_chain_storage_version(),
DidPallet::<R>::current_storage_version()
)
}
if LookupPallet::<R>::on_chain_storage_version() != LookupPallet::<R>::current_storage_version() {
log::warn!(
"🚨 Lookup pallet on chain version {:?} != declared storage version {:?}.",
LookupPallet::<R>::on_chain_storage_version(),
LookupPallet::<R>::current_storage_version()
)
}
if InflationPallet::<R>::on_chain_storage_version() != InflationPallet::<R>::current_storage_version() {
log::warn!(
"🚨 Inflation pallet on chain version {:?} != declared storage version {:?}.",
InflationPallet::<R>::on_chain_storage_version(),
InflationPallet::<R>::current_storage_version()
)
}
if Web3NamesPallet::<R>::on_chain_storage_version() != Web3NamesPallet::<R>::current_storage_version() {
log::warn!(
"🚨 Web3names pallet on chain version {:?} != declared storage version {:?}.",
Web3NamesPallet::<R>::on_chain_storage_version(),
Web3NamesPallet::<R>::current_storage_version()
)
}
if ParachainStakingPallet::<R>::on_chain_storage_version()
!= ParachainStakingPallet::<R>::current_storage_version()
{
log::warn!(
"🚨 Parachain staking pallet on chain version {:?} != declared storage version {:?}.",
ParachainStakingPallet::<R>::on_chain_storage_version(),
ParachainStakingPallet::<R>::current_storage_version()
)
}
if PublicCredentialsPallet::<R>::on_chain_storage_version()
!= PublicCredentialsPallet::<R>::current_storage_version()
{
log::warn!(
"🚨 Public credentials pallet on chain version {:?} != declared storage version {:?}.",
PublicCredentialsPallet::<R>::on_chain_storage_version(),
PublicCredentialsPallet::<R>::current_storage_version()
)
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<sp_std::vec::Vec<u8>, &'static str> {
log::info!("RemoveInsecureRandomnessPallet::pre_upgrade() checks 🔎");
if frame_support::migration::have_storage_value(PALLET_RUNTIME_NAME, PALLET_STORAGE_NAME, b"") {
Ok(sp_std::vec::Vec::default())
} else {
Err("Storage in pallet_insecure_randomness_collective_flip is already empty before migration.")
}

Ok(Vec::default())
}

fn on_runtime_upgrade() -> frame_support::weights::Weight {
Self::migrate()
}

fn post_upgrade(_state: Vec<u8>) -> Result<(), &'static str> {
type AttestationPallet<R> = attestation::Pallet<R>;
type CTypePallet<R> = ctype::Pallet<R>;
type DelegationPallet<R> = delegation::Pallet<R>;
type DidPallet<R> = did::Pallet<R>;
type LookupPallet<R> = pallet_did_lookup::Pallet<R>;
type InflationPallet<R> = pallet_inflation::Pallet<R>;
type Web3NamesPallet<R> = pallet_web3_names::Pallet<R>;
type ParachainStakingPallet<R> = parachain_staking::Pallet<R>;
type PublicCredentialsPallet<R> = public_credentials::Pallet<R>;

assert_eq!(
AttestationPallet::<R>::on_chain_storage_version(),
AttestationPallet::<R>::current_storage_version(),
"Attestation pallet on chain version {:?} != declared storage version {:?}.",
AttestationPallet::<R>::on_chain_storage_version(),
AttestationPallet::<R>::current_storage_version()
);
// Although it's part of a different migration, we check that the CType pallet
// storage version is also consistent.
assert_eq!(
CTypePallet::<R>::on_chain_storage_version(),
CTypePallet::<R>::current_storage_version(),
"CType pallet on chain version {:?} != declared storage version {:?}.",
CTypePallet::<R>::on_chain_storage_version(),
CTypePallet::<R>::current_storage_version()
fn on_runtime_upgrade() -> Weight {
let MultiRemovalResults { unique, .. } = clear_prefix(
&Twox128::hash(PALLET_RUNTIME_NAME),
// Storage version and `RandomMaterial` vector.
Some(2),
None,
);
assert_eq!(
DelegationPallet::<R>::on_chain_storage_version(),
DelegationPallet::<R>::current_storage_version(),
"Delegation pallet on chain version {:?} != declared storage version {:?}.",
DelegationPallet::<R>::on_chain_storage_version(),
DelegationPallet::<R>::current_storage_version()
);
assert_eq!(
DidPallet::<R>::on_chain_storage_version(),
DidPallet::<R>::current_storage_version(),
"Did pallet on chain version {:?} != declared storage version {:?}.",
DidPallet::<R>::on_chain_storage_version(),
DidPallet::<R>::current_storage_version()
);
assert_eq!(
LookupPallet::<R>::on_chain_storage_version(),
LookupPallet::<R>::current_storage_version(),
"Lookup pallet on chain version {:?} != declared storage version {:?}.",
LookupPallet::<R>::on_chain_storage_version(),
LookupPallet::<R>::current_storage_version()
);
assert_eq!(
InflationPallet::<R>::on_chain_storage_version(),
InflationPallet::<R>::current_storage_version(),
"Inflation pallet on chain version {:?} != declared storage version {:?}.",
InflationPallet::<R>::on_chain_storage_version(),
InflationPallet::<R>::current_storage_version()
);
assert_eq!(
Web3NamesPallet::<R>::on_chain_storage_version(),
Web3NamesPallet::<R>::current_storage_version(),
"Web3names pallet on chain version {:?} != declared storage version {:?}.",
Web3NamesPallet::<R>::on_chain_storage_version(),
Web3NamesPallet::<R>::current_storage_version()
);
assert_eq!(
ParachainStakingPallet::<R>::on_chain_storage_version(),
ParachainStakingPallet::<R>::current_storage_version(),
"Parachain staking pallet on chain version {:?} != declared storage version {:?}.",
ParachainStakingPallet::<R>::on_chain_storage_version(),
ParachainStakingPallet::<R>::current_storage_version()
);
assert_eq!(
PublicCredentialsPallet::<R>::on_chain_storage_version(),
PublicCredentialsPallet::<R>::current_storage_version(),
"Public credentials pallet on chain version {:?} != declared storage version {:?}.",
PublicCredentialsPallet::<R>::on_chain_storage_version(),
PublicCredentialsPallet::<R>::current_storage_version()
log::info!(
"Deleted {} elements from the pallet_insecure_randomness_collective_flip pallet storage.",
unique
);

log::info!("💿 Storage version post checks ok ✅");

Ok(())
T::DbWeight::get().writes(unique.into())
}
}

#[cfg(not(feature = "try-runtime"))]
impl<R> OnRuntimeUpgrade for MigrateToNewStorageVersion<R>
where
R: attestation::Config + pallet_web3_names::Config + public_credentials::Config,
{
fn on_runtime_upgrade() -> frame_support::weights::Weight {
Self::migrate()
#[cfg(feature = "try-runtime")]
fn post_upgrade(_state: sp_std::vec::Vec<u8>) -> Result<(), &'static str> {
log::info!("RemoveInsecureRandomnessPallet::post_upgrade() checks 🔍");
if frame_support::migration::have_storage_value(PALLET_RUNTIME_NAME, PALLET_STORAGE_NAME, b"") {
Err("Storage in pallet_insecure_randomness_collective_flip is not empty after migration.")
} else {
Ok(())
}
}
}
6 changes: 2 additions & 4 deletions runtimes/peregrine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,8 +692,6 @@ impl pallet_utility::Config for Runtime {
type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
}

impl pallet_insecure_randomness_collective_flip::Config for Runtime {}

impl public_credentials::Config for Runtime {
type AccessControl = PalletAuthorize<DelegationAc<Runtime>>;
type AttesterId = DidIdentifier;
Expand Down Expand Up @@ -922,7 +920,7 @@ construct_runtime! {
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system = 0,
RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip = 1,
// DELETED: RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip = 1,

Timestamp: pallet_timestamp = 2,
Indices: pallet_indices::{Pallet, Call, Storage, Event<T>} = 5,
Expand Down Expand Up @@ -1078,7 +1076,7 @@ pub type Executive = frame_executive::Executive<
Runtime,
// Executes pallet hooks in the order of definition in construct_runtime
AllPalletsWithSystem,
pallet_did_lookup::migrations::EthereumMigration<Runtime>,
runtime_common::migrations::RemoveInsecureRandomnessPallet<Runtime>,
>;

#[cfg(feature = "runtime-benchmarks")]
Expand Down
6 changes: 2 additions & 4 deletions runtimes/spiritnet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -689,8 +689,6 @@ impl pallet_utility::Config for Runtime {
type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
}

impl pallet_insecure_randomness_collective_flip::Config for Runtime {}

impl public_credentials::Config for Runtime {
type AccessControl = PalletAuthorize<DelegationAc<Runtime>>;
type AttesterId = DidIdentifier;
Expand Down Expand Up @@ -919,7 +917,7 @@ construct_runtime! {
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system = 0,
RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip = 1,
// DELETED: RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip = 1,

Timestamp: pallet_timestamp = 2,
Indices: pallet_indices::{Pallet, Call, Storage, Event<T>} = 5,
Expand Down Expand Up @@ -1072,7 +1070,7 @@ pub type Executive = frame_executive::Executive<
Runtime,
// Executes pallet hooks in the order of definition in construct_runtime
AllPalletsWithSystem,
pallet_did_lookup::migrations::EthereumMigration<Runtime>,
runtime_common::migrations::RemoveInsecureRandomnessPallet<Runtime>,
>;

#[cfg(feature = "runtime-benchmarks")]
Expand Down
Loading

0 comments on commit 6187dc9

Please sign in to comment.