Layer 7 · The DIG Node peer network
Canonical references:
dig-gossip(the peer transport, discovery, and gossip layer — TLS-WebSocket peers,peer_id = SHA-256(TLS SPKI DER), address manager, introducer + peer-exchange),dig-relay(the rendezvous / hole-punch coordinator / circuit relay serving theRelayMessagewire),dig-nat(theconnect(peer)NAT-traversal ladder),dig-dht(the Kademlia DHT with provider records that locate which peers hold content), anddig-constants(DIG_RELAY_URL). This layer is how DIG Nodes find and reach each other; the dig RPC is what they speak once connected.
This is the normative anchor for DIG Node ↔ Node communication. Every peer-facing crate — dig-nat, dig-relay, dig-gossip, dig-dht, and dig-node — conforms to the contracts below. Where a statement is a wire contract it is fixed at the field/byte level; a conforming reimplementation must reproduce it exactly.
The thesis: authenticated peers, direct when possible, relay only as a last resort
- Every peer link is mutually authenticated. All node↔node traffic runs over mutual-TLS (mTLS). A peer's identity is the hash of its TLS public key; there is no unauthenticated peer channel.
- Direct paths are preferred. A node tries, in a fixed order, to open a direct connection (already reachable → UPnP → NAT-PMP → PCP → relay-coordinated hole-punch) before it ever relays. When any direct path succeeds, no relay is used.
- The relay is the last resort, never the trust anchor.
relay.dig.netbridges bytes only when every direct strategy fails. It forwards opaque, end-to-end-authenticated payloads by peer id and can read none of them.
The relay has four distinct roles
relay.dig.net is not a single service — it fills four separate roles, three of which are low-bandwidth signalling. Keeping them distinct matters because only the fourth carries a peer's data stream:
| # | Role | Bandwidth | What the relay does | Where |
|---|---|---|---|---|
| 1 | STUN server | tiny | Answers a Binding request so a node learns its public reflexive IP:port (RFC 5389). | §3 |
| 2 | Introducer | small | Registers a node's presence and returns known-peer lists for rendezvous/discovery. | §4a |
| 3 | Hole-punch signalling | small | Brokers a hole punch between two NAT'd peers — relays their candidate-address exchange and coordinates the simultaneous-open timing — after which the peers connect directly. The relay carries only the coordination messages, never the data. | §5 |
| 4 | Relayed (TURN-like) transport | full | Proxies all of a peer connection's data when no direct path exists. High-bandwidth, last resort only. | §6 |
Roles 1–3 are how the relay helps two peers connect directly; role 4 is the only one where the peer's stream flows through the relay. A node always prefers role 3 (broker a direct link) over role 4 (proxy the whole stream), because role 3 costs the relay almost nothing while role 4 consumes real bandwidth. Whatever the tier, once connected the link is mTLS with peer_id = SHA-256(SPKI) (§1) — the relay is never the trust anchor.
0 · The two RPC tiers — mTLS peer/control vs anonymous public read
A DIG Node's RPC is served on two distinct tiers with two distinct authentication models, because two different callers need it: other nodes (which present a client certificate) and browsers/agents (which cannot present a client certificate but must still be able to READ content). One dig-node process serves both; the tier a method lives on is a frozen contract every serve-layer and every RPC client conforms to.
| PEER / CONTROL tier | PUBLIC READ tier | |
|---|---|---|
| Purpose | node↔node: discovery, DHT, PEX, availability-for-sync, PUSH/WRITE, config/control | browser/agent content retrieval only |
| Auth | mutual TLS — client cert REQUIRED; peer_id = SHA-256(TLS SPKI DER) (§1); write routes additionally per-request BLS-signed (§21.9) | none — anonymous, no client cert, no bearer for reads |
| Transport | dig-nat mTLS mux (peer RPC + DHT + PEX streams) on the P2P port DIG_PEER_PORT (default 9444); the §21 authenticated HTTPS write routes | plain HTTPS JSON-RPC, CORS-enabled, on the public read listener (network-wide: rpc.dig.net) |
| Browser-reachable | No — an anonymous caller cannot open it | Yes — this is the browser/agent read path |
| Mutation / identity | write, peer, config, control all live here | read-only — no mutation, no peer/config method reachable |
| Integrity trust | mTLS peer identity | client-side self-verification (merkle inclusion proof + chain-anchored root pin) — the server is untrusted (Verification & provenance) |
| Miss behavior | method-specific error | decoy-on-miss, never 404 (blind host) |
The boundary invariant
Two rules, jointly, are the contract:
- No peer / write / config / control method is reachable without mTLS. Every method that mutates state, exchanges peer information, moves the DHT/PEX, or reconfigures the node is served only on the mTLS peer/control tier. On the anonymous public-read listener these methods do not exist — an anonymous caller that names one receives
-32601(method not found), the same as any unimplemented method. A node MUST NOT honor a write/peer/control method on a connection that did not complete the mTLS handshake. - Content read requires no mTLS. The read methods —
dig.getContentand the read side ofdig.getProof/dig.getCapsule/dig.getManifest/dig.getMetadata, plus the §21 GET routes (content/proof/roots/descriptor) — are served anonymously so a browser works. They are read-only: they never mutate, never reveal peer/config state, and never accept a write.
Which tier every method sits on is enumerated in §7a.