Running a Sentrix Validator
[!NOTE] Sentrix is permissionless under Voyager DPoS — anyone with the required self-stake can register as a validator without contacting the Foundation. The chain does not maintain a whitelist.
This is the end-to-end guide for an independent operator — not the
Sentrix team, not an internal contributor — who wants to run a Sentrix
validator node. You provide the hardware, the time, and the stake. The
chain does not care who you are or where your host is; it only cares
that your validator address is in the on-chain stake registry, that you
bonded MIN_SELF_STAKE (15,000 SRX), and that your node produces valid
blocks when it's your turn.
The doc assumes you can read a Linux manpage, can use systemd, and
have shell access to a server under your control. No specific cloud
provider, no specific OS version, no "join the operator's private
fleet" required.
Choose your participation path
Before going further, decide whether you actually need to run a validator. Three ways to participate in Sentrix consensus economics, ranked by hands-on commitment:
| Path | What you do | Stake | Hardware | Risk | Reward |
|---|---|---|---|---|---|
| Run a validator (this guide) | Operate a node 24/7, sign every assigned block, keep the keystore safe, respond to incidents. | ≥ 15,000 SRX self-stake + any delegated stake | One server matching the spec in §4 | Slashing (20% on double-sign), jailing (liveness <70%) | Block reward + tx fees + commission on delegations |
| Delegate to a validator | Pick an active validator from /staking/validators, submit StakingOp::Delegate { validator, amount }. Claim accrued rewards with StakingOp::ClaimRewards when convenient. | Any amount (no minimum) | None | Slashing follows the validator you delegated to | Block reward share net of validator commission |
| Wait for staking SaaS | Stake through a third-party provider that runs the hardware for you. | Provider-defined | None | Custodial — you trust the provider | Provider-defined |
Today only paths 1 and 2 exist on Sentrix — no staking SaaS providers yet. If you can't commit ≥ 99.5% uptime + the §4 spec, delegate instead. Validator slashing applies to the wallet that signed the bad block — not to the delegators behind that validator's stake, but their delegated rewards stop accruing while the validator is jailed. Both paths benefit from the same emission curve.
The rest of this doc assumes you've picked Path 1.
Table of contents
- What you're signing up for
- Active-set shape
- 5-minute quickstart
- Hardware + network
- Get the binary
- Keystore
- systemd unit
- Register as a validator (permissionless)
- Deploying updates
- Monitoring
- Recovery paths
- FAQ
- Where to ask
1. What you're signing up for
Consensus responsibility
Sentrix runs Voyager DPoS + BFT on mainnet, live since h=579,047
(2026-04-25). Stake-weighted, uncapped candidate set (cap was
lifted v2.2.11), 21 active validators rotate based on stake rank,
3-phase BFT round (propose / prevote / precommit) per block, 2/3+1 of
stake-weighted active set finalises. Block-time target is BLOCK_TIME_SECS = 1 second; mainnet ranges ~1–2 s in steady state, testnet typically ~1 s.
[!IMPORTANT]
- Node uptime expectation: >99.5%. The in-chain liveness tracker jails validators that miss more than 70% of slots in a rolling 14,400-block window (~4 hours at 1 s block time).
- You sign every block in your turn. Double-signing is slashable (20% stake cut + auto-jail).
- Self-stake minimum: 15,000 SRX (1,500,000,000,000 sentri), enforced by
register_validatorapply path.- You may delegate additional stake to yourself to climb the active- set ranking (top-21 produce blocks).
Operational responsibility
- Running the
sentrixbinary under systemd. - Firewall + SSH hardening. Recommended: UFW + fail2ban +
PasswordAuthentication=no. - Encrypted keystore (Argon2id v2). Never publish your private key, never ship it in an env variable that ends up in process listings.
- Monitoring: read your own
journalctl -u sentrix-<your-name>and know whatCRITICAL #1e: state_root mismatchmeans (= you're diverging from canonical, recovery procedure in §11). - Upgrades: track the chain's release channel, deploy new binaries within the announced maintenance window.
2. Active-set shape
| Parameter | Value |
|---|---|
| Active validators | 21 (top by total stake) |
| Candidate set | unlimited (any address with ≥ MIN_SELF_STAKE) |
MIN_SELF_STAKE | 15,000 SRX |
| Permissionless | yes — no whitelist, no admin approval |
| Block time | 1 s target; mainnet ~1–2 s observed, testnet ~1 s |
| Finality | BFT supermajority (2/3+1 stake-weighted) |
The small active set is deliberate — BFT supermajority round-trips stay short, block time stays low. Candidates beyond 21 sit on the bench ranked by stake and rotate in when an active spot frees up (jail, unbond, slash).
3. 5-minute quickstart
For operators who already run blockchain nodes and just want the
"happy path" — fill in <…> placeholders:
# 1. Pull + build (Rust 1.95+)
git clone https://github.com/sentrix-labs/sentrix.git && cd sentrix
cargo build --release -p sentrix-node # binary: target/release/sentrix
# 2. Generate keystore (writes data/wallets/<addr>.json)
./target/release/sentrix wallet generate --password "<strong-passphrase>"
# 3. Fund the new address with ≥15,000 SRX (mainnet — buy / OTC / earn;
# testnet — faucet at https://faucet.sentrixchain.com)
# 4. Install + run as systemd (see §7 for unit template)
sudo cp target/release/sentrix /opt/sentrix/
sudo systemctl enable --now sentrix-<your-name>
# 5. Submit RegisterValidator tx (see §8 for the exact JSON-RPC payload)
# Or wait for the upcoming `sentrix validator register` CLI helper.
That's the whole permissionless flow. No email, no DM, no approval.
4. Hardware + network
Mainnet reference (observed at recent steady state):
| Resource | Minimum | Comfortable |
|---|---|---|
| vCPU | 8 | 16 |
| RAM | 16 GiB | 32 GiB |
| Swap | 16 GiB persistent (/etc/fstab) | 32 GiB |
| Disk | 1 TB NVMe SSD | 2 TB NVMe SSD |
| Bandwidth | 100 Mbit sustained | 1 Gbit |
[!CAUTION] RAM + swap floor is non-negotiable.
chain.dbis mmap'd; tight memory with zero swap → page-cache thrash under tx load → tokio worker stalls → silent halts. Empirically observed across 2026-04 incidents. Any 64-bit Linux works (Ubuntu 22.04 + 24.04 verified).
The consensus binary is OS-deterministic across kernel, glibc, and CPU family — verified across Ubuntu 22.04 (glibc 2.35) and 24.04 (glibc 2.39) hosts.
Open inbound ports:
30303/tcp(or your--port) — libp2p P2P22/tcp— SSH (restrict to your IP / jumpbox if possible)
[!WARNING] Do not expose the RPC port (
8545) publicly without a reverse proxy + rate limit. Bind RPC to127.0.0.1and front it via Cloudflare / Caddy / nginx if you want public RPC. Otherwise keep local-only.
5. Get the binary
Build from source (recommended)
git clone https://github.com/sentrix-labs/sentrix.git
cd sentrix
cargo build --release -p sentrix-node
# target/release/sentrix
Toolchain: Rust 1.95+ (stable). The reference reproducible build:
docker run --rm -v "$PWD:/w" -w /w rust:1.95-bullseye \
cargo build --release -p sentrix-node
Compare sha256sum target/release/sentrix against the published
release-notes hash to verify your build matches canonical.
Download a release
Signed tarballs at https://github.com/sentrix-labs/sentrix/releases.
Verify SHA-256 against the release notes. Extract sentrix and
chmod +x.
6. Keystore
Generate the validator keypair:
./sentrix wallet generate --password "<strong-passphrase>"
# Address: 0x...
# Keystore: data/wallets/<addr>.json
Or import an existing private key:
./sentrix wallet encrypt "<hex-private-key>" \
--password "<pwd>" \
--output /opt/sentrix/data/wallets/my-validator.keystore
Set permissions:
sudo chmod 600 /opt/sentrix/data/wallets/*.json
sudo chown <service-user>:<group> /opt/sentrix/data/wallets/*.json
[!TIP] Wallet helpers (v2.2.10+) use a no-echo prompt (
rpassword), confirm-twice onrekey, atomic backup+rename with rollback on failure, and zeroize passwords on drop. Thewallet rekeycommand verifies a decrypt round-trip before overwriting your only copy, and leaves a.bak-<ts>you canrmafter stable operation.
Password hygiene
- Password lives in the systemd
EnvironmentFileat mode600. Never in the unit file itself (env files don't show inps; unit files do). - Rotate with
sentrix wallet rekey <keystore> --old-password … --new-password …. - Lost password = lost validator. There is no recovery path. Use a password manager + encrypted backup.
7. systemd unit
/etc/systemd/system/sentrix-<your-name>.service:
[Unit]
Description=Sentrix validator (<your-name>)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=<unprivileged-service-user>
WorkingDirectory=/opt/sentrix
ExecStart=/opt/sentrix/sentrix start \
--validator-keystore /opt/sentrix/data/wallets/<my>.keystore \
--peers <bootstrap-multiaddrs-from-channel>
Restart=always
RestartSec=5
LimitNOFILE=65536
EnvironmentFile=/etc/sentrix/sentrix-<your-name>.env
Environment=SENTRIX_DATA_DIR=/opt/sentrix/data
Environment=SENTRIX_ENCRYPTED_DISK=true
[Install]
WantedBy=multi-user.target
Env file /etc/sentrix/sentrix-<your-name>.env (mode 600, owner =
service user):
SENTRIX_WALLET_PASSWORD=<your-keystore-password>
Start + tail:
sudo systemctl daemon-reload
sudo systemctl enable --now sentrix-<your-name>
sudo journalctl -u sentrix-<your-name> -f
You should see:
Validator mode: 0x<your-validator-address>
P2P transport: libp2p (Noise encrypted)
Peer connected: 12D3KooW…
[!NOTE] Bootstrap peer multiaddrs are published in the chain's release notes and refreshed periodically. Ask in the operator channel if you're unsure which set is current.
8. Register as a validator (permissionless)
Your node is running as a peer. To produce blocks you must register in the on-chain stake registry.
Requirements
| Field | Value |
|---|---|
| Bond | tx.amount must equal self_stake and be ≥ 15,000 SRX |
| Commission rate | 0 – 100% (basis points; 1000 = 10%) |
| Validator address | Your wallet's address (= sender of the tx) |
| Public key | Uncompressed secp256k1 hex (printed by wallet info) |
The bond moves your SRX to the protocol treasury during apply; you
can unbond later via StakingOp::Undelegate (subject to a 7-day
unbonding period).
Build + submit the transaction
The wire format is StakingOp::RegisterValidator { self_stake, commission_rate, public_key }
sent as a regular signed transaction with to_address = TOKEN_OP_ADDRESS
and tx.amount == self_stake.
Until the dedicated CLI helper ships, use any of:
sentrixREPL / scripted tx builder — the chain shipscli_create_token_tx(same shape as token ops); analogouscli_create_staking_txhelper coming in a follow-up release.- JSON-RPC eth_sendRawTransaction — encode
StakingOpas the txdatafield, sign with your wallet, broadcast. - Web tooling — a simple form will land at
https://validators.sentrixchain.comfor non-CLI operators.
Verify registration
# Stake registry (your address should appear)
curl -s https://rpc.sentrixchain.com/staking/validators | jq '.validators[] | select(.address=="0x<yours>")'
# Authority (round-robin scheduler — RegisterValidator mirrors here)
curl -s https://rpc.sentrixchain.com/chain/info | jq '.active_validators'
You'll appear immediately in stake_registry, and rotate into the active set at the next epoch boundary if you're in the top-21 by total stake (self + delegated).
[!IMPORTANT] The protocol does not require operator approval, a moniker whitelist, or off-chain registration. Pre-2026-05-13 docs that described an email + admin-cosign flow are now obsolete — that was the PoA Pioneer path before Voyager DPoS activated. Voyager has been live since h=579,047 and the candidate cap (was 100) was lifted in v2.2.11.
9. Deploying updates
Use the generic scripts/deploy-validator.sh in the repo:
./scripts/deploy-validator.sh \
--ssh-key ~/.ssh/my_operator_key \
--service sentrix-my-name \
--bin-dir /opt/sentrix \
--rpc-url http://127.0.0.1:8545 \
--binary ./target/release/sentrix
SCPs the binary, archives the previous copy, restarts the service, health-checks it.
For a rolling restart across many validators, loop over the above.
MIN_ACTIVE_VALIDATORS = 1 since v2.1.11 — the chain technically
tolerates a single active validator, but keep 3+ up during a rolling
deploy so block production never depends on a single host.
10. Monitoring
At minimum, alert on:
systemctl is-failed sentrix-<your-name>journalctl -u sentrix-<your-name> --since '5 min ago' | grep -c CRITICAL> threshold/chain/info.heightdelta = 0 for >2 min- Disk free < 10 GiB
Sentrix emits a rolling-window state_root-mismatch alarm (v2.1.9+) that fires one LOUD log line if you start rejecting >100 peer blocks per 5 min — the message includes the rsync-recovery playbook inline.
Grafana dashboard templates: see operator issue #625 (work-in-progress).
11. Recovery paths
You missed a lot of blocks (< 1 week)
The node syncs from peers automatically on restart. The GetBlocks
handler serves evicted history from MDBX, so fresh nodes and long-
stalled nodes both catch up without a state snapshot.
Your state diverges
[!CAUTION] Do not run
sentrix state importon a post-genesis chain. v2.1.5 and later refuse to start on a keystore built from that path. The correct recovery is frozen-rsync ofchain.dbfrom a peer you trust, with ALL validators halted.
Short procedure:
# 1. Stop your node + the trusted peer
systemctl stop sentrix-<your-name> # local
ssh trusted "systemctl stop sentrix-<theirs>"
# 2. Rsync chain.db
rsync -avz trusted:/opt/sentrix/data/chain.db /opt/sentrix/data/
# 3. Start both
systemctl start sentrix-<your-name>
ssh trusted "systemctl start sentrix-<theirs>"
Full incident archive: internal operator runbooks.
You lose your data directory
Restore from backup, or sync from scratch. The node re-fetches all
blocks from peers. On Voyager you may be jailed for downtime and
need a StakingOp::Unjail tx.
12. FAQ
Do I need permission from the Sentrix team?
No. Since v2.2.11 (2026-05-13), registration is fully permissionless
— any address with ≥15,000 SRX bonded can submit
StakingOp::RegisterValidator. The candidate cap was lifted.
How do I get 15,000 SRX on mainnet?
Buy on a DEX once liquid, OTC from existing holders, or earn through ecosystem participation (faucet drops are too small for mainnet bonding — testnet faucet has enough for testing).
What's the difference between "candidate" and "active validator"?
- Candidate — anyone registered in the stake registry. No cap.
- Active — top-21 by total stake (self + delegated), produces blocks via round-robin. The 22nd-highest candidate sits on the bench until an active spot frees up (jail, unbond, slash).
How are blocks scheduled?
Voyager uses round-robin over the active set: proposer(h) = active_set[h % active_set.len()]. Active set is sorted by stake
(deterministic). Failed proposers timeout and the next-in-rotation
takes over (BFT skip-round).
Can I run multiple validators from one host?
Technically yes (multiple systemd units + different keystores + different ports + different data dirs), but operationally fragile — one disk failure or noisy-neighbour CPU spike takes down both. The reference deployment co-tenants 3 validators per host only on hosts sized 8 vCPU / 24 GiB; sub-that you should run one validator per host.
What happens if I get jailed?
Your stake_registry entry flips is_jailed = true, you stop being
in the active set, no blocks scheduled to you, no rewards accrue.
Submit StakingOp::Unjail after the jail-cooldown to re-enter the
candidate pool. Repeated jails = stake slash + tombstone (permanent
removal) per the slashing parameters.
Is my private key recoverable?
No. Lost password = lost validator. Bonded SRX is unrecoverable without the signing key. Treat keystore + password like a hardware wallet seed.
What counts as "double-signing" and how do I avoid it?
Double-signing = signing two different blocks at the same (height, round). The on-chain last-sign.json guard ships in v2.1.85+ and
refuses to re-sign a different hash for the same (h, r), so the
binary itself blocks the slashing condition. The two ways you can
still trip it: (a) running the same keystore on two hosts at once
(both have their own last-sign.json, neither sees the other's
signature), (b) restoring an old chain.db snapshot that rewinds
past a height you've already signed (and manually removing
last-sign.json to "fix" the boot error). Rule: one keystore, one
running process, never delete last-sign.json to bypass a guard
error.
Can I migrate my validator to a new host?
Yes — keystore + chain.db move together. (1) Stop the old host's
service. (2) scp the keystore, last-sign.json, and chain.db
to the new host. (3) Set up the systemd unit + env file on the new
host. (4) Start. The old host must not start again with the
same keystore, ever — that's the double-sign trap above. Best
practice is to rename the old keystore file to *.archived on the
old host before bringing the new host up.
What's the difference between validator and fullnode?
A validator signs blocks. It bonds ≥ 15,000 SRX, sits in the active-set rotation, and faces slashing / jailing. It should NOT serve public RPC.
A fullnode follows the chain but doesn't sign. It serves public JSON-RPC / REST / gRPC / WSS to dApps and explorers, replays new blocks via libp2p, and can be load-balanced. No stake required, no slashing risk.
The reference deployment runs both: validators behind a firewall, fullnodes as the public-RPC frontline. If you only want to operate infrastructure (not earn validator rewards), run a fullnode — it's the same binary with a different config.
How do I monitor for jail risk before it happens?
The liveness tracker fires JAIL_THRESHOLD = 70% missed-in-window.
Alert before that:
/sentrix_statusreturnsliveness_window_signedandliveness_window_total. Alert atsigned/total < 0.85for early warning.- Prometheus exporter exports the per-validator missed-count gauge
(
sentrix_validator_missed_blocks_in_window). - Grafana dashboard panel shows the trend — see
observability.mdfor the JSON.
If you breach 0.85, find the cause (host CPU, disk, network) before 0.70 fires.
Can I change my commission rate after registering?
Yes — submit StakingOp::UpdateValidator { commission_rate: new_bp }. The new rate applies to blocks produced from that height
forward; previously-accrued rewards in the accumulator pay out at
the rate that was active when they accrued. Delegators see the
change on next claim. There's no cool-down or rate-limit on
updates today, but spamming changes erodes trust — communicate
ahead with your delegators.
How long from RegisterValidator to producing blocks?
Two thresholds:
- Candidate — instant on
RegisterValidatorapply. The tx finalizing puts you in the candidate pool. - Active — next time you're ranked in the top-21 by total stake. If the active set has fewer than 21 today, you go active in the next epoch boundary. If the active set is full, you're active when one of the bottom-stake actives unbonds, gets jailed, or gets out-staked by you.
On testnet that's typically minutes (small active set, churn). On mainnet today the active set is small (4 reference validators), so a fresh registration with ≥ 15,000 SRX self-stake enters active immediately on the next epoch tick.
13. Where to ask
| Channel | URL |
|---|---|
| Validator ops coordination | [email protected] |
| Public docs | https://docs.sentrixchain.com/operations/ |
| Block explorer (mainnet) | https://scan.sentrixchain.com |
| Block explorer (testnet) | https://scan-testnet.sentrixchain.com |
| Public RPC mainnet (chain 7119) | https://rpc.sentrixchain.com |
| Public RPC testnet (chain 7120) | https://testnet-rpc.sentrixchain.com |
| Testnet faucet | https://faucet.sentrixchain.com |
| Sourcify verifier | https://verify.sentrixchain.com |
| gRPC + gRPC-Web | https://grpc.sentrixchain.com · https://grpc-testnet.sentrixchain.com |
| GitHub issues | https://github.com/sentrix-labs/sentrix/issues |
| Security advisories | security.md in repo root |
[!NOTE] This doc describes a chain that supports many independent operators on diverse hosts and OS versions. If any step above assumes the reference operator's infrastructure or invokes a Foundation / Treasury / Core / Beacon label in a way that isn't marked as a historical reference, file a PR or open an issue.