TLDR; This proposal is about unifying passing configuration to status-go. Each environment (cli, Docker, status-react) would use a JSON blob to start a node and manage its services. For the CLI, it would mean no flags except for one
-c/--config. Moreover, the provided configuration would be final and would not be implicitly updated.
The current state of configuration in status-go is less than ideal. It has a long history and accumulated a lot of tech debt. I think it’s high time to discuss its future form and refactor it.
I have a list of the most frustrating things about the current configuration in status-go:
- defaults are scattered over many places; in case of a CLI, some defaults are defined for flags and some are in
- provided config as a JSON blob is not final; there is an “update phase” which checks if e.g. bootnodes are empty while
ClusterConfigis enabled and if that’s the case, the config is implicitly changed,
- it’s called
NodeConfigwhile it encapsulates other areas as well,
- it’s not flatten;
NodeConfighas other structs embedded like
ClusterConfigthat can be
The another matter that needs clarification is how the config is utilized. This is derived from the fact how status-go is utilized:
- as a CLI program (
statusdbinary) and the config is built from the provided flags or a config file (rarely used),
- as a Docker container and in this case the config is also built from the provided flags,
- as a library statically linked with status-react where the config is built using
GenerateConfigbinding and JSON object manipulation in ObjC or Java.
This proposal is about unifying the way the configuration is provided and used in the mentioned environments. The config object should always be created from a JSON blob and it must be complete and final, i.e. there are no implicit updates and if some required values are missing, an error is returned.
In the CLI, we would ideally remove all flags and only accept JSON files:
statusd -c config/fleet-eth.beta.json -c path/to/my/config.json
As you can see, it’s possible to provide multiple JSON files. They will be merged according to the occurrence order. The reason is that some configuration values rarely change and can be versioned. A fleet configuration is a good example. At the same time, it should be possible to easily experiment and provide a custom config file.
We may consider keeping some very popular flags like
-datadir but that raises a question which flags are popular and should be kept. Alternative is to do use https://github.com/kelseyhightower/envconfig instead where each configuration value can be overridden with a env variable (it will be possible because the configuration struct will be flat).
If we remove flags, how can we pass a custom configuration file to a docker container? One option is to dynamically create a JSON file in Ansible based on some vars, upload it on a host machine and mount as a volume. Is this solution ok? cc @jakubgs
status-react will pass the config to start the node in the same way as today. However, the question is whether we should keep
GenerateConfig binding or it should be removed. In my opinion, we should remove it and encourage usage of
ValidateConfig binding instead. In this way, we would be able to remove most of the JSON manipulation from Objective-C and Java code and keep the configuration as plain JSON files. cc @yenda
Also, we will get rid of a situation that some values are defined in status-go and some in status-react (the current situation with bootnodes and Whisper nodes vs MailServer nodes) as all values would need to be defined on status-react side.
- We still need to have a way to calculate some configuration values. For example, if the network ID is provided and LES enabled, we can safely calculate the chain genesis which is required by LES.
ValidateConfigshould return an error if these values are missing and it’s not possible to calculate them.