Struct frame_support::migrations::VersionedMigration
source · pub struct VersionedMigration<const FROM: u16, const TO: u16, Inner, Pallet, Weight> { /* private fields */ }
Expand description
Handles storage migration pallet versioning.
VersionedMigration
allows developers to write migrations without worrying about checking and
setting storage versions. Instead, the developer wraps their migration in this struct which
takes care of version handling using best practices.
It takes 5 type parameters:
From
: The version being upgraded from.To
: The version being upgraded to.Inner
: An implementation ofUncheckedOnRuntimeUpgrade
.Pallet
: The Pallet being upgraded.Weight
: The runtime’s RuntimeDbWeight implementation.
When a VersionedMigration
on_runtime_upgrade
, pre_upgrade
, or post_upgrade
method is
called, the on-chain version of the pallet is compared to From
. If they match, the Inner
UncheckedOnRuntimeUpgrade
is called and the pallets on-chain version is set to To
after the migration. Otherwise, a warning is logged notifying the developer that the upgrade was
a noop and should probably be removed.
By not bounding Inner
with OnRuntimeUpgrade
, we prevent developers from
accidentally using the unchecked version of the migration in a runtime upgrade instead of
VersionedMigration
.
§Examples
// In file defining migrations
/// Private module containing *version unchecked* migration logic.
///
/// Should only be used by the [`VersionedMigration`] type in this module to create something to
/// export.
///
/// We keep this private so the unversioned migration cannot accidentally be used in any runtimes.
///
/// For more about this pattern of keeping items private, see
/// - https://github.com/rust-lang/rust/issues/30905
/// - https://internals.rust-lang.org/t/lang-team-minutes-private-in-public-rules/4504/40
mod version_unchecked {
use super::*;
pub struct VersionUncheckedMigrateV5ToV6<T>(core::marker::PhantomData<T>);
impl<T: Config> UncheckedOnRuntimeUpgrade for VersionUncheckedMigrateV5ToV6<T> {
// `UncheckedOnRuntimeUpgrade` implementation...
}
}
pub type MigrateV5ToV6<T, I> =
VersionedMigration<
5,
6,
VersionUncheckedMigrateV5ToV6<T, I>,
crate::pallet::Pallet<T, I>,
<T as frame_system::Config>::DbWeight
>;
// Migrations tuple to pass to the Executive pallet:
pub type Migrations = (
// other migrations...
MigrateV5ToV6<T, ()>,
// other migrations...
);
Trait Implementations§
source§impl<const FROM: u16, const TO: u16, Inner: UncheckedOnRuntimeUpgrade, Pallet: GetStorageVersion<InCodeStorageVersion = StorageVersion> + PalletInfoAccess, DbWeight: Get<RuntimeDbWeight>> OnRuntimeUpgrade for VersionedMigration<FROM, TO, Inner, Pallet, DbWeight>
impl<const FROM: u16, const TO: u16, Inner: UncheckedOnRuntimeUpgrade, Pallet: GetStorageVersion<InCodeStorageVersion = StorageVersion> + PalletInfoAccess, DbWeight: Get<RuntimeDbWeight>> OnRuntimeUpgrade for VersionedMigration<FROM, TO, Inner, Pallet, DbWeight>
Implementation of the OnRuntimeUpgrade
trait for VersionedMigration
.
Its main function is to perform the runtime upgrade in on_runtime_upgrade
only if the on-chain
version of the pallets storage matches From
, and after the upgrade set the on-chain storage to
To
. If the versions do not match, it writes a log notifying the developer that the migration
is a noop.
source§fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError>
fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError>
Executes pre_upgrade if the migration will run, and wraps the pre_upgrade bytes in
VersionedPostUpgradeData
before passing them to post_upgrade, so it knows whether the
migration ran or not.
source§fn on_runtime_upgrade() -> Weight
fn on_runtime_upgrade() -> Weight
Executes the versioned runtime upgrade.
First checks if the pallets on-chain storage version matches the version of this upgrade. If
it matches, it calls Inner::on_runtime_upgrade
, updates the on-chain version, and returns
the weight. If it does not match, it writes a log notifying the developer that the migration
is a noop.
source§fn post_upgrade(
versioned_post_upgrade_data_bytes: Vec<u8>,
) -> Result<(), TryRuntimeError>
fn post_upgrade( versioned_post_upgrade_data_bytes: Vec<u8>, ) -> Result<(), TryRuntimeError>
Executes Inner::post_upgrade
if the migration just ran.
pre_upgrade passes VersionedPostUpgradeData::MigrationExecuted
to post_upgrade if
the migration ran, and VersionedPostUpgradeData::Noop
otherwise.
source§fn try_on_runtime_upgrade(checks: bool) -> Result<Weight, TryRuntimeError>
fn try_on_runtime_upgrade(checks: bool) -> Result<Weight, TryRuntimeError>
pre_upgrade
->
on_runtime_upgrade
-> post_upgrade
hooks for a migration. Read moreAuto Trait Implementations§
impl<const FROM: u16, const TO: u16, Inner, Pallet, Weight> Freeze for VersionedMigration<FROM, TO, Inner, Pallet, Weight>
impl<const FROM: u16, const TO: u16, Inner, Pallet, Weight> RefUnwindSafe for VersionedMigration<FROM, TO, Inner, Pallet, Weight>
impl<const FROM: u16, const TO: u16, Inner, Pallet, Weight> Send for VersionedMigration<FROM, TO, Inner, Pallet, Weight>
impl<const FROM: u16, const TO: u16, Inner, Pallet, Weight> Sync for VersionedMigration<FROM, TO, Inner, Pallet, Weight>
impl<const FROM: u16, const TO: u16, Inner, Pallet, Weight> Unpin for VersionedMigration<FROM, TO, Inner, Pallet, Weight>
impl<const FROM: u16, const TO: u16, Inner, Pallet, Weight> UnwindSafe for VersionedMigration<FROM, TO, Inner, Pallet, Weight>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CheckedConversion for T
impl<T> CheckedConversion for T
source§impl<T> FmtForward for T
impl<T> FmtForward for T
source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§impl<T, Outer> IsWrappedBy<Outer> for T
impl<T, Outer> IsWrappedBy<Outer> for T
source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moresource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moresource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.source§impl<T> Pointable for T
impl<T> Pointable for T
source§impl<T> SaturatedConversion for T
impl<T> SaturatedConversion for T
source§fn saturated_from<T>(t: T) -> Selfwhere
Self: UniqueSaturatedFrom<T>,
fn saturated_from<T>(t: T) -> Selfwhere
Self: UniqueSaturatedFrom<T>,
source§fn saturated_into<T>(self) -> Twhere
Self: UniqueSaturatedInto<T>,
fn saturated_into<T>(self) -> Twhere
Self: UniqueSaturatedInto<T>,
T
. Read moresource§impl<T> Tap for T
impl<T> Tap for T
source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read moresource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read moresource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read moresource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read moresource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read moresource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read moresource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.source§impl<T, U> TryIntoKey<U> for Twhere
U: TryFromKey<T>,
impl<T, U> TryIntoKey<U> for Twhere
U: TryFromKey<T>,
type Error = <U as TryFromKey<T>>::Error
fn try_into_key(self) -> Result<U, <U as TryFromKey<T>>::Error>
source§impl<S, T> UncheckedInto<T> for Swhere
T: UncheckedFrom<S>,
impl<S, T> UncheckedInto<T> for Swhere
T: UncheckedFrom<S>,
source§fn unchecked_into(self) -> T
fn unchecked_into(self) -> T
unchecked_from
.source§impl<T, S> UniqueSaturatedInto<T> for S
impl<T, S> UniqueSaturatedInto<T> for S
source§fn unique_saturated_into(self) -> T
fn unique_saturated_into(self) -> T
T
.