Runtime Upgrade ref docs and Single Block Migration example pallet (#1554)

Closes https://github.com/paritytech/polkadot-sdk-docs/issues/55

- Changes 'current storage version' terminology to less ambiguous
'in-code storage version' (suggestion by @ggwpez)
- Adds a new example pallet `pallet-example-single-block-migrations`
- Adds a new reference doc to replace
https://docs.substrate.io/maintain/runtime-upgrades/ (temporarily living
in the pallet while we wait for developer hub PR to merge)
- Adds documentation for the `storage_alias` macro
- Improves `trait Hooks` docs 
- Improves `trait GetStorageVersion` docs
- Update the suggested patterns for using `VersionedMigration`, so that
version unchecked migrations are never exported
- Prevents accidental usage of version unchecked migrations in runtimes

https://github.com/paritytech/substrate/pull/14421#discussion_r1255467895
- Unversioned migration code is kept inside `mod version_unchecked`,
versioned code is kept in `pub mod versioned`
- It is necessary to use modules to limit visibility because the inner
migration must be `pub`. See
https://github.com/rust-lang/rust/issues/30905 and

https://internals.rust-lang.org/t/lang-team-minutes-private-in-public-rules/4504/40
for more.

### todo

- [x] move to reference docs to proper place within sdk-docs (now that
https://github.com/paritytech/polkadot-sdk/pull/2102 is merged)
- [x] prdoc

---------

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Juan <juangirini@gmail.com>
Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Co-authored-by: command-bot <>
Co-authored-by: gupnik <nikhilgupta.iitk@gmail.com>
This commit is contained in:
Liam Aharon
2024-02-28 18:32:02 +11:00
committed by GitHub
parent 7ec0b8741b
commit 12ce4f7d04
87 changed files with 1222 additions and 369 deletions
+20 -20
View File
@@ -34,7 +34,7 @@ use sp_runtime::TryRuntimeError;
use sp_runtime::{traits::Zero, FixedPointNumber, FixedU128, Saturating};
use sp_std::prelude::*;
mod old {
mod v11 {
use super::*;
pub type BalanceOf<T, OldCurrency> = <OldCurrency as frame_support::traits::Currency<
@@ -87,7 +87,7 @@ where
{
owner: AccountIdOf<T>,
#[codec(compact)]
deposit: old::BalanceOf<T, OldCurrency>,
deposit: v11::BalanceOf<T, OldCurrency>,
#[codec(compact)]
refcount: u64,
determinism: Determinism,
@@ -112,17 +112,17 @@ where
let hash = T::Hashing::hash(&code);
PristineCode::<T>::insert(hash, code.clone());
let module = old::PrefabWasmModule {
let module = v11::PrefabWasmModule {
instruction_weights_version: Default::default(),
initial: Default::default(),
maximum: Default::default(),
code,
determinism: Determinism::Enforced,
};
old::CodeStorage::<T>::insert(hash, module);
v11::CodeStorage::<T>::insert(hash, module);
let info = old::OwnerInfo { owner: account, deposit: u32::MAX.into(), refcount: u64::MAX };
old::OwnerInfoOf::<T, OldCurrency>::insert(hash, info);
let info = v11::OwnerInfo { owner: account, deposit: u32::MAX.into(), refcount: u64::MAX };
v11::OwnerInfoOf::<T, OldCurrency>::insert(hash, info);
}
#[derive(Encode, Decode, MaxEncodedLen, DefaultNoBound)]
@@ -148,16 +148,16 @@ where
fn step(&mut self) -> (IsFinished, Weight) {
let mut iter = if let Some(last_key) = self.last_code_hash.take() {
old::OwnerInfoOf::<T, OldCurrency>::iter_from(
old::OwnerInfoOf::<T, OldCurrency>::hashed_key_for(last_key),
v11::OwnerInfoOf::<T, OldCurrency>::iter_from(
v11::OwnerInfoOf::<T, OldCurrency>::hashed_key_for(last_key),
)
} else {
old::OwnerInfoOf::<T, OldCurrency>::iter()
v11::OwnerInfoOf::<T, OldCurrency>::iter()
};
if let Some((hash, old_info)) = iter.next() {
log::debug!(target: LOG_TARGET, "Migrating OwnerInfo for code_hash {:?}", hash);
let module = old::CodeStorage::<T>::take(hash)
let module = v11::CodeStorage::<T>::take(hash)
.expect(format!("No PrefabWasmModule found for code_hash: {:?}", hash).as_str());
let code_len = module.code.len();
@@ -184,7 +184,7 @@ where
let bytes_before = module
.encoded_size()
.saturating_add(code_len)
.saturating_add(old::OwnerInfo::<T, OldCurrency>::max_encoded_len())
.saturating_add(v11::OwnerInfo::<T, OldCurrency>::max_encoded_len())
as u32;
let items_before = 3u32;
let deposit_expected_before = price_per_byte
@@ -241,10 +241,10 @@ where
fn pre_upgrade_step() -> Result<Vec<u8>, TryRuntimeError> {
let len = 100;
log::debug!(target: LOG_TARGET, "Taking sample of {} OwnerInfo(s)", len);
let sample: Vec<_> = old::OwnerInfoOf::<T, OldCurrency>::iter()
let sample: Vec<_> = v11::OwnerInfoOf::<T, OldCurrency>::iter()
.take(len)
.map(|(k, v)| {
let module = old::CodeStorage::<T>::get(k)
let module = v11::CodeStorage::<T>::get(k)
.expect("No PrefabWasmModule found for code_hash: {:?}");
let info: CodeInfo<T, OldCurrency> = CodeInfo {
determinism: module.determinism,
@@ -258,9 +258,9 @@ where
.collect();
let storage: u32 =
old::CodeStorage::<T>::iter().map(|(_k, v)| v.encoded_size() as u32).sum();
let mut deposit: old::BalanceOf<T, OldCurrency> = Default::default();
old::OwnerInfoOf::<T, OldCurrency>::iter().for_each(|(_k, v)| deposit += v.deposit);
v11::CodeStorage::<T>::iter().map(|(_k, v)| v.encoded_size() as u32).sum();
let mut deposit: v11::BalanceOf<T, OldCurrency> = Default::default();
v11::OwnerInfoOf::<T, OldCurrency>::iter().for_each(|(_k, v)| deposit += v.deposit);
Ok((sample, deposit, storage).encode())
}
@@ -269,7 +269,7 @@ where
fn post_upgrade_step(state: Vec<u8>) -> Result<(), TryRuntimeError> {
let state = <(
Vec<(CodeHash<T>, CodeInfo<T, OldCurrency>)>,
old::BalanceOf<T, OldCurrency>,
v11::BalanceOf<T, OldCurrency>,
u32,
) as Decode>::decode(&mut &state[..])
.unwrap();
@@ -283,7 +283,7 @@ where
ensure!(info.refcount == old.refcount, "invalid refcount");
}
if let Some((k, _)) = old::CodeStorage::<T>::iter().next() {
if let Some((k, _)) = v11::CodeStorage::<T>::iter().next() {
log::warn!(
target: LOG_TARGET,
"CodeStorage is still NOT empty, found code_hash: {:?}",
@@ -292,7 +292,7 @@ where
} else {
log::debug!(target: LOG_TARGET, "CodeStorage is empty.");
}
if let Some((k, _)) = old::OwnerInfoOf::<T, OldCurrency>::iter().next() {
if let Some((k, _)) = v11::OwnerInfoOf::<T, OldCurrency>::iter().next() {
log::warn!(
target: LOG_TARGET,
"OwnerInfoOf is still NOT empty, found code_hash: {:?}",
@@ -302,7 +302,7 @@ where
log::debug!(target: LOG_TARGET, "OwnerInfoOf is empty.");
}
let mut deposit: old::BalanceOf<T, OldCurrency> = Default::default();
let mut deposit: v11::BalanceOf<T, OldCurrency> = Default::default();
let mut items = 0u32;
let mut storage_info = 0u32;
CodeInfoOf::<T, OldCurrency>::iter().for_each(|(_k, v)| {