Validator guide

This page describes how to become a Stroom Network validator

TODO

Validator Node Provisioning Open Questions

There are the following options available for the node provisioning for users

  • Provide sources + build instructions

  • Provide binaries created for different platforms

  • Provide docker images

Such as we don't have a clear vision of our partners infrastructures and strict requirements to run the node on bare metal instances we would take the third option as most convenient to start with.

(?) Are we going to publish this image as public one? From the one hand we don't have any secret information there but from the other – it would be better to authorize users to pull the image. Also, there are 2 repos for docker images.

TODO: research options to grant access to private docker images in repositories. And choose one of the next repos as one to store images DockerHub vs AWS ECR vs AWS S3 (we can share here presigned links to download files i.e. docker images). If we decide to make images public I propose to publish them to DockerHub as the most convenient option for users to pull there

Stroom Network Overview

Stroom.network is a liquid staking protocol for Bitcoin, where yield is derived from Lightning Network transaction fees. The liquid token is issued on the Ethereum blockchain. Staked Bitcoin liquidity is kept in the custody of a permissioned decentralized network of validating nodes powered by the FROST protocol.

FROST protocol is a round-optimized threshold signing algorithm for Schnorr signatures. Schnorr signatures offer several benefits:

  • smaller signature sizes

  • faster verification times

  • has been formally proven to be resistant to any attack.

  • The most significant benefit of Schnorr signatures is its linear structure. It allows key aggregation— the ability to aggregate multiple signatures into one signature that is valid for the sum of its keys.

Due to linear structure, Schnorr signatures enable native and efficient multisig - multiple collaborating parties to produce a signature that is valid for the sum of their public keys.

In turn, FROST enables the production of a Schnorr signature valid for the given network by consuming a threshold (t) number of signatures for a number of participants (n). Usually, the threshold is defined as

t = [2/3 * n] + 1

Any transaction for being published to the blockchain must be signed by at least 2/3 + 1 participants, which provides BFT-style security guarantees.

There are two node types within the Stroom Network:

  • Executor node: a static leader for every voting round and transaction relayer; it has the authority to sign FROST messages. It also provides API for frontend and external calls. Managed by the Stroom team.

  • Validator node: network participant with authority to sign (approve or reject) FROST messages. Managed by Stroom partners.

The purpose of this document is to provide a guide on validator node setup. It is recommended to have a self-hosted Ethereum node hosted close to the go-stroom validator.

Ethereum Node

The Stroom node should be provided a PRC endpoint URL for the Ethereum node running within the given Ethereum network (Sepolia for testnet). It's used to query Stroom smart contracts and track events. Technically, you can use any publicly available RPC provider. However, using a self-hosted full node for the mainnet is strongly encouraged.

Also, the Stroom team has a hosted Ethereum node available via (TODO add eth url)

Bitcoin and Lightning Nodes

The Stroom team manages the Bitcoin node connected to the Bitcoin testnet network and three Lightning nodes on top of it for testing purposes. In the current implementation of the network, all Stroom network validators should be connected to the same Lightning node for correct balance calculation and tracking events on the Bitcoin blockchain. In the upcoming upgrade, each validator node will be required to have access to its own Bitcoin full node.

TODO: provide LND details (url, macaroons ). Macaroons upload to s3?

Pre-Requirements

  • Host machine with Docker installed (TODO add hardware requirements)

Node Keys generation

All Stroom network validators should securely generate public-private key pair and share their public key with all other validators during the network setup ceremony. This ceremony is specifically designed to generate common validators' public key, that will be used to check signatures against it.

So it's required to generate a valid Schnorr keys for signing transactions. Please see details at https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#design

Stroom team provides a simple tool to easily generate such keys:

docker run stroomnetwork/key-generator:v0.0.1 --network=signet

It'll print keys to the console.

Persistence

The Stroom node stores the state using the Postgres database so that one should be provided. Postgres setup is out of the scope of this guide and is the responsibility of the validators.

Also, please see the details in the example.

Network Setup Ceremony

TODO: describes how the network setup should look like

Docker Compose Example

services:
    stroom-validator-node:
      image: public.ecr.aws/g3y5i1b4/stroom-validator:v0.0.203
      command:
        - --bitcoin.lnd-rpc-host=bob-lnd.testnet.stroom.ninja:10009
        - --bitcoin.lnd-tls-path=/creds/lnd-stroom-bob-tls.cert
        - --bitcoin.lnd-macaroon-path=/creds/lnd-stroom-bob-readonly.macaroon
        - --ethereum.node-raw-url=https://ethereum.test.stroom.network
        - --ethereum.lnbtc-contract-address=0xb2cA0D6a50AB8daAe0B8729D4bA98D4ca757Bcf3
        - --ethereum.slnbtc-contract-address=0x3c79AaEDfcB80874fDc179a0A3A3A2EE8fEB778d
        - --db.user=postgres
        - --db.password=postgres
        - --db.host=stroom-validator-node-db
        - --db.port=5432
        - --db.db-name=stroomdb
        - --db.schema-mode=2
        - --node.private-key=0000000000000000000000000000000000000000000000000000000000000000
        - --node.listen-address=0.0.0.0:4444
        - --node.initial-lnd-balance=0
        - --node.approval-threshold=3
        - --watch.bitcoin-finalization-depth=3
        - --watch.lightning-delta-check-interval=60s
        - --bridge.bitcoin-start-height=185778
        - --bridge.ethereum-start-height=5427341
        - --node.validator-addresses=1000000000000000000000000000000000000000000000000000000000000000
        - --node.validator-addresses=2000000000000000000000000000000000000000000000000000000000000000
      volumes:
        - ./creds:/creds
      ports:
        - 4444:4444
      networks:
        - team-testnet
      depends_on:
        - stroom-validator-node-db

    stroom-validator-node-db:
      image: postgres:16.0-alpine
      container_name: stroom-validator-node-db
      restart: unless-stopped
      user: postgres
      environment:
        POSTGRES_USER: postgres
        POSTGRES_PASSWORD: postgres
        POSTGRES_DB: stroomdb
      volumes:
        - ./postgresql:/var/lib/postgresql
      healthcheck:
        test: [ "CMD-SHELL", "pg_isready" ]
        interval: 5s
        timeout: 3s
        retries: 5
      ports:
        - "5432:5432"
      networks:
        - team-testnet

networks:
  team-testnet:
    driver: bridge

Step-By-Step

  1. Create a new folder:

mkdir -p stroom-testnet
cd stroom-testnet
  1. Create a new directory for LND auth files:

mkdir -p creds
  1. Stroom network initiator should share 2 files via presigned link lnd-stroom-bob-readonly.macaroon, lnd-stroom-bob-tls.cert. Download them and past to creds directory.

  2. Create docker compose file and past there content above.

touch docker-compose.yml
  • past the content

  1. Expose your public address

Open new terminal window and run ngrok

ngrok tcp 4444

Please discover your public address after "Forwarding block" something like 5.tcp.eu.ngrok.io:18327

  1. Generate new keys:

docker run stroomnetwork/key-generator:v0.0.1 --network=signet
  1. Paste generated secret key into your docker compose after --node.private-key=

  2. Share your public key with your public address i.e. 0288784d3a9196db158d60bbdeece214092dfe0967ab85e0e91cd69cacce8c7de6@5.tcp.eu.ngrok.io:18327

  3. Get all validators info and past to docker compose to --node.validator-addresses=?

  4. Run compose

docker compose up

Last updated