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

Commit

Permalink
feat: connectedMultiaddr (#49)
Browse files Browse the repository at this point in the history
* feat: connectedMultiaddr
* feat: all new shiny API that makes everyone happy
  • Loading branch information
daviddias committed Mar 30, 2017
1 parent 21700b8 commit 422d0fd
Show file tree
Hide file tree
Showing 6 changed files with 299 additions and 207 deletions.
26 changes: 17 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,19 @@
- [API](#api)
- [`PeerInfo.create([id, ] callback)`](#peerinfocreateid-callback)
- [`new PeerInfo(id)`](#new-peerinfoid)
- [`multiaddrs`](#multiaddrs)
- [`multiaddr.add(addr)`](#multiaddraddaddr)
- [`multiaddr.addSafe(addr)`](#multiaddraddsafeaddr)
- [`multiaddr.rm(addr)`](#multiaddrrmaddr)
- [`multiaddr.replace(existing, fresh)`](#multiaddrreplaceexisting-fresh)
- [`.connect(ma)`](#connectma)
- [`.disconnect()`](#connectma)
- [`.isConnected()`](#connectma)
- [`.multiaddrs`](#multiaddrs)
- [`.multiaddrs.add(addr)`](#multiaddraddaddr)
- [`.multiaddrs.addSafe(addr)`](#multiaddraddsafeaddr)
- [`.multiaddrs.forEach(fn)`](#multiaddrforeachfn)
- [`.multaiddrs.size`]((#multiaddrsize)
- [`.multiaddrs.has()`]((#multiaddrhas)
- [`.multiaddrs.delete(addr)`](#multiaddrdeleteaddr)
- [`.multiaddrs.toArray()`](#multiaddrtoarray)
- [`.multiaddrs.replace(existing, fresh)`](#multiaddrreplaceexisting-fresh)
- [`.multiaddrs.distinct()`](#distinct)
- [Contribute](#contribute)
- [License](#license)

Expand Down Expand Up @@ -103,14 +111,14 @@ Creates a new PeerInfo instance from an existing PeerID.

A list of multiaddresses instances that `peer` can be reached at.

### `multiaddr.add(addr)`
### `.multiaddrs.add(addr)`

- `addr: Multiaddr`

Adds a new multiaddress that `peer` can be reached at. `addr` is an instance of
a [multiaddr](https://github.com/libp2p/js-multiaddr).

### `multiaddr.addSafe(addr)`
### `.multiaddr.addSafe(addr)`

- `addr: Multiaddr`

Expand All @@ -123,13 +131,13 @@ peers which will not provide a useful multiaddr to be shared to the rest of the
network (e.g. a multiaddr referring to a peer inside a LAN being shared to the
outside world).

### `multiaddr.rm(addr)`
### `.multiaddr.delete(addr)`

- `addr: Multiaddr`

Removes a multiaddress instance `addr` from `peer`.

### `multiaddr.replace(existing, fresh)`
### `.multiaddr.replace(existing, fresh)`

- `existing: Multiaddr`
- `fresh: Multiaddr`
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@
"pre-commit": "^1.2.2"
},
"dependencies": {
"multiaddr": "^2.2.3",
"multiaddr": "^2.3.0",
"lodash.uniqby": "^4.7.0",
"peer-id": "^0.8.5"
"peer-id": "^0.8.6"
},
"contributors": [
"David Dias <[email protected]>",
Expand Down
105 changes: 22 additions & 83 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,99 +1,36 @@
'use strict'

const Id = require('peer-id')
const multiaddr = require('multiaddr')
const uniqBy = require('lodash.uniqby')

exports = module.exports = PeerInfo

function ensureMultiaddr (addr) {
if (multiaddr.isMultiaddr(addr)) {
return addr
}

return multiaddr(addr)
}
const ensureMultiaddr = require('./utils').ensureMultiaddr
const MultiaddrSet = require('./multiaddr-set')
const assert = require('assert')

// Peer represents a peer on the IPFS network
function PeerInfo (peerId) {
if (!(this instanceof PeerInfo)) {
return new PeerInfo(peerId)
}
class PeerInfo {
constructor (peerId) {
assert(peerId, 'Missing peerId. Use Peer.create(cb) to create one')

if (!peerId) {
throw new Error('Missing peerId. Use Peer.create(cb) to create one')
this.id = peerId
this.multiaddrs = new MultiaddrSet()
this.protocols = new Set()
this._connectedMultiaddr = undefined
}

this.id = peerId

this.multiaddrs = []
const observedMultiaddrs = []

this.multiaddr = {}

this.multiaddr.add = (addr) => {
addr = ensureMultiaddr(addr)

var exists = false
this.multiaddrs.some((m, i) => {
if (m.equals(addr)) {
exists = true
return true
}
})
if (!exists) {
this.multiaddrs.push(addr)
// only stores the current multiaddr being used
connect (ma) {
ma = ensureMultiaddr(ma)
if (!this.multiaddrs.has(ma)) {
throw new Error('can\'t be connected to missing multiaddr from set')
}
this._connectedMultiaddr = ma
}

// to prevent multiaddr explosion
this.multiaddr.addSafe = (addr) => {
addr = ensureMultiaddr(addr)

var check = false
observedMultiaddrs.some((m, i) => {
if (m.equals(addr)) {
this.multiaddr.add(addr)
observedMultiaddrs.splice(i, 1)
check = true
}
})
if (!check) {
observedMultiaddrs.push(addr)
}
}

this.multiaddr.rm = (addr) => {
addr = ensureMultiaddr(addr)

this.multiaddrs.some((m, i) => {
if (m.equals(addr)) {
this.multiaddrs.splice(i, 1)
return true
}
})
}

this.multiaddr.replace = (existing, fresh) => {
if (!Array.isArray(existing)) {
existing = [existing]
}
if (!Array.isArray(fresh)) {
fresh = [fresh]
}
existing.forEach((m) => {
this.multiaddr.rm(m)
})
fresh.forEach((m) => {
this.multiaddr.add(m)
})
disconnect () {
this._connectedMultiaddr = undefined
}

this.distinctMultiaddr = () => {
var result = uniqBy(this.multiaddrs, function (item) {
return [item.toOptions().port, item.toOptions().transport].join()
})
return result
isConnected () {
return Boolean(this._connectedMultiaddr)
}
}

Expand All @@ -120,3 +57,5 @@ PeerInfo.isPeerInfo = (peerInfo) => {
peerInfo.id &&
peerInfo.multiaddrs)
}

module.exports = PeerInfo
98 changes: 98 additions & 0 deletions src/multiaddr-set.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
'use strict'

const ensureMultiaddr = require('./utils').ensureMultiaddr
const uniqBy = require('lodash.uniqby')

// Because JavaScript doesn't let you overload the compare in Set()..
class MultiaddrSet {
constructor (multiaddrs) {
this._multiaddrs = multiaddrs || []
this._observedMultiaddrs = []
}

add (ma) {
ma = ensureMultiaddr(ma)

if (!this.has(ma)) {
this._multiaddrs.push(ma)
}
}

// addSafe - prevent multiaddr explosion™
// Multiaddr explosion is when you dial to a bunch of nodes and every node
// gives you a different observed address and you start storing them all to
// share with other peers. This seems like a good idea until you realize that
// most of those addresses are unique to the subnet that peer is in and so,
// they are completely worthless for all the other peers. This method is
// exclusively used by identify.
addSafe (ma) {
ma = ensureMultiaddr(ma)

const check = this._observedMultiaddrs.some((m, i) => {
if (m.equals(ma)) {
this.add(ma)
this._observedMultiaddrs.splice(i, 1)
return true
}
})
if (!check) {
this._observedMultiaddrs.push(ma)
}
}

toArray () {
return this._multiaddrs.slice()
}

get size () {
return this._multiaddrs.length
}

forEach (fn) {
return this._multiaddrs.forEach(fn)
}

has (ma) {
ma = ensureMultiaddr(ma)
return this._multiaddrs.some((m) => m.equals(ma))
}

delete (ma) {
ma = ensureMultiaddr(ma)

this._multiaddrs.some((m, i) => {
if (m.equals(ma)) {
this._multiaddrs.splice(i, 1)
return true
}
})
}

// replaces selected existing multiaddrs with new ones
replace (existing, fresh) {
if (!Array.isArray(existing)) {
existing = [existing]
}
if (!Array.isArray(fresh)) {
fresh = [fresh]
}
existing.forEach((m) => this.delete(m))
fresh.forEach((m) => this.add(m))
}

clear () {
this._multiaddrs = []
}

// this only really helps make ip6 and ip4 multiaddrs distinct if they are
// different
// TODO this is not an ideal solution, probably this code should just be
// in libp2p-tcp
distinct () {
return uniqBy(this._multiaddrs, (ma) => {
return [ma.toOptions().port, ma.toOptions().transport].join()
})
}
}

module.exports = MultiaddrSet
15 changes: 15 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict'

const multiaddr = require('multiaddr')

function ensureMultiaddr (ma) {
if (multiaddr.isMultiaddr(ma)) {
return ma
}

return multiaddr(ma)
}

module.exports = {
ensureMultiaddr: ensureMultiaddr
}
Loading

0 comments on commit 422d0fd

Please sign in to comment.