|
| 1 | +# Claude Agent Guide: lido-charon-distributed-validator-node (LCDVN) |
| 2 | + |
| 3 | +This repo is the Docker Compose launcher for one node of an Obol Distributed Validator (DV) cluster operating inside the **Lido Simple DVT module** (staking module ID 2 on mainnet). It is a near-twin of `charon-distributed-validator-node` (CDVN) with Lido-specific additions: the `validator-ejector` service and the Lido EasyTrack / oracle wiring. |
| 4 | + |
| 5 | +> This repo is a **deployment guide, not a canonical deployment**. Lido Simple DVT operators are expected to fork/clone and adapt for their own ops — version-pin client images, tune monitoring, add HA, etc. Don't treat it as turnkey production config. |
| 6 | +
|
| 7 | +For non-Lido DV operators use `charon-distributed-validator-node` instead. Module coverage: **Simple DVT only**. Lido CSM and stVault are **not** yet optimised for this repo. |
| 8 | + |
| 9 | +## Quickstart |
| 10 | + |
| 11 | +```bash |
| 12 | +# Pick a network |
| 13 | +cp .env.sample.hoodi .env # or .env.sample.mainnet |
| 14 | + |
| 15 | +# If using commit-boost (instead of mev-boost): |
| 16 | +cp commit-boost/config.toml.sample.hoodi commit-boost/config.toml |
| 17 | + |
| 18 | +# Edit .env to set your Lido-specific values (see below), client selection, monitoring. |
| 19 | +# Drop a completed .charon/ (from DKG) into the repo root. |
| 20 | +docker compose up -d |
| 21 | +docker compose logs -f charon |
| 22 | +``` |
| 23 | + |
| 24 | +**Prerequisite:** a `.charon/` directory from a completed DKG ceremony must exist in the repo root before start. No DKG yet → run one via [launchpad.obol.org](https://launchpad.obol.org) first. |
| 25 | + |
| 26 | +## Mandatory Lido-specific env vars |
| 27 | + |
| 28 | +All exist in `.env.sample.*` — uncomment and set: |
| 29 | + |
| 30 | +| Var | What | Where to find | |
| 31 | +|-----|------|---------------| |
| 32 | +| `VE_OPERATOR_ID` | Your Lido Simple DVT operator ID | [operators.lido.fi](https://operators.lido.fi) (mainnet) / Lido testnet dashboard (hoodi) | |
| 33 | +| `VE_EASY_TRACK_MOTION_CREATOR_ADDRESSES_ALLOWLIST` | Your cluster's Lido Operator SAFE manager address(es), JSON array | The SAFE you registered with Lido when onboarding | |
| 34 | +| `VE_STAKING_MODULE_ID` | Pre-set to `2` (Simple DVT) — don't change | `.env.sample.*` | |
| 35 | +| `VE_LOCATOR_ADDRESS`, `VE_ORACLE_ADDRESSES_ALLOWLIST`, `VE_EASY_TRACK_ADDRESS` | Lido contract addresses for the network | Pre-populated per network in the env samples — treat as config, not secret | |
| 36 | + |
| 37 | +To enable Obol's log collection (helps the core team diagnose cluster issues), uncomment `MONITORING=${MONITORING:-monitoring},monitoring-log-collector`. |
| 38 | + |
| 39 | +## validator-ejector |
| 40 | + |
| 41 | +Lido publishes validator exit signals via on-chain oracles. The `validator-ejector` service in this stack watches the CL/EL, listens for signed exit messages targeting this operator, and forwards them to the DV so Charon + VCs can cooperate to exit the validator. This is the **key Lido-specific piece** — without it, a DV running under Lido Simple DVT can't honour Lido's exit protocol and risks slashing or socialised losses. |
| 42 | + |
| 43 | +If `validator-ejector` won't start or logs oracle-address mismatches, double-check `VE_ORACLE_ADDRESSES_ALLOWLIST` against the network's Lido deployment (they rotate occasionally). |
| 44 | + |
| 45 | +## Client stack (same shape as CDVN) |
| 46 | + |
| 47 | +Modular via `.env` knobs: `EL`, `CL`, `VC`, `MEV`. Defaults ship reasonable choices per network. |
| 48 | + |
| 49 | +> **Pick non-default clients where you can.** Same reasoning as CDVN — every operator running defaults deepens client supermajorities and raises correlated-failure risk for Ethereum and for the cluster. Within a Lido Simple DVT cluster, coordinate with your co-operators (step 6 of the README): pick EL/CL/VC combinations *different* from theirs so a single client bug can't take the whole cluster offline. |
| 50 | +
|
| 51 | +## Networks |
| 52 | + |
| 53 | +Env samples shipped: `.env.sample.mainnet`, `.env.sample.hoodi`. |
| 54 | + |
| 55 | +- **mainnet** — Lido Simple DVT live module, `VE_STAKING_MODULE_ID=2`. |
| 56 | +- **hoodi** — Lido's current testnet target. |
| 57 | + |
| 58 | +The README still mentions `.env.sample.holesky` — this is **stale**. Holesky is dead; the sample doesn't ship and shouldn't be used. |
| 59 | + |
| 60 | +## Compose layout |
| 61 | + |
| 62 | +Same structure as CDVN, plus Lido-specific services: |
| 63 | + |
| 64 | +- `docker-compose.yml` — Charon, validator-ejector, monitoring base. |
| 65 | +- `compose-el.yml` / `compose-cl.yml` / `compose-vc.yml` / `compose-mev.yml` — client variants wired via `EL`/`CL`/`VC`/`MEV` in `.env`. |
| 66 | +- `compose-monitoring.yml`, `compose-debug.yml` — observability add-ons. |
| 67 | +- `commit-boost/` — commit-boost config samples per network (requires `MEV=mev-commitboost`). |
| 68 | +- `alloy/` — log-collection config. |
| 69 | + |
| 70 | +## Standard workflows |
| 71 | + |
| 72 | +### Verify cluster health after setup |
| 73 | +```bash |
| 74 | +docker compose exec charon charon alpha test <beacon|validator|peers|infra> |
| 75 | +``` |
| 76 | +Use the global `test-a-dv-cluster` skill to interpret failures. |
| 77 | + |
| 78 | +### Update to a new release |
| 79 | +```bash |
| 80 | +docker compose down |
| 81 | +git stash # save local .env / custom overrides |
| 82 | +git pull |
| 83 | +git checkout v0.X.Y # pin to a release tag |
| 84 | +git stash apply |
| 85 | +docker compose up -d |
| 86 | +``` |
| 87 | + |
| 88 | +### Switching a client |
| 89 | +Same as CDVN: `docker compose down`, edit the `EL`/`CL`/`VC`/`MEV` line in `.env`, `docker compose up -d`. For commit-boost, also update `commit-boost/config.toml`. |
| 90 | + |
| 91 | +## Monitoring & alerts |
| 92 | + |
| 93 | +Same stack as CDVN: Prometheus + Grafana + Loki + Alloy. Remote-write and Loki push target Obol's hosted monitoring; Discord alerts via `ALERT_DISCORD_IDS`. See the `obol-monitoring` skill for deep diagnostics. |
| 94 | + |
| 95 | +Lido operators should keep `monitoring-log-collector` enabled so the core team can correlate validator-ejector / exit issues across the Simple DVT module. |
| 96 | + |
| 97 | +## Ports |
| 98 | + |
| 99 | +Charon: 3600 (validator API) / 3610 (p2p tcp) / 3620 (metrics). EL/CL ports overridable via `EL_PORT_*` / `CL_PORT_*` env vars. |
| 100 | + |
| 101 | +## Deployment best practices |
| 102 | + |
| 103 | +Obol maintains a [deployment best practices guide](https://docs.obol.org/run-a-dv/prepare/deployment-best-practices) covering hardware sizing, networking, monitoring, backups, key handling, and operational hygiene. **Proactively offer to audit the user's setup against it** — walk through `.env` values, client pinning, monitoring + Discord alerting, `validator-ejector` health, and `.charon/` backup posture, then surface concrete improvements. Lido Simple DVT operators are held to a higher reliability bar than solo DVs (socialised slashing risk, exit-protocol SLAs), so the review should weight monitoring coverage and exit-path readiness heavily. |
| 104 | + |
| 105 | +## Related products |
| 106 | + |
| 107 | +- **`charon-distributed-validator-node`** — (CDVN) non-Lido stock DV stack. Same shape, simpler config. |
| 108 | +- **Obol Stack + `helm-charts/charts/dv-pod`** — Kubernetes-native path; Lido SDVT operators running on k8s should evaluate this. |
| 109 | +- **DappNode** (`dappnode/DAppNodePackage-obol-generic`) — third-party package to run a DV on a DappNode. |
| 110 | + |
| 111 | +## Key docs |
| 112 | + |
| 113 | +- Obol: https://docs.obol.org/docs/int/key-concepts |
| 114 | +- Obol errors: https://docs.obol.org/docs/faq/errors |
| 115 | +- Lido Simple DVT: https://operators.lido.fi/modules/simple-dvt |
| 116 | +- validator-ejector (Lido): https://github.com/lidofinance/validator-ejector |
| 117 | +- Deployment best practices: https://docs.obol.org/run-a-dv/prepare/deployment-best-practices |
| 118 | +- Launchpad: https://launchpad.obol.org |
| 119 | +- Canonical agent index: https://obol.org/llms.txt |
0 commit comments