'use strict' // Narrow diagnostic: validates the installed Hyperswarm/HyperDHT package and // the local bootstrap node independently of Cabal's Hypercore replication. const assert = require('assert') const crypto = require('crypto') const dgram = require('dgram') const { loadCabalCore } = require('./cable_hyperswarm') const { requireCabal } = loadCabalCore() const DHT = requireCabal('hyperdht') const Swarm = requireCabal('hyperswarm') function freePort () { return new Promise((resolve, reject) => { const socket = dgram.createSocket('udp4') socket.once('error', reject) socket.bind(0, '127.0.0.1', () => { const port = socket.address().port socket.close(err => err ? reject(err) : resolve(port)) }) }) } async function main () { const portA = await freePort() const portB = await freePort() const relayPort = await freePort() const useBuiltin = process.env.HYPERSWARM_TEST_BUILTIN === '1' const bootstrapPort = useBuiltin ? 0 : await freePort() const bootstrap = useBuiltin ? null : DHT.bootstrapper(bootstrapPort, '127.0.0.1', { host: '127.0.0.1' }) const relay = useBuiltin ? null : new DHT({ bootstrap: ['127.0.0.1:' + bootstrapPort], host: '127.0.0.1', port: relayPort, ephemeral: false, firewalled: false }) const swarms = [] try { if (bootstrap) await bootstrap.ready() if (relay) await relay.ready() if (bootstrap) console.log('bootstrap state', { id: Boolean(bootstrap.id), ephemeral: bootstrap.ephemeral, storage: Boolean(bootstrap._persistent) }) if (relay) console.log('relay state', { id: Boolean(relay.id), ephemeral: relay.ephemeral, storage: Boolean(relay._persistent) }) const endpoint = useBuiltin ? undefined : '127.0.0.1:' + relayPort for (const port of [portA, portB]) { const dht = new DHT({ ...(useBuiltin ? {} : { bootstrap: [endpoint] }), host: '127.0.0.1', port, ephemeral: false, firewalled: false }) dht._nat.add('127.0.0.1', port) const swarm = new Swarm({ dht }) dht.on('error', err => console.error('DHT error:', err.message)) swarm.on('error', err => console.error('swarm error:', err.message)) swarms.push(swarm) } const [a, b] = swarms const topic = crypto.randomBytes(32) let connected = 0 const onConnection = socket => { connected++; socket.on('error', () => {}) } a.on('connection', onConnection) b.on('connection', onConnection) const onDiscoveryError = (label) => err => console.error(label + ' discovery error:', err && (err.stack || err)) const discoveryA = a.join(topic, { server: true, client: false, onerror: onDiscoveryError('A') }) const aFlushed = await discoveryA.flushed() const discoveryB = b.join(topic, { server: false, client: true, onerror: onDiscoveryError('B') }) const bFlushed = await discoveryB.flushed() console.log('Hyperswarm discovery flush:', aFlushed + '/' + bFlushed) console.log('DHT node tables:', { a: a.dht.toArray(), b: b.dht.toArray(), relay: relay && relay.table.toArray().map(node => ({ host: node.host, port: node.port })) }) if (relay) console.log('relay stored topic peers:', relay._persistent.records.get(topic.toString('hex'), 20).length) const lookup = b.dht.lookup(topic) const lookupResults = [] lookup.on('data', result => lookupResults.push(result.peers.length)) await lookup.finished() console.log('explicit topic lookup peer counts:', lookupResults) const deadline = Date.now() + 20000 while (connected < 2 && Date.now() < deadline) await new Promise(resolve => setTimeout(resolve, 100)) const discovered = connected >= 2 console.log('Hyperswarm state:', { connections: [a.connections.size, b.connections.size], queued: [a.connecting, b.connecting], peerEntries: [a.peers.size, b.peers.size] }) if (!discovered) { console.log('DHT discovery did not connect both local nodes; trying direct Hyperswarm peers to isolate transport') a.joinPeer(b.keyPair.publicKey) b.joinPeer(a.keyPair.publicKey) const directDeadline = Date.now() + 10000 while (connected < 2 && Date.now() < directDeadline) await new Promise(resolve => setTimeout(resolve, 100)) } assert(connected >= 2, 'local Hyperswarm peers failed direct transport too') console.log('local Hyperswarm transport: PASS') if (!discovered) { console.error('local DHT discovery: FAIL (the bootstrap node did not yield peer addresses)') process.exitCode = 1 } else console.log('local Hyperswarm DHT discovery: PASS') } finally { for (const swarm of swarms) { try { await swarm.destroy() } catch (_) {} } if (relay) { try { await relay.destroy() } catch (_) {} } if (bootstrap) { try { await bootstrap.destroy() } catch (_) {} } } } main().catch(err => { console.error(err.stack || err); process.exitCode = 1 })