OverviewFilesCommitsIssuesDocsReleasesPeers

pear-git-v3 / test / per-room-swarm-join.test.js

82 lines · javascript ref:
// Per-room swarm.join layer (Keet activateRoom — issue #34/#37).
//
// Each org/repo is its own autobase ("room"); a peer rendezvous for a
// SPECIFIC room by joining that room's discoveryKey on the shared swarm,
// NOT the owner's daemon identity topic. This test forces the two
// daemons onto DIFFERENT identity topics (distinct raw identities), so
// the ONLY way the peer can reach the owner is via the per-room topic.
// Proves: (1) per-room rendezvous works across daemons that share no
// daemon topic; (2) peer-mode scope is isolated — a room never joined is
// unreachable.

import test from 'brittle'
import process from '#node:process'
import { mkdtempSync } from '#node:fs'
import { join } from '#node:path'
import { tmpdir } from '#node:os'
import b4a from 'b4a'
import createTestnet from '@hyperswarm/testnet'

import { startPearGit } from '../index.js'

let n = 0
const tmpStorage = () => mkdtempSync(join(tmpdir(), 'pgv3-prsj-' + (n++) + '-'))
const tmpSock = () => join(mkdtempSync(join(tmpdir(), 'pgv3-prsj-sock-' + (n++) + '-')), 'svc.sock')
async function waitFor (pred, ms = 12000) {
  const t0 = Date.now()
  while (Date.now() - t0 < ms) {
    try { if (await pred()) return true } catch {}
    await new Promise((r) => setTimeout(r, 50))
  }
  return false
}

test('per-room swarm.join: peer rendezvous via the ORG topic only (different daemon topics, no leak)', async (t) => {
  // Each daemon gets its OWN raw identity → its OWN daemon topic.
  process.env.PGV3_USE_RAW_IDENTITY = '1'
  const testnet = await createTestnet(3, t.teardown)

  const nodeA = await startPearGit({
    storage: tmpStorage(), uds: tmpSock(), http: { port: 0 },
    swarm: { swarm: { bootstrap: testnet.bootstrap } }, deploy: false, sync: false
  })
  t.teardown(async () => { try { await nodeA.close() } catch {} })
  const nodeB = await startPearGit({
    storage: tmpStorage(), uds: tmpSock(), http: { port: 0 },
    swarm: { swarm: { bootstrap: testnet.bootstrap } }, deploy: false, sync: false
  })
  t.teardown(async () => { try { await nodeB.close() } catch {} })

  // Sanity: the daemons are NOT on a shared identity topic. Without the
  // per-room join, the peer could never find the owner.
  t.not(
    b4a.toString(nodeA.svc.swarm.topic, 'hex'),
    b4a.toString(nodeB.svc.swarm.topic, 'hex'),
    'daemons are on DIFFERENT identity topics'
  )

  // A owns alpha + beta; announce each room on the shared swarm.
  await nodeA.orgs.create('alpha', 'group', { displayName: 'Alpha' })
  await nodeA.orgs.create('beta', 'group', { displayName: 'Beta' })
  nodeA.svc.activateRoom(nodeA.orgs.getOrgRoom('alpha').discoveryKey)
  nodeA.svc.activateRoom(nodeA.orgs.getOrgRoom('beta').discoveryKey)
  const { invitation } = await nodeA.orgs.createOrgInvite('alpha', { role: 'reader', swarm: nodeA.svc.swarm.swarm })

  // B pairs into ONLY alpha over the swarm: mount it + join alpha's room topic.
  const joined = await nodeB.orgs.joinOrg(invitation, { swarm: nodeB.svc.swarm.swarm })
  t.is(joined.name, 'alpha', 'peer joined alpha')
  nodeB.svc.activateRoom(nodeB.orgs.getOrgRoom('alpha').discoveryKey)

  // B replicates alpha purely via the per-room rendezvous.
  const sawAlpha = await waitFor(async () => {
    await nodeB.orgs.sync()
    const o = await nodeB.orgs.get('alpha')
    return !!(o && o.displayName === 'Alpha')
  })
  t.ok(sawAlpha, 'peer replicated alpha via the org room topic (no shared daemon topic)')

  // Isolation: B never joined/mounted beta → structurally unreachable.
  t.absent(await nodeB.orgs.get('beta'), 'beta not visible (never joined its room topic)')
  t.alike(nodeB.orgs.listOrgKeys().map((o) => o.name), ['alpha'], 'peer tracks only alpha')
})