Turbo-Geth is an Ethereum client that was originally a fork of the popular Go-Ethereum (Geth) client. It has since seen significant re-writing of the database structure, data model, and sync process enabling node operators to run “Full Archive” without needing > 4TB of storage. Work is even being done to test HDD sync (as opposed to SSD).
In this article I’m going to walk through a step by step setup of how to download, build, and execute Turbo-Geth as a service using Supervisor. I’m going to assume you’re running Ubuntu but other Linux distros should work fine/similarly. It may be possible to run on Windows, however, building and running as a service on Windows is an entirely different can of worms that I won’t get into here. If you’d rather use Systemd as opposed to Supervisor, there are other sources available.
At the time of this writing my Turbo-Geth installation consumes 690GB of storage at block #10,795,444
I’m going to assume that you’re root for the duration of the setup. If you are using
sudo with these commands, I recommend simply entering root environment with
sudo -i otherwise you will have issues with go not being in your path.
The essentials: build-essential, supervisor, wget, and git
apt-get install -y build-essential supervisor wget git
At the time of this writing the most recent Go Language version is 1.15.5. Check here.
wget https://golang.org/dl/go1.15.5.linux-amd64.tar.gz tar -C /usr/local -xzf go1.15.5.linux-amd64.tar.gz echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile #ln -s /usr/local/go/bin/go /bin/go . ~/.profile
I added an option Symbolic link, that is commented out above that can be used to make go available in the path of every user, uncomment it if you want to.
Isolated turbogeth user
Ideally we don’t want our Turbo-Geth process running as root so I’m going to create a new user account for the service to run under.
useradd -m -s /bin/bash turbogeth
cd /opt git clone https://github.com/ledgerwatch/turbo-geth.git cd turbo-geth make
Setting up the Services
Unlike Go-Ethereum (geth), Turbo-Geth has a separate RPC service called
rpcdaemon that we also need to setup. I will setup both as Supervisor services.
First, let’s create a data directory for Turbo-Geth to work with, as the default sucks (
~/.local/share/turbogeth). You can change this to whatever you want. I personally have a secondary SSD attached to
/data so I’m going to use that. I’m also going to make the
turbogeth user the owner of the new folder.
mkdir -p /data/turbo-geth/datadir chown -R turbogeth:turbogeth /data/turbo-geth
Next let’s create our service… use your favorite editor and create the following file:
vi /etc/supervisor/conf.d/tg.conf [program:tg] command=bash -c '/opt/turbo-geth/build/bin/tg --datadir="/data/turbo-geth/datadir" --private.api.addr="0.0.0.0:9090"' user=turbogeth autostart=true autorestart=true stderr_logfile=/var/log/supervisor/tg.err.log stderr_logfile_maxbytes=1000000 stderr_logfile_backups=10 stdout_logfile=/var/log/supervisor/tg.out.log stdout_logfile_maxbytes=1000000 stdout_logfile_backups=10 stopwaitsecs=300
Breaking this down section by section, we’re telling Supervisor to create a service called
tg which will run the
tg executable, specifying the
datadir. By default the
tg executable is going to listen only on
127.0.0.1:9090 which is fine if you run the
rpcdaemon on the same system. Or you can set it to
0.0.0.0:9090 like I have done above to listen on all interfaces. Be careful adding additional flags here, as not all geth flags are supported. If you have a static IP address you could also add:
Next we’re telling Supervisor to run it as the
turbogeth user we created earlier, telling it to auto start and auto restart.
The stderr and stdout lines tell Supervisor where to log the console output to and sets up log rotation. Logs can get rather big if you don’t rotate them.
stopwaitsecs=300 tells Supervisor to wait at least 5 minutes after the kill signal before forcefully shutting it down. This is probably not required for Turbo-Geth, but I got into the habit of including it with my Ethereum node processes because nothing sucks more than pre-mature killing of the process resulting in a corrupt DB.
Now, let’s create the service for the
vi /etc/supervisor/conf.d/rpcdaemon.conf [program:rpcdaemon] command=bash -c '/opt/turbo-geth/build/bin/rpcdaemon --private.api.addr="localhost:9090" --http.addr="0.0.0.0" --http.port=8545 --http.vhosts="*" --http.corsdomain="*" --http.api="eth,debug,net,trace,web3,tg" --ws' user=turbogeth autostart=true autorestart=true stderr_logfile=/var/log/supervisor/rpcdaemon.err.log stderr_logfile_maxbytes=1000000 stderr_logfile_backups=10 stdout_logfile=/var/log/supervisor/rpcdaemon.out.log stdout_logfile_maxbytes=1000000 stdout_logfile_backups=10
Here we have created our second service. The important thing here is that we’re pointing
rpcdaemon at the
tg is listening on. From there we’re exposing our RPC endpoint to “all IPs” by using
--http.addr="0.0.0.0" and we’re listening on port 8545. We’ve basically disabled any host or cors checking by using
="*", we’re exposing all available methods (currently:
eth,debug,net) and we’re also enabling WebSocket support.
The rpcdaemon doesn’t have a database to get corrupted so no need to worry about killing the process.
LISTENING ON ALL IP ADDRESSES AND DISABLING HOST/CORS CHECKING IS NOT RECOMMENDED IF YOUR SERVER IS REACHABLE FROM THE INTERNET.
I assume that most people reading this are just trying to run a node inside their own network, and that some sort of firewall should be protecting their node from external connections. Otherwise, you should setup
ufw or similar on your node to protect your endpoints. Of course if you’re running Turbo-Geth on your workstation or you have no reason to access it remotely you can change
127.0.0.1 and then only local connections will be accepted.
If you are running this on a cloud server and you don’t really know what you’re doing here’s a quick firewall using
# Allow SSH form anywhere so we don't get locked out ufw allow ssh # Allow TPC/UDP 30303 from anywhere for peering ufw allow 30303 # Turn on the firewall ufw enable # If you want to allow specific IPs (e.g. 22.214.171.124) to hit your RPC endpoint: ufw allow proto tcp from 126.96.36.199 to any port 8545
Let the nodling commence
systemctl enable supervisor systemctl start supervisor
This should enable supervisor, telling it to start at startup, and it should start supervisor which in turn should start your
You can check on the status of stuff:
# Check on the tg service: supervisorctl status tg tail /var/log/supervisor/tg.err.log # Check on the rpcdaemon status: supervisorctl status rpcdaemon
If for some reason the services don’t start it’s probably a typo in your supervisor config files
Once you make whatever changes you need to make to the config you reload it with this:
supervisorctl reread supervisorctl reload
Updating Your Node
Updating Turbo-Geth is fairly straight forward, we simply pull the latest changes from github, run make, and restart our services.
cd /opt/turbo-geth/ git pull make supervisorctl restart tg supervisorctl restart rpcdaemon
I would suggest excising some caution in updating, although the Turbo-Geth team does their best to ensure that the master branch of Turbo-Geth is safe and stable, it’s always best to be safe. Also, some updates might not be reversible, as the database model can change, when that happens, the startup of your node after update will include a migration of data (no need to re-sync). However, if you want to downgrade, you would likely have to re-sync.