mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-07-08 13:21:34 +00:00
Compare commits
13 Commits
docs/deleg
...
v0.26.0-rc
Author | SHA1 | Date | |
---|---|---|---|
7c2c852fc0 | |||
e8d8aab278 | |||
dd48d268ec | |||
99a53592e2 | |||
2a2e7a1012 | |||
791f39a09b | |||
65d52857a5 | |||
48b1b442e9 | |||
9554b05c6f | |||
df6ef45a2d | |||
b4a70ea476 | |||
45716da465 | |||
905c911946 |
43
CHANGELOG.md
43
CHANGELOG.md
@ -1,3 +1,46 @@
|
||||
<a name="0.26.0-rc.1"></a>
|
||||
# [0.26.0-rc.1](https://github.com/libp2p/js-libp2p/compare/v0.26.0-rc.0...v0.26.0-rc.1) (2019-07-31)
|
||||
|
||||
|
||||
|
||||
<a name="0.26.0-rc.0"></a>
|
||||
# [0.26.0-rc.0](https://github.com/libp2p/js-libp2p/compare/v0.25.5...v0.26.0-rc.0) (2019-07-31)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* make subscribe comply with ipfs interface ([#389](https://github.com/libp2p/js-libp2p/issues/389)) ([9554b05](https://github.com/libp2p/js-libp2p/commit/9554b05))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* integrate gossipsub by default ([#365](https://github.com/libp2p/js-libp2p/issues/365)) ([791f39a](https://github.com/libp2p/js-libp2p/commit/791f39a))
|
||||
* promisify all api methods that accept callbacks ([#381](https://github.com/libp2p/js-libp2p/issues/381)) ([df6ef45](https://github.com/libp2p/js-libp2p/commit/df6ef45))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* new configuration for deciding the implementation of pubsub to be used.
|
||||
In this context, the experimental flags were also removed. See the README for the latest usage.
|
||||
* The ipfs interface specified that options
|
||||
should be provided after the handler, not before.
|
||||
https://github.com/ipfs/interface-js-ipfs-core/blob/v0.109.0/SPEC/PUBSUB.md#pubsubsubscribe
|
||||
|
||||
This corrects the order of parameters. See the jsdocs examples
|
||||
for subscribe to see how it should be used.
|
||||
|
||||
|
||||
|
||||
<a name="0.25.5"></a>
|
||||
## [0.25.5](https://github.com/libp2p/js-libp2p/compare/v0.25.4...v0.25.5) (2019-07-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* peer routing for delegate router ([#377](https://github.com/libp2p/js-libp2p/issues/377)) ([905c911](https://github.com/libp2p/js-libp2p/commit/905c911)), closes [/github.com/libp2p/go-libp2p-core/blob/6e566d10f4a5447317a66d64c7459954b969bdab/routing/query.go#L15-L24](https://github.com//github.com/libp2p/go-libp2p-core/blob/6e566d10f4a5447317a66d64c7459954b969bdab/routing/query.go/issues/L15-L24)
|
||||
|
||||
|
||||
|
||||
<a name="0.25.4"></a>
|
||||
## [0.25.4](https://github.com/libp2p/js-libp2p/compare/v0.25.3...v0.25.4) (2019-06-07)
|
||||
|
||||
|
11
README.md
11
README.md
@ -119,6 +119,7 @@ const MPLEX = require('libp2p-mplex')
|
||||
const SECIO = require('libp2p-secio')
|
||||
const MulticastDNS = require('libp2p-mdns')
|
||||
const DHT = require('libp2p-kad-dht')
|
||||
const GossipSub = require('libp2p-gossipsub')
|
||||
const defaultsDeep = require('@nodeutils/defaults-deep')
|
||||
const Protector = require('libp2p-pnet')
|
||||
const DelegatedPeerRouter = require('libp2p-delegated-peer-routing')
|
||||
@ -154,7 +155,8 @@ class Node extends Libp2p {
|
||||
peerDiscovery: [
|
||||
MulticastDNS
|
||||
],
|
||||
dht: DHT // DHT enables PeerRouting, ContentRouting and DHT itself components
|
||||
dht: DHT, // DHT enables PeerRouting, ContentRouting and DHT itself components
|
||||
pubsub: GossipSub
|
||||
},
|
||||
|
||||
// libp2p config options (typically found on a config.json)
|
||||
@ -187,9 +189,8 @@ class Node extends Libp2p {
|
||||
timeout: 10e3
|
||||
}
|
||||
},
|
||||
// Enable/Disable Experimental features
|
||||
EXPERIMENTAL: { // Experimental features ("behind a flag")
|
||||
pubsub: false
|
||||
pubsub: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -204,6 +205,8 @@ class Node extends Libp2p {
|
||||
|
||||
### API
|
||||
|
||||
**IMPORTANT NOTE**: All the methods listed in the API section that take a callback are also now Promisified. Libp2p is migrating away from callbacks to async/await, and in a future release (that will be announced in advance), callback support will be removed entirely. You can follow progress of the async/await endeavor at https://github.com/ipfs/js-ipfs/issues/1670.
|
||||
|
||||
#### Create a Node - `Libp2p.createLibp2p(options, callback)`
|
||||
|
||||
> Behaves exactly like `new Libp2p(options)`, but doesn't require a PeerInfo. One will be generated instead
|
||||
|
@ -17,7 +17,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"detect-dom-ready": "^1.0.2",
|
||||
"libp2p": "../../../",
|
||||
"libp2p-bootstrap": "~0.9.7",
|
||||
"libp2p-kad-dht": "^0.15.3",
|
||||
"libp2p-mplex": "~0.8.5",
|
||||
"libp2p-secio": "~0.11.1",
|
||||
"libp2p-spdy": "~0.13.3",
|
||||
|
@ -8,8 +8,7 @@ const SPDY = require('libp2p-spdy')
|
||||
const SECIO = require('libp2p-secio')
|
||||
const Bootstrap = require('libp2p-bootstrap')
|
||||
const DHT = require('libp2p-kad-dht')
|
||||
const defaultsDeep = require('@nodeutils/defaults-deep')
|
||||
const libp2p = require('../../../../')
|
||||
const libp2p = require('libp2p')
|
||||
|
||||
// Find this list at: https://github.com/ipfs/js-ipfs/blob/master/src/core/runtime/config-browser.json
|
||||
const bootstrapList = [
|
||||
@ -26,9 +25,9 @@ const bootstrapList = [
|
||||
]
|
||||
|
||||
class Node extends libp2p {
|
||||
constructor (_options) {
|
||||
const wrtcStar = new WebRTCStar({ id: _options.peerInfo.id })
|
||||
const wsstar = new WebSocketStar({ id: _options.peerInfo.id })
|
||||
constructor ({ peerInfo }) {
|
||||
const wrtcStar = new WebRTCStar({ id: peerInfo.id })
|
||||
const wsstar = new WebSocketStar({ id: peerInfo.id })
|
||||
|
||||
const defaults = {
|
||||
modules: {
|
||||
@ -86,7 +85,7 @@ class Node extends libp2p {
|
||||
}
|
||||
}
|
||||
|
||||
super(defaultsDeep(_options, defaults))
|
||||
super({ ...defaults, peerInfo })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,9 +10,11 @@ function createNode (callback) {
|
||||
}
|
||||
|
||||
const peerIdStr = peerInfo.id.toB58String()
|
||||
const ma = `/dns4/star-signal.cloud.ipfs.team/tcp/443/wss/p2p-webrtc-star/p2p/${peerIdStr}`
|
||||
const webrtcAddr = `/dns4/star-signal.cloud.ipfs.team/tcp/443/wss/p2p-webrtc-star/p2p/${peerIdStr}`
|
||||
const wsAddr = `/dns4/ws-star.discovery.libp2p.io/tcp/443/wss/p2p-websocket-star`
|
||||
|
||||
peerInfo.multiaddrs.add(ma)
|
||||
peerInfo.multiaddrs.add(webrtcAddr)
|
||||
peerInfo.multiaddrs.add(wsAddr)
|
||||
|
||||
const node = new Node({
|
||||
peerInfo
|
||||
|
@ -46,6 +46,9 @@ domReady(() => {
|
||||
myPeerDiv.append(idDiv)
|
||||
|
||||
console.log('Node is listening o/')
|
||||
node.peerInfo.multiaddrs.toArray().forEach(ma => {
|
||||
console.log(ma.toString())
|
||||
})
|
||||
|
||||
// NOTE: to stop the node
|
||||
// node.stop((err) => {})
|
||||
|
@ -20,5 +20,3 @@ Then simply go into the folder [1](./1) and execute the following
|
||||
> npm start
|
||||
# open your browser in port :9090
|
||||
```
|
||||
|
||||
[Version Published on IPFS](http://ipfs.io/ipfs/Qmbc1J7ehw1dNYachbkCWPto4RsnVvqCKNVzmYEod2gXcy)
|
||||
|
14
package.json
14
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "libp2p",
|
||||
"version": "0.25.4",
|
||||
"version": "0.26.0-rc.1",
|
||||
"description": "JavaScript implementation of libp2p, a modular peer to peer network stack",
|
||||
"leadMaintainer": "Jacob Heun <jacobheun@gmail.com>",
|
||||
"main": "src/index.js",
|
||||
@ -48,7 +48,6 @@
|
||||
"err-code": "^1.1.2",
|
||||
"fsm-event": "^2.1.0",
|
||||
"libp2p-connection-manager": "^0.1.0",
|
||||
"libp2p-floodsub": "^0.16.1",
|
||||
"libp2p-ping": "^0.8.5",
|
||||
"libp2p-switch": "^0.42.12",
|
||||
"libp2p-websockets": "^0.12.2",
|
||||
@ -58,11 +57,12 @@
|
||||
"peer-book": "^0.9.1",
|
||||
"peer-id": "^0.12.2",
|
||||
"peer-info": "^0.15.1",
|
||||
"promisify-es6": "^1.0.3",
|
||||
"superstruct": "^0.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nodeutils/defaults-deep": "^1.1.0",
|
||||
"aegir": "^19.0.3",
|
||||
"aegir": "^20.0.0",
|
||||
"chai": "^4.2.0",
|
||||
"chai-checkmark": "^1.0.1",
|
||||
"cids": "^0.7.1",
|
||||
@ -73,7 +73,9 @@
|
||||
"libp2p-circuit": "^0.3.7",
|
||||
"libp2p-delegated-content-routing": "^0.2.2",
|
||||
"libp2p-delegated-peer-routing": "^0.2.2",
|
||||
"libp2p-kad-dht": "^0.15.2",
|
||||
"libp2p-floodsub": "~0.17.0",
|
||||
"libp2p-gossipsub": "~0.0.4",
|
||||
"libp2p-kad-dht": "^0.15.3",
|
||||
"libp2p-mdns": "^0.12.3",
|
||||
"libp2p-mplex": "^0.8.4",
|
||||
"libp2p-secio": "^0.11.1",
|
||||
@ -83,6 +85,7 @@
|
||||
"libp2p-websocket-star": "~0.10.2",
|
||||
"libp2p-websocket-star-rendezvous": "~0.3.0",
|
||||
"lodash.times": "^4.3.2",
|
||||
"merge-options": "^1.0.1",
|
||||
"nock": "^10.0.6",
|
||||
"pull-goodbye": "0.0.2",
|
||||
"pull-mplex": "^0.1.2",
|
||||
@ -95,6 +98,7 @@
|
||||
"Aditya Bose <13054902+adbose@users.noreply.github.com>",
|
||||
"Alan Shaw <alan.shaw@protocol.ai>",
|
||||
"Alan Shaw <alan@tableflip.io>",
|
||||
"Alex Potsides <alex@achingbrain.net>",
|
||||
"Andrew Nesbitt <andrewnez@gmail.com>",
|
||||
"Chris Bratlien <chrisbratlien@gmail.com>",
|
||||
"Chris Dostert <chrisdostert@users.noreply.github.com>",
|
||||
@ -129,8 +133,8 @@
|
||||
"Sönke Hahn <soenkehahn@gmail.com>",
|
||||
"Thomas Eizinger <thomas@eizinger.io>",
|
||||
"Tiago Alves <alvesjtiago@gmail.com>",
|
||||
"Vasco Santos <vasco.santos@ua.pt>",
|
||||
"Vasco Santos <vasco.santos@moxy.studio>",
|
||||
"Vasco Santos <vasco.santos@ua.pt>",
|
||||
"Volker Mische <volker.mische@gmail.com>",
|
||||
"Yusef Napora <yusef@napora.org>",
|
||||
"Zane Starr <zcstarr@gmail.com>",
|
||||
|
@ -19,6 +19,7 @@ const modulesSchema = s({
|
||||
connProtector: s.union(['undefined', s.interface({ protect: 'function' })]),
|
||||
contentRouting: optional(list(['object'])),
|
||||
dht: optional(s('null|function|object')),
|
||||
pubsub: optional(s('null|function|object')),
|
||||
peerDiscovery: optional(list([s('object|function')])),
|
||||
peerRouting: optional(list(['object'])),
|
||||
streamMuxer: optional(list([s('object|function')])),
|
||||
@ -59,12 +60,10 @@ const configSchema = s({
|
||||
timeout: 10e3
|
||||
}
|
||||
}),
|
||||
// Experimental config
|
||||
EXPERIMENTAL: s({
|
||||
pubsub: 'boolean'
|
||||
}, {
|
||||
// Experimental defaults
|
||||
pubsub: false
|
||||
// Pubsub config
|
||||
pubsub: s('object?', {
|
||||
// DHT defaults
|
||||
enabled: false
|
||||
})
|
||||
}, {})
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
const tryEach = require('async/tryEach')
|
||||
const parallel = require('async/parallel')
|
||||
const errCode = require('err-code')
|
||||
const promisify = require('promisify-es6')
|
||||
|
||||
module.exports = (node) => {
|
||||
const routers = node._modules.contentRouting || []
|
||||
@ -24,7 +25,7 @@ module.exports = (node) => {
|
||||
* @param {function(Error, Result<Array>)} callback
|
||||
* @returns {void}
|
||||
*/
|
||||
findProviders: (key, options, callback) => {
|
||||
findProviders: promisify((key, options, callback) => {
|
||||
if (typeof options === 'function') {
|
||||
callback = options
|
||||
options = {}
|
||||
@ -60,7 +61,7 @@ module.exports = (node) => {
|
||||
results = results || []
|
||||
callback(null, results)
|
||||
})
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Iterates over all content routers in parallel to notify it is
|
||||
@ -70,7 +71,7 @@ module.exports = (node) => {
|
||||
* @param {function(Error)} callback
|
||||
* @returns {void}
|
||||
*/
|
||||
provide: (key, callback) => {
|
||||
provide: promisify((key, callback) => {
|
||||
if (!routers.length) {
|
||||
return callback(errCode(new Error('No content routers available'), 'NO_ROUTERS_AVAILABLE'))
|
||||
}
|
||||
@ -78,6 +79,6 @@ module.exports = (node) => {
|
||||
parallel(routers.map((router) => {
|
||||
return (cb) => router.provide(key, cb)
|
||||
}), callback)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
13
src/dht.js
13
src/dht.js
@ -2,19 +2,20 @@
|
||||
|
||||
const nextTick = require('async/nextTick')
|
||||
const errCode = require('err-code')
|
||||
const promisify = require('promisify-es6')
|
||||
|
||||
const { messages, codes } = require('./errors')
|
||||
|
||||
module.exports = (node) => {
|
||||
return {
|
||||
put: (key, value, callback) => {
|
||||
put: promisify((key, value, callback) => {
|
||||
if (!node._dht) {
|
||||
return nextTick(callback, errCode(new Error(messages.DHT_DISABLED), codes.DHT_DISABLED))
|
||||
}
|
||||
|
||||
node._dht.put(key, value, callback)
|
||||
},
|
||||
get: (key, options, callback) => {
|
||||
}),
|
||||
get: promisify((key, options, callback) => {
|
||||
if (typeof options === 'function') {
|
||||
callback = options
|
||||
options = {}
|
||||
@ -25,8 +26,8 @@ module.exports = (node) => {
|
||||
}
|
||||
|
||||
node._dht.get(key, options, callback)
|
||||
},
|
||||
getMany: (key, nVals, options, callback) => {
|
||||
}),
|
||||
getMany: promisify((key, nVals, options, callback) => {
|
||||
if (typeof options === 'function') {
|
||||
callback = options
|
||||
options = {}
|
||||
@ -37,6 +38,6 @@ module.exports = (node) => {
|
||||
}
|
||||
|
||||
node._dht.getMany(key, nVals, options, callback)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -4,12 +4,13 @@ const PeerId = require('peer-id')
|
||||
const PeerInfo = require('peer-info')
|
||||
const multiaddr = require('multiaddr')
|
||||
const errCode = require('err-code')
|
||||
const promisify = require('promisify-es6')
|
||||
|
||||
module.exports = (node) => {
|
||||
/*
|
||||
* Helper method to check the data type of peer and convert it to PeerInfo
|
||||
*/
|
||||
return function (peer, callback) {
|
||||
return promisify(function (peer, callback) {
|
||||
let p
|
||||
// PeerInfo
|
||||
if (PeerInfo.isPeerInfo(peer)) {
|
||||
@ -62,5 +63,5 @@ module.exports = (node) => {
|
||||
}
|
||||
|
||||
callback(null, p)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
30
src/index.js
30
src/index.js
@ -6,6 +6,7 @@ const debug = require('debug')
|
||||
const log = debug('libp2p')
|
||||
log.error = debug('libp2p:error')
|
||||
const errCode = require('err-code')
|
||||
const promisify = require('promisify-es6')
|
||||
|
||||
const each = require('async/each')
|
||||
const series = require('async/series')
|
||||
@ -68,7 +69,7 @@ class Libp2p extends EventEmitter {
|
||||
|
||||
// Attach stream multiplexers
|
||||
if (this._modules.streamMuxer) {
|
||||
let muxers = this._modules.streamMuxer
|
||||
const muxers = this._modules.streamMuxer
|
||||
muxers.forEach((muxer) => this._switch.connection.addStreamMuxer(muxer))
|
||||
|
||||
// If muxer exists
|
||||
@ -98,7 +99,7 @@ class Libp2p extends EventEmitter {
|
||||
|
||||
// Attach crypto channels
|
||||
if (this._modules.connEncryption) {
|
||||
let cryptos = this._modules.connEncryption
|
||||
const cryptos = this._modules.connEncryption
|
||||
cryptos.forEach((crypto) => {
|
||||
this._switch.connection.crypto(crypto.tag, crypto.encrypt)
|
||||
})
|
||||
@ -121,9 +122,9 @@ class Libp2p extends EventEmitter {
|
||||
})
|
||||
}
|
||||
|
||||
// enable/disable pubsub
|
||||
if (this._config.EXPERIMENTAL.pubsub) {
|
||||
this.pubsub = pubsub(this)
|
||||
// start pubsub
|
||||
if (this._modules.pubsub && this._config.pubsub.enabled !== false) {
|
||||
this.pubsub = pubsub(this, this._modules.pubsub)
|
||||
}
|
||||
|
||||
// Attach remaining APIs
|
||||
@ -186,6 +187,13 @@ class Libp2p extends EventEmitter {
|
||||
})
|
||||
|
||||
this._peerDiscovered = this._peerDiscovered.bind(this)
|
||||
|
||||
// promisify all instance methods
|
||||
;['start', 'stop', 'dial', 'dialProtocol', 'dialFSM', 'hangUp', 'ping'].forEach(method => {
|
||||
this[method] = promisify(this[method], {
|
||||
context: this
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -395,8 +403,8 @@ class Libp2p extends EventEmitter {
|
||||
}
|
||||
},
|
||||
(cb) => {
|
||||
if (this._floodSub) {
|
||||
return this._floodSub.start(cb)
|
||||
if (this.pubsub) {
|
||||
return this.pubsub.start(cb)
|
||||
}
|
||||
cb()
|
||||
},
|
||||
@ -434,8 +442,8 @@ class Libp2p extends EventEmitter {
|
||||
)
|
||||
},
|
||||
(cb) => {
|
||||
if (this._floodSub) {
|
||||
return this._floodSub.stop(cb)
|
||||
if (this.pubsub) {
|
||||
return this.pubsub.stop(cb)
|
||||
}
|
||||
cb()
|
||||
},
|
||||
@ -557,7 +565,7 @@ module.exports = Libp2p
|
||||
* @param {function(Error, Libp2p)} callback
|
||||
* @returns {void}
|
||||
*/
|
||||
module.exports.createLibp2p = (options, callback) => {
|
||||
module.exports.createLibp2p = promisify((options, callback) => {
|
||||
if (options.peerInfo) {
|
||||
return nextTick(callback, null, new Libp2p(options))
|
||||
}
|
||||
@ -566,4 +574,4 @@ module.exports.createLibp2p = (options, callback) => {
|
||||
options.peerInfo = peerInfo
|
||||
callback(null, new Libp2p(options))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const tryEach = require('async/tryEach')
|
||||
const errCode = require('err-code')
|
||||
const promisify = require('promisify-es6')
|
||||
|
||||
module.exports = (node) => {
|
||||
const routers = node._modules.peerRouting || []
|
||||
@ -21,7 +22,7 @@ module.exports = (node) => {
|
||||
* @param {function(Error, Result<Array>)} callback
|
||||
* @returns {void}
|
||||
*/
|
||||
findPeer: (id, options, callback) => {
|
||||
findPeer: promisify((id, options, callback) => {
|
||||
if (typeof options === 'function') {
|
||||
callback = options
|
||||
options = {}
|
||||
@ -47,12 +48,12 @@ module.exports = (node) => {
|
||||
})
|
||||
|
||||
tryEach(tasks, (err, results) => {
|
||||
if (err && err.code !== 'NOT_FOUND') {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
results = results || []
|
||||
callback(null, results)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
126
src/pubsub.js
126
src/pubsub.js
@ -2,82 +2,128 @@
|
||||
|
||||
const nextTick = require('async/nextTick')
|
||||
const { messages, codes } = require('./errors')
|
||||
const FloodSub = require('libp2p-floodsub')
|
||||
const promisify = require('promisify-es6')
|
||||
|
||||
const errCode = require('err-code')
|
||||
|
||||
module.exports = (node) => {
|
||||
const floodSub = new FloodSub(node)
|
||||
|
||||
node._floodSub = floodSub
|
||||
module.exports = (node, Pubsub) => {
|
||||
const pubsub = new Pubsub(node, { emitSelf: true })
|
||||
|
||||
return {
|
||||
subscribe: (topic, options, handler, callback) => {
|
||||
/**
|
||||
* Subscribe the given handler to a pubsub topic
|
||||
*
|
||||
* @param {string} topic
|
||||
* @param {function} handler The handler to subscribe
|
||||
* @param {object|null} [options]
|
||||
* @param {function} [callback] An optional callback
|
||||
*
|
||||
* @returns {Promise|void} A promise is returned if no callback is provided
|
||||
*
|
||||
* @example <caption>Subscribe a handler to a topic</caption>
|
||||
*
|
||||
* // `null` must be passed for options until subscribe is no longer using promisify
|
||||
* const handler = (message) => { }
|
||||
* await libp2p.subscribe(topic, handler, null)
|
||||
*
|
||||
* @example <caption>Use a callback instead of the Promise api</caption>
|
||||
*
|
||||
* // `options` may be passed or omitted when supplying a callback
|
||||
* const handler = (message) => { }
|
||||
* libp2p.subscribe(topic, handler, callback)
|
||||
*/
|
||||
subscribe: promisify((topic, handler, options, callback) => {
|
||||
if (typeof options === 'function') {
|
||||
callback = handler
|
||||
handler = options
|
||||
callback = options
|
||||
options = {}
|
||||
}
|
||||
|
||||
if (!node.isStarted() && !floodSub.started) {
|
||||
if (!node.isStarted() && !pubsub.started) {
|
||||
return nextTick(callback, errCode(new Error(messages.NOT_STARTED_YET), codes.PUBSUB_NOT_STARTED))
|
||||
}
|
||||
|
||||
function subscribe (cb) {
|
||||
if (floodSub.listenerCount(topic) === 0) {
|
||||
floodSub.subscribe(topic)
|
||||
if (pubsub.listenerCount(topic) === 0) {
|
||||
pubsub.subscribe(topic)
|
||||
}
|
||||
|
||||
floodSub.on(topic, handler)
|
||||
pubsub.on(topic, handler)
|
||||
nextTick(cb)
|
||||
}
|
||||
|
||||
subscribe(callback)
|
||||
},
|
||||
}),
|
||||
|
||||
unsubscribe: (topic, handler, callback) => {
|
||||
if (!node.isStarted() && !floodSub.started) {
|
||||
/**
|
||||
* Unsubscribes from a pubsub topic
|
||||
*
|
||||
* @param {string} topic
|
||||
* @param {function|null} handler The handler to unsubscribe from
|
||||
* @param {function} [callback] An optional callback
|
||||
*
|
||||
* @returns {Promise|void} A promise is returned if no callback is provided
|
||||
*
|
||||
* @example <caption>Unsubscribe a topic for all handlers</caption>
|
||||
*
|
||||
* // `null` must be passed until unsubscribe is no longer using promisify
|
||||
* await libp2p.unsubscribe(topic, null)
|
||||
*
|
||||
* @example <caption>Unsubscribe a topic for 1 handler</caption>
|
||||
*
|
||||
* await libp2p.unsubscribe(topic, handler)
|
||||
*
|
||||
* @example <caption>Use a callback instead of the Promise api</caption>
|
||||
*
|
||||
* libp2p.unsubscribe(topic, handler, callback)
|
||||
*/
|
||||
unsubscribe: promisify((topic, handler, callback) => {
|
||||
if (!node.isStarted() && !pubsub.started) {
|
||||
return nextTick(callback, errCode(new Error(messages.NOT_STARTED_YET), codes.PUBSUB_NOT_STARTED))
|
||||
}
|
||||
if (!handler && !callback) {
|
||||
floodSub.removeAllListeners(topic)
|
||||
|
||||
if (!handler) {
|
||||
pubsub.removeAllListeners(topic)
|
||||
} else {
|
||||
floodSub.removeListener(topic, handler)
|
||||
pubsub.removeListener(topic, handler)
|
||||
}
|
||||
|
||||
if (floodSub.listenerCount(topic) === 0) {
|
||||
floodSub.unsubscribe(topic)
|
||||
if (pubsub.listenerCount(topic) === 0) {
|
||||
pubsub.unsubscribe(topic)
|
||||
}
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
nextTick(() => callback())
|
||||
return nextTick(() => callback())
|
||||
}
|
||||
},
|
||||
|
||||
publish: (topic, data, callback) => {
|
||||
if (!node.isStarted() && !floodSub.started) {
|
||||
return Promise.resolve()
|
||||
}),
|
||||
|
||||
publish: promisify((topic, data, callback) => {
|
||||
if (!node.isStarted() && !pubsub.started) {
|
||||
return nextTick(callback, errCode(new Error(messages.NOT_STARTED_YET), codes.PUBSUB_NOT_STARTED))
|
||||
}
|
||||
|
||||
if (!Buffer.isBuffer(data)) {
|
||||
return nextTick(callback, errCode(new Error('data must be a Buffer'), 'ERR_DATA_IS_NOT_A_BUFFER'))
|
||||
try {
|
||||
data = Buffer.from(data)
|
||||
} catch (err) {
|
||||
return nextTick(callback, errCode(new Error('data must be convertible to a Buffer'), 'ERR_DATA_IS_NOT_VALID'))
|
||||
}
|
||||
|
||||
floodSub.publish(topic, data, callback)
|
||||
},
|
||||
pubsub.publish(topic, data, callback)
|
||||
}),
|
||||
|
||||
ls: (callback) => {
|
||||
if (!node.isStarted() && !floodSub.started) {
|
||||
ls: promisify((callback) => {
|
||||
if (!node.isStarted() && !pubsub.started) {
|
||||
return nextTick(callback, errCode(new Error(messages.NOT_STARTED_YET), codes.PUBSUB_NOT_STARTED))
|
||||
}
|
||||
|
||||
const subscriptions = Array.from(floodSub.subscriptions)
|
||||
const subscriptions = Array.from(pubsub.subscriptions)
|
||||
|
||||
nextTick(() => callback(null, subscriptions))
|
||||
},
|
||||
}),
|
||||
|
||||
peers: (topic, callback) => {
|
||||
if (!node.isStarted() && !floodSub.started) {
|
||||
peers: promisify((topic, callback) => {
|
||||
if (!node.isStarted() && !pubsub.started) {
|
||||
return nextTick(callback, errCode(new Error(messages.NOT_STARTED_YET), codes.PUBSUB_NOT_STARTED))
|
||||
}
|
||||
|
||||
@ -86,15 +132,19 @@ module.exports = (node) => {
|
||||
topic = null
|
||||
}
|
||||
|
||||
const peers = Array.from(floodSub.peers.values())
|
||||
const peers = Array.from(pubsub.peers.values())
|
||||
.filter((peer) => topic ? peer.topics.has(topic) : true)
|
||||
.map((peer) => peer.info.id.toB58String())
|
||||
|
||||
nextTick(() => callback(null, peers))
|
||||
},
|
||||
}),
|
||||
|
||||
setMaxListeners (n) {
|
||||
return floodSub.setMaxListeners(n)
|
||||
}
|
||||
return pubsub.setMaxListeners(n)
|
||||
},
|
||||
|
||||
start: promisify((cb) => pubsub.start(cb)),
|
||||
|
||||
stop: promisify((cb) => pubsub.stop(cb))
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ const tryEcho = require('./utils/try-echo')
|
||||
const echo = require('./utils/echo')
|
||||
|
||||
describe('circuit relay', () => {
|
||||
let handlerSpies = []
|
||||
const handlerSpies = []
|
||||
let relayNode1
|
||||
let relayNode2
|
||||
let nodeWS1
|
||||
|
@ -33,7 +33,7 @@ describe('configuration', () => {
|
||||
expect(() => {
|
||||
validateConfig({
|
||||
modules: {
|
||||
transport: [ WS ]
|
||||
transport: [WS]
|
||||
}
|
||||
})
|
||||
}).to.throw()
|
||||
@ -52,7 +52,7 @@ describe('configuration', () => {
|
||||
validateConfig({
|
||||
peerInfo,
|
||||
modules: {
|
||||
transport: [ ]
|
||||
transport: []
|
||||
}
|
||||
})
|
||||
}).to.throw('ERROR_EMPTY')
|
||||
@ -62,8 +62,8 @@ describe('configuration', () => {
|
||||
const options = {
|
||||
peerInfo,
|
||||
modules: {
|
||||
transport: [ WS ],
|
||||
peerDiscovery: [ Bootstrap ],
|
||||
transport: [WS],
|
||||
peerDiscovery: [Bootstrap],
|
||||
dht: DHT
|
||||
}
|
||||
}
|
||||
@ -74,16 +74,16 @@ describe('configuration', () => {
|
||||
minPeers: 25
|
||||
},
|
||||
modules: {
|
||||
transport: [ WS ],
|
||||
peerDiscovery: [ Bootstrap ],
|
||||
transport: [WS],
|
||||
peerDiscovery: [Bootstrap],
|
||||
dht: DHT
|
||||
},
|
||||
config: {
|
||||
peerDiscovery: {
|
||||
autoDial: true
|
||||
},
|
||||
EXPERIMENTAL: {
|
||||
pubsub: false
|
||||
pubsub: {
|
||||
enabled: false
|
||||
},
|
||||
dht: {
|
||||
kBucketSize: 20,
|
||||
@ -112,8 +112,8 @@ describe('configuration', () => {
|
||||
const options = {
|
||||
peerInfo,
|
||||
modules: {
|
||||
transport: [ WS ],
|
||||
peerDiscovery: [ Bootstrap ],
|
||||
transport: [WS],
|
||||
peerDiscovery: [Bootstrap],
|
||||
dht: DHT
|
||||
},
|
||||
config: {
|
||||
@ -132,8 +132,8 @@ describe('configuration', () => {
|
||||
minPeers: 25
|
||||
},
|
||||
modules: {
|
||||
transport: [ WS ],
|
||||
peerDiscovery: [ Bootstrap ],
|
||||
transport: [WS],
|
||||
peerDiscovery: [Bootstrap],
|
||||
dht: DHT
|
||||
},
|
||||
config: {
|
||||
@ -144,8 +144,8 @@ describe('configuration', () => {
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
EXPERIMENTAL: {
|
||||
pubsub: false
|
||||
pubsub: {
|
||||
enabled: false
|
||||
},
|
||||
dht: {
|
||||
kBucketSize: 20,
|
||||
@ -181,8 +181,8 @@ describe('configuration', () => {
|
||||
dialTimeout: 30e3
|
||||
},
|
||||
modules: {
|
||||
transport: [ WS ],
|
||||
peerDiscovery: [ ]
|
||||
transport: [WS],
|
||||
peerDiscovery: []
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,10 +204,10 @@ describe('configuration', () => {
|
||||
const options = {
|
||||
peerInfo,
|
||||
modules: {
|
||||
transport: [ WS ],
|
||||
peerDiscovery: [ Bootstrap ],
|
||||
peerRouting: [ peerRouter ],
|
||||
contentRouting: [ contentRouter ],
|
||||
transport: [WS],
|
||||
peerDiscovery: [Bootstrap],
|
||||
peerRouting: [peerRouter],
|
||||
contentRouting: [contentRouter],
|
||||
dht: DHT
|
||||
},
|
||||
config: {
|
||||
@ -221,8 +221,8 @@ describe('configuration', () => {
|
||||
}
|
||||
|
||||
expect(validateConfig(options).modules).to.deep.include({
|
||||
peerRouting: [ peerRouter ],
|
||||
contentRouting: [ contentRouter ]
|
||||
peerRouting: [peerRouter],
|
||||
contentRouting: [contentRouter]
|
||||
})
|
||||
})
|
||||
|
||||
@ -230,7 +230,7 @@ describe('configuration', () => {
|
||||
const options = {
|
||||
peerInfo,
|
||||
modules: {
|
||||
transport: [ WS ]
|
||||
transport: [WS]
|
||||
},
|
||||
config: {
|
||||
dht: {
|
||||
@ -269,8 +269,8 @@ describe('configuration', () => {
|
||||
dht: DHT
|
||||
},
|
||||
config: {
|
||||
EXPERIMENTAL: {
|
||||
pubsub: false
|
||||
pubsub: {
|
||||
enabled: false
|
||||
},
|
||||
peerDiscovery: {
|
||||
autoDial: true
|
||||
|
@ -121,8 +121,9 @@ describe('.contentRouting', () => {
|
||||
const cid = new CID('QmTp9VkYvnHyrqKQuFPiuZkiX9gPcqj6x5LJ1rmWuSnnnn')
|
||||
|
||||
nodeE.contentRouting.findProviders(cid, { maxTimeout: 5000 }, (err, providers) => {
|
||||
expect(err).to.not.exist()
|
||||
expect(providers).to.have.length(0)
|
||||
expect(err).to.exist()
|
||||
expect(err.code).to.eql('ERR_NOT_FOUND')
|
||||
expect(providers).to.not.exist()
|
||||
done()
|
||||
})
|
||||
})
|
||||
@ -150,7 +151,7 @@ describe('.contentRouting', () => {
|
||||
nodeA = new Node({
|
||||
peerInfo,
|
||||
modules: {
|
||||
contentRouting: [ delegate ]
|
||||
contentRouting: [delegate]
|
||||
},
|
||||
config: {
|
||||
dht: {
|
||||
@ -185,19 +186,10 @@ describe('.contentRouting', () => {
|
||||
it('should be able to register as a provider', (done) => {
|
||||
const cid = new CID('QmU621oD8AhHw6t25vVyfYKmL9VV3PTgc52FngEhTGACFB')
|
||||
const mockApi = nock('http://0.0.0.0:60197')
|
||||
// mock the swarm connect
|
||||
.post('/api/v0/swarm/connect')
|
||||
.query({
|
||||
arg: `/ip4/0.0.0.0/tcp/60194/p2p-circuit/ipfs/${nodeA.peerInfo.id.toB58String()}`,
|
||||
'stream-channels': true
|
||||
})
|
||||
.reply(200, {
|
||||
Strings: [`connect ${nodeA.peerInfo.id.toB58String()} success`]
|
||||
}, ['Content-Type', 'application/json'])
|
||||
// mock the refs call
|
||||
.post('/api/v0/refs')
|
||||
.query({
|
||||
recursive: true,
|
||||
recursive: false,
|
||||
arg: cid.toBaseEncodedString(),
|
||||
'stream-channels': true
|
||||
})
|
||||
@ -216,10 +208,11 @@ describe('.contentRouting', () => {
|
||||
it('should handle errors when registering as a provider', (done) => {
|
||||
const cid = new CID('QmU621oD8AhHw6t25vVyfYKmL9VV3PTgc52FngEhTGACFB')
|
||||
const mockApi = nock('http://0.0.0.0:60197')
|
||||
// mock the swarm connect
|
||||
.post('/api/v0/swarm/connect')
|
||||
// mock the refs call
|
||||
.post('/api/v0/refs')
|
||||
.query({
|
||||
arg: `/ip4/0.0.0.0/tcp/60194/p2p-circuit/ipfs/${nodeA.peerInfo.id.toB58String()}`,
|
||||
recursive: false,
|
||||
arg: cid.toBaseEncodedString(),
|
||||
'stream-channels': true
|
||||
})
|
||||
.reply(502, 'Bad Gateway', ['Content-Type', 'application/json'])
|
||||
@ -251,7 +244,7 @@ describe('.contentRouting', () => {
|
||||
timeout: '1000ms',
|
||||
'stream-channels': true
|
||||
})
|
||||
.reply(200, `{"Extra":"","ID":"QmWKqWXCtRXEeCQTo3FoZ7g4AfnGiauYYiczvNxFCHicbB","Responses":[{"Addrs":["/ip4/0.0.0.0/tcp/0"],"ID":"${provider}"}],"Type":1}\n`, [
|
||||
.reply(200, `{"Extra":"","ID":"QmWKqWXCtRXEeCQTo3FoZ7g4AfnGiauYYiczvNxFCHicbB","Responses":[{"Addrs":["/ip4/0.0.0.0/tcp/0"],"ID":"${provider}"}],"Type":4}\n`, [
|
||||
'Content-Type', 'application/json',
|
||||
'X-Chunked-Output', '1'
|
||||
])
|
||||
@ -308,7 +301,7 @@ describe('.contentRouting', () => {
|
||||
nodeA = new Node({
|
||||
peerInfo,
|
||||
modules: {
|
||||
contentRouting: [ delegate ]
|
||||
contentRouting: [delegate]
|
||||
},
|
||||
config: {
|
||||
relay: {
|
||||
|
@ -19,8 +19,8 @@ describe('libp2p creation', () => {
|
||||
it('should be able to start and stop successfully', (done) => {
|
||||
createNode([], {
|
||||
config: {
|
||||
EXPERIMENTAL: {
|
||||
pubsub: true
|
||||
pubsub: {
|
||||
enabled: true
|
||||
},
|
||||
dht: {
|
||||
enabled: true
|
||||
@ -29,10 +29,10 @@ describe('libp2p creation', () => {
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
let sw = node._switch
|
||||
let cm = node.connectionManager
|
||||
let dht = node._dht
|
||||
let pub = node._floodSub
|
||||
const sw = node._switch
|
||||
const cm = node.connectionManager
|
||||
const dht = node._dht
|
||||
const pub = node.pubsub
|
||||
|
||||
sinon.spy(sw, 'start')
|
||||
sinon.spy(cm, 'start')
|
||||
@ -77,13 +77,13 @@ describe('libp2p creation', () => {
|
||||
it('should not create disabled modules', (done) => {
|
||||
createNode([], {
|
||||
config: {
|
||||
EXPERIMENTAL: {
|
||||
pubsub: false
|
||||
pubsub: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
expect(node._floodSub).to.not.exist()
|
||||
expect(node._pubsub).to.not.exist()
|
||||
done()
|
||||
})
|
||||
})
|
||||
@ -113,7 +113,7 @@ describe('libp2p creation', () => {
|
||||
this.timeout(10e3)
|
||||
createLibp2p({
|
||||
modules: {
|
||||
transport: [ WS ]
|
||||
transport: [WS]
|
||||
}
|
||||
}, (err, libp2p) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -130,7 +130,7 @@ describe('libp2p creation', () => {
|
||||
createLibp2p({
|
||||
peerInfo,
|
||||
modules: {
|
||||
transport: [ WS ]
|
||||
transport: [WS]
|
||||
}
|
||||
}, (err, libp2p) => {
|
||||
expect(err).to.not.exist()
|
||||
|
@ -60,9 +60,9 @@ describe('libp2p state machine (fsm)', () => {
|
||||
node.once('stop', done)
|
||||
|
||||
// stop the stopped node
|
||||
node.stop()
|
||||
node.stop(() => {})
|
||||
})
|
||||
node.start()
|
||||
node.start(() => {})
|
||||
})
|
||||
|
||||
it('should callback with an error when it occurs on stop', (done) => {
|
||||
@ -79,7 +79,7 @@ describe('libp2p state machine (fsm)', () => {
|
||||
expect(2).checks(done)
|
||||
|
||||
sinon.stub(node._switch, 'stop').callsArgWith(0, error)
|
||||
node.start()
|
||||
node.start(() => {})
|
||||
})
|
||||
|
||||
it('should noop when starting a started node', (done) => {
|
||||
@ -89,17 +89,17 @@ describe('libp2p state machine (fsm)', () => {
|
||||
})
|
||||
node.once('start', () => {
|
||||
node.once('stop', done)
|
||||
node.stop()
|
||||
node.stop(() => {})
|
||||
})
|
||||
|
||||
// start the started node
|
||||
node.start()
|
||||
node.start(() => {})
|
||||
})
|
||||
node.start()
|
||||
node.start(() => {})
|
||||
})
|
||||
|
||||
it('should error on start with no transports', (done) => {
|
||||
let transports = node._modules.transport
|
||||
const transports = node._modules.transport
|
||||
node._modules.transport = null
|
||||
|
||||
node.on('stop', () => {
|
||||
@ -115,7 +115,7 @@ describe('libp2p state machine (fsm)', () => {
|
||||
|
||||
expect(2).checks(done)
|
||||
|
||||
node.start()
|
||||
node.start(() => {})
|
||||
})
|
||||
|
||||
it('should not start if the switch fails to start', (done) => {
|
||||
@ -150,7 +150,7 @@ describe('libp2p state machine (fsm)', () => {
|
||||
})
|
||||
})
|
||||
|
||||
node.stop()
|
||||
node.stop(() => {})
|
||||
})
|
||||
|
||||
it('should not dial (fsm) when the node is stopped', (done) => {
|
||||
@ -162,7 +162,7 @@ describe('libp2p state machine (fsm)', () => {
|
||||
})
|
||||
})
|
||||
|
||||
node.stop()
|
||||
node.stop(() => {})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -72,7 +72,7 @@ describe('peer discovery', () => {
|
||||
stop: sinon.stub().callsArg(0)
|
||||
}
|
||||
|
||||
const options = { modules: { peerDiscovery: [ mockDiscovery ] } }
|
||||
const options = { modules: { peerDiscovery: [mockDiscovery] } }
|
||||
|
||||
createNode(['/ip4/0.0.0.0/tcp/0'], options, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -95,7 +95,7 @@ describe('peer discovery', () => {
|
||||
|
||||
const MockDiscovery = sinon.stub().returns(mockDiscovery)
|
||||
|
||||
const options = { modules: { peerDiscovery: [ MockDiscovery ] } }
|
||||
const options = { modules: { peerDiscovery: [MockDiscovery] } }
|
||||
|
||||
createNode(['/ip4/0.0.0.0/tcp/0'], options, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -120,7 +120,7 @@ describe('peer discovery', () => {
|
||||
const enabled = sinon.stub().returns(true)
|
||||
|
||||
const options = {
|
||||
modules: { peerDiscovery: [ mockDiscovery ] },
|
||||
modules: { peerDiscovery: [mockDiscovery] },
|
||||
config: {
|
||||
peerDiscovery: {
|
||||
mockDiscovery: {
|
||||
@ -156,7 +156,7 @@ describe('peer discovery', () => {
|
||||
const disabled = sinon.stub().returns(false)
|
||||
|
||||
const options = {
|
||||
modules: { peerDiscovery: [ mockDiscovery ] },
|
||||
modules: { peerDiscovery: [mockDiscovery] },
|
||||
config: {
|
||||
peerDiscovery: {
|
||||
mockDiscovery: {
|
||||
@ -192,7 +192,7 @@ describe('peer discovery', () => {
|
||||
MockDiscovery.tag = 'mockDiscovery'
|
||||
|
||||
const options = {
|
||||
modules: { peerDiscovery: [ MockDiscovery ] },
|
||||
modules: { peerDiscovery: [MockDiscovery] },
|
||||
config: {
|
||||
peerDiscovery: {
|
||||
mockDiscovery: {
|
||||
@ -228,7 +228,7 @@ describe('peer discovery', () => {
|
||||
}
|
||||
|
||||
const options = {
|
||||
modules: { peerDiscovery: [ mockDiscovery ] },
|
||||
modules: { peerDiscovery: [mockDiscovery] },
|
||||
config: {
|
||||
peerDiscovery: {
|
||||
mockDiscovery: { enabled: true }
|
||||
@ -294,7 +294,7 @@ describe('peer discovery', () => {
|
||||
})
|
||||
|
||||
it('find peers', function (done) {
|
||||
let expectedPeers = new Set([
|
||||
const expectedPeers = new Set([
|
||||
nodeB.peerInfo.id.toB58String(),
|
||||
nodeC.peerInfo.id.toB58String()
|
||||
])
|
||||
@ -332,7 +332,7 @@ describe('peer discovery', () => {
|
||||
|
||||
it('find peers', function (done) {
|
||||
this.timeout(20e3)
|
||||
let expectedPeers = new Set([
|
||||
const expectedPeers = new Set([
|
||||
nodeB.peerInfo.id.toB58String(),
|
||||
nodeC.peerInfo.id.toB58String()
|
||||
])
|
||||
@ -374,7 +374,7 @@ describe('peer discovery', () => {
|
||||
})
|
||||
|
||||
it('find peers', function (done) {
|
||||
let expectedPeers = new Set([
|
||||
const expectedPeers = new Set([
|
||||
nodeB.peerInfo.id.toB58String(),
|
||||
nodeC.peerInfo.id.toB58String()
|
||||
])
|
||||
@ -421,7 +421,7 @@ describe('peer discovery', () => {
|
||||
})
|
||||
|
||||
it('find peers through the dht', function (done) {
|
||||
let expectedPeers = new Set([
|
||||
const expectedPeers = new Set([
|
||||
nodeB.peerInfo.id.toB58String(),
|
||||
nodeC.peerInfo.id.toB58String()
|
||||
])
|
||||
|
@ -105,7 +105,7 @@ describe('.peerRouting', () => {
|
||||
})
|
||||
createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
peerRouting: [ delegate ]
|
||||
peerRouting: [delegate]
|
||||
},
|
||||
config: {
|
||||
dht: {
|
||||
@ -211,7 +211,7 @@ describe('.peerRouting', () => {
|
||||
})
|
||||
createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
peerRouting: [ delegate ]
|
||||
peerRouting: [delegate]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
|
@ -24,7 +24,7 @@ describe('private network', () => {
|
||||
config = {
|
||||
peerInfo,
|
||||
modules: {
|
||||
transport: [ WS ],
|
||||
transport: [WS],
|
||||
dht: DHT
|
||||
}
|
||||
}
|
||||
@ -50,14 +50,14 @@ describe('private network', () => {
|
||||
|
||||
it('should create a libp2p node with a provided protector', () => {
|
||||
let node
|
||||
let protector = {
|
||||
const protector = {
|
||||
psk: '123',
|
||||
tag: '/psk/1.0.0',
|
||||
protect: () => { }
|
||||
}
|
||||
|
||||
expect(() => {
|
||||
let options = defaultsDeep(config, {
|
||||
const options = defaultsDeep(config, {
|
||||
modules: {
|
||||
connProtector: protector
|
||||
}
|
||||
@ -71,7 +71,7 @@ describe('private network', () => {
|
||||
|
||||
it('should throw an error if the protector does not have a protect method', () => {
|
||||
expect(() => {
|
||||
let options = defaultsDeep(config, {
|
||||
const options = defaultsDeep(config, {
|
||||
modules: {
|
||||
connProtector: { }
|
||||
}
|
||||
|
@ -11,23 +11,31 @@ const parallel = require('async/parallel')
|
||||
const series = require('async/series')
|
||||
const _times = require('lodash.times')
|
||||
|
||||
const Floodsub = require('libp2p-floodsub')
|
||||
const mergeOptions = require('merge-options')
|
||||
|
||||
const { codes } = require('../src/errors')
|
||||
const createNode = require('./utils/create-node')
|
||||
|
||||
function startTwo (callback) {
|
||||
function startTwo (options, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options
|
||||
options = {}
|
||||
}
|
||||
|
||||
const tasks = _times(2, () => (cb) => {
|
||||
createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
createNode('/ip4/0.0.0.0/tcp/0', mergeOptions({
|
||||
config: {
|
||||
peerDiscovery: {
|
||||
mdns: {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
EXPERIMENTAL: {
|
||||
pubsub: true
|
||||
pubsub: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}, (err, node) => {
|
||||
}, options), (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
node.start((err) => cb(err, node))
|
||||
})
|
||||
@ -47,22 +55,17 @@ function stopTwo (nodes, callback) {
|
||||
], callback)
|
||||
}
|
||||
|
||||
// There is a vast test suite on PubSub through js-ipfs
|
||||
// https://github.com/ipfs/interface-ipfs-core/blob/master/js/src/pubsub.js
|
||||
// and libp2p-floodsub itself
|
||||
// https://github.com/libp2p/js-libp2p-floodsub/tree/master/test
|
||||
// TODO: consider if all or some of those should come here
|
||||
describe('.pubsub', () => {
|
||||
describe('.pubsub on (default)', (done) => {
|
||||
describe('.pubsub on (default)', () => {
|
||||
it('start two nodes and send one message, then unsubscribe', (done) => {
|
||||
// Check the final series error, and the publish handler
|
||||
expect(2).checks(done)
|
||||
|
||||
let nodes
|
||||
const data = Buffer.from('test')
|
||||
const data = 'test'
|
||||
const handler = (msg) => {
|
||||
// verify the data is correct and mark the expect
|
||||
expect(msg.data).to.eql(data).mark()
|
||||
expect(msg.data.toString()).to.eql(data).mark()
|
||||
}
|
||||
|
||||
series([
|
||||
@ -72,15 +75,11 @@ describe('.pubsub', () => {
|
||||
cb(err)
|
||||
}),
|
||||
// subscribe on the first
|
||||
(cb) => nodes[0].pubsub.subscribe('pubsub', handler, cb),
|
||||
(cb) => nodes[0].pubsub.subscribe('pubsub', handler, null, cb),
|
||||
// Wait a moment before publishing
|
||||
(cb) => setTimeout(cb, 500),
|
||||
// publish on the second
|
||||
(cb) => nodes[1].pubsub.publish('pubsub', data, cb),
|
||||
// ls subscripts
|
||||
(cb) => nodes[1].pubsub.ls(cb),
|
||||
// get subscribed peers
|
||||
(cb) => nodes[1].pubsub.peers('pubsub', cb),
|
||||
// Wait a moment before unsubscribing
|
||||
(cb) => setTimeout(cb, 500),
|
||||
// unsubscribe on the first
|
||||
@ -110,6 +109,85 @@ describe('.pubsub', () => {
|
||||
cb(err)
|
||||
}),
|
||||
// subscribe on the first
|
||||
(cb) => nodes[0].pubsub.subscribe('pubsub', handler, {}, cb),
|
||||
// Wait a moment before publishing
|
||||
(cb) => setTimeout(cb, 500),
|
||||
// publish on the second
|
||||
(cb) => nodes[1].pubsub.publish('pubsub', data, cb),
|
||||
// ls subscripts
|
||||
(cb) => nodes[1].pubsub.ls(cb),
|
||||
// get subscribed peers
|
||||
(cb) => nodes[1].pubsub.peers('pubsub', cb),
|
||||
// Wait a moment before unsubscribing
|
||||
(cb) => setTimeout(cb, 500),
|
||||
// unsubscribe from all
|
||||
(cb) => nodes[0].pubsub.unsubscribe('pubsub', null, cb),
|
||||
// Verify unsubscribed
|
||||
(cb) => {
|
||||
nodes[0].pubsub.ls((err, topics) => {
|
||||
expect(topics.length).to.eql(0).mark()
|
||||
cb(err)
|
||||
})
|
||||
},
|
||||
// Stop both nodes
|
||||
(cb) => stopTwo(nodes, cb)
|
||||
], (err) => {
|
||||
// Verify there was no error, and mark the expect
|
||||
expect(err).to.not.exist().mark()
|
||||
})
|
||||
})
|
||||
it('publish should fail if data is not a buffer nor a string', (done) => {
|
||||
createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
config: {
|
||||
peerDiscovery: {
|
||||
mdns: {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
pubsub: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
node.start((err) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
node.pubsub.publish('pubsub', 10, (err) => {
|
||||
expect(err).to.exist()
|
||||
expect(err.code).to.equal('ERR_DATA_IS_NOT_VALID')
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('.pubsub on using floodsub', () => {
|
||||
it('start two nodes and send one message, then unsubscribe', (done) => {
|
||||
// Check the final series error, and the publish handler
|
||||
expect(2).checks(done)
|
||||
|
||||
let nodes
|
||||
const data = Buffer.from('test')
|
||||
const handler = (msg) => {
|
||||
// verify the data is correct and mark the expect
|
||||
expect(msg.data).to.eql(data).mark()
|
||||
}
|
||||
|
||||
series([
|
||||
// Start the nodes
|
||||
(cb) => startTwo({
|
||||
modules: {
|
||||
pubsub: Floodsub
|
||||
}
|
||||
}, (err, _nodes) => {
|
||||
nodes = _nodes
|
||||
cb(err)
|
||||
}),
|
||||
// subscribe on the first
|
||||
(cb) => nodes[0].pubsub.subscribe('pubsub', handler, cb),
|
||||
// Wait a moment before publishing
|
||||
(cb) => setTimeout(cb, 500),
|
||||
@ -118,11 +196,45 @@ describe('.pubsub', () => {
|
||||
// Wait a moment before unsubscribing
|
||||
(cb) => setTimeout(cb, 500),
|
||||
// unsubscribe on the first
|
||||
(cb) => {
|
||||
nodes[0].pubsub.unsubscribe('pubsub')
|
||||
// Wait a moment to make sure the ubsubscribe-from-all worked
|
||||
setTimeout(cb, 500)
|
||||
},
|
||||
(cb) => nodes[0].pubsub.unsubscribe('pubsub', handler, cb),
|
||||
// Stop both nodes
|
||||
(cb) => stopTwo(nodes, cb)
|
||||
], (err) => {
|
||||
// Verify there was no error, and mark the expect
|
||||
expect(err).to.not.exist().mark()
|
||||
})
|
||||
})
|
||||
it('start two nodes and send one message, then unsubscribe without handler', (done) => {
|
||||
// Check the final series error, and the publish handler
|
||||
expect(3).checks(done)
|
||||
|
||||
let nodes
|
||||
const data = Buffer.from('test')
|
||||
const handler = (msg) => {
|
||||
// verify the data is correct and mark the expect
|
||||
expect(msg.data).to.eql(data).mark()
|
||||
}
|
||||
|
||||
series([
|
||||
// Start the nodes
|
||||
(cb) => startTwo({
|
||||
modules: {
|
||||
pubsub: Floodsub
|
||||
}
|
||||
}, (err, _nodes) => {
|
||||
nodes = _nodes
|
||||
cb(err)
|
||||
}),
|
||||
// subscribe on the first
|
||||
(cb) => nodes[0].pubsub.subscribe('pubsub', handler, cb),
|
||||
// Wait a moment before publishing
|
||||
(cb) => setTimeout(cb, 500),
|
||||
// publish on the second
|
||||
(cb) => nodes[1].pubsub.publish('pubsub', data, cb),
|
||||
// Wait a moment before unsubscribing
|
||||
(cb) => setTimeout(cb, 500),
|
||||
// unsubscribe from all
|
||||
(cb) => nodes[0].pubsub.unsubscribe('pubsub', null, cb),
|
||||
// Verify unsubscribed
|
||||
(cb) => {
|
||||
nodes[0].pubsub.ls((err, topics) => {
|
||||
@ -145,9 +257,12 @@ describe('.pubsub', () => {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
EXPERIMENTAL: {
|
||||
pubsub: true
|
||||
pubsub: {
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
pubsub: Floodsub
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -155,9 +270,9 @@ describe('.pubsub', () => {
|
||||
node.start((err) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
node.pubsub.publish('pubsub', 'datastr', (err) => {
|
||||
node.pubsub.publish('pubsub', 10, (err) => {
|
||||
expect(err).to.exist()
|
||||
expect(err.code).to.equal('ERR_DATA_IS_NOT_A_BUFFER')
|
||||
expect(err.code).to.equal('ERR_DATA_IS_NOT_VALID')
|
||||
|
||||
done()
|
||||
})
|
||||
@ -174,9 +289,6 @@ describe('.pubsub', () => {
|
||||
mdns: {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
EXPERIMENTAL: {
|
||||
pubsub: false
|
||||
}
|
||||
}
|
||||
}, (err, node) => {
|
||||
@ -198,8 +310,8 @@ describe('.pubsub', () => {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
EXPERIMENTAL: {
|
||||
pubsub: true
|
||||
pubsub: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}, (err, node) => {
|
||||
|
@ -36,7 +36,7 @@ describe('stream muxing', () => {
|
||||
parallel([
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ SPDY ]
|
||||
streamMuxer: [SPDY]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -46,7 +46,7 @@ describe('stream muxing', () => {
|
||||
}),
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ SPDY ]
|
||||
streamMuxer: [SPDY]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -72,7 +72,7 @@ describe('stream muxing', () => {
|
||||
parallel([
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ Mplex ]
|
||||
streamMuxer: [Mplex]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -82,7 +82,7 @@ describe('stream muxing', () => {
|
||||
}),
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ Mplex ]
|
||||
streamMuxer: [Mplex]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -108,7 +108,7 @@ describe('stream muxing', () => {
|
||||
parallel([
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ pMplex ]
|
||||
streamMuxer: [pMplex]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -118,7 +118,7 @@ describe('stream muxing', () => {
|
||||
}),
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ pMplex ]
|
||||
streamMuxer: [pMplex]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -146,7 +146,7 @@ describe('stream muxing', () => {
|
||||
parallel([
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ Mplex ]
|
||||
streamMuxer: [Mplex]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -156,7 +156,7 @@ describe('stream muxing', () => {
|
||||
}),
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ SPDY, Mplex ]
|
||||
streamMuxer: [SPDY, Mplex]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -184,7 +184,7 @@ describe('stream muxing', () => {
|
||||
parallel([
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ Mplex ]
|
||||
streamMuxer: [Mplex]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -194,7 +194,7 @@ describe('stream muxing', () => {
|
||||
}),
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ pMplex ]
|
||||
streamMuxer: [pMplex]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -222,7 +222,7 @@ describe('stream muxing', () => {
|
||||
parallel([
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ SPDY, Mplex ]
|
||||
streamMuxer: [SPDY, Mplex]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -232,7 +232,7 @@ describe('stream muxing', () => {
|
||||
}),
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ Mplex, SPDY ]
|
||||
streamMuxer: [Mplex, SPDY]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -260,7 +260,7 @@ describe('stream muxing', () => {
|
||||
parallel([
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ SPDY, pMplex ]
|
||||
streamMuxer: [SPDY, pMplex]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -270,7 +270,7 @@ describe('stream muxing', () => {
|
||||
}),
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ pMplex, SPDY ]
|
||||
streamMuxer: [pMplex, SPDY]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -298,7 +298,7 @@ describe('stream muxing', () => {
|
||||
parallel([
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ SPDY ]
|
||||
streamMuxer: [SPDY]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
@ -308,7 +308,7 @@ describe('stream muxing', () => {
|
||||
}),
|
||||
(cb) => createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
modules: {
|
||||
streamMuxer: [ Mplex ]
|
||||
streamMuxer: [Mplex]
|
||||
}
|
||||
}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
|
@ -55,7 +55,7 @@ describe('transports', () => {
|
||||
const b = new Node({
|
||||
peerInfo: peerInfo,
|
||||
modules: {
|
||||
streamMuxer: [ Mplex ]
|
||||
streamMuxer: [Mplex]
|
||||
}
|
||||
})
|
||||
expect(b._modules.streamMuxer).to.eql([require('pull-mplex')])
|
||||
|
@ -8,6 +8,7 @@ const SPDY = require('libp2p-spdy')
|
||||
const MPLEX = require('libp2p-mplex')
|
||||
const PULLMPLEX = require('pull-mplex')
|
||||
const KadDHT = require('libp2p-kad-dht')
|
||||
const GossipSub = require('libp2p-gossipsub')
|
||||
const SECIO = require('libp2p-secio')
|
||||
const defaultsDeep = require('@nodeutils/defaults-deep')
|
||||
const libp2p = require('../..')
|
||||
@ -57,7 +58,8 @@ class Node extends libp2p {
|
||||
wsStar.discovery,
|
||||
Bootstrap
|
||||
],
|
||||
dht: KadDHT
|
||||
dht: KadDHT,
|
||||
pubsub: GossipSub
|
||||
},
|
||||
config: {
|
||||
peerDiscovery: {
|
||||
@ -88,8 +90,8 @@ class Node extends libp2p {
|
||||
},
|
||||
enabled: false
|
||||
},
|
||||
EXPERIMENTAL: {
|
||||
pubsub: false
|
||||
pubsub: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ const WS = require('libp2p-websockets')
|
||||
const Bootstrap = require('libp2p-bootstrap')
|
||||
const SPDY = require('libp2p-spdy')
|
||||
const KadDHT = require('libp2p-kad-dht')
|
||||
const GossipSub = require('libp2p-gossipsub')
|
||||
const MPLEX = require('libp2p-mplex')
|
||||
const PULLMPLEX = require('pull-mplex')
|
||||
const SECIO = require('libp2p-secio')
|
||||
@ -52,7 +53,8 @@ class Node extends libp2p {
|
||||
MulticastDNS,
|
||||
Bootstrap
|
||||
],
|
||||
dht: KadDHT
|
||||
dht: KadDHT,
|
||||
pubsub: GossipSub
|
||||
},
|
||||
config: {
|
||||
peerDiscovery: {
|
||||
@ -81,8 +83,8 @@ class Node extends libp2p {
|
||||
},
|
||||
enabled: true
|
||||
},
|
||||
EXPERIMENTAL: {
|
||||
pubsub: false
|
||||
pubsub: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user