OverviewFilesCommitsIssuesDocsReleasesPeers

hypercompute / lib / transport.js

47 lines · javascript ref:
// lib/transport.js — the two communication planes (SPEC §2, §3). SCAFFOLD (P1).
//
//   DURABLE  : replicate the pool Autobase over each hyperswarm connection.
//   HOT PATH : unordered datagrams (conn.trySend / 'message') for ephemeral
//              task-available / claiming / result-ready signals. No HOL, no ack.
//
// HOT-PATH GATE: drop any connection whose remotePublicKey is not in member/*.
//
// ⚠️ OPEN (SPEC §10): verify hyperswarm `connection` forwards trySend()/'message'
// to secret-stream's unordered path un-wrapped. If not, drop to a dedicated
// secret-stream or the raw udx stream. Test before relying on it.

const { isMember } = require('./membership')

function startTransport (swarm, node, { gate = true } = {}) {
  swarm.join(node.base.discoveryKey, { server: true, client: true })
  node.peers = new Set()

  swarm.on('connection', async (conn) => {
    // 1) replicate the durable plane
    node.store.replicate(conn)

    // 2) hot-path membership gate
    if (gate && !(await isMember(node.base, conn.remotePublicKey))) {
      // conn.destroy(); return   // enable once enrollment is the only join path
    }

    // 3) DATA PLANE: unordered datagrams (the latency win) — see OPEN note above
    conn.on('message', (buf) => {
      try { node.onDatagram && node.onDatagram(conn, JSON.parse(buf.toString())) } catch {}
    })

    node.peers.add(conn)
    conn.on('close', () => node.peers.delete(conn))
  })
}

// fire-and-forget datagram to all connected peers (the hot path)
function broadcast (node, dgram) {
  const buf = Buffer.from(JSON.stringify(dgram))
  for (const conn of node.peers || []) {
    if (typeof conn.trySend === 'function') conn.trySend(buf)
  }
}

module.exports = { startTransport, broadcast }