OverviewFilesCommitsIssuesDocsReleasesPeers

atproto-bridge / pds / test / blind-relay.test.js

96 lines · javascript ref:
// BlindRelay: a keyless availability seeder keeps an ALLOWLISTED peer frontable while its ORIGIN is
// OFFLINE. Origin announces + serves cores → relay replicates + re-announces on the DID topic →
// origin goes offline → a PeerRouter still fronts the DID (via the relay) and serves a signed CAR
// that verifies against the DID key. Also asserts the relay is BLIND (no apply-write / sign).
import test from 'brittle'
import { mkdtempSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import Hyperswarm from 'hyperswarm'
import createTestnet from '@hyperswarm/testnet'
import c from 'compact-encoding'
import ProtomuxRPC from 'protomux-rpc'
import b4a from 'b4a'
import { openCorestore } from 'atproto-store/lib/corestore.js'
import { RepoStore } from 'atproto-store/lib/repo-store.js'
import { RepoManager } from 'atproto-store/lib/repo-manager.js'
import { FirehoseSequencer } from 'atproto-store/lib/sequencer.js'
import { readCar, loadCommit } from 'atproto-repo/lib/repo.js'
import { verifyCommit } from 'atproto-repo/lib/commit.js'
import { keyFromPrivate } from 'atproto-identity'
import { discoveryTopic } from 'atproto-identity/lib/discovery.js'
import { mkDidRouter } from './mk-did-router.js'
import { BlindRelay } from '../lib/blind-relay.js'
import { pushAnnounce } from './serve-announce.js'

const NOW = '2026-07-03T00:00:00.000Z'
async function waitFor (fn, timeout = 15000) {
  const end = Date.now() + timeout
  while (Date.now() < end) { if (await fn()) return true; await new Promise(r => setTimeout(r, 100)) }
  return false
}

// A minimal serve-membrane-equivalent origin peer (same helper as peer-front.test.js).
async function servePeer (testnet, did, priv) {
  const store = openCorestore(mkdtempSync(join(tmpdir(), 'br-origin-')))
  const repo = await new RepoStore(store, { name: `atproto-repo:${did}` }).ready()
  let micros = 1_700_000_000_000_000n
  const mgr = await new RepoManager(repo, { did, privateKey: priv, clock: () => (micros += 1_000_000n) }).init()
  const seq = await new FirehoseSequencer(store.get({ name: 'firehose' })).ready()
  const w = await mgr.applyWrite({ action: 'create', collection: 'app.bsky.feed.post', rkey: '3a', record: { $type: 'app.bsky.feed.post', text: did, createdAt: NOW } })
  await seq.sequenceCommit(w, { time: NOW })
  const sw = new Hyperswarm({ bootstrap: testnet.bootstrap })
  sw.on('connection', (conn) => {
    store.replicate(conn)
    pushAnnounce(conn, { did, handle: `${did.slice(-6)}.test`, repo, seq })
  })
  await sw.join(discoveryTopic(did), { server: true, client: true }).flushed()
  return { store, repo, seq, sw, close: async () => { await sw.destroy(); await seq.close(); await repo.close(); await store.close() } }
}

function mkRouter (testnet, fronted, keyByDid) {
  const store = openCorestore(mkdtempSync(join(tmpdir(), 'br-bridge-')))
  const swarm = new Hyperswarm({ bootstrap: testnet.bootstrap })
  const router = mkDidRouter(swarm, store, { fronted, resolveVerifyKey: async (did) => keyByDid[did] })
  return { store, swarm, router, close: async () => { await router.close(); await swarm.destroy(); await store.close() } }
}

test('blind relay keeps an allowlisted peer frontable while the ORIGIN is OFFLINE', async (t) => {
  const testnet = await createTestnet(3)
  const DID = 'did:plc:relaymeeeeeeeeeeeeeeeee'
  const PRIV = new Uint8Array(32).fill(5)
  const key = keyFromPrivate(PRIV).publicKey

  // 1. origin peer serving its signed repo + firehose on discoveryTopic(DID)
  const origin = await servePeer(testnet, DID, PRIV)
  const coords = { did: DID, handle: 'relayme.test', repoKey: b4a.toString(origin.repo.core.key, 'hex'), firehoseKey: b4a.toString(origin.seq.core.key, 'hex') }

  // 2. blind relay seeding ONLY this allowlisted peer
  const relayStore = openCorestore(mkdtempSync(join(tmpdir(), 'br-relay-')))
  const relay = await new BlindRelay(relayStore, { seedPeers: [coords], swarmOpts: { bootstrap: testnet.bootstrap } }).ready()

  // 3. the relay FULLY downloads the origin's repo + firehose (contiguous == length, so it can serve
  //    with the origin gone — not just a sparse header replica)
  t.ok(await waitFor(() => { const s = relay.status().peers[0]; return s && s.repoLength > 0 && s.repoContiguous === s.repoLength && s.firehoseLength > 0 && s.firehoseContiguous === s.firehoseLength }), 'relay fully downloaded the origin cores')

  // 4. ORIGIN GOES OFFLINE
  await origin.close()

  // 5. a fresh router fronts the DID — the origin is gone, so it MUST reach the relay
  const b = mkRouter(testnet, [DID], { [DID]: key })
  t.teardown(async () => { await relay.close(); await relayStore.close(); await b.close(); await testnet.destroy() })

  const front = await b.router.front(DID)
  t.is(front.did, DID, 'fronted the peer via the RELAY while the origin is OFFLINE')
  const { carBytes } = await front.getRepo()
  t.ok(verifyCommit(loadCommit(await readCar(carBytes)).value, key), 'relay-served CAR verifies against the DID key — keyless + offline origin')
  const rec = await front.getRecord('app.bsky.feed.post', '3a')
  t.is(rec && rec.value.text, DID, 'the peer record is served via the relay')
})

test('BlindRelay is GATED — refuses a non-allowlisted seed entry (bad shape)', async (t) => {
  const relayStore = openCorestore(mkdtempSync(join(tmpdir(), 'br-gate-')))
  t.teardown(async () => { await relayStore.close() })
  t.exception(() => new BlindRelay(relayStore, { seedPeers: [{ did: 'did:plc:x' }] }), /requires .* repoKey/, 'seed entry without coords is rejected (no blind seeding of arbitrary dids)')
})