Nodes
A node is a staked QUIC endpoint that caches and serves content-addressed blobs.- Identity. ed25519
NodeId(from iroh) bound on-chain to an Ethereum address via EIP-712 + ed25519 ownership proof at registration (network). - Stake. Required to join the mesh. Enforced by
StakingRegistry. - Gossip. Publishes
NodeAnnounce(~800 bytes, 60 s default) on the global topic (cdn/global/v1) and a regional topic (cdn/region/{cc}/v1). Also emitsRateChangewhen updating prices. - Delivery. Serves
cdn/client/v1— the sole paid-delivery protocol for both client→node and node→node traffic. - Earnings. Per-MB voucher revenue in the channel’s token — any governance-allowlisted ERC-20.
| Shape | What’s different | When to run |
|---|---|---|
| Pure cache | No origin backend. Pulls missed blobs from other nodes. | You want to earn on popular content; you don’t control any origin. |
| Origin-backed | Configured with an S3-compatible backend, NFS mount, or local disk. The hash→object-key mapping is a local content catalog. | You are the content provider, or you are running a “last-mile” seed node for a provider. |
Clients
A client is a lightweight QUIC endpoint that consumes content and pays for it.- Identity. ed25519 NodeId (ephemeral — no stake, no on-chain registration).
- Gossip. Subscribes to topics but does not publish.
- Payment. Opens an on-chain ERC-20 payment channel with each node it buys from, then signs EIP-712 vouchers per MB (payments).
- Trust model. Verifies BLAKE3 hashes on all bytes received. Trusts only what the trust model calls the “three-tier trust boundary”: verified cryptographically, trusted for availability, not trusted for content.
--max-channels N) and resume crashed transfers from the last BLAKE3-verified byte (bootstrap).
External components
These are not CDN protocol participants. They ride the same QUIC transport but do not gossip, probe, or stake.Origin backend
An S3 bucket, R2 bucket, MinIO instance, NFS mount, or local disk. Holds the canonical bytes. Origin-backed nodes query it on cache miss via anOriginStore trait. Never exposed to the network — the hash→object-key mapping is a private catalog held by the operator.
App server
Operated by the content provider when content is encrypted (encryption). Holds blob encryption keys, authenticates client sessions, and delivers epoch-key-wrapped blob keys overcdn/keys/v1. Compromise of the app server exposes all its content — this is an accepted trust assumption.
The CDN can deliver ciphertext blobs without any app server at all; encryption is opt-in per content provider.
Watchtowers
Non-custodial observers that hold a node’s latest voucher and submitdisputeChannel if a stale close is detected on-chain (watchtower). Cannot steal funds — the voucher’s EIP-712 signature is the only authorization the contract honors. Nodes register with 2–3 independent watchtowers via cdn/watchtower/v1.
Fees are held by a WatchtowerEscrow contract that requires mandatory heartbeats with voucher commitments — watched parties can reclaim escrowed fees on heartbeat failure.
Who stakes, who pays
| Participant | Stakes? | Pays? | Earns? |
|---|---|---|---|
| Pure cache node | ✅ TOKEN | ✅ Pays upstream on cache miss | ✅ Per-MB voucher revenue |
| Origin-backed node | ✅ TOKEN | ❌ | ✅ Per-MB voucher revenue |
| Client | ❌ | ✅ Per-MB voucher | ❌ |
| App server | ❌ | ❌ (off-protocol) | N/A |
| Watchtower | ❌ | ❌ | Fees via WatchtowerEscrow |