Repository navigation
Relay peering: advertise terms in NIP-11, authenticate peers, handle feeds distinctly from clients #931
Description
Motivation
Relaying is asymmetric: accepting writes is cheap, serving reads (subscription fan-out) is where the cost lives. Relays already exchange feeds today — nostream's static mirroring does it — but every peering relationship is arranged out of band and hardcoded in config:
- A relay has no way to advertise that it offers feeds to other relays, in what scope, or on what terms.
- The source relay cannot distinguish a peer's feed subscription from an ordinary client's — a peer is just another connection, subject to the same rate limits and subscription caps designed for end users.
- There is no peer identity handshake: mirroring targets are URLs in a config file, not authenticated relay keypairs.
The protocol pieces mostly exist (NIP-77 explicitly covers relay-relay sync, NIP-11 already carries fees/payments_url and a relay self pubkey, NIP-42 provides connection authentication). What's missing is the control plane: discovery, identity, and peer-aware handling. The plan is to build it in nostream first, get real operators peering with it, and only then propose a NIP that codifies working practice.
Topology this enables
Peering makes relay roles composable instead of every relay having to be everything:
- Archive/backbone peers — hold deep history, talk mostly to other relays, sell or swap feeds.
- Cache peers — hold only a rolling recent window (e.g. the last hour), fed by backbones, absorbing the recency-biased bulk of read load near where demand is. They store almost nothing, are cheap to run anywhere, and are disposable: if one dies, a replacement backfills its whole window over negentropy in minutes and nothing is lost.
- Edge/community relays — user-facing; hold what their community needs and fetch the rest from cache/archive peers on demand (step 5).
A cache peer is a configuration of the machinery in this issue (short retention + a peering feed), not a separate implementation — but two things must hold: the advertisement (#932) should let a peer express a rolling-window scope and its retention, and a cache miss must be legible as "outside my window — ask an archive", never as "this event does not exist", so on-demand requests can fall through cache → archive.
Proposal
-
Peering advertisement in the NIP-11 document. Add a
peeringsection: whether peering is offered, offered scopes (kinds / time ranges), terms reusing the existing fee-object shape (amount,unit,period— settlement-free must be expressible), and a peer contact/endpoint. -
Authenticated peer identity. A peer relay connects and authenticates via NIP-42 AUTH using its relay keypair (the
selfpubkey from its NIP-11 document). nostream recognizes configured peers by pubkey rather than by URL alone. -
Peer-aware connection handling. Connections authenticated as known peers are treated as feeds, not clients: peer-specific (or exempt) rate limits and subscription caps, eligible for unrestricted full-feed subscriptions. Ordinary client protections (EWMA rate limiting, admission) unchanged for everyone else.
-
Sync via existing primitives. Peers reconcile history with NIP-77 negentropy and stay current with a live subscription. No new wire protocol.
-
On-demand event requests between peers. Beyond the standing feed and periodic reconciliation, a peer may request specific events from another peer at any time — by event ID or by filter — using ordinary REQ or an ad-hoc negentropy session, served under peer limits rather than client limits. This covers what the feed's scope doesn't: fetching a specific event outside the feed's kinds/time range (e.g. completing a thread whose root only the peer holds) and deep backfill — without widening the standing feed. Two constraints: peer request rates and response sizes are still bounded (peer-specific request limits, higher than clients') so a peer credential isn't an egress-abuse vector; and requests are covered by the flat peering terms — never charged per request or per event. Requests and the events they serve are accounted in the admin console alongside feed stats.
-
Lightning settlement for paid peering — automatic, budget-fenced. When the advertised terms carry a fee, the source relay issues a Lightning invoice to the peer for the peering period, using nostream's existing payments processors (the same machinery as admission fees). The peer relay pays automatically on receipt from its configured Lightning wallet — no operator in the loop per invoice — but only inside a strict trust envelope:
- After the peer authenticates (step 2), the source relay presents a BOLT11 invoice for the amount/period from its advertised terms.
- The paying relay auto-pays only if all of these hold: the invoice comes from a configured, trusted peer (pubkey match, step 8); the amount matches the terms that peer advertised in its NIP-11 document; the invoice has not already been paid (dedupe on payment hash); and paying it stays within budget (below).
- Settlement is detected through the existing processor callbacks; on settlement the peer's feed access activates until the end of the paid period.
- Before expiry the source relay offers a renewal invoice; if the period lapses unpaid, the feed is suspended (not the stored data — resuming is a payment, not a re-sync from zero).
-
Periodic budgets as the trust/risk control. Automatic payment is safe only inside an operator-set envelope:
- The operator configures a periodic budget for peering payments — per peer and optionally a global cap across all peers (e.g. X sats per peer per month). Auto-pay never exceeds the remaining budget for the current period.
- An invoice that fails any check in step 5 — over budget, amount mismatch with advertised terms, unknown peer, duplicate — is not auto-paid. It is held and surfaced in the admin console for manual operator approval, so an exceptional invoice becomes a decision, not a silent drain or a silent feed death.
- Peering spend is accounted per peer per period and visible in the admin operations console (invoices received, paid, held, budget remaining), alongside the existing mirror/peer panels.
- Budgets fail closed for money and loud for service: exhausting a budget stops auto-pay and notifies the operator; it never silently borrows from the next period.
-
Configured trust for v1. The peer list remains operator-configured (pubkeys, not just URLs). The NIP-11 advertisement is for discovery and terms expression; automatically accepting unknown peers is out of scope.
Out of scope
- Per-event payments of any kind — paying per novel event makes manufacturing junk events a revenue strategy. Terms are flat (per period), never per event.
- Specifying what terms should be. This standardizes expression and handling, not business rules.
- The NIP itself — that comes after at least two independent operators are peering with this implementation.
Acceptance
- Two nostream instances can establish a peering feed where the only operator-supplied trust material is the peer's pubkey; terms and scopes are read from the peer's NIP-11 document.
- A peer feed no longer trips client rate limits or subscription caps; unauthenticated connections get no peer treatment.
- A paid peering relationship can be completed end-to-end with no operator action: peer authenticates, receives the invoice, the invoice is auto-paid within budget, and the feed activates for the paid period; an unpaid lapse suspends the feed and a later payment resumes it.
- An invoice that is over budget, exceeds the peer's advertised terms, comes from an unconfigured pubkey, or duplicates an already-paid invoice is never auto-paid; it appears in the admin console as a held invoice awaiting operator approval.
- Auto-pay can never exceed the configured periodic budget, per peer or globally, including across renewal invoices inside the same period.
- A relay can fetch a specific out-of-scope event from a peer on demand (by event ID) without changing the feed configuration; peer requests beyond peer request limits are throttled, and serving a request never generates a per-request or per-event charge.
- Peering state (peers, last sync, feed health) is visible in the admin operations console alongside the existing mirror panels.
- Docs cover enabling peering as source and as peer, settlement-free and paid-terms configurations.
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsBacklog
Activity