Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 201 additions & 0 deletions site/content/blog/eth2-dev-chain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
---
title: Setting up private Ethereum 2.0 development chain
date: 2020-03-26T09:00:00-00:00
image: /images/blog/ethereum20-validator.png
draft: false
keywords:
- ethereum 2.0
- proof of staking
- dev
- lighthouse
- chainguardian
description: Learn how to setup eth2 development chain using lighthouse client.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping it short (because of truncate on web, google etc.): How to setup Eth2 development chain using Lighthouse client

---

> Disclaimer: This article is highly technical intended for developers and eth2 enthusiasts.

### Why would I setup private eth2 chain?

If you had any experience with development on eth1, you probably already know answer to this question so
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case this might not be needed as it is really short paragraph and good to read anyway. Can be a bit on the offensive side too.

You can start with something like: "In case you have experience with development on eth1, you may be familiar with the problem of fast testing and using private networks as a solution." That way you say immediately what's this section about and people can choose to skip or not.

feel free to skip ahead.

At the moment, eth2 has a bunch short lived single client testnets and [one long lived](https://prylabs.net/) with
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are linking Prysmatic 2x times and this is kinda hidden linking :D
Rephrase so you only link once the name i.e. At the moment, eth2 has a bunch of short lived single client testnets and one long lived which is Prysmatic's Sapphire Testnet](https://prylabs.net/). However, real stable client testnet is yet to come.

real stable client testnet still TBD. So, yeah, you can use [Prysmatic's Sapphire Testnet](https://prylabs.net/) but
beware it will take some time to sync and if you wanna test some validator related operations, you will have to wait
couple of hours to become active validator. Imagine, waiting couple of hours just to find out your app has bug
with validator related operation and now you have to do everything all over.

Our motivation for this setup was [ChainGuardian](https://github.com/nodefactoryio/chainguardian), a desktop validator
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it a validator client really or more of desktop app for validators or something like that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my experience, if I say or write any else then "desktop validator client" people have no idea what I'm talking about. And it is, as a matter of fact, our core functionality

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk, I was referring that technically client is something like lodestar, lighthouse etc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those are beacon nodes. They do have validators but they are cli tools

client. Since we need to test whole onboarding process together with validation itself, dev chain is a must have.

### Choosing client
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eth2 client*


As you might already know, there is [quite a few teams](https://docs.ethhub.io/ethereum-roadmap/ethereum-2.0/eth2.0-teams/teams-building-eth2.0/)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

link on [teams developing eth2 clients]

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are quite a few teams developing eth2 clients

developing eth2 clients each focusing on specific features (security, enterprise, resource constrained devices, browser).

We went with [Lighthouse client](https://github.com/sigp/lighthouse) as their API is closely matched to
[api standardization efforts](https://github.com/ethereum/eth2.0-apis) and other clients. Also, they seemed most
stable at the moment.

### Step 1: Setup private Eth1 chain

We will use docker and docker-compose throughout this article to orchestrate various pieces of architecture.

First, we need eth1 account that will serve purpose of signer in POA chain and it will be used to deploy deposit contract
and validator deposits. Store private key of that account in `signer.key` file.

We will also need:

- genesis.json - genesis file containing params of our POA chain
- passwd.txt - some file containing some dummy password for geth to encrypt our account

You can read more about setting up POA chain and generating genesis file [here](https://hackernoon.com/setup-your-own-private-proof-of-authority-ethereum-network-with-geth-9a0a3750cda8)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that linking here is not considered good SEO practice. so maybe this would be:

If you want to learn more about custom POA chain and generating genesis file, you can go through tutorial on how to [setup your own private POA network with geth](https://hackernoon.com/setup-your-own-private-proof-of-authority-ethereum-network-with-geth-9a0a3750cda8)

just make sure you:

- prefund your "signer"
- change `config.clique.period` to like 3 which means eth1 chain will produce block every 3 seconds

You can checkout our [configuration](https://github.com/NodeFactoryIo/ChainGuardian/tree/mpetrunic/lighthouse/eth1)
and [docker-compose](https://github.com/NodeFactoryIo/ChainGuardian/blob/a789bcf16e34f193b4fb4a72c975dd553a1f8ca9/docker-compose.yml#L3).

### Step 2: Deploy deposit contract
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on eth1 (for someone setting up the first time might be a confusion)


Eth2 chain will monitor deposit contract for new deposits and use deposit data to activate validator.
You can download deposit contract artifact for spec version 0.10.1 [here](https://raw.githubusercontent.com/ethereum/eth2.0-specs/v0.10.1/deposit_contract/contracts/validator_registration.json).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also here

We just need `bytecode` from that artifact so extract it from artifact and save as `deposit-contract.bin`.

We are using [gochain/web3](https://github.com/gochain/web3) image which allows you to deploy any bytecode to eth1 chain and much more.
We use this snippet in docker-compose to deploy contract:
```yaml
deployer:
image: gochain/web3:0.2.19
depends_on:
- eth1-node
restart: on-failure
container_name: "cg_eth1_deployer"
entrypoint: []
command: sh -c '/opt/wait-for.sh eth1-node:8545 -- /app/web3 contract deploy /opt/deposit-contract.bin'
volumes:
- "./eth1/deposit-contract.bin:/opt/deposit-contract.bin"
# this allows us to wait until eth1 node is ready
- "./wait-for.sh:/opt/wait-for.sh"
environment:
# signer key from `signer.key` file
- "WEB3_PRIVATE_KEY=0xcd8ed955f2eab4faa99c5165a76aa89953c6da9438649fc9f3235fbd72da29e1"
- "WEB3_RPC_URL=http://eth1-node:8545"
```

If you start your docker-compose, you should see eth1 node initialization followed by deposit contract deployment
after which your contract address will be displayed to use in following steps.

### Step 3: Eth2 chain configuration

Ligthhouse is providing awesome cli tool called [lcli](https://github.com/sigp/lighthouse/tree/master/lcli) to generate
testnet configuration.

We used following command:
```shell script
lcli --spec minimal new-testnet \
--deposit-contract-address <eth1 contract address> \
--eth1-follow-distance 1 \
--testnet-dir ./my-testnet-config \
--min-genesis-delay 1
```

Let's break it down:

- `--spec minimal` instructs command to use "light" chain specification instead of mainnet values which will stress your PC a bit more
- Even though we are using [minimal configuration](https://github.com/ethereum/eth2.0-specs/blob/v0.10.1/configs/minimal.yaml), this command will override default balance and deposits amounts (32eth -> 3.2eth etc)

- `--deposit-contract-address` where we put our contract address from Step 2
- `--eth1-follow-distance` since you private eth1 chain won't have reorgs, you should put `config.clique.period` from Step 1 here so you don't have to wait 16 confirmations (default value)
- `--testnet-dir` where we our generated testnet configuration files will end up

You can checkout rest of options with `lcli new-testnet --help`.

If everything went fine, you will end up with following files:

- boot_enr.yaml - contains enr-s of bootnodes (it will be empty array as we will only have our node and private chain)
- config.yaml - contains most of chain configurations
- deploy_block.txt - contains block at which eth1 deposit contract was deployed
- deposit_contract.txt - contains address of eth1 deposit contract

If you would like your eth2 chain to be faster, you can play around with:
- SECONDS_PER_SLOT - pretty self explaining, you should be fine with 3s per slot at minimal configuration
- SLOTS_PER_EPOCH - reducing this will make chain finalize faster
- SLOTS_PER_ETH1_VOTING_PERIOD - reducing this will activate validators faster

### Step 4: Start eth2 node and validators

There is couple of ways to start eth2 chain:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

two ways?


- start from genesis state (we prefer this one as it requires less configuration modification)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. (numbering)

- we generate genesis state and provide it to beacon node
- wait for genesis to start
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- we wait until there is enough deposits to kickoff genesis

We use this script to prepare and start beacon node:
```shell script
#!/bin/bash
# remove old genesis if exists
rm -rf /opt/cg_testnet/genesis.ssz
# remove datadir if exists
rm -rf ~/.lighthouse/beacon
# remove validators data if exists
rm -rf ~/.lighthouse/validators
# wait until eth1 node is available
/opt/wait-for.sh eth1-node:8545
# wait till deposit contract is deployed
sleep 5
# create genesis.ssz with current time and 16 validators
lcli -s minimal interop-genesis -t $(date +%s) -d /opt/cg_testnet 16
# To be able to add new validators we need to fill deposit contract with deposits for our 16 preloaded validators
lighthouse account validator new \
--testnet-dir /opt/cg_testnet \
--spec minimal \
--send-deposits \
--account-index 0 \
--eth1-endpoint http://eth1-node:8545 \
--password /opt/passwd.txt \
--deposit-value 32000000000 \
insecure \
0 16
# start beacon node
lighthouse -s minimal bn --eth1 --eth1-endpoint http://eth1-node:8545 --http --http-address 0.0.0.0 --maxpeers 0 --testnet-dir /opt/cg_testnet
```
We just need to put that script inside Lighthouse docker-container and start it along with container running validator clients:
```yaml
eth2-bn:
image: sigp/lighthouse:latest
container_name: "lighthouse_beacon_node"
command: /opt/start.sh
restart: on-failure
links:
- deployer:deployer
volumes:
- "./cg_testnet:/opt/cg_testnet"
- "./eth1/passwd.txt:/opt/passwd.txt:ro"
- "./cg_testnet/start.sh:/opt/start.sh:ro"
- "./wait-for.sh:/opt/wait-for.sh"
depends_on:
- eth1-node
- deployer
ports:
- "5052:5052"

eth2-validators:
image: sigp/lighthouse:latest
restart: on-failure
container_name: "lighthouse_validators"
command: 'lighthouse vc --server http://eth2-bn:5052 --spec minimal testnet insecure 0 16'
depends_on:
- eth2-bn
```

Note: Those 16 preloaded validators use their index and private keys so they are pretty deterministic.

You can see full example in our [ChainGuardian app repo](https://github.com/NodeFactoryIo/ChainGuardian/tree/mpetrunic/lighthouse).
If you encounter any issues or have more questions, feel free to hop on our [discord](https://discord.gg/7Kd4FZq).

*NodeFactory is a blockchain R&D company that turns ideas into reliable solutions. We are always looking for new adventures so let us know about your project by contacting us in the form below! In case you need help with any of the mentioned, join our [Discord](https://discord.gg/adsEWkS) or follow us on [Twitter](https://twitter.com/nodefactoryio).*