Skip to content
chasingrainbows edited this page Nov 13, 2025 · 2 revisions

Welcome to the lido-oracle wiki!

Release Page: Lido Oracle

🟢 Mainnet

Oracle - v6.0.3

Dockerhub digest
sha256:88c67a75ece2f483d7d91a9f36d0a17e6da4224041327a6fdde9c69679b7ee45

Commit hash:
87419df85fe1b6c0ed21b4f38e03691843ecba7b

🟡 Testnet

Oracle - v7.0.0-beta-3

Dockerhub digest
sha256:4e36e77f4d22a8ff13f48e46112c4c51039232c1b8c7932c3c678cfd7ae50461

Commit hash:
d6c09a16736b2c132343a4e349c8f27179c73e6e

Keys API

Dockerhub digest:
sha256:f8ce1d8828c99af22bba112ef23c0d235534a1436d8e4ba46f368c636f1c4bc9
Commit hash:
99d4d4d99878a192028bb391251976d7fce53ba8

📋 Required variables

Blockchain basics

Name Notes
EXECUTION_CLIENT_URI URL to execution node. Supports fallbacks
CONSENSUS_CLIENT_URI URL to consensus node. Supports fallbacks
KEYS_API_URI URL to Keys API service. Supports fallbacks
LIDO_LOCATOR_ADDRESS Lido Locator smart contract address.
MEMBER_PRIV_KEY If no key provided, Oracle starts in DRY mode.
MEMBER_PRIV_KEY_FILE File with private key. Can be used instead of MEMBER_PRIV_KEY.

IPFS

Name Notes
PINATA_DEDICATED_GATEWAY_URL URL of the dedicated Pinata gateway (required for Pinata provider, fallback to public gateway if dedicated fails)
PINATA_DEDICATED_GATEWAY_TOKEN Token for accessing dedicated Pinata gateway (required for Pinata provider)
PINATA_JWT Pinata IPFS provider. JWT token
STORACHA_SPACE_DID Storacha IPFS provider. Space DID identificator
STORACHA_AUTHORIZATION Storacha IPFS provider. Authorization token
STORACHA_AUTH_SECRET Storacha IPFS provider. Secret key
LIDO_IPFS_HOST Host to access Lido IPFS cluster
LIDO_IPFS_TOKEN Bearer token for Lido IPFS cluster authentication

CSM variables

Name Notes
CSM_MODULE_ADDRESS Community Staking Module Address

Envs full list.

🔧 Upgrade flow

This guide provides a generalized process for transitioning from an existing Oracle version to a newer version. The goal is to ensure zero downtime, with the old version continuing to run uninterrupted while the new version is tested in a non-disruptive mode.
  • Keep Oracle [current_version] on host running and ensure it must not be interrupted.
  • Start Oracle [new_version] on host alongside Oracle [current_version]. Copy all current configuration variables as-is from [current_version] to [new_version]. Verify that required ENV variables are provided to all Oracle modules.
  • Run Oracle [new_version] in DRY mode to check if the protocol has been upgraded, while [current_version] operates normally.
  • Once the upgrade is confirmed successful in DRY mode, [current_version] can then be shut down and eventually removed, while [new_version] continues to operate in production mode.

ℹ️ Additional information

Check Oracle's setup is ready

Run command with docker
docker run -it --env-file .env lidofinance/oracle@sha256:636bd89ef85e59ba6cf8c97b75deb8006fdd5d3043611344959c71a5bd70306d check

or in pure python

poetry run python src.main check

image

System requirements

Per Oracle type (Accounting, Ejector, CSM): - vCPU - 1 - Memory - 8 GB

Keys API:

  • vCPU - 1
  • Memory - 4 GB

Execution Client Node

To prepare the report, Oracle fetches up to 28 days old events, makes historical requests for balance data and makes simulated reports on historical blocks. This requires an [archive](https://ethereum.org/en/developers/docs/nodes-and-clients/#archive-node) execution node. Oracle needs 45 days of archived data.
Client Tested Notes
Geth 🟢 --gcmode=archive
--syncmode=snap

OR

--gcmode=archive
--syncmode=full
Nethermind 🔴 Not tested yet
Besu 🔴 Recent changes require FULL sync
Erigon 🟢 Use
--prune=rhtc
--prune.r.older=324000
--prune.h.older=324000
--prune.t.older=256
--prune.c.older=256
params

Consensus Client Node

Also, to calculate some metrics for bunker mode Oracle needs [archive](https://ethereum.org/en/developers/docs/nodes-and-clients/#archive-node) consensus node.
Client Tested Notes
Lighthouse Use --reconstruct-historic-states param
Lodestar Not tested yet
Nimbus Not tested yet
Prysm Use
--grpc-max-msg-size=104857600
--enable-historical-state-representation=true
--slots-per-archive-point=1024
[--enable-debug-rpc-endpoints (if <5.1.0)]
params
Teku Use
--data-storage-mode=archive
--data-storage-archive-frequency=1024
--reconstruct-historic-states=true
params

Docker compose example

version: '3'

##
# env variables:
# CONSENSUS_CLIENT_URI
# EXECUTION_CLIENT_URI
# KEYS_API_DB_PASSWORD
# KEYS_API_CHAIN_ID
# LIDO_LOCATOR_ADDRESS
# CSM_MODULE_ADDRESS
# PINATA_JWT
# PINATA_DEDICATED_GATEWAY_URL
# PINATA_DEDICATED_GATEWAY_TOKEN
# STORACHA_SPACE_DID
# STORACHA_AUTHORIZATION
# STORACHA_AUTH_SECRET
# LIDO_IPFS_HOST
# LIDO_IPFS_TOKEN
##
services:
  lido-keys-api-db:
    image: postgres:14-alpine
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: 1m
        max-file: "1"
    deploy:
      resources:
        limits:
          cpus: "1"
          memory: 4G
    labels:
      - "prometheus-job=lido-keys-api-db"
    environment:
      - "POSTGRES_DB=keys-api-db"
      - "POSTGRES_USER=keys-api-user"
      - "POSTGRES_PASSWORD=${KEYS_API_DB_PASSWORD}"
    volumes:
      - ./lido-keys-api/db/:/var/lib/postgresql/data

  lido-keys-api:
    image: lidofinance/lido-keys-api:dev
    restart: unless-stopped
    depends_on:
      - lido-keys-api-db
    deploy:
      resources:
        limits:
          cpus: "2"
          memory: 3G
    labels:
      - "prometheus-job=lido-keys-api"
      - "prometheus-endpoint=/metrics"
      - "prometheus-port=3000"
    environment:
      - "NODE_ENV=testnet"
      - "LOG_LEVEL=info"
      - "LOG_FORMAT=json"
      - "PORT=3000"
      - "PROVIDERS_URLS=${EXECUTION_CLIENT_URI}"
      - "CHAIN_ID=${KEYS_API_CHAIN_ID}"
      - "DB_PORT=5432"
      - "DB_HOST=lido-keys-api-db"
      - "DB_NAME=keys-api-db"
      - "DB_USER=keys-api-user"
      - "DB_PASSWORD=${KEYS_API_DB_PASSWORD}"
      - "CL_API_URLS=${CONSENSUS_CLIENT_URI}"
      - "VALIDATOR_REGISTRY_ENABLE=False"
    ports:
      - '3000:3000'

  lido-oracle-accounting:
    image: lidofinance/oracle:dev
    restart: unless-stopped
    depends_on:
      - lido-keys-api
    deploy:
      resources:
        limits:
          cpus: "1"
          memory: 4G
    labels:
      - "prometheus-job=lido-oracle-accounting"
      - "prometheus-endpoint=/"
      - "prometheus-port=9000"
    environment:
      - "PROMETHEUS_PORT=9000"
      - "EXECUTION_CLIENT_URI=${EXECUTION_CLIENT_URI}"
      - "CONSENSUS_CLIENT_URI=${CONSENSUS_CLIENT_URI}"
      - "KEYS_API_URI=http://lido-keys-api:3000"
      - "MEMBER_PRIV_KEY=${MEMBER_PRIV_KEY}"
      - "LIDO_LOCATOR_ADDRESS=${LIDO_LOCATOR_ADDRESS}"
      - "ALLOW_REPORTING_IN_BUNKER_MODE=false"
      - "PINATA_DEDICATED_GATEWAY_URL=${PINATA_DEDICATED_GATEWAY_URL}"
      - "PINATA_DEDICATED_GATEWAY_TOKEN=${PINATA_DEDICATED_GATEWAY_TOKEN}"
      - "PINATA_JWT=${PINATA_JWT}"
      - "STORACHA_SPACE_DID=${STORACHA_SPACE_DID}"
      - "STORACHA_AUTH_SECRET=${STORACHA_AUTH_SECRET}"
      - "STORACHA_AUTHORIZATION=${STORACHA_AUTHORIZATION}"
      - "LIDO_IPFS_HOST=${LIDO_IPFS_HOST}"
      - "LIDO_IPFS_TOKEN=${LIDO_IPFS_TOKEN}"
    command: accounting

  lido-oracle-ejector:
    image: lidofinance/oracle:dev
    restart: unless-stopped
    depends_on:
      - lido-keys-api
    deploy:
      resources:
        limits:
          cpus: "1"
          memory: 4G
    labels:
      - "prometheus-job=lido-oracle-ejector"
      - "prometheus-endpoint=/"
      - "prometheus-port=9000"
    environment:
      - "PROMETHEUS_PORT=9000"
      - "EXECUTION_CLIENT_URI=${EXECUTION_CLIENT_URI}"
      - "CONSENSUS_CLIENT_URI=${CONSENSUS_CLIENT_URI}"
      - "KEYS_API_URI=http://lido-keys-api:3000"
      - "MEMBER_PRIV_KEY=${MEMBER_PRIV_KEY}"
      - "LIDO_LOCATOR_ADDRESS=${LIDO_LOCATOR_ADDRESS}"
      - "PINATA_DEDICATED_GATEWAY_URL=${PINATA_DEDICATED_GATEWAY_URL}"
      - "PINATA_DEDICATED_GATEWAY_TOKEN=${PINATA_DEDICATED_GATEWAY_TOKEN}"
      - "PINATA_JWT=${PINATA_JWT}"
      - "STORACHA_SPACE_DID=${STORACHA_SPACE_DID}"
      - "STORACHA_AUTH_SECRET=${STORACHA_AUTH_SECRET}"
      - "STORACHA_AUTHORIZATION=${STORACHA_AUTHORIZATION}"
      - "LIDO_IPFS_HOST=${LIDO_IPFS_HOST}"
      - "LIDO_IPFS_TOKEN=${LIDO_IPFS_TOKEN}"
    command: ejector

  lido-oracle-csm:
    image: lidofinance/oracle:dev
    restart: unless-stopped
    depends_on:
      - lido-keys-api
    deploy:
      resources:
        limits:
          cpus: "2"
          memory: 4G
    labels:
      - "prometheus-job=lido-oracle-ejector"
      - "prometheus-endpoint=/"
      - "prometheus-port=9000"
    environment:
      - "PROMETHEUS_PORT=9000"
      - "EXECUTION_CLIENT_URI=${EXECUTION_CLIENT_URI}"
      - "CONSENSUS_CLIENT_URI=${CONSENSUS_CLIENT_URI}"
      - "KEYS_API_URI=http://lido-keys-api:3000"
      - "MEMBER_PRIV_KEY=${MEMBER_PRIV_KEY}"
      - "LIDO_LOCATOR_ADDRESS=${LIDO_LOCATOR_ADDRESS}"
      - "CSM_MODULE_ADDRESS=${CSM_MODULE_ADDRESS}"
      - "PINATA_DEDICATED_GATEWAY_URL=${PINATA_DEDICATED_GATEWAY_URL}"
      - "PINATA_DEDICATED_GATEWAY_TOKEN=${PINATA_DEDICATED_GATEWAY_TOKEN}"
      - "PINATA_JWT=${PINATA_JWT}"
      - "STORACHA_SPACE_DID=${STORACHA_SPACE_DID}"
      - "STORACHA_AUTH_SECRET=${STORACHA_AUTH_SECRET}"
      - "STORACHA_AUTHORIZATION=${STORACHA_AUTHORIZATION}"
      - "LIDO_IPFS_HOST=${LIDO_IPFS_HOST}"
      - "LIDO_IPFS_TOKEN=${LIDO_IPFS_TOKEN}"
    command: csm