Substrate Runtime Toolbox (srtool)

Unlike all other Blockchains, Polkadot (based on Substrate) allows on-chain protocol upgrades without requiring the node operators to do anything but to keep their node up and running.

If you know everything about Substrate Runtime, you may jump to the Installation section.

In order to achieve this, Polkadot stores its runtime executable as a WASM blob in its own storage. If the WASM blob is replaced, the new runtime kicks in and all the nodes start using it, altogether.

pre
Figure 1. Polkadot Runtime

Unlike Blockchains such as Ethereum or Bitcoin where most of the node operators must agree, synchronize, and upgrade the software that it running on they computers, Polkadot has the ability to activate a new runtime autonomously after going thru the governance process required by the current runtime!

Any developer can write a new version of the runtime and use the on-chain governance mechanisms in order to propose a new runtime candidate.

If this proposal is supported by the stake holders through on-chain governance, the new WASM runtime will activate at a given block without the operators having to take any action. Even if some node operators use old version of the node, they will still be using the current runtime.

This may sound obvious but no other blockchain expose such a feature.

Node operators that are up-to-date however get a little benefit: if the hash of the current runtime matches native code they run locally, the native code will be used instead of the slower WASM blob.

This also guarantees that Polkadot always uses one single version of its runtime. That would be similar to 100% of all Bitcoin or Ethereum nodes to run the exact same version of the protocol at a given point of time. A nice utopia…​

1. Verification of the runtime

Let’s consider a Blockchain developer who wants to proposes a change or a new feature. First of all, (s)he can write the Rust code required for the change and test it.

The WASM Runtime blob is a binary file that is mostly not human readable. Here is how it looks like:

...
00ad 4280 8080 80a0 0484 1001 0000 0b81
0101 017f 2300 41c0 006b 2204 2400 2004
2001 3602 0c20 0420 0036 0208 2004 2003
3602 1420 0420 0236 0210 2004 412c 6a41
0236 0200 2004 413c 6a41 0336 0200 2004
4202 3702 1c20 0441 9498 c400 3602 1820
0441 0436 0234 2004 2004 4130 6a36 0228
2004 2004 4110 6a36 0238 2004 2004 4108
6a36 0230 2004 4118 6a41 94ad c000 1038
000b 0200 0bb1 0101 037f 0240 0240 0240
0240 2000 2802 0022 0028 0204 2203 2000
2802 0822 046b 2002 490d 0020 0028 0200
2103 0c01 0b20 0420 026a 2205 2004 490d
0220 0341 0174 2204 2005 2004 2005 4b1b
2204 4100 480d 0202 4002 4020 030d 0020
0410 2121 030c 010b 2000 2802 0020 0320
0410 2521 030b 2003 450d 0120 0020 0436
0204 2000 2003 3602 0020 0028 0208 2104
0b20 0020 0420 026a 3602 0820 0320 046a
...

The sample above is only a very small portion of the runtime wasm for Kusama v0.7.8.

Considering this file, it is clearly difficult for anyone (even skilled!) to understand what the code is doing.

For this reason, our Blockchain developer will have to:

  • share the code

  • explain the intent

  • explain the code, new features and changes

Failing to do so will likely end up in the proposal to upgrade the runtime to fail and the candidate runtime will never replace the current one.

Here is portion of a change that was introduced recently with Kusama 0.7.8:

change
Figure 2. Extract of a recent change made to the runtime

This specific change is rather simple, self explanatory but nonetheless enhanced by some comments. Nice job! :)

How can we now make sure that the binary blob that we saw previously, is really doing what the author of the code tells us it does.

How can we make sure that the author is not lying about the real code used to generate the binary blob?

It is possible to take the entire code of the Polkadot runtime, compile it and compare the output with the full binary blob that was submitted on-chain.

If the blob I can now generate on my own machine matches the blob submitted by the dev, I can trust that the source code I am reading is matching the wasm blob that is about to be replacing the runtime.

If I agree with the intent of the code and its implementation, I can now make an informed decision and vote in favor of the proposal to upgrade the runtime code used by all nodes.

$ srtool build
🧰 Substrate Runtime Toolbox 🧰
        - by Chevdor -
🏗  Building polkadot-runtime as release using rustc 1.39.0 (4560ea788 2019-11-04)
⏳ That can take a little while, be patient... subsequent builds will be faster.
   Compiling polkadot-runtime v0.7.8 (/build/runtime)
    Finished release [optimized] target(s) in 18m 17s
✨ Your Substrate WASM Runtime is ready! ✨
Summary:
  Size    : 1.1M (1088)
  Content : 0x0061736d0100000001a4022b60037f7f...6164643720323031392d31312d303729
  SHA256  : e9ca04eecd6079d3099de361b604b8d7fb591421c3beebab7e7c9166fae37c18
  Wasm    : ./srtool/release/wbuild/polkadot-runtime/polkadot_runtime.compact.wasm
Note
Some of the hashes shown in this article may not match the hashes currently returned by the latest version of srtool as they have been done with early versions of srtool.

The key information in the output above it the ShA256 hash: e9ca04eecd6079d3099de361b604b8d7fb591421c3beebab7e7c9166fae37c18.

We can trust any piece of code that compiles into a binary matching this hash to be the original code used to produce the WASM blob.

Note
The SHA256 hash we just produced deterministically can only be produced with a given version of the Rust compiler: rustc.

Stake holder now can make an informed decision when see such a proposal:

motion
Figure 3. A council motion proposing a new new runtime blob
Note
The content of the blob in the screenshot does not match the sample output. This is due to the fact that I took the screenshot on another wasm blob as the initial one was no long easily accessible at the time of writing this article.

2. Installation

The srtool project is hosted on gitlab.com/chevdor/srtool and you can read the README to get started.

You may also stop by the Docker Hub to leave a star to the image making all of this possible but remember that using a different image will yield to a different hash.

Here is the TLDR version:

First you set and alias
echo "export RUSTC_VERSION=nightly-2019-12-07; export PACKAGE=polkadot-runtime; alias srtool='docker run --rm -it -e PACKAGE=\$PACKAGE -v \$PWD:/build -v /tmp/cargo:/cargo-home chevdor/srtool:\$RUSTC_VERSION'" >> ~/.bash_profile && source ~/.bash_profile

You can now invoke srtool from the polkadot folder. Here are a few commands you can try:

Get some help
srtool help
Run a regular build
srtool build
Run run a build and get a json friendly output
srtool build --json
Additionally save the json report
srtool build --json --save

3. Caveats

On Linux, using Docker may require to prepend sudo to each docker command. You may also follow the instructions here to get rid of this requirements.

If you run into some issues, go though the following check-list:

  • docker ps does not respond with any error

  • pwd is the folder where your polkadot repository is located

  • you did use the full command as in the alias including all the -v and -e flags

If you still run into some issues, ask for some help on Riot.


This site is best viewed using the Brave browser,role=external,window=_blank.

Not only it will help you block most trackers, keep you safer on the internet but it also allows you supporting websites such as this one without having to spend a dime.

Using Brave allows me bringing this content to you, without any ad, subscription and other annoyance (I am looking at you Medium…​). Using Brave gives you the opportunity to show your appreciation for that in a few clicks!

You can read more about Brave in this article.


Avatar
Wilfried Kopp
Building Blockchains & Decentralized Solutions

I am building decentralized solutions and tooling to support them. I am developing Smart Contracts on Ethereum and Substrate while aspiring at being more proficient in Rust. GPG Fingerprint 15AF C574 D3F9 F1C3 CCDD E31E 2DCE C4DC 506E 6475

Related