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
"validators": [ // Metadata related to each validator to be created
{
"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
"deposit_amounts": [ // Partial deposit amounts in gwei (must sum up to 32ETH)
"16000000000",
"16000000000"
],
"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 definition 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)
"partial_deposit_data": [...], // Deposit datas to activate this validator (corresponds to deposit_amounts)
"builder_registration": {...} // Pre-generated signed builder registration for the validator
}
],
"deposit_amounts": [ // Partial deposit amounts in gwei (must sum up to 32ETH)
"16000000000",
"16000000000"
],
"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 attest to being part of this cluster.
"node_signatures": ["0xabcdef...abcedef"] // Signatures of the lock hash by each operator. Proves that this lock file (and the validators) was generated by all the operators
}
charon run
just requires a cluster-lock.json
file to configure the cluster. See the cluster.DepositData and cluster.BuilderRegistration Go structs for more details
on how an individual distributed_validator
looks like.
The following is the historical change log of the cluster config:
v1.8.0
default:- Added the
deposit_amounts
list to cluster lock which contains partial deposit amounts in gwei. - When not specified, the single value of 32ETH will be used. All partial amounts must sum up to 32ETH.
distributed_validator
structure replaceddeposit_data
withpartial_deposit_data
respectively.
- Added the
v1.7.0
:- Added the
builder_registration
structure todistributed_validators
list in cluster lock. - This enables distributed validators to submit pre-generated validator registrations that enable MEV-blocks.
- Added the
node_signatures
list to cluster lock which contains signatures of the lock hash signed by each individual node.
- Added the
v1.6.0
:- Add
deposit_data
structure todistributed_validators
list in cluster lock. - This allows anyone with access to the lock file to activate the validators, specifically, the creator.
- Add
v1.5.0
:- Add the
validators
list to cluster definition that containsfee_recipient_address
&withdrawal_address
for each validator. - This allows configuring multiple fee recipient and withdrawal addresses instead of a single address for all validators.
- Add the
v1.4.0
:- 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.
--beacon-node-submit-timeout duration Timeout for the submission-related HTTP requests Charon makes to the configured beacon nodes. (default 2s)
--beacon-node-timeout duration Timeout for the HTTP requests Charon makes to the configured beacon nodes. (default 2s)
--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.
--consensus-protocol string Preferred consensus protocol name for the node. Selected automatically when not specified.
--debug-address string Listening address (ip and port) for the pprof and QBFT debug API. It is not enabled by default.
--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 the distributed validator cluster. If both cluster manifest and cluster lock files are provided, the cluster manifest file takes precedence. (default ".charon/cluster-lock.json")
--log-color string Log color; auto, force, disable. (default "auto")
--log-format string Log format; console, logfmt or json (default "console")
--log-level string Log level; debug, info, warn or error (default "info")
--log-output-path string Path in which to write on-disk logs.
--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")
--manifest-file string The path to the cluster manifest file. If both cluster manifest and cluster lock files are provided, the cluster manifest file takes precedence. (default ".charon/cluster-manifest.pb")
--monitoring-address string Listening address (ip and port) for the monitoring API (prometheus). (default "127.0.0.1:3620")
--no-verify Disables cluster definition and lock file verification.
--p2p-disable-reuseport Disables TCP port reuse for outgoing libp2p 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-relays strings Comma-separated list of libp2p relay URLs or multiaddrs. (default [https://0.relay.obol.tech,https://2.relay.obol.dev,https://1.relay.obol.tech])
--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.
--private-key-file string The path to the charon enr private key file. (default ".charon/charon-enr-private-key")
--private-key-file-lock Enables private key locking to prevent multiple instances using the same key.
--proc-directory string Directory to look into in order to detect other stack components running on the host.
--simnet-beacon-mock Enables an internal mock beacon node for running a simnet.
--simnet-beacon-mock-fuzz Configures simnet beaconmock to return fuzzed responses.
--simnet-slot-duration duration Configures slot duration in simnet beacon mock. (default 1s)
--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.
--synthetic-block-proposals Enables additional synthetic block proposal duties. Used for testing of rare duties.
--testnet-capella-hard-fork string Capella hard fork version of the custom test network.
--testnet-chain-id uint Chain ID of the custom test network.
--testnet-fork-version string Genesis fork version in hex of the custom test network.
--testnet-genesis-timestamp int Genesis timestamp of the custom test network.
--testnet-name string Name of the custom test network.
--validator-api-address string Listening address (ip and port) for validator-facing traffic proxying the beacon-node API. (default "127.0.0.1:3600")