Migrate an Existing Validator

Migrate an existing validator by splitting its private key into shares

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

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.2.0
CLUSTER_NAME=                  # The name of the cluster you want to create.
WITHDRAWAL_ADDRESS=            # The address you want to use for withdrawals (this is just for accuracy in your lock file, you can't change a withdrawal address for 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}" \
   --withdrawal-addresses="${WITHDRAWAL_ADDRESS}" \
   --fee-recipient-addresses="${FEE_RECIPIENT_ADDRESS}" \
   --split-existing-keys \
   --split-keys-dir=/opt/charon/split_keys \
   --nodes ${NODES} \
   --network mainnet

The above command will create validator_keys along with cluster-lock.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 finalised epochs before starting the Charon cluster,
 otherwise slashing could occur.                               
****************************************************************

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

./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
│  ├─ validator_keys            # Validator keystores and password
│  │  ├─ keystore-*.json        # Validator private share key for duty signing
│  │  ├─ keystore-*.txt         # Keystore password files for keystore-*.json

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.

Last updated