# 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