How to run the node tester in production: starting and stopping public testing, interpreting results, and dealing with common failures.
The node tester runs continuous VPN session audits against every active node on the Sentinel chain and publishes results to a public dashboard. The operator controls when tests run; public visitors only read results. This runbook covers day-to-day operations, monitoring, incident response, and the security checklist required before exposing the dashboard to the public internet.
- Navigate to your admin panel (default path:
/admin; changed byADMIN_PATH). - Log in with your
ADMIN_TOKEN. - Click Start Public Testing.
- Select the test mode:
- P2P — tester wallet pays gas and session fees directly. Requires P2P balance in the tester wallet.
- Subscription / Fee-granted — tests only nodes in a specific plan.
Sessions are broadcast via
broadcastWithFeeGrant; the plan operator covers all gas. RequiressubscriptionGranter(the plan owner'ssent1...address) and the tester wallet to be an active plan subscriber.
- Confirm the minimum inter-pass delay (default 30 seconds; higher values reduce chain load between full iterations).
- Click Confirm. The loop starts immediately.
Within 30 seconds, public pages (/ and /live) will show an active-testing
banner. The /live page streams real-time iteration progress via SSE.
- From the admin panel, click Stop Public Testing.
- The loop finishes its current node test and then halts.
- The public banner clears within 30 seconds as the SSE
loop:stoppedevent propagates.
Stopping is graceful: the current node test completes, results are written, and
then the loop exits. A hard stop (process restart) also works — audit.db is
never left in a corrupt state.
Click New Test on the admin panel. This runs a single full pass over all
online nodes using audit/pipeline.js and then stops. Mutually exclusive with
Public Testing Mode: if the continuous loop is running, New Test returns
409 Conflict — stop Public Testing first.
Click Retest Failed on the admin panel. This re-runs only the nodes that failed or were skipped in the most recent audit pass. Useful after fixing a WireGuard or V2Ray configuration issue without paying for a full re-scan. Also mutually exclusive with an active continuous loop.
Click Test Sub. Plan on the admin panel, then select a plan from the dropdown (populated from your wallet's active subscriptions). Only that plan's nodes are tested, and gas is covered by the plan operator's fee grant.
The admin panel shows:
- Current status (
idle,running,paused_internet,stopping) - Active run: nodes tested, passed, failed, elapsed time
- Public Testing status:
running/stopped, current iteration count, mode - Live SSE log panel: real-time per-node events
In Public Testing Mode, one iteration is a complete pass over all online
nodes. The iteration counter increments each time the loop completes a full
scan and restarts. A single iteration can take minutes to hours depending on
network size and NODE_DELAY_MS.
SSE events:
loop:started— loop began, emits{ mode, minDelayMs, iteration: 0 }iteration:start— a new pass is beginning, emits{ iteration, mode }iteration:end— pass complete, emits{ iteration, mode, durationMs, passed, failed }loop:stopped— loop halted, emits{ iterations, reason }
data/audit.db— SQLite database. Primary store for all node results, error logs, run metadata, and bandwidth history.runs/— one JSON file per completed audit pass. Useful for archiving and offline analysis.
GET /health
# Returns: {"ok":true}
Use this as the liveness probe for your reverse proxy or container orchestrator.
The tester wallet's P2P balance has fallen below 0.5 P2P. Top up by sending
P2P tokens to the wallet's sent1... address (displayed on the admin panel
under "Wallet"). Sub. Plan mode is unaffected — it uses fee grants, not the
tester's own balance.
The active LCD endpoint is unreachable. The server cycles through its built-in failover list automatically:
https://sentinel-api.polkachu.comhttps://api.sentinel.quokkastake.iohttps://sentinel-rest.publicnode.com
If all are unreachable, check general internet connectivity from the host. You
can override the endpoint list by setting LCD_ENDPOINTS in .env as a
comma-separated list and restarting the server.
On Windows, WireGuard tunnel creation requires an elevated process. Without it, WireGuard-protocol nodes are skipped (only V2Ray nodes are tested, which is approximately 70% of the network).
Fix: use SentinelAudit.vbs in the project root to relaunch with UAC
elevation, or run npm start from an elevated terminal.
On Linux/macOS: restart the server with sudo npm start.
A regular audit (single-pass) is already running. Wait for it to finish or click Stop on the admin panel, then start Public Testing.
The continuous Public Testing loop is live. Click Stop Public Testing on
the admin panel and wait for the loop:stopped SSE event before starting a
one-shot audit.
The tester wallet has no active plan subscriptions on-chain. Either switch to Test ALL (P2P) mode, or subscribe to a plan through a Sentinel app first.
The plan operator has not granted a fee allowance to the tester wallet, or the grant has expired. Verify by running:
sentinel-audit balance # also prints active fee grantsContact the plan operator to issue or renew the MsgGrantAllowance on-chain.
The database accumulates result rows, error logs, and run metadata over time. To remove orphaned or runaway rows from incomplete runs:
node scripts/cleanup-runaway-runs.mjsFor a full database analysis (tables, row counts, size breakdown):
node scripts/analyze.cjsNeither script deletes completed run data — they only remove dangling or
partial records. Back up audit.db before running either script.
The Node.js process may have accumulated large in-memory log buffers. Restart
the server — audit.db is durable and no data is lost. For systemd deployments:
sudo systemctl restart sentinel-node-testerFor Docker:
docker compose restartComplete every item before pointing a public domain at this server.
-
PUBLIC_MODE=trueset in.env. -
ADMIN_TOKENset to a 32-byte (64-character) random hex value. Generate:node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" -
ADMIN_PATHchanged from/adminto an unguessable path (e.g./ops-7f3a9) for defense in depth. Not a substitute for a strong token, but reduces automated scanning exposure. -
ALLOW_PUBLIC_TEST=false(the default) unless you deliberately want public visitors to trigger test runs. Leaving itfalsemeans only the admin can start tests. -
MNEMONICis not checked into git. Confirm with:git log --all --oneline -- .envIf it appears, rotate the mnemonic immediately and revoke the exposed wallet. -
HTTPS termination at the reverse proxy level. The application speaks plain HTTP; TLS must be provided externally.
Minimal nginx example:
server { listen 443 ssl; server_name tester.example.com; ssl_certificate /etc/letsencrypt/live/tester.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/tester.example.com/privkey.pem; location / { proxy_pass http://127.0.0.1:3001; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # SSE: disable buffering proxy_buffering off; proxy_cache off; } }
Minimal Caddy example:
tester.example.com { reverse_proxy 127.0.0.1:3001 { flush_interval -1 } }The
flush_interval -1/proxy_buffering offdirective is required for SSE (/api/public/eventsand the admin log stream) to deliver events in real time. -
Admin path not indexed by search engines. Add to your
robots.txt:User-agent: * Disallow: /admin(replace
/adminwith your actualADMIN_PATH).
Two items must be included in any backup:
data/audit.db— the SQLite database. All persistent results live here.runs/— per-run JSON archives. Used for replay and offline analysis.
The .env file must also be backed up securely (separately from the codebase).
For Docker deployments, both paths are bind-mounted from the host — back up the host directories directly.
- deploy/README.md — Docker and systemd deployment steps.
- docs/CLI.md — full CLI subcommand reference.
- docs/ARCHITECTURE-PUBLIC-LIVE.md — public live-view page design.
- TROUBLESHOOTING.md — extended troubleshooting guide.