UNPKG

zeronet-swarm

Version:
127 lines (107 loc) 3.4 kB
'use strict' // basics const Libp2p = require('libp2p') const series = require('async/series') const LProtocol = require('zeronet-protocol').Lp2p const debug = require('debug') const log = debug('zeronet:swarm:libp2p') // multiformats const PeerInfo = require('peer-info') const multiaddr = require('multiaddr') // libp2p connection const SPDY = require('libp2p-spdy') const MPLEX = require('libp2p-mplex') const SECIO = require('libp2p-secio') // websocket-star const WebsocketStarMulti = require('libp2p-websocket-star-multi') // discovery const Railing = require('libp2p-railing') const MulticastDNS = require('libp2p-mdns') // dht const DHT = require('libp2p-kad-dht') function Libp2pSwarm (opt, protocol, zeronet) { const self = this log('creating libp2p swarm') const peerInfo = new PeerInfo(opt.id) self.idB58 = opt.id.toB58String() let listen = opt.listen || [] listen.forEach(addr => peerInfo.multiaddrs.add(multiaddr(addr))) self.adv = [] let dht let discovery = [] let transport = opt.transports || [] if (opt.bootstrap && opt.bootstrap.length) { discovery.push(new Railing(opt.bootstrap)) log('enabled bootstrap with %s peer(s)', opt.bootstrap.length) } if (opt.mdns) { discovery.push(new MulticastDNS(peerInfo, 'zeronet')) log('enabled multicast-dns') } if (opt.dht) dht = DHT if (opt.custom_dht) dht = opt.custom_dht if (dht) log('enabled dht') if (opt.wstar) { // wstar is an array with servers for wstar multi const wsm = new WebsocketStarMulti({ servers: opt.wstar, ignore_no_online: opt.wstar_ignore, id: opt.id }) peerInfo.multiaddrs.add(multiaddr('/p2p-websocket-star')) transport.push(wsm) discovery.push(wsm.discovery) log('enabled websocket-star-multi with %s server(s) (ignore if unreachable %s)', opt.wstar.length, opt.wstar_ignore || false) } const modules = { transport, connection: { muxer: [ MPLEX, SPDY ], crypto: [SECIO] }, discovery: (opt.discover || []).concat(discovery), dht } const options = { /* relay: { enabled: true, hop: { enabled: true, active: false // passive relay } } */ } const lp2p = self.lp2p = self.libp2p = new Libp2p(modules, peerInfo, /* peerBook */ null, options) const swarm = lp2p swarm.on('peer:discovery', pi => { if (pi.id.toB58String() === peerInfo.id.toB58String()) return const next = () => swarm.dial(pi, () => {}) if (swarm.isStarted()) next() else swarm.once('start', () => process.nextTick(next)) }) swarm.on('peer:connect', peer => { if (peer.id.toB58String() === peerInfo.id.toB58String()) return const npeer = zeronet.peerPool.add(peer) if (!npeer) return const next = () => npeer.dial(() => {}) if (swarm.isStarted()) next() else swarm.once('start', () => process.nextTick(next)) }) self.start = cb => series([ cb => lp2p.start(cb), cb => { self.adv = [] peerInfo.multiaddrs.forEach(ma => self.adv.push(ma.toString())) cb() } ], cb) self.stop = cb => { delete lp2p.switch.muxedConns[''] lp2p.stop(cb) } self.dial = (peer, proto, cb) => typeof proto === 'function' ? lp2p.dial(peer, cb) : lp2p.dialProtocol(peer, proto, cb) self.proto = self.protocol = new LProtocol({}, self) } module.exports = Libp2pSwarm