# Create a DV With a Group

### Pre-requisites <a href="#pre-requisites" id="pre-requisites"></a>

* A basic [knowledge](https://docs.ethstaker.cc/ethstaker-knowledge-base/) of Ethereum nodes and validators.
* A machine that meets the [minimum requirements](https://docs.obol.org/next/prepare/deployment-best-practices#hardware-specifications) for the network you intend to validate.
* If you are taking part using a [DappNode](https://dappnode.com/):
  * A computer with an up to date version of [DappNode](https://docs.dappnode.io/docs/user/install/overview/)'s software and an internet connection.
* If you are taking part using [Sedge](https://www.nethermind.io/sedge), or [Charon's Distributed Validator Node](https://github.com/ObolNetwork/lido-charon-distributed-validator-node) (CDVN) starter repo:
  * Ensure you have [git](https://git-scm.com/downloads) installed.
  * Ensure you have [docker](https://docs.docker.com/engine/install/) installed.
  * Make sure `docker` is running before executing the commands below.
  * If you are taking part using **Helm**:
    * Ensure you have [kubectl](https://kubernetes.io/docs/tasks/tools/) installed and configured to communicate with your Kubernetes cluster.
    * Ensure you have [Helm](https://helm.sh/docs/intro/install/) (v3+) installed.
    * Ensure you have access to a running Kubernetes cluster.

### Step 1: Get your ENR <a href="#step-1-get-your-enr" id="step-1-get-your-enr"></a>

{% tabs %}
{% tab title="CDVN" %}
In order to prepare for a distributed key generation ceremony, you need to create an ENR for your Charon client. This ENR is a public/private key pair that allows the other Charon clients in the DKG to identify and connect to your node. If you are creating a cluster but not taking part as a node operator in it, you can skip this step.

```sh
# Clone the repo
git clone https://github.com/ObolNetwork/charon-distributed-validator-node.git
# Change directory
cd charon-distributed-validator-node/
# Use docker to create an ENR. Backup the file `.charon/charon-enr-private-key`.
docker run --rm -v "$(pwd):/opt/charon" obolnetwork/charon:v1.9.0 create enr
```

You should expect to see a console output like this:

```sh
Created ENR private key: .charon/charon-enr-private-key
enr:-JG4QGQpV4qYe32QFUAbY1UyGNtNcrVMip83cvJRhw1brMslPeyELIz3q6dsZ7GblVaCjL_8FKQhF6Syg-O_kIWztimGAYHY5EvPgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQKzMe_GFPpSqtnYl-mJr8uZAUtmkqccsAx7ojGmFy-FY4N0Y3CCDhqDdWRwgg4u
```

{% hint style="warning" %}
Please make sure to create a backup of the private key at `.charon/charon-enr-private-key` Be careful not to commit it to git! **If you lose this file you won't be able to take part in the DKG ceremony nor start the DV cluster successfully.**
{% endhint %}

{% hint style="success" %}
If instead of being shown your `enr` you see an error saying `permission denied` then you may need to [update your docker permissions](https://docs.obol.org/next/advanced-and-troubleshooting/troubleshooting/errors#how-to-fix-permission-denied-errors) to allow the command to run successfully.
{% endhint %}

For Step 2 of the quickstart:

* Select the **Creator** tab if you are coordinating the creation of the cluster (this role holds no position of privilege in the cluster, it only sets the initial terms of the cluster that the other operators agree to).
* Select the **Operator** tab if you are accepting an invitation to operate a node in a cluster, proposed by the cluster creator.
  {% endtab %}

{% tab title="DappNode" %}
**Prepare an Execution and Consensus client**

Before preparing the DappNode to take part in a Distributed Validator Cluster, you must ensure you have selected an execution client & consensus client on your DappNode under the 'Stakers' tab for the network you intend to validate.

1. Login to the DappNode Interface:

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-4c5a07921fc9685883e6b083e11d4d2c996e9425%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
2. Click on the 'Stakers' tab on the left side, select an execution client (e.g. Geth) & consensus client (e.g. Lodestar) & click 'Apply changes'. This will start the syncing process which can take a number of hours.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-0e418d6851d964d53e09567512d95c27bf04b542%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
3. Once the clients are finished syncing, it should reflect on your 'Dashboard' as shown below.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-59bed3662d8aea06a6f117edce95f77ae2870db6%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

**Install the Obol DappNode package**

With a fully synced Ethereum node now running on the DappNode, the below steps will walk through installing the Obol package via an IPFS hash and preparing for a Distributed Key Generation ceremony. Future versions of this guide will download the package from the official DappNode DappStore once a stable 1.0 release is made.

1. Before installing the package, make sure you are installing the correct one for Mainnet. You can find the link to the package below:
   * [Mainnet Repo](http://my.dappnode/installer/dnp/obol.dnp.dappnode.eth)
2. Copy the latest IPFS hash from the release details dropdown.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-83cf77b41c63c403f721391ade9b51e46c3bf5ae%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
3. Go back to DappNode Dashboard > Dappstore, select the 'Public' tab, and accept the terms & conditions before proceeding.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-d333c9eb09434db5e8e5d6c67e564ccc78810a00%2Fimage-67.png?alt=media" alt=""><figcaption></figcaption></figure>
4. Paste the IPFS hash you copied from Github and click 'Search' (It may take a minute for the package to be found.) You will then be presented with the package installation page. Under the blue 'Install' button, click on 'Advanced Options' & toggle the button to 'Bypass only signed safe restriction'.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-6a87435c384699d5ceae60158d396a9eb4ce666b%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
5. Click 'Install' & in the config mode page > select new cluster & submit. (if you already have the config URL, you can select URL option.)

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-d54d6660e9ef0edbfe80bf48954c2d03d6baf396%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
6. Accept the terms & conditions and the install process will begin.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-beddc192d6946a1be3769267b63f8a0371c16ca6%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-42826e33ba5455d397e9ea4131037c28a09bb7a4%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
7. You should now be able to see the Obol package under the 'Packages' tab. Click on the package to see important details.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-061467b893605788adbc4b8baa2b8c2d083e5d6b%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
8. Under the 'Info' tab, you will see pre-generated ENRs, along with information such as the status of all five distributed validator clusters, their docker volumes & other menu options.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-59599f6197637ef97743ef73d15912741f087175%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
9. Select any of the ENRs listed that are not already in use. This ENR will be used in the next step.

For Step 2 of the quickstart:

* Select the **Creator** tab if you are coordinating the creation of the cluster (this role holds no position of privilege in the cluster, it only sets the initial terms of the cluster that the other operators agree to).
* Select the **Operator** tab if you are accepting an invitation to operate a node in a cluster, proposed by the cluster creator.
  {% endtab %}

{% tab title="Sedge" %}
**Installing Sedge**

First you must install Sedge, please refer to the [official Sedge installation guide](https://docs.sedge.nethermind.io/docs/quickstart/install-guide) to do so.

**Check the install was successful**

Run the below command to check if your have successfully installed sedge in your computer.

```
sedge
```

Expected output:

```sh
A tool to allow deploying validators with ease.
  Usage:
    sedge [command]
  Available Commands:
    cli             Generate a node setup interactively
    clients         List supported clients
    deps            Manage dependencies
    down            Shutdown sedge running containers
    generate        Generate new setups according to selected options
    help            Help about any command
    import-key      Import validator keys
    keys            Generate keystore folder
    logs            Get running container logs
    networks        List supported networks
    run             Run services
    show            Show useful information about sedge running containers
    slashing-export Export slashing protection data
    slashing-import Import slashing protection data
    version         Print sedge version
  Flags:
    -h, --help               help for sedge
        --log-level string   Set Log Level, e.g panic, fatal, error, warn, warning, info, debug, trace (default "info")
  Use "sedge [command] --help" for more information about a command.
```

Create an ENR using charon:

```sh
# Use docker to create an ENR. Backup the file `.charon/charon-enr-private-key`.
docker run --rm -v "$(pwd):/opt/charon" obolnetwork/charon:v1.9.0 create enr
```

For Step 2 of the quickstart:

* Select the **Creator** tab if you are coordinating the creation of the cluster (this role holds no position of privilege in the cluster, it only sets the initial terms of the cluster that the other operators agree to).
* Select the **Operator** tab if you are accepting an invitation to operate a node in a cluster, proposed by the cluster creator.
  {% endtab %}

{% tab title="Helm" %}
In order to prepare for a distributed key generation ceremony, you need to create an ENR for your Charon client. When deploying with Helm, the chart can automatically generate an ENR and store it as a Kubernetes secret.

**1. Add the Obol Helm repository:**

```sh
helm repo add obol https://obolnetwork.github.io/helm-charts
helm repo update
```

**2. Install the chart with your operator address:**

```sh
helm install my-dv-pod obol/dv-pod \
  --set='charon.operatorAddress=<YOUR_OPERATOR_ADDRESS>' \
  --set='charon.beaconNodeEndpoints[0]=<BEACON_NODE_ENDPOINT>'
```

The chart will automatically generate an ENR private key and store it as a Kubernetes secret. The DKG sidecar init container will then poll the Obol API for cluster invites associated with your operator address.

**3. Retrieve your ENR to share with the cluster creator:**

```sh
kubectl get secret -l app.kubernetes.io/name=dv-pod -o jsonpath='{.items[0].data.enr}' | base64 -d
```

{% hint style="warning" %}
The ENR secret **must** be created in the same namespace where the Helm chart is installed. If the secret exists in a different namespace, the ENR job will regenerate a new key, potentially overriding your intended configuration.
{% endhint %}

{% hint style="info" %}
If you already have an ENR private key (e.g., generated via docker), you can provide it to the chart instead of auto-generating:

```sh
kubectl create secret generic charon-enr-private-key \
  --from-file=charon-enr-private-key=.charon/charon-enr-private-key
```

The chart will detect this existing secret and use it rather than generating a new one.
{% endhint %}

For Step 2 of the quickstart:

* Select the **Creator** tab if you are coordinating the creation of the cluster (this role holds no position of privilege in the cluster, it only sets the initial terms of the cluster that the other operators agree to).
* Select the **Operator** tab if you are accepting an invitation to operate a node in a cluster, proposed by the cluster creator.
  {% endtab %}
  {% endtabs %}

### Step 2: Create a cluster or accept an invitation to a cluster <a href="#step-2-create-a-cluster-or-accept-an-invitation-to-a-cluster" id="step-2-create-a-cluster-or-accept-an-invitation-to-a-cluster"></a>

{% tabs %}
{% tab title="Creator" %}
**Collect addresses, configure the cluster, share the invitation**

Before starting the cluster creation process, you will need to collect an Ethereum address for each operator in the cluster. They will need to be able to sign messages through MetaMask with this address. *(Broader wallet support will be added in future.)* With these addresses in hand, go through the cluster creation flow.

{% tabs %}
{% tab title="Launchpad" %}
You will use the Launchpad to create an invitation, and share it with the operators. This video shows the flow within the [DV Launchpad](https://docs.obol.org/next/learn/readme/launchpad)

{% embed url="<https://www.youtube.com/watch?v=6pXASqjAQbs>" %}

The following are the steps for creating a cluster.

1. Go to the [DV Launchpad](https://docs.obol.org/next/learn/readme/launchpad#dv-launchpad-links)
2. Connect your wallet

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-8d0c18c83e5305ab72b3dc19beb7f5b932040312%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
3. Select `Create a Cluster with a group` then `Get Started`.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-51bc14cb245f4d050408bf97b32b25bc1721785a%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
4. Follow the flow and accept the advisories.
5. Configure the Cluster
   1. Input the `Cluster Name` & `Cluster Size` (i.e. number of operators in the cluster). The threshold will update automatically, it shows the number of nodes that need to be functioning for the validator(s) to stay active.
6. Input the Ethereum addresses for each operator that you collected previously. If you will be taking part as an operator, click the "Use My Address" button for Operator 1.

   1. Select the desired amount of validators (32 ETH each) the cluster will run.
   2. If you are taking part in the cluster, enter the ENR you generated in [step one](#step-1-get-your-enr) in the "What is your charon client's ENR?" field.
   3. Choose the suitable withdrawal configuration:

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-ee992399aead529abe7c6e12f7abb19d7c690269%2FWithdrawalConfigurations.png?alt=media" alt=""><figcaption></figcaption></figure>

   * **Split only rewards**: Deploys an OVM contract as withdrawal address to a principal address of your choice, and a splitter as fee recipient. OVM is used to distribute amounts to principal and fee recipient. It requires two inputs:
     * **Owner address**: The Owner address is the super-admin of the OVM. It has access to all the roles - deposit, withdraw, distribute etc and it can also give roles to other addresses. For security purposes, it is recommended to either use a trusted address or a multi-sig wallet like [SAFE](https://app.safe.global/welcome/accounts) so all the transactions are approved by a quorum of addresses inside the SAFE. For testing purposes on Hoodi, [protofire](https://app.safe.protofire.io/home) can be used.
     * **Principal address**: This is the address that will receive the amount after the principal threshold amount is crossed. Read more about it [here](https://docs.obol.org/next/learn/readme/obol-splits#obol-validator-managers) where it is explained.
   * **Split Everything**: Deploys an OVM contract as withdrawal address, with principal and fee recipient addresses both as splitter contracts. In this case both principal and rewards are distributed. It just requires Owner address as input which is again recommended to be a SAFE wallet.
   * **Lido CSM**: Deploys the clusters with Lido's withdrawal vault as withdrawal address and execution vault as fee recipient. Read more about the process to register CSM cluster [here](https://docs.obol.org/next/run-a-dv/integrations/lido-csm).
   * **Custom**: Enter the `Principal address` which should receive the principal 32 ETH and the accrued consensus layer rewards when the validator is exited. This can optionally be set to the contract address of a multisig / splitter contract. Enter the `Fee Recipient address` to which the execution layer rewards will go. This can be the same as the principal address, or it can be a different address. This can optionally be set to the contract address of a multisig / splitter contract.
7. Click `Create Cluster Configuration`. Review that all the details are correct, and press `Confirm and Sign` You will be prompted to sign two or three transactions with your MetaMask wallet. These are:
   1. The `config_hash`. This is a hashed representation of the details of this cluster, to ensure everyone is agreeing to an identical setup.
   2. The `operator_config_hash`. This is your acceptance of the terms and conditions to participate as a node operator.
   3. Your `ENR`. Signing your ENR authorises the corresponding private key to act on your behalf in the cluster.
8. Share your cluster invite link with the operators. Following the link will show you a screen waiting for other operators to accept the configuration you created.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-f93189423fd9ab383804e681510c9c7e47472f7c%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
9. You can use the link to monitor how many of the operators have already signed their approval of the cluster configuration and submitted their ENR.

Once every participating operator is ready, the next step is the distributed key generation amongst the operators.

* If you are not planning on operating a node, and were only configuring the cluster for the operators, your journey ends here. Well done!
* If you are one of the cluster operators, continue to the next step.
  {% endtab %}

{% tab title="CDVN" %}
You will use the CLI to create the cluster definition file, which you will distribute it to the operators manually.

1. The leader or creator of the cluster will prepare the `cluster-definition.json` file for the Distributed Key Generation ceremony using the `charon create dkg` command.
2. Populate the `charon create dkg` command with the appropriate flags including the `name`, the `num-validators`, the `fee-recipient-addresses`, the `withdrawal-addresses`, and the `operator-enrs` of all the operators participating in the cluster.
3. Run the `charon create dkg` command that generates DKG cluster-definition.json file.

   ```sh
   docker run --rm -v "$(pwd):/opt/charon" obolnetwork/charon:v1.9.0 create dkg 

   --name="Quickstart" 

   --num-validators=1 

   --fee-recipient-addresses="0x0000000000000000000000000000000000000000" 

   --withdrawal-addresses="0x0000000000000000000000000000000000000000" 

   --operator-enrs="enr:-JG4QGQpV4qYe32QFUAbY1UyGNtNcrVMip83cvJRhw1brMslPeyELIz3q6dsZ7GblVaCjL_8FKQhF6Syg-O_kIWztimGAYHY5EvPgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQKzMe_GFPpSqtnYl-mJr8uZAUtmkqccsAx7ojGmFy-FY4N0Y3CCDhqDdWRwgg4u"
   ```

   This command should output a file at `.charon/cluster-definition.json` This file needs to be shared with the other operators in a cluster.

   * The `.charon` folder is hidden by default. To view it, run `ls -al .charon` in your terminal. Else, if you are on `macOS`, press `Cmd + Shift + .` to view all hidden files in the Finder application.

Once every participating operator is ready, the next step is the distributed key generation amongst the operators.

* If you are not planning on operating a node, and were only configuring the cluster for the operators, your journey ends here. Well done!
* If you are one of the cluster operators, continue to the next step.
  {% endtab %}
  {% endtabs %}
  {% endtab %}

{% tab title="Operator" %}
**Join the cluster prepared by the creator**

Use the Launchpad or CLI to join the cluster configuration generated by the creator:

{% tabs %}
{% tab title="Launchpad" %}
Your cluster creator needs to configure the cluster, and send you an invite URL link to join the cluster on the Launchpad. Once you've received the Launchpad invite link, you can begin the cluster acceptance process.

{% embed url="<https://www.youtube.com/watch?v=6pXASqjAQbs>" %}

1. Click on the DV launchpad link provided by the leader or creator. Make sure you recognise the domain and the person sending you the link, to ensure you are not being phished.
2. Connect your wallet using the Ethereum address the leader was provided.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-b8abd878274cc9b25b2113ad95664c24e771ffad%2Fimage-79.png?alt=media" alt=""><figcaption></figcaption></figure>
3. Review the operators addresses submitted and click `Get Started` to continue.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-3385dc654d6685d0b4132b1d83b1b0b76a1a603d%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
4. Review and accept the DV Launchpad terms & conditions and advisories.
5. Before accepting the invite and adding your ENR, ensure the following:

   <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p><strong>Important:</strong> Review these details carefully before proceeding. Once you accept the cluster configuration, you'll be committed to the withdrawal and fee recipient addresses set by the creator.</p></div>

   1. **Withdrawal address verification:**
      * If the withdrawal address is an OVM (Obol Validator Manager):
        1. Make sure it has the **OVM tag** to ensure it's the correct and official version of the audited contract.
        2. Ensure the **OVM owner** is correct. If it's a SAFE contract, verify the SAFE and all addresses inside the SAFE are as expected.
        3. Verify that all **roles are assigned correctly** if required. Note that the owner can edit roles even after accepting the cluster invite. If you require roles to be permanent, ensure ownership is renounced before accepting.
      * For more information on OVM roles, see the [OVM role assignment guide](https://docs.obol.org/next/advanced-and-troubleshooting/advanced/assign-ovm-roles).
   2. **Fee recipient verification:**
      * If the fee recipient is a splitter contract, ensure the **percentage of fee splits are correct**.
      * Just like OVM, fee recipient contracts also have an owner. Ensure that **ownership is revoked** if you want the shares to remain unchanged.
6. Review the cluster configuration set by the creator and add your `ENR` that you generated in [step 1](#step-1-get-your-enr).\\

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-f3bb24fe4028473c5d544ec104e723172927854f%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
7. Sign the two transactions with your wallet, these are:
   * The config hash. This is a hashed representation of all of the details for this cluster.
   * Your own `ENR` This signature authorises the key represented by this ENR to act on your behalf in the cluster.
8. Wait for all the other operators in your cluster to also finish these steps.

Once every participating operator is ready, the next step is the distributed key generation amongst the operators.

* If you are not planning on operating a node, and were only configuring the cluster for the operators, your journey ends here. Well done!
* If you are one of the cluster operators, continue to the next step.
  {% endtab %}

{% tab title="CDVN" %}
You'll receive the `cluster-definition.json` file created by the leader/creator. You should save it in the `.charon/` folder that was created initially. (Alternatively, you can use the `--definition-file` flag to override the default expected location for this file.)

Once every participating operator is ready, the next step is the distributed key generation amongst the operators.

* If you are not planning on operating a node, and were only configuring the cluster for the operators, your journey ends here. Well done!
* If you are one of the cluster operators, continue to the next step.
  {% endtab %}
  {% endtabs %}
  {% endtab %}
  {% endtabs %}

### Step 3: Run the Distributed Key Generation (DKG) ceremony <a href="#step-3-run-the-distributed-key-generation-dkg-ceremony" id="step-3-run-the-distributed-key-generation-dkg-ceremony"></a>

{% hint style="success" %}
For the [DKG](https://docs.obol.org/next/learn/charon/dkg) to complete, all operators need to be running the command simultaneously. It helps if operators can agree on a certain time or schedule a video call for them to all run the command together.
{% endhint %}

{% tabs %}
{% tab title="Launchpad" %}
{% embed url="<https://www.youtube.com/watch?v=cEMhxHuNJrI>" %}

1. Once all operators successfully signed, your screen will automatically advance to the next step and look like this. Click `Continue`. (If you closed the tab, you can always go back to the invite link shared by the leader and connect your wallet.)

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-9a75d72771f65f622c756c30487ff2c57f729a49%2Fimage-20.png?alt=media" alt=""><figcaption></figcaption></figure>
2. Copy and run the `docker` command on the screen into your terminal. It will retrieve the remote cluster details and begin the DKG process.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-ab0576557e73ecd40d72935d1224c2919c2a5992%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
3. Assuming the DKG is successful, a number of artefacts will be created in the `.charon` folder of the node. These include:
   * A `deposit-data.json` file. This contains the information needed to activate the validator on the Ethereum network.
   * A `cluster-lock.json` file. This contains the information needed by Charon to operate the distributed validator cluster with its peers.
   * A `validator_keys/` folder. This folder contains the private key shares and passwords for the created distributed validators.
     {% endtab %}

{% tab title="CDVN" %}
Once the creator gives you the `cluster-definition.json` file and you place it in a `.charon` subdirectory, run:

```sh
docker run --rm -v "$(pwd):/opt/charon" obolnetwork/charon:v1.9.0 dkg --publish
```

and the DKG process should begin.
{% endtab %}

{% tab title="DappNode" %}
Follow this step if you are signing through the DV Launchpad, importing the cluster definition URL into the DappNode package's config & then running the DKG inside the DappNode, followed by cluster run.

<figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-736f76c325f4daa8a321330c5190fa6b41e3fd55%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

1. After all operators have signed with their wallet and has provided an ENR from the DappNode info tab, the Launchpad will instruct operators to begin the DKG ceremony. Click continue & navigate to the 'Dappnode/Avado' tab where the cluster definition URL is presented.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-5832a2f30b7b036f9e01dc880682584d97dda7d1%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
2. To run the Distributed Key Generation ceremony using a DappNode, you must paste the cluster definition URL into the Obol Package interface. Go to the 'Config' tab, select 'URL' from the dropdown menu, paste the cluster definition URL you retrieved from the launchpad, into the validator `cluster-*`field which matches the cluster you took the ENR from. Example: If you picked ENR1 for signing, then you should paste the URL into Cluster-1. Finally, click the 'Update' button at the bottom of the page.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-1ebb002868ceb2c29b4ef0ae2e9751dfeff4619b%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-b9ca3193f846100c728da47383809bb569a9a573%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-39d4b75618399dae4cc2f185c40e96002fce1502%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
3. After DappNode records the cluster definition URL, go back to the 'Info' tab and restart the Charon container.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-d4d159e9981c94fbcec8783c4e85cf9d5728f9f5%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
4. The node is now ready and will attempt to complete the DKG. You can monitor the DKG progress via the 'Logs' tab of the package. Once all clients in the cluster can establish a connection with one another and they each complete a handshake (confirm everyone has a matching `cluster_definition_hash`), the key generation ceremony begins.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-458d86d906ff5c0dabf5041f5528f01bab256edf%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
5. Example of DKG ceremony competed log.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-e63a0bfc46b9ea7e1afa2e7c28b459d0ed12adb8%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

**Create a DV Node Backup**

It is important to back up all artefacts generated by the DKG ceremony, and your node ENR private key. The below steps will show you how to download your keys & node artefacts.

1. Navigate to the backup tab inside the Obol package.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-5625b972fc23bca46b57f7974bfaab78567031c9%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
2. Click on the 'Backup now' button and it will open a new chrome window with a 'file save' option. Select the path where you want to save the Backup tar file.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-f6fd63f8afed318467765ff023ede57e26676dc0%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>
3. Double click to extract the tar file. There will be folders for each charon node (max 5). Navigate to each node folder, and all artefacts related to each node will be present.

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-2a1d2593318b281f20de36d02a5710b5ec08f8db%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

   <figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-e50b84e69983f718ecb166db401c5bdf2d161e5d%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

{% endtab %}

{% tab title="Sedge" %}
Sedge does not currently support taking part in a DKG. Follow the instructions for **Launchpad** to take part in the DKG with Charon, and in Step 4 you will import these keys into Sedge.
{% endtab %}

{% tab title="Helm" %}
If you installed the Helm chart in Step 1 with the `charon.operatorAddress` parameter, the DKG sidecar will handle the ceremony automatically.

**Automatic DKG (recommended):**

The DKG sidecar init container continuously polls the Obol API for cluster invites associated with your operator address. Once all operators in the cluster have signed their approvals on the Launchpad, the sidecar will:

1. Detect the cluster invite
2. Run the DKG ceremony automatically
3. Store the generated artifacts (cluster-lock, validator keys) in the persistent volume

You can monitor the DKG progress by checking the pod logs:

```sh
kubectl logs my-dv-pod-0 -c dkg-sidecar -f
```

{% hint style="info" %}
If you want the sidecar to target a specific cluster definition, you can set the `targetConfigHash` parameter:

```sh
helm upgrade my-dv-pod obol/dv-pod \
  --reuse-values \
  --set='charon.dkgSidecar.targetConfigHash=0x...'
```

{% endhint %}

**Pre-existing artifacts:**

If you have already completed the DKG ceremony outside of Helm (e.g., via docker), you can provide the artifacts directly:

```sh
# Create a secret with the validator keystores
kubectl create secret generic validator-keys \
  --from-file=.charon/validator_keys/keystore-0.json \
  --from-file=.charon/validator_keys/keystore-0.txt

# Create a ConfigMap with the cluster lock file
kubectl create configmap cluster-lock \
  --from-file=.charon/cluster-lock.json

# Install or upgrade the chart with the pre-existing artifacts
helm upgrade --install my-dv-pod obol/dv-pod \
  --set='configMaps.clusterLock=cluster-lock' \
  --set='validatorClient.keystores.secretName=validator-keys' \
  --set='charon.beaconNodeEndpoints[0]=<BEACON_NODE_ENDPOINT>'
```

{% hint style="info" %}
For large cluster-lock files (>1MB), use the lock hash instead of a ConfigMap:

```sh
LOCK_HASH=$(jq -r '.lock_hash' .charon/cluster-lock.json)
helm upgrade my-dv-pod obol/dv-pod \
  --reuse-values \
  --set="charon.lockHash=$LOCK_HASH"
```

{% endhint %}
{% endtab %}
{% endtabs %}

{% hint style="danger" %}
Please make sure to create a backup of your `.charon/` folder. **If you lose your private keys you won't be able to start the DV cluster successfully and may risk your validator deposit becoming unrecoverable.** Ensure every operator has their `.charon` folder securely and privately backed up before activating any validators.
{% endhint %}

{% hint style="info" %}
The `cluster-lock` and `deposit-data` files are identical for each operator, if lost, they can be copied from one operator to another.
{% endhint %}

Now that the DKG has been completed, all operators can start their nodes.

### Step 4: Start your Distributed Validator Node <a href="#step-4-start-your-distributed-validator-node" id="step-4-start-your-distributed-validator-node"></a>

With the DKG ceremony over, the last phase before activation is to prepare your node for validating over the long-term.

The [CDVN repository](https://github.com/ObolNetwork/charon-distributed-validator-node) is configured to sync an execution layer client (`Nethermind`) and a consensus layer client (`Lighthouse`) using Docker Compose. Further client combinations can be prepared using Sedge. You can also leverage alternative ways to run a node such as Ansible, Helm, or Kubernetes manifests.

{% tabs %}
{% tab title="CDVN" %}
{% hint style="info" %}
Currently, the [CDVN repo](https://github.com/ObolNetwork/charon-distributed-validator-node) has defaults for the Hoodi testnet and for mainnet.
{% endhint %}

Start by copying the appropriate `.env.sample.<NETWORK>` file to `.env`, and modifying values as needed.

```sh
# To prepare the node for the Hoodi test network
# Copy ".env.sample.hoodi", renaming it ".env"
cp .env.sample.hoodi .env

# To prepare the node for the main Ethereum network
# Copy ".env.sample.mainnet", renaming it ".env"
cp .env.sample.mainnet .env
```

In the same folder where you created your ENR in Step 1, and ran the DKG in Step 3, start your node in the DV cluster with docker compose.

```sh

# To be run from the ./charon-distributed-validator-node folder
# Spin up a Distributed Validator Node with a Validator Client
docker compose up -d
```

{% hint style="danger" %}
Do not start this node until the DKG is complete, as the charon container will interfere with the charon instance attempting to take part in the DKG ceremony.
{% endhint %}

If at any point you need to turn off your node, you can run:

```sh
# Shut down the currently running Distributed Validator Node
docker compose down
```

You should use the Grafana dashboard that accompanies the quickstart repo to see whether your cluster is healthy.

```sh
# Open Grafana dashboard
open http://localhost:3000/d/charonoverview/
```

In particular you should check:

* That your Charon client can connect to the configured beacon client.
* That your Charon client can connect to all peers directly.
* That your validator client is connected to Charon, and has the private keys it needs loaded and accessible. Most components in the dashboard have some help text there to assist you in understanding your cluster performance. You might notice that there are logs indicating that a validator cannot be found and that APIs are returning 404. This is to be expected at this point, as the validator public keys listed in the lock file have not been deposited and acknowledged on the consensus layer yet (usually it takes \~16 hours after the deposit is made).
  {% endtab %}

{% tab title="Existing BN" %}
{% hint style="danger" %}
Using a remote beacon node will impact the performance of your Distributed Validator and should be used sparingly.
{% endhint %}

If you already have a beacon node running somewhere and you want to use that instead of running an EL (`nethermind`) & CL (`lighthouse`) as part of the example repo, you can disable these images. To do so, follow these steps:

1. Stop your docker compose

```sh
docker compose down
```

2. Uncomment and set the `CHARON_BEACON_NODE_ENDPOINTS` variable in the `.env` file to your beacon node's URL

```sh
...
# Connect to one or more external beacon nodes. Use a comma separated list excluding spaces.
CHARON_BEACON_NODE_ENDPOINTS=<YOUR_REMOTE_BEACON_NODE_URL>
...
```

{% hint style="info" %}
If your existing beacon node is running in a another CDVN instance on the same Docker host, you can access it by specifying `http://host.docker.internal:5052` as the endpoint. Note: You will need to change the charon p2p port in the .env file (`CHARON_PORT_P2P_TCP=`) of the second CDVN stack to avoid port conflict.
{% endhint %}

3. Uncomment `EL=el-none` and `CL=cl-none` variables in the `.env` file and comment `EL=el-nethermind` and `CL=cl-lighthouse` variables:

```sh
...
#EL=el-nethermind
...
EL=el-none
...
#CL=cl-lighthouse
...
CL=cl-none
...
```

4. Start your docker compose

```sh
docker compose up -d
```

{% endtab %}

{% tab title="Sedge" %}
To prepare a Distributed Validator node using sedge, we will use the `sedge generate` command to prepare a docker-compose file of our preferred clients, `sedge import-key` to import the artifacts created during the DKG ceremony, and `sedge run` to begin running the node.

**Sedge generate**

With Sedge installed, and the DKG complete, it’s time to deploy a Distributed Validator. Using the `sedge generate` command and its subcommands, Sedge will create a Docker Compose file needed to run the validator node.

1. The following command generates the artifacts required to deploy a distributed validator on the Hoodi network, using Teku as the validator client, Prysm as the consensus client, and Geth as the execution client. For additional supported client combinations, [refer to the documentation here](https://github.com/NethermindEth/sedge?tab=readme-ov-file#supported-networks-and-clients).

   ```sh
   sedge generate full-node --validator=teku --consensus=prysm --execution=geth --network=hoodi --distributed
   ```

   You should be shown a long list of configuration outputs with the following endings:

   ```sh
   2024-09-20 12:56:15 -- [INFO] Generation of files successfully, happy staking! You can use now 'sedge run' to start the setup.
   ```
2. Explore the config files.

   You should now see a `sedge-data` directory created in the folder where you ran the `sedge generate` command. To view the directory contents, use the `ls` command.

   ```sh
   ls sedge-data
   > docker-compose.yml jwtsecret
   ```

**Sedge Import-key**

Use the following command to import keys from the directory where the `.charon` dir is located.

```sh
sedge import-key --from ./ hoodi teku
```

**Sedge Run**

After confirming the configurations and ensuring all files are in place, use the `sedge run` command to deploy the DV docker containers. Sedge will then begin pulling all the required Docker images.

```sh
> sedge run
2024-09-20 13:11:49 -- [INFO] [Logger Init] Log level: info
2024-09-20 13:11:49 -- [WARN] A new Version of sedge is available. Please update to the latest Version. See https://github.com/NethermindEth/sedge/releases for more information. Latest detected tag: fatal: not a git repository (or any of the parent directories): .git
2024-09-20 13:11:50 -- [INFO] Setting up containers
2024-09-20 13:11:50 -- [INFO] Running command: docker compose -f /sedge/sedge-data/docker-compose.yml build
2024-09-20 13:11:50 -- [INFO] Running command: docker compose -f /sedge-data/docker-compose.yml pull
[+] Pulling 16/44
 ⠇ consensus [⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀] Pulling                                                                                                                                                     20.8s
   ⠙ b003b463d750 Downloading [===============>                                   ]   32.9kB/103.7kB                                                                                                14.2s
   ⠙ fe5ca62666f0 Waiting                                                                                                                                                                           14.2s
   ⠙ b02a7525f878 Waiting                                                                                                                                                                           14.2s
   ⠙ fcb6f6d2c998 Waiting                                                                                                                                                                           14.2s
   ⠙ e8c73c638ae9 Waiting                                                                                                                                                                           14.2s
   ⠙ 1e3d9b7d1452 Waiting                                                                                                                                                                           14.2s
   ⠙ 4aa0ea1413d3 Waiting                                                                                                                                                                           14.2s
   ⠙ 7c881f9ab25e Waiting                                                                                                                                                                           14.2s
   ⠙ 5627a970d25e Waiting                                                                                                                                                                           14.2s
   ⠙ 5cf83054c259 Waiting                                                                                                                                                                           14.2s
   ⠙ fec68abcb14d Waiting                                                                                                                                                                           14.2s
   ⠙ 4d5ad547ce94 Waiting                                                                                                                                                                           14.2s
   ⠙ e1ea80853e89 Waiting                                                                                                                                                                           14.2s
   ⠙ 17b1d7e8d99a Waiting                                                                                                                                                                           14.2s
   ⠙ 841a2fc14521 Waiting                                                                                                                                                                           14.2s
   ⠙ 55b44d28dd62 Waiting                                                                                                                                                                           14.2s
   ⠙ f3e3115c6547 Pulling fs layer                                                                                                                                                                  14.2s
   ⠙ 3cec53649029 Waiting                                                                                                                                                                           14.2s
   ⠙ 01739568079a Waiting                                                                                                                                                                           14.2s
   ⠙ c6bd24b188db Waiting                                                                                                                                                                           14.2s
   ⠙ fe8d2e9c9467 Waiting                                                                                                                                                                           14.2s
   ⠙ c151008cbec0 Waiting                                                                                                                                                                           14.2s
   ⠙ de1ef6c90686 Waiting                                                                                                                                                                           14.2s
   ⠙ 03d09d97b125 Waiting                                                                                                                                                                           14.2s
 ✔ execution Pulled                                                                                                                                                                                  9.3s
   ✔ a258b2a6b59a Pull complete                                                                                                                                                                      1.5s
   ✔ a2d6cf6afda3 Pull complete                                                                                                                                                                      1.7s
   ✔ a3dd8256fc41 Pull complete                                                                                                                                                                      6.9s
```

Once all docker images are pulled, sedge will create & start the containers to run all the required clients. See below for example output of the progress.

```sh
✔ 8db8b5d461a7 Pull complete                                                                                                                                                                     24.1s
   ✔ 2288b86b1d5f Pull complete                                                                                                                                                                     24.3s
   ✔ 4becb7b9a44b Pull complete                                                                                                                                                                     24.3s
   ✔ 4f4fb700ef54 Pull complete                                                                                                                                                                     24.3s
   ✔ 5c35e3728c84 Pull complete                                                                                                                                                                     35.1s
2024-09-20 13:12:45 -- [INFO] Running command: docker compose -f /sedge-data/docker-compose.yml create
[+] Creating 7/7
 ✔ Network sedge-network              Created                                                                                                                                                        0.1s
 ✔ Container sedge-dv-client          Created                                                                                                                                                        0.4s
 ✔ Container sedge-consensus-client   Created                                                                                                                                                        0.4s
 ✔ Container sedge-execution-client   Created                                                                                                                                                        0.4s
 ✔ Container sedge-mev-boost          Created                                                                                                                                                        0.4s
 ✔ Container sedge-validator-blocker  Created                                                                                                                                                        0.4s
 ✔ Container sedge-validator-client   Created                                                                                                                                                        0.1s
2024-09-20 13:12:45 -- [INFO] Running command: docker compose -f /sedge-data/docker-compose.yml up -d
[+] Running 4/5
 ✔ Container sedge-consensus-client   Started                                                                                                                                                        1.0s
 ⠧ Container sedge-validator-blocker  Waiting                                                                                                                                                      130.8s
 ✔ Container sedge-dv-client          Started                                                                                                                                                        1.0s
 ✔ Container sedge-execution-client   Started                                                                                                                                                        1.3s
 ✔ Container sedge-mev-boost          Started      
```

Given time, the execution and consensus clients should complete syncing, and if a Distributed Validator has already been activated, the node should begin to validate.

If you encounter issues with using Sedge as part of a DV cluster, consider consulting the [Sedge docs](https://docs.sedge.nethermind.io/) directly, or opening an [issue](https://github.com/NethermindEth/sedge/issues) or [pull request](https://github.com/NethermindEth/sedge/pulls) if appropriate.
{% endtab %}

{% tab title="Ansible" %}
Use an Ansible playbook to start your node. [See the repo here](https://github.com/ObolNetwork/obol-ansible) for further instructions.
{% endtab %}

{% tab title="Helm" %}
If you installed the Helm chart in Step 1 and the DKG completed automatically in Step 3, your Distributed Validator node is already running. You can verify its status with:

```sh
kubectl get pods
kubectl logs my-dv-pod-0 -c charon -f
```

**Key configuration options:**

You can customise your deployment by upgrading the release with additional parameters:

```sh
helm upgrade my-dv-pod obol/dv-pod \
  --reuse-values \
  --set='network=mainnet' \
  --set='charon.beaconNodeEndpoints[0]=<BEACON_NODE_ENDPOINT>' \
  --set='charon.builderApi=true' \
  --set='validatorClient.type=lighthouse'
```

The chart supports five validator client types: `lighthouse` (default), `teku`, `nimbus`, `lodestar`, and `prysm`.

**External validator client:**

If you prefer to run your own validator client outside the chart, disable the integrated one and point your external client at the Charon validator API:

```sh
helm upgrade my-dv-pod obol/dv-pod \
  --reuse-values \
  --set='validatorClient.enabled=false'
```

Your external validator client should connect to the Charon validator API as if it were a beacon node:

```
http://<RELEASE_NAME>.<NAMESPACE>.svc.cluster.local:3600
```

**Monitoring:**

Enable Prometheus service monitoring:

```sh
helm upgrade my-dv-pod obol/dv-pod \
  --reuse-values \
  --set='serviceMonitor.enabled=true'
```

**Uninstalling:**

```sh
helm uninstall my-dv-pod
```

{% hint style="danger" %}
Uninstalling the Helm release will remove all Kubernetes components. Ensure you have backed up your validator keys and cluster artifacts before uninstalling.
{% endhint %}

If you encounter issues, consult the [Helm chart documentation](https://github.com/ObolNetwork/helm-charts/tree/main/charts/dv-pod) or open an [issue](https://github.com/ObolNetwork/helm-charts/issues).
{% endtab %}

{% tab title="K8s" %}
Use Kubernetes manifests to start your Charon client and validator client. These manifests expect an existing Beacon Node Endpoint to connect to. [See the repo here](https://github.com/ObolNetwork/charon-k8s-distributed-validator-node) for further instructions.
{% endtab %}
{% endtabs %}

{% hint style="success" %}
In a Distributed Validator Cluster, it is important to have a low latency connection to your peers. Charon clients will use the NAT protocol to attempt to establish a direct connection to one another automatically. If this doesn't happen, you should port forward Charon's p2p port to the public internet to facilitate direct connections. The default port to expose is `:3610`. Read more about Charon's networking [here](https://docs.obol.org/next/learn/charon/charon-networking).
{% endhint %}

If you have gotten to this stage, every node is up, synced and connected, congratulations. You can now move forward to [activating your validator](https://docs.obol.org/next/run-a-dv/running/activate-a-dv) to begin staking.

### FAQ <a href="#faq" id="faq"></a>

<details>

<summary><strong>What happens if I lose my ENR private key?</strong></summary>

If you lose your ENR private key (`.charon/charon-enr-private-key`), you won't be able to participate in the DKG ceremony or start the DV cluster successfully. It's critical to back up this file securely before proceeding with the cluster creation process.

</details>

<details>

<summary><strong>Can I change the cluster configuration after it's been created?</strong></summary>

Once a cluster configuration has been created and signed by all operators, it cannot be changed. If you need to modify the cluster settings, you'll need to create a new cluster configuration and have all operators sign the new configuration.

</details>

<details>

<summary><strong>What if one operator doesn't show up for the DKG ceremony?</strong></summary>

All operators must participate simultaneously in the DKG ceremony for it to complete successfully. If an operator is unable to participate, you'll need to wait for them or create a new cluster configuration without that operator. It's recommended to schedule the DKG ceremony at a time when all operators can participate.

</details>

<details>

<summary><strong>How do I know if my node is properly connected to the cluster?</strong></summary>

You can verify your node's connection status by checking the Grafana dashboard (if using CDVN) or monitoring the Charon logs. Your Charon client should be able to connect to all peers directly, and you should see successful handshakes in the logs. The dashboard will show connection status for each peer in the cluster.

</details>

<details>

<summary><strong>What should I do if the DKG ceremony fails?</strong></summary>

If the DKG ceremony fails, check the logs for error messages. Common issues include network connectivity problems, mismatched cluster definitions, or operators not running the command simultaneously. Ensure all operators have the correct `cluster-definition.json` file and are running the DKG command at the same time. You may need to restart the DKG process after resolving any issues.

</details>

<details>

<summary><strong>Can I use different client combinations for different operators in the cluster?</strong></summary>

Yes, each operator can use different execution and consensus clients. The Charon client handles the coordination between different client implementations, so operators can choose the clients that work best for their infrastructure while still participating in the same distributed validator cluster.

</details>

<details>

<summary><strong>What happens if I need to replace an operator in the cluster?</strong></summary>

Replacing an operator can be done using the `charon alpha edit replace-operator` command for a single operator swap, or via validator consolidation when making larger changes. For more information, see the [replacing operators guide](https://docs.obol.org/next/run-a-dv/editing/replace-operator).

</details>

<details>

<summary><strong>How should I set the validator count for compounding rewards?</strong></summary>

We recommend setting the validator count such that each validator's maxEB is capped at 1920 ETH, allowing rewards to compound for two years until it reaches 2048 ETH. [**Read more**](#step-1-get-your-enr)

Unlike a standard bank account where interest compounds daily, validator rewards follow a step-function. Your effective balance (which earns rewards) only increases when your real balance exceeds the current effective balance by 1.25 ETH. This "hysteresis" means growth is slightly slower than pure continuous compounding, as 'dust' rewards sit idle until they accumulate enough to trigger a balance update.

**Recommendation: The 1920 ETH Strategy**

To maximize compounding efficiency, avoid depositing the full 2048 ETH cap immediately. Leaving \~128 ETH of "headroom" allows your validators to compound rewards autonomously for approximately 2 years (at 3% APR) before hitting the 2048 ETH effective balance cap.

<figure><img src="https://2241724632-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqEcekJHEGL3v8mnLzK2b%2Fuploads%2Fgit-blob-a54e720e46702920be13ef23972b33a3e4aff1c2%2FCompoundingRewardsCurve.png?alt=media" alt=""><figcaption></figcaption></figure>

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.obol.org/next/run-a-dv/start/create-a-dv-with-a-group.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
