Basic storage migration
A simple migration guide using the Nicks pallet as a reference.
#
GoalWrite a storage migration for a pallet that adds an additional Vec<u8>
storage item to runtime storage.
#
Use casesA pallet that adds a single storage item and needs to be included in a runtime upgrade.
#
OverviewThis guide will step through a storage migration on FRAME's Nick's pallet. It shows how to modify a storage map to provide an optional field that includes a last name, and how to write the migration function ready to be triggered upon a runtime upgrade. This guide can equally be used in other contexts which require a simple storage migration that modifies a storage map in a runtime.
#
Steps#
1. Create a storage struct and utility typeWrite a struct to manage the previous and new storage items, first and last:
Write a utility type enum to keep track of the storage versions:
#
2. Update your storage itemsThe Nicks pallet only keeps track of a lookup table in storage, but we also need to add PalletVersion
to
declare the current version in storage. To update these items, use the Nickname
struct in the NameOf
item and add the new storage item PalletVersion
:
#
3. Update all functionsAll of the Nicks pallet functions need to account for the new last: Option<Vec<u8>>
storage item. Update each function by adding it as a parameter, for example:
In addition, update all storage writes with the Nickname
struct:
#
4. Declare a migration moduleThe migration module should contain two parts:
- A module indicating the deprecated storage to migrate from.
- The migration function which returns a weight.
The scaffolding of this module looks like this:
migrate_to_v2
#
5. Write Here's an overview of what this function needs to do:
- Check the storage version to make sure a migration is needed (good practice)
- Transform the storage values into the new storage format
- Update the storage version
- Return the weight consumed by the migration
#
Check the storage versionConstruct the migrate_to_v2
logic around the check. If the storage migration doesn't need to happen, return 0:
#
Transform storage valuesUsing the translate storage method
,
transform the storage values to the new format. Since the existing nick
value in storage can be made of a string separated by a
space, split it at the ' '
and place anything after that into the new last
storage item. If it isn't, last
takes the None
value:
note
remove Option
wrapping to make sure decoding works properly.
#
Return the consumed weightTo do this, count the number of storage reads and writes and return the corresponding weight:
migrate_to_v2
in on_runtime_upgrade
#
Use Go back to the pallet's functions and specify the migrate_to_v2
function in on_runtime_upgrade
:
types.json
file#
6. Create a Put the new storage types in a types.json
which you will need to trigger the migration using a UI. Our new types in JSON are:
#
Examples#
Resources#
How-to guides- Trigger Migration using Polkadot JS: learn how to trigger the migration on a live chain
#
Rust docs- Rust docs for the
Option
enum frame_support::storage::migration
utility docs