# Validator health check

## Overview

| Check         | Purpose                               |
| ------------- | ------------------------------------- |
| CPU / Load    | Ensures node isn’t CPU-bound          |
| Memory / Swap | Detects paging or low RAM             |
| Disk I/O      | Measures NVMe read/write latency      |
| Network       | Measures ping to `rpc.mainnet.x1.xyz` |
| NTP / Clock   | Verifies system time sync             |
| Vote Account  | Confirms validator is actively voting |

***

## Usage

1. Copy the full script below into a file named `x1_health.sh`:

   ```bash
   nano x1_health.sh
   ```
2. Make it executable:

   ```bash
   chmod +x x1_health.sh
   ```
3. Run:

   ```bash
   ./x1_health.sh
   ```

***

## Full Script

```bash
#!/bin/bash
# === X1 Validator Health Report ===
# Checks CPU, Memory, Disk I/O, Network, NTP, and Vote Activity

set -euo pipefail

echo "=============================================="
echo "🧠 X1 Validator Health Report"
echo "=============================================="
echo ""

# --- CPU & Load ---
echo "🔹 CPU & Thread Load"
echo "   → Measures overall CPU load and idle capacity."
CPU_MODEL=$(lscpu | grep "Model name" | awk -F: '{print $2}' | sed 's/^[ \t]*//')
LOAD=$(uptime | awk -F'load average:' '{print $2}' | xargs)
CPU_LINE=$(top -bn1 | grep "%Cpu" | head -1)
CPU_IDLE=$(echo "$CPU_LINE" | awk '{for(i=1;i<=NF;i++){if($i=="id,"){print $(i-1)}}}' | sed 's/,//')
CPU_IDLE=${CPU_IDLE:-$(echo "$CPU_LINE" | awk '{print $8}' | sed 's/,//')}
echo "CPU Model: $CPU_MODEL"
echo "Load Average: $LOAD"
echo "CPU Idle: ${CPU_IDLE:-unknown}%"
echo ""

# --- Memory ---
echo "🔹 Memory"
echo "   → Shows total, used, and cached memory (checks swap usage)."
free -h | awk 'NR==1 || NR==2 {print}'
SWAP_USED=$(free -m | awk '/Swap/ {print $3}')
echo "Swap used: ${SWAP_USED} MB"
echo ""

# --- Network ---
echo "🔹 Network latency to X1 RPC"
echo "   → Tests latency and packet loss to rpc.mainnet.x1.xyz."
PING_OUT=$(ping -c5 rpc.mainnet.x1.xyz)
PING_AVG=$(echo "$PING_OUT" | grep "rtt" | awk -F'/' '{print $5}')
echo "$PING_OUT" | grep "packets transmitted"
echo "Average ping: ${PING_AVG} ms"
echo ""

# --- Disk I/O (accurate NVMe parser) ---
echo "🔹 Disk I/O (5s sample)"
echo "   → Monitors live NVMe latency and utilization during validator operation."
IOSTAT_OUT=$(iostat -xm 1 5 | awk '/nvme/ {line=$0} END{print line}')
if [ -n "$IOSTAT_OUT" ]; then
  echo "$IOSTAT_OUT"
  R_LAT=$(echo "$IOSTAT_OUT" | awk '{print $10}')
  W_LAT=$(echo "$IOSTAT_OUT" | awk '{print $14}')
  UTIL=$(echo "$IOSTAT_OUT" | awk '{print $NF}')
else
  R_LAT="N/A"
  W_LAT="N/A"
  UTIL="N/A"
  echo "(No NVMe device detected — skipping latency check)"
fi
echo ""
echo "Avg Read Latency: ${R_LAT:-N/A} ms"
echo "Avg Write Latency: ${W_LAT:-N/A} ms"
echo "Disk Utilization: ${UTIL:-N/A} %"
echo ""

# --- NTP / Clock ---
echo "🔹 NTP / Clock sync"
echo "   → Verifies system clock and NTP synchronization status."
timedatectl status | grep -E "System clock|NTP service|synchronized|Time zone"
echo ""

# --- Vote Account Status ---
echo "🔹 Vote Account Activity"
echo "   → Confirms validator vote-account is active and submitting votes."
DEFAULT_VOTE_PATH="$HOME/.config/solana/vote-account.json"
if [ -f "$DEFAULT_VOTE_PATH" ]; then
  VOTE_ADDR=$(solana address -k "$DEFAULT_VOTE_PATH" 2>/dev/null || true)
else
  VOTE_FILE=$(find "$HOME/.config/solana" -maxdepth 1 -type f -name "*vote*.json" | head -n1 || true)
  if [ -n "$VOTE_FILE" ]; then
    VOTE_ADDR=$(solana address -k "$VOTE_FILE" 2>/dev/null || true)
  else
    VOTE_ADDR=""
  fi
fi

if [ -n "$VOTE_ADDR" ]; then
  echo "Detected vote account: $VOTE_ADDR"
  VOTE_INFO=$(solana vote-account "$VOTE_ADDR" 2>/dev/null || true)

  ROOT_SLOT=$(echo "$VOTE_INFO" | awk '/Root Slot:/ {print $3; exit}')
  LAST_VOTE=$(echo "$VOTE_INFO" | awk '/^- slot:/ {print $3; exit}')
  EPOCH_NUM=$(echo "$VOTE_INFO" | awk '/^- epoch:/ {print $3; exit}')

  echo "Root Slot: ${ROOT_SLOT:-N/A}"
  echo "Last Vote Slot: ${LAST_VOTE:-N/A}"
  echo "Epoch: ${EPOCH_NUM:-N/A}"

  if [[ "$LAST_VOTE" =~ ^[0-9]+$ ]]; then
    echo "Vote activity: ✅ Active (recent votes found)"
    VOTE_STATUS="✅ Voting active"
  else
    echo "Vote activity: ⚠️ No recent votes found"
    VOTE_STATUS="⚠️ Voting inactive"
  fi
else
  echo "⚠️ No vote-account.json found in ~/.config/solana/"
  VOTE_STATUS="⚠️ No vote account detected"
fi
echo ""

# --- Summary ---
echo "=============================================="
echo "✅ SUMMARY REPORT"
echo "=============================================="

if (( $(echo "$CPU_IDLE < 30" | bc -l) )); then CPU_STATUS="⚠️ High CPU usage"; else CPU_STATUS="✅ CPU OK"; fi
if (( SWAP_USED > 200 )); then MEM_STATUS="⚠️ Swap in use"; else MEM_STATUS="✅ Memory OK"; fi
if (( $(echo "$PING_AVG > 50" | bc -l) )); then NET_STATUS="⚠️ High latency"; else NET_STATUS="✅ Network OK"; fi
if [[ "$R_LAT" =~ ^[0-9.]+$ ]] && (( $(echo "$R_LAT > 2" | bc -l) )) || [[ "$W_LAT" =~ ^[0-9.]+$ ]] && (( $(echo "$W_LAT > 2" | bc -l) )); then
  DISK_STATUS="⚠️ Slow disk I/O"
else
  DISK_STATUS="✅ Disk OK"
fi
if timedatectl status | grep -q "synchronized: yes"; then CLOCK_STATUS="✅ Clock synced"; else CLOCK_STATUS="⚠️ NTP not synced"; fi

printf "%-15s %s\n" "CPU:" "$CPU_STATUS"
printf "%-15s %s\n" "Memory:" "$MEM_STATUS"
printf "%-15s %s\n" "Network:" "$NET_STATUS"
printf "%-15s %s\n" "Disk I/O:" "$DISK_STATUS"
printf "%-15s %s\n" "Clock:" "$CLOCK_STATUS"
printf "%-15s %s\n" "Vote:" "$VOTE_STATUS"
echo ""
echo "Done."
echo "=============================================="
```

***

## Example Output

```
🧠 X1 Validator Health Report
CPU Model: AMD Ryzen 9 9900X 12-Core Processor
Load Average: 5.62, 5.58, 5.47
CPU Idle: 78.3%

Avg Read Latency: 0.15 ms
Avg Write Latency: 0.23 ms
Disk Utilization: 8.3 %

🔹 Vote Account Activity
Detected vote account: 7oTGUhJt72GgGczT5KzQsqEcnuiHz8Wd9Wo5ZsKmR4hX
Root Slot: 6163567
Last Vote Slot: 6163611
Epoch: 40
Vote activity: ✅ Active (recent votes found)

==============================================
✅ SUMMARY REPORT
==============================================
CPU:        ✅ CPU OK
Memory:     ✅ Memory OK
Network:    ✅ Network OK
Disk I/O:   ✅ Disk OK
Clock:      ✅ Clock synced
Vote:       ✅ Voting active
Done.
==============================================
```

***

## Notes

* Run it as your validator user (not root) for accurate environment checks.
* Requires: `bc`, `sysstat`, and `solana` CLI in `$PATH`.\
  Install with:

  ```bash
  sudo apt install -y bc sysstat
  ```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.x1.xyz/validating/performance/validator-health-check.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
