Skip to content
This repository has been archived by the owner on Feb 11, 2020. It is now read-only.

Commit

Permalink
feat: all new shiny api
Browse files Browse the repository at this point in the history
  • Loading branch information
daviddias committed Mar 31, 2017
1 parent ab64395 commit d82da99
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 91 deletions.
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/diasdavid/js-peer-book.git"
"url": "git+https://github.com/libp2p/js-peer-book.git"
},
"pre-commit": [
"lint",
Expand All @@ -33,19 +33,20 @@
"author": "David Dias <daviddias@ipfs.io>",
"license": "MIT",
"bugs": {
"url": "https://github.com/diasdavid/js-peer-book/issues"
"url": "https://github.com/libp2p/js-peer-book/issues"
},
"homepage": "https://github.com/diasdavid/js-peer-book#readme",
"homepage": "https://github.com/libp2p/js-peer-book#readme",
"dependencies": {
"bs58": "^4.0.0"
"bs58": "^4.0.0",
"peer-id": "^0.8.6",
"peer-info": "^0.9.1"
},
"devDependencies": {
"aegir": "^11.0.1",
"async": "^2.2.0",
"chai": "^3.5.0",
"dirty-chai": "^1.2.2",
"multiaddr": "^2.3.0",
"peer-info": "~0.9.0",
"pre-commit": "^1.2.2"
},
"contributors": [
Expand All @@ -54,4 +55,4 @@
"greenkeeperio-bot <support@greenkeeper.io>",
"npmcdn-to-unpkg-bot <npmcdn-to-unpkg-bot@users.noreply.github.com>"
]
}
}
105 changes: 74 additions & 31 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,78 +1,121 @@
'use strict'

const bs58 = require('bs58')
const PeerId = require('peer-id')
const PeerInfo = require('peer-info')

function getB58Str (peer) {
let b58Str

if (typeof peer === 'string') {
b58Str = peer
} else if (Buffer.isBuffer(peer)) {
b58Str = bs58.encode(peer).toString()
} else if (PeerId.isPeerId(peer)) {
b58Str = peer.toB58String()
} else if (PeerInfo.isPeerInfo(peer)) {
b58Str = peer.id.toB58String()
} else {
throw new Error('not valid PeerId or PeerInfo, or B58Str')
}

return b58Str
}

class PeerBook {
constructor () {
this._peers = {}
}

// checks if peer exists
// peer can be PeerId, b58String or PeerInfo
has (peer) {
const b58Str = getB58Str(peer)
return Boolean(this._peers[b58Str])
}

/**
* Stores a peerInfo, if already exist, only adds the multiaddrs
* Stores a peerInfo, if already exist, merges the new into the old.
*
* @param {PeerInfo} peerInfo
* @param {replace} boolean
* @returns {null}
* @returns {PeerInfo}
*/
put (peerInfo, replace) {
if (this._peers[peerInfo.id.toB58String()] && !replace) {
// peerInfo.replace merges by default if none to replace are passed
this._peers[peerInfo.id.toB58String()]
.multiaddrs.replace([], peerInfo.multiaddrs.toArray())
const localPeerInfo = this._peers[peerInfo.id.toB58String()]

// insert if doesn't exist or replace if replace flag is true
if (!localPeerInfo || replace) {
this._peers[peerInfo.id.toB58String()] = peerInfo
return peerInfo
}

this._peers[peerInfo.id.toB58String()] = peerInfo
}
// peerInfo.replace merges by default if none to replace are passed
peerInfo.multiaddrs.forEach((ma) => localPeerInfo.multiaddrs.add(ma))

getAll () {
return this._peers
// pass active connection state
const ma = peerInfo.isConnected()
if (ma) {
localPeerInfo.connect(ma)
}

// pass known protocols
peerInfo.protocols.forEach((p) => localPeerInfo.protocols.add(p))

if (!localPeerInfo.id.privKey && peerInfo.id.privKey) {
localPeerInfo.id.privKey = peerInfo.id.privKey
}

if (!localPeerInfo.id.pubKey && peerInfo.id.pubKey) {
localPeerInfo.id.pubKey = peerInfo.id.pubKey
}

return localPeerInfo
}

/**
* Get the info to the given PeerId.
* Get the info to the given PeerId, PeerInfo or b58Str id
*
* @param {PeerId} id
* @returns {PeerInfo}
*/
get (id) {
return this.getByB58String(id.toB58String())
}
get (peer) {
const b58Str = getB58Str(peer)

getByB58String (b58String) {
const peerInfo = this._peers[b58String]
const peerInfo = this._peers[b58Str]

if (peerInfo) {
return peerInfo
}
throw new Error('PeerInfo not found')
}

getByMultihash (multihash) {
const b58multihash = bs58.encode(multihash).toString()
return this.getByB58String(b58multihash)
}

removeByB58String (b58String) {
if (this._peers[b58String]) {
delete this._peers[b58String]
}
getAll () {
return this._peers
}

removeByMultihash (multihash) {
const b58multihash = bs58.encode(multihash).toString()
this.removeByB58String(b58multihash)
getAllArray () {
return Object.keys(this._peers).map((b58Str) => this._peers[b58Str])
}

/**
* Return all multiaddrs for a given PeerId.
*
* @param {PeerId} id
* @param {PeerId, PeerInfo, Multihash, B58Str} id
* @returns {Array<Multiaddr>}
*/
getAddrs (id) {
const info = this.get(id)
getMultiaddrs (peer) {
const info = this.get(peer)
return info.multiaddrs
}

remove (peer) {
const b58Str = getB58Str(peer)

if (this._peers[b58Str]) {
delete this._peers[b58Str]
}
}
}

module.exports = PeerBook
121 changes: 67 additions & 54 deletions test/peer-book.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ chai.use(dirtyChai)
const Multiaddr = require('multiaddr')
const PeerInfo = require('peer-info')
const async = require('async')
const utils = require('./utils')
const createPeerInfo = utils.createPeerInfo

const PeerBook = require('../src')

describe('peer-book', function () {
this.timeout(50000)
describe('peer-book', () => {
let pb
let p1
let p2
Expand All @@ -21,10 +22,22 @@ describe('peer-book', function () {

before((done) => {
async.parallel([
(cb) => PeerInfo.create(cb),
(cb) => PeerInfo.create(cb),
(cb) => PeerInfo.create(cb),
(cb) => PeerInfo.create(cb)
(cb) => createPeerInfo([
'/tcp/1000',
'/tcp/1001'
], cb),
(cb) => createPeerInfo([
'/tcp/2000',
'/tcp/2001'
], cb),
(cb) => createPeerInfo([
'/tcp/3000',
'/tcp/3001'
], cb),
(cb) => createPeerInfo([
'/tcp/4000',
'/tcp/4001'
], cb)
], (err, infos) => {
if (err) {
return done(err)
Expand All @@ -44,44 +57,48 @@ describe('peer-book', function () {
expect(pb).to.exist()
})

it('put peerInfo', () => {
pb.put(p1)
pb.put(p2)
pb.put(p3)
it('.put', () => {
expect(pb.put(p1)).to.eql(p1)
expect(pb.put(p2)).to.eql(p2)
expect(pb.put(p3)).to.eql(p3)
})

it('get all peerInfo', () => {
it('.getAll', () => {
const peers = pb.getAll()
expect(Object.keys(peers).length).to.equal(3)
})

it('get', () => {
it('.getAllArray', () => {
expect(pb.getAllArray()).to.have.length(3)
})

it('.get by PeerId', () => {
const peer = pb.get(p1.id)
expect(peer).to.eql(p1)
})

it('getByB58String', () => {
const p1Id = p1.id.toB58String()
const peer = pb.getByB58String(p1Id)
it('.get by B58String ', () => {
const b58Str = p1.id.toB58String()
const peer = pb.get(b58Str)
expect(peer).to.eql(p1)
})

it('getByB58String non existent', (done) => {
it('.get by B58String non existent', (done) => {
try {
pb.getByB58String(p4.id.toB58String())
pb.get(p4.id.toB58String())
} catch (err) {
expect(err).to.exist()
done()
}
})

it('getByMultihash', () => {
const p1Id = p1.id.toBytes()
const peer = pb.getByMultihash(p1Id)
expect(peer).to.deep.equal(p1)
it('.get by Multihash', () => {
const mh = p1.id.toBytes()
const peer = pb.get(mh)
expect(peer).to.eql(p1)
})

it('getByMultihash non existent', (done) => {
it('.get by Multihash non existent', (done) => {
try {
pb.getByMultihash(p4.id.toBytes())
} catch (err) {
Expand All @@ -90,49 +107,45 @@ describe('peer-book', function () {
}
})

it('removeByB58String', (done) => {
const p1Id = p1.id.toB58String()
pb.removeByB58String(p1Id)
try {
pb.getByB58String(p1Id)
} catch (err) {
expect(err).to.exist()
done()
}
it('.remove by B58String', () => {
const b58Str = p1.id.toB58String()

pb.remove(b58Str)
expect(pb.has(b58Str)).to.equal(false)
})

it('removeByMultihash', (done) => {
const p1Id = p1.id.toBytes()
pb.removeByMultihash(p1Id)
try {
pb.getByMultihash(p1Id)
} catch (err) {
expect(err).to.exist()
done()
}
it('.remove by Multihash', () => {
const mh = p1.id.toBytes()

pb.remove(mh)
expect(pb.has(mh)).to.equal(false)
})

it('add repeated Id, merge info', () => {
const peerA = new PeerInfo(p3.id)
peerA.multiaddrs.add(new Multiaddr('/ip4/127.0.0.1/tcp/4001'))
pb.put(peerA)
const peerB = pb.getByB58String(p3.id.toB58String())
expect(peerA).to.eql(peerB)
it('.put repeated Id, merge info', () => {
const peer3A = new PeerInfo(p3.id)
peer3A.multiaddrs.add(new Multiaddr('/ip4/127.0.0.1/tcp/4001'))

pb.put(peer3A)
const peer3B = pb.get(p3.id.toBytes())

expect(peer3B.multiaddrs.toArray()).to.have.length(3)
})

it('add repeated Id, replace info', () => {
const peerA = new PeerInfo(p3.id)
peerA.multiaddrs.add(new Multiaddr('/ip4/188.0.0.1/tcp/5001'))
pb.put(peerA, true)
const peerB = pb.getByB58String(p3.id.toB58String())
expect(peerA).to.deep.equal(peerB)
it('.put repeated Id, replace info', () => {
const peer3A = new PeerInfo(p3.id)
peer3A.multiaddrs.add(new Multiaddr('/ip4/188.0.0.1/tcp/5001'))

pb.put(peer3A, true)
const peer3B = pb.get(p3.id.toB58String())
expect(peer3A.multiaddrs.toArray()).to.eql(peer3B.multiaddrs.toArray())
})

it('getAddrs', () => {
it('.getMultiaddrs', () => {
const pb = new PeerBook()
const peer = new PeerInfo(p3.id)
peer.multiaddrs.add(new Multiaddr('/ip4/127.0.0.1/tcp/1234'))

pb.put(peer)
expect(pb.getAddrs(p3.id)).to.be.eql(peer.multiaddrs)
expect(pb.getMultiaddrs(p3.id)).to.be.eql(peer.multiaddrs)
})
})
Loading

0 comments on commit d82da99

Please sign in to comment.