OverviewFilesCommitsIssuesDocsReleasesPeers

keet-daemon / test / probe-shared-metabase.js

88 lines · javascript ref:
// Probe: do TWO MetadataBase instances with the SAME deterministic
// bootstrap key (derived from a roomId) actually share state via
// Hyperswarm replication?
//
// Spins up two independent Corestores in /tmp, opens a MetadataBase
// in each with roomId set, has peer A write a field, polls peer B
// until they see it.
//
// Run: bare test/probe-shared-metabase.js
//
// PASS criteria: peer B's view contains the field A wrote, within 30s.
// FAIL means the deterministic-bootstrap mechanism alone isn't enough
// and we need explicit writer-add ops.

import fs from 'bare-fs'
import path from 'bare-path'
import os from 'bare-os'
import { MetadataBase, deriveRoomBootstrapKey } from '../lib/metadata-base.js'

const ROOM = 'probe-room-' + Math.random().toString(36).slice(2, 10)
const DEADLINE_MS = 30000

const dirA = path.join(os.tmpdir(), 'probe-meta-A-' + Date.now())
const dirB = path.join(os.tmpdir(), 'probe-meta-B-' + Date.now())
fs.mkdirSync(dirA, { recursive: true })
fs.mkdirSync(dirB, { recursive: true })

console.log('roomId:', ROOM)
console.log('bootstrap:', deriveRoomBootstrapKey(ROOM).toString('hex'))
console.log('dirA:', dirA)
console.log('dirB:', dirB)

const mbA = new MetadataBase(dirA, { roomId: ROOM })
const mbB = new MetadataBase(dirB, { roomId: ROOM })

let exitCode = 1

try {
  console.log('\n[A] opening...')
  await mbA.ready()
  console.log('[A] base.key:', mbA.base.key.toString('hex').slice(0, 16) + '…')
  console.log('[A] base.discoveryKey:', mbA.base.discoveryKey.toString('hex').slice(0, 16) + '…')

  console.log('\n[B] opening...')
  await mbB.ready()
  console.log('[B] base.key:', mbB.base.key.toString('hex').slice(0, 16) + '…')
  console.log('[B] base.discoveryKey:', mbB.base.discoveryKey.toString('hex').slice(0, 16) + '…')

  const keysMatch = mbA.base.key.equals(mbB.base.key)
  console.log('\nkeys match across peers?', keysMatch)
  const dkeysMatch = mbA.base.discoveryKey.equals(mbB.base.discoveryKey)
  console.log('discovery keys match?', dkeysMatch)
  if (!keysMatch || !dkeysMatch) {
    console.log('FAIL — peers opened different autobases despite deterministic bootstrap')
    process.exit(1)
  }

  console.log('\n[A] writing room field with id =', ROOM)
  await mbA.set(ROOM, { test_field: 'hello from A', ts: Date.now() })
  console.log('[A] write OK; A view:', JSON.stringify(await mbA.get(ROOM)))

  console.log('\n[B] polling until field appears (deadline ' + (DEADLINE_MS / 1000) + 's)...')
  const t0 = Date.now()
  while (Date.now() - t0 < DEADLINE_MS) {
    const v = await mbB.get(ROOM)
    if (v && v.test_field === 'hello from A') {
      console.log('[B] saw the write at +' + ((Date.now() - t0) / 1000).toFixed(1) + 's: ' + JSON.stringify(v))
      console.log('\nPASS — peers converged on shared state via deterministic bootstrap.')
      exitCode = 0
      break
    }
    await new Promise(r => setTimeout(r, 500))
  }
  if (exitCode !== 0) {
    console.log('FAIL — B never saw A\'s write within ' + (DEADLINE_MS / 1000) + 's.')
    console.log('[B] final view:', JSON.stringify(await mbB.get(ROOM)))
  }
} catch (err) {
  console.error('error:', err.message)
  console.error(err.stack)
} finally {
  try { await mbA._closing || mbA.close?.() } catch {}
  try { await mbB._closing || mbB.close?.() } catch {}
  fs.rmSync(dirA, { recursive: true, force: true })
  fs.rmSync(dirB, { recursive: true, force: true })
  process.exit(exitCode)
}