diff --git a/.aegir.js b/.aegir.js index 7e21003e61..33a98f8a6d 100644 --- a/.aegir.js +++ b/.aegir.js @@ -1,7 +1,6 @@ 'use strict' const pull = require('pull-stream') -const parallel = require('async/parallel') const WebSocketStarRendezvous = require('libp2p-websocket-star-rendezvous') const sigServer = require('libp2p-webrtc-star/src/sig-server') @@ -15,68 +14,46 @@ const { let wrtcRendezvous let wsRendezvous let node +let peerInfo -const before = (done) => { - parallel([ - (cb) => { - sigServer.start({ - port: WRTC_RENDEZVOUS_MULTIADDR.nodeAddress().port - // cryptoChallenge: true TODO: needs https://github.com/libp2p/js-libp2p-webrtc-star/issues/128 - }) - .then(server => { - wrtcRendezvous = server - cb() - }) - .catch(cb) - }, - (cb) => { - WebSocketStarRendezvous.start({ - port: WS_RENDEZVOUS_MULTIADDR.nodeAddress().port, - refreshPeerListIntervalMS: 1000, - strictMultiaddr: false, - cryptoChallenge: true - }, (err, _server) => { - if (err) { - return cb(err) - } - wsRendezvous = _server - cb() - }) - }, - (cb) => { - getPeerRelay((err, peerInfo) => { - if (err) { - return done(err) - } - - node = new Node({ - peerInfo, - config: { - relay: { - enabled: true, - hop: { - enabled: true, - active: true - } - } - } - }) +const before = async () => { + [wrtcRendezvous, wsRendezvous, peerInfo] = await Promise.all([ + sigServer.start({ + port: WRTC_RENDEZVOUS_MULTIADDR.nodeAddress().port + // cryptoChallenge: true TODO: needs https://github.com/libp2p/js-libp2p-webrtc-star/issues/128 + }), + WebSocketStarRendezvous.start({ + port: WS_RENDEZVOUS_MULTIADDR.nodeAddress().port, + refreshPeerListIntervalMS: 1000, + strictMultiaddr: false, + cryptoChallenge: true + }), + getPeerRelay() + ]) - node.handle('/echo/1.0.0', (protocol, conn) => pull(conn, conn)) - node.start(cb) - }) + node = new Node({ + peerInfo, + config: { + relay: { + enabled: true, + hop: { + enabled: true, + active: true + } + } } - ], done) + }) + + node.handle('/echo/1.0.0', (protocol, conn) => pull(conn, conn)) + await node.start() } -const after = (done) => { - setTimeout(() => - parallel([ - (cb) => wrtcRendezvous.stop().then(cb).catch(cb), - ...[node, wsRendezvous].map((s) => (cb) => s.stop(cb)), - ], done), - 2000 - ) +const after = () => { + return Promise.all([ + wrtcRendezvous.stop(), + wsRendezvous.stop(), + node.stop() + ]) } module.exports = { diff --git a/package.json b/package.json index c1b857d9a3..4d462cbf67 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "libp2p-tcp": "^0.13.0", "libp2p-webrtc-star": "^0.16.1", "libp2p-websocket-star": "~0.10.2", - "libp2p-websocket-star-rendezvous": "~0.3.0", + "libp2p-websocket-star-rendezvous": "~0.4.1", "lodash.times": "^4.3.2", "merge-options": "^1.0.1", "nock": "^10.0.6", diff --git a/src/index.js b/src/index.js index f76e8fd6ba..af2b2bceae 100644 --- a/src/index.js +++ b/src/index.js @@ -187,6 +187,11 @@ 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 }) + }) } /** @@ -295,6 +300,13 @@ class Libp2p extends EventEmitter { }) } + /** + * Disconnects from the given peer + * + * @param {PeerInfo|PeerId|Multiaddr|string} peer The peer to ping + * @param {function(Error)} callback + * @returns {void} + */ hangUp (peer, callback) { this._getPeerInfo(peer, (err, peerInfo) => { if (err) { return callback(err) } @@ -303,6 +315,13 @@ class Libp2p extends EventEmitter { }) } + /** + * Pings the provided peer + * + * @param {PeerInfo|PeerId|Multiaddr|string} peer The peer to ping + * @param {function(Error, Ping)} callback + * @returns {void} + */ ping (peer, callback) { if (!this.isStarted()) { return callback(notStarted('ping', this.state._state)) @@ -550,11 +569,6 @@ class Libp2p extends EventEmitter { } } -// promisify all instance methods -['start', 'stop', 'dial', 'dialProtocol', 'dialFSM', 'hangUp', 'ping'].forEach(method => { - Libp2p[method] = promisify(Libp2p[method]) -}) - module.exports = Libp2p /** * Like `new Libp2p(options)` except it will create a `PeerInfo` diff --git a/test/circuit-relay.browser.js b/test/circuit-relay.browser.js index 54f522d108..6455f3c6ff 100644 --- a/test/circuit-relay.browser.js +++ b/test/circuit-relay.browser.js @@ -43,12 +43,7 @@ describe('circuit relay', () => { let peerRelay before('get peer relay', async () => { - peerRelay = await new Promise(resolve => { - getPeerRelay((err, peer) => { - expect(err).to.not.exist() - resolve(peer) - }) - }) + peerRelay = await getPeerRelay() }) before('create the browser nodes', async () => { diff --git a/test/node.js b/test/node.js index 9e5bd89bd1..224509fcc3 100644 --- a/test/node.js +++ b/test/node.js @@ -6,6 +6,7 @@ require('./stream-muxing.node') require('./peer-discovery.node') require('./peer-routing.node') require('./ping.node') +require('./promisify.node') require('./pubsub.node') require('./content-routing.node') require('./circuit-relay.node') diff --git a/test/promisify.node.js b/test/promisify.node.js new file mode 100644 index 0000000000..5a62e0d5b8 --- /dev/null +++ b/test/promisify.node.js @@ -0,0 +1,87 @@ +/* eslint-env mocha */ +'use strict' + +/** + * This test suite is intended to validate compatability of + * the promisified api, until libp2p has been fully migrated to + * async/await. Once the migration is complete and all tests + * are using async/await, this file can be removed. + */ + +const chai = require('chai') +chai.use(require('dirty-chai')) +const expect = chai.expect +const promisify = require('promisify-es6') +const createNode = promisify(require('./utils/create-node')) +const { createPeerInfo } = require('./utils/create-node') +const Node = require('./utils/bundle-nodejs') +const pull = require('pull-stream') +const Ping = require('libp2p-ping') + +/** + * As libp2p is currently promisified, when extending libp2p, + * method arguments must be passed to `super` to ensure the + * promisify callbacks are properly resolved + */ +class AsyncLibp2p extends Node { + async start (...args) { + await super.start(...args) + } + + async stop (...args) { + await super.start(...args) + } +} + +async function createAsyncNode () { + const peerInfo = await promisify(createPeerInfo)() + peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0') + return new AsyncLibp2p({ peerInfo }) +} + +describe('promisified libp2p', () => { + let libp2p + let otherNode + const ECHO_PROTO = '/echo/1.0.0' + + before('Create and Start', async () => { + [libp2p, otherNode] = await Promise.all([ + createNode('/ip4/0.0.0.0/tcp/0'), + createAsyncNode() + ]) + + return [libp2p, otherNode].map(node => { + node.handle(ECHO_PROTO, (_, conn) => pull(conn, conn)) + return node.start() + }) + }) + + after('Stop', () => { + return [libp2p, otherNode].map(node => node.stop()) + }) + + afterEach('Hang up', () => { + return libp2p.hangUp(otherNode.peerInfo) + }) + + it('dial', async () => { + const stream = await libp2p.dial(otherNode.peerInfo) + expect(stream).to.not.exist() + expect(libp2p._switch.connection.getAll()).to.have.length(1) + }) + + it('dialFSM', async () => { + const connectionFSM = await libp2p.dialFSM(otherNode.peerInfo, ECHO_PROTO) + expect(connectionFSM).to.exist() + }) + + it('dialProtocol', async () => { + const stream = await libp2p.dialProtocol(otherNode.peerInfo, ECHO_PROTO) + expect(stream).to.exist() + }) + + it('ping', async () => { + const ping = await libp2p.ping(otherNode.peerInfo) + expect(ping).to.be.an.instanceOf(Ping) + }) +}) diff --git a/test/transports.browser.js b/test/transports.browser.js index 8324191dd7..88614078a0 100644 --- a/test/transports.browser.js +++ b/test/transports.browser.js @@ -25,14 +25,11 @@ describe('transports', () => { let peerBMultiaddr let nodeA - before((done) => { - getPeerRelay((err, peerInfo) => { - expect(err).to.not.exist() - peerB = new PeerInfo(peerInfo.id) - peerBMultiaddr = `/ip4/127.0.0.1/tcp/9200/ws/p2p/${peerInfo.id.toB58String()}` - peerB.multiaddrs.add(peerBMultiaddr) - done() - }) + before(async () => { + const peerInfo = await getPeerRelay() + peerB = new PeerInfo(peerInfo.id) + peerBMultiaddr = `/ip4/127.0.0.1/tcp/9200/ws/p2p/${peerInfo.id.toB58String()}` + peerB.multiaddrs.add(peerBMultiaddr) }) after((done) => nodeA.stop(done)) diff --git a/test/transports.node.js b/test/transports.node.js index c7d86cd41d..3b4faf9696 100644 --- a/test/transports.node.js +++ b/test/transports.node.js @@ -17,7 +17,9 @@ const createNode = require('./utils/create-node.js') const tryEcho = require('./utils/try-echo') const echo = require('./utils/echo') -const { WRTC_RENDEZVOUS_MULTIADDR } = require('./utils/constants') +const { + WRTC_RENDEZVOUS_MULTIADDR +} = require('./utils/constants') describe('transports', () => { describe('TCP only', () => { @@ -576,25 +578,24 @@ describe('transports', () => { let nodeTCP let nodeWS let nodeWebSocketStar - let ss + const PORT = 24642 + + before(async () => { + ss = await rendezvous.start({ + port: PORT + }) + }) before((done) => { parallel([ - (cb) => { - rendezvous.start({ port: 24642 }, (err, server) => { - expect(err).to.not.exist() - ss = server - cb() - }) - }, (cb) => { const wstar = new WSStar() createNode([ '/ip4/0.0.0.0/tcp/0', '/ip4/127.0.0.1/tcp/25011/ws', - '/ip4/127.0.0.1/tcp/24642/ws/p2p-websocket-star' + `/ip4/127.0.0.1/tcp/${PORT}/ws/p2p-websocket-star` ], { modules: { transport: [ @@ -603,13 +604,6 @@ describe('transports', () => { wstar ], peerDiscovery: [wstar.discovery] - }, - config: { - peerDiscovery: { - [wstar.discovery.tag]: { - enabled: true - } - } } }, (err, node) => { expect(err).to.not.exist() @@ -640,18 +634,11 @@ describe('transports', () => { const wstar = new WSStar({}) createNode([ - '/ip4/127.0.0.1/tcp/24642/ws/p2p-websocket-star' + `/ip4/127.0.0.1/tcp/${PORT}/ws/p2p-websocket-star` ], { modules: { transport: [wstar], peerDiscovery: [wstar.discovery] - }, - config: { - peerDiscovery: { - [wstar.discovery.tag]: { - enabled: true - } - } } }, (err, node) => { expect(err).to.not.exist() @@ -670,7 +657,9 @@ describe('transports', () => { (cb) => nodeTCP.stop(cb), (cb) => nodeWS.stop(cb), (cb) => nodeWebSocketStar.stop(cb), - (cb) => ss.stop(cb) + async () => { + await ss.stop() + } ], done) }) diff --git a/test/utils/constants.js b/test/utils/constants.js index bc9b3d7136..33eaf45cb4 100644 --- a/test/utils/constants.js +++ b/test/utils/constants.js @@ -5,6 +5,7 @@ const PeerInfo = require('peer-info') const nextTick = require('async/nextTick') const peerJSON = require('../fixtures/test-peer') const multiaddr = require('multiaddr') +const promisify = require('promisify-es6') let peerRelay = null @@ -20,7 +21,7 @@ let peerRelay = null * @param {function(error, PeerInfo)} callback * @returns {void} */ -module.exports.getPeerRelay = (callback) => { +module.exports.getPeerRelay = promisify((callback) => { if (peerRelay) return nextTick(callback, null, peerRelay) PeerId.createFromJSON(peerJSON, (err, peerId) => { @@ -34,7 +35,7 @@ module.exports.getPeerRelay = (callback) => { callback(null, peerRelay) }) -} +}) -module.exports.WS_RENDEZVOUS_MULTIADDR = multiaddr('/ip4/127.0.0.1/tcp/14444/wss') -module.exports.WRTC_RENDEZVOUS_MULTIADDR = multiaddr('/ip4/127.0.0.1/tcp/15555/wss') +module.exports.WS_RENDEZVOUS_MULTIADDR = multiaddr('/ip4/127.0.0.1/tcp/14444/ws') +module.exports.WRTC_RENDEZVOUS_MULTIADDR = multiaddr('/ip4/127.0.0.1/tcp/15555/ws')