How to setup an Ethereum node on Raspberry Pi

Introduction

Raspberry Pi is a small single board computer that can be used to run a local Ethereum node. While many users operate nodes with cloud service providers, this can be expensive overtime, especially for full nodes of the mainnet, but Raspberry Pi has a low barrier to entry to get started with a local node setup. Raspberry Pi, and other single board computers, consume far less energy than a tradtional server or desktop machine and a Raspberry Pi's storage can be expanded through external hard drive solutions; NAS, RAID, and other external storage.

What you'll learn

  • Setup a Rasberry Pi 4 Model B with Ubuntu-LTS & Core-geth
  • Run Core-geth to provide the ETC, ETH, or related test networks.

Step 01 - Requirements

  • Computer: A computer to setup your microSD card and remotely access the Raspberry Pi.
  • Internet: An internet connection to provide internet via Wifi or Etherent cable (recommend) to the Raspberry Pi.
    • Ethernet cable (optional/ recommended) : To connect the Raspberry Pi to internet.
  • Raspberry Pi 4 Model B / 4 GB RAM: Core-geth requires a minimum of 4 GB of RAM. On full size servers, you can get away with 2 GB RAM with additional Swap memory, but at least 4 GB is recommended.
    • USB-C 5.1V 3A Power Supply: To supply the Pi with power.
    • Micro SD Card >= 16 GB: The SD Card stores the operating system ready to use in the Raspberry Pi device.

Step 02 - Install Ubuntu on your Raspberry Pi

  1. Complete the How to install Ubuntu on your Raspberry Pi guide.

If you're having trouble determining the Raspberry Pi's IP address to SSH into it, then try using nmap as explained here.

Step 03 - Initial Server Setup

After completing Step 02, you should be able to remotely access the Raspberry Pi. Let's just call in an Ubuntu server for now. At this point the Ubuntu server is still fresh and requires some optimizations and software.

1. Update & upgrade Ubuntu system & other software.

updatesystem deps

Update the operating system

sudo apt-get update && sudo apt-get upgrade

Install unzip

sudo apt install unzip

Setup go-lang

sudo snap install go --classic

Install make

sudo apt install make

Install htop

sudo apt install htop

Install build-essentials

sudo apt-get install build-essential

2. Assign a static IP address.

edit-netplan

View IP address

ip addr show

You may see a dynamic IP address (the same IP used to SSH) has been assigned to interface card "eth0". To make this IP address static, edit the netplan configuration file "/etc/netplan/50-cloud-init.yaml” using vim, nano, vi, or whatever terminal text editor you prefer.

network:
        ethernets:
            eth0:
                addresses: [192.168.1.144/24]
                gateway4: 192.168.1.1
                nameservers:
                    addresses: [4.2.2.2, 8.8.8.8]
        version: 2

Using your IP address and the example yaml file above. Edit /etc/netplan/50-cloud-init.yaml in vim

sudo vim /etc/netplan/50-cloud-init.yaml

Vim tip: i to enter insert mode to begin editing the text. Esc to exit insert mode. :wq to save the changes.

Apply the new netplan

sudo netplan apply

Check the changes were applied

ip addr show && ip route show

Reboot

sudo reboot

Step 04 - Mount HDD/ SSD.

Storing the state of the blockchain requires more sufficient memory resources. Extending memory resources to the Raspberry Pi is quite simple since it has many USB ports to plug in an external HHD/ SSD, RAID, NAS, or whatever storage configuration you prefer.

1. Identify the disk & Mount the disk

It will be "/dev/sda". In many cases it's "/dev/sda" or "/dev/sda1", "/dev/sda2", etc...

List available disks

sudo fdisk -l

Create a partition for the disk.

sudo mkfs.ext4 /dev/sda

Mount the disk

sudo mkdir /mnt/ssd

sudo chown -R ubuntu:ubuntu /mnt/ssd/ # "ubuntu" is the default hostname

sudo mount /dev/sda /mnt/ssd # mount the disk "dev/sda" to "/mnt/ssd"

2. Automatically mount disk on startup

Get the unique ID of the disk (UUID="<the-unique-id>")

sudo blkid

Edit the /etc/fstab file, inserting the below example at the end of the file.

sudo vim /etc/fstab

Insert "UID=b2907e9d-1a37-4f26-8d43-b51ff3e1c66f /mnt/ssd ext4 defaults 0 0" at the end of the file with your disks UUID.

Reboot

sudo reboot

Check the disk was mounted

df -ha /dev/sda

Step 05 - Add Swap Space

Swap is a space on a disk that is used when the amount of physical RAM memory is full. Geth can consume a lot of memory during sync and setting up a Swap helps mitigate out-of-memory errors.
  1. Since the device is Ubuntu-LTS, simply follow this external tutorial on adding Swap space to your Ubuntu: https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-20-04

Step 05 - Install Core-geth

1. Build from source

installgeth

Clone the repo & change directory into the source

git clone https://github.com/etclabscore/core-geth.git && cd core-geth/

Make geth

make geth # this may take a few minutes

Move the built geth binary to the /bin/ directory

sudo mv ~/core-geth/build/bin/geth /bin/

2. Check installation

geth version

View usage and commands

geth --help

Congrats Core-geth is installed!

Step 06 - Run Core-geth

By default, geth will store data in ~/.ethereum/geth/ on the microSD card, but you want to store data on the external disk space NOT the SD card.

The --datadir <PATH> tells geth to use a specific directory (your external disk).

The --cache <VALUE> tells geth to use a set amount of RAM in Megabytes. Since the device has 4 GB of RAM, --cache 256 should mitigate out-of-memory errors, but might not be required if Swap memory is setup.

The --syncmode fast tells geth to synchronise in fast mode.

1. Create a data directory on the external disk.

It's best practice to name the directory based on the specific network to be run.

Make the data directory

sudo mkdir /mnt/ssd/ethereum/ # ethereum example

sudo mkdir /mnt/ssd/classic/ # ethereum classic example

2. Run geth <commands> <datadirectory>

geth --syncmode fast --cache 256 --datadir /mnt/ssd/ethereum # ethereum

geth --classic --syncmode fast --cache 256 --datadir /mnt/ssd/classic # ethereum classic

By default, Geth runs in the foreground of the terminal/ command prompt. To run geth in the background simply use nohup in the beginning and & at the end of the command. Example:

nohup geth --classic --syncmode fast --cache 256 --datadir /mnt/ssd/classic # ethereum classic &

Check geth process is running and current resource consumption using htop

htop

Ctrl + Z to exit htop.

Some tips

View syncing status using Geth Console

view-sync-status

sudo geth attach ipc:/mnt/ssd/classic/geth.ipc

# once entered in the geth console use "eth.syncing" to return current syncing status

> eth.syncing

# type "exit" to exit the geth console