Do relays need to stay online? The full exploit surface analyzed · content/relay-networks-and-exploits.md
Relay Networks — availability, offline behaviour, and the full exploit surface
Date: 2026-09-15 · Founder's questions: "Do relays have to remain online? What are potential network exploits?"
1. Do relays have to remain online?
No. Relays can go offline at any time. The system degrades gracefully.
What happens when a relay goes offline:
| Scenario |
What happens |
Data loss? |
Recovery |
| Primary relay goes down |
Messages sent TO it are undeliverable (you get a network error) |
❌ no loss — messages weren't delivered |
Your client automatically falls back to the next relay in your --relays list |
| Relay goes down WHILE holding messages |
Those messages are inaccessible until the relay restarts |
❌ no loss — messages are on disk |
Recipient gets them when the relay comes back |
| ALL relays go down |
No message delivery possible |
❌ no loss — senders' messages spool locally |
Anchors queue in the spool; messages retry; offline ferry works |
| Relay disk dies (permanent) |
Messages held by that relay are lost |
⚠️ yes — those specific messages |
Mitigated by: multi-relay send (send to 2+ relays), and the fact that the SENDER still has the plaintext |
The key insight: the sender always keeps the plaintext
Sender encrypts message → sends to relay → relay goes down
↓
Sender STILL HAS the plaintext + the encryption key
They can re-send through any other relay
The message isn't "lost" — it's just "not yet delivered"
This is fundamentally different from email (where a dead SMTP server means bounced mail) or a dead hard drive (where data is gone). The relay is a CACHE, not a source of truth.
The multi-relay architecture (already implemented and tested):
Sender ──┬──► Relay 1 (superlocal :8830) ──┐
├──► Relay 2 (cachyos-x8664 :8840) ──┤──► Recipient polls ALL of them
└──► Relay 3 (compute provider :8851) ──┘ (deduplicates by envelope ID)
- Send to one relay (primary), fallback to others if it fails
- Receive from ALL relays (poll every one, deduplicate)
- If ANY relay is up, messages flow
- If ALL relays are down, messages spool and retry
The offline ferry (the extreme case):
When even multi-relay doesn't work (no internet at all, air-gapped machines):
# On machine A (has the message):
qalchat.py export-env --to bob > /usb/messages.dat
# Carry USB to machine B:
qalchat.py import-env < /usb/messages.dat
# → Machine B now has the encrypted envelopes
# → Decryption happens locally (keys never left the devices)
# → Anchors spool until the chain is reachable
This is tested and working. The relay is a convenience, never a dependency.
Relay uptime SLA (what we actually run):
| Relay |
Location |
Uptime mechanism |
What happens if it dies |
| Relay 1 |
superlocal (our server) |
systemd Restart=on-failure, 5s backoff |
auto-restarts; messages preserved on disk |
| Relay 2 |
cachyos-x8664 (gmktec) |
systemd (same) |
same |
| Chain healer |
timer every 5 min |
probes chain; restarts or regenesis if needed |
chain comes back; anchors flush from spool |
| Fleet monitor |
60s cycle |
Signal alerts on any state change |
we know within 60 seconds |
2. The full exploit surface (honest threat analysis)
Level 1: Network-level attacks
| Attack |
How it works |
Our defence |
Severity if unmitigated |
| Relay flooding (DoS) |
Attacker sends millions of garbage envelopes to fill relay storage/disk |
Rate limiting per IP (configurable); envelope size caps; relay operator can set quotas |
Medium — relay slows/dies, messages queue |
| Bandwidth exhaustion |
Attacker sends huge file chunks continuously |
Chunk size limit (256 KiB); rate limiting; relay can reject oversized payloads |
Medium — relay unavailable for legitimate users |
| Eclipse attack |
Attacker isolates a user from honest relays (network-level blocking) |
Multi-relay architecture (attacker must block ALL relays); offline ferry bypasses entirely; LAN relay works even with no internet |
Low if multi-relay; High if single relay |
| DNS hijack |
Attacker redirects relay hostname to malicious server |
Envelope signatures (ed25519) detect fake envelopes; pinned contacts detect key substitution |
Low — the attack is detected, not just prevented |
| Traffic analysis |
Attacker observes WHO sends to WHOM (metadata) |
Relay sees sender/recipient handles + timestamps; content is encrypted; multiple relays = no single observer; future: mix-net/tor-style routing |
Medium — content is safe but the social graph leaks |
Level 2: Envelope-level attacks
| Attack |
How it works |
Our defence |
Severity |
| Envelope replay |
Attacker captures an envelope and re-sends it |
Hash chain (each envelope references the previous); envelope IDs are unique; recipients deduplicate |
Low — replayed envelopes are silently dropped |
| Envelope forgery |
Attacker crafts a fake envelope claiming to be from someone |
ed25519 signature verification (relay checks; recipient checks); proof-of-possession at registration |
Very low — signature forge requires quantum computer |
| Envelope poisoning |
Attacker sends malformed/corrupted envelopes |
AES-GCM authenticated encryption (corrupted data = decryption failure); sha256 hash verification before reassembly |
Very low — corrupted envelopes rejected before decryption |
| Old-key substitution |
Attacker registers a relay with someone else's old key |
QR invite PINNING (the recipient has the real key pinned); proof-of-possession at registration; key rotation is anchored |
Low if pins used; Medium if TOFU-only (first contact without verification) |
Level 3: Identity-level attacks
| Attack |
How it works |
Our defence |
Severity |
| Identity theft (key compromise) |
Attacker steals a private key |
2-second revocation (anchored DID shows REVOKED); agent caps limit damage; Stronghold encrypts keys at rest; 12-word recovery re-derives keys |
High if undetected; Low if revocation is quick |
| Sybil attack |
Attacker creates thousands of fake identities |
Graduated tiers (verified identity → higher caps); agent caps; reputation system; per-IP rate limiting |
Medium — sybils can't DO much without spending |
| Identity fronting |
Legitimate identity is used as a proxy for a bad actor |
Controller DID (every agent/device has a controller who can revoke); spend caps bound to the identity; all actions receipt-anchored |
Low — the controller is accountable |
Level 4: Chain-level attacks
| Attack |
How it works |
Our defence |
Severity |
| Validator collusion |
Validators collude to rewrite history |
Currently 1-4 validators (private chain = we ARE the validators); Phase 2+ adds external validators; anchoring to public IOTA makes history externally verifiable |
Low now (we're honest); Medium when decentralised |
| Spam anchoring |
Attacker floods the chain with garbage anchors |
Gas costs (sponsored, but rate-limited); anchor size is 32 bytes each; the chain doesn't slow |
Low — spam costs the attacker, chain unaffected |
| Smart contract exploit |
Bug in qal_data/qal_credit/qal_reserve |
Move VM safety (linear types prevent most bug classes); property tests; red-team campaigns (4 criticals found and fixed); audit planned |
Medium before audit; Low after |
| Chain rollback |
Validators rewrite a confirmed checkpoint |
Starfish consensus (BFT with finality — no reorgs once committed); anchoring to public IOTA makes rollback externally visible |
Very low in BFT; zero if anchored |
Level 5: Economic attacks
| Attack |
How it works |
Our defence |
Severity |
| Double-spend attempt |
Try to spend the same QALS twice |
Object model (each Coin object is consumed by the transaction that spends it); UTXO-style linear types |
Impossible — Move VM prevents it |
| Cap bypass attempt |
Try to spend beyond the daily cap |
Chain-enforced (qal_credit bytecode aborts); even if the agent is fully compromised |
Impossible — it's math, not policy |
| Reserve drain |
Try to redeem more than the reserve holds |
Mint invariant (on-chain Reserve refuses to mint beyond deposits); monthly proof-of-reserves |
Impossible — bytecode enforcement |
| Wash trading |
Self-trade to farm reputation |
Reputation only accrues on settled external demand (payer ≠ payee lineage check); volume doesn't equal reputation |
Low — structurally prevented |
The exploit hierarchy summary:
HARDEST TO EXPLOIT (essentially impossible):
├── Double-spend (Move VM prevents it)
├── Cap bypass (bytecode enforcement)
├── Reserve drain (on-chain invariant)
└── Envelope forgery (ed25519 signatures)
HARD TO EXPLOIT (defences in depth):
├── Identity theft (2s revocation + caps + Stronghold)
├── Envelope replay (hash chain + dedup)
└── Key substitution (QR pins + proof-of-possession)
MEDIUM (mitigated but requires vigilance):
├── Relay flooding (rate limits + multi-relay)
├── Traffic analysis (multiple relays, future: mix-net)
├── Sybil attacks (graduated tiers + caps)
└── Eclipse (multi-relay + offline ferry)
ACKNOWLEDGED LIMITATIONS (honest):
├── Relay metadata visibility (who talks to whom)
├── Relay storage exhaustion (48h TTL caps it)
└── Validator concentration (Phase 1: we are the validators)
3. The relay evolution (how attacks get harder over time)
| Phase |
Relays |
Attack surface |
New defences |
| Now |
2-3 relays (our machines) |
We could theoretically read metadata |
We don't; content is encrypted; receipts are public |
| + months |
Compute providers add relay mode |
More relays = harder to eclipse |
Relay reputation on-chain; geographic distribution |
| + year |
Every wallet is a relay |
Thousands of relays |
Eclipse becomes nearly impossible; mix-net possible |
| Future |
Anonymous relay routing |
Tor-style circuits |
Metadata also protected |