# Solana Validator Setup
## Optimal Hardware Requirements
- CPU: 16 cores @ 3GHz
- RAM: 128GB
- Storage: 500GB (OS) + 500GB (Accounts) + 1TB (Ledger)
Start with a fresh Ubuntu VM (Server 20.04).
## Dependencies
1. Create unprivileged Solana user:
```
sudo adduser soluser
```
2. Update package information:
```
sudo apt update
```
3. Create directory structure:
```
mkdir -p ~/deployments/solana/disks/{accounts,ledger}
mkdir -p ~/deployments/solana/{keys,logs}
mkdir -p ~/{dependencies,scripts}
```
4. **(optional: if using multiple disks)** Mount accounts and ledger partitions:
- Mount disks and set ownership:
```
sudo mount /dev/<accounts_partition> ~/deployments/solana/disks/accounts
sudo mount /dev/<ledger_partition> ~/deployments/solana/disks/ledger
sudo chown soluser:soluser ~/deployments/solana/disks/{accounts,ledger}
```
> Available partitions can be listed by `sudo lsblk`.
- Update fstab:
```
sudo sh -c 'echo "UUID=<uuid> /home/user/deployments/solana/disks/<mntdir> ext4 defaults,nofail 0 0" >> /etc/fstab'
```
> UUID of a partition can be obtained by `sudo blkid /dev/<partition>`.
5. **(optional: if sudo version is < 1.9)** Update `sudo` to >= v1.9 from source (for the `RLIMIT_CORE` patch):
- Install updates
```
sudo apt update && sudo apt upgrade --assume-yes
```
- Install make dependencies
```
sudo apt install gcc make
```
- Fetch source and uncompress
```
cd ~/dependencies
wget https://www.sudo.ws/dist/sudo-1.9.11p3.tar.gz
tar -zxvf sudo-1.9.11p3.tar.gz
```
- Configure
```
cd sudo-1.9.11p3/
sudo su
./configure --prefix=/usr --libexecdir=/usr/lib --with-secure-path --with-all-insults --with-env-editor --docdir=/usr/share/doc/sudo-1.9.5p2 --with-passprompt="[sudo] password for %p: "
```
- Make and install
```
make
make install && ln -sfv libsudo_util.so.0.0.0 /usr/lib/sudo/libsudo_util.so.0
```
6. Relogin.
## Tune System
1. Optimize sysctl knobs:
```
bash -c "cat >/etc/sysctl.d/21-solana-validator.conf <<EOF
# Increase UDP buffer sizes
net.core.rmem_default = 134217728
net.core.rmem_max = 134217728
net.core.wmem_default = 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"
```
```
sudo sysctl -p /etc/sysctl.d/21-solana-validator.conf
```
2. Increase process file descriptor count limit:
```
bash -c "cat >/etc/security/limits.d/90-solana-nofiles.conf <<EOF
# Increase process file descriptor count limit
* - nofile 1000000
EOF"
```
3. Relogin.
## Connect to Cluster
0. Switch to the `solana` user:
```
su - solana
```
1. Install the Solana Toolkit binary:
```
sh -c "$(curl -sSfL https://release.solana.com/v1.10.32/install)"
```
2. Set the cluster URL using Solana CLI:
```
CLUSTER_URL="http://api.devnet.solana.com"
solana config set --url $CLUSTER_URL
```
3. Before attaching a validator node, sanity check that the cluster is accessible by fetching the cluster version:
```
solana cluster-version
```
> If everything went well, the cluster version will be returned.
## Create Accounts
1. Generate an identity keypair for the validator:
```
solana-keygen new -o ~/deployments/solana/keys/validator-keypair.json
```
2. Set the Solana config to use the generated keypair:
```
solana config set --keypair ~/deployments/solana/keys/validator-keypair.json
```
3. Generate authorized withdrawer account keypair:
```
solana-keygen new -o ~/deployments/solana/keys/authorized-withdrawer-keypair.json
```
4. Generate vote account keypair:
```
solana-keygen new -o ~/deployments/solana/keys/vote-account-keypair.json
```
5. Add token to account via airdrop (required for creating a vote account):
```
solana airdrop 1
```
6. Create vote account:
```
solana create-vote-account ~/deployments/solana/keys/vote-account-keypair.json ~/deployments/solana/keys/validator-keypair.json ~/deployments/solana/keys/authorized-withdrawer-keypair.json
```
## Connect Validator
1. Make a script to start the validator:
- `~/scripts/validator.sh`
```
#!/bin/bash
CLUSTER_ENTRYPOINT="entrypoint.devnet.solana.com:8001"
SOLANA_USER=solana
VALIDATOR_IDENTITY_PATH="/home/$SOLANA_USER/deployments/solana/keys/validator-keypair.json"
VOTE_IDENTITY_PATH="/home/$SOLANA_USER/deployments/solana/keys/vote-account-keypair.json"
LOG_PATH="/home/$SOLANA_USER/deployments/solana/logs/solana-validator.log"
ACCOUNTS_DISK_PATH="/home/$SOLANA_USER/deployments/solana/disks/accounts"
LEDGER_DISK_PATH="/home/$SOLANA_USER/deployments/solana/disks/ledger"
LEDGER_SIZE=50000000
solana-validator \
--entrypoint $CLUSTER_ENTRYPOINT \
--identity $VALIDATOR_IDENTITY_PATH \
--vote-account $VOTE_IDENTITY_PATH \
--log $LOG_PATH \
--accounts $ACCOUNTS_DISK_PATH \
--ledger $LEDGER_DISK_PATH \
--limit-ledger-size $LEDGER_SIZE \
--wal-recovery-mode skip_any_corrupted_record \
--rpc-port 8899 \
--no-poh-speed-test \
--skip-poh-verify \
--no-port-check
```
- Make it executable:
```
chmod +x ~/scripts/validator.sh
```
2. Create a service to start validator on boot:
- `/etc/systemd/system/validator.service`
```
[Unit]
Description=Solana Validator
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=on-failure
RestartSec=1
LimitNOFILE=1000000
LogRateLimitIntervalSec=0
User=user
Environment=PATH=/bin:/usr/bin:/home/user/.local/share/solana/install/active_release/bin
Environment=SOLANA_METRICS_CONFIG=host=https://metrics.solana.com:8086,db=devnet,u=scratch_writer,p=topsecret
ExecStart=/home/user/scripts/validator.sh
[Install]
WantedBy=multi-user.target
```
3. Enable and start the service:
```
sudo systemctl enable --now validator.service
```
4. Test validator connection:
```
solana gossip
```
> A successful connection would return a list with the validator's public key and IP address.
## Configure logging and monitoring
1. Set up logrotate to limit log size:
- `/etc/logrotate.d/solana`
```
/home/user/deployments/solana/logs/solana-validator.log {
su user user
rotate 12
daily
compress
missingok
notifempty
postrotate
systemctl kill -s USR1 validator.service
endscript
}
```
- Give appropriate permissions:
```
sudo chmod 644 /etc/logrotate.d/solana
```
- Restart logrotate to load the new configuration:
```
sudo systemctl restart logrotate
```
-----
# To Do
- TPU and RPC address is 'none' on gossip, why?
- Prometheus
- Grafana
- "update" instructions