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

Runtime upgrade #87

Closed
4 tasks done
PopcornPaws opened this issue Jan 11, 2023 · 2 comments
Closed
4 tasks done

Runtime upgrade #87

PopcornPaws opened this issue Jan 11, 2023 · 2 comments
Assignees

Comments

@PopcornPaws
Copy link
Collaborator

PopcornPaws commented Jan 11, 2023

Description

Two main areas are needed to be explored and tested properly:

  • runtime upgrades
  • benchmarking pallet call weights properly
    Both are extremely important to understand well, because we are probably going to need many runtime upgrades initially on the nodes. As for weights, the speed of the chain depends on them, because transactions are included in blocks based on their pre-benchmarked weights. Thus, for optimal operation, the weights have to be benchmarked properly.

Solution

@PopcornPaws
Copy link
Collaborator Author

PopcornPaws commented Jan 13, 2023

Runtime upgrades

One of the defining features of Substrate-based chains are forkless upgrades, that is, the runtime (a compiled wasm binary) describing on-chain behaviour (pallet api, storage, etc.) is part of the state. Therefore, node operators/network maintainers can propose upgrades to the runtime which, if it is accepted in a governance voting process, overrides the on-chain runtime.

The runtime code can be set via the frame-system pallet (docs). This is an operational type of code, which means multiple things:

  • it requires system-level root access
  • it may execute as long as it needs to
  • the caller doesn't need to pay when calling it

Root access can be gained via the Sudo pallet or via decentralized governance.

Migrations and testing

Runtime upgrades are much easier to perform when it only extends pallet functionality without modifying the underlying storage. However, if the storage is changed, because, for example:

  • we change the key type in one of our storage maps from u64 to i64
  • increase the minimum existential deposit (i.e. balance) an account needs to have in order to not be "killed" (deleted) by the runtime
    then we need to perform a migration step when updating the runtime. This means that we need to write one-time functions that are called by the OnRuntimeUpgrade::on_runtime_upgrade hook. For example, we can iterate over our (u64 -> AccountId) map, and replace it by an (i64 -> AccountId) map in the storage.

It is important, however, to test these runtime upgrades via the try-runtime feature of Substrate. This tool enables you to test a proposed runtime against a running node by

  • connecting to a deployed node
  • call the runtime and retrieve state at a specific block
  • test the retrieved data via try-runtime tests
    Instead of using the convoluted Trie + RocksDB pair for storage tests, try-runtime mocks a simple key-value store in memory while testing the state.

You can specify pre_upgrade and post_upgrade hooks in your pallets hidden behind the try-runtime feature that perform some checks that should pass before and after an upgrade/migration (example usage)

@PopcornPaws PopcornPaws changed the title Runtime upgrade and Weight benchmarking Runtime upgrade Jan 13, 2023
@PopcornPaws
Copy link
Collaborator Author

I'm closing this issue because for now it doesn't require code to be written, it's more like a reference manual TLDR for future use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant