---
# System prepended metadata

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

---

# Council daemon v2 migration guide [Goerli]


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

## Table of contents
- [Changelog](#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 (Node Operator Registry contract keys) exists. Council daemon v2 supports Staking Router contract.

#### Keys API

For fetching keys from different 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 a database. To read more about Keys API check [document](https://hackmd.io/@lido/B1aCdW6Lo)

#### Using a 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:
- Run additional Council daemon
- Wait for the protocol upgrade

### Run additional Council daemon

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. 


### Wait for the protocol upgrade

In the result of voting for the protocol upgrade to v2, 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, where they indicate that the contract addresses have changed.

```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"}
```
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. There is an example below 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. The same as you use for the current version
WALLET_PRIVATE_KEY=0x0000000000000000000000000000000000000000000000000000000000000001

# Keys API
KEYS_API_PORT=3001

# Goerli chain id
CHAIN_ID=5

# EL node url in format http://node.eth (without end slash)
RPC_URL=http://YOUR_NODE.eth

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

```
</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:fd264c3315197c5d70666ad98f182475d9b952342d09142b954f93e77ce3b71a
    container_name: keys_api_service_api
    restart: unless-stopped
    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:4fa0c4ebf56bf3382266debfc3d7e860530d7439129f0cc0f5fbdc8f3e1779eb
    restart: unless-stopped
    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=http://keys_api_service_api
      - KEYS_API_PORT=3001
      - 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 we will enact the vote and advise when you can disable the old instance.
