How to deploy a Solana RPC Node
There are two ways to become a citizen of the Solana network.
- Spin up a Validator
- Spin up an RPC Node
If you’re the nerdy type and know the difference already, skip ahead 🙂. But for others, let’s dive a bit deeper.
Validator vs. RPC Node
If thou must vote, thou must be a Validator.
Validators are the workhorses of the network, maintaining the chain’s state, validating the submitted transactions and producing blocks when their turn arrives.
In essence, they get to vote i.e. participate in the consensus process. A validator’s voting share depends on the amount of tokens staked to it. When chosen as a leader, it also furnishes blocks for the network and it’s stakeholders are rewarded for it. Handsomely, might I add 😉.
An RPC Node executes the same program as a Validator but it does NOT participate in the consensus process. Instead, developers and applications use it to access and interact with the chain.
Technically, one could spin up a validator which also functions as an RPC Node, but this is strongly discouraged due to performance reasons. Greed never works.
How to run an RPC Node
While this tutorial expounds upon the process of deploying an RPC Node, deploying a Validator is almost similar. I will drop cues along the way if you want to run a Validator instead.
Prerequisites
You should be wealthy enough to have access to the following.
- CPU
- 12 Cores / 32 Threads or more, with each core being 2.8GHz+
- AVX2 instruction support (unless you’re compilingsolana
from source) - RAM
- 128GB or more
- 256GB or more if you want to enable account indices for a fully performant RPC API - Disk
- 2x 1TB NVMe SSD or better
- One to store the accounts data
- One to store the ledger data
- 1x 256GB NVMe SSD or better (to host the OS)
- Technically, 1x 2TB NVMe SSD can work but highly discouraged - Networking
- Access to at least 300Mbit/s symmetric but 1Gbit/s+ is preferred - Operating System
- Ubuntu 20.04
- You may use any other linux based OS too and modify the instructions accordingly
For a comprehensive list, you may give this a read. Otherwise, let’s just yolo it.
1. Understanding the disks
First off, let’s SSH as root
into the machine that’s going to run the node. Or if it’s your local desktop, then just power up a bash session and sudo su
.
Let’s run lsblk
and understand the output. Here’s a sample.
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 63.2M 1 loop /snap/core20/1623
loop1 7:1 0 67.8M 1 loop /snap/lxd/22753
loop2 7:2 0 48M 1 loop /snap/snapd/17336
loop3 7:3 0 48M 1 loop /snap/snapd/16778
nvme2n1 259:0 0 3.5T 0 disk
└─nvme2n1p1 259:3 0 3.5T 0 part
nvme1n1 259:1 0 3.5T 0 disk
└─nvme1n1p1 259:4 0 3.5T 0 part
nvme0n1 259:2 0 238.5G 0 disk
├─nvme0n1p1 259:5 0 1M 0 part
└─nvme0n1p2 259:6 0 238.5G 0 part /
nvme0n1
hosts the Operating System. We don’t care about it. It’s not worth our attention.nvme1n1
will be used to store the ledger data. It has one partitionnvme1n1p1
.nvme2n1
will be used to store the accounts data. It also has one partitionnvme2n1p1
spanning the entire disk.
You may use the parted
tool to create partitions on your disks if they’re not already present.
💡 Both
nvme1n1p1
andnvme2n1p1
have been formatted usingxfs
. You may also useext4
.
Oh and while we’re at this step, do yourself a favor and run apt update -y && apt upgrade -y
.
2. Mounting the disks
We need to create the appropriate data directories and mount the two disks mentioned above.
As alluded to earlier, we will use /var/solana/data
for the ledger and /var/solana/accounts
for the accounts data.
root@antematter:~# mkdir /var/solana
root@antematter:~# mkdir /var/solana/data /var/solana/accounts
root@antematter:~# mount /dev/nvme1n1p1 /var/solana/data
root@antematter:~# mount /dev/nvme2n1p1 /var/solana/accounts
You may also edit the /etc/fstab
file to always mount the disks on startup.
3. Creating a user
It is recommended to create another user to run the RPC node as. Shouldn’t be much hassle.
root@antematter:~# adduser solana
root@antematter:~# chown solana:solana /var/solana/data
root@antematter:~# chown solana:solana /var/solana/accounts
We’re also making solana
the owner of both the data directories.
4. Installing the Solana binaries
Let’s make sure to switch to the newly created solana
user first.
root@antematter:~# su - solana
And now let’s just curl
the script which sets up the binaries. Easy peasy.
solana@antematter:~# sh -c "$(curl -sSfL <https://release.solana.com/stable/install>)"
Make sure to append the following to your .profile
for solana
if it’s not already there.
export PATH="/home/solana/.local/share/solana/install/active_release/bin:$PATH"
To verify if the CLI tools have been installed, run solana --version
. For me, it is
solana@antematter:~# solana --version
solana-cli 1.13.5 (src:9382e90c; feat:4011803773)
5. Creating the Validator Keypair
Each Validator (or an RPC Node) is identified on the network with a keypair. So let’s create one for our own RPC Node.
solana@antematter:~# solana-keygen new -o /var/solana/data/config/validator-keypair.json
We do not need to deposit any SOL to this account since we’re not running a validator. If you were, however, trying to run a validator, not only will you need to fund this account, you will need two more keypairs and initialize a vote account. Refer here.
6. Running the system tuner
Solana is a wild beast and as such your system needs to be tuned for it to function performantly.
There are two ways to do this: manual & automatic. Let’s opt for the manual one, create config files with thousands of overwhelming entries using vi
and committing them using sysctl
.
NO! That’s torture. Let’s just run the automatic tuner.
solana@antematter:~# sudo $(command -v solana-sys-tuner) --user sol > sys-tuner.log 2>&1
You will obviously need solana
to be a sudoer
. Switch to root
and run adduser solana sudo
.
7. Creating a startup script
Just about there! Let’s create a startup script so we can easily craft a systemd
service around it.
Switch back to the solana
user and cd
into the home directory. Then let’s run the following commands
solana@antematter:~# mkdir /home/solana/bin && cd /home/solana/bin
solana@antematter:~/bin# touch validator.sh
Now we just need to put the following script inside the validator.sh
file we just created.
#!/bin/bashset -e
set -uexport RUST_LOG=errorsolana-validator \
--ledger /var/solana/data/ledger \
--accounts /var/solana/accounts \
--identity /var/solana/data/config/validator-keypair.json \
--known-validator 7Np41oeYqPefeNQEHSv1UDhYrehxin3NStELsSKCT4K2 \
--known-validator GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ \
--known-validator DE1bawNcRJB9rVm3buyMVfr8mBEoyyu73NBovf2oXJsJ \
--known-validator CakcnaRDHka2gXyfbEd2d3xsvkJkqsLw2akB3zsN1D2S \
--expected-genesis-hash 5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d \
--entrypoint entrypoint.mainnet-beta.solana.com:8001 \
--entrypoint entrypoint2.mainnet-beta.solana.com:8001 \
--entrypoint entrypoint3.mainnet-beta.solana.com:8001 \
--entrypoint entrypoint4.mainnet-beta.solana.com:8001 \
--entrypoint entrypoint5.mainnet-beta.solana.com:8001 \
--rpc-port 8899 \
--dynamic-port-range 8000-8020 \
--wal-recovery-mode skip_any_corrupted_record \
--init-complete-file /var/solana/data/init-completed \
--limit-ledger-size 50000000 \
--log - \
--only-known-rpc \
--full-rpc-api \
--no-voting \
--enable-rpc-transaction-history \
--enable-cpi-and-log-storage
Here’s a brief explanation of the non self-explanatory and important flags.
--known-validator
points to a validator on the network you trust. These validators will be used to fetch the network’s snapshot.--rpc-port
specifies the port where the RPC server will be listening.--limit-ledger-size
specifies the amount of shreds in root slots. This is useful for limiting disk usage.--full-rpc-api
exposes RPC methods for querying the chain’s state.--no-voting
tells the validator to not participate in the consensus process i.e. spin up as an RPC node.--enable-rpc-transaction-history
will enable historical transaction information over the RPC server but will consume more disk.
💡 You may use the
--rpc-bind-address
flag to bind the RPC server to a specific address such as127.0.0.1
.
To run a Validator instead of an RPC Node, you can remove the following flags
--no-voting
--full-rpc-api
--enable-rpc-transaction-history
--enable-cpi-and-log-storage
- Lastly, provide the voting keypair using the
--vote-account
flag.
Oh and we should not forget this little thing.
solana@antematter:~bin# chmod +x validator.sh
8. Creating a system service
solana@antematter:~bin# sudo su - root
root@antematter:~# touch /etc/systemd/system/solana-validator.service
And then dump the following blob of text inside the file we just willed into existence.
[Unit]
Description=Solana RPC Node
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=solana
LimitNOFILE=1000000
LogRateLimitIntervalSec=0
Environment=PATH=/bin:/usr/bin:/home/solana/.local/share/solana/install/active_release/bin
ExecStart=/home/solana/bin/validator.sh
[Install]
WantedBy=multi-user.target
9. Running the RPC Node
Before running the systemd
service, you can try and make sure everything works seamlessly by switching to the solana
user, cd
ing into the ~/bin
directory and running ./validator.sh
.
To view complete logs, make sure to remove the line export RUST_LOG=error
from the bash script and redirect logging to a specific file by modifying the --log
flag.
The RPC Node takes some time to boot up and download a recent network snapshot. But once you’ve verified that everything works correctly, kill the process and run the systemd
service.
solana@antematter:~# sudo systemctl daemon-reload
solana@antematter:~# sudo systemctl enable solana-validator
solana@antematter:~# sudo systemctl start solana-validator
Voila! We our now knee-deep into the Solana-land.
10. So…is it really up?
I don’t know. But I can help you know.
System Service
solana@antematter:~# sudo systemctl status solana-validator
● solana-validator.service - Solana RPC Node
Loaded: loaded (/etc/systemd/system/solana-validator.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2022-10-31 10:17:55 UTC; 21h ago
Main PID: 69314 (validator.sh)
Tasks: 836 (limit: 618684)
Memory: 479.8G
CGroup: /system.slice/solana-validator.service
├─69314 /bin/bash /home/solana/bin/validator.sh
└─69328 solana-validator --ledger /var/solana/data/ledger ...
Your output should be similar to mine.
Solana Gossip
Let’s find out our public key which identifies our validator on the network.
solana@antematter:~# solana-keygen pubkey /var/data/data/config/validator-keypair.json
Then run the following and verify our public key is indeed present in the output.
solana@antematter:~# solana gossip | grep <pubkey>
11. Catching up
Once your RPC Node joins the network for the first time, it must download a snapshot from one of the known validators. By the time it downloads the snapshot, the network usually already has progressed further. So our node has to work faster than the network to catch up.
Use the following command to see how much behind the network our node is.
solana@antematter:~# solana catchup <pubkey>
If the above command fails, it may be that your validator is still downloading the snapshot and has not fully joined the network. Give it some time, it deserves your patience.
Oh and once the node is fully up and initialized, you should add --no-snapshot-fetch
to your validator.sh
to avoid slow restarts in the future.
12. Enabling account indices
Story time!
I provisioned my RPC Node and set up an nginx
proxy to secure access to the node. I was elated. I provided the RPC URL to my team working on a project.
But lo and behold, calls to getTokenAccountsByOwner
were getting stuck. Initially, I thought it was a problem with ports or the node itself. But then I found out that the calls would eventually succeed, they were just taking a LOT of time.
The answer lies here. We need to enable in-memory indices to make account-data RPC requests performant. There are three indices you can enable by providing the --account-index <type>
flag to the node.
program-id
spl-token-mint
spl-token-owner
💡 Enabling all three indices will hog all the available RAM, eventually killing the process.
My machine had access to 500GB of RAM but the three indices combined just gulped it down in an instant. Eventually, I just settled with the spl-token-owner
index.
TL;DR
There is no TL;DR for this post. You’ve got to read everything or the RPC node won’t work.
Want us to help?
If you’d like us to help you set up an RPC Node or a Validator, drop us a line at our website: antematter.io