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

Warnings

Acknowledgements and Disclaimer

Support

Prerequisites

Note for Raspberry Pi Users

Requirements

Overview

Step 1 — Generate Staking Data

Download the Deposit Tool (Eth2 Deposit CLI)

$ cd ~
$ sudo apt install curl
$ curl -LO https://github.com/ethereum/eth2.0-deposit-cli/releases/download/v1.2.0/eth2deposit-cli-256ea21-linux-amd64.tar.gz
$ sudo tar xvf eth2deposit-cli-256ea21-linux-amd64.tar.gz
$ cd eth2deposit-cli-256ea21-linux-amd64

Run the Deposit Tool (Eth2 Deposit CLI)

$ sudo ./deposit new-mnemonic --num_validators NumberOfValidators --mnemonic_language=english --chain prater
deposit.exe new-mnemonic --num_validators NumberOfValidators --mnemonic_language=english --chain prater

Step 2 — Connect to the Server

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

Step 3 — Update the Server

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

Step 4 — Secure the Server

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 5 — Configure Timekeeping

$ timedatectl
$ sudo timedatectl set-ntp on
$ ntpq -p
$ sudo apt-get remove ntp

Step 6 — 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 -f -u 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 7— Install Lighthouse 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 llvm-dev libclang-dev clang

Step 8 — Clone and Build Lighthouse

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

Step 9 — Copy the Lighthouse Binary

$ sudo cp /$HOME/.cargo/bin/lighthouse /usr/local/bin

Step 10 — Import Validator Keys

Copy the Validator Keystore Files

Import Keystore Files into the Validator Wallet

$ sudo mkdir -p /var/lib/lighthouse
$ sudo chown -R <yourusername>:<yourusername> /var/lib/lighthouse
$ cd /usr/local/bin
$ sudo lighthouse --network prater account validator import --directory $HOME/eth2deposit-cli/validator_keys --datadir /var/lib/lighthouse
Running account manager for prater network
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-256ea21-linux-amd64/validator_keys/keystore-m_12381_3600_0_0_0-1630781828.json":- Public key: 0xa799ba21bbbe0127add9060aff9c99f0383abd485e4452bde6abe03b79bd155fedb5e2b51f2c597cfc7e1f63e2b675f5
- UUID: 6c4a3a14-7feb-449c-acf4-2155cf0c4690
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 0 validators (2 skipped).WARNING: DO NOT USE THE ORIGINAL KEYSTORES TO VALIDATE WITH ANOTHER CLIENT, OR YOU WILL GET SLASHED.
sudo chown -R root:root /var/lib/lighthouse

Step 11 — Configure the Beacon Node

Set up the Beacon Node Account and Directory

$ 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 chmod 700 /var/lib/lighthouse/beacon
$ ls -dl /var/lib/lighthouse/beacon

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]
User=lighthousebeacon
Group=lighthousebeacon
Type=simple
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/lighthouse bn --network prater --datadir /var/lib/lighthouse --staking --validator-monitor-auto --metrics --eth1-endpoints http://127.0.0.1:8545
[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
Sep 06 16:33:02 ETH-STAKER-01 lighthouse[92873]: Sep 06 16:33:02.978 INFO Lighthouse started                      version: Lighthouse/v1.5.2-rc.0-ddbd4e6
Sep 06 16:33:02 ETH-STAKER-01 lighthouse[92873]: Sep 06 16:33:02.978 INFO Configured for network name: prater
Sep 06 16:33:02 ETH-STAKER-01 lighthouse[92873]: Sep 06 16:33:02.978 INFO Data directory initialised datadir: /var/lib/lighthouse
Sep 06 16:33:02 ETH-STAKER-01 lighthouse[92873]: Sep 06 16:33:02.978 WARN Running HTTP server on port 5052
Sep 06 16:33:03 ETH-STAKER-01 lighthouse[92873]: Sep 06 16:33:03.037 INFO Deposit contract address: 0xff50ed3d0ec03ac01d4c79aad74928bff48a7b2b, deploy_block: 4367322
Sep 06 16:33:03 ETH-STAKER-01 lighthouse[92873]: Sep 06 16:33:03.198 INFO Starting from known genesis state service: beacon
Sep 06 16:33:05 ETH-STAKER-01 lighthouse[92873]: Sep 06 16:33:05.904 INFO Block production enabled method: json rpc via http, endpoints: ["https://goerli.infura.io/"]
Sep 06 16:34:42 ETH-STAKER-01 lighthouse[92873]: Sep 06 16:34:42.001 INFO Syncing                                 est_time: 3 days 21 hrs, speed: 3.56 slots/sec, distance: 1203045 slots (23 weeks 6 days), peers: 19, service: slot_notifier

Step 12 — Configure the Validator

Set up the Validator Node Account and Directory

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

Create and Configure the Service

$ sudo nano /etc/systemd/system/lighthousevalidator.service
[Unit]
Description=Lighthouse Eth2 Client Validator Node
Wants=network-online.target
After=network-online.target
[Service]
User=lighthousevalidator
Group=lighthousevalidator
Type=simple
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/lighthouse vc --network prater --datadir /var/lib/lighthouse --graffiti "<yourgraffiti>" --metrics
[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
-- Logs begin at Sat 2021-09-04 18:41:01 UTC. --
Sep 06 16:50:10.442 INFO Genesis has already occurred seconds_ago: 14439010
Sep 06 16:50:10.442 INFO Block production service started service: block
Sep 06 16:50:10.442 INFO Attestation production service started next_update_millis: 1558, service: attestation
Sep 06 16:50:10.442 INFO Sync committee service started next_update_millis: 1558, service: sync_committee
Sep 06 16:50:10.442 INFO Doppelganger protection disabled.
Sep 06 16:50:10.442 INFO HTTP API server is disabled
Sep 06 16:50:10.448 WARN Failed to download sync committee duties, error: All endpoints failed http://localhost:5052/ => RequestFailed(ServerMessage(ErrorMessage { code: 503, message: "SERVICE_UNAVAILABLE: beacon node is syncing: head slot is 3072, current slot is 1203250", stacktraces: [] })), sync_committee_period: 146, service: duties
Sep 06 16:47:40.002 INFO Connected to beacon node endpoint: http://localhost:5052/, version: Lighthouse/Lighthouse/v1.5.2-rc.0-ddbd4e6/x86_64-linux
Sep 06 16:47:40.004 WARN Beacon node is not synced endpoint: http://localhost:5052/, head_slot: 2560, sync_distance: 1200678
Sep 06 16:47:42.002 ERRO No synced beacon nodes synced: 0, available: 1, total: 1, service: notifier
Sep 06 16:47:42.002 INFO Awaiting activation slot: 1203238, epoch: 37601, validators: 2, service: notifier

Step 13 — Fund the Validator Keys

Get Göerli ETH

Complete the Launchpad

Check the Status of Your Validators

Step 14 — Monitoring: 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.29.2/prometheus-2.29.2.linux-amd64.tar.gz
$ tar xvf prometheus-2.29.2.linux-amd64.tar.gz
$ sudo cp prometheus-2.29.2.linux-amd64/prometheus /usr/local/bin/
$ sudo cp prometheus-2.29.2.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.29.2.linux-amd64/consoles /etc/prometheus
$ sudo cp -r prometheus-2.29.2.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.29.2.linux-amd64.tar.gz prometheus-2.29.2.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=2021-09-06T16:57:40.941Z caller=main.go:784 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 15 — Monitoring: Install Node Exporter

$ cd ~
$ curl -LO https://github.com/prometheus/node_exporter/releases/download/v1.2.2/node_exporter-1.2.2.linux-amd64.tar.gz
$ tar xvf node_exporter-1.2.2.linux-amd64.tar.gz
$ sudo cp node_exporter-1.2.2.linux-amd64/node_exporter /usr/local/bin
$ sudo chown -R node_exporter:node_exporter /usr/local/bin/node_exporter
$ rm -rf node_exporter-1.2.2.linux-amd64.tar.gz node_exporter-1.2.2.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 16 — Monitoring: 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: 8.1.2
Version table:
8.1.2 500
500 https://packages.grafana.com/oss/deb stable/main amd64 Packages
8.1.1 500
500 https://packages.grafana.com/oss/deb stable/main amd64
...
$ 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 and Recommended Next Steps

Further Reading

Appendix A — Updating Geth

$ sudo systemctl stop lighthousevalidator
$ sudo systemctl stop lighthousebeacon
$ sudo systemctl stop geth
$ sudo apt update && upgrade
$ sudo systemctl start geth
$ sudo systemctl status geth # <-- Check for errors
$ sudo journalctl -f -u geth # <-- Monitor
$ sudo systemctl start lighthousebeacon
$ sudo systemctl status lighthousebeacon # <-- Check errors
$ sudo journalctl -fu lighthousebeacon # <-- Monitor
$ sudo systemctl start lighthousevalidator
$ sudo systemctl status lighthousevalidator # <-- Check errors
$ sudo journalctl -fu lighthousevalidator # <-- Monitor

Appendix B — 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

Appendix C — Adding Validators

Generate Deposit Data

$ sudo ./deposit existing-mnemonic --validator_start_index <ValidatorStartIndex> --num_validators <NumberOfValidators> --chain prater
deposit.exe existing-mnemonic --validator_start_index <ValidatorStartIndex> --num_validators <NumberOfValidators> --chain prater

Copy the Validator Keystore Files

Import Keystore Files into the Validator Wallet

$ sudo systemctl stop lighthousevalidator
$ sudo chown -R <yourusername>:<yourusername> /var/lib/lighthouse/validators
$ cd /usr/local/bin
$ sudo lighthouse --network prater account validator import --directory $HOME/eth2deposit-cli/validator_keys --datadir /var/lib/lighthouse
Skipping import of keystore for existing public key: "/home/ethstaker/eth2deposit-cli/validator_keys/keystore-m_12381_3600_0_0_0-1630781828.json"
Keystore found at "/home/ethstaker/eth2deposit-cli/validator_keys/keystore-m_12381_3600_2_0_0-1630953396.json": - Public key: 0x87ad7e70c1e95c287a0666d723cc4575cb1ae3f972cdede9e5c64270229a0918165ecc72c8a2bf01ae49075a63c06681
- UUID: f38f9224-a95b-4820-b39e-0f1815a49c2a
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 1 validators (2 skipped).
$ sudo chown -R lighthousevalidator:lighthousevalidator /var/lib/lighthouse/validators
$ sudo systemctl start lighthousevalidator
$ sudo systemctl status lighthousevalidator # <-- Check for errors
$ sudo journalctl -fu lighthousevalidator # <-- Monitor
$ sudo chown -R <yourusername>:<yourusername> /var/lib/lighthouse/validators
$ sudo nano /var/lib/lighthouse/validators/validator_definitions.yml
$ sudo chown -R lighthousevalidator:lighthousevalidator /var/lib/lighthouse/validators 
$ sudo systemctl restart lighthousevalidator
$ sudo systemctl status lighthousevalidator # <-- Check for errors
$ sudo journalctl -fu lighthousevalidator # <-- Monitor

Appendix D — Exiting Validators

$ cd ~
$ cd /usr/local/bin
$ lighthouse --network prater account validator exit --keystore /var/lib/lighthouse/validators/<ValidatorPublicKey>/voting-keystore.json --beacon-node http://localhost:5052

Appendix E — Expanding the Logical Volume

$ sudo lvdisplay # <-- Check your logical volume size
$ sudo lvm
> lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv
> lvextend -l +100%FREE -r /dev/ubuntu-vg/ubuntu-lv
> exit
$ sudo resize2fs /dev/ubuntu-vg/ubuntu-lv
$ df -h # <-- Check results

--

--

--

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.

More from Medium

New Market: FRAX/USDC

Stader — Whale Army AMA Session

Is Bitcoin really Driving the Altcoin Market?

Let’s talk about Crypto, The difference between Ethereum and Solana.