Ethereum Validator Setup

Contents

Preparing your Machine

BIOS

One small tweak in the BIOS: enable the “restore power on AC loss” flag, so that the server will automatically turn back on after a power loss.

Networking

External Firewall (Port Forwarding)

  1. For SSH I don’t need remote access most of the time, so I don’t allow port 22 through the firewall by default. https://unifi.ui.com lets me remote in to my firewall and change these settings when needed.
  2. For the execution client (besu), we’ll foreward 30303
  3. For the consensus client (prysm), we’ll foreward 9001

LAN Segregation

To keep the node maximally segregated from internal threats, I’ve put the node onto its own LAN with no other clients.

  1. Physically plug the node directly into the LAN2 port on the USG
  2. Enable the LAN2 port on the USG (in the USG settings)
  3. Create a new Network under Settings > Networks and assign it to the LAN2 Network Group. I’m using a /30 subnet so that there is only a single usable IP (the node’s).
  4. Assign the node a fixed IP (the only IP) on the LAN2 network via the node’s client settings.
  5. Add rule to firewall to reject inter-LAN communication. I’m using a reject ALL from Network:default to Network:LAN2

Operating System Hardening

Follow the steps listed under Ubuntu Hardening.

Mounting Additional Storage

I’ll be storing the blockchain state itself on a disk seperate from the operating system & binaries.

First we need to identify the disk: sudo fdisk -l (It should be something like /dev/sda or /dev/sdb). As a sanity check, we can use sudo blkid to view existing partitions (only the OS disk will show up).

Once the disk is identified, create the partition: sudo cgdisk /dev/sda

Then format the new partition: sudo mkfs -t ext4 /dev/sda1

Create a mount point: sudo mkdir /mnt/storage

Run sudo blkid and take note of the UUID, add this line into /etc/fstab to make the mount point permanent between restarts:

UUID=""  /mnt/storage  ext4  defaults  0  2

Finally, mount manually without rebooting as a test: sudo mount -av


Goerli Testnet Setup

Before jumping in to staking on mainnet, let’s spend some time getting comfortable using the various ethereum clients by setting up against the Goerli testnet.

Obtaining Goerli Eth

To stake we’ll need 32 eth, plus a bit extra for various transaction fees. One way to get this is by going through the verification process in the ethstaker discord. However I found it easier to use a PoW faucet, which takes some time (about half a day) but does not require any other verifications: goerli-faucet.pk910.de.

Additional faucet can be found here: faucetlink.to/goerli


Rocketpool Setup

For my node I’ll be using Rocketpool, for three main reasons:

  • the ability to stake in 16 ETH increments
  • access to a smoothing pool
  • commission on staking for rETH holders

There are of course downsides to using Rocketpool

  • forced to stake RPL collatoral (think of this as the price you pay to earn commissions)
  • smart contract risk

Rocketpool has excellent docs on how to set up their software, so I won’t be duplicating everything here, but will make note of my choices along the setup path.

1) https://docs.rocketpool.net/guides/node/eth-clients.html

For my clients I selected:

  • Besu for execution, primarily because it’s minority & does not require offline pruning
  • Prysm for consensus

Note: Since launch I have now switched to Geth + Teku. I switched to Geth because I found Besu to be far to unstable. I switched to Teku to facilitate this change (it has better failover node features). Note: For Teku, it defaults to archive mode in rocketpool config. This can be disabled since I’m not going to build the oDAO reward trees.

2) https://docs.rocketpool.net/guides/node/install-modes.html

For an install mode, I went with the default docker configuration. I’m already very comfortable with docker so may as well stick with the default for simplicity.

Rocket Arb

If there is a premium on rETH at the time of creating the minipool, there is an opportunity to capture a MEV arbitrage. This is because when you launch a minipool it will create 16 ETH worth of space into the deposit pool. The arb looks like this:

  1. Launch the minipool, creating 16 ETH worth of space in the deposit pool
  2. Take a 16 ETH flash loan
  3. Deposit the 16 ETH into the deposit pool, receiving rETH in return
  4. Sell the rETH on a DEX (1inch)
  5. Repay the flash loan, and keep the profits.

At the time I launched my minipool there was no rETH premium. I have therefore not tested this library myself, but there exists a tool to assist with crafting these transactions here: https://github.com/xrchz/rocketarb

Notes mentioning this note