Repository: paritytech/substrate
File: frame/support/src/migrations.rs (Rust)

Code before:
/// 	VersionedRuntimeUpgrade<
/// 		4, // From on-chain version 4
/// 		5, // To on-chain version 5
/// 		parachains_configuration::migration::v5::MigrateToV5<Runtime>,
/// 		Configuration,
/// 		RocksDbWeight,
/// 	>,
/// 	VersionedRuntimeUpgrade<
/// 		5, // From on-chain version 5
/// 		7, // To on-chain version 7
/// 		parachains_configuration::migration::v6::MigrateToV6<Runtime>,
/// 		Configuration,
/// 		RocksDbWeight,
/// 	>,
/// 	// ...other migrations
/// );
/// ```
#[cfg(feature = "experimental")]
pub struct VersionedRuntimeUpgrade<const FROM: u16, const TO: u16, Inner, Pallet, Weight> {
	_marker: PhantomData<(Inner, Pallet, Weight)>,
}

/// Implementation of the `OnRuntimeUpgrade` trait for `VersionedRuntimeUpgrade`.
///
/// 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-chian storage to
/// `To`. If the versions do not match, it writes a log notifying the developer that the migration
/// is a noop.
#[cfg(feature = "experimental")]
impl<
		const FROM: u16,
		const TO: u16,
		Inner: OnRuntimeUpgrade,
		Pallet: GetStorageVersion<CurrentStorageVersion = StorageVersion> + PalletInfoAccess,
		DbWeight: Get<RuntimeDbWeight>,
	> OnRuntimeUpgrade for VersionedRuntimeUpgrade<FROM, TO, Inner, Pallet, DbWeight>
{
	/// Executes pre_upgrade if the migration will run, and wraps the pre_upgrade bytes in an Option
	/// before passing them to post_upgrade, so it knows whether the migration ran or not.
	#[cfg(feature = "try-runtime")]
	fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
		use codec::Encode;
		let on_chain_version = Pallet::on_chain_storage_version();
		if on_chain_version == FROM {
			Ok(Some(Inner::pre_upgrade()?).encode())
		} else {
			Ok(None::<Vec<u8>>.encode())
		}
	}

	/// Executes the versioned runtime upgrade.

Review comment (suggestion):
```suggestion
/// version of the pallets storage matches `From`, and after the upgrade set the on-chain storage to
```

Code after:
/// 	// OnRuntimeUpgrade implementation...
/// }
///
/// pub type VersionCheckedMigrateV5ToV6<Runtime, Pallet, DbWeight> =
/// 	VersionedRuntimeUpgrade<5, 6, VersionUncheckedMigrateV5ToV6<Runtime>, Pallet, DbWeight>;
///
/// // Migrations tuple to pass to the Executive pallet:
/// pub type Migrations = (
/// 	// other migrations...
/// 	VersionCheckedMigrateV5ToV6<Runtime, Balances, RuntimeDbWeight>,
/// 	// other migrations...
/// );
/// ```
#[cfg(feature = "experimental")]
pub struct VersionedRuntimeUpgrade<const FROM: u16, const TO: u16, Inner, Pallet, Weight> {
	_marker: PhantomData<(Inner, Pallet, Weight)>,
}

/// A helper enum to wrap the pre_upgrade bytes like an Option before passing them to post_upgrade.
/// This enum is used rather than an Option to make the API clearer to the developer.
#[cfg(feature = "experimental")]
#[derive(codec::Encode, codec::Decode)]
pub enum VersionedPostUpgradeData {
	/// The migration ran, inner vec contains pre_upgrade data.
	MigrationExecuted(Vec<u8>),
	/// This migration is a noop, do not run post_upgrade checks.
	Noop,
}

/// Implementation of the `OnRuntimeUpgrade` trait for `VersionedRuntimeUpgrade`.
///
/// 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.
#[cfg(feature = "experimental")]
impl<
		const FROM: u16,
		const TO: u16,
		Inner: OnRuntimeUpgrade,
		Pallet: GetStorageVersion<CurrentStorageVersion = StorageVersion> + PalletInfoAccess,
		DbWeight: Get<RuntimeDbWeight>,
	> OnRuntimeUpgrade for VersionedRuntimeUpgrade<FROM, TO, Inner, Pallet, DbWeight>
{
	/// 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.
	#[cfg(feature = "try-runtime")]
	fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
		use codec::Encode;
		let on_chain_version = Pallet::on_chain_storage_version();