Solana

Instructions to set up your Solana Validator node.

All commands mentioned in this section should be done on your trusted computer and NOT on a server where you intend to run your validator.

Install the Agave release on your local (not the server) machine by running:

Terminal window
sh -c "$(curl -sSfL https://release.anza.xyz/v2.2.0/install)"

You can replace v2.2.0 with the release tag matching the software version of your desired release.

Confirm you have the desired version of solana installed by running:

Terminal window
solana --version

After a successful install, agave-install update may be used to easily update the Solana software to a newer version at any time.

Once you have successfully installed the cli, the next step is to change your config so that it is making requests to the right cluster:

Terminal window
export SOLANA_METRICS_CONFIG="host=https://metrics.solana.com:8086,db=mainnet-beta,u=mainnet-beta_write,p=password"
solana config set --url https://api.mainnet-beta.solana.com
Terminal window
export SOLANA_METRICS_CONFIG="host=https://metrics.solana.com:8086,db=tds,u=testnet_write,p=c4fa841aa918bf8274e3e2a44d77568d9861b3ea"
solana config set --url https://api.testnet.solana.com/

Create a new keypair for your validator, vote account, and authorized withdrawer.

Terminal window
solana-keygen new -o validator-keypair.json
solana-keygen new -o vote-account-keypair.json
solana-keygen new -o authorized-withdrawer-keypair.json

Here’s what each keypair is used for:

Validator keypair (validator-keypair.json) This is the identity of your validator node. It signs votes, transactions, and blocks. Think of it as the “identity card” for your validator in the Solana network.

Vote account keypair (vote-account-keypair.json) This account holds and tracks your validator’s voting credits. It’s linked to your validator identity and records the validator’s participation in consensus.

Authorized withdrawer keypair (authorized-withdrawer-keypair.json) This key has permission to withdraw rewards from the vote account. You can (and often should) separate this from the validator operator to improve security, as it controls the movement of funds.

Reminder: Even if you’re familiar with keypair management, here’s a quick best practices review:

  • Store keypairs securely and back them up safely.
  • Never share private keys or store them on insecure machines.
  • Set strict file permissions (chmod 600).

Create a vote account for your validator.

Terminal window
solana config set --keypair ./validator-keypair.json

Now verify your account balance of 0:

Terminal window
solana balance

Deposit some SOL into that keypair account in order create a transaction

Terminal window
solana airdrop 1

The airdrop sub command does not work on mainnet, so you will have to acquire SOL and transfer it into this keypair’s account if you are setting up a mainnet validator.

Create a vote account:

Terminal window
solana create-vote-account -ut \
--fee-payer ./validator-keypair.json \
./vote-account-keypair.json \
./validator-keypair.json \
./authorized-withdrawer-keypair.json

Note -ut tells the cli command that we would like to use the testnet cluster. If you’re creating the RPC node you don’t need the vote account.

Now it’s time to connect to the server. SSH into your server.

All commands mentioned below should be done on a server where you intend to run your validator.

Create a new Ubuntu user, named sol, for running the validator:

Terminal window
sudo adduser sol
sudo usermod -aG sudo sol

Prepare the hard drives or partitions to be used for the validator: for ledger and AccountsDB.

Your system will need to be tuned in order to run properly. Your validator may not start without the settings below.

Terminal window
sudo bash -c "cat >/etc/sysctl.d/21-agave-validator.conf <<EOF
# Increase max UDP buffer sizes
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
# Increase memory mapped files limit
vm.max_map_count = 1000000
# Increase number of allowed open file descriptors
fs.nr_open = 1000000
EOF"

Apply the settings:

Terminal window
sudo sysctl -p /etc/sysctl.d/21-agave-validator.conf

Add:

LimitNOFILE=1000000

to the [Service] section of your systemd service file, if you use one. If not:

DefaultLimitNOFILE=1000000

to /etc/systemd/system.conf ([Manager] section).

Terminal window
sudo bash -c "cat >/etc/security/limits.d/90-solana-nofiles.conf <<EOF
# Increase process file descriptor count limit
* - nofile 1000000
EOF"

On your personal computer, not on the validator, securely copy your validator-keypair.json file and your vote-account-keypair.json file to the validator server:

Terminal window
scp validator-keypair.json sol@<server.hostname>:
scp vote-account-keypair.json sol@<server.hostname>:

On the validator server, switch to the sol user:

Terminal window
su - sol

Your remote machine will need the Solana CLI installed to run the Agave validator software. For simplicity, install the cli with user sol. Refer again to Solana’s Install Tool or build from source.

In your sol home directory (e.g. “/home/sol/), create a folder called bin`. Inside that folder create a file called validator.sh and make it executable:

Terminal window
mkdir -p /home/sol/bin
touch /home/sol/bin/validator.sh
chmod +x /home/sol/bin/validator.sh

Next, open the validator.sh file for editing and paste the following:

#!/bin/bash
exec agave-validator \
--identity ~/validator-keypair.json \
--vote-account ~/vote-account-keypair.json \
--known-validator 7Np41oeYqPefeNQEHSv1UDhYrehxin3NStELsSKCT4K2 \
--known-validator GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ \
--known-validator DE1bawNcRJB9rVm3buyMVfr8mBEoyyu73NBovf2oXJsJ \
--known-validator CakcnaRDHka2gXyfbEd2d3xsvkJkqsLw2akB3zsN1D2S \
--only-known-rpc \
--ledger ledger \
--rpc-port 8899 \
--private-rpc \
--dynamic-port-range 8000-8020 \
--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 \
--expected-genesis-hash 5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d \
--wal-recovery-mode skip_any_corrupted_record \
--limit-ledger-size
#!/bin/bash
exec agave-validator \
--identity validator-keypair.json \
--vote-account vote-account-keypair.json \
--known-validator 5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on \
--known-validator dDzy5SR3AXdYWVqbDEkVFdvSPCtS9ihF5kJkHCtXoFs \
--known-validator Ft5fbkqNa76vnsjYNwjDZUXoTWpP7VYm3mtsaQckQADN \
--known-validator eoKpUABi59aT4rR9HGS3LcMecfut9x7zJyodWWP43YQ \
--known-validator 9QxCLckBiJc783jnMvXZubK4wH86Eqqvashtrwvcsgkv \
--only-known-rpc \
--ledger ledger \
--rpc-port 8899 \
--dynamic-port-range 8000-8020 \
--entrypoint entrypoint.testnet.solana.com:8001 \
--entrypoint entrypoint2.testnet.solana.com:8001 \
--entrypoint entrypoint3.testnet.solana.com:8001 \
--expected-genesis-hash 4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY \
--wal-recovery-mode skip_any_corrupted_record \
--limit-ledger-size

Refer to agave-validator --help for more information on what each flag is doing in this script. You can try running to check if working as expected.

Terminal window
tail -f agave-validator.log

Check also if gossip protocol is working as expected. More information can be found here.

Assuming you have a user called sol on your machine, create the file /etc/systemd/system/sol.service with the following:

[Unit]
Description=Solana Validator
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=sol
LimitNOFILE=1000000
LogRateLimitIntervalSec=0
Environment="PATH=/bin:/usr/bin:/home/sol/.local/share/solana/install/active_release/bin"
ExecStart=/home/sol/bin/validator.sh
[Install]
WantedBy=multi-user.target

Ensure that running /home/sol/bin/validator.sh manually starts the validator as expected. Don’t forget to mark it executable with chmod +x /home/sol/bin/validator.sh.

Start the service with:

Terminal window
sudo systemctl enable --now sol

Since a Solana RPC server runs the same process as a consensus validator, first follow the instructions above. Below is an example validator.sh file for a testnet RPC server.

#!/bin/bash
exec agave-validator \
--identity ~/validator-keypair.json \
--vote-account ~/vote-account-keypair.json \
--known-validator 7Np41oeYqPefeNQEHSv1UDhYrehxin3NStELsSKCT4K2 \
--known-validator GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ \
--known-validator DE1bawNcRJB9rVm3buyMVfr8mBEoyyu73NBovf2oXJsJ \
--known-validator CakcnaRDHka2gXyfbEd2d3xsvkJkqsLw2akB3zsN1D2S \
--only-known-rpc \
--full-rpc-api \
--ledger ledger \
--no-voting \
--rpc-port 8899 \
--private-rpc \
--dynamic-port-range 8000-8020 \
--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 \
--expected-genesis-hash 5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d \
--wal-recovery-mode skip_any_corrupted_record \
--limit-ledger-size
#!/bin/bash
exec agave-validator \
--identity /home/sol/validator-keypair.json \
--known-validator 5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on \
--known-validator dDzy5SR3AXdYWVqbDEkVFdvSPCtS9ihF5kJkHCtXoFs \
--known-validator eoKpUABi59aT4rR9HGS3LcMecfut9x7zJyodWWP43YQ \
--known-validator 7XSY3MrYnK8vq693Rju17bbPkCN3Z7KvvfvJx4kdrsSY \
--known-validator Ft5fbkqNa76vnsjYNwjDZUXoTWpP7VYm3mtsaQckQADN \
--known-validator 9QxCLckBiJc783jnMvXZubK4wH86Eqqvashtrwvcsgkv \
--only-known-rpc \
--full-rpc-api \
--no-voting \
--ledger /mnt/ledger \
--accounts /mnt/accounts \
--log /home/sol/solana-rpc.log \
--rpc-port 8899 \
--rpc-bind-address 0.0.0.0 \
--private-rpc \
--dynamic-port-range 8000-8020 \
--entrypoint entrypoint.testnet.solana.com:8001 \
--entrypoint entrypoint2.testnet.solana.com:8001 \
--entrypoint entrypoint3.testnet.solana.com:8001 \
--expected-genesis-hash 4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY \
--wal-recovery-mode skip_any_corrupted_record \
--limit-ledger-size

Edit on GitHub