System configuration is a set of parameters that determine the network access parameters of a node and behavior of the node while operating in the network.
Exonum services may have their own configuration settings.
The configuration settings of the anchoring service include the parameters of the RPC connection to a Bitcoin Core node as well as a Bitcoin address used for anchoring.
System configuration falls into 2 parts:
- Global parameters must be identical for all full nodes in the network. The global parameters are saved in the blockchain when the genesis block is created.
- Local parameters may differ for each node. Local parameters for a node are stored in the TOML format. A path to the configuration file is specified on the node start up.
This categorization holds for both core and service parameters. The following table shows three possible parameter categories.
|Global||Validators’ public keys||Anchoring address|
|Local||Validator’s private key||(N/A)|
Note that there is no unified mechanism for changing local configuration for services. If necessary, local configuration may be injected into the service using a parameterized service artifact, or by separating the config-dependent part into a component executing separately and communicating with the service using a secure communication channel (e.g., private API).
The time oracle illustrates the first approach (the service factory accepts a time provider), and the anchoring service the second one (the part communicating with the Bitcoin node is separated into an independent executable).
Global configuration may be changed using the supervisor service, and local configuration by editing the configuration file. When the blockchain is being created, the initial global configuration is supplied from a file, too, since the blockchain is absent at this point.
Genesis configuration is the global configuration which is necessary to start a new node. While nodes update the global configuration using the supervisor service, a node need to get the genesis configuration from a trusted source. Indeed, at the point the genesis config is used, the node knows has no blockchain data.
The contents of the genesis configuration is outlined below.
Each validator has two public keys. The consensus key is used for consensus messages (including precommits that authorize blocks in the blockchain), and to authorize / encrypt P2P connections. The service key is used to sign transactions generated by services.
Consensus Algorithm Parameters¶
Configuration of the consensus algorithm, such as the maximum allowed message length, the maximum number of transactions per block, and various timeouts.
Artifacts and service instances that are deployed on the blockchain from the very beginning. A special setup for these services is required to avoid the chicken-and-egg problem. For example, if a supervisor service is not deployed from the start, it will be impossible to deploy / instantiate any services in the future.
The node address broadcasted to other peers using
Listen address of the current node
Path to the passphrase-encrypted key material used to derive secret keys of the node. The passphrase should be provided on node startup via a terminal prompt or an environment variable.
List of full node addresses that the node will allow incoming connections from, and to which it will attempt to connect on startup.
Local connection parameters for a node.
Maximum number of incoming connections
Maximum number of outgoing connections
Activates of the
NODELAYalgorithm from the TCP stack (see RFC2126)
Enables keep-alive and sets the idle time interval (ms) for the TCP stack (see RFC 1122). Keep-alive will be disabled if this parameter is not set.
Timeout interval (ms) between reconnection attempts
Maximum number of reconnection attempts
HTTP API configuration parameters.
Timeout interval (ms) to update info about connected peers
Listen address for public HTTP API server
Listen address for private HTTP API server
Sets up the CORS headers for public API endpoints. The parameter can take any of the three forms:
"*"enables requests from all origins
- Origin string (e.g.,
"http://example.com") enables requests from a single specific origin
- An array of origin strings
["http://a.example.com", "http://b.example.com"]) enables requests from any of the specified origins
Sets up the CORS headers for private API endpoints. Syntax is the same as for public_allow_origin.
HTTP server restart options in case their endpoints are updated (e.g., a new Rust service is instantiated or a Rust service is stopped).
allow_origin parameters are not specified, CORS headers are not added
to any requests, which can lead to requests from external origins
being improperly processed by user agents with the CORS support
(such as web browsers). However, you can easily avoid this by passing the
public API of an Exonum node through the web server
delivering web assets (for example, Nginx). In this case, the requests to
API would be same-origin, so CORS restrictions would not apply.
Parameters that determine the maximum number of events that may be placed into the event queue of each type:
Maximum number of queued API requests.
Maximum number of queued internal events.
Maximum number of queued incoming network messages.
Maximum number of queued outgoing network messages.
Global parameters should be changed by using the supervisor service. The service ensures that the configuration updates are synchronized among nodes in the network.
Local parameters may be changed by editing the configuration file and restarting the node to apply changes. In certain cases additional actions may be required to keep the system operational.
To keep a node operating when changing its validator key, you also need to update the corresponding global variable (the list of validator keys) using the supervisor.