2016-03-23 15:30:14 +01:00
|
|
|
'use strict'
|
|
|
|
|
2019-11-15 16:48:32 +01:00
|
|
|
const { EventEmitter } = require('events')
|
2018-10-19 17:37:34 +02:00
|
|
|
const debug = require('debug')
|
|
|
|
const log = debug('libp2p')
|
|
|
|
log.error = debug('libp2p:error')
|
2017-04-06 15:45:23 -04:00
|
|
|
|
2019-06-06 12:21:31 +02:00
|
|
|
const PeerInfo = require('peer-info')
|
2019-10-21 16:53:58 +02:00
|
|
|
const multiaddr = require('multiaddr')
|
2018-02-07 07:48:37 +00:00
|
|
|
|
|
|
|
const peerRouting = require('./peer-routing')
|
|
|
|
const contentRouting = require('./content-routing')
|
|
|
|
const dht = require('./dht')
|
2018-02-14 11:30:36 +01:00
|
|
|
const pubsub = require('./pubsub')
|
2019-10-21 16:53:58 +02:00
|
|
|
const { getPeerInfo, getPeerInfoRemote } = require('./get-peer-info')
|
|
|
|
const { validate: validateConfig } = require('./config')
|
2019-04-16 12:05:22 +02:00
|
|
|
const { codes } = require('./errors')
|
2015-09-27 00:14:40 +01:00
|
|
|
|
2019-10-21 16:53:58 +02:00
|
|
|
const Dialer = require('./dialer')
|
2019-10-02 13:31:28 +02:00
|
|
|
const TransportManager = require('./transport-manager')
|
2019-10-21 16:53:58 +02:00
|
|
|
const Upgrader = require('./upgrader')
|
2019-11-06 15:11:13 +01:00
|
|
|
const PeerStore = require('./peer-store')
|
2019-11-06 15:47:11 +01:00
|
|
|
const Registrar = require('./registrar')
|
2019-11-07 12:11:50 +01:00
|
|
|
const {
|
|
|
|
IdentifyService,
|
|
|
|
multicodecs: IDENTIFY_PROTOCOLS
|
|
|
|
} = require('./identify')
|
2019-10-02 13:31:28 +02:00
|
|
|
|
2018-10-19 17:37:34 +02:00
|
|
|
/**
|
2019-06-06 12:21:31 +02:00
|
|
|
* @fires Libp2p#error Emitted when an error occurs
|
|
|
|
* @fires Libp2p#peer:connect Emitted when a peer is connected to this node
|
|
|
|
* @fires Libp2p#peer:disconnect Emitted when a peer disconnects from this node
|
|
|
|
* @fires Libp2p#peer:discovery Emitted when a peer is discovered
|
2018-10-19 17:37:34 +02:00
|
|
|
*/
|
2019-06-06 12:21:31 +02:00
|
|
|
class Libp2p extends EventEmitter {
|
2018-06-28 10:06:25 +02:00
|
|
|
constructor (_options) {
|
2017-03-27 12:26:34 +01:00
|
|
|
super()
|
2018-06-28 10:06:25 +02:00
|
|
|
// validateConfig will ensure the config is correct,
|
|
|
|
// and add default values where appropriate
|
2019-04-11 12:44:58 +02:00
|
|
|
this._options = validateConfig(_options)
|
2016-11-26 03:07:52 +01:00
|
|
|
|
2019-04-11 12:44:58 +02:00
|
|
|
this.datastore = this._options.datastore
|
|
|
|
this.peerInfo = this._options.peerInfo
|
2019-11-06 15:11:13 +01:00
|
|
|
this.peerStore = new PeerStore()
|
2017-07-20 14:19:36 -07:00
|
|
|
|
2019-04-11 12:44:58 +02:00
|
|
|
this._modules = this._options.modules
|
|
|
|
this._config = this._options.config
|
2018-06-28 10:06:25 +02:00
|
|
|
this._transport = [] // Transport instances/references
|
|
|
|
this._discovery = [] // Discovery service instances/references
|
2016-11-26 03:07:52 +01:00
|
|
|
|
2019-11-15 16:48:32 +01:00
|
|
|
this.peerStore = new PeerStore()
|
|
|
|
|
2019-10-21 16:53:58 +02:00
|
|
|
// Setup the Upgrader
|
|
|
|
this.upgrader = new Upgrader({
|
|
|
|
localPeer: this.peerInfo.id,
|
|
|
|
onConnection: (connection) => {
|
|
|
|
const peerInfo = getPeerInfo(connection.remotePeer)
|
2019-11-06 15:11:13 +01:00
|
|
|
|
|
|
|
this.peerStore.put(peerInfo)
|
2019-11-06 15:47:11 +01:00
|
|
|
this.registrar.onConnect(peerInfo, connection)
|
2019-10-21 16:53:58 +02:00
|
|
|
this.emit('peer:connect', peerInfo)
|
|
|
|
},
|
|
|
|
onConnectionEnd: (connection) => {
|
|
|
|
const peerInfo = getPeerInfo(connection.remotePeer)
|
2019-11-06 15:47:11 +01:00
|
|
|
|
|
|
|
this.registrar.onDisconnect(peerInfo, connection)
|
2019-10-21 16:53:58 +02:00
|
|
|
this.emit('peer:disconnect', peerInfo)
|
|
|
|
}
|
|
|
|
})
|
2016-11-26 03:07:52 +01:00
|
|
|
|
2019-11-07 12:11:50 +01:00
|
|
|
// Create the Registrar
|
|
|
|
this.registrar = new Registrar({ peerStore: this.peerStore })
|
|
|
|
this.handle = this.handle.bind(this)
|
|
|
|
this.registrar.handle = this.handle
|
|
|
|
|
2019-10-02 13:31:28 +02:00
|
|
|
// Setup the transport manager
|
|
|
|
this.transportManager = new TransportManager({
|
|
|
|
libp2p: this,
|
2019-10-21 16:53:58 +02:00
|
|
|
upgrader: this.upgrader
|
2019-10-02 13:31:28 +02:00
|
|
|
})
|
|
|
|
this._modules.transport.forEach((Transport) => {
|
|
|
|
this.transportManager.add(Transport.prototype[Symbol.toStringTag], Transport)
|
|
|
|
})
|
|
|
|
|
2019-10-21 16:53:58 +02:00
|
|
|
// Attach crypto channels
|
|
|
|
if (this._modules.connEncryption) {
|
|
|
|
const cryptos = this._modules.connEncryption
|
|
|
|
cryptos.forEach((crypto) => {
|
2019-11-04 14:05:58 +01:00
|
|
|
this.upgrader.cryptos.set(crypto.protocol, crypto)
|
2019-10-21 16:53:58 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-11-07 12:11:50 +01:00
|
|
|
this.dialer = new Dialer({
|
2019-11-26 16:40:04 +01:00
|
|
|
transportManager: this.transportManager,
|
|
|
|
peerStore: this.peerStore
|
2019-11-07 12:11:50 +01:00
|
|
|
})
|
|
|
|
|
2016-11-26 03:07:52 +01:00
|
|
|
// Attach stream multiplexers
|
2018-06-28 10:06:25 +02:00
|
|
|
if (this._modules.streamMuxer) {
|
2019-07-30 15:11:24 +02:00
|
|
|
const muxers = this._modules.streamMuxer
|
2019-10-21 16:53:58 +02:00
|
|
|
muxers.forEach((muxer) => {
|
|
|
|
this.upgrader.muxers.set(muxer.multicodec, muxer)
|
2016-11-26 03:07:52 +01:00
|
|
|
})
|
2019-04-11 13:49:31 +02:00
|
|
|
|
2019-11-07 12:11:50 +01:00
|
|
|
// Add the identify service since we can multiplex
|
|
|
|
this.dialer.identifyService = new IdentifyService({
|
|
|
|
registrar: this.registrar,
|
|
|
|
peerInfo: this.peerInfo,
|
|
|
|
protocols: this.upgrader.protocols
|
|
|
|
})
|
|
|
|
this.handle(Object.values(IDENTIFY_PROTOCOLS), this.dialer.identifyService.handleMessage)
|
|
|
|
}
|
2019-11-06 15:47:11 +01:00
|
|
|
|
2018-06-08 00:30:21 +02:00
|
|
|
// Attach private network protector
|
|
|
|
if (this._modules.connProtector) {
|
2019-11-04 14:05:58 +01:00
|
|
|
this.upgrader.protector = this._modules.connProtector
|
2018-06-08 00:30:21 +02:00
|
|
|
} else if (process.env.LIBP2P_FORCE_PNET) {
|
|
|
|
throw new Error('Private network is enforced, but no protector was provided')
|
|
|
|
}
|
|
|
|
|
2018-06-28 10:06:25 +02:00
|
|
|
// dht provided components (peerRouting, contentRouting, dht)
|
2019-11-26 16:40:04 +01:00
|
|
|
if (this._modules.dht) {
|
|
|
|
this._dht = dht(this, this._modules.dht, this._config.dht)
|
2016-11-26 03:07:52 +01:00
|
|
|
}
|
|
|
|
|
2019-07-31 09:38:14 +02:00
|
|
|
// start pubsub
|
2019-11-15 16:48:32 +01:00
|
|
|
if (this._modules.pubsub) {
|
2019-08-19 17:06:08 +02:00
|
|
|
this.pubsub = pubsub(this, this._modules.pubsub, this._config.pubsub)
|
2017-04-06 15:45:23 -04:00
|
|
|
}
|
|
|
|
|
2018-06-28 10:06:25 +02:00
|
|
|
// Attach remaining APIs
|
2018-10-19 16:28:28 +02:00
|
|
|
// peer and content routing will automatically get modules from _modules and _dht
|
2018-02-07 07:48:37 +00:00
|
|
|
this.peerRouting = peerRouting(this)
|
|
|
|
this.contentRouting = contentRouting(this)
|
2017-04-06 15:45:23 -04:00
|
|
|
|
2019-04-11 12:44:58 +02:00
|
|
|
this._peerDiscovered = this._peerDiscovered.bind(this)
|
2018-10-19 17:37:34 +02:00
|
|
|
}
|
|
|
|
|
2018-11-12 15:43:32 +01:00
|
|
|
/**
|
|
|
|
* Overrides EventEmitter.emit to conditionally emit errors
|
|
|
|
* if there is a handler. If not, errors will be logged.
|
|
|
|
* @param {string} eventName
|
|
|
|
* @param {...any} args
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
emit (eventName, ...args) {
|
|
|
|
if (eventName === 'error' && !this._events.error) {
|
|
|
|
log.error(...args)
|
|
|
|
} else {
|
|
|
|
super.emit(eventName, ...args)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-19 17:37:34 +02:00
|
|
|
/**
|
2019-11-19 17:44:45 -06:00
|
|
|
* Starts the libp2p node and all its subsystems
|
2018-10-19 17:37:34 +02:00
|
|
|
*
|
2019-11-19 17:44:45 -06:00
|
|
|
* @returns {Promise<void>}
|
2018-10-19 17:37:34 +02:00
|
|
|
*/
|
2019-11-19 17:44:45 -06:00
|
|
|
async start () {
|
|
|
|
log('libp2p is starting')
|
|
|
|
try {
|
|
|
|
await this._onStarting()
|
|
|
|
await this._onDidStart()
|
|
|
|
log('libp2p has started')
|
|
|
|
} catch (err) {
|
|
|
|
this.emit('error', err)
|
|
|
|
log.error('An error occurred starting libp2p', err)
|
|
|
|
await this.stop()
|
|
|
|
throw err
|
|
|
|
}
|
|
|
|
this._isStarted = true
|
2018-10-19 17:37:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stop the libp2p node by closing its listeners and open connections
|
2019-10-21 16:53:58 +02:00
|
|
|
* @async
|
2018-10-19 17:37:34 +02:00
|
|
|
* @returns {void}
|
|
|
|
*/
|
2019-10-21 16:53:58 +02:00
|
|
|
async stop () {
|
2019-11-19 17:44:45 -06:00
|
|
|
log('libp2p is stopping')
|
2019-10-21 16:53:58 +02:00
|
|
|
|
|
|
|
try {
|
2019-11-15 16:48:32 +01:00
|
|
|
this.pubsub && await this.pubsub.stop()
|
2019-11-26 16:40:04 +01:00
|
|
|
this._dht && await this._dht.stop()
|
2019-10-21 16:53:58 +02:00
|
|
|
await this.transportManager.close()
|
|
|
|
} catch (err) {
|
|
|
|
if (err) {
|
|
|
|
log.error(err)
|
|
|
|
this.emit('error', err)
|
|
|
|
}
|
|
|
|
}
|
2019-11-19 17:44:45 -06:00
|
|
|
log('libp2p has stopped')
|
2018-10-19 17:37:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
isStarted () {
|
2019-11-19 17:44:45 -06:00
|
|
|
return this._isStarted
|
2018-10-19 17:37:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dials to the provided peer. If successful, the `PeerInfo` of the
|
2019-11-06 15:11:13 +01:00
|
|
|
* peer will be added to the nodes `peerStore`
|
2018-10-19 17:37:34 +02:00
|
|
|
*
|
|
|
|
* @param {PeerInfo|PeerId|Multiaddr|string} peer The peer to dial
|
2019-10-21 16:53:58 +02:00
|
|
|
* @param {object} options
|
|
|
|
* @param {AbortSignal} [options.signal]
|
|
|
|
* @returns {Promise<Connection>}
|
2018-10-19 17:37:34 +02:00
|
|
|
*/
|
2019-10-21 16:53:58 +02:00
|
|
|
dial (peer, options) {
|
|
|
|
return this.dialProtocol(peer, null, options)
|
2018-10-19 17:37:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dials to the provided peer and handshakes with the given protocol.
|
2019-11-06 15:11:13 +01:00
|
|
|
* If successful, the `PeerInfo` of the peer will be added to the nodes `peerStore`,
|
2018-10-19 17:37:34 +02:00
|
|
|
* and the `Connection` will be sent in the callback
|
|
|
|
*
|
2019-10-21 16:53:58 +02:00
|
|
|
* @async
|
2018-10-19 17:37:34 +02:00
|
|
|
* @param {PeerInfo|PeerId|Multiaddr|string} peer The peer to dial
|
2019-10-21 16:53:58 +02:00
|
|
|
* @param {string[]|string} protocols
|
|
|
|
* @param {object} options
|
|
|
|
* @param {AbortSignal} [options.signal]
|
|
|
|
* @returns {Promise<Connection|*>}
|
2018-10-19 17:37:34 +02:00
|
|
|
*/
|
2019-10-21 16:53:58 +02:00
|
|
|
async dialProtocol (peer, protocols, options) {
|
|
|
|
let connection
|
|
|
|
if (multiaddr.isMultiaddr(peer)) {
|
|
|
|
connection = await this.dialer.connectToMultiaddr(peer, options)
|
|
|
|
} else {
|
|
|
|
peer = await getPeerInfoRemote(peer, this)
|
|
|
|
connection = await this.dialer.connectToPeer(peer, options)
|
2018-12-14 17:54:32 +01:00
|
|
|
}
|
2018-10-19 17:37:34 +02:00
|
|
|
|
2019-11-06 15:11:13 +01:00
|
|
|
const peerInfo = getPeerInfo(connection.remotePeer)
|
|
|
|
|
2019-10-21 16:53:58 +02:00
|
|
|
// If a protocol was provided, create a new stream
|
|
|
|
if (protocols) {
|
2019-11-06 15:11:13 +01:00
|
|
|
const stream = await connection.newStream(protocols)
|
|
|
|
|
|
|
|
peerInfo.protocols.add(stream.protocol)
|
|
|
|
this.peerStore.put(peerInfo)
|
|
|
|
|
|
|
|
return stream
|
2018-10-19 17:37:34 +02:00
|
|
|
}
|
|
|
|
|
2019-11-06 15:11:13 +01:00
|
|
|
this.peerStore.put(peerInfo)
|
2019-10-21 16:53:58 +02:00
|
|
|
return connection
|
2018-10-19 17:37:34 +02:00
|
|
|
}
|
|
|
|
|
2019-08-06 10:53:23 +02:00
|
|
|
/**
|
2019-11-19 17:44:45 -06:00
|
|
|
* Disconnects all connections to the given `peer`
|
2019-08-06 10:53:23 +02:00
|
|
|
*
|
2019-11-19 17:44:45 -06:00
|
|
|
* @param {PeerId} peer The PeerId to close connections to
|
|
|
|
* @returns {Promise<void>}
|
2019-08-06 10:53:23 +02:00
|
|
|
*/
|
2019-11-19 17:44:45 -06:00
|
|
|
hangUp (peer) {
|
|
|
|
return Promise.all(
|
|
|
|
this.registrar.connections.get(peer.toB58String()).map(connection => {
|
|
|
|
return connection.close()
|
|
|
|
})
|
|
|
|
)
|
2018-10-19 17:37:34 +02:00
|
|
|
}
|
|
|
|
|
2019-11-19 17:44:45 -06:00
|
|
|
// TODO: Update ping
|
|
|
|
// /**
|
|
|
|
// * Pings the provided peer
|
|
|
|
// *
|
|
|
|
// * @param {PeerInfo|PeerId|Multiaddr|string} peer The peer to ping
|
|
|
|
// * @returns {Promise<Ping>}
|
|
|
|
// */
|
|
|
|
// ping (peer) {
|
|
|
|
// const peerInfo = await getPeerInfoRemote(peer, this)
|
|
|
|
// return new Ping(this._switch, peerInfo)
|
|
|
|
// }
|
2018-10-19 17:37:34 +02:00
|
|
|
|
2019-10-21 16:53:58 +02:00
|
|
|
/**
|
|
|
|
* Registers the `handler` for each protocol
|
|
|
|
* @param {string[]|string} protocols
|
2019-11-07 12:11:50 +01:00
|
|
|
* @param {function({ connection:*, stream:*, protocol:string })} handler
|
2019-10-21 16:53:58 +02:00
|
|
|
*/
|
|
|
|
handle (protocols, handler) {
|
|
|
|
protocols = Array.isArray(protocols) ? protocols : [protocols]
|
|
|
|
protocols.forEach(protocol => {
|
|
|
|
this.upgrader.protocols.set(protocol, handler)
|
|
|
|
})
|
2019-11-07 12:11:50 +01:00
|
|
|
|
|
|
|
this.dialer.identifyService.pushToPeerStore(this.peerStore)
|
2018-10-19 17:37:34 +02:00
|
|
|
}
|
|
|
|
|
2019-10-21 16:53:58 +02:00
|
|
|
/**
|
|
|
|
* Removes the handler for each protocol. The protocol
|
|
|
|
* will no longer be supported on streams.
|
|
|
|
* @param {string[]|string} protocols
|
|
|
|
*/
|
|
|
|
unhandle (protocols) {
|
|
|
|
protocols = Array.isArray(protocols) ? protocols : [protocols]
|
|
|
|
protocols.forEach(protocol => {
|
|
|
|
this.upgrader.protocols.delete(protocol)
|
|
|
|
})
|
2019-11-07 12:11:50 +01:00
|
|
|
|
|
|
|
this.dialer.identifyService.pushToPeerStore(this.peerStore)
|
2018-10-19 17:37:34 +02:00
|
|
|
}
|
|
|
|
|
2019-10-02 13:31:28 +02:00
|
|
|
async _onStarting () {
|
2017-12-14 07:27:13 +00:00
|
|
|
const multiaddrs = this.peerInfo.multiaddrs.toArray()
|
2018-06-28 10:06:25 +02:00
|
|
|
|
2019-11-19 17:44:45 -06:00
|
|
|
await this.transportManager.listen(multiaddrs)
|
2019-11-15 16:48:32 +01:00
|
|
|
|
|
|
|
if (this._config.pubsub.enabled) {
|
|
|
|
this.pubsub && this.pubsub.start()
|
|
|
|
}
|
2019-11-26 16:40:04 +01:00
|
|
|
|
|
|
|
if (this._config.dht.enabled) {
|
|
|
|
this._dht && this._dht.start()
|
|
|
|
}
|
2019-11-19 17:44:45 -06:00
|
|
|
}
|
2019-11-15 16:48:32 +01:00
|
|
|
|
2019-11-19 17:44:45 -06:00
|
|
|
/**
|
|
|
|
* Called when libp2p has started and before it returns
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
_onDidStart () {
|
|
|
|
// Once we start, emit and dial any peers we may have already discovered
|
|
|
|
for (const peerInfo of this.peerStore.peers.values()) {
|
|
|
|
this.emit('peer:discovery', peerInfo)
|
|
|
|
this._maybeConnect(peerInfo)
|
2019-10-02 13:31:28 +02:00
|
|
|
}
|
2015-09-27 00:14:40 +01:00
|
|
|
}
|
|
|
|
|
2019-04-11 12:44:58 +02:00
|
|
|
/**
|
|
|
|
* Handles discovered peers. Each discovered peer will be emitted via
|
|
|
|
* the `peer:discovery` event. If auto dial is enabled for libp2p
|
|
|
|
* and the current connection count is under the low watermark, the
|
|
|
|
* peer will be dialed.
|
|
|
|
* @private
|
|
|
|
* @param {PeerInfo} peerInfo
|
|
|
|
*/
|
|
|
|
_peerDiscovered (peerInfo) {
|
2019-04-16 12:05:22 +02:00
|
|
|
if (peerInfo.id.toB58String() === this.peerInfo.id.toB58String()) {
|
|
|
|
log.error(new Error(codes.ERR_DISCOVERED_SELF))
|
|
|
|
return
|
|
|
|
}
|
2019-11-06 15:11:13 +01:00
|
|
|
peerInfo = this.peerStore.put(peerInfo)
|
2019-04-11 12:44:58 +02:00
|
|
|
|
|
|
|
if (!this.isStarted()) return
|
|
|
|
|
|
|
|
this.emit('peer:discovery', peerInfo)
|
|
|
|
this._maybeConnect(peerInfo)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Will dial to the given `peerInfo` if the current number of
|
|
|
|
* connected peers is less than the configured `ConnectionManager`
|
|
|
|
* minPeers.
|
|
|
|
* @private
|
|
|
|
* @param {PeerInfo} peerInfo
|
|
|
|
*/
|
2019-11-19 17:44:45 -06:00
|
|
|
async _maybeConnect (peerInfo) {
|
|
|
|
// If auto dialing is on and we have no connection to the peer, check if we should dial
|
|
|
|
if (this._config.peerDiscovery.autoDial === true && !this.registrar.connections.get(peerInfo)) {
|
2019-04-11 12:44:58 +02:00
|
|
|
const minPeers = this._options.connectionManager.minPeers || 0
|
2019-11-19 17:44:45 -06:00
|
|
|
// TODO: This does not account for multiple connections to a peer
|
|
|
|
if (minPeers > this.registrar.connections.size) {
|
2019-04-11 12:44:58 +02:00
|
|
|
log('connecting to discovered peer')
|
2019-11-19 17:44:45 -06:00
|
|
|
try {
|
|
|
|
await this.dialer.connectToPeer(peerInfo)
|
|
|
|
} catch (err) {
|
|
|
|
log.error('could not connect to discovered peer', err)
|
|
|
|
}
|
2019-04-11 12:44:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initializes and starts peer discovery services
|
|
|
|
*
|
|
|
|
* @private
|
2019-11-19 17:44:45 -06:00
|
|
|
* @returns {Promise<void>}
|
2019-04-11 12:44:58 +02:00
|
|
|
*/
|
2019-11-19 17:44:45 -06:00
|
|
|
_setupPeerDiscovery () {
|
2019-04-11 12:44:58 +02:00
|
|
|
for (const DiscoveryService of this._modules.peerDiscovery) {
|
|
|
|
let config = {
|
|
|
|
enabled: true // on by default
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DiscoveryService.tag &&
|
|
|
|
this._config.peerDiscovery &&
|
|
|
|
this._config.peerDiscovery[DiscoveryService.tag]) {
|
|
|
|
config = { ...config, ...this._config.peerDiscovery[DiscoveryService.tag] }
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config.enabled) {
|
|
|
|
let discoveryService
|
|
|
|
|
|
|
|
if (typeof DiscoveryService === 'function') {
|
|
|
|
discoveryService = new DiscoveryService(Object.assign({}, config, { peerInfo: this.peerInfo }))
|
|
|
|
} else {
|
|
|
|
discoveryService = DiscoveryService
|
|
|
|
}
|
|
|
|
|
|
|
|
discoveryService.on('peer', this._peerDiscovered)
|
|
|
|
this._discovery.push(discoveryService)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-19 17:44:45 -06:00
|
|
|
return this._discovery.map(d => d.start())
|
2019-04-11 12:44:58 +02:00
|
|
|
}
|
2016-11-26 03:07:52 +01:00
|
|
|
}
|
|
|
|
|
2019-06-06 12:21:31 +02:00
|
|
|
module.exports = Libp2p
|
|
|
|
/**
|
|
|
|
* Like `new Libp2p(options)` except it will create a `PeerInfo`
|
|
|
|
* instance if one is not provided in options.
|
|
|
|
* @param {object} options Libp2p configuration options
|
2019-11-15 16:48:32 +01:00
|
|
|
* @returns {Libp2p}
|
2019-06-06 12:21:31 +02:00
|
|
|
*/
|
2019-11-15 16:48:32 +01:00
|
|
|
module.exports.create = async (options = {}) => {
|
2019-06-06 12:21:31 +02:00
|
|
|
if (options.peerInfo) {
|
2019-11-15 16:48:32 +01:00
|
|
|
return new Libp2p(options)
|
2019-06-06 12:21:31 +02:00
|
|
|
}
|
2019-11-15 16:48:32 +01:00
|
|
|
|
|
|
|
const peerInfo = await PeerInfo.create()
|
|
|
|
|
|
|
|
options.peerInfo = peerInfo
|
|
|
|
return new Libp2p(options)
|
|
|
|
}
|