This document describes the configuration options for running a charon node and cluster locally or in production.
A charon cluster is configured in two steps:
cluster-definition.json
which defines the intended cluster configuration without validator keys.cluster-lock.json
which includes and extendscluster-definition.json
with distributed validator bls public key shares.
The charon create dkg
command is used to create cluster-definition.json
file which is used as input to charon dkg
.
The charon create cluster
command combines both steps into one and just outputs the final cluster-lock.json
without a DKG step.
The schema of the cluster-definition.json
is defined as:
{
"name": "best cluster", // Cosmetic cluster name
"creator": { // Creator of this cluster definition
"address": "0x123..abfc", // ETH1 address of the creator
"config_signature": "0x123456...abcdef" // EIP712 Signature of config_hash by ETH1 address. Proves that the creator created the config.
},
"operators": [ // Operators of all Charon nodes in the cluster
{
"address": "0x123..abfc", // ETH1 address of the operator
"enr": "enr://abcdef...12345", // Charon node ENR
"config_signature": "0x123456...abcdef", // EIP712 Signature of config_hash by ETH1 address. Proves that the operator accepts the config.
"enr_signature": "0x123654...abcedf" // EIP712 Signature of ENR by ETH1 address. Allows this ENR to act on behalf of the operator.
}
],
"uuid": "1234-abcdef-1234-abcdef", // Random unique identifier.
"version": "v1.3.0", // Schema version
"timestamp": "2022-01-01T12:00:00+00:00", // Creation timestamp
"num_validators": 100, // Number of distributed validators (n*32ETH staked) to be created in cluster.lock
"threshold": 3, // Threshold required for signature reconstruction
"fee_recipient_address":"0x123..abfc", // ETH1 fee recipient address
"withdrawal_address": "0x123..abfc", // ETH1 withdrawal address
"dkg_algorithm": "foo_dkg_v1" , // DKG algorithm for key generation
"fork_version": "0x00112233", // Chain/network identifier
"config_hash": "0xabcfde...acbfed", // Hash of the initial configuration fields excluding operator ENRs and signatures
"definition_hash": "0xabcdef...abcedef" // Final hash of all fields (after all operators have added ENRs and signatures)
}
See the cluster.Definition and cluster.Operator Go structs for
details on how this cluster-definition.json
object is (de)serialised and how the SSZ
config hash and definition hash are calculated.
The creator config_signature
and operator config_signature
and enr_signature
are EIP712 signatures of typed structured data as opposed to just raw bytes. EIP712 enables users to see the object that they are signing in their wallet (ex: Metamask).
See eip712sigs.go for details on the EIP712 structure used to create these signatures.
The above cluster-definition.json
is generated by the dv-launchpad provided as input to the charon dkg
command which generates keys and the cluster-lock.json
file.
The cluster-lock.json
has the following schema:
{
"cluster_definition": {...}, // Cluster definiition json, identical schema to above,
"distributed_validators": [ // Length equal to num_validators (n*32ETH staked).
{
"distributed_public_key": "0x123..abfc", // DV root pubkey
"public_shares": [ "0x123..abfc", "0x123..abfc"], // The public share of each operator (length of num_operators)
"fee_recipient": "0x123..abfc" // Fee recipient address of this validator. Defaults to definition fee_recipient if empty.
}
],
"lock_hash": "0xabcdef...abcedef", // Hash of the cluster definition and distributed validators. Uniquely identifies a cluster lock.
"signature_aggregate": "0xabcdef...abcedef" // BLS aggregate signature of the lock hash signed by all the key shares of all the distributed validators. Proves that the key shares exist and attested to being part of this cluster.
}
charon run
just requires a cluster-lock.json
file to configure the cluster.
The following is the historical change log of the cluster config:
v1.4.0
default:- Added the
creator
nested structure to the cluster definition proving who created the cluster definition (including non-operators). - Refactored operator
config_signature
EIP712 structure to distinguish between operator and creatorconfig_signatures
.
- Added the
v1.3.0
:- Refactored
config_hash
,definition_hash
andlock_hash
calculations by aligning with SSZ common types:ByteList[MaxN]
: Variable length with max limit for strings.BytesN
: Fixed length byte.Uint64
: numbers.
- Refactored definition operator signatures:
config_signature
andenr_signature
to use updated EIP712 structured types. - This version is compatible with dv-launchpad generated
cluster-definition.json
. - See example definition.json and lock.json
- Refactored
v1.2.0
:- Refactored all base64 fields to Ethereum's standard 0x prefixed hex.
- Refactored definition operator signatures:
config_signature
andenr_signature
. - Refactored definition fields:
config_hash
anddefinition_hash
. - Refactored lock fields:
lock_hash
,signature_aggregate
anddistributed_validators.public_shares
.
- Refactored definition operator signatures:
- Remove definition operator
nonce
field since it isn't used for anything. Only supportnonce=0
for older versions. - See example definition.json and lock.json
- Refactored all base64 fields to Ethereum's standard 0x prefixed hex.
v1.1.0
:- Added cosmetic
Timestamp
field to cluster definition to help identification by humans. - See example definition.json and lock.json
- Added cosmetic
v1.0.0
:- Initial definition and lock versions.
- See example definition.json and lock.json
This version of Charon (logic) supports the following cluster config versions (files): v1.0.0
, v1.1.0
, v1.2.0
.
Charon uses viper for configuration combined with cobra for cli commands.
In descending order, the Charon node checks the following places for configuration:
- From environment vars beginning with
CHARON_
, with hyphens substituted for underscores. e.g.CHARON_BEACON_NODE=http://....
- From the config file specified with the
-config-file
flag as YAML, e.g.beacon-node: http://...
- From CLI params, e.g.
--beacon-node http://...
The following is the output of charon run --help
and provides the available configuration options.
Starts the long-running Charon middleware process to perform distributed validator duties.
Usage:
charon run [flags]
Flags:
--beacon-node-endpoints strings Comma separated list of one or more beacon node endpoint URLs.
--builder-api Enables the builder api. Will only produce builder blocks. Builder API must also be enabled on the validator client. Beacon node must be connected to a builder-relay to access the builder network.
--data-dir string Deprecated, please use 'private-key-file'.
--feature-set string Minimum feature set to enable by default: alpha, beta, or stable. Warning: modify at own risk. (default "stable")
--feature-set-disable strings Comma-separated list of features to disable, overriding the default minimum feature set.
--feature-set-enable strings Comma-separated list of features to enable, overriding the default minimum feature set.
-h, --help Help for run
--jaeger-address string Listening address for jaeger tracing.
--jaeger-service string Service name used for jaeger tracing. (default "charon")
--lock-file string The path to the cluster lock file defining distributed validator cluster. (default ".charon/cluster-lock.json")
--log-format string Log format; console, logfmt or json (default "console")
--log-level string Log level; debug, info, warn or error (default "info")
--loki-addresses strings Enables sending of logfmt structured logs to these Loki log aggregation server addresses. This is in addition to normal stderr logs.
--loki-service string Service label sent with logs to Loki. (default "charon")
--monitoring-address string Listening address (ip and port) for the monitoring API (prometheus, pprof). (default "127.0.0.1:3620")
--no-verify Disables cluster definition and lock file verification.
--p2p-allowlist string Comma-separated list of CIDR subnets for allowing only certain peer connections. Example: 192.168.0.0/16 would permit connections to peers on your local network only. The default is to accept all connections.
--p2p-bootnode-relay Enables using bootnodes as libp2p circuit relays. Useful if some charon nodes are not publicly accessible. (default true)
--p2p-bootnodes strings Comma-separated list of discv5 bootnode URLs or ENRs. (default [http://bootnode.lb.gcp.obol.tech:3640/enr])
--p2p-bootnodes-from-lockfile Enables using cluster lock ENRs as discv5 bootnodes. Allows skipping explicit bootnodes if key generation ceremony included correct IPs.
--p2p-denylist string Comma-separated list of CIDR subnets for disallowing certain peer connections. Example: 192.168.0.0/16 would disallow connections to peers on your local network. The default is to accept all connections.
--p2p-external-hostname string The DNS hostname advertised by libp2p. This may be used to advertise an external DNS.
--p2p-external-ip string The IP address advertised by libp2p. This may be used to advertise an external IP.
--p2p-tcp-address strings Comma-separated list of listening TCP addresses (ip and port) for libP2P traffic. Empty default doesn't bind to local port therefore only supports outgoing connections.
--p2p-udp-address string Listening UDP address (ip and port) for discv5 discovery. Empty default disables discv5 discovery.
--private-key-file string The path to the charon enr private key file. (default ".charon/charon-enr-private-key")
--simnet-beacon-mock Enables an internal mock beacon node for running a simnet.
--simnet-validator-keys-dir string The directory containing the simnet validator key shares. (default ".charon/validator_keys")
--simnet-validator-mock Enables an internal mock validator client when running a simnet. Requires simnet-beacon-mock.
--validator-api-address string Listening address (ip and port) for validator-facing traffic proxying the beacon-node API. (default "127.0.0.1:3600")