How to Prune an ETH 2.0 Node With Prysm and Geth as an External Execution Layer

16 DEC 2022
9 min read
Company News
9 min read
Article content
What Is Pruning?
A Guide on Pruning Geth With the Prysm Consensus Client
Conclusion

A validator node on the post-merge Ethereum consists of execution and consensus clients communicating over EngineAPI. If you need to disable the execution client, for example, to prune Geth and free some space up, you will have to use an external execution layer.

This guide explains how to temporarily connect a consensus client to an external execution client and prune the primary database without losing attestations and rewards. We will do this using Geth and Prysm as examples.

What Is Pruning?

A snap-sync’d Geth node takes up about 650 GB on the hard disk. Over time, the blockchain grows, the disk fills with data, and the node refuses to work.

The developers of Geth have provided a way to clean the database up and return it to its original size: pruning. Geth regularly snapshots the database, and pruning removes old data and brings the database back to its original 650 GB.

Pruning takes about four hours. During this time, Geth finds target trie nodes, removes stale trie nodes, and forms a new database. 

To prune an ETH 2.0 validator, follow this algorithm:

  • Prepare an external node.
  • Install and synchronize the execution and consensus clients on the external node.
  • Stop the execution and consensus clients on the local node.
  • Connect the consensus client on the local node to the execution client on the external node.
  • To prune the execution client on the local node, wait for completion.
  • Stop the consensus client, and reconnect it to the execution client on the local node.
  • Run the execution and consensus clients on the local node.

Sounds like a heart transplant surgery, doesn’t it?

A Guide on Pruning Geth With the Prysm Consensus Client

Everstake uses two Linux machines: a local node (ov6) (with both the Geth execution client and the Prysm consensus client) and an external node (ov7) with the same clients.

Configure the firewall of the external node to be able to connect to it on port 8551:

sudo iptables -A INPUT -i $(ip route get 8.8.8.8 | awk '{ print $5 }' | head -n 1) -p tcp --dport 8551 -s IP ov6 -j ACCEPT -m comment --comment "EL for ov6”

Check if the IP rule has been added:

sudo iptables -vnL

Configure the geth.service systemd script on external node ov7. Add --authrpc.addr 0.0.0.0 to the ExecStart line:

ExecStart=geth --syncmode snap --cache 4096 --http --http.addr 0.0.0.0 --http.api "engine,eth,net,rpc,web3,debug,txpool,admin" --ws --ws.addr="0.0.0.0" --ws.origins "*" --authrpc.vhosts="localhost" --authrpc.jwtsecret=/mnt/operational/lido/jwt/jwt.hex --http.vhosts=* --metrics.addr 0.0.0.0 --metrics.port 7070 --metrics --txpool.accountslots 64 --txpool.globalslots 8192 --txpool.accountqueue 128 --vmodule "rpc=5" --datadir "/mnt/operational/lido/geth”

↓↓↓

ExecStart=geth --syncmode snap --cache 4096 --http --http.addr 0.0.0.0 --authrpc.addr 0.0.0.0 --http.api "engine,eth,net,rpc,web3,debug,txpool,admin" --ws --ws.addr="0.0.0.0" --ws.origins "*" --authrpc.vhosts="localhost" --authrpc.jwtsecret=/mnt/operational/lido/jwt/jwt.hex --http.vhosts=* --metrics.addr 0.0.0.0 --metrics.port 7070 --metrics --txpool.accountslots 64 --txpool.globalslots 8192 --txpool.accountqueue 128 --vmodule "rpc=5" --datadir "/mnt/operational/lido/geth" 

Refresh the systemctl daemon:

sudo systemctl daemon-reload

Stop Prysm on the external node:

sudo systemctl stop ethereum2-node.service

Make sure Prysm has stopped and Geth is listening to 0.0.0.0:8511:

sudo netstat -tlpn

Launch the Geth systemd script on the external node:

sudo systemctl restart geth.service

Go to the local node. Once there, stop both Prysm and Geth:

sudo systemctl stop ethereum2-node.service

sudo systemctl stop geth.service

Configure Prysm to connect to the external node. In the Prysm systemd script, change --execution-endpoint to the IP address of the external node (ov7 in our case):

ExecStart=/mnt/operational/lido/prysm/prysm.sh beacon-chain --datadir /mnt/operational/lido/prysm/data --p2p-host-ip ${HOST} --execution-endpoint=http://localhost:8551 --http-mev-relay=http://localhost:18550 --jwt-secret=/mnt/operational/lido/jwt/jwt.hex --min-sync-peers 7 --p2p-max-peers 100 --suggested-fee-recipient=0x7f396Ef9F10C7beB11D01f2EA4a99a5787993474 --monitoring-host 0.0.0.0 --accept-terms-of-use

↓↓↓

ExecStart=/mnt/operational/lido/prysm/prysm.sh beacon-chain --datadir /mnt/operational/lido/prysm/data --p2p-host-ip ${HOST} --execution-endpoint=http://IP-OV7:8551 --http-mev-relay=http://localhost:18550 --jwt-secret=/mnt/operational/lido/jwt/jwt.hex --min-sync-peers 7 --p2p-max-peers 100 --suggested-fee-recipient=0x7f396Ef9F10C7beB11D01f2EA4a99a5787993474 --monitoring-host 0.0.0.0 --accept-terms-of-use

Refresh the systemctl daemon:

sudo systemctl daemon-reload

On the local node, back up the JWT token, e.g., in jwt.hex.bak:

cp /mnt/operational/lido/jwt/jwt.hex /mnt/operational/lido/jwt/jwt.hex.bak

Copy the JWT token from the external node, paste it into jwt.hex on the local node, and save the changes:

cat /mnt/operational/lido/jwt/jwt.hex 

nano /mnt/operational/lido/jwt/jwt.hex

Launch Prysm on the local node:

sudo systemctl start ethereum2-node.service

Check the logs for the connection to the external node:

eternal el-geth cat /mnt/operational/lido/prysm/stderr.txt |grep 8551

Check that Geth on the external node and Prysm on the local node catch up with the headblock.

Then prune Geth on the local node (Double-check that Geth is not running!):

tmux new -s PRUNE

geth snapshot prune-state --datadir "/mnt/operational/lido/geth”

Pruning will complete after two or three hours. Then revert the changes and launch the local validator:

  • Stop both Prysm and Geth.
  • Return the JWT from jwt.hex.bak to jwt.hex on the local node.
  • Return --execution-endpoint=http://localhost:8551 to the Prysm systemd.
  • Run Geth and then Prysm on the local node.
  • Remove --authrpc.addr 0.0.0.0 from the Geth systemd on the external node.
  • Close the 8551 IP port on the external node.

Conclusion

Pruning enables Ethereum validators with the Geth client to keep a 1 TB hard disk node running stably. 

Pruning was easy in the Ethereum PoW days, but with the move to PoS, one has to switch the consensus client to an external execution client for pruning. This is relatively easy, and one can get used to changing clients if they do it regularly.

Our instructions describe pruning with the Geth and Prysm consensus clients, but you can do the same with Teku, Lighthouse, and other consensus clients for Ethereum. Just study the configuration files, figure out what IP to change, and disable and enable the clients in the correct order.

Visit our Twitter and Discord.

Dark - Light
Everstake Logo
Everstake
Content Manager
Everstake is the world's leading validator, with 735,000+ delegators across 77 blockchain networks. We stake $4.8 billion in assets and provide best-in-class staking services to institutional and retail clients.

Related articles

Contact us

Have questions?
We’re always there to answer!

contact us
Our distributed team of 20+ community managers is online 24/7 and is ready to assist you.
quote avatar

We’d love to hear your thoughts.

Your opinion matters. Share any concerns, issues, or suggestions you may have with us so that Everstake could work on them, and your experience could improve.
Give FEEDBACK