This repository was archived by the owner on Nov 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
RemovePallet
migration tool
#6977
Closed
Closed
Changes from all commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
eb49fda
try_kill_gov_v1_storage test poc
liamaharon 5ab6c31
log key counts and clear keys
liamaharon f95ab4b
move count_keys into remote_tests
liamaharon a1702ee
remove code duplication
liamaharon cefdab5
improve comment
liamaharon a812fa6
cleanup syntax
liamaharon b6ef384
typo
liamaharon 10654e2
migrate removal functionality from test to onruntimeupgrade
liamaharon 359d8eb
fix formatting
liamaharon cb0dbc9
Merge branch 'master' of github.com:paritytech/polkadot into liam-rem…
liamaharon b1864d6
formatting
liamaharon 53a0316
improve error log
liamaharon 212e6a1
use struct const syntax
liamaharon 69feee0
refactor to generic RemovePallet
liamaharon 49865f8
count initial prefix read in weight
liamaharon 28b499c
improve comment
liamaharon abc6c93
add licence and docs
liamaharon cd46283
revert redundant change
liamaharon 4069109
typo
liamaharon b2044f1
Merge branch 'master' of github.com:paritytech/polkadot into liam-rem…
liamaharon e5934b2
use helper storage methods
liamaharon ba87f37
remove tips storage
liamaharon a3f3b31
Merge branch 'master' of github.com:paritytech/polkadot into liam-rem…
liamaharon c0081eb
usage docs
liamaharon f181f1c
make parameter types consts
liamaharon 9d0ce58
move docs to struct
liamaharon afa82e9
Update runtime/common/src/remove_pallet.rs
liamaharon e477c92
add error log if clear_prefix returns unexpected result
liamaharon 0bf4140
Merge branch 'liam-remove-kusama-gov-v1-storage' of github.com:parity…
liamaharon fc37d00
return error from post_upgrade in case of failure
liamaharon a0fbaa7
typo
liamaharon dd6cab9
improve outer comment
liamaharon 7766cb1
Update runtime/common/src/remove_pallet.rs
liamaharon 39ce205
Merge branch 'liam-remove-kusama-gov-v1-storage' of github.com:parity…
liamaharon f935984
Update runtime/common/src/remove_pallet.rs
liamaharon e0632be
Update runtime/common/src/remove_pallet.rs
liamaharon fb39cbe
Merge branch 'master' of github.com:paritytech/polkadot into liam-rem…
liamaharon 299ce74
remove kusama gov v1 storage deletion
liamaharon 21baa56
fix universal alias function signature
liamaharon 29848c7
generic DbWeight
liamaharon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
// Copyright 2017-2023 Parity Technologies (UK) Ltd. | ||
// This file is part of Polkadot. | ||
|
||
// Polkadot is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
|
||
// Polkadot is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
|
||
// You should have received a copy of the GNU General Public License | ||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
//! Contains `RemovePallet`, a tool for deleting all storage items of a given pallet. | ||
//! | ||
//! This can be useful for cleaning up the storage of a pallet which has been removed from the | ||
//! runtime. | ||
#[cfg(feature = "try-runtime")] | ||
use frame_support::storage::unhashed::contains_prefixed_key; | ||
use frame_support::weights::RuntimeDbWeight; | ||
use sp_core::Get; | ||
use sp_io::{hashing::twox_128, storage::clear_prefix, KillStorageResult}; | ||
use sp_std::marker::PhantomData; | ||
#[cfg(feature = "try-runtime")] | ||
use sp_std::vec::Vec; | ||
|
||
/// `RemovePallet` is a utility struct used to remove all storage items associated with a specific | ||
/// pallet. | ||
/// | ||
/// This struct is generic over two parameters: | ||
/// - `P` is a type that implements the `Get` trait for a static string, representing the pallet's name. | ||
/// - `DbWeight` is a type that implements the `Get` trait for `RuntimeDbWeight`, providing the weight | ||
/// for database operations. | ||
/// | ||
/// On runtime upgrade, the `on_runtime_upgrade` function will clear all storage items associated with | ||
/// the specified pallet, logging the number of keys removed. If the `try-runtime` feature is enabled, | ||
/// the `pre_upgrade` and `post_upgrade` functions can be used to verify the storage removal before and | ||
/// after the upgrade. | ||
/// | ||
/// # Examples: | ||
/// ```ignore | ||
/// construct_runtime! { | ||
/// pub enum Runtime where | ||
/// Block = Block, | ||
/// NodeBlock = primitives::Block, | ||
/// UncheckedExtrinsic = UncheckedExtrinsic | ||
/// { | ||
/// System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 0, | ||
/// | ||
/// SomePalletToRemove: pallet_something::{Pallet, Call, Storage, Event<T>} = 1, | ||
/// AnotherPalletToRemove: pallet_something_else::{Pallet, Call, Storage, Event<T>} = 2, | ||
/// | ||
/// YourOtherPallets... | ||
/// } | ||
/// }; | ||
/// | ||
/// parameter_types! { | ||
/// pub const SomePalletToRemoveStr: &'static str = "SomePalletToRemove"; | ||
/// pub const AnotherPalletToRemoveStr: &'static str = "AnotherPalletToRemove"; | ||
/// } | ||
/// | ||
/// pub type Migrations = ( | ||
/// RemovePallet<SomePalletToRemoveStr, RocksDbWeight>, | ||
/// RemovePallet<AnotherPalletToRemoveStr, RocksDbWeight>, | ||
/// AnyOtherMigrations... | ||
/// ); | ||
/// | ||
/// pub type Executive = frame_executive::Executive< | ||
/// Runtime, | ||
/// Block, | ||
/// frame_system::ChainContext<Runtime>, | ||
/// Runtime, | ||
/// Migrations | ||
/// >; | ||
/// ``` | ||
/// | ||
/// WARNING: `RemovePallet` has no guard rails preventing it from bricking the chain if the | ||
/// operation of removing storage for the given pallet would exceed the block weight limit. | ||
/// | ||
/// If your pallet has too many keys to be removed in a single block, it is advised to wait for | ||
/// a multi-block scheduler currently under development which will allow for removal of storage | ||
/// items (and performing other heavy migrations) over multiple blocks. | ||
/// (https://github.com/paritytech/substrate/issues/13690) | ||
pub struct RemovePallet<P: Get<&'static str>, DbWeight: Get<RuntimeDbWeight>>( | ||
PhantomData<(P, DbWeight)>, | ||
); | ||
impl<P: Get<&'static str>, DbWeight: Get<RuntimeDbWeight>> frame_support::traits::OnRuntimeUpgrade | ||
for RemovePallet<P, DbWeight> | ||
{ | ||
fn on_runtime_upgrade() -> frame_support::weights::Weight { | ||
let hashed_prefix = twox_128(P::get().as_bytes()); | ||
let keys_removed = match clear_prefix(&hashed_prefix, None) { | ||
KillStorageResult::AllRemoved(value) => value, | ||
KillStorageResult::SomeRemaining(value) => { | ||
log::error!( | ||
"`clear_prefix` failed to remove all keys for {}. THIS SHOULD NEVER HAPPEN! 🚨", | ||
P::get() | ||
); | ||
value | ||
}, | ||
} as u64; | ||
|
||
log::info!("Removed {} {} keys 🧹", keys_removed, P::get()); | ||
|
||
DbWeight::get().reads_writes(keys_removed + 1, keys_removed) | ||
} | ||
|
||
#[cfg(feature = "try-runtime")] | ||
fn pre_upgrade() -> Result<Vec<u8>, &'static str> { | ||
let hashed_prefix = twox_128(P::get().as_bytes()); | ||
match contains_prefixed_key(&hashed_prefix) { | ||
true => log::info!("Found {} keys pre-removal 👀", P::get()), | ||
false => log::warn!( | ||
"Migration RemovePallet<{}> can be removed (no keys found pre-removal).", | ||
P::get() | ||
), | ||
}; | ||
Ok(Vec::new()) | ||
} | ||
|
||
#[cfg(feature = "try-runtime")] | ||
fn post_upgrade(_state: Vec<u8>) -> Result<(), &'static str> { | ||
let hashed_prefix = twox_128(P::get().as_bytes()); | ||
match contains_prefixed_key(&hashed_prefix) { | ||
true => { | ||
log::error!("{} has keys remaining post-removal ❗", P::get()); | ||
return Err("Keys remaining post-removal, this should never happen 🚨") | ||
}, | ||
false => log::info!("No {} keys found post-removal 🎉", P::get()), | ||
liamaharon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}; | ||
Ok(()) | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also move it to Substrate… 🤷♂️
Not sure if it is worth it right now though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ggwpez good point, I think we may as well do it now if it would need to happen later anyway.
Is there an existing package in substrate you think this would fit well into?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably
frame-support
.