Run a Validator

Install

  • Install Rust and Cargo.
  • Clone scl-node and build the release binary with cargo build --release. The binary lands at target/release/scl-node.
  • Keep it alongside a writable data directory for state and logs.

You do not need a local Bitcoin node: chain data is read from an Esplora endpoint over HTTP.

Configure

Configuration comes from a config.toml next to the binary, from environment variables, or both; environment variables override the file. All fields have working defaults.

Example config.toml:

node_id = "my-node"
rest_address = "0.0.0.0:8080"        # client-facing REST API
bind_address = "0.0.0.0:50051"       # gRPC: peer sync and gossip
url = "http://my-node.example:50051" # public gRPC URL advertised to peers
peers = ["http://node1.example:50051", "http://node2.example:50051"]
esplora = "https://blockstream.info/api"
db_path = "./data/scl-node"
data_dir = "./data"
peer_limit = 10

# Optional: stable Ed25519 identity for signing gossip (64 hex chars).
# Omit for an ephemeral identity.
gossip_private_key = ""

# Optional: bearer token protecting private endpoints
# (confirmed-call log, admin operations). Omit to leave them locked.
api_token = ""

The equivalent environment variables:

Variable Default Purpose
SCL_NODE_ID scl-node-1 Node identifier
SCL_REST_ADDRESS 0.0.0.0:8080 REST API bind
SCL_BIND_ADDRESS 0.0.0.0:50051 gRPC bind
SCL_PUBLIC_URL http://localhost:50051 Public gRPC URL advertised to peers
SCL_PEERS empty Comma-separated peer gRPC URLs
SCL_PEER_LIMIT 10 Max peers for gossip forwarding
SCL_ESPLORA_URL https://blockstream.info/api Esplora API base (set a testnet URL for testnet)
SCL_DB_PATH data/scl-node Database path
SCL_GOSSIP_PRIVATE_KEY empty Ed25519 seed for a stable gossip identity
SCL_API_TOKEN empty Bearer token for private endpoints
RUST_LOG info Log filter

Start

./scl-node

There are no subcommands; configuration fully determines behavior. A docker-compose.yml in the repository runs a single node with persistent data if you prefer containers.

On startup your node:

  • Initializes local storage.
  • Fetches the current Bitcoin height from Esplora and anchors its block journal.
  • Reloads the contract registry.
  • Syncs with peers using Merkle-based diffing.
  • Then serves requests, gossips payloads, and watches Bitcoin for new blocks (checking every 60 seconds, with a full peer sync every 5 minutes).

Health check:

curl -i http://localhost:8080/health
# Expect: HTTP/1.1 200 OK

curl http://localhost:8080/node_status

Verify you're in sync

Compare state roots with another node; matching roots at the same height prove matching state:

curl http://localhost:8080/v2/state_root

For the full REST and gRPC surface, see the Node API Reference. Treat the REST surface as current implementation, not a stable public API.

Earning XRB

Validators stake XRB to participate in validation rounds and earn from the validator emission pool, released per Bitcoin block, plus fee flows from network activity. See Fuel and Emissions for the mechanism and numbers.