Updating parachain with migrations
Tags: substrate, polkadot, runtimeupgrade, parachain
Published: 2023-05-30 11:44:20

How to look and add migrations while upgrading parachain to new version via runtime upgrade.

We use example of simple [parachain node template] (https://github.com/substrate-developer-hub/substrate-parachain-template/) with tag `polkadot-v0.9.32` and upgrade it to `polkadot-v0.9.40`. 
To test this upgrade we need local testnet. How to create simple testnet [short guide here](https://dev.to/nikania/quick-list-starting-local-parachain-testnet-3ncg).

## Build `polkadot-v0.9.32` parachain-template version
First, we add some pallets that changed between these two versions to parachain-template:
`pallet-alliance` and `pallet_assets`.
Then, we build and place parachain in `/bin` folder 
```bash
cargo build --release
mkdir bin
cp ./target/release/parachain-template-node \
    ./bin/parachain-template-node-v0.9.32
```
##Prepare for runtime upgrade
(official guide [here](https://docs.substrate.io/maintain/runtime-upgrades/))
a) change versions `polkadot-v0.9.32` to `polkadot-v0.9.40` in Cargo.toml
b) fix compile errors🤯
a1)-b1) it's faster to use `polkadot-v0.9.40` parachain-template version instead upgrading in this example😎
c) change spec_version
###d) add migrations
_this was the most unclear_ to me (do I need to apply them? where to find migrations? how to apply them?), but I'll show you **how to add substrate migrations** (not your own):

- look through the [releases](https://github.com/paritytech/polkadot/releases) in Polkadot repo and search for migrations description, here I found migrations in 
[v0.9.34 release](https://github.com/paritytech/polkadot/releases/tag/v0.9.34),
[v0.9.38 release](https://github.com/paritytech/polkadot/releases/tag/v0.9.38),
[v0.9.40 release](https://github.com/paritytech/polkadot/releases/tag/v0.9.40)
- download the source code and look for migrations in `runtime/polkadot/src/lib.rs` in struct `frame_executive::Executive`, migrations can be summed in type `Migrations` or just put there, 
here I found the following migrations:
```rust
// in v0.9.34
pub type Migrations = (
	//9320
	// "Bound uses of call" <https://github.com/paritytech/polkadot/pull/5729>
	pallet_preimage::migration::v1::Migration<Runtime>,
	pallet_scheduler::migration::v3::MigrateToV4<Runtime>,
	pallet_democracy::migrations::v1::Migration<Runtime>,
	pallet_multisig::migrations::v1::MigrateToV1<Runtime>,
	// "Properly migrate weights to v2" <https://github.com/paritytech/polkadot/pull/6091>
	parachains_configuration::migration::v3::MigrateToV3<Runtime>,
	//9330
	pallet_election_provider_multi_phase::migrations::v1::MigrateToV1<Runtime>,
	pallet_fast_unstake::migrations::v1::MigrateToV1<Runtime>,
	//9340
	pallet_balances::migration::MigrateToTrackInactive<Runtime, xcm_config::CheckAccount>,
	crowdloan::migration::MigrateToTrackInactive<Runtime>,
);
```
```rust
// in v.0.9.38
pub type Migrations = (
	// "Use 2D weights in XCM v3" <https://github.com/paritytech/polkadot/pull/6134>
	pallet_xcm::migration::v1::MigrateToV1<Runtime>,
	parachains_ump::migration::v1::MigrateToV1<Runtime>,
	// Remove stale entries in the set id -> session index storage map (after
	// this release they will be properly pruned after the bonding duration has
	// elapsed)
	pallet_grandpa::migrations::CleanupSetIdSessionMap<Runtime>,
);
```
```rust
// in v0.9.40
pub type Migrations = (
	pallet_nomination_pools::migration::v4::MigrateToV4<
		Runtime,
		NominationPoolsMigrationV4OldPallet,
	>,
);
```
- also look for migrations in Cumulus repo, here I found [v9360](https://github.com/paritytech/cumulus/releases/tag/parachains-v9360) [v9330](https://github.com/paritytech/cumulus/releases/tag/parachains-v9330) [v9380](https://github.com/paritytech/cumulus/releases/tag/parachains-v9380) [v9400] (https://github.com/paritytech/cumulus/releases/tag/parachains-v9400)
- migrations found in Cumulus:
```rust
// v9400
pub type Migrations = (pallet_nfts::migration::v1::MigrateToV1<Runtime>,);
// v9380
pub type Migrations = (pallet_contracts::Migration<Runtime>,);
// v9360
type Migrations = (
	pallet_alliance::migration::Migration<Runtime>,
	pallet_balances::migration::MigrateToTrackInactive<Runtime, xcm_config::CheckingAccount>,
);
// v9330
pub type Executive = frame_executive::Executive<
	Runtime,
	Block,
	frame_system::ChainContext<Runtime>,
	Runtime,
	AllPalletsWithSystem,
	pallet_assets::migration::v1::MigrateToV1<Runtime>,
>;

```
- for all pallet that exist in your chain, add migrations, here I added (don't need to add balances: read instructions in `pallet_balances::migration::MigrateToTrackInactive`): 
```rust
pub type Migrations = (
    pallet_xcm::migration::v1::MigrateToV1<Runtime>,
    pallet_alliance::migration::Migration<Runtime>,
    pallet_assets::migration::v1::MigrateToV1<Runtime>,
// added myself just to look in logs
    TestOnRuntimeUpgrade,
);
```
```rust
pub struct TestOnRuntimeUpgrade;

impl OnRuntimeUpgrade for TestOnRuntimeUpgrade {
	fn on_runtime_upgrade() -> frame_support::weights::Weight {
		frame_support::log::info!("ಠ_ಠ 🤞🤞🤞🤞🤞🤞🤞🤞🤞🤞 migrations applied");
		Weight::from_ref_time(1)
	}
}
```
e) build `cargo b -r`, save wasm

## Perform upgrade and check everything is ok
- run old-versioned parachain in local testnet (can use [quick list](https://dev.to/nikania/quick-list-starting-local-parachain-testnet-3ncg))
```bash
cargo run ./bin/parachain-template-node-v0.9.32
```
- upgrade runtime ([official guide](https://docs.substrate.io/tutorials/build-a-blockchain/upgrade-a-running-network/))

Migrations of `pallet_xcm`, `pallet_alliance` and `pallet_assets` are needed only if there is something in the storage of these pallets. Therefore, in this example migrations are unnecessary. I did this example only to show how to find the migrations.

Any comments, corrections and suggestions are appreciated!💬