Guide to Staking on Ethereum 2.0 (Ubuntu/Lighthouse)
--
Last updated: 2022–04–16
NOTE: Do not use this guide. New version is here: https://someresat.medium.com/guide-to-staking-on-ethereum-ubuntu-lighthouse-773f5d982e03
This is a step-by-step guide to staking on the Ethereum 2.0 mainnet using the Sigma Prime Lighthouse client. It is based on the following technologies:
- Ubuntu v20.04 (LTS) x64 server
- Go Ethereum Node (code branch)
- Sigma Prime’s Ethereum 2.0 client, Lighthouse (code branch)
- MetaMask crypto wallet browser extension
WARNING: Staking requires at least 32 ETH + gas fees. DO NOT send ETH anywhere without knowing what you are doing. This guide includes instructions to safely deposit your ETH for staking on the Ethereum 2.0 mainnet using official methods. Never send your ETH to anyone.
Acknowledgements
This guide is based on information gathered from various on-line resources and wouldn’t exist without them. Thank you, all!
Thanks to the EthStaker Admins and Educators, the Eth2 client teams, and the staking community for their help and review.
Special thanks to the Eth2 client teams and the Ethereum Foundation researchers. Their tireless efforts over the past few years have brought us to the cusp of an incredible moment in history — the launch of Ethereum 2.0.
Disclaimer
This article (the guide) is for informational purposes only and does not constitute professional advice. The author does not guarantee accuracy of the information in this article and the author is not responsible for any damages or losses incurred by following this article. A full disclaimer can be found at the bottom of this page — please read before continuing.
Support
For technical support please reach out to:
- The EthStaker community on Reddit or Discord. Knowledgeable and friendly community passionate about staking on Ethereum 2.0.
- The Lighthouse client team Discord.
Prerequisites
This guide assumes knowledge of Ethereum, ETH, staking, Linux, and MetaMask (or Portis or Fortmatic).
This guide also requires the following before getting started:
- Ubuntu server v20.04 (LTS) amd64 or newer, installed and running on a local computer or in the cloud. A locally running computer is encouraged for greater decentralization — if the cloud provider goes down then all nodes hosted with that provider go down.
- MetaMask crypto wallet browser extension (or Portis or Fortmatic), installed and configured. A computer with a desktop (Mac, Windows, Linux, etc.) and a browser (Brave, Safari, FireFox, etc.) is required.
Testnet to Mainnet
If moving from a testnet setup to a mainnet setup it is strongly recommended that you start on fresh (newly installed) server instance. This guide has not been tested for migration scenarios and does not guarantee success if you are using an existing instance with previously installed testnet software.
Requirements
- Hardware requirements are a broad topic. In general a relatively modern CPU, 8GB RAM (16GB is better), a SSD of at least 500GB (1TB is better), and a stable internet connection with sufficient download speed and monthly data allowance are likely required for good staking performance.
NOTE: Check your available disk space. Even you have a large SSD there are cases where Ubuntu is reporting only 200GB free. If this applies to you then take a look at Appendix F— Expanding the Logical Volume.
Activation
Before we get started, a note on validator Activation.
As demand grows for staking, the queue to register new validators increases. Based on various factors, the Ethereum PoS network allows a fixed number validators to join per day. Depending on demand it might be hours, days, weeks, or months until your deposit becomes active and starts validating.
A handy app showing the current activation queue length and estimated activation time can be found here: https://eth2-validator-queue.web.app/
The screenshot above was taken on 04/16/2022, indicating a deposit into the ETH 2.0 staking contract on that day will incur a wait time to activation of roughly 16 days. This means once you queue your validator to join the network (by depositing your 32 ETH) it won’t be eligible to participate in staking or to earn staking rewards until it is activated.
NOTE: As stated at the beginning of this guide, DO NOT deposit your ETH without understanding what you are doing. DO NOT send your ETH to the ETH 2.0 deposit contract without following the detailed instructions in this guide.
Overview
The simplified diagram below indicates the scope of this guide. The yellow boxes are the areas this guide mostly covers.
The conceptual flow through the guide is:
- Generate the staking Validator Keys and Deposit Data
- Prepare the Ubuntu Server (firewall, security, etc.)
- Set up an Eth1 Node and sync it with the Eth1 Blockchain
- Configure the Lighthouse client and sync it with the Eth1 Node
- Deposit ETH to Activate Validator Keys
Let’s get started!
Step 1 — Generate Staking Data
In order to participate in staking it is necessary to generate some data files based on the number of validators you’d like to fund and operate.
NOTE: If you have already generated your deposit data and validator key(s) you can skip this step.
Each validator requires a deposit of 32 ETH. You should have sufficient ETH in your MetaMask wallet to fund each validator. For example if you plan to run 5 validators you will need to have (32 x 5) = 160 ETH plus some extra to cover the gas fees. The ETH deposit will happen later in the guide after everything else is up and running.
Download the Deposit Tool (Deposit CLI)
Go here to get the “Latest release” of the deposit command line interface (CLI) app.
In the Assets section download the version matching the platform you are currently on (e.g. Windows, Mac, Linux Desktop, etc.).
Run the Deposit Tool (Eth2 Deposit CLI)
Decompress the archive. There should be a binary file (executable) inside. The deposit tool generates files for staking as well as a mnemonic key. This key must be handled securely. There are two options to proceed from here.
Recommended — Copy the binary file to a USB drive. Connect to a fully air-gapped machine (never previously connected to the internet), copy the file over and run from there.
Not recommended — Run from the current machine. An internet connection may be an opportunity to leak your mnemonic key. If a fully air-gapped machine isn’t available disconnect the internet on the current machine before proceeding.
When ready, run the file in a terminal window (or CMD in Windows) to continue using the commands below. Replace <NumberOfValidators>
with the number of validators you want to fund. E.g. --num_validators 2
.
On Linux/Mac:
./deposit new-mnemonic --num_validators <NumberOfValidators> --chain mainnet
On Windows:
deposit.exe new-mnemonic --num_validators <NumberOfValidators> --chain mainnet
Once you execute the above steps on your platform of choice you will be asked to create a validator keystore password. Back it up somewhere safe. You will need this later to load the validator keys into the Lighthouse validator wallet.
A seed phrase (mnemonic) will be generated. Back it up somewhere safe. This is CRITICAL. You will eventually use this to generate your withdrawal keys for your ETH or add additional validators. If you lose this key you will not be able to withdraw your funds.
Once you have confirmed your mnemonic your validator keys will be created.
The newly created validator keys and deposit data file are created at the specified location. The contents of the folder are shown below.
Notes about the files:
- The
deposit_data-[timestamp].json
file contains the public keys for the validators and information about the staking deposit. This file will be used to complete the ETH deposit process later on. - The
keystore-m...json
files contain the encrypted validator signing key. There is one keystore-m per validator that you are funding. These will be imported into the Lighthouse validator wallet for use while staking. You will copy these files over to the Ubuntu server (if not already there) later.
Final Steps
Now that you have the deposit data and the keystore files move on to set up the Ubuntu server.
DO NOT DEPOSIT any ETH at this moment.
It is important to complete and verify your staking setup first. If the ETH deposits become active and your staking setup is not ready you will start receiving penalties for non-activity.
Step 2 — Connect to the Server
Using a SSH client, connect to your Ubuntu server. If you are logged in as root
then create a user-level account with admin privileges instead, since logging in as the root user is risky.
NOTE: If you are not logged in as
root
then skip this and go to Step 3.
Create a new user. Replace <yourusername>
with a username of your choice. You will asked to create a strong password and provide some other optional information.
# adduser <yourusername>
Grant admin rights to the new user by adding it to the sudo
group. This will allow the user to perform actions with superuser privileges by typing sudo
before commands.
# usermod -aG sudo <yourusername>
Optional: If you used SSH keys to connect to your Ubuntu instance via the root
user you will need to associate the new user with the root user’s SSH key data.
# rsync --archive --chown=<yourusername>:<yourusername> ~/.ssh /home/<yourusername>
Finally, log out of root
and log in as <yourusername>
.
Step 3 — Update the Server
Make sure the system is up to date with the latest software and security updates.
$ sudo apt update && sudo apt upgrade
$ sudo apt dist-upgrade && sudo apt autoremove
$ sudo reboot
Step 4 — Secure the Server
Security is important. This is not a comprehensive security guide, just some basic settings.
Modify the Default SSH Port
Port 22 is the default SSH port and a common attack vector. Change the SSH port to avoid this.
Choose a port number between 1024–49151 and run the following command to check is not already in use. A blank response indicates not in use, a red text response indicates it is in use: try a different port. E.g. sudo ss -tulpn | grep ':6673'
$ sudo ss -tulpn | grep ':<YourSSHPortNumber>'
If confirmed available, modify the default port by updating SSH config.
$ sudo nano /etc/ssh/sshd_config
Find or add (if not present) the line Port 22
in the file. Remove the #
(if present) and change the value as below.
Port <YourSSHPortNumber>
Check the screen shot below for reference. Press CTRL+x then ‘y’ then <enter> to save and exit.
Restart the SSH service to reflect the above changes.
$ sudo systemctl restart ssh
Log out and log back in via SSH using <YourSSHPortNumber>
for the port.
Configure the Firewall
Ubuntu 20.04 servers can use the default UFW firewall to restrict inbound traffic to the server. Before you enable it allow inbound traffic for SSH, Go Ethereum, and Lighthouse.
Install UFW
UFW should be installed by default. The following command will ensure it is.
$ sudo apt install ufw
Apply UFW Defaults
Explicitly apply the defaults. Inbound traffic denied, outbound traffic allowed.
$ sudo ufw default deny incoming
$ sudo ufw default allow outgoing
Allow SSH
Allow inbound traffic on <YourSSHPortNumber>
as set above. SSH requires the TCP protocol. E.g. sudo ufw allow 6673/tcp
$ sudo ufw allow <yourSSHportnumber>/tcp
Deny SSH Port 22
Deny inbound traffic on port 22/TCP.
NOTE: Only do this after you SSH in using
<YourSSHPortNumber>
.
$ sudo ufw deny 22/tcp
Allow Go Ethereum
Allow P2P connections with Go Ethereum peers (port 30303). If using an Eth1 node hosted by a 3rd party then skip this step.
NOTE: If you are hosting your Ubuntu instance locally your internet router may need to be configured to allow incoming traffic on port 30303 as well.
$ sudo ufw allow 30303
Allow Lighthouse
Allows P2P connections with Lighthouse peers for actions on the beacon node (port 9000).
NOTE: If you are hosting your Ubuntu instance locally your internet router may need to be configured to allow incoming traffic on port 9000 as well.
$ sudo ufw allow 9000
Enable the firewall and verify the rules have been correctly configured.
$ sudo ufw enable
$ sudo ufw status numbered
Check the screen shot below for reference.
Step 5 — Configure Timekeeping
Ubuntu has time synchronization built in and activated by default using systemd’s timesyncd service. Verify it’s running correctly.
$ timedatectl
The NTP service
should be active
. If not then run:
$ sudo timedatectl set-ntp on
Check the screen shot below for reference.
You should only be using a single keeping service. If you were using NTPD from a previous installation you can check if it exists and remove it using the following commands.
$ ntpq -p
$ sudo apt-get remove ntp
Step 6 — Set up an Ethereum (Eth1) Node
An Ethereum node is required for staking. You can either run a local Eth1 node or use a third party node. This guide will provide instructions for running Go Ethereum. If you would rather use a third party option then skip this step.
NOTE: Check your available disk space. An Eth1 node requires roughly 400GB of space. Even you have a large SSD there are cases where Ubuntu is reporting only 200GB free. If this applies to you then take a look at Appendix F — Expanding the Logical Volume.
Install Go Ethereum
Install the Go Ethereum client using PPA’s (Personal Package Archives).
$ sudo add-apt-repository -y ppa:ethereum/ethereum
$ sudo apt update
$ sudo apt install geth
Go Ethereum will be configured to run 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
Create the data directory for the Eth1 chain. This is required for storing the Eth1 node data.
$ sudo mkdir -p /var/lib/goethereum
Set directory permissions. The goeth
account needs permission to modify the data directory.
$ sudo chown -R goeth:goeth /var/lib/goethereum
Create a systemd service config file to configure the service.
$ sudo nano /etc/systemd/system/geth.service
Paste the following service configuration into the file.
[Unit]
Description=Go Ethereum Client
After=network.target
Wants=network.target[Service]
User=goeth
Group=goeth
Type=simple
Restart=always
RestartSec=5
ExecStart=geth --http --datadir /var/lib/goethereum --cache 2048 --maxpeers 30[Install]
WantedBy=default.target
Notable flags:
--http
Expose an HTTP endpoint (http://localhost:8545) that the Lighthouse beacon chain will connect to.
--cache
Size of the internal cache in GB. Reduce or increase depending on your available system memory. A setting of 2048
results in roughly 4–5GB of memory usage.
--maxpeers
Maximum number of peers to connect with. More peers equals more internet data usage. Do not set this too low or your Eth1 node will struggle to stay in sync.
Check the screen shot below for reference. Press CTRL+x then ‘y’ then <enter> to save and exit.
Reload systemd to reflect the changes and start the service. Check status to make sure it’s running correctly.
$ sudo systemctl daemon-reload
$ sudo systemctl start geth
$ sudo systemctl status geth
Check the screen shot below for reference.
It should say active (running) in green text. If not then go back and repeat the steps to fix the problem. Press Q to quit (will not affect the geth service).
Enable the geth service to automatically start on reboot.
$ sudo systemctl enable geth
The Go Ethereum node will begin to sync. You can follow the progress or check for errors by running the following command. Press CTRL+c to exit (will not affect the geth service).
$ sudo journalctl -fu geth.service
Check the screen shot below for reference.
Check Sync Status
To check your Eth1 node sync status use the following command to access the console.
geth attach http://127.0.0.1:8545
> eth.syncing
If false
is returned then your sync is complete. If syncing data is returned then you are still syncing. For reference there are roughly 700–800 million knownStates
.
Check the screen shot below for reference.
Press CTRL+d to exit when done.
Check Connected Peers
To check your Eth1 node connected peers use the following command to access the console.
geth attach http://127.0.0.1:8545
> net.peerCount
The peerCount
will not exceed your setting for --maxpeers
. If you are having trouble finding peers to sync see the next section.
Press CTRL+d to exit when done.
Add Bootnodes (Optional)
Sometimes it can take a while to find peers to sync. If so, you can add some bootnodes to help things along. Go here for the latest list and modify the geth service as follows:
$ sudo systemctl stop geth
$ sudo nano /etc/systemd/system/geth.service
Modify the ExecStart line and add the --bootnodes
flag with a few of the latest peers, comma separated.
ExecStart=geth --http --datadir /var/lib/goethereum --cache 2048 --maxpeers 30 --bootnodes "enode://d0b4a09d072b3f021e233fe55d43dc404a77eeaed32da9860cc72a5523c90d31ef9fab7f3da87967bc52c1118ca3241c0eced50290a87e0a91a271b5fac8d0a6@157.230.142.236:30303,enode://5070366042daaf15752fea340e7ffce3fd8fc576ac846034bd551c3eebac76db122a73fe8418804c5070a5e6d690fae133d9953f85d7aa00375d9a4a06741dbc@116.202.231.71:30303"
Save the file and exit. Restart the service and observe.
$ sudo systemctl daemon-reload
$ sudo systemctl start geth
$ sudo journalctl -fu geth.service
NOTE: It is necessary to follow a specific series of steps to update Geth. See Appendix A — Updating Geth for further information.
NOTE: From time-to-time it is necessary to “prune” Geth’s database to keep its size on disk as small as possible. See Appendix D — Pruning Geth for further information.
Step 7 — Download Lighthouse
The Lighthouse client is a single binary which encapsulates the functionality of the beacon chain and validator. This step will download and prepare the Lighthouse binary.
First, go here and identify the latest release. It is at the top of the page. For example:
In the assets section (expand if necessary) copy the download link to the lighthouse-v…-x86_64-unknown-linux-gnu.tar.gz file. Be sure to copy the correct link.
NOTE: There are two types of binaries — portable and non-portable. The difference is explained here. Portable works on a broader set of hardware but comes with a 20% performance cost.
Download the archive using the commands below. Modify the URL in the instructions below to match the download link for the latest version.
$ cd ~
$ sudo apt install curl
$ curl -LO https://github.com/sigp/lighthouse/releases/download/v1.4.0/lighthouse-v1.4.0-x86_64-unknown-linux-gnu.tar.gz
Extract the binary from the archive and copy to the /usr/local/bin
directory. The Lighthouse service will run it from there. Modify the URL name as necessary.
$ tar xvf lighthouse-v1.4.0-x86_64-unknown-linux-gnu.tar.gz
$ sudo cp lighthouse /usr/local/bin
Use the following commands to verify the binary works with your server CPU. If not, go back and download the portable version and redo the steps to here and try again.
$ cd /usr/local/bin/
$ ./lighthouse --version # <-- should display version information
NOTE: There has been at least one case where version information is displayed yet subsequent commands have failed. If you get a
Illegal instruction (core dumped)
error while running theaccount validator import
command (next step), then you may need to use the portable version instead.
Clean up the extracted files.
$ cd ~
$ sudo rm lighthouse
$ sudo rm lighthouse-v1.4.0-x86_64-unknown-linux-gnu.tar.gz
NOTE: It is necessary to follow a specific series of steps to update Lighthouse. See Appendix B — Updating Lighthouse for further information.
Step 8 — Import the Validator Keys
Configure Lighthouse by importing the validator keys and creating the service and service configuration required to run it.
Copy the Validator Keystore Files
If you generated the validator keystore-m…json
file(s) on a machine other than your Ubuntu server you will need to copy the file(s) over to your home directory. You can do this using a USB drive (if your server is local), or via secure FTP (SFTP).
Place the files here: $HOME/eth2deposit-cli/validator_keys
. Create the directories if necessary.
Import Keystore Files into the Validator Wallet
Create a directory to store the validator wallet data and give the current user permission to access it. The current user needs access because they will be performing the import. Change <yourusername>
to the logged in username.
$ sudo mkdir -p /var/lib/lighthouse
$ sudo chown -R <yourusername>:<yourusername> /var/lib/lighthouse
Run the validator key import process. You will need to provide the directory where the generated keystore-m
files are located. E.g. $HOME/eth2deposit-cli/validator_keys
.
$ cd /usr/local/bin
$ lighthouse --network mainnet account validator import --directory $HOME/eth2deposit-cli/validator_keys --datadir /var/lib/lighthouse
You will be asked to provide the password for the validator keys. This is the password you set when you created the keys during Step 1.
You will be asked to provide the password for each key, one-by-one. Be sure to correctly provide the password each time because the validator will be running as a service and it needs to persist the password(s) to a file to access the key(s).
Note that the validator data is saved in the following location created during the keystore import process:
/var/lib/lighthouse/validators
.
Check the screen shot below for reference.
Restore default permissions to the lighthouse
directory.
sudo chown -R root:root /var/lib/lighthouse
The import is complete and the wallet is now set up.
NOTE: It is necessary to follow a specific series of steps to add an additional validator. See Appendix C — Adding a Validator for further information.
Step 9 — Configure the Beacon Node Service
In this step you will configure and run the Lighthouse beacon node as a service so if the system restarts the process will automatically start back up again.
Set up the Beacon Node Account and Directory
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 lighthousebeacon
Create the data directory for the Lighthouse beacon node database and set permissions.
$ 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
Check the screen shot below for reference.
Create and Configure the Service
Create a systemd service config file to configure the service.
$ sudo nano /etc/systemd/system/lighthousebeacon.service
Paste the following into the file.
[Unit]
Description=Lighthouse Eth2 Client 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 mainnet --datadir /var/lib/lighthouse --staking --eth1-endpoints http://127.0.0.1:8545[Install]
WantedBy=multi-user.target
Notable flags.
bn
subcommand instructs the lighthouse binary to run a beacon node.
--eth1-endpoints
One or more comma-delimited server endpoints for web3 connection. If multiple endpoints are given the endpoints are used as fallback in the given order. More information here and a list of 3rd party options here. For example:
--eth1-endpoints http://127.0.0.1:8545,https://your3rdpartynode
Check the screen shot below for reference. Press CTRL+x then ‘y’ then <enter> to save and exit.
Reload systemd to reflect the changes and start the service.
$ sudo systemctl daemon-reload
Note: If you are running a local Eth1 node (see Step 6) you should wait until it fully syncs before starting the lighthousebeacon service. Check progress here:
sudo journalctl -fu geth.service
Start the service and check to make sure it’s running correctly.
$ sudo systemctl start lighthousebeacon
$ sudo systemctl status lighthousebeacon
Check the screen shot below for reference.
If you did everything right, it should say active (running) in green text. If not then go back and repeat the steps to fix the problem. Press Q to quit (will not affect the lighthousebeacon service).
Enable the service to automatically start on reboot.
$ sudo systemctl enable lighthousebeacon
If the Eth2 chain is post-genesis the Lighthouse beacon chain will begin to sync. It may take several hours to fully sync. You can follow the progress or check for errors by running the journalctl
command. Press CTRL+c to exit (will not affect the lighthousebeacon service).
$ sudo journalctl -fu lighthousebeacon.service
A truncated view of the log shows the following status information.
[NOTE: A current issue is resulting in an incorrect error message.]
INFO Waiting for genesis
wait_time: 5 days 5 hrs, peers: 50, service: slot_notifier
Once the Eth2 mainnet starts up the beacon chain will automatically start processing. The output will give an indication of time to fully sync with the Eth1 node.
Step 10 — Configure the Validator Service
In this step you will configure and run the Lighthouse validator node as a service so if the system restarts the process will automatically start back up again.
Set up the Validator Node Account and Directory
Create an account for the validator node to run under. This type of account can’t log into the server.
$ sudo useradd --no-create-home --shell /bin/false lighthousevalidator
In Step 8 the validator wallet creation process created the following directory: /var/lib/lighthouse/validators
. Set directory permissions so the lighthousevalidator
account can modify that directory.
$ sudo chown -R lighthousevalidator:lighthousevalidator /var/lib/lighthouse/validators
$ sudo chmod 700 /var/lib/lighthouse/validators
$ ls -dl /var/lib/lighthouse/validators
Check the screen shot below for reference.
Create and Configure the Service
Create a systemd service file to store the service config.
$ sudo nano /etc/systemd/system/lighthousevalidator.service
Paste the following into the file.
[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 mainnet --datadir /var/lib/lighthouse --graffiti "<yourgraffiti>"[Install]
WantedBy=multi-user.target
Notable flags.
vc
subcommand instructs the lighthouse binary to run a validator node.
--graffiti "<yourgraffiti>"
Replace with your own graffiti string. For security and privacy reasons avoid information that can uniquely identify you. E.g. --graffiti "Hello Eth2! From Dominator"
.
Check the screen shot below for reference. Press CTRL+x then ‘y’ then <enter> to save and exit.
Reload systemd to reflect the changes and start the service and check to make sure it’s running correctly.
$ sudo systemctl daemon-reload
$ sudo systemctl start lighthousevalidator
$ sudo systemctl status lighthousevalidator
Check the screen shot below for reference.
If you did everything right, it should say active (running) in green text. If not then go back and repeat the steps to fix the problem. Press Q to quit (will not affect the lighthousevalidator service).
Enable the service to automatically start on reboot.
$ sudo systemctl enable lighthousevalidator
You can follow the progress or check for errors by running the journalctl
command. Press CTRL+c to exit (will not affect the lighthousevalidator service).
$ sudo journalctl -fu lighthousevalidator.service
A truncated view of the log shows the following status information.
INFO Lighthouse started version: Lighthouse/v1.4.0-c6baa0e
INFO Configured for testnet name: mainnet
WARN The mainnet specification is being used. This not recommended (yet).
INFO Starting validator client validator_dir: "/var/lib/lighthouse/validators", beacon_node: http://localhost:5052/
INFO Completed validator discovery new_validators: 0
INFO Enabled validator voting_pubkey: 0xaa...
INFO Enabled validator voting_pubkey: 0x90...
INFO Initialized validators enabled: 2, disabled: 0
INFO Connected to beacon node version: Lighthouse/v1.4.0-c6baa0e/x86_64-linux
INFO Starting node prior to genesis seconds_to_wait: 444946
INFO Waiting for genesis seconds_to_wait: 444946, bn_staking_enabled: true
For post-genesis deposits it may take hours or even days to activate the validator account(s) once the beacon chain has started processing.
Once the Eth2 mainnet starts up the beacon chain and validator will automatically start processing.
You can check the status of your validator(s) via beaconcha.in. Simply search for your validator public key(s) or search using your MetaMask (or other) wallet address. It may be a while before the data appears on the site.
Step 11 — Fund the Validator Keys
Now that your set up is up and running you will need to deposit ETH to fund your validators.
NOTE: If you have already submitted your staking deposits you can skip this step.
This step involves depositing the required amount of ETH to the Eth2.0 deposit contract. DO NOT SEND ETH TO THE DEPOSIT CONTRACT. This is done in a web browser running your MetaMask (or other) wallet via the Eth2.0 Launchpad website.
NOTE: Post-genesis, wait until your Eth1 node and beacon chain have fully synced before proceeding with the deposit. If you don’t Lighthouse will be inactive while the Eth1 node or beacon chain sync and you may be subject to inactivity penalties.
Go here: https://launchpad.ethereum.org/
Click through the warning steps and continue through the screens until you get to the Generate Key Pairs section. Select the number of validators you are going to run. Choose a value that matches the number of validator files you generated in Step 1.
Scroll down, check the box if you agree, and click Continue.
You will be asked to upload the deposit_data-[timestamp].json
file. You generated this file in Step 1. Browse/select or drag the file and click Continue.
Connect your wallet. Choose MetaMask (or one of the other supported wallets), log in, select the account where you have your ETH and click Continue.
Your MetaMask balance will be displayed. The site will allow you to continue if you have selected Mainnet and you have sufficient ETH balance.
A summary shows the number of validators and total amount of ETH required. Tick the boxes if you agree and click continue.
If you are ready to deposit click on Initiate All Transactions.
This will pop open MetaMask (or other wallet) where you can confirm each transaction.
Once all the transactions have successfully completed you are done!
Congratulations you have deposited your stake!
Check the Status of Your Validator Deposits
Newly added validators can take a while (hours to days) to activate. You can check the status of your keys with these steps:
- Copy your MetaMask (or other) wallet address.
- Go here: https://beaconscan.com/
- Search for your key(s) using your wallet address.
Diving into a specific validator you see a Status and an estimate until activation (Activation Epoch) for the validator.
You now have a functioning beacon chain and validator and your mainnet deposit is in. Once your deposit is active and the Ethereum 2.0 mainnet is running you will begin staking and earning rewards.
Congratulations: You are officially an Ethereum Staker!
Probably a good time to get a fresh beverage and hydrate.
Step 12 — Monitoring
Due to a few unresolved security concerns monitoring will be a near-future addition to this guide.
In the meantime, there is a monitoring option offered by beaconcha.in.
Final Remarks and Recommended Next Steps
Thanks for the opportunity. Hopefully this guide was helpful for you.
Next steps:
- Triple check all key and password backups.
- Reboot your machine and make sure the services come back up.
- Understand how to update the client and server software.
- Consider setting a max size for systemd journal logs. See Appendix F.
- Use
htop
to monitor resources on the local machine. - Get familiar with beaconcha.in so you can monitor your validators. They offer alerting (via email — sign up required) and monitoring.
- Join the Ethstaker and Lighthouse Discord for important notifications.
- Share any feedback for this guide on Discord, Twitter, or Reddit.
- Help others with their setup on the Ethstaker discord.
- Share this guide using the friend link!
- Tips: somer.eth
Further Reading
It is strongly recommended that you evaluate information from as many sources as possible. These are additional resources to help familiarize yourself with staking on Eth2.
The author has not tested or verified these resources. Use at your own risk.
- Client team official documentation Prysm | Lighthouse | Teku | Nimbus
- /r/EthStaker Sticky
- Unofficial docker environment for Ethereum 2.0 clients
- Setup an Eth2 Mainnet Validator System on Ubuntu
- Guide | How to setup a validator on ETH2 mainnet
- Guide | Security Best Practices for a ETH2 validator beaconchain node
- Additional Monitoring for ETH2 Staking Nodes
- Telegram Service for Ethereum 2.0 Staking
Appendix A — Updating Geth
If you need to update to the latest version of Geth follow these steps.
$ sudo systemctl stop lighthousevalidator
$ sudo systemctl stop lighthousebeacon$ sudo systemctl stop geth
$ sudo apt update && sudo apt upgrade
$ sudo systemctl start geth
$ sudo systemctl status geth # <-- Check for errors
$ sudo journalctl -fu geth # <-- Monitor$ sudo systemctl start lighthousebeacon
$ sudo systemctl status lighthousebeacon # <-- Check for errors
$ sudo journalctl -fu lighthousebeacon # <-- Monitor$ sudo systemctl start lighthousevalidator
$ sudo systemctl status lighthousevalidator # <-- Check for errors
$ sudo journalctl -fu lighthousevalidator # <-- Monitor
Appendix B — Updating Lighthouse
If you need to update to the latest version of Lighthouse follow these steps.
First, go here and identify the latest Linux release. Modify the URL in the instructions below to match the download link for the latest version.
NOTE: There are two types of binaries — portable and non-portable. The difference is explained here. Make sure you choose the correct type.
$ cd ~
$ sudo apt install curl
$ curl -LO https://github.com/sigp/lighthouse/releases/download/v1.4.0/lighthouse-v1.4.0-x86_64-unknown-linux-gnu.tar.gz
Stop the Lighthouse client services.
$ sudo systemctl stop lighthousevalidator
$ sudo systemctl stop lighthousebeacon
Extract the binary from the archive and copy to the /usr/local/bin
directory. Modify the URL name as necessary.
$ tar xvf lighthouse-v1.4.0-x86_64-unknown-linux-gnu.tar.gz
$ sudo cp lighthouse /usr/local/bin
Restart the services and check for errors.
$ sudo systemctl start lighthousebeacon
$ sudo systemctl status lighthousebeacon # <-- Check for errors
$ sudo journalctl -fu lighthousebeacon # <-- Monitor$ sudo systemctl start lighthousevalidator
$ sudo systemctl status lighthousevalidator # <-- Check for errors
$ sudo journalctl -fu lighthousevalidator # <-- Monitor
Clean up the extracted files.
$ cd ~
$ sudo rm lighthouse
$ sudo rm lighthouse-v1.4.0-x86_64-unknown-linux-gnu.tar.gz
Appendix C — Adding a Validator
If you want to add one or more validators to your existing validator wallet use the following steps.
NOTE: This appendix assumes that you have already followed the guide and completed all of the steps. Do not use this section to add validators to an empty validator wallet/incomplete setup.
Check Validator Queue Times
There may be a queue to activate a new validator on the ETH 2.0 mainnet. You can check current queue times by heading over here: https://eth2-validator-queue.web.app/
Generate Deposit Data
You will need to generate deposit data for your new validators. This will be used to add the new validators to your existing wallet.
Go here to get the “Latest release” of the deposit command line interface (CLI) app.
Transfer the binary to a USB stick and copy to an air-gapped machine for safety (recommended), or if not available, copy to a machine that is not connected to the net (not recommended).
When ready, run the file in a terminal window (or CMD in Windows) to continue using the commands below.
The existing-mnemonic
command is used to re-generate or derive new keys from your existing mnemonic. You will need to supply your mnemonic phrase to do this, hence the security requirements.
On Linux/Mac:
./deposit existing-mnemonic --validator_start_index <ValidatorStartIndex> --num_validators <NumberOfValidators> --chain mainnet
On Windows:
deposit.exe existing-mnemonic --validator_start_index <ValidatorStartIndex> --num_validators <NumberOfValidators> --chain mainnet
Replace <ValidatorStartIndex>
with the start index of the new validator(s) you are adding. For example: If you have 3 existing validators (#0, #1, #2) and you want to add two more, you would specify 3
(being the next number in the sequence) as the start index. E.g. --validator_start_index 3
.
NOTE: Double check the start index. Be sure you use the correct value.
Replace <NumberOfValidators>
with the number of validators you want to fund. Each validator will require a 32 ETH deposit to fund. E.g. from the example above, we are adding two new validators: --num_validators 2
.
Enter your mnemonic that you should have stored safely after creating your initial validator(s).
You will be asked to enter your validator keystore password. This password was set in Step 1. You can create a different password here, but it is recommended for simplicity to use the same password as the original keystore. Once you have confirmed your keystore password your validator keys will be created.
The newly created validator keys and deposit data file are created at the specified location. The contents of the folder are shown below.
Notes about the files:
- The newer
deposit_data-[timestamp].json
file contains the public keys for the newly added validators and information about the staking deposit. This file will be used to complete the ETH deposit process later on. - The newly created
keystore-m...json
files contain the encrypted validator signing key. There is one keystore-m per additional validator that you are funding. These will be imported into the Lighthouse validator wallet for use while staking. You will copy these files over to the Ubuntu server (if not already there) later.
DO NOT DEPOSIT any ETH at this moment.
It is important to complete and verify your staking setup first. If the ETH deposits become active and your staking setup is not ready you will start receiving penalties for non-activity. Let’s do that next.
Copy the Validator Keystore Files
If you generated the validator keystore-m…json
file(s) on a machine other than your Ubuntu server you will need to copy the file(s) over to your home directory. You can do this using a USB drive (if your server is local), or via secure FTP (SFTP).
Place the files here: $HOME/eth2deposit-cli/validator_keys
. Create the directories if necessary.
Import Keystore Files into the Validator Wallet
We are now ready to import the keystore-m…json
file(s) into our existing validator wallet.
First stop the validator. This is going to cause your validator to miss some attestations, but it is unavoidable. The loss of income is generally small.
$ sudo systemctl stop lighthousevalidator
The current user needs access because they will be performing the import. Change <yourusername>
to the logged in username.
$ sudo chown -R <yourusername>:<yourusername> /var/lib/lighthouse/validators
Run the validator key import process. You will need to provide the directory where the generated keystore-m
files are located. E.g. $HOME/eth2deposit-cli/validator_keys
. The wallet directory --datadir /var/lib/lighthouse
is also required.
$ cd /usr/local/bin
$ lighthouse --network mainnet account validator import --directory $HOME/eth2deposit-cli/validator_keys --datadir /var/lib/lighthouse
Enter the keystore password when prompted for each file.
If you have your original and new keystore-m
files in the directory you will be asked to enter the password for each file.
If you used a different password for the new files, you will need to use the original password for the existing keystore-m
files and the new password for the new keystore-m
files.
If you have your original keystore-m
files in the directory that have been previously added it will skip the import (since they are already in the validator wallet) and inform you:
Skipping import of keystore for existing public key: "/home/ethstaker/eth2deposit-cli/validator_keys/keystore-m_12381_3600_2_0_0-1616386570.json"
For the new keystore file(s) it will confirm the addition for each:
Keystore found at "/home/ethstaker/eth2deposit-cli/validator_keys/keystore-m_12381_3600_4_0_0-1616386614.json":- Public key: 0x87ad7e70c1e95c287a0666d723cc4575cb1ae3f972cdede9e5c64270229a0918165ecc72c8a2bf01ae49075a63c06681
- UUID: f38f9224-a95b-4820-b39e-0f1815a49c2aIf 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.
When the operation is complete it will display a summary. In this case, there were 3 keystore files that had previously been imported (skipped) and 2 new files that were imported.
Successfully imported 2 validators (3 skipped).
Next we restore the permissions to the validator directory.
$ sudo chown -R lighthousevalidator:lighthousevalidator /var/lib/lighthouse/validators
And then restart the validator and check for errors.
$ sudo systemctl start lighthousevalidator
$ sudo systemctl status lighthousevalidator # <-- Check for errors
$ sudo journalctl -fu lighthousevalidator # <-- Monitor
Note, although the service output may specify 0 new validators, the listing should contain the full set.
INFO Completed validator discovery new_validators: 0
INFO Enabled validator voting_pubkey: 0x969...97e
INFO Enabled validator voting_pubkey: 0x979...a89
INFO Enabled validator voting_pubkey: 0xac6...363
INFO Enabled validator voting_pubkey: 0x87a...681
INFO Enabled validator voting_pubkey: 0xb46...26a
INFO Initialized validators enabled: 5, disabled: 0
Now that the validators have been imported into your validator wallet and ready to perform duties, you will need to go over to Step 11 — Fund the Validator Keys above and fund the new validators via the Launchpad. You will need to upload the deposit_data-[timestamp].json
file that was created earlier in this section.
NOTE: The new validators will not be fully functional until you complete Step 11 and the validators clear the activation queue.
Appendix D — Pruning Geth
To avoid running out of disk space on your server, it may be useful to periodically run a prune operation on the Geth database. This operation will attempt to reduce the size of (prune) the Geth database. Thanks to Yorick Downe and his excellent guide for help with this section.
Some important prerequisites:
- Geth v1.10.3 or above must be installed. See Appendix A — Updating Geth for instructions to update if necessary.
- Geth must be fully synced. See Step 6 — Set up an Ethereum (Eth1) Node for instructions to check if it is fully synced.
- Geth logs are not showing “state snapshot generation” messages. You can see the service log output using
$ sudo journalctl -fu geth.service
. If it is, it should show an “eta” with a time interval. Allow that to elapse + 128 blocks (~35 mins) before starting the prune operation. - Geth will not be operating normally during the prune operation. The prune operation takes around 4–6 hours.
- To avoid disruption to your validator(s) during the prune operation, make sure a 3rd party
--eth1-endpoints
flag is set in the lighthousebeacon.service config. See Step 9 — Configure the Beacon Node Service. - There must be more than 25GB free space on your server for the prune to run without risk of failure. Check available space using the
df -h
command. For example, the output below shows the main partition is/dev/hda1
and there is 82GB free:
ethstaker@ETH-STAKER-002:~$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 3.9G 0 3.9G 0% /dev
tmpfs 796M 996K 795M 1% /run
/dev/hda1 155G 74G 82G 48% /
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/vda15 105M 5.2M 100M 5% /boot/efi
tmpfs 796M 0 796M 0% /run/user/1000
ethstaker@ETH-STAKER-002:~$
If you meet the pre-requisites above then continue on. If not, check for advice on how to proceed with the EthStaker community on Reddit or Discord.
Start the Prune Operation
To run the prune it is necessary to update the service configuration for Geth to add the required prune command.
Stop the geth service.
$ sudo systemctl stop geth
Observe the behavior of the Lighthouse validator. The beacon chain should fall back to the supplied 3rd party --eth1-endpoints
URL and the validator should continue its validation duties. Use the following commands to inspect the respective service logs.
$ sudo journalctl -fu lighthousebeacon.service
Open the geth service systemd configuration file.
$ sudo nano /etc/systemd/system/geth.service
Add the snapshot prune-state
instruction at the end of the ExecStart
line.
[Unit]
Description=Go Ethereum Client
After=network.target
Wants=network.target[Service]
User=goeth
Group=goeth
Type=simple
Restart=always
RestartSec=5
ExecStart=geth --http --datadir /var/lib/goethereum --cache 2048 --maxpeers 30 snapshot prune-state[Install]
WantedBy=default.target
Press CTRL+x then ‘y’ then <enter> to save and exit.
Reload systemd to reflect the changes and start the geth service. Check status to make sure it’s running correctly.
$ sudo systemctl daemon-reload
$ sudo systemctl start geth
$ sudo systemctl status geth
From Yorick’s guide:
Geth will prune in 3 stages: “Iterating state snapshot”, “Pruning state data”, and “Compacting database”. During the “Compacting database” stage, it may not output any log entries for an hour or so (mainstream SSD IOPS). Don’t restart it when this happens, let it run!
If you see messages about “generating snapshot” and an ETA during the prune, you don’t actually have a snapshot yet! Either the --datadir
and/or USER aren't right, or Geth just didn't have enough time to complete the snapshot. In that case, do stop the process, run Geth normally again, and observe its logs until snapshot has completed and is 128 blocks old.
Once the prune has completed open the geth service systemd configuration file.
$ sudo systemctl stop geth
$ sudo nano /etc/systemd/system/geth.service
Remove the snapshot prune-state
instruction at the end of the ExecStart
line.
[Unit]
Description=Go Ethereum Client
After=network.target
Wants=network.target[Service]
User=goeth
Group=goeth
Type=simple
Restart=always
RestartSec=5
ExecStart=geth --http --datadir /var/lib/goethereum --cache 2048 --maxpeers 30[Install]
WantedBy=default.target
Press CTRL+x then ‘y’ then <enter> to save and exit.
Reload systemd to reflect the changes and start the geth service. Check status to make sure it’s running correctly.
$ sudo systemctl daemon-reload
$ sudo systemctl start geth
$ sudo systemctl status geth # <-- Check for errors
$ sudo journalctl -fu geth.service # <-- Monitor
The Lighthouse beacon chain will automatically detect that Geth is back up and running and will swap back to using that as the primary Eth1 source. Again, you can check the service log to observe the behavior.
$ sudo journalctl -fu lighthousebeacon.service
The prune operation is now complete. You can check how much disk space was freed up using df -h
.
Appendix E — Clear Systemd Journal Logs
The systemd services create logs that grow over time. It is possible to clear the logs to free up disk space on your server.
NOTE: The following steps will delete existing log data. Be careful if you require this data for debugging purposes.
Check the amount of disk space the logs are using.
$ sudo journalctl --disk-usage
To clear the logs use the following command.
$ sudo journalctl --flush --rotate
$ sudo journalctl --vacuum-time=3days
The --flush
flag flushes the logs currently in memory onto the disk.
The --rotate
flag archives the existing logs so they can’t be written to any more and starts new logs for each service.
The --vacuum-time
flag deletes log data that is older than 3 days.
Output should be similar to the screenshot below.
It is recommended to check the logs are in a good state after the vacuum operation.
$ sudo journalctl --verify
Each log should have a status of PASS
.
Automatically Limit Log Size
If you would prefer to have the system automatically keep log data to a specified max size complete the following additional steps.
Open the systemd journal service configuration file.
$ sudo nano /etc/systemd/journald.conf
Carefully edit the file to set the maximum disk space that can be used by the journal in persistent storage. Remove the #
from the line SystemMaxUse
and add a value in megabytes, say 200M
.
Check the screen shot below for reference. Press CTRL+x then ‘y’ then <enter> to save and exit.
Restart the journald after updating the file.
$ sudo systemctl restart systemd-journald
Journal logs will now be limited to 200MB in size.
Appendix F — Expanding the Logical Volume
There are cases where Ubuntu is provisioning only 200GB of a larger SSD causing users to run out of disk space when syncing their Eth1 node. The error message is similar to:
Fatal: Failed to register the Ethereum service: write /var/lib/goethereum/geth/chaindata/383234.ldb: no space left on device
To address this issue, assuming you have a SSD that is larger than 200GB, expand the space allocation for the LVM by following these steps:
$ 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
That should resize your disk to the maximum available space.
If you need support on this please check with the EthStaker Discord.
Full Disclaimer
This article (the guide) is for informational purposes only and does not constitute professional advice. The author does not warrant or guarantee the accuracy, integrity, quality, completeness, currency, or validity of any information in this article. All information herein is provided “as is” without warranty of any kind and is subject to change at any time without notice. The author disclaims all express, implied, and statutory warranties of any kind, including warranties as to accuracy, timeliness, completeness, or fitness of the information in this article for any particular purpose. The author is not responsible for any direct, indirect, incidental, consequential or any other damages arising out of or in connection with the use of this article or in reliance on the information available on this article. This includes any personal injury, business interruption, loss of use, lost data, lost profits, or any other pecuniary loss, whether in an action of contract, negligence, or other misuse, even if the author has been informed of the possibility.