---
# System prepended metadata

title: 'Council daemon v2 migration guide [Goerli]'

---

# Council daemon v2 migration guide [Goerli]


This guide describes how to migrate from Council deamon v1 to Council deamon v2.
This guide is for the **Goerli** test network.

## Table of contents
- [Changlelog](#Changelog)
- [Overview](#Overview)
- [Step by step guide](#Step-by-step-guide)

## Changelog
#### Staking Router support
Council daemon currently fetches keys from Node Operator Registry contract. In future validators set can be expanded with Community and DVT validators sets. In new protocol version Staking Router contract manages these different sets of validators. These sets implemented as Staking Modules of Staking Router. Currently only curated set (ode Operator Registry contract keys) exists. Council daemon v2 supports Staking Router contract.

#### Keys API

For fetching keys from diffent Staking Modules Council daemon v2 uses Keys API service. Keys API is a simple HTTP API to fetch keys from staking modules contracts. It stores keys in PostgreSQL database. To read more about Keys API check [document](https://hackmd.io/fv8btyNTTOGLZI6LqYyYIg?view)

#### Using a PostgreSQL database to store the key cache
The database is used as a caching layer of the Keys API. Since we will support a wide range of modules in the future, we need a database to store keys and other staking modules information in a more flexible way.

#### We now use RabbitMQ instead of Kafka
Using RabbitMQ is a step towards decentralization and reducing dependence on SaaS solutions.

## Overview

The deployment consists of two parts:
- Preparation of new infrastructure
- Waiting for the DAO vote

### Preparation of new infrastructure

Since the application was changed and it is important for us to keep the Consuls up and running during the upgrade, we need **to leave the old council-daemon v1 instance running** and start the new council-daemon v2.

You can read how to start a new build of the application in the [guide](https://github.com/lidofinance/lido-council-daemon/blob/develop/README.md). This document contains the configuration files and a short guide on how to run Council daemon v2. 


### Waiting for the DAO vote

In the result of voting council-daemon v2 will switch to Staking Router contract automatically and start handling deposits and pauses. Council-daemon v1 will handle deposits and pauses before voting. 

We have added the following logs to the application to check switching to new contracts.

```log
info: Contract address was changed {"address":"0x0000000000000000000000000000000000000000","contractKey":"contract:LidoAbi"}
info: Contract address was changed {"address":"0x0000000000000000000000000000000000000000","contractKey":"contract:SecurityAbi"}
info: Contract address was changed {"address":"0x0000000000000000000000000000000000000000","contractKey":"contract:StakingRouterAbi"}
```
Where it indicates that the contract addresses have changed. The addresses will be different, not as in the example.

## Step by step guide

### Run a **separate** instance
To update, we need to run a new build of the application (council-daemon v2) **without turning off** the old build (council-daemon v1).
In order to start a new build it is necessary to fill in the file with ENV variables. Below is an example to fill out. Data for RabbitMQ will be sent to your personal messages.

<details>
<summary>sample.env</summary>

```
# App
PORT=3000

# Log level: debug, info, notice, warning or error
LOG_LEVEL=info

# Log format: simple or json
LOG_FORMAT=simple

# Pubsub (default: rabbitmq)
PUBSUB_SERVICE=rabbitmq

# RabbitMQ
RABBITMQ_URL=wss://dsm.testnet.fi:443/ws
RABBITMQ_LOGIN=LOGIN_FROM_PERSONAL_MESSAGES
RABBITMQ_PASSCODE=PASSWORD_FROM_PERSONAL_MESSAGES

# Private key
# Used to sign transactions and stop the protocol.
# Make sure there are enough ETH on the balance to send a transaction to stop the protocol
WALLET_PRIVATE_KEY=0x0000000000000000000000000000000000000000000000000000000000000001

KEYS_API_HOST=http://keys_api_service_api

# Keys API
KEYS_API_PORT=3001

# chain id
# for mainnet 1
# for testnet 5
CHAIN_ID=5

RPC_URL=

# KeysAPI DB config
KEYS_API_DB_NAME=keys_service_db
KEYS_API_DB_PORT=5452
KEYS_API_DB_HOST=localhost
KEYS_API_DB_USER=test
KEYS_API_DB_PASSWORD=test

```
</details>

The completed configuration file must be named as `.env`
Next, take the docker-compose configuration file and put it next to the completed `.env` file.

<details>

<summary>docker-compose.yml</summary>

```yaml=
version: '3.7'

services:
  keys_api_service_db:
    image: postgres:14-alpine
    container_name: keys_api_service_db
    restart: unless-stopped
    environment:
      - POSTGRES_DB=${KEYS_API_DB_NAME}
      - POSTGRES_USER=${KEYS_API_DB_USER}
      - POSTGRES_PASSWORD=${KEYS_API_DB_PASSWORD}
    ports:
      - ${KEYS_API_DB_PORT}:5432
    volumes:
      - ./.volumes/pgdata-${CHAIN_ID}/:/var/lib/postgresql/data

  keys_api_service_api:
    image: lidofinance/lido-keys-api@sha256:996476f3c272fd74ba89b8e46ec2510bc5c07831ebb276ad661ddb00971f1a21
    container_name: keys_api_service_api
    ports:
      - '127.0.0.1:${KEYS_API_PORT}:3001'
    environment:
      - PORT=3001
      - LOG_LEVEL=${LOG_LEVEL}
      - LOG_FORMAT=${LOG_FORMAT}
      - CHAIN_ID=${CHAIN_ID}
      - PROVIDERS_URLS=${RPC_URL}
      - VALIDATOR_REGISTRY_ENABLE=false
      - DB_NAME=${KEYS_API_DB_NAME}
      - DB_PORT=5432
      - DB_HOST=keys_api_service_db
      - DB_USER=${KEYS_API_DB_USER}
      - DB_PASSWORD=${KEYS_API_DB_PASSWORD}
    depends_on:
      - keys_api_service_db

  council_daemon:
    image: lidofinance/lido-council-daemon@sha256:f9b1715aa4367821676a9cada0b6d159ace24a7f446da81e9c2838031e7bb5a9
    ports:
      - "127.0.0.1:${PORT}:3000" # port is used for prometheus metrics
    environment:
      - PORT=3000
      - LOG_LEVEL=${LOG_LEVEL}
      - LOG_FORMAT=${LOG_FORMAT}
      - RPC_URL=${RPC_URL}
      - WALLET_PRIVATE_KEY=${WALLET_PRIVATE_KEY}
      - KEYS_API_HOST=${KEYS_API_HOST}
      - KEYS_API_PORT=${KEYS_API_PORT}
      - PUBSUB_SERVICE=rabbitmq
      - RABBITMQ_URL=${RABBITMQ_URL}
      - RABBITMQ_LOGIN=${RABBITMQ_LOGIN}
      - RABBITMQ_PASSCODE=${RABBITMQ_PASSCODE}
    depends_on:
      - keys_api_service_api
    volumes:
      - ./.volumes/cache/:/council/cache/

```
</details>

After installing the docker-compose file and the .env configuration file, simply type the command:

```bash
docker-compose up -d
```

Next, we can read the log:
```bash
docker-compose logs -f
```

### **Don't disconnect** old instance (council-daemon v1)

In this step, it is important to make sure that you have not shut down the old application instance. We will let you know when you can turn it off.

### Check that the new instance (council-daemon v2) works
You may have errors in your logs but this should not interfere with the functionality of the application

### Stay tuned
After March 20th the Lido team will contact you and advise when you can disable the old instance
