OverviewFilesCommitsIssuesDocsReleasesPeers

pear-git-v3 / test / repo-created-entry.test.js

127 lines · javascript ref:
// Regression for the tracker-key split-brain (2026-07-05 hyper-proto-peer).
//
// The "created" RepoEventLog entry conveys a repo's tracker bootstrap key so a
// mirror can mount its issue/refs tracker. It used to be appended first-time-
// only, reading the key from the IssueRegistry at that instant. If the key
// wasn't registered yet at first serve (an ordering race) the entry shipped
// issueBootstrapKey:null PERMANENTLY — a mirror that replicated it bound no
// tracker and forked a split-brain island (its refs froze while the git-pack
// path kept the bare repo looking current).
//
// Fix: maybeAppendCreatedEntry re-emits a KEYED entry on a later serve once the
// key exists. repo-mirror binds on any entry carrying the key (idempotent), so
// the mirror converges. These tests drive the real emission logic against a
// real RepoEventLog, and prove the re-emitted keyed entry replicates to a
// mirror log.

import test from 'brittle'
import { mkdtempSync } from '#node:fs'
import { join } from '#node:path'
import { tmpdir } from '#node:os'
import Corestore from 'corestore'

import { RepoEventLog } from '../lib/services/repo-event-log.js'
import { maybeAppendCreatedEntry } from '../lib/services/repo-created-entry.js'

function tmpStorage () { return mkdtempSync(join(tmpdir(), 'pgv3-repo-created-')) }

// Controllable IssueRegistry stand-in: keys().repos returns whatever we set.
function fakeIssueRegistry (repos = {}) {
  return {
    _repos: { ...repos },
    async keys () { return { repos: this._repos } },
    setKey (name, hex) { this._repos[name] = hex }
  }
}
const fakeSync = { info: (name) => ({ head: 'head-' + name }) }

async function readAll (log) {
  const out = []
  for await (const e of log.entries({ live: false, start: 0 })) out.push(e)
  return out
}
const hexOf = (buf) => (buf ? buf.toString('hex') : null)

test('created entry: key ready at first serve → one keyed entry, idempotent after', async (t) => {
  const store = new Corestore(tmpStorage()); await store.ready()
  const log = new RepoEventLog({ corestore: store }); await log.ready()
  t.teardown(async () => { await log.close(); await store.close() })

  const keyHex = 'ab'.repeat(32)
  const reg = fakeIssueRegistry({ foo: keyHex })
  const logged = new Set(); const keyed = new Set()

  const r1 = await maybeAppendCreatedEntry({ name: 'foo', syncServer: fakeSync, issueRegistry: reg, repoEventLog: log, loggedNames: logged, keyedNames: keyed })
  t.alike(r1, { appended: true, keyed: true }, 'first serve appends a keyed entry')

  await maybeAppendCreatedEntry({ name: 'foo', syncServer: fakeSync, issueRegistry: reg, repoEventLog: log, loggedNames: logged, keyedNames: keyed })
  const entries = await readAll(log)
  t.is(entries.length, 1, 'no duplicate append once keyed')
  t.is(hexOf(entries[0].issueBootstrapKey), keyHex, 'entry carries the tracker key')
})

test('created entry: null at first serve, key lands later → re-emits keyed entry (the fix)', async (t) => {
  const store = new Corestore(tmpStorage()); await store.ready()
  const log = new RepoEventLog({ corestore: store }); await log.ready()
  t.teardown(async () => { await log.close(); await store.close() })

  const keyHex = 'cd'.repeat(32)
  const reg = fakeIssueRegistry({}) // tracker key NOT registered yet
  const logged = new Set(); const keyed = new Set()

  const r1 = await maybeAppendCreatedEntry({ name: 'ppp', syncServer: fakeSync, issueRegistry: reg, repoEventLog: log, loggedNames: logged, keyedNames: keyed })
  t.alike(r1, { appended: true, keyed: false }, 'first serve appends a NULL-key entry (the race)')
  t.is((await readAll(log))[0].issueBootstrapKey, null, 'first entry has no key — the split-brain trigger')

  const r2 = await maybeAppendCreatedEntry({ name: 'ppp', syncServer: fakeSync, issueRegistry: reg, repoEventLog: log, loggedNames: logged, keyedNames: keyed })
  t.is(r2.appended, false, 'no re-emit while the key is still absent')
  t.is((await readAll(log)).length, 1, 'still just the one null entry')

  reg.setKey('ppp', keyHex) // tracker key now registered
  const r3 = await maybeAppendCreatedEntry({ name: 'ppp', syncServer: fakeSync, issueRegistry: reg, repoEventLog: log, loggedNames: logged, keyedNames: keyed })
  t.alike(r3, { appended: true, keyed: true }, 'key landed → re-emits a keyed entry')

  const entries = await readAll(log)
  t.is(entries.length, 2, 'log now holds the null entry + the keyed re-emit')
  t.is(hexOf(entries[1].issueBootstrapKey), keyHex, 're-emitted entry carries the real tracker key')

  const r4 = await maybeAppendCreatedEntry({ name: 'ppp', syncServer: fakeSync, issueRegistry: reg, repoEventLog: log, loggedNames: logged, keyedNames: keyed })
  t.is(r4.appended, false, 'no further appends after keyed')
  t.is((await readAll(log)).length, 2, 'log unchanged')
})

test('the re-emitted keyed entry replicates to a mirror log (what repo-mirror binds on)', async (t) => {
  const pStore = new Corestore(tmpStorage()); await pStore.ready()
  const primary = new RepoEventLog({ corestore: pStore }); await primary.ready()

  const keyHex = 'ef'.repeat(32)
  const reg = fakeIssueRegistry({})
  const logged = new Set(); const keyed = new Set()
  // Reproduce the race: null first entry, then keyed re-emit once the key lands.
  await maybeAppendCreatedEntry({ name: 'zzz', syncServer: fakeSync, issueRegistry: reg, repoEventLog: primary, loggedNames: logged, keyedNames: keyed })
  reg.setKey('zzz', keyHex)
  await maybeAppendCreatedEntry({ name: 'zzz', syncServer: fakeSync, issueRegistry: reg, repoEventLog: primary, loggedNames: logged, keyedNames: keyed })

  // Mirror opens the SAME log by key on a second corestore; replicate in-process.
  const mStore = new Corestore(tmpStorage()); await mStore.ready()
  const mirror = new RepoEventLog({ corestore: mStore, key: primary.keyHex }); await mirror.ready()
  const s1 = primary.core.replicate(true)
  const s2 = mirror.core.replicate(false)
  s1.pipe(s2).pipe(s1)
  t.teardown(async () => {
    try { s1.destroy() } catch {}; try { s2.destroy() } catch {}
    await mirror.close(); await mStore.close(); await primary.close(); await pStore.close()
  })

  for (let i = 0; i < 60 && mirror.length < 2; i++) {
    try { await mirror.core.update() } catch {}
    await new Promise((r) => setTimeout(r, 50))
  }

  const mirrorEntries = []
  for await (const e of mirror.entries({ live: false, start: 0 })) mirrorEntries.push(e)
  const keyedOnMirror = mirrorEntries.find((e) => hexOf(e.issueBootstrapKey) === keyHex)
  t.ok(keyedOnMirror, 'mirror replicated the re-emitted keyed entry — tracker key conveyed, no split-brain')
  t.is(keyedOnMirror && keyedOnMirror.name, 'zzz', 'keyed entry is for the right repo')
})