| |

Ethereum Node on a Raspberry Pi4

There is a wonderful out of the box SD card setup for ETH 1 and ETH 2 Raspberry Pi/Ubuntu nodes from ethereum.org, check those out if you want a simple, stable setup.

https://ethereum.org/en/developers/tutorials/run-node-raspberry-pi/

This tutorial is for those that already have a server setup but would also like to add an Ethereum node and needs to manually setup a Geth (we will be covering ETH 1 in this post).

While it is not recommend to run too much on your Raspberry Pi, Geth can be demanding, we can use the process we learn here for bigger more powerful machines.

The key to this install is adding an additional SSD HDD so let us do that.

Setting Up External SSD

Due to the size of the chain we need a large fast hard drive to store the block data. Another consideration is power consumption of the HDD/SSD, it will need to be powered eternally if the RasPi bus cannot deliver the power necessary. There is a wealth of reviews and specs online that will help you find the right drive, in general and pocket SSD will work just fine.

lsblk
sudo fdisk -l
sudo mkfs.ext4 /dev/sda

Filesystem UUID: a6bf4133-08f8-4b96-8fd5-cfbe14a88297

Manually, mount disk.

sudo mkdir /mnt/ssd
sudo chown -R pi:pi /mnt/ssd/
sudo mount /dev/sda /mnt/ssd

Automatically, configure fstab to automatically mount the disk when the system starts.

sudo blkid
sudo nano /etc/fstab

...add this at end ...

UUID=a6bf4133-08f8-4b96-8fd5-cfbe14a88297 /mnt/ssd ext4 defaults 0 0

Commit changes with a reboot.

sudo reboot

Verify that the drive started up with the rest of the system.

df -ha /dev/sda

Memory Swap to SSD

Now that we have a fast, large auto-mounting SSD we can use it to do a number of helpful things.

Using it for memory swap is one of those things. Geth can use a lot of memory crunching block so let us use some space on our SSD to alleviate the burden.

sudo nano /etc/dphys-swapfile

... add this to file ...
CONF_SWAPSIZE=8192
CONF_MAXSWAP=8192
CONF_SWAPFILE=/mnt/ssd/swap.file

... save and restart ...
sudo /etc/init.d/dphys-swapfile restart

sudo systemctl status dphys-swapfile.service

Checking Disk Performance

Let check or disk speed to see if we can successfully sync Geth.

Write Test

sudo dd if=/dev/zero  of=/mnt/ssd/deleteme.dat bs=32M count=64 oflag=direct
  • 64+0 records in
  • 64+0 records out
  • 2147483648 bytes (2.1 GB, 2.0 GiB) copied, 91.5097 s, 23.5 MB/s

Read Test

sudo dd if=/mnt/ssd/deleteme.dat of=/dev/null bs=32M count=64 iflag=direct
  • 64+0 records in
  • 64+0 records out
  • 2147483648 bytes (2.1 GB, 2.0 GiB) copied, 66.4352 s, 32.3 MB/s

Under 50MB/s is probably a no go, you might not be able to catch up to the head.

Port Forward

30303 from outside.

Stability

sudo nano /boot/config.txt

... add ...
gpu_mem=16
arm_64bit=1

Installing GoLang

Find the current download link for your processor and OS.

mkdir ~/download
cd ~/download
wget https://go.dev/dl/go1.17.7.linux-arm64.tar.gz

sudo tar -C /usr/local -xvf go1.17.7.linux-arm64.tar.gz
sudo chown root:root /usr/local/go
sudo chmod 755 /usr/local/go
sudo nano /etc/profile

... add this at end ...

export PATH=$PATH:/usr/local/go/bin

... save ...

sudo reboot

When it comes back online we can check that Go installed properly with the following command.

go version

go version go1.17.7 linux/arm64

Yay! Now we have go an can build and sync our ETH Node.

Installing Geth from Source

git clone https://github.com/ethereum/go-ethereum.git --branch v1.10.16
cd go-ethereum
make geth

... wait ...

... then move the binary ...

sudo mv ~/go-ethereum/build/bin/geth /usr/local/bin

geth version
  • Version: 1.10.16-stable
  • Git Commit: 20356e57b119b4e70ce47665a71964434e15200d
  • Architecture: arm64
  • Go Version: go1.17.7
  • Operating System: linux
  • GOPATH=
  • GOROOT=go

Sync It!

Set a folder on the SDD to hold the ETH files. Then use that folder to sync geth.

sudo mkdir /mnt/ssd/ethereum
sudo chown -R pi:pi /mnt/ssd/ethereum

... test it ...
geth --syncmode snap --cache 1024 --rpc --rpcaddr 0.0.0.0 --datadir /mnt/ssd/ethereum

Ctrl+C to stop so we can setup Geth as startup service. Also Check appendix to see the difference between -syncmode.

Geth Service

sudo nano /etc/systemd/system/geth.service

... add this ...

[Unit]
Description=Geth Node
After=network.target auditd.service
Wants=network.target
[Service]
WorkingDirectory=/home/pi
ExecStart=/usr/local/bin/geth --syncmode snap --cache 1024 --http --http.addr 0.0.0.0 --datadir /mnt/ssd/ethereum
User=pi
Group=pi
Restart=always
RestartSec=5s

[Install]
WantedBy=multi-user.target
Alias=geth.service

Run the Daemon

sudo systemctl daemon-reload
sudo systemctl start geth

sudo systemctl enable geth

systemctl status geth.service
tail -f /var/log/syslog

Watch the Daemon Work

Accessing the RPC

To open RPC communication, execute:

$ geth --cache=xxx --syncmode "xxx" --http --http.addr 0.0.0.0

http enable the HTTP-RPC server.

http.addr 0.0.0.0 allow other computers on the network to connect to Geth server.

The node is now accessible on http://<rp4_ip_address>:8545

The rp4_ip_address is accessible with ip command:

You can use https://metamask.io/ to test the node connection.

  • Select Custom RPC Network.
  • Add your node name and settings and save.

Attaching to the Node

//geth attach geth.ipc
geth attach http://localhost:8545

net.listening   # are we able to get connections?
net.peerCount   # how many other nodes are we connected to
admin.peers     # list of peers we are connected to
admin.nodeInfo  # info about the node
eth.syncing     # are we syncing? how much work left to do?

Syncing

Just spun it up, so I will report back when it finishes with an update, bug fixes and/or some insights. Probably a couple of days, ciao!

Pfau

References

sudo apt-get install git sysstat -y
htop
vcgencmd measure_temp

https://core-geth.org/setup-on-raspberry-pi

https://greg.jeanmart.me/2020/02/23/running-an-ethereum-full-node-on-a-raspberrypi-4-/

Blockchain Caffe

https://raphaelpralat.medium.com/start-an-ethereum-node-on-a-raspberry-pi-4-with-geth-ba13d9f57ef8

https://github.com/ethereum/go-ethereum/issues/16796

#!/bin/bash

## DEFINE PARAMS
SYNCM="--syncmode fast"
CACHE="--cache 256"
GARBC="--gcmode full"
DATAD="--datadir /mnt/Ethereum/geth/datadir"

IDENT="--identity BlockchainCaffe"
#ETHST="--ethstats should be nodename:secret@host:port"

RPC='--rpc --rpccorsdomain "*" --rpcapi="db,eth,net,web3,personal,web3" --allow-insecure-unlock'
WSC='--ws --wsaddr "localhost" --wsport "8546" --wsorigins "*" --wsapi="db,eth,net,web3,personal,web3"'

GETH_PARAMS="$SYNCM $CACHE $GARBC $DATAD $IDENT $ETHST $RPC $WSC"

## SET TIME
ntpdate -s time.nist.gov

## START GETH
eval "/usr/local/bin/geth ${GETH_PARAMS}"
Feb 21 15:56:48 raspberrypi geth[23395]: API AND CONSOLE OPTIONS:
Feb 21 15:56:48 raspberrypi geth[23395]:   --ipcdisable                        Disable the IPC-RPC server
Feb 21 15:56:48 raspberrypi geth[23395]:   --ipcpath value                     Filename for IPC socket/pipe within the datadir (explicit paths escape it)
Feb 21 15:56:48 raspberrypi geth[23395]:   --http                              Enable the HTTP-RPC server
Feb 21 15:56:48 raspberrypi geth[23395]:   --http.addr value                   HTTP-RPC server listening interface (default: "localhost")
Feb 21 15:56:48 raspberrypi geth[23395]:   --http.port value                   HTTP-RPC server listening port (default: 8545)
Feb 21 15:56:48 raspberrypi geth[23395]:   --http.api value                    API's offered over the HTTP-RPC interface
Feb 21 15:56:48 raspberrypi geth[23395]:   --http.rpcprefix value              HTTP path path prefix on which JSON-RPC is served. Use '/' to serve on all paths.
Feb 21 15:56:48 raspberrypi geth[23395]:   --http.corsdomain value             Comma separated list of domains from which to accept cross origin requests (browser enforced)
Feb 21 15:56:48 raspberrypi geth[23395]:   --http.vhosts value                 Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard. (default: "localhost")
Feb 21 15:56:48 raspberrypi geth[23395]:   --ws                                Enable the WS-RPC server
Feb 21 15:56:48 raspberrypi geth[23395]:   --ws.addr value                     WS-RPC server listening interface (default: "localhost")
Feb 21 15:56:48 raspberrypi geth[23395]:   --ws.port value                     WS-RPC server listening port (default: 8546)
Feb 21 15:56:48 raspberrypi geth[23395]:   --ws.api value                      API's offered over the WS-RPC interface
Feb 21 15:56:48 raspberrypi geth[23395]:   --ws.rpcprefix value                HTTP path prefix on which JSON-RPC is served. Use '/' to serve on all paths.
Feb 21 15:56:48 raspberrypi geth[23395]:   --ws.origins value                  Origins from which to accept websockets requests
Feb 21 15:56:48 raspberrypi geth[23395]:   --graphql                           Enable GraphQL on the HTTP-RPC server. Note that GraphQL can only be started if an HTTP server is started as well.
Feb 21 15:56:48 raspberrypi geth[23395]:   --graphql.corsdomain value          Comma separated list of domains from which to accept cross origin requests (browser enforced)
Feb 21 15:56:48 raspberrypi geth[23395]:   --graphql.vhosts value              Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard. (default: "localhost")
Feb 21 15:56:48 raspberrypi geth[23395]:   --rpc.gascap value                  Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite) (default: 50000000)
Feb 21 15:56:48 raspberrypi geth[23395]:   --rpc.evmtimeout value              Sets a timeout used for eth_call (0=infinite) (default: 5s)
Feb 21 15:56:48 raspberrypi geth[23395]:   --rpc.txfeecap value                Sets a cap on transaction fee (in ether) that can be sent via the RPC APIs (0 = no cap) (default: 1)
Feb 21 15:56:48 raspberrypi geth[23395]:   --rpc.allow-unprotected-txs         Allow for unprotected (non EIP155 signed) transactions to be submitted via RPC
Feb 21 15:56:48 raspberrypi geth[23395]:   --jspath loadScript                 JavaScript root path for loadScript (default: ".")
Feb 21 15:56:48 raspberrypi geth[23395]:   --exec value                        Execute JavaScript statement
Feb 21 15:56:48 raspberrypi geth[23395]:   --preload value                     Comma separated list of JavaScript files to preload into the console

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *