10

When I look at chain specs defined in code they usually contain something like this in their genesis:

GenesisConfig {
    system: my_runtime::SystemConfig {
        code: my_runtime::WASM_BINARY
            .expect("WASM binary was not build, please build it!")
            .to_vec(),
    },
    ...
}

If someone builds a node from source wouldn't that lead to a genesis mismatch due to different wasm blobs? Am I right in the assumption that such a config is merely used to generate a chain spec json file from it?

1 Answer 1

9

Yes that is right.

To generate the genesis block we are currently leveraging the native runtime. It holds the GenesisConfig that can decode the json chain specs for example or is the one that is used in the code like in your example. The problem is now that the native runtime evolves together with the on chain runtime, because both are sharing the same code. This would then lead to a genesis block with a potential different storage root. Even with the same native runtime, it would be required that WASM_BINARY is the same for everyone, but that isn't the case.

To solve this, we have the raw chain spec. The raw chain spec is basically the genesis database, aka it contains all the key => value pairs that you will find on each node as genesis state. Putting these values into the trie, will give you the storage root of the genesis block. This way we are not dependent on the native runtime to generate the genesis block. It is always advised, especially for Parachains, to first generate the raw chain spec. Parachain builders then can use the chain spec to extract the genesis wasm binary and to get the genesis state of their Parachain. If they don't do it that way, they probably will have different data registered on the relay chain than the Parachain nodes are using. This will then lead to collators being unable to build PoV candidates, because they can not find the required block in their local database. The error they will see is:

Could not find the header of the genesis block in the database!

TLDR: If you want to launch a chain, production or for testing (with multiple nodes), use a raw chain spec!

3
  • But why do we need to extract the wasm blob from the raw chain spec? Isn't it enough that it is in storage due to the genesis block built from the raw chain spec and then the parachain client loads it from there? Commented Feb 21, 2022 at 14:02
  • This is only for Cumulus based Parachain. When you have a Cumulus based Parachain, the validation code that is used on the relay chain, is the exact same code as what you find in :code in the Parachain state. The Parachain nodes take the code from their own state. The extraction of the wasm code is only required for when you want to register a Parachain on the relay chain. The relay chain requires the validation code (in our case the runtime wasm binary) and the genesis state (in our case the SCALE encoded genesis header) as inputs for the registration tx.
    – bkchr
    Commented Feb 21, 2022 at 14:29
  • Ahh okay I see it is for registration! Commented Feb 21, 2022 at 15:03

Your Answer

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

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