Skip to main content
Version: next 🚧

Migrate an Existing Validator

warning

This process should only be used if you want to split an existing validator private key into multiple private key shares for use in a Distributed Validator Cluster. If your existing validator is not properly shut down before the Distributed Validator starts, your validator may be slashed.

If you are starting a new validator, you should follow a quickstart guide instead.

Split an existing Ethereum validator key into multiple key shares for use in an Obol Distributed Validator Cluster.

Pre-requisites​

  • Ensure you have the existing validator keystores (the ones to split) and passwords.
  • Ensure you have docker installed.
  • Make sure docker is running before executing the commands below.
  • If you use MEV-Boost, you must either:
    • Turn off your MEV-Boost client before you split your keys, or;
    • Temporarily use a relay you won't be using when running the Distributed Validator; to prevent registering for MEV with a timestamp more recent than the one Charon prepares at the moment of key splitting.

Step 1. Prepare the existing keystore files​

info

Starting with Charon v1.8.0, you may not need to manually prepare the keystore files as described below. Charon can recursively search for keystore files in the specified directory and attempt to match the corresponding password files. The only case where this does not work is when you specify an exact list of withdrawal or fee recipient addresses; in that case, you must prepare the files manually and ensure the keystore indices match the order of the specified addresses.

Create a folder to hold the encrypted keystores, along with the passwords to decrypt them.

# Create a folder
mkdir split_keys

Copy the existing validator keystore.json files into this new folder. Alongside them, with a matching filename but ending with .txt should be the password to the keystore (e.g.: keystore-0.json, keystore-0.txt). The files must start with keystore*.

At the end of this process, you should have a tree like this:

├── split_keys
│   ├── keystore-0.json
│   ├── keystore-0.txt
│   ├── keystore-1.json
│   ├── keystore-1.txt
│ ...
│   ├── keystore-N.json
│   ├── keystore-N.txt

Step 2. Split the keys using the charon docker command​

Run the following docker command to split the keys (for mainnet):

CHARON_VERSION= # E.g. v1.10.0
CLUSTER_NAME= # The name of the cluster you want to create.
WITHDRAWAL_ADDRESS= # The address you want to use for withdrawals. It is recorded in the lock file and in the re-created deposit data files; it does not change the withdrawal address of a validator that has already been deposited.
FEE_RECIPIENT_ADDRESS= # The address you want to use for block reward and MEV payments.
NODES= # The number of nodes in the cluster.

docker run --rm -v $(pwd):/opt/charon obolnetwork/charon:${CHARON_VERSION} create cluster \
--name="${CLUSTER_NAME}" \
--cluster-dir=/opt/charon/cluster \
--withdrawal-addresses="${WITHDRAWAL_ADDRESS}" \
--fee-recipient-addresses="${FEE_RECIPIENT_ADDRESS}" \
--split-existing-keys \
--split-keys-dir=/opt/charon/split_keys \
--nodes ${NODES} \
--network mainnet \
--publish

The above command will create validator_keys along with cluster-lock.json and deposit-data-*.json in ./cluster for each node.

Command output:

***************** WARNING: Splitting keys **********************
Please make sure any existing validator has been shut down for
at least 2 finalized epochs before starting the charon cluster,
otherwise slashing could occur.
****************************************************************

Created charon cluster:
--split-existing-keys=true

/opt/charon/cluster/
├─ node[0-*]/ # Directory for each node
│ ├─ charon-enr-private-key # Charon networking private key for node authentication
│ ├─ cluster-lock.json # Cluster lock defines the cluster lock file which is signed by all nodes
│ ├─ deposit-data-*.json # Deposit data files are used to activate a Distributed Validator on the DV Launchpad
│ ├─ validator_keys # Validator keystores and password
│ │ ├─ keystore-*.json # Validator private share key for duty signing
│ │ ├─ keystore-*.txt # Keystore password files for keystore-*.json
warning

The deposit-data-*.json files are re-created and signed with the existing validator private keys, using the withdrawal addresses provided above. For a validator that is already activated, the on-chain withdrawal credentials remain unchanged — do not submit these deposit data files.

These split keys can now be used to start a Charon cluster.

Step 3. (Optional) Encrypt artifacts for distribution​

Within each folder are the encrypted private key shares, along with the decryption passwords. To transmit these folders to the operators/machines where they will run, it might be prudent to encrypt the folder as a .zip to transport them.

# For each folder in ./cluster/ encrypt it with a different password
zip -er node1.zip ./cluster/node1/

# Repeat for node2,...,nodeN.