Guide to Staking on Ethereum 2.0 (Ubuntu/Pyrmont/Lighthouse)

  • Configure a newly running Ubuntu server instance
  • Configure and run an Ethereum 1.0 node as a service
  • Generate a Lighthouse wallet and import Pyrmont validator account keys
  • Compile and configure the Lighthouse client software for Ethereum 2.0, Phase 0 (Pyrmont testnet) and run as a service
  • Install and configure Prometheus metrics and set up a Grafana dashboard

Warnings

Acknowledgements and Disclaimer

Support

  • EthStaker community on Reddit or Discord. Knowledgeable and friendly community passionate about staking on Ethereum 2.0.
  • Lighthouse client team Discord. The client software engineering team. Experts on Lighthouse and its usage.

Prerequisites

  • Ubuntu server v20.04 (LTS) amd64 or newer, installed and running on a local computer on your network or in the cloud (AWS, Digital Ocean, Microsoft Azure, etc.). A local computer is recommended for greater decentralization — if the cloud provider goes down then all nodes hosted with that provider go down.
  • MetaMask crypto wallet browser extension, installed and configured. A computer with a desktop (Mac, Windows, Linux) and a browser (Safari, Brave, FireFox, etc.) is required.

Note for Raspberry Pi Users

Requirements

  • Ubuntu server instance. I used v20.04 (LTS) amd64 server VM.
  • MetaMask crypto wallet browser extension, installed and configured.
  • Hardware recommended hardware requirements:
    - Processor: Intel Core i7–4770 or AMD FX-8310 or better
    - Memory: 16GB RAM
    - Storage: 100GB available space SSD

Overview

  • Set up a Eth1 node and sync it with the Eth1 Göerli testnet
  • Configure Beacon Node and sync it with the Eth1 Node
  • Generate and activate validator keys
  • Configure the Validator Client
  • The Beacon Node makes the magic happen (blocks, attestations, slashings) with the help of the validator (signing)

Step 0 — Connect to the Server

# adduser <yourusername>
# usermod -aG sudo <yourusername>
# rsync --archive --chown=<yourusername>:<yourusername> ~/.ssh /home/<yourusername>

Step 1 — Update Your System

$ sudo apt update && sudo apt upgrade
$ sudo apt dist-upgrade && sudo apt autoremove

Step 2 — Secure Your System

Configure the firewall

$ sudo ss -tulpn | grep ':<yourSSHportnumber>'
$ sudo ufw allow <yourSSHportnumber>/tcp
$ sudo nano /etc/ssh/sshd_config
$ sudo systemctl restart ssh
$ sudo ufw deny 22/tcp
$ sudo ufw allow 30303
$ sudo ufw allow 9000
$ sudo ufw allow 3000/tcp
$ sudo ufw allow 9090/tcp
$ sudo ufw enable
$ sudo ufw status numbered

Step 3— Install and Run Go Ethereum Node

Install Go Ethereum

$ sudo add-apt-repository -y ppa:ethereum/ethereum
$ sudo apt update
$ sudo apt install geth

Run Go Ethereum as a Background Service

$ sudo useradd --no-create-home --shell /bin/false goeth
$ sudo mkdir -p /var/lib/goethereum
$ sudo chown -R goeth:goeth /var/lib/goethereum
$ sudo nano /etc/systemd/system/geth.service
[Unit]
Description=Ethereum go client
After=network.target
Wants=network.target
[Service]
User=goeth
Group=goeth
Type=simple
Restart=always
RestartSec=5
ExecStart=geth --goerli --http --datadir /var/lib/goethereum
[Install]
WantedBy=default.target
$ sudo systemctl daemon-reload
$ sudo systemctl start geth
$ sudo systemctl status geth
$ sudo systemctl enable geth
$ sudo journalctl -fu geth.service
$ sudo systemctl stop geth
$ sudo nano /etc/systemd/system/geth.service
ExecStart=geth --goerli --http --datadir /var/lib/goethereum --bootnodes "enode://46add44b9f13965f7b9875ac6b85f016f341012d84f975377573800a863526f4da19ae2c620ec73d11591fa9510e992ecc03ad0751f53cc02f7c7ed6d55c7291@94.237.54.114:30313,enode://119f66b04772e8d2e9d352b81a15aa49d565590bfc9a80fe732706919f8ccd00a471cf8433e398c55c4862aadb4aadf3a010201483b87e8358951698aa0b6f07@13.250.50.139:30303"
$ sudo systemctl daemon-reload
$ sudo systemctl start geth
$ sudo journalctl -f -u geth.service

Step 4— Install Dependencies

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ source $HOME/.cargo/env
cargo install --path lighthouse --force --locked
make: cargo: Command not found
make: *** [Makefile:20: install] Error 127
$ sudo apt install -y git gcc g++ make cmake pkg-config libssl-dev

Step 5— Install and Build Lighthouse

$ cd ~
$ git clone -b v1.0.0 https://github.com/sigp/lighthouse.git
$ cd lighthouse
$ make

Step 6— Complete the Pyrmont On-boarding Process

  • Get Göerli ETH
  • Generate the validator keys. Each key is a validator account
  • Fund the validator account(s) with 32 Göerli ETH per account
  • Wait for your validator account(s) to become active

Get Goerli ETH

  1. Go to a computer with the MetaMask browser extension installed.
  2. Click on MetaMask and log in.
  3. Using the drop-down at the top, select the Göerli Test Network.
  4. Click on the account name to copy your Göerli Test Network wallet address.
  5. Using your address, get Göerli ETH from the authenticated faucet or via the #request-goerli-eth channel on the ethstaker Discord using the bot command: !goerliEth <yourwalletaddress>.

Generate Validator Keys

$ cd ~
$ curl -LO https://github.com/ethereum/eth2.0-deposit-cli/releases/download/v1.1.0/eth2deposit-cli-ed5a6d3-linux-amd64.tar.gz
$ tar xvf eth2deposit-cli-ed5a6d3-linux-amd64.tar.gz
$ cd eth2deposit-cli-ed5a6d3-linux-amd64
$ rm -rf eth2deposit-cli-ed5a6d3-linux-amd64.tar.gz
$ ./deposit new-mnemonic --num_validators <numberofvalidators> --mnemonic_language=english --chain pyrmont

Fund the Validator Keys

Check the Status of Your Validators

  1. Copy your Göerli Test Network wallet address
  2. Go here: https://pyrmont.beaconcha.in/
  3. Search your wallet address. Your keys will be shown.

Step 7— Create the Validator Wallet

$ sudo mkdir -p /var/lib/lighthouse
$ sudo chown -R <yourusername>:<yourusername> /var/lib/lighthouse
$ cd lighthouse
$ lighthouse --network pyrmont account validator import --directory $HOME/<PathToValidatorKeys> --datadir /var/lib/lighthouse
Running account manager for pyrmont testnet
validator-dir path: "/var/lib/lighthouse/validators"
validator-dir path: "/var/lib/lighthouse/validators"
WARNING: DO NOT USE THE ORIGINAL KEYSTORES TO VALIDATE WITH ANOTHER CLIENT, OR YOU WILL GET SLASHED.
Keystore found at "/home/ethstaker/eth2deposit-cli-ed5a6d3-linux-amd64/validator_keys/keystore-m_12381_3600_1_0_0-1605678395.json":- Public key: 0xa79583298ecbd5564fce6ccefe2e69969705aff950235dc59ae303fa210b029b565c08303eb18cf02ecc26c429059d7f
- UUID: 94079858-57db-4fb2-8272-5dbdfb31e65e
If you enter the password it will be stored as plain-text in validator_definitions.yml so that it is not required each time the validator client starts.Enter the keystore password, or press enter to omit it:Password is correct.Successfully imported keystore.
Successfully updated validator_definitions.yml.
Successfully imported 2 validators (0 skipped).WARNING: DO NOT USE THE ORIGINAL KEYSTORES TO VALIDATE WITH ANOTHER CLIENT, OR YOU WILL GET SLASHED.
sudo chown root:root /var/lib/lighthouse

Step 8— Configure the Beacon Node

Setup Accounts and Directories

$ sudo useradd --no-create-home --shell /bin/false lighthousebeacon
$ sudo mkdir -p /var/lib/lighthouse/beacon
$ sudo chown -R lighthousebeacon:lighthousebeacon /var/lib/lighthouse/beacon
$ sudo cp /$HOME/.cargo/bin/lighthouse /usr/local/bin

Create and Configure the Service

$ sudo nano /etc/systemd/system/lighthousebeacon.service
[Unit]
Description=Lighthouse Beacon Node
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=lighthousebeacon
Group=lighthousebeacon
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/lighthouse beacon_node --datadir /var/lib/lighthouse --network pyrmont --staking --eth1-endpoint http://127.0.0.1:8545 --metrics
[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl start lighthousebeacon
$ sudo systemctl status lighthousebeacon
$ sudo systemctl enable lighthousebeacon
$ sudo journalctl -fu lighthousebeacon.service
Nov 19 09:57:15 ETH-STAKER-001 systemd[1]: Started Lighthouse Beacon Node.
Nov 19 09:57:15 ETH-STAKER-001 lighthouse[158842]: Nov 19 09:57:15.398 WARN Ethereum 2.0 is pre-release. This software is experimental
Nov 19 09:57:15 ETH-STAKER-001 lighthouse[158842]: Nov 19 09:57:15.398 INFO Lighthouse started version: Lighthouse/v0.3.5-1a530e5a
Nov 19 09:57:15 ETH-STAKER-001 lighthouse[158842]: Nov 19 09:57:15.398 INFO Configured for testnet name: pyrmont
Nov 19 09:57:15 ETH-STAKER-001 lighthouse[158842]: Nov 19 09:57:15.398 INFO Data directory initialised datadir: /var/lib/lighthouse
Nov 19 09:57:15 ETH-STAKER-001 lighthouse[158842]: Nov 19 09:57:15.398 WARN Running HTTP server on port 5052
Nov 19 09:57:15 ETH-STAKER-001 lighthouse[158842]: Nov 19 09:57:15.456 INFO Starting from known genesis state service: beacon
Nov 19 09:57:16 ETH-STAKER-001 lighthouse[158842]: Nov 19 09:57:16.564 INFO Block production enabled method: json rpc via http, endpoint: https://goerli.prylabs.net
Nov 19 09:59:37 ETH-STAKER-001 lighthouse[158842]: Nov 19 09:59:37.001 INFO Syncing                                 est_time: 18 mins, speed: 5.31 slots/sec, distance: 5830 slots (19 hrs 26 mins), peers: 29, service: slot_notifier

Step 9 — Configure the Validator

Setup Accounts and Directories

$ sudo useradd --no-create-home --shell /bin/false lighthousevalidator
$ sudo chown -R lighthousevalidator:lighthousevalidator /var/lib/lighthouse/validators

Create and Configure the Service

$ sudo nano /etc/systemd/system/lighthousevalidator.service
[Unit]
Description=Lighthouse Validator
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=lighthousevalidator
Group=lighthousevalidator
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/lighthouse validator_client --network pyrmont --datadir /var/lib/lighthouse --graffiti "<yourPOAPstring>"
[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl start lighthousevalidator
$ sudo systemctl status lighthousevalidator
$ sudo systemctl enable lighthousevalidator
$ sudo journalctl -fu lighthousevalidator.service
Nov 19 10:13:54 ETH-STAKER-001 lighthouse[159892]: Nov 19 10:13:54.772 INFO Completed validator discovery           new_validators: 0
Nov 19 10:13:55 ETH-STAKER-001 lighthouse[159892]: Nov 19 10:13:55.904 INFO Enabled validator voting_pubkey: 0xa79583298ecbd5564fce6ccefe2e69969705aff950235dc59ae303fa210b029b565c08303eb18cf02ecc26c429059d>
Nov 19 10:13:55 ETH-STAKER-001 lighthouse[159892]: Nov 19 10:13:55.904 INFO Enabled validator voting_pubkey: 0x8c8b19c544d79bdaf60d7dcc86ebaeeed4d804d2ecb4c66e5b27e19a664a81457a1c02a873a110e1d332abce5800cf>
Nov 19 10:13:55 ETH-STAKER-001 lighthouse[159892]: Nov 19 10:13:55.904 INFO Initialized validators enabled: 2, disabled: 0
Nov 19 10:13:55 ETH-STAKER-001 lighthouse[159892]: Nov 19 10:13:55.931 INFO Connected to beacon node version: Lighthouse/v0.3.5-1a530e5a/x86_64-linux
Nov 19 10:13:55 ETH-STAKER-001 lighthouse[159892]: Nov 19 10:13:55.934 INFO Genesis has already occurred seconds_ago: 80028
Nov 19 10:13:55 ETH-STAKER-001 lighthouse[159892]: Nov 19 10:13:55.934 INFO Loaded validator keypair store voting_validators: 2
Nov 19 10:13:55 ETH-STAKER-001 lighthouse[159892]: Nov 19 10:13:55.934 INFO Block production service started service: block
Nov 19 10:13:55 ETH-STAKER-001 lighthouse[159892]: Nov 19 10:13:55.934 INFO Attestation production service started next_update_millis: 11065, service: attestation
Nov 19 10:13:55 ETH-STAKER-001 lighthouse[159892]: Nov 19 10:13:55.935 INFO HTTP API server is disabled
Nov 19 10:25:49 ETH-STAKER-001 lighthouse[159892]: Nov 19 10:25:49.004 INFO Awaiting activation                     slot: 6728, epoch: 210, validators: 2, service: notifier

Step 10 — Install Prometheus

Create User Accounts

$ sudo useradd --no-create-home --shell /bin/false prometheus
$ sudo useradd --no-create-home --shell /bin/false node_exporter

Create Directories

$ sudo mkdir /etc/prometheus
$ sudo mkdir /var/lib/prometheus
$ sudo chown -R prometheus:prometheus /etc/prometheus
$ sudo chown -R prometheus:prometheus /var/lib/prometheus

Download Prometheus software

$ cd ~
$ curl -LO https://github.com/prometheus/prometheus/releases/download/v2.20.0/prometheus-2.20.0.linux-amd64.tar.gz
$ tar xvf prometheus-2.20.0.linux-amd64.tar.gz
$ sudo cp prometheus-2.20.0.linux-amd64/prometheus /usr/local/bin/
$ sudo cp prometheus-2.20.0.linux-amd64/promtool /usr/local/bin/
$ sudo chown -R prometheus:prometheus /usr/local/bin/prometheus
$ sudo chown -R prometheus:prometheus /usr/local/bin/promtool
$ sudo cp -r prometheus-2.20.0.linux-amd64/consoles /etc/prometheus
$ sudo cp -r prometheus-2.20.0.linux-amd64/console_libraries /etc/prometheus
$ sudo chown -R prometheus:prometheus /etc/prometheus/consoles
$ sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries
$ rm -rf prometheus-2.20.0.linux-amd64.tar.gz prometheus-2.20.0.linux-amd64

Edit the Configuration File

$ sudo nano /etc/prometheus/prometheus.yml
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
- job_name: 'nodes'
metrics_path: /metrics
static_configs:
- targets: ['localhost:5054']
- job_name: 'node_exporter'
static_configs:
- targets: ['localhost:9100']
$ sudo chown -R prometheus:prometheus /etc/prometheus/prometheus.yml
$ sudo -u prometheus /usr/local/bin/prometheus \
--config.file /etc/prometheus/prometheus.yml \
--storage.tsdb.path /var/lib/prometheus/ \
--web.console.templates=/etc/prometheus/consoles \
--web.console.libraries=/etc/prometheus/console_libraries
level=info ts=2020-08-02T04:56:51.414Z caller=main.go:805 msg="Loading configuration file" filename=/etc/prometheus/prometheus.yml
level=info ts=2020-08-02T04:56:51.415Z caller=main.go:833 msg="Completed loading of configuration file" filename=/etc/prometheus/prometheus.yml
level=info ts=2020-08-02T04:56:51.415Z caller=main.go:652 msg="Server is ready to receive web requests."

Set Prometheus to Auto-Start as a Service

$ sudo nano /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=prometheus
Group=prometheus
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/prometheus \
--config.file /etc/prometheus/prometheus.yml \
--storage.tsdb.path /var/lib/prometheus/ \
--web.console.templates=/etc/prometheus/consoles \
--web.console.libraries=/etc/prometheus/console_libraries
[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl start prometheus
$ sudo systemctl status prometheus
$ sudo systemctl enable prometheus

Step 11 — Install Node Exporter

$ cd ~
$ curl -LO https://github.com/prometheus/node_exporter/releases/download/v1.0.1/node_exporter-1.0.1.linux-amd64.tar.gz
$ tar xvf node_exporter-1.0.1.linux-amd64.tar.gz
$ sudo cp node_exporter-1.0.1.linux-amd64/node_exporter /usr/local/bin
$ sudo chown -R node_exporter:node_exporter /usr/local/bin/node_exporter
$ rm -rf node_exporter-1.0.1.linux-amd64.tar.gz node_exporter-1.0.1.linux-amd64

Set Node Exporter to Auto-Start as a Service

$ sudo nano /etc/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl start node_exporter
$ sudo systemctl status node_exporter
$ sudo systemctl enable node_exporter

Test Prometheus and Node Exporter (Optional)

http://<yourserverip>:9090/new/graph?g0.expr=node_memory_MemFree_bytes&g0.tab=1&g0.stacked=0&g0.range_input=1h

Step 12 — Install Grafana

$ wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
$ sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main"
$ sudo apt update
$ apt-cache policy grafana
grafana:
Installed: (none)
Candidate: 7.1.1
Version table:
7.1.1 500
500 https://packages.grafana.com/oss/deb stable/main amd64 Packages
7.1.0 500
500 https://packages.grafana.com/oss/deb stable/main amd64 Packages
7.0.6 500
500 https://packages.grafana.com/oss/deb stable/main amd6
...
$ sudo apt install grafana
$ sudo systemctl start grafana-server
$ sudo systemctl status grafana-server
$ sudo systemctl enable grafana-server

Configure Grafana Login

Configure the Grafana Data Source

Add data source screen.
Data source configuration.
Data source is confirmed working.

Import a Grafana Dashboard

Final Remarks

  • A future update includes a more comprehensive dashboard (hardware metrics and metrics on the eth1 node) and information on alerting.
  • If you have feedback you can reach me on Twitter or Reddit.
  • If you liked this guide and think others would benefit from it then please share it using the friends link!
  • Tips: somer.eth

Appendix — Updating Lighthouse

$ rustup update
$ cd ~
$ cd lighthouse
$ git fetch --tags && git checkout <release>
$ make
$ sudo systemctl stop lighthousevalidator
$ sudo systemctl stop lighthousebeacon
$ sudo cp /$HOME/.cargo/bin/lighthouse /usr/local/bin
$ sudo systemctl start lighthousebeacon
$ sudo systemctl status lighthousebeacon # <-- Check errors.
$ sudo journalctl -fu lighthousebeacon # <-- Check errors.
$ sudo systemctl start lighthousevalidator
$ sudo systemctl status lighthousevalidator # <-- Check errors.
$ sudo journalctl -fu lighthousevalidator # <-- Check errors.

Unlisted

--

--

--

Passionate about Ethereum and decentralized technology.

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Somer Esat

Somer Esat

Passionate about Ethereum and decentralized technology.