Run a validator
What a validator does
Section titled “What a validator does”Validators reach agreement through SecureWeave, NDSR’s BFT voting layer (quorum ⌊2n/3⌋+1, equivocation proofs, vote gossip and persistence).
- Executes direct calls (
/v1/execute) and keeps every module’s state, with state sync from peers. - Verifies committee votes, audits a random 10 % of rounds plus every contested one, and signs finality records.
- Checks and signs miner-set snapshots against its own Sepolia RPC.
- Proposes and attests per-project reward receipts; records slashing evidence.
Finality and audits · State sync
Requirements
Section titled “Requirements”- An always-on Linux server (x86_64 or aarch64) with a public HTTPS URL (validators receive inbound requests from the Hub and from each other). The testnet validators run on 1 vCPU / 1 GB / 10 GB machines.
- The
ndsrbinary built from the runtime’s source (cargo build --release --bin ndsr). - One or more Sepolia JSON-RPC endpoints.
- An EVM payout address.
Run it
Section titled “Run it”-
Create the node identity:
Terminal window ndsr keygen --data-dir /var/lib/ndsr# {"key_file":"/var/lib/ndsr/node.key","node_id":"ndsr-…","public_key":"0x…"} -
Start the node in committee mode (a non-loopback bind requires an API token of at least 16 characters):
Terminal window export NDSR_API_TOKEN=$(openssl rand -hex 24) # keep it secret; the Hub uses it as a bearer tokenndsr serve \--data-dir /var/lib/ndsr --bind 0.0.0.0:7070 \--ccs https://testnet-rpc.necter.network \--hub https://testnet-rpc.necter.network \--node-url https://node.example.org \--payout-address 0xYOUR_PAYOUT_ADDRESS \--chain-rpc https://ethereum-sepolia-rpc.publicnode.com --chain-rpc https://1rpc.io/sepolia \--chain-id 11155111 --network necter-testnet \--persist-ledgerPut TLS in front of port 7070 (any reverse proxy) so
--node-urlis reachable over HTTPS. -
The node registers itself with a signed request and appears as pending. Once approved and flagged, it syncs the validator set, starts receiving rounds and catches up module state from its peers.
Important flags
Section titled “Important flags”| Flag (env) | Default | |
|---|---|---|
--data-dir (NDSR_DATA_DIR) |
ndsr-data |
node.key, state.db, consensus.db, ledger.db, modules/ |
--bind (NDSR_BIND) |
127.0.0.1:7070 |
non-loopback requires NDSR_API_TOKEN |
--ccs (NDSR_CCS_URL) |
registration, heartbeats, receipts, artifact fetch | |
--hub (NDSR_HUB_URL) |
the --ccs URL |
base URL for /v1 calls |
--node-url (NDSR_NODE_URL) |
public URL the Hub and peers use | |
--payout-address (NDSR_PAYOUT_ADDRESS) |
EVM address for this node’s rewards | |
--chain-rpc (NDSR_CHAIN_RPC) |
Sepolia RPC, repeatable, tried in order; enables committee mode | |
--chain-confirmations |
32 | reorg depth used when finalized lags |
--chain-id |
11155111 | checked against eth_chainId |
--chain-start-block |
0 | first block of event replay (the testnet contracts were deployed at block 11870176) |
--staking-contract, --registry-contract |
from the Hub’s GET / |
|
--network |
necter-testnet |
|
--network-params FILE |
built-in testnet values | refused if its hash differs from GET /v1/network/params |
--epoch-secs, --gas-per-unit |
3600, 1000000 | network parameters: must match every other validator |
--exec-workers, --exec-queue |
CPUs (2..16), 64 | execution pool; /execute answers 503 beyond it |
--state-sync |
true | attest module state roots and catch up from peers |
--max-gas |
10^10 | largest gas_limit accepted (must match the network) |
ndsr serve --help lists every flag.
Health
Section titled “Health”| Route | |
|---|---|
GET /health, GET /node |
liveness and identity (open) |
GET /status |
executions, gas, rounds, gossip, rewards, pool, state sync; capabilities: {committee, receipt_v2, chain_rpc}; full detail with the bearer token |
GET /consensus/rounds/{round_id} |
tally, finality, own vote |
GET /consensus/evidence |
slashing evidence this node recorded |
GET /ledger?module=&function=&limit= |
recent signed receipts (with --persist-ledger) |
Committee mode is switched on for the network only when every current validator reports
capabilities.committee = true.