Skip to content
Tenzro
Documentation menu
Consensus and ledger

Networking

How Tenzro Network 1 nodes find and reach each other: post-quantum validator channels, gossip, discovery, NAT traversal and local-first routing.

Tenzro Network 1 nodes run on residential connections, mobile links, homelabs and data centres. The networking layer has to work from behind any NAT, find nearby providers first, and give validators channels that stay secure against quantum attack. It has three parts:

  • Validator channels for consensus traffic, keyed with post-quantum cryptography and authenticated by hardware keys.
  • A peer-to-peer mesh (libp2p: gossipsub, Kademlia, Identify, AutoNAT v2, Circuit-Relay v2 and DCUtR) for discovery and broadcast.
  • A content-addressed data plane over QUIC for large payloads. See Iroh.

Validator channels

Every pair of active validators holds an authenticated channel for consensus traffic:

  1. Key exchange. The two sides run a hybrid key exchange, X25519 plus ML-KEM-768. The channel keys come from both shared secrets, so an attacker has to break both to read or forge traffic.
  2. Hardware-signed handshake. Each side signs the handshake transcript with its hardware key, a composite ML-DSA-65 plus P-256 signature, bound to the chain, the genesis and the epoch. Impersonating a validator means forging both signature schemes and having its hardware.
  3. Authenticated traffic. Every message on the channel carries a message authentication code and a sequence number, so messages cannot be forged, replayed or reordered.
  4. Re-keying. Channels are re-keyed every epoch, when the validator set may change.

The hardware signs once per channel, not once per message, so consensus runs at network speed. See Consensus.

Gossip

Gossipsub carries network-wide broadcasts on named topics:

TopicCarries
tenzro/blocksBlock propagation
tenzro/transactionsTransaction propagation
tenzro/attestationsTEE attestation evidence
tenzro/modelsModel registrations
tenzro/inferenceInference requests
tenzro/providersProvider announcements
tenzro/agentsAgent messages
tenzro/trainingTraining rounds
tenzro/databasesDatabase announcements
tenzro/blobsStorage replication requests
tenzro/identityIdentity updates
tenzro/statusStatus and discovery

Announcements are signed, and validator-only topics accept messages only from peers in the current validator set.

Discovery

  • Kademlia DHT finds peers across the internet.
  • mDNS finds peers on the same local network. tenzro_localPeers (or tenzro discover local-peers) lists them.
  • DNS bootstrap. Start a node with --bootstrap-dns <zone> and it resolves _tenzro-boot._tcp.<zone> SRV records, plus a _tenzro-id._tcp TXT record per target carrying that peer's id. Rotating a bootstrap peer is a zone edit.
  • Static boot nodes. --boot-nodes takes a comma-separated list of multiaddrs. Bootstrap lists can carry both DNS and IP forms of each peer, so a first dial does not depend on DNS resolving from the joiner's network.
_tenzro-boot._tcp.boot.example.org. 60 IN SRV 10 0 9000 v0.boot.example.org.
_tenzro-id._tcp.v0.boot.example.org. 60 IN TXT "peer_id=12D3KooW..."

NAT traversal

Nodes need no public address and no --external flag. By default tenzro-node listens on both /ip4/0.0.0.0/tcp/9000 and /ip4/0.0.0.0/udp/9000/quic-v1, so a peer can reach it over whichever transport its NAT allows. QUIC's stable port lets hole punching work reliably.

Four behaviours work together:

  • Identify. Peers exchange listen addresses and report the address they see you on. The node learns its public address from agreement between several peers.
  • AutoNAT v2. Dial-back probes confirm that the address is actually reachable.
  • Circuit-Relay v2. Publicly reachable nodes relay for nodes that are not.
  • DCUtR. Upgrades a relayed connection to a direct one by hole punching.

Publicly reachable validators run the server halves (relay and AutoNAT server); other nodes run the client halves.

toml
[network]
enable_relay = true          # serve as a relay when publicly reachable
enable_hole_punching = true  # punch through NAT as a client

The stack adapts at runtime. A node starts its DHT in client mode and promotes itself to server only once it has confirmed it is directly reachable, so a node behind a NAT never advertises an address nobody can dial. A node that finds a relay-capable peer books a relay reservation straight away, so a relayed address is ready before the first hole-punch attempt.

Reachability and local-first routing

Each node folds AutoNAT results, relay use and direct dials into a reachability tier (direct, relay_only or unreachable), published through tenzro_nodeReachability. Cluster planning uses it to leave out machines that cannot hold a direct link.

When a local provider can serve a request, the network prefers it: a request goes to a provider on the same LAN before crossing the internet, and falls back to remote providers otherwise.

Connection resilience

Dropped connections are expected on home and mobile links. Reconnects use exponential backoff with jitter. A streaming inference or training session that loses its connection resumes from its last acknowledged position instead of starting again.

Firewalls

Firewall rules on your host are yours to set. Open TCP 9000 and UDP 9000 for the peer-to-peer mesh, and UDP 9001 for the data plane. Some container-optimised host images drop all inbound traffic by default; add accept rules for these ports there too.