Tenzro Testnet is live —request testnet TNZO
← Back to Tutorials

Run a Validator Node

InfrastructureAdvanced30 min

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.

FeatureTier 1: MicroNodeTier 2: Light ClientTier 3: Validator
InstallationNoneBinaryFull node
TDIP IdentityAuto-provisionedSelf-managedSelf-managed
MPC WalletAuto-provisionedSelf-managedSelf-managed
Block SyncNoHeaders onlyFull
ConsensusNoNoHotStuff-2 BFT
TNZO StakingNoOptionalRequired

Entry points: MCP, TenzroClaw, Claude Code, A2A protocol, TypeScript/Rust SDK, REST API, CLI, Desktop App. Full architecture docs →

Prerequisites

⚠️ 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:latest

Step 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

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 20

Expected 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:

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/metrics

Port Reference

Ensure these ports are accessible for proper validator operation:

PortServiceRequired
8545JSON-RPCYes
8080Web API + MetricsYes
9000P2P (libp2p)Yes (must be publicly accessible)
3001MCP ServerOptional
3002A2A ProtocolOptional

Gossipsub Topics

Your validator subscribes to these libp2p gossipsub topics:

TopicDescription
tenzro/blocks/1.0.0Block propagation
tenzro/transactions/1.0.0Transaction propagation
tenzro/consensus/1.0.0Consensus messages (validator-only)
tenzro/attestations/1.0.0TEE attestations (validator-only)
tenzro/models/1.0.0Model registrations
tenzro/status/1.0.0Status and discovery
tenzro/agents/1.0.0Agent-to-agent messages

Production Deployment Tips

  • Use a dedicated server with SSD storage for optimal performance
  • Set up monitoring with Prometheus + Grafana for the /metrics endpoint
  • Configure log rotation to prevent disk space exhaustion
  • Back up your /data directory 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