4

My understanding is that when anything about the storage type is changed for example the encoded type stored, the keys, prefix etc then a storage migration is required.

But when else? Is there a standard definition of when storage migrations are required? What happens if a StorageMap is removed from a pallet for example?

Thanks

2 Answers 2

3

Is there a standard definition of when storage migrations are required?

I believe the most concise answer to this is to consider your blockchain two separate parts that need to work together:

  • The logic of your chain (runtime)
  • The state of your chain (storage)

If at any point these two parts become incompatible with one another, your chain is basically bricked.

Thus, the question you need to ask yourself when upgrading the logic of your chain, is what expectations it has on the underlying storage available.

For example, adding a new callable function (extrinsic) does not affect the behavior or layout of your storage, so no such storage migration is needed. Also, removing callable functions, or even entire modules has no impact. Adding new storage items, which will start empty also have no impact. There are a ton of things which can change in your runtime logic, which have no impact on storage, and thus needs no migration.

One reason you might need to migrate storage is a change in the serialization of the storage, which can come from refactoring the layout of structures.

For example, imagine something as simple as changing:

struct MyStruct<T> {
    id: u32,
    value: T::Balance,
}

Into:

struct MyStruct<T> {
    value: T::Balance,
    id: u32,
}

Nothing about the content or meaning of the struct has changed. In fact, the total encoded bytes of the object has stayed exactly the same, but the order of the items in the struct has flipped. This means, when the struct was originally put into storage, the first bits in the serialized form of the struct was the id, but after the logic change, it will try to parse those same bits as the value, and this will lead to problems. This actually won't brick your chain, as the encoded bytes will still fit perfectly, but you will end up totally misrepresenting the intended data.


So ultimately the question you need to ask yourself is:

Did an upgrade to the logic change the assumptions about the underlying storage?

If yes, then you need a storage migration.

1
  • It would be great to have this alongside the tutorial in substrate docs as preliminary reading.
    – gatsey
    May 21 at 11:32
2

My understanding is that when anything about the storage type is changed for example the encoded type stored, the keys, prefix etc then a storage migration is required.

That is the correct understanding and also includes all the cases when a storage migration is required.

When you remove a storage type, you should also write a migration to clean up the storage. Otherwise there will be data left in the state that is useless.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.