-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Versioned OnRuntimeUpgrade
#13107
Comments
This looks interesting @ggwpez. Can you provide an example of how the associated types or const generics would be used in practice to determine whether a migration should run or be deleted? |
I would like to wait for @kianenigma to tell us his thought about this. |
Yeah, this is very much like what I had in mind. a |
Interesting, this was the solution I had in mind based on what @kianenigma proposed.
migration implementation.
if |
@ECJ222 I am not sure if i correctly understood your example code. |
pub struct AutoMigrate<From, To, Inner, Pallet>(
sp_std::marker::PhantomData<(From, To, Inner, Pallet)>,
);
impl<
From: Get<StorageVersion>,
To: Get<StorageVersion>,
Inner: OnRuntimeUpgrade,
Pallet: GetStorageVersion + PalletInfoAccess,
> OnRuntimeUpgrade for AutoMigrate<From, To, Inner, Pallet>
{
fn on_runtime_upgrade() -> Weight {
let current = Pallet::current_storage_version();
let on_chain = Pallet::on_chain_storage_version();
if current == To::get() && on_chain == From::get() {
let weight = Inner::on_runtime_upgrade();
current.put::<Pallet>();
log!(info, "{:?} applied successfully.", To::get());
weight
} else {
log!(warn, "{:?} not applied.", To::get());
todo!("need to get DbWeight somehow as well..");
}
}
} Here's how I would do this. |
This logic is wrong. Especially if you may need to put multiple migrations in one runtime upgrade.
That is correct. |
OnRuntimeUpgrade
OnRuntimeUpgrade
Okay, here's a new thought about this, as discussed in DM with @ggwpez when discussing 298dacd. A typical runtime migration looks like this: // assuming you have set `#[pallet::storage_verson(2)]`
fn on_runtime_upgrade() -> Weight {
let current = Pallet::<T>::current_storage_version();
let onchain = Pallet::<T>::on_chain_storage_version();
if current == 2 && onchain == 1 {
// do stuff.
current.put::<Pallet<T>>();
} else {
log!(info, "Migration did not executed. This probably should be removed");
}
} Using this First, I would remove Each If this is If this is Moreover, once we have this, Executive can actually have a more educated approach towards executing them. All migrations are coming from the runtime. This will bring:
|
I'm planning to start on this soon, after I wrap up my current main work effort (lazy-download). |
Let's look at this issue when working on this |
The only issue I can think of with removing this is that we would not know what initial on-chain version to set for a pallet when it's introduced to the runtime, blocking us from fixing paritytech/polkadot-sdk#109. You're correct though that we shouldn't need it in any migrations.
Cool. I like the idea of the executive pallet managing this, so we don't need to think about versions at all inside the |
To what version are you then setting the storage version in the genesis state? I'm with you that we should probably remove the |
That was also my initial thought. However, if we tightly couple at least the most recent migration to the pallet, we could initialise the on-chain version based on the latest migrations I'm still unsure if we should do it, but it's something to consider. |
We currently have the pattern of first manually checking whether a migration should run or can be deleted.
Then setting the version and in the
post_upgrade
we check that it was set. This is error prone and redundant.We could improve here by using either associated types/consts or const generics to track the required version directly in the trait.
Both being options for the case that there is (and should) be no version.
To keep it backwards compatible we should probably create a new or wrapper trait.
The text was updated successfully, but these errors were encountered: