Step 002: Plan wdrozenia Solana RPC (Agave mainnet, non-voting, private RPC + Geyser->Postgres + monitoring + NOC tmux) Zalozenia (default): - WG iface: wg0, WG subnet: 10.66.66.0/24, WG IP baremetala: 10.66.66.1 - Public iface: eth0, public IP: 149.50.116.219 - RPC: 8899 (HTTP), WS: 8900 (WS = RPC_PORT+1) - Postgres (lokalnie): 5432 (DB: geyser, user: geyser) - (Optional) Yellowstone gRPC: 10000 (tylko po WG) - Prometheus: 9090, Grafana: 3000, node_exporter: 9100 (tylko po WG) - Dynamic port range (cluster): 8000-8020/udp (public eth0) - User: solana - Dirs: - /var/lib/solana (ledger/accounts) - /etc/solana (configs) - /var/log/solana (logs) 0) Preconditions (check) # WG dziala ip -4 a show wg0 wg show # SSH po WG dziala (z laptop/VPS): # ssh user@10.66.66.1 1) Packages sudo apt-get update sudo apt-get install -y \ tmux btop \ sysstat iotop \ ethtool nstat \ chrony curl jq git ca-certificates \ ripgrep \ smartmontools nvme-cli \ build-essential pkg-config libssl-dev \ clang llvm-dev libclang-dev \ cmake protobuf-compiler libudev-dev zlib1g-dev 2) Users/Dirs sudo getent group solana >/dev/null || sudo groupadd --system solana sudo id -u solana >/dev/null 2>&1 || sudo useradd --system --gid solana \ --home-dir /var/lib/solana --create-home --shell /bin/bash solana sudo install -d -o root -g root -m 0755 /etc/solana /opt/solana/bin sudo install -d -o solana -g solana -m 0750 \ /var/lib/solana /var/lib/solana/ledger /var/lib/solana/accounts /var/log/solana # identity permissions (po utworzeniu pliku): # sudo chown solana:solana /var/lib/solana/identity.json # sudo chmod 600 /var/lib/solana/identity.json 2A) Storage (rekomendowane) # Variant A: jesli /dev/nvme0n1 jest wolny i chcesz go podzielic 50/50: # doc/step-002a-storage-nvme0n1-xfs.txt # # Variant B (mpabi): masz juz 2x NVMe z XFS: # - SOLACCT na accounts (nvme0n1p1) # - SOLLEDG na ledger (nvme1n1p1) # doc/step-002a-storage-existing-solacct-solledg-xfs.txt 3) Firewall/WG binding (private-only) # UFW: deny everything inbound by default sudo ufw default deny incoming sudo ufw default allow outgoing # WireGuard (public) sudo ufw allow 51820/udp # SSH only via WG sudo ufw allow in on wg0 to any port 22 proto tcp sudo ufw deny in on eth0 to any port 22 proto tcp # RPC/WS only via WG sudo ufw allow in on wg0 to any port 8899 proto tcp sudo ufw allow in on wg0 to any port 8900 proto tcp sudo ufw deny in on eth0 to any port 8899 proto tcp sudo ufw deny in on eth0 to any port 8900 proto tcp # Yellowstone gRPC only via WG sudo ufw allow in on wg0 to any port 10000 proto tcp sudo ufw deny in on eth0 to any port 10000 proto tcp # Monitoring only via WG sudo ufw allow in on wg0 to any port 9100 proto tcp sudo ufw allow in on wg0 to any port 9090 proto tcp sudo ufw allow in on wg0 to any port 3000 proto tcp sudo ufw deny in on eth0 to any port 9100 proto tcp sudo ufw deny in on eth0 to any port 9090 proto tcp sudo ufw deny in on eth0 to any port 3000 proto tcp # Cluster ports (public, inbound) for sync (UDP) sudo ufw allow in on eth0 to any port 8000:8020 proto udp # (opcjonalnie) jesli bedziesz mial problemy z reachability: # sudo ufw allow in on eth0 to any port 8000:8020 proto tcp sudo ufw enable sudo ufw status verbose 4) Validator (Agave) config + systemd (non-voting RPC-only) # sysctl baseline (Agave startup checks) sudo tee /etc/sysctl.d/90-agave.conf >/dev/null <<'EOF' net.core.rmem_max = 134217728 net.core.wmem_max = 134217728 EOF sudo sysctl --system # ulimit baseline sudo tee /etc/security/limits.d/90-solana.conf >/dev/null <<'EOF' * soft nofile 1000000 * hard nofile 1000000 EOF # Agave tools (solana-keygen etc.) for solana user sudo -u solana -H bash -lc 'sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"' # Copy binaries to /opt/solana/bin (avoid symlink permission gotchas) sudo cp -a /var/lib/solana/.local/share/solana/install/active_release/bin/. /opt/solana/bin/ sudo find /opt/solana/bin -maxdepth 1 -type f -exec chmod 0755 {} \; /opt/solana/bin/solana --version || true /opt/solana/bin/solana-keygen --version # Build agave-validator (pin tag + toolchain) # Uwaga: dla nowszych stable release'ow binarka moze nie byc publikowana, # wiec build ze zrodel jest wymagany. # doc/step-002f-agave-build-from-source-latest.txt # Identity (create once) if [ ! -f /var/lib/solana/identity.json ]; then sudo -u solana -H /opt/solana/bin/solana-keygen new --no-passphrase -o /var/lib/solana/identity.json sudo chown solana:solana /var/lib/solana/identity.json sudo chmod 600 /var/lib/solana/identity.json fi # Genesis hash (mainnet) GENESIS_HASH="$(curl -sS -H 'content-type: application/json' \ --data '{"jsonrpc":"2.0","id":1,"method":"getGenesisHash"}' \ https://api.mainnet-beta.solana.com | jq -r .result)" echo "$GENESIS_HASH" # Oczekiwane (mainnet): 5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d # systemd unit (bind RPC to WG/localhost only) # UWAGA: w unit file NIE uzywaj `\\` na koncu linii w ExecStart. # Jesli wpiszesz `\\`, agave-validator dostanie literalny argument `\` i padnie z: # "error: The subcommand '\\' wasn't recognized" # # Najprosciej: ExecStart w 1 linii, bez "kontynuacji" backslashami. # Ale: zeby uniknac problemow z wklejaniem/lamaniem linii, ponizej jest bezpieczna wersja wielolinijkowa. sudo tee /etc/systemd/system/agave-validator.service >/dev/null <<'EOF' [Unit] Description=Agave validator (mainnet, RPC-only, non-voting) After=network-online.target wg-quick@wg0.service Wants=network-online.target wg-quick@wg0.service [Service] Type=simple User=solana Group=solana WorkingDirectory=/var/lib/solana Environment=RUST_LOG=info LimitNOFILE=1048576 Restart=always RestartSec=5 TimeoutStopSec=120 ExecStart=/opt/solana/bin/agave-validator \ --identity /var/lib/solana/identity.json \ --no-voting \ --private-rpc \ --ledger /var/lib/solana/ledger \ --accounts /var/lib/solana/accounts \ --log /var/log/solana/validator.log \ --bind-address 0.0.0.0 \ --rpc-bind-address 10.66.66.1 \ --rpc-port 8899 \ --dynamic-port-range 8000-8020 \ --entrypoint entrypoint.mainnet-beta.solana.com:8001 \ --expected-genesis-hash 5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d \ --full-rpc-api \ --limit-ledger-size 50000000 NoNewPrivileges=true PrivateTmp=true ProtectSystem=full ReadWritePaths=/var/lib/solana/ledger /var/lib/solana/accounts /var/log/solana /var/lib/solana [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable --now agave-validator systemctl is-active agave-validator journalctl -u agave-validator -n 80 --no-pager # Jesli padnie na genesis (brak genesis.tar.bz2): # doc/step-002c-genesis-download-mainnet.txt # # Jesli padnie na snapshot (mainnet wymaga snapshot): # doc/step-002d-snapshot-download-mainnet.txt # # Jesli chcesz najpierw odpalic validator z CLI (test), zanim przepniesz na systemd: # doc/step-002e-agave-validator-run-cli.txt 5) Geyser plugin -> Postgres # Krok po kroku: # doc/step-003-geyser-plugin-postgres.txt # # W skrocie: # - budujesz plugin .so i wrzucasz do /opt/solana/plugins/ # - tworzysz /etc/solana/geyser-postgres.json # - dopisujesz do ExecStart: # --geyser-plugin-config /etc/solana/geyser-postgres.json 6) Drift DLOB (2 markets) (on VPS, not baremetal) (placeholder) # VPS env: # PERP_MARKETS_TO_LOAD=0,75 # USE_GRPC=true # GRPC_ENDPOINT=http://10.66.66.1:10000 7) Monitoring (bind to WG only) (placeholder) # node_exporter (prefer bind to WG): # sudo apt-get install -y prometheus-node-exporter # sudo systemctl enable --now prometheus-node-exporter # # Prometheus/Grafana (bind to 10.66.66.1): # sudo apt-get install -y prometheus grafana # sudo systemctl enable --now prometheus grafana-server 8) NOC tmux (btop) (placeholder) # Create tmux session: # btop # iostat -x 1 # vmstat 1 # nstat -az # ethtool -S eth0 | head -n 40 (wrap in watch) # journalctl -fu agave-validator # while true; do curl getHealth/getSlot; sleep 1; done 9) Troubleshooting checklist # Services: systemctl status agave-validator --no-pager journalctl -u agave-validator -n 200 --no-pager # Sockets and binds: ss -lntp | egrep ':22\\b|:8899\\b|:8900\\b|:10000\\b|:9100\\b|:9090\\b|:3000\\b' || true # Firewall: sudo ufw status verbose # RPC local: curl -sS -H 'content-type: application/json' \ --data '{"jsonrpc":"2.0","id":1,"method":"getHealth"}' \ http://127.0.0.1:8899 | jq . 5-min quick verification checklist wg show sudo ufw status verbose systemctl is-active agave-validator ss -lntp | egrep ':8899\\b|:8900\\b|:10000\\b|:9090\\b|:3000\\b|:9100\\b' || true curl -sS -H 'content-type: application/json' \ --data '{"jsonrpc":"2.0","id":1,"method":"getSlot"}' \ http://10.66.66.1:8899 | jq .