Run a Validator Node
What You'll Build
Run a Tenzro validator that produces blocks via HotStuff-2 BFT consensus, validates transactions, and earns TNZO staking rewards. Validators are the backbone of the Tenzro Ledger, securing the network and enabling decentralized settlement for AI inference and TEE services.
Tier 3: Validator Node
Running a validator makes you a Tier 3 participant — the backbone of the Tenzro Ledger. Validators produce blocks, participate in HotStuff-2 BFT consensus, validate transactions, and earn TNZO rewards.
| Feature | Tier 1: MicroNode | Tier 2: Light Client | Tier 3: Validator |
|---|---|---|---|
| Installation | None | Binary | Full node |
| TDIP Identity | Auto-provisioned | Self-managed | Self-managed |
| MPC Wallet | Auto-provisioned | Self-managed | Self-managed |
| Block Sync | No | Headers only | Full |
| Consensus | No | No | HotStuff-2 BFT |
| TNZO Staking | No | Optional | Required |
Entry points: MCP, TenzroClaw, Claude Code, A2A protocol, TypeScript/Rust SDK, REST API, CLI, Desktop App. Full architecture docs →
Prerequisites
- Linux server (x86_64 or aarch64), macOS, or Docker environment
- 4+ CPU cores, 8 GB RAM, 100 GB SSD minimum
- Static IP or DNS with port 9000 open for P2P networking
- TNZO tokens for staking (available from testnet faucet)
- Basic understanding of blockchain consensus and command-line operations
⚠️ Validator Responsibilities
Running a validator carries responsibility. Equivocation (double-voting) results in 10% stake slashing. Ensure you run exactly one validator instance per identity.
Your validator must maintain high uptime and network connectivity. Prolonged downtime may result in missed rewards and reduced reputation.
Step 1: Pull the Docker Image
The Tenzro node is distributed as a Docker image hosted in Google Artifact Registry. Pull the latest stable version:
docker pull us-central1-docker.pkg.dev/tenzro-infra/tenzro/tenzro-node:latestStep 2: Start a Validator Node
Create a persistent data directory and start your validator with the following command:
mkdir -p ~/tenzro-validator-data
docker run -d \
--name tenzro-validator \
-p 8545:8545 \
-p 8080:8080 \
-p 9000:9000 \
-p 3001:3001 \
-p 3002:3002 \
-v ~/tenzro-validator-data:/data \
us-central1-docker.pkg.dev/tenzro-infra/tenzro/tenzro-node:latest \
--role validator \
--data-dir /data \
--listen-addr /ip4/0.0.0.0/tcp/9000 \
--rpc-addr 0.0.0.0:8545 \
--boot-nodes '/ip4/10.0.0.10/tcp/9000'Command Flags Explained
--role validator— Run as a block-producing validator participating in HotStuff-2 BFT consensus--data-dir /data— Persistent storage for chain state, cryptographic keys, and block data--listen-addr /ip4/0.0.0.0/tcp/9000— Bind P2P libp2p listener for gossipsub networking--rpc-addr 0.0.0.0:8545— JSON-RPC server (also starts Web API on :8080, MCP on :3001, A2A on :3002)--boot-nodes— Connect to existing validators for peer discovery and DHT bootstrapping
Step 3: Verify Your Validator
Check that your validator is running and syncing with the network:
# Check node status
curl -s http://localhost:8080/status | python3 -m json.tool
# Check block height (should be incrementing)
curl -s -X POST http://localhost:8545 \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
# View logs
docker logs tenzro-validator --tail 20Expected output should show role: "validator", block_height increasing, and peer_count > 0.
Step 4: Join the Network and Mint a Bearer JWT
Before staking or registering an identity, join the network to provision a TDIP identity + MPC wallet, then onboard via OAuth 2.1 + DPoP (RFC 9449) to mint a bearer JWT. The JWT authenticates write operations against the MCP and JSON-RPC endpoints.
# Step 4a — provision identity + wallet via the CLI:
tenzro join --name "my-validator"
# Output includes:
# DID: did:tenzro:human:...
# Wallet: 0x...
# Step 4b — onboard via OAuth 2.1 + DPoP to mint a bearer JWT:
tenzro auth onboard-human --display-name "my-validator"
# Output: { "access_token": "eyJ...", "dpop_bound": true, "expires_in": 3600 }
# Or call the RPCs directly:
curl -s -X POST http://localhost:8545 \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"tenzro_participate","params":{"display_name":"my-validator"},"id":1}'
curl -s -X POST http://localhost:8545 \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"tenzro_onboardHuman","params":{"display_name":"my-validator"},"id":2}'
# Returns: { "identity": {...}, "wallet": {...}, "access_token": "eyJ..." }The bearer JWT is DPoP-bound to a holder Ed25519 key (RFC 7638 thumbprint). Use it as Authorization: DPoP <jwt> alongside a per-request DPoP: <proof> header for authenticated calls. Read-only queries (block height, balance, node status) are public. Write operations (staking, identity registration, sending transactions) require the JWT. Tokens are revocable by jti or by DID (cascading through the act-chain) — no central authority is involved.
Step 5: Stake TNZO Tokens
Validators must stake TNZO to participate in consensus. First create a wallet, request testnet tokens, then stake:
# Create a wallet
curl -s -X POST http://localhost:8545 \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"tenzro_createWallet","params":{"key_type":"ed25519"},"id":1}'
# Request testnet TNZO (100 TNZO per request, 24h cooldown)
curl -s -X POST http://localhost:8080/faucet \
-H 'Content-Type: application/json' \
-d '{"address":"YOUR_ADDRESS_HERE"}'
# Stake tokens (minimum 10,000 TNZO recommended)
curl -s -X POST http://localhost:8545 \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"tenzro_stake","params":{"amount":"10000","role":"validator"},"id":1}'
# Check staking status
curl -s -X POST http://localhost:8545 \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"tenzro_getVotingPower","params":{},"id":1}'Step 6: Register Your Identity
Register a TDIP (Tenzro Decentralized Identity Protocol) identity for your validator:
# Register a human identity
curl -s -X POST http://localhost:8545 \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"tenzro_registerIdentity","params":{"identity_type":"human","display_name":"My Validator"},"id":1}'
# Resolve your DID
curl -s -X POST http://localhost:8545 \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"tenzro_resolveIdentity","params":{"did":"YOUR_DID_HERE"},"id":1}'HotStuff-2 BFT Consensus
Tenzro validators participate in HotStuff-2 BFT consensus, an optimized version of the HotStuff protocol with the following properties:
- Two-phase commit: PREPARE → COMMIT → DECIDE
- O(n) linear communication complexity (instead of O(n²) in PBFT)
- TEE-attested validators get 2x weight in leader selection for enhanced security
- View change timeout: exponential backoff (base 2s, factor 1.5, max 30s)
- Equivocation detection: double-voting results in 10% stake slashing
Validators vote on blocks proposed by the current leader. Once a supermajority (2/3+) is reached, the block is finalized and added to the chain.
Validator Configuration (TOML)
For more advanced configuration, create a TOML config file:
[node]
role = "validator"
data_dir = "/data"
log_level = "info"
[rpc]
addr = "0.0.0.0:8545"
[network]
listen_addr = "/ip4/0.0.0.0/tcp/9000"
boot_nodes = ["/ip4/10.0.0.10/tcp/9000"]
[consensus]
# HotStuff-2 BFT settings
view_change_timeout_ms = 2000
max_block_size = 1048576
[staking]
auto_stake = true
stake_amount = "10000"Pass the config file to your validator with --config /path/to/config.toml. CLI flags override config file values.
Monitoring Your Validator
Monitor your validator's health and performance with these commands:
# Check peer connections
curl -s -X POST http://localhost:8545 \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"tenzro_nodeInfo","params":{},"id":1}'
# Check network sync status
curl -s -X POST http://localhost:8545 \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"tenzro_syncing","params":{},"id":1}'
# Prometheus metrics
curl -s http://localhost:8080/metricsPort Reference
Ensure these ports are accessible for proper validator operation:
| Port | Service | Required |
|---|---|---|
| 8545 | JSON-RPC | Yes |
| 8080 | Web API + Metrics | Yes |
| 9000 | P2P (libp2p) | Yes (must be publicly accessible) |
| 3001 | MCP Server | Optional |
| 3002 | A2A Protocol | Optional |
Gossipsub Topics
Your validator subscribes to these libp2p gossipsub topics:
| Topic | Description |
|---|---|
tenzro/blocks/1.0.0 | Block propagation |
tenzro/transactions/1.0.0 | Transaction propagation |
tenzro/consensus/1.0.0 | Consensus messages (validator-only) |
tenzro/attestations/1.0.0 | TEE attestations (validator-only) |
tenzro/models/1.0.0 | Model registrations |
tenzro/status/1.0.0 | Status and discovery |
tenzro/agents/1.0.0 | Agent-to-agent messages |
Production Deployment Tips
- Use a dedicated server with SSD storage for optimal performance
- Set up monitoring with Prometheus + Grafana for the
/metricsendpoint - Configure log rotation to prevent disk space exhaustion
- Back up your
/datadirectory regularly (contains cryptographic keys) - Consider running behind a firewall with only port 9000 exposed publicly
- Join the Tenzro validator community on Discord for updates and support
Next Steps
- Run a Light Node — Learn about Tier 2 light client nodes
- Connect via MCP — Interact with your validator via Model Context Protocol
- Build a Payment Agent — Create an AI agent that uses your validator
- Full Documentation — Deep dive into Tenzro architecture and APIs