OverviewFilesCommitsIssuesDocsReleasesPeers

keet-daemon / test / probe-state-v3-admit-dedup.mjs

77 lines · javascript ref:
// Proves the admit-dedup guard: a member attaches its `admit` proof to EVERY
// optimistic write, so apply used to re-run addWriter/ackWriter (+log) once per
// op. The _admitted Set must collapse that to ONE addWriter per writer, while
// still rejecting an unverified proof (no admission, no set application).
import { StateBaseV3 } from '../lib/state-base-v3.js'
import crypto from 'hypercore-crypto'
import b4a from 'b4a'
import fs from 'bare-fs'
import path from 'bare-path'
import os from 'bare-os'

const ROOT = path.join(os.tmpdir(), 'sbv3-admit-dedup-' + Bare.pid)
try { fs.rmSync(ROOT, { recursive: true, force: true }) } catch {}
const roomKey = crypto.randomBytes(32)
const roomSeed = crypto.randomBytes(32)
const kpA = crypto.keyPair() // admin → elected creator
const kpB = crypto.keyPair() // peer member (admitted optimistically)
const kpC = crypto.keyPair() // outsider (NOT a member → rejected, never admitted)
const hex = (b) => b4a.toString(b, 'hex')
const members = [
  { key: hex(kpA.publicKey), role: 1 },
  { key: hex(kpB.publicKey), role: 3 }
]
const baseOpts = (kp) => ({ roomSeed, encryptionKey: roomSeed, network: false, selfKeyPair: kp, selfKey: kp.publicKey, getMembers: async () => members })

let pass = 0; let fail = 0
const ok = (c, m) => { if (c) { pass++; console.log('  ok  ' + m) } else { fail++; console.log('  FAIL ' + m) } }

async function main () {
  const A = new StateBaseV3(path.join(ROOT, 'A'), roomKey, baseOpts(kpA))
  await A.ready()
  ok(A.writable, 'A (admin) elected creator → writable')
  await A.projectMembers(members)

  const B = new StateBaseV3(path.join(ROOT, 'B'), roomKey, baseOpts(kpB))
  await B.ready()
  const admitB = await B._buildAdmissionProof()
  ok(!!admitB, 'B built an admission proof')

  // Counting stub for the autobase writer ops; tx = A's view (has __members__).
  let addWriterCalls = 0; let ackCalls = 0
  const ctx = {
    node: { from: { key: B.base.local.key } },
    tx: A.base.view,
    base: {
      addWriter: async () => { addWriterCalls++ },
      ackWriter: async () => { ackCalls++ }
    }
  }
  // rec has no `key` → admit block runs, then _applySet returns before the data
  // insert (keeps the test focused on admission, no writable-tx needed).
  const recB = { admit: admitB }

  // Simulate the peer's repeated admit-carrying ops.
  for (let i = 0; i < 5; i++) await A._applySet(recB, ctx)

  ok(addWriterCalls === 1, '1. addWriter called EXACTLY once across 5 admit ops (got ' + addWriterCalls + ')')
  ok(ackCalls === 1, '2. ackWriter called EXACTLY once (got ' + ackCalls + ')')
  ok(A._admitted.has(hex(B.base.local.key)), '3. B recorded in _admitted set')

  // Outsider C: valid sig but NOT a member → role null → never admitted, set never applied.
  const cLocal = crypto.randomBytes(32)
  const sigC = crypto.sign(b4a.concat([cLocal, A.base.key]), kpC.secretKey)
  const admitC = JSON.stringify({ identity: hex(kpC.publicKey), proof: hex(sigC) })
  const ctxC = { node: { from: { key: cLocal } }, tx: A.base.view, base: ctx.base }
  const before = addWriterCalls
  await A._applySet({ admit: admitC }, ctxC)
  ok(addWriterCalls === before, '4. outsider C did NOT trigger addWriter (still ' + addWriterCalls + ')')
  ok(!A._admitted.has(hex(cLocal)), '5. outsider C NOT recorded in _admitted (rejected)')

  await A.close(); await B.close()
  try { fs.rmSync(ROOT, { recursive: true, force: true }) } catch {}
  console.log('\n[probe] pass=' + pass + ' fail=' + fail)
  Bare.exit(fail ? 1 : 0)
}
main().catch((e) => { console.error('[probe] THREW:', e && e.stack ? e.stack : e); Bare.exit(2) })