Skip to content

Commit

Permalink
feat: refactor to use async/await
Browse files Browse the repository at this point in the history
Also upgrades all the deps, moves from `ipfs-api` to `ipfs-http-client`
and removes a lot of results massaging that is now done in the
http client.
  • Loading branch information
achingbrain committed Jul 5, 2019
1 parent abb2f23 commit f1548a6
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 128 deletions.
6 changes: 4 additions & 2 deletions .aegir.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ const server = createServer()

module.exports = {
hooks: {
pre: server.start.bind(server),
post: server.stop.bind(server)
browser: {
pre: () => server.start(),
post: () => server.stop()
}
}
}
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ const DelegatedPeerRouting = require('libp2p-delegated-routing')
// default is to use ipfs.io
const routing = new DelegatedPeerRouing()

routing.findPeer('peerid', (err, peerInfo) => {
if (err) {
return console.error(err)
}
try {
const peerInfo = await routing.findPeer('peerid')

console.log('found peer details', peerInfo)
})
} catch (err) {
console.error(err)
}
```

## License
Expand Down
10 changes: 4 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,14 @@
"coverage": "aegir coverage"
},
"devDependencies": {
"aegir": "^15.2.0",
"async": "^2.6.1",
"aegir": "^19.0.4",
"chai": "^4.2.0",
"go-ipfs-dep": "~0.4.17",
"ipfsd-ctl": "~0.39.2"
"ipfsd-ctl": "~0.44.0"
},
"dependencies": {
"ipfs-api": "^24.0.2",
"peer-id": "~0.11.0",
"peer-info": "~0.14.1"
"ipfs-http-client": "^32.0.1",
"peer-id": "~0.12.2"
},
"contributors": [
"David Dias <daviddias.p@gmail.com>",
Expand Down
59 changes: 13 additions & 46 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
'use strict'

const PeerInfo = require('peer-info')
const PeerId = require('peer-id')
const dht = require('ipfs-api/src/dht')
const defaultConfig = require('ipfs-api/src/utils/default-config')
const dht = require('ipfs-http-client/src/dht')
const defaultConfig = require('ipfs-http-client/src/utils/default-config')

const DEFAULT_MAX_TIMEOUT = 30e3 // 30 second default
const DEFAULT_IPFS_API = {
Expand All @@ -12,10 +11,6 @@ const DEFAULT_IPFS_API = {
host: 'ipfs.io'
}

const peerNotFoundError = (id) => {
return new Error(`Peer "${id}" not found`)
}

class DelegatedPeerRouting {
constructor (api) {
this.api = Object.assign({}, defaultConfig(), DEFAULT_IPFS_API, api)
Expand All @@ -28,54 +23,26 @@ class DelegatedPeerRouting {
* @param {PeerID} id
* @param {object} options
* @param {number} options.maxTimeout How long the query can take. Defaults to 30 seconds
* @param {function(Error, PeerInfo)} callback
* @returns {void}
* @returns {Promise<PeerInfo>}
*/
findPeer (id, options, callback) {
if (typeof options === 'function') {
callback = options
options = {}
} else if (typeof options === 'number') { // This will be deprecated in a next release
options = {
maxTimeout: options
}
} else {
options = options || {}
}

async findPeer (id, options = {}) {
if (PeerId.isPeerId(id)) {
id = id.toB58String()
}

options.maxTimeout = options.maxTimeout || DEFAULT_MAX_TIMEOUT

this.dht.findpeer(id, {
timeout: `${options.maxTimeout}ms`// The api requires specification of the time unit (s/ms)
}, (err, results) => {
if (err) {
return callback(err)
try {
return await this.dht.findPeer(id, {
timeout: `${options.maxTimeout}ms`// The api requires specification of the time unit (s/ms)
})
} catch (err) {
if (err.message.includes('not found')) {
return undefined
}

// cleanup result from ipfs-api
const actual = results.filter((res) => Boolean(res.Responses))

if (actual.length === 0) {
return callback(peerNotFoundError(id))
}

const wantedResponse = actual.find((el) => el.Type === 2)
if (wantedResponse === undefined) {
return callback(peerNotFoundError(id))
}
const details = wantedResponse.Responses[0]
const info = new PeerInfo(
PeerId.createFromB58String(details.ID)
)
details.Addrs.forEach((addr) => info.multiaddrs.add(addr))

// there should be only one of these
callback(null, info)
})
throw err
}
}
}

Expand Down
109 changes: 40 additions & 69 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,13 @@

const expect = require('chai').expect
const IPFSFactory = require('ipfsd-ctl')
const async = require('async')
const PeerID = require('peer-id')

const DelegatedPeerRouting = require('../src')
const factory = IPFSFactory.create({ type: 'go' })

function spawnNode (boostrap, callback) {
if (typeof boostrap === 'function') {
callback = boostrap
boostrap = []
}

factory.spawn({
async function spawnNode (boostrap = []) {
const node = await factory.spawn({
// Lock down the nodes so testing can be deterministic
config: {
Bootstrap: boostrap,
Expand All @@ -25,15 +19,13 @@ function spawnNode (boostrap, callback) {
}
}
}
}, (err, node) => {
if (err) return callback(err)

node.api.id((err, id) => {
if (err) return callback(err)

callback(null, node, id)
})
})
const id = await node.api.id()

return {
node,
id
}
}

describe('DelegatedPeerRouting', function () {
Expand All @@ -45,37 +37,28 @@ describe('DelegatedPeerRouting', function () {
let bootstrapNode
let bootstrapId

before((done) => {
async.waterfall([
// Spawn a "Boostrap" node that doesnt connect to anything
(cb) => spawnNode(cb),
(ipfsd, id, cb) => {
bootstrapNode = ipfsd
bootstrapId = id
cb()
},
// Spawn our local node and bootstrap the bootstrapper node
(cb) => spawnNode(bootstrapId.addresses, cb),
(ipfsd, id, cb) => {
nodeToFind = ipfsd
peerIdToFind = id
cb()
},
// Spawn the delegate node and bootstrap the bootstrapper node
(cb) => spawnNode(bootstrapId.addresses, cb),
(ipfsd, id, cb) => {
delegatedNode = ipfsd
cb()
}
], done)
before(async () => {
// Spawn a "Boostrap" node that doesnt connect to anything
const bootstrap = await spawnNode()
bootstrapNode = bootstrap.node
bootstrapId = bootstrap.id

// Spawn our local node and bootstrap the bootstrapper node
const local = await spawnNode(bootstrapId.addresses)
nodeToFind = local.node
peerIdToFind = local.id

// Spawn the delegate node and bootstrap the bootstrapper node
const delegate = await spawnNode(bootstrapId.addresses)
delegatedNode = delegate.node
})

after((done) => {
async.parallel([
(cb) => nodeToFind.stop(cb),
(cb) => delegatedNode.stop(cb),
(cb) => bootstrapNode.stop(cb)
], done)
after(() => {
return Promise.all([
nodeToFind.stop(),
delegatedNode.stop(),
bootstrapNode.stop()
])
})

describe('create', () => {
Expand Down Expand Up @@ -117,52 +100,43 @@ describe('DelegatedPeerRouting', function () {
})

describe('findPeers', () => {
it('should be able to find peers via the delegate with a peer id string', (done) => {
it('should be able to find peers via the delegate with a peer id string', async () => {
const opts = delegatedNode.apiAddr.toOptions()
const router = new DelegatedPeerRouting({
protocol: 'http',
port: opts.port,
host: opts.host
})

router.findPeer(peerIdToFind.id, (err, peer) => {
expect(err).to.equal(null)
expect(peer.id.toB58String()).to.eql(peerIdToFind.id)
done()
})
const peer = await router.findPeer(peerIdToFind.id)
expect(peer.id.toB58String()).to.eql(peerIdToFind.id)
})

it('should be able to find peers via the delegate with a peerid', (done) => {
it('should be able to find peers via the delegate with a peerid', async () => {
const opts = delegatedNode.apiAddr.toOptions()
const router = new DelegatedPeerRouting({
protocol: 'http',
port: opts.port,
host: opts.host
})

router.findPeer(PeerID.createFromB58String(peerIdToFind.id), (err, peer) => {
expect(err).to.equal(null)
expect(peer.id.toB58String()).to.eql(peerIdToFind.id)
done()
})
const peer = await router.findPeer(PeerID.createFromB58String(peerIdToFind.id))
expect(peer.id.toB58String()).to.eql(peerIdToFind.id)
})

it('should be able to specify a maxTimeout', (done) => {
it('should be able to specify a maxTimeout', async () => {
const opts = delegatedNode.apiAddr.toOptions()
const router = new DelegatedPeerRouting({
protocol: 'http',
port: opts.port,
host: opts.host
})

router.findPeer(PeerID.createFromB58String(peerIdToFind.id), { maxTimeout: 2000 }, (err, peer) => {
expect(err).to.equal(null)
expect(peer.id.toB58String()).to.eql(peerIdToFind.id)
done()
})
const peer = await router.findPeer(PeerID.createFromB58String(peerIdToFind.id), { maxTimeout: 2000 })
expect(peer.id.toB58String()).to.eql(peerIdToFind.id)
})

it('should not be able to find peers not on the network', (done) => {
it('should not be able to find peers not on the network', async () => {
const opts = delegatedNode.apiAddr.toOptions()
const router = new DelegatedPeerRouting({
protocol: 'http',
Expand All @@ -172,11 +146,8 @@ describe('DelegatedPeerRouting', function () {

// This is one of the default Bootstrap nodes, but we're not connected to it
// so we'll test with it.
router.findPeer('QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64', (err, peer) => {
expect(err).to.be.an('error')
expect(peer).to.eql(undefined)
done()
})
const peer = await router.findPeer('QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64')
expect(peer).to.eql(undefined)
})
})
})

0 comments on commit f1548a6

Please sign in to comment.