Guide to Staking on Ethereum 2.0 (Ubuntu/Medalla/Nimbus)

Image for post
Image for post

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

  • Configure and run an Ethereum 1.0 node as a service.
  • Compile and configure the Nimbus client software for Ethereum 2.0, Phase 0 (Medalla testnet) and run as a service.
  • Install and configure Prometheus metrics and set up a Grafana dashboard.

WARNING

This guide is for the Medalla testnet. DO NOT, under any circumstances, send real ETH to this testnet. You will lose it.

Acknowledgements and Disclaimer

This guide is based on information I pulled together from various on-line resources and this guide wouldn’t exist without them. Thank you, all!

Support

This stuff can be tricky. If you need help there are two great resources you can reach out to:

  • Nimbus client team Discord. The client software engineering team. Experts on Nimbus and its usage.

Prerequisites

This guide is not intended for absolute beginners. It assumes some knowledge of Ethereum, ETH, staking, Linux, and MetaMask. Before you get started you will need to have your Ubuntu server instance up and running. It will help to have the MetaMask browser extension installed and configured somewhere. The rest we will do along the way.

Note for Raspberry Pi Users

I haven’t tested this guide on a Rpi. If you want to try, just swap out the software listed below for the ARM version, where available. No guarantee it will work!

Requirements

  • Ubuntu server instance. I used v20.04 (LTS) amd64 server VM.
  • MetaMask crypto wallet browser extension, installed and configured.
  • Hardware requirements are currently undefined. I used a VM with the following specs:
    - Intel(R) Xeon(R) Gold 6140 CPU @ 2.30GHz
    - 4 GB RAM
    - 80GB SSD

Overview

This is a long and detailed guide. Here’s a super simplified diagram to help you conceptualize what we are going to do. The yellow boxes are the parts this guide mostly covers.

Image for post
Image for post
  • Generate and activate validator keys
  • Configure the Beacon Node (includes the validator)
  • The Beacon Node makes the magic happen (blocks, attestations, etc.) with the help of the validator (signing)

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

Step 0 — Connect to the Server

Using a SSH client, connect to your Ubuntu server. The root user account on Ubuntu server is normally disabled by default, however some cloud providers enable it. If you are logged in as root then let’s create a user-level account with admin privileges instead, since using the root user to log in is risky.

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

Step 1 — Update Your System

Make sure your system is up to date with the latest software and security updates. Reboot if necessary.

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

Step 2 — Secure Your System

Security is important. This is not a comprehensive security guide, rather just some basic settings.

Configure the firewall

Ubuntu 20.04 servers can use the default UFW firewall to restrict traffic to the server. We need to allow inbound traffic for SSH, Go Ethereum, Grafana, and Nimbus.

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

Step 3 — Configure ntpd Timekeeping (Optional)

Ubuntu has time synchronization built in and activated by default using systemd’s timesyncd service. However, for applications that require more precise timekeeping (like a blockchain) we will use ntpd.

$ sudo timedatectl set-ntp no
$ timedatectl
$ sudo apt install ntp
$ ntpq -p
Image for post
Image for post
$ ntpq -c rv
ethstaker@ETH-STAKER-001:~$ ntpq -c rv
associd=0 status=0615 leap_none, sync_ntp, 1 event, clock_sync,
version="ntpd 4.2.8p12@1.3728-o (1)", processor="x86_64",
system="Linux/5.4.0-48-generic", leap=00, stratum=2, precision=-24,
rootdelay=1.453, rootdisp=8.653, refid=209.51.161.238,
reftime=e315548b.d020811b Wed, Sep 23 2020 4:58:51.812,
clock=e31554cf.99ddcf68 Wed, Sep 23 2020 4:59:59.601, peer=5978, tc=6,
mintc=3, offset=3.040122, frequency=6.453, sys_jitter=2.164815,
clk_jitter=2.062, clk_wander=0.539, tai=37, leapsec=201701010000,
expire=202012280000

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

Step 4— Install and Run Go Ethereum Node

Install and configure an Ethereum 1.0 node that the Nimbus beacon node will connect to. If you’d rather use a node hosted by a 3rd party (Infura, etc.) then skip this step.

Install Go Ethereum

Go Ethereum recommends using PPA’s (Personal Package Archives).

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

Run Go Ethereum as a Background Service

Create an account for the service to run under. This type of account can’t log into the server.

$ 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 --ws --datadir /var/lib/goethereum
[Install]
WantedBy=default.target
Image for post
Image for post
$ sudo systemctl daemon-reload
$ sudo systemctl start geth
$ sudo systemctl status geth
Image for post
Image for post
$ 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
Image for post
Image for post
Image for post
Image for post

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

Step 5 — Install Dependencies

A number of dependencies Developer tools (C compiler, Make, Bash, Git, PCRE) are required to build the Nimbus client.

$ sudo apt install build-essential git libpcre3-dev

Step 6— Install and Build Nimbus

Now we’re ready to build Nimbus. The Nimbus build produces a beacon_node binary. We execute the binary with different subcommands or flags to get the functionality we need. E.g.:

$ cd ~
$ git clone https://github.com/status-im/nimbus-eth2
$ cd nimbus-eth2
$ make NIMFLAGS="-d:insecure" medalla-build
Image for post
Image for post

Step 7— Complete the Medalla On-boarding Process

In order to run a validator on the Eth2.0 Medalla testnet we will need to sign up for one or more validator accounts.

  • 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

Next we will generate the validator keys. The validator client supports multiple validator keys. Each validator key is basically a “validator account” on the Medalla testnet.

$ cd ~
$ git clone https://github.com/ethereum/eth2.0-deposit-cli.git
$ cd eth2.0-deposit-cli
$ python3 -V
$ sudo apt install software-properties-common
$ sudo add-apt-repository ppa:deadsnakes/ppa
$ sudo apt update
$ sudo apt install python3.7
$ sudo apt install python3-pip
$ sudo ./deposit.sh install
$ ./deposit.sh new-mnemonic --num_validators <numberofvalidators> --mnemonic_language=english --chain medalla
Success!
Your keys can be found at: /home/<yourusername>/eth2.0-deposit-cli/validator_keys

Copy Deposit Data File

In the validator_keys directory there will be a deposit_data-[timestamp].json file. You will need to upload this via a website in the next step. Since we are on a server we don’t have a web browser so secure FTP (SFTP) the file to a desktop computer that does.

Fund the Validator Keys

This step involves depositing the required amount of Göerli ETH to the Medalla testnet staking contract. This is done on the Eth2.0 Lauchpad website.

Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post

Check the Status of Your Validators

Newly added validators can take a while (hours/days/weeks) to activate. You can check the status of your keys with these steps:

  1. Go here: https://medalla.beaconcha.in/
  2. Search your wallet address. Your keys will be shown.
Image for post
Image for post

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

Step 8— Create the Validator Wallet

The validator wallet is created by importing the keystore-m JSON files from the previous step.

$ sudo mkdir -p /var/lib/nimbus
$ sudo chown -R <yourusername>:<yourusername> /var/lib/nimbus
$ sudo chmod 0750 /var/lib/nimbus
$ cd ~
$ cd nimbus-eth2
$ build/nimbus_beacon_node_spec_0_12_3 deposits import --data-dir=/var/lib/nimbus $HOME/eth2.0-deposit-cli/validator_keys
Image for post
Image for post

Step 9— Configure the Beacon Node

We will run the beacon node as a service so if the system restarts the process will automatically start back up again.

Setup Accounts and Directories

Create an account for the beacon node to run under. This type of account can’t log into the server.

$ sudo useradd --no-create-home --shell /bin/false nimbus
$ sudo chown -R nimbus:nimbus /var/lib/nimbus
$ sudo cp /$HOME/nimbus-eth2/build/nimbus_beacon_node_spec_0_12_3 /usr/local/bin

Create and Configure the Service

Create a systemd service file to store the service config.

$ sudo nano /etc/systemd/system/nimbus.service
[Unit]
Description=Nimbus Beacon Node
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=nimbus
Group=nimbus
Restart=always
WorkingDirectory=/var/lib/nimbus
Environment="ClientIP=$(curl -s v4.ident.me)"
ExecStart=/bin/bash -c '/usr/local/bin/nimbus_beacon_node_spec_0_12_3 --network=medalla --data-dir=/var/lib/nimbus --web3-url=ws://127.0.0.1:8546 --metrics --metrics-port=8008 --rpc --rpc-port=9091 --max-peers=250 --nat=extip:${ClientIP} --validators-dir=/var/lib/nimbus/validators --secrets-dir=/var/lib/nimbus/secrets --log-level=INFO --log-file=/var/lib/nimbus/beacon_node.log'
[Install]
WantedBy=multi-user.target
Image for post
Image for post
$ sudo systemctl daemon-reload
$ sudo systemctl start nimbus
$ sudo systemctl status nimbus
Image for post
Image for post
$ sudo systemctl enable nimbus
$ sudo journalctl -fu nimbus.service
Nov 17 08:28:08 ETH-STAKER-001 bash[38646]: NOT 2020-11-17 08:27:56.010+00:00 Syncing in progress; skipping validator duties for now topics="beacval" tid=38646 file=validator_duties.nim:500 slot=754639 headSlot=4148
Nov 17 08:28:08 ETH-STAKER-001 bash[38646]: INF 2020-11-17 08:27:56.010+00:00 Slot end topics="beacnde" tid=38646 file=nimbus_beacon_node.nim:551 slot=754639 nextSlot=754640 head=e26f2de5:4148 headEpoch=129 finalizedHead=9f8fdba9:4064 finalizedEpoch=127
Image for post
Image for post

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

Step 10— Install Prometheus

Prometheus is an open-source systems monitoring and alerting toolkit. It runs as a service on your Ubuntu server and its job is to capture metrics. More information here.

Create User Accounts

Accounts for the services to run under. These accounts can’t log into the server.

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

Create Directories

Program and data 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

Adjust the version number to the latest version from the Prometheus download page. Rpi users be sure to get the ARM binary.

$ cd ~
$ curl -LO https://github.com/prometheus/prometheus/releases/download/v2.20.1/prometheus-2.20.1.linux-amd64.tar.gz
$ tar xvf prometheus-2.20.1.linux-amd64.tar.gz
$ sudo cp prometheus-2.20.1.linux-amd64/prometheus /usr/local/bin/
$ sudo cp prometheus-2.20.1.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.1.linux-amd64/consoles /etc/prometheus
$ sudo cp -r prometheus-2.20.1.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.1.linux-amd64.tar.gz prometheus-2.20.1.linux-amd64

Edit the Configuration File

Prometheus uses a configuration file so it knows where to scrape the data from. We will set this up here.

$ sudo nano /etc/prometheus/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'nimbus'
static_configs:
- targets: ['localhost:8008']
- 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-09-12T22:16:21.179Z caller=web.go:524 component=web msg="Start listening for connections" address=0.0.0.0:9090
level=info ts=2020-09-12T22:16:21.181Z caller=main.go:700 fs_type=EXT4_SUPER_MAGIC
level=info ts=2020-09-12T22:16:21.181Z caller=main.go:701 msg="TSDB started"
level=info ts=2020-09-12T22:16:21.182Z caller=main.go:805 msg="Loading configuration file" filename=/etc/prometheus/prometheus.yml
level=info ts=2020-09-12T22:16:21.182Z caller=main.go:833 msg="Completed loading of configuration file" filename=/etc/prometheus/prometheus.yml
level=info ts=2020-09-12T22:16:21.183Z caller=main.go:652 msg="Server is ready to receive web requests."

Set Prometheus to Auto-Start as a Service

Create a systemd service file to store the service config which tells systemd to run Prometheus as the prometheus user, with the configuration file located in the /etc/prometheus/prometheus.yml directory, and to store its data in the /var/lib/prometheus directory.

$ 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
Image for post
Image for post
$ sudo systemctl enable prometheus

Step 11 — Install Node Exporter

Prometheus will provide metrics about the beacon chain and validators. If we want metrics about our Ubuntu instance, we’ll need an extension called Node_Exporter. You can find the latest stable version here if you want to specify a different version below. Rpi users remember to get the ARM binary.

$ 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

Create a systemd service file to store the service config which tells systemd to run Node_Exporter as the node_exporter user.

$ 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
Image for post
Image for post
$ sudo systemctl enable node_exporter

Test Prometheus and Node Exporter (Optional)

Everything should be ready to go. You may optionally test the functionality by opening a port in the firewall (see Step 1) and browsing to http://<yourserverip>:9090. From there you can run queries to view different metrics. For example try this query to see how much memory is free in bytes:

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

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

Step 12— Install Grafana

While Prometheus is our data source, Grafana is going provide our reporting dashboard capability. Let’s install it and configure a dashboard.

$ 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.5
Version table:
7.1.5 500
500 https://packages.grafana.com/oss/deb stable/main amd64 Packages
7.1.4 500
500 https://packages.grafana.com/oss/deb stable/main amd64 Packages
7.1.3 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
Image for post
Image for post
$ sudo systemctl enable grafana-server

Configure Grafana Login

Great job on getting this far! Now that you have everything up and running you can go to http://<yourserverip>:3000/ in a browser and the Grafana login screen should come up.

Configure the Grafana Data Source

Let’s configure a datasource. Move your mouse over the gear icon on the left menu bar. A menu will pop-up — choose Data Sources.

Image for post
Image for post
Image for post
Image for post
Image for post
Image for post

Import a Grafana Dashboard

Now let’s import a dashboard. Move your mouse over the + icon on the left menu bar. A menu will pop-up - choose Import.

Image for post
Image for post

Final Remarks

Okay… That’s it! We are done! I hope you enjoyed this guide.

  • If you liked this guide and think others would benefit from it then please share it using the friends link!
  • Tips appreciated: somer.eth

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

Appendix — Updating Nimbus

If you need to update the code due to changes in the Git repository follow these steps to get the latest files and build your binaries:

$ cd ~
$ cd nimbus-eth2
$ git pull
$ make update
$ make NIMFLAGS="-d:insecure" medalla-build
$ sudo systemctl stop nimbus
$ sudo cp /$HOME/nimbus-eth2/build/nimbus_beacon_node_spec_0_12_3 /usr/local/bin
$ sudo systemctl start nimbus
$ sudo systemctl status nimbus # <-- Check for errors
$ sudo journalctl -fu nimbus.service # <-- Monitor

Appendix — Updating Geth

If you need to update to the latest version of Geth follow these steps:

$ sudo systemctl stop geth
$ sudo systemctl stop nimbus
$ sudo apt update && upgrade
$ sudo systemctl start geth
$ sudo systemctl status geth # <-- Check for errors
$ sudo journalctl -f -u geth # <-- Monitor
$ sudo systemctl start nimbus
$ sudo systemctl status nimbus # <-- Check for errors
$ sudo journalctl -f -u nimbus.service # <-- Monitor

Passionate about Ethereum and decentralized technology.

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