Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: on-chain storage version for pallets where it is missing #458

Merged
merged 6 commits into from
Jan 30, 2023
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
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pallets/ctype/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub mod pallet {
use crate::ctype_entry::CtypeEntry;

/// The current storage version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
const STORAGE_VERSION: StorageVersion = StorageVersion::new(2);

/// Type of a CType hash.
pub type CtypeHashOf<T> = <T as frame_system::Config>::Hash;
Expand Down
9 changes: 9 additions & 0 deletions runtimes/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@ smallvec.workspace = true
# Internal dependencies
attestation.workspace = true
ctype.workspace = true
delegation = {workspace = true, optional = true}
did = {workspace = true, optional = true}
pallet-did-lookup = {workspace = true, optional = true}
pallet-inflation = {workspace = true, optional = true}
kilt-support.workspace = true
parachain-staking.workspace = true
public-credentials.workspace = true
pallet-web3-names.workspace = true

# Substrate dependencies
frame-support.workspace = true
Expand Down Expand Up @@ -97,11 +102,15 @@ std = [
]
try-runtime = [
"attestation/try-runtime",
"delegation",
"did",
"frame-support/try-runtime",
"frame-system/try-runtime",
"kilt-support/try-runtime",
"pallet-authorship/try-runtime",
"pallet-balances/try-runtime",
"pallet-did-lookup",
"pallet-inflation",
"pallet-membership/try-runtime",
"pallet-transaction-payment/try-runtime",
"parachain-staking/try-runtime",
Expand Down
214 changes: 211 additions & 3 deletions runtimes/common/src/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ 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> {
assert_eq!(ctype::Pallet::<T>::on_chain_storage_version(), 0,);
// 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;
Expand All @@ -44,7 +46,7 @@ impl<T: ctype::Config> OnRuntimeUpgrade for AddCTypeBlockNumber<T> {
let onchain = ctype::Pallet::<T>::on_chain_storage_version();

log::info!(
"💰 Running migration with current storage version {:?} / onchain {:?}",
"💰 Running CType migration with current storage version {:?} / onchain {:?}",
current,
onchain
);
Expand All @@ -67,7 +69,7 @@ impl<T: ctype::Config> OnRuntimeUpgrade for AddCTypeBlockNumber<T> {

#[cfg(feature = "try-runtime")]
fn post_upgrade(state: Vec<u8>) -> Result<(), &'static str> {
assert_eq!(ctype::Pallet::<T>::on_chain_storage_version(), 1);
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);
Expand All @@ -81,3 +83,209 @@ impl<T: ctype::Config> OnRuntimeUpgrade for AddCTypeBlockNumber<T> {
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")]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did not find a better way to make the dependencies that are only used with try-runtime optional.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you not make the pre_ and post_ implementation optional?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but you can't import crates only for that. The point of this solution is that the crates for the pallets are imported only when the feature is enabled.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hence the dependency for those can be made optional.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah you are referring to the where clause

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!

impl<R> OnRuntimeUpgrade for MigrateToNewStorageVersion<R>
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,
{
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()
)
}

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()
);
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!("💿 Storage version post checks ok ✅");

Ok(())
}
}

#[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()
}
}
7 changes: 5 additions & 2 deletions runtimes/peregrine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use xcm_executor::XcmExecutor;

use delegation::DelegationAc;
use kilt_support::traits::ItemFilter;
use pallet_did_lookup::{linkable_account::LinkableAccountId, migrations::EthereumMigration};
use pallet_did_lookup::linkable_account::LinkableAccountId;
pub use parachain_staking::InflationInfo;
pub use public_credentials;

Expand Down Expand Up @@ -1067,8 +1067,11 @@ pub type Executive = frame_executive::Executive<
pallet_preimage::migration::v1::Migration<Runtime>,
pallet_scheduler::migration::v3::MigrateToV4<Runtime>,
pallet_democracy::migrations::v1::Migration<Runtime>,
pallet_did_lookup::migrations::EthereumMigration<Runtime>,
runtime_common::migrations::AddCTypeBlockNumber<Runtime>,
EthereumMigration<Runtime>,
// The migration above must be run as last since it checks that all pallets are using the new StorageVersion
// properly.
runtime_common::migrations::MigrateToNewStorageVersion<Runtime>,
),
>;

Expand Down
7 changes: 5 additions & 2 deletions runtimes/spiritnet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use xcm_executor::XcmExecutor;

use delegation::DelegationAc;
use kilt_support::traits::ItemFilter;
use pallet_did_lookup::{linkable_account::LinkableAccountId, migrations::EthereumMigration};
use pallet_did_lookup::linkable_account::LinkableAccountId;
pub use parachain_staking::InflationInfo;
pub use public_credentials;

Expand Down Expand Up @@ -1063,8 +1063,11 @@ pub type Executive = frame_executive::Executive<
pallet_preimage::migration::v1::Migration<Runtime>,
pallet_scheduler::migration::v3::MigrateToV4<Runtime>,
pallet_democracy::migrations::v1::Migration<Runtime>,
pallet_did_lookup::migrations::EthereumMigration<Runtime>,
runtime_common::migrations::AddCTypeBlockNumber<Runtime>,
EthereumMigration<Runtime>,
// The migration above must be run as last since it checks that all pallets are using the new StorageVersion
// properly.
runtime_common::migrations::MigrateToNewStorageVersion<Runtime>,
),
>;

Expand Down