OverviewFilesCommitsIssuesDocsReleasesPeers

atproto-base / test / firehose.test.mjs

62 lines · javascript ref:
// FIREHOSE — consecutive finalized heads become atproto #commit frames (the DIFF: ops + minimal
// proof blocks + prevData), byte-exact via atproto-store's codec (what the bridge consumes), and
// DETERMINISTIC across co-owners. Covers create/update/delete and a genesis.

import test from 'brittle'
import { deriveAtprotoKey, createAtprotoIdentity } from 'atproto-identity'
import { readCar } from 'atproto-repo/lib/car.js'
import { commitFrame, decodeCommitFrame } from 'atproto-store/lib/firehose.js'
import { buildCommitWrite } from '../lib/firehose.js'
import { nextRev } from '../lib/rev.js'

const MNEMONIC = 'test test test test test test test test test test test junk'
const ID = createAtprotoIdentity(MNEMONIC, { handle: 'x.7rnx.net', pdsUrl: 'https://pds.7rnx.net' })
const KEY = deriveAtprotoKey(MNEMONIC)
const rec = (t) => ({ $type: 'app.bsky.feed.post', text: t, createdAt: '2026-07-23T00:00:00.000Z', langs: ['en'] })
const R = (k, v) => ({ key: 'app.bsky.feed.post/' + k, value: rec(v) })
const opFor = (w, path) => w.ops.find((o) => o.path === path)

test('firehose #commit: create/update/delete diffs, decodable frames, deterministic', async (t) => {
  const did = ID.did; const pk = KEY.privateKey

  // genesis: create 3a
  const rev1 = nextRev(null)
  const w1 = await buildCommitWrite({ oldRecords: [], newRecords: [R('3a', 'one')], did, rev: rev1, prev: null, privateKey: pk })
  t.is(w1.ops.length, 1); t.is(opFor(w1, 'app.bsky.feed.post/3a').action, 'create')

  // add 3b
  const rev2 = nextRev(rev1)
  const w2 = await buildCommitWrite({ oldRecords: [R('3a', 'one')], newRecords: [R('3a', 'one'), R('3b', 'two')], did, rev: rev2, since: rev1, prev: w1.commitCid, privateKey: pk })
  t.is(opFor(w2, 'app.bsky.feed.post/3b').action, 'create')
  t.absent(opFor(w2, 'app.bsky.feed.post/3a'), 'unchanged record produces no op')

  // update 3a
  const rev3 = nextRev(rev2)
  const w3 = await buildCommitWrite({ oldRecords: [R('3a', 'one'), R('3b', 'two')], newRecords: [R('3a', 'one-edited'), R('3b', 'two')], did, rev: rev3, since: rev2, prev: w2.commitCid, privateKey: pk })
  const up = opFor(w3, 'app.bsky.feed.post/3a')
  t.is(up.action, 'update'); t.ok(up.prev, 'update carries prev CID for inductive proof')

  // delete 3b
  const rev4 = nextRev(rev3)
  const w4 = await buildCommitWrite({ oldRecords: [R('3a', 'one-edited'), R('3b', 'two')], newRecords: [R('3a', 'one-edited')], did, rev: rev4, since: rev3, prev: w3.commitCid, privateKey: pk })
  const del = opFor(w4, 'app.bsky.feed.post/3b')
  t.is(del.action, 'delete'); t.ok(del.prev, 'delete carries prev CID for exclusion proof')

  // frame + decode round-trip
  const frame = await commitFrame(w2, { seq: 2, time: '2026-07-23T00:00:00.000Z' })
  const dec = decodeCommitFrame(frame)
  t.is(dec.header.t, '#commit', 'decodes as #commit')
  t.is(dec.body.commit.toString(), w2.commitCid.toString(), 'frame commit CID matches')
  t.is(dec.body.rev, rev2, 'frame rev matches')
  t.is(dec.body.repo, did, 'frame repo = did')
  t.is(dec.body.ops.length, 1, 'frame carries the diff ops')
  const car = await readCar(dec.body.blocks)
  t.is(car.roots[0].toString(), w2.commitCid.toString(), 'frame CAR root = the commit')
  t.ok(car.blocks.has(opFor(w2, 'app.bsky.feed.post/3b').cid.toString()), 'the new record block travels in the frame')

  // DETERMINISM: a co-owner rebuilding the same transition gets the identical commit + ops.
  const w2b = await buildCommitWrite({ oldRecords: [R('3a', 'one')], newRecords: [R('3a', 'one'), R('3b', 'two')], did, rev: rev2, since: rev1, prev: w1.commitCid, privateKey: pk })
  t.is(w2.commitCid.toString(), w2b.commitCid.toString(), 'firehose commit deterministic across co-owners')
  t.is(Buffer.compare(Buffer.from(w2.signedCommit.sig), Buffer.from(w2b.signedCommit.sig)), 0, 'identical signature')
})