## chain specificaition in `omni-node`: cli considerations ### Staus quo This is what we have today. The spec is a self-contained file allowing to run the chain. `spec.json` contains the full state including the runtime blob: ``` node --chain spec.json ``` The node itself may contain a number of named, pre-defined chain specs. It is a convinient way to quickly run the node w/o neccessity of having chain-spec files. ``` node --chain rococo-staging ``` Obiously this approach won't work with generic `omni-node` for two reasons: - `omni-node` does not know the internals of runtime, thus is not able to define an initial state, - `omni-node` does not know chain properties. ### omni-node It is tempting to get away from chain-spec file and allow to run node w/o neccessity to build or interact with spec file. Here are some ideas: 1. Use internal preset. Provides no way to customize chain spec properties. Using internal preset is required as default runtime genesis config may not work in many cases as some critical values are not initialized by default: ``` omni-node --runtime runtime.wasm --chain testnet ``` 1. It should be easy to run omni-node with the given runtime, without neccessity to update the chain-spec file. This could be achieved with (`--runtime` overrides `code` defined in `spec.json`): ``` omni-node --chain spec.json --runtime new-runtime.wasm ``` 1. For good experience it would be desired to not over bloat chain-spec.json file size. This is unfortunately a case when it contains a runtime blob. This could be overcome in two ways: - `spec.json` may contain empty (or `0x0`) hexstring in `gensis::runtimeGenesis::code` - the chain-spec file may not contain `gensis::runtimeGenesis::code` field at all. In both cases `--runtime` option would fix the runtime field while reading the chain-spec into memory. We could also extend chain spec builder commands with ability to create such specs (e.g `--dev` or `--no-code` / `--no-runtime` options). 1. Sometimes the chain properties must be defined. We could try to extend command in (1) with chain spec properties provided in extra file: ``` omni-node --runtime runtime.wasm --chain testnet --chain-properties properties.json ``` or with specialized command line arguments: ``` omni-node --runtime runtime.wasm --chain testnet --name ... --bootnodes ... --id ``` Ergonomy of usability of both is questionable. We could hide `--chain-properties` and read `chain-properties.json` silently if it exists: ``` omni-node --runtime runtime.wasm --chain testnet ``` But at the end, I believe we cannot get away from chain-spec file (it will be needed for production chains), and introduction of new config file containing only chain properties maybe confusing. 1. `chain-properties.json` from previous bullet (4) is just a *partial chain spec* or *state-less chain spec* (or *genesis-less chain spec*). This idea can be introduced to our *dictionary*. We could extend chain spec building tool with ability of building the chain-spec that does not contain `genesis` section (e.g. `--no-genesis` or `--no-state`). However, in this approach we would need to duplicate chain-spec building functionality into *run* command. This would require aligning naming conventions in *run* and *build-spec* subcommands. Some ideas: ``` omni-node --runtime runtime.wasm --chain spec.json --genesis-preset testnet ``` ``` omni-node --runtime runtime.wasm --chain spec.json --genesis-patch patch.json ``` ``` omni-node --runtime runtime.wasm --chain spec.json --genesis-full genesis-confg.json ``` ### Building chain spec utilities Runtime blob may contain predefined presets of runtime genesis config (which also can be seen as initial state presets). The preset is a json patch containing a list of key-values pairs overriding corresponding values in default runtime genesis config. The list of presets can be obtained with: ``` omni-node spec list-presets -r runtime.wasm ``` A particular preset can be displayed with: ``` omni-node spec display-preset -r runtime.wasm -p "staging" ``` The chain-spec based on given preset can be generated by: ``` omni-node spec create -r runtime.wasm named-preset staging > spec.json ``` The user defined patch can be used to build a chain-spec: ``` omni-node spec create -r runtime.wasm patch "state-patch.json" ``` The user can also provide full runtime genesis config in json representation: ``` omni-node spec create -r runtime.wasm full "state-full.json" ``` Each of before mentioned subcommands of the `create` command support `raw` chain-spec creation. Update-code subcommand is also provided: ``` omni-node update-code spec.json new-code.wasm ``` ### Typical flows #### With chain-spec Scenario: spawning network. 1. Create spec file, which is not over bloated with code blob: ``` omni-node spec create -r runtime.wasm --no-code named-preset staging > spec.json ``` 1. Edit the `spec.json`, add bootnodes, chain properties, adjust state etc. This is done once. 1. If needed progress work on your runtime and rebuild it and just keep running the node with the new runtime (`spec.json` remains the same): ``` omni-node --chain spec.json --runtime runtime.wasm ``` #### With chain-spec Scenario: running single node. 1. Rebuild runtime and run the node with the runtime: ``` omni-node --runtime runtime.wasm --preset preset-name ``` #### With *no-genesis* chain-spec Scenario: spawning network. 1. Create spec file, which is not over bloated with code blob: ``` omni-node spec create -r runtime.wasm --no-genesis --name ... --id ... ...> spec.json ``` 1. Edit the `spec.json`, add bootnodes, chain properties, etc. This is done once. 1. Rebuild runtime and run the node with the runtime: ``` omni-node --chain spec.json --genesis-preset testnet --runtime runtime.wasm ```