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

Update VersionedMigration to ensure it is not possible to use the unchecked migration #1324

Closed
xlc opened this issue Aug 31, 2023 · 6 comments · Fixed by #3835
Closed

Update VersionedMigration to ensure it is not possible to use the unchecked migration #1324

xlc opened this issue Aug 31, 2023 · 6 comments · Fixed by #3835
Assignees
Labels
C1-mentor A task where a mentor is available. Please indicate in the issue who the mentor could be. D0-easy Can be fixed primarily by duplicating and adapting code by an intermediate coder. I5-enhancement An additional feature request. T1-FRAME This PR/Issue is related to core FRAME, the framework.

Comments

@xlc
Copy link
Contributor

xlc commented Aug 31, 2023

We should have a new UncheckedOnRuntimeUpgrade trait, and have the unchecked migration implements it instead of OnRuntimeUpgrade. In this way, it will not be possible to accidental use the unchecked migration in the actual migration.

@liamaharon liamaharon added C1-mentor A task where a mentor is available. Please indicate in the issue who the mentor could be. T1-FRAME This PR/Issue is related to core FRAME, the framework. labels Aug 31, 2023
@ggwpez ggwpez added D0-easy Can be fixed primarily by duplicating and adapting code by an intermediate coder. I5-enhancement An additional feature request. labels Feb 5, 2024
@dastansam
Copy link
Contributor

hey @ggwpez

can I start working on this?

@ggwpez
Copy link
Member

ggwpez commented Feb 26, 2024

Need to check with @liamaharon first. The idea is to rename+deprecate the current OnRuntimeUpgrade trait and then only advertise the checked version?

@liamaharon
Copy link
Contributor

@xlc do you mind elaborating here, to make sure we're on the same page?

@xlc
Copy link
Contributor Author

xlc commented Feb 27, 2024

/// Migrates `QueueConfigData` from v1 (using only reference time weights) to v2 (with
/// 2D weights).
pub struct UncheckedMigrationToV2<T: Config>(PhantomData<T>);
impl<T: Config> OnRuntimeUpgrade for UncheckedMigrationToV2<T> {
#[allow(deprecated)]
fn on_runtime_upgrade() -> Weight {
let translate = |pre: v1::QueueConfigData| -> v2::QueueConfigData {
v2::QueueConfigData {
suspend_threshold: pre.suspend_threshold,
drop_threshold: pre.drop_threshold,
resume_threshold: pre.resume_threshold,
threshold_weight: Weight::from_parts(pre.threshold_weight, 0),
weight_restrict_decay: Weight::from_parts(pre.weight_restrict_decay, 0),
xcmp_max_individual_weight: Weight::from_parts(
pre.xcmp_max_individual_weight,
DEFAULT_POV_SIZE,
),
}
};
if v2::QueueConfig::<T>::translate(|pre| pre.map(translate)).is_err() {
log::error!(
target: crate::LOG_TARGET,
"unexpected error when performing translation of the QueueConfig type \
during storage upgrade to v2"
);
}
T::DbWeight::get().reads_writes(1, 1)
}
}
/// [`UncheckedMigrationToV2`] wrapped in a
/// [`VersionedMigration`](frame_support::migrations::VersionedMigration), ensuring the
/// migration is only performed when on-chain version is 1.
#[allow(dead_code)]
pub type MigrationToV2<T> = frame_support::migrations::VersionedMigration<
1,
2,
UncheckedMigrationToV2<T>,
Pallet<T>,
<T as frame_system::Config>::DbWeight,
>;

this is an example migration using VersionedMigration

It implements a UncheckedMigrationToV2, which is unsafe. We have to wrap it with VersionedMigration and use it.

However, we can't prevent people from using the UncheckedMigrationToV2.

This is because VersionedMigration takes a type implements OnRuntimeUpgrade, and offers an implementation of OnRuntimeUpgrade.

The solution is add a new trait UncheckedOnRuntimeUpgrade, and make VersionedMigration take it. In that way, the UncheckedMigration does not implement OnRuntimeUpgrade and therefore cannot be accidentally used.

@liamaharon
Copy link
Contributor

Cool thanks @xlc I think this makes sense. So we should leave OnRuntimeUpgrade as-is, but make a breaking change to VersionedMigration so that it takes a struct implementing an identical trait with a different name UncheckedOnRuntimeUpgrade.

@liamaharon
Copy link
Contributor

@dastansam I've assigned you, don't hesitate to drop questions here if you have any.

github-merge-queue bot pushed a commit that referenced this issue Apr 2, 2024
… of `VersionedMigration` (#3835)

closes #1324 

#### Problem
Currently, it is possible to accidentally use inner unversioned
migration instead of `VersionedMigration` since both implement
`OnRuntimeUpgrade`.

#### Solution

With this change, we make it clear that value of `Inner` is not intended
to be used directly. It is achieved by bounding `Inner` to new trait
`UncheckedOnRuntimeUpgrade`, which has the same interface (except
`unchecked_` prefix) as `OnRuntimeUpgrade`.

#### `try-runtime` functions

Since developers can implement `try-runtime` for `Inner` value in
`VersionedMigration` and have custom logic for it, I added the same
`try-runtime` functions to `UncheckedOnRuntimeUpgrade`. I looked for a
ways to not duplicate functions, but couldn't find anything that doesn't
significantly change the codebase. So I would appreciate If you have any
suggestions to improve this

cc @liamaharon @xlc 

polkadot address: 16FqwPZ8GRC5U5D4Fu7W33nA55ZXzXGWHwmbnE1eT6pxuqcT

---------

Co-authored-by: Liam Aharon <[email protected]>
Ank4n pushed a commit that referenced this issue Apr 9, 2024
… of `VersionedMigration` (#3835)

closes #1324 

#### Problem
Currently, it is possible to accidentally use inner unversioned
migration instead of `VersionedMigration` since both implement
`OnRuntimeUpgrade`.

#### Solution

With this change, we make it clear that value of `Inner` is not intended
to be used directly. It is achieved by bounding `Inner` to new trait
`UncheckedOnRuntimeUpgrade`, which has the same interface (except
`unchecked_` prefix) as `OnRuntimeUpgrade`.

#### `try-runtime` functions

Since developers can implement `try-runtime` for `Inner` value in
`VersionedMigration` and have custom logic for it, I added the same
`try-runtime` functions to `UncheckedOnRuntimeUpgrade`. I looked for a
ways to not duplicate functions, but couldn't find anything that doesn't
significantly change the codebase. So I would appreciate If you have any
suggestions to improve this

cc @liamaharon @xlc 

polkadot address: 16FqwPZ8GRC5U5D4Fu7W33nA55ZXzXGWHwmbnE1eT6pxuqcT

---------

Co-authored-by: Liam Aharon <[email protected]>
dharjeezy pushed a commit to dharjeezy/polkadot-sdk that referenced this issue Apr 9, 2024
… of `VersionedMigration` (paritytech#3835)

closes paritytech#1324 

#### Problem
Currently, it is possible to accidentally use inner unversioned
migration instead of `VersionedMigration` since both implement
`OnRuntimeUpgrade`.

#### Solution

With this change, we make it clear that value of `Inner` is not intended
to be used directly. It is achieved by bounding `Inner` to new trait
`UncheckedOnRuntimeUpgrade`, which has the same interface (except
`unchecked_` prefix) as `OnRuntimeUpgrade`.

#### `try-runtime` functions

Since developers can implement `try-runtime` for `Inner` value in
`VersionedMigration` and have custom logic for it, I added the same
`try-runtime` functions to `UncheckedOnRuntimeUpgrade`. I looked for a
ways to not duplicate functions, but couldn't find anything that doesn't
significantly change the codebase. So I would appreciate If you have any
suggestions to improve this

cc @liamaharon @xlc 

polkadot address: 16FqwPZ8GRC5U5D4Fu7W33nA55ZXzXGWHwmbnE1eT6pxuqcT

---------

Co-authored-by: Liam Aharon <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C1-mentor A task where a mentor is available. Please indicate in the issue who the mentor could be. D0-easy Can be fixed primarily by duplicating and adapting code by an intermediate coder. I5-enhancement An additional feature request. T1-FRAME This PR/Issue is related to core FRAME, the framework.
Projects
None yet
4 participants