Compare commits

...

57 Commits

Author SHA1 Message Date
babb90fe17 chore: release version v0.8.0 2017-03-31 16:19:24 +01:00
2f9070a725 chore: update contributors 2017-03-31 16:19:24 +01:00
a48ec65961 Merge pull request #85 from libp2p/feat/advanced-peer-book
fix: correct method on peer-book
2017-03-31 16:18:37 +01:00
031ecb3fe7 fix: correct method on peer-book 2017-03-31 16:17:59 +01:00
c6bdd869be Merge pull request #76 from libp2p/feat/advanced-peer-book
fix: avoid deleting nodes from peerBook
2017-03-31 16:17:18 +01:00
dee0340806 chore: update to latest peer-info, peer-book and libp2p-swarm 2017-03-31 15:52:20 +01:00
a4b41b0f9a feat: not remove peer from peerBook on disconnect 2017-03-30 07:20:45 +01:00
291e79fc99 fix: addition of ipfs id appendix must come before transport filtering 2017-03-29 21:02:37 +01:00
59ea9c388f feat: append peer id to multiaddr if not there 2017-03-29 20:02:54 +01:00
300936f2f3 fix: avoid deleting nodes from peerBook 2017-03-29 18:03:00 +01:00
9f4ec2a915 chore: release version v0.7.0 2017-03-29 08:03:58 +01:00
c7f4368007 chore: update contributors 2017-03-29 08:03:58 +01:00
9ff04779f5 Merge pull request #75 from libp2p/feat/update-peer-events
feat: Feat/update peer events
2017-03-29 08:03:13 +01:00
f73c045767 feat: update events to conform with #74 2017-03-29 07:32:46 +01:00
8840c9b250 docs: document new events 2017-03-29 07:32:29 +01:00
df4c99df4a chore: release version v0.6.2 2017-03-28 12:44:52 +01:00
6e05a0b239 chore: update contributors 2017-03-28 12:44:52 +01:00
c781abc30c chore: deps 2017-03-28 12:43:00 +01:00
6a66931ba4 chore: release version v0.6.1 2017-03-27 16:48:53 +01:00
426fc27b26 chore: update contributors 2017-03-27 16:48:52 +01:00
d6325dee90 chore: update deps 2017-03-27 16:48:41 +01:00
f74bc0596d chore: release version v0.6.0 2017-03-27 15:48:46 +01:00
8f9e82b0fb chore: update contributors 2017-03-27 15:48:46 +01:00
9724fa190e chore: update deps 2017-03-27 15:46:10 +01:00
721da9ab41 Merge pull request #64 from libp2p/feat/new-api
feat: Formalising the API
2017-03-27 15:45:41 +01:00
d27bd2b912 cr 2017-03-27 15:43:08 +01:00
2c23d9a718 fix: last touches 2017-03-27 14:42:05 +01:00
a6623c1ba2 feat: new super simplified API 2017-03-27 12:26:34 +01:00
5d4d94e75f docs: finish API documentation 2017-03-24 18:20:14 +00:00
a4b97b9627 docs: libp2p API 2017-03-24 17:07:08 +00:00
3584209947 docs: update readme, add base class extending example and start listing API calls 2017-03-24 16:02:57 +00:00
b5209fc456 chore: release version v0.5.5 2017-03-21 17:06:34 +01:00
932d8772da chore: update contributors 2017-03-21 17:06:33 +01:00
baee2b7945 chore(deps): update 2017-03-21 17:04:56 +01:00
153f8884fa Merge pull request #54 from libp2p/greenkeeper-aegir-10.0.0
Update aegir to version 10.0.0 🚀
2017-02-13 18:05:01 -08:00
b71f77dcf7 chore: release version v0.5.4 2017-02-10 23:19:27 -08:00
8dc8e0530b chore: update contributors 2017-02-10 23:19:27 -08:00
4ed0ce16af chore: update deps 2017-02-10 23:17:30 -08:00
cbb7290a97 chore: release version v0.5.3 2017-02-10 19:28:41 -08:00
63b10c01e3 chore: update contributors 2017-02-10 19:28:41 -08:00
11c21b6999 fix: use async.setImmediate 2017-02-10 19:28:34 -08:00
109ee51d7b chore: release version v0.5.2 2017-02-09 10:18:38 -08:00
09182b43bf chore: update contributors 2017-02-09 10:18:38 -08:00
a130ab2dc1 chore: ^ to ~ 2017-02-09 10:16:51 -08:00
13355bf179 chore(package): update aegir to version 10.0.0
https://greenkeeper.io/
2017-02-07 18:45:33 +01:00
e24a1e43dc chore: release version v0.5.1 2017-01-28 21:20:21 +00:00
cb7d60ef65 chore: update contributors 2017-01-28 21:20:20 +00:00
a01b9479eb fix: remove unnecessary log 2017-01-28 21:20:16 +00:00
d01876a3d1 chore: release version v0.5.0 2017-01-28 21:14:26 +00:00
eb5eed8b21 chore: update contributors 2017-01-28 21:14:26 +00:00
3c58613b69 chore: release version v0.4.0 2017-01-28 21:14:04 +00:00
5dd5d37f6a feat: new discovery interface 2017-01-28 21:14:04 +00:00
6c3dd4b780 chore: update deps 2017-01-28 21:14:04 +00:00
06913271c7 docs(readme): fix typos 2017-01-16 12:01:09 +01:00
2cdd7033f0 add options 2016-12-11 12:03:21 -08:00
c2cf1da2ce Merge pull request #50 from libp2p/greenkeeper-aegir-9.2.1 2016-12-10 12:00:26 -08:00
8d0124ee5c chore(package): update aegir to version 9.2.1
https://greenkeeper.io/
2016-12-09 13:25:07 +01:00
5 changed files with 313 additions and 154 deletions

58
CHANGELOG.md Normal file
View File

@ -0,0 +1,58 @@
<a name="0.8.0"></a>
# [0.8.0](https://github.com/libp2p/js-libp2p/compare/v0.7.0...v0.8.0) (2017-03-31)
### Bug Fixes
* addition of ipfs id appendix must come before transport filtering ([291e79f](https://github.com/libp2p/js-libp2p/commit/291e79f))
* avoid deleting nodes from peerBook ([300936f](https://github.com/libp2p/js-libp2p/commit/300936f))
* correct method on peer-book ([031ecb3](https://github.com/libp2p/js-libp2p/commit/031ecb3))
### Features
* append peer id to multiaddr if not there ([59ea9c3](https://github.com/libp2p/js-libp2p/commit/59ea9c3))
* not remove peer from peerBook on disconnect ([a4b41b0](https://github.com/libp2p/js-libp2p/commit/a4b41b0))
<a name="0.7.0"></a>
# [0.7.0](https://github.com/libp2p/js-libp2p/compare/v0.6.2...v0.7.0) (2017-03-29)
### Features
* update events to conform with [#74](https://github.com/libp2p/js-libp2p/issues/74) ([f73c045](https://github.com/libp2p/js-libp2p/commit/f73c045))
<a name="0.6.2"></a>
## [0.6.2](https://github.com/libp2p/js-libp2p/compare/v0.6.1...v0.6.2) (2017-03-28)
<a name="0.6.1"></a>
## [0.6.1](https://github.com/libp2p/js-libp2p/compare/v0.6.0...v0.6.1) (2017-03-27)
<a name="0.6.0"></a>
# [0.6.0](https://github.com/libp2p/js-libp2p/compare/v0.5.5...v0.6.0) (2017-03-27)
### Bug Fixes
* last touches ([2c23d9a](https://github.com/libp2p/js-libp2p/commit/2c23d9a))
### Features
* new super simplified API ([a6623c1](https://github.com/libp2p/js-libp2p/commit/a6623c1))
<a name="0.5.5"></a>
## [0.5.5](https://github.com/libp2p/js-libp2p/compare/v0.5.4...v0.5.5) (2017-03-21)

163
README.md
View File

@ -39,7 +39,7 @@ To sum up, libp2p is a "network stack" -- a protocol suite -- that cleanly separ
## Bundles ## Bundles
With its modular nature, libp2p can be found being used in different projects with different sets of features, while perserving the same top level API. `js-libp2p` is only a skelleton and should not be installed directly, if you are looking for a prebundled libp2p stack, please check: With its modular nature, libp2p can be found being used in different projects with different sets of features, while preserving the same top level API. `js-libp2p` is only a skeleton and should not be installed directly, if you are looking for a prebundled libp2p stack, please check:
- [libp2p-ipfs-nodejs](https://github.com/ipfs/js-libp2p-ipfs-nodejs) - The libp2p build used by js-ipfs when run in Node.js - [libp2p-ipfs-nodejs](https://github.com/ipfs/js-libp2p-ipfs-nodejs) - The libp2p build used by js-ipfs when run in Node.js
- [libp2p-ipfs-browser](https://github.com/ipfs/js-libp2p-ipfs-browser) - The libp2p build used by js-ipfs when run in a Browser (that supports WebRTC) - [libp2p-ipfs-browser](https://github.com/ipfs/js-libp2p-ipfs-browser) - The libp2p build used by js-ipfs when run in a Browser (that supports WebRTC)
@ -48,7 +48,7 @@ If you have developed a libp2p bundle, please consider submitting it to this lis
## Install ## Install
> Again, as noted above, this module is only a skeleton and should not be used directly other than libp2p bundle implementors that want to extend its code. Again, as noted above, this module is only a skeleton and should not be used directly other than libp2p bundle implementors that want to extend its code.
```sh ```sh
npm install --save libp2p npm install --save libp2p
@ -56,27 +56,164 @@ npm install --save libp2p
## Usage ## Usage
> **Disclamer - We haven't solidified [libp2p interface](https://github.com/libp2p/interface-libp2p) yet, it might change at anytime.**
### Extending libp2p skeleton ### Extending libp2p skeleton
libp2p becomes very simple and basically acts as a glue for every module that compose this library. Since it can be highly customized, it requires some setup. What we recommend is to have a libp2p build for the system you are developing taking into account in your needs (e.g. for a browser working version of libp2p that acts as the network layer of IPFS, we have a built and minified version that browsers can require) libp2p becomes very simple and basically acts as a glue for every module that compose this library. Since it can be highly customized, it requires some setup. What we recommend is to have a libp2p build for the system you are developing taking into account in your needs (e.g. for a browser working version of libp2p that acts as the network layer of IPFS, we have a built and minified version that browsers can require).
### libp2p API **Example:**
Defined by [interface-libp2p](https://github.com/libp2p/interface-libp2p) ```JavaScript
// Creating a bundle that adds:
// transport: websockets + tcp
// stream-muxing: SPDY
// crypto-channel: secio
// discovery: multicast-dns
## Development const libp2p = require('libp2p')
const TCP = require('libp2p-tcp')
const WS = require('libp2p-websockets')
const spdy = require('libp2p-spdy')
const secio = require('libp2p-secio')
const MulticastDNS = require('libp2p-mdns')
## Linting class Node extends libp2p {
constructor (peerInfo, peerBook, options) {
options = options || {}
```sh const modules = {
> npm run lint transport: [
new TCP(),
new WS()
],
connection: {
muxer: [
spdy
],
crypto: [
secio
]
},
discovery: [
new MulticastDNS(peerInfo, 'your-identifier')
]
}
super(modules, peerInfo, peerBook, options)
}
}
// Now all the nodes you create, will have TCP, WebSockets, SPDY, SECIO and MulticastDNS support.
``` ```
### API
#### Create a Node - `new libp2p.Node([peerInfo, peerBook, options])`
> Creates an instance of the libp2p.Node.
- `peerInfo`: instance of [PeerInfo][] that contains the [PeerId][], Keys and [multiaddrs][multiaddr] of the libp2p Node. Optional.
- `peerBook`: instance of [PeerBook][] that contains the [PeerInfo][] of known peers. Optional.
- `options`: Object containing custom options for the bundle.
#### `libp2p.start(callback)`
> Start the libp2p Node.
`callback` is a function with the following `function (err) {}` signature, where `err` is an Error in case starting the node fails.
#### `libp2p.stop(callback)`
> Stop the libp2p Node.
`callback` is a function with the following `function (err) {}` signature, where `err` is an Error in case stopping the node fails.
#### `libp2p.dial(peer [, protocol, callback])`
> Dials to another peer in the network.
- `peer`: can be an instance of [PeerInfo][], [PeerId][] or [multiaddr][]
- `protocol`: String that defines the protocol (e.g '/ipfs/bitswap/1.1.0')
`callback` is a function with the following `function (err, conn) {}` signature, where `err` is an Error in of failure to dial the connection and `conn` is a [Connection][] instance in case of a protocol selected, if not it is undefined.
#### `libp2p.hangUp(peer, callback)
> Closes an open connection with a peer, graciously.
- `peer`: can be an instance of [PeerInfo][], [PeerId][] or [multiaddr][]
`callback` is a function with the following `function (err) {}` signature, where `err` is an Error in case stopping the node fails.
#### `libp2p.handle(protocol, handlerFunc [, matchFunc])`
> Handle new protocol
- `protocol`: String that defines the protocol (e.g '/ipfs/bitswap/1.1.0')
- `handlerFunc`: Function with signature `function (protocol, conn) {}`
- `matchFunc`: Function for matching on protocol (exact matching, semver, etc). Default to exact match.
#### `libp2p.unhandle(protocol)
> Stop handling protocol
- `protocol`: String that defines the protocol (e.g '/ipfs/bitswap/1.1.0')
#### `libp2p.on('peer:discovery', (peer) => {})`
> Peer has been discovered.
- `peer`: instance of [PeerInfo][]
#### `libp2p.on('peer:connect', (peer) => {})`
> We connected to a new peer
- `peer`: instance of [PeerInfo][]
#### `libp2p.on('peer:disconnect', (peer) => {})`
> We disconnected from Peer
- `peer`: instance of [PeerInfo][]
#### `libp2p.isOn()`
> Check if libp2p is started
#### `libp2p.ping(peer [, options], callback)`
> Ping a node in the network
#### `libp2p.peerBook`
> PeerBook instance of the node
#### `libp2p.peerInfo`
> PeerInfo instance of the node
---------------------
`SOON™`
#### `libp2p.findPeers`
#### `libp2p.findProviders`
#### `libp2p.record.put`
#### `libp2p.record.get`
[PeerInfo]: https://github.com/libp2p/js-peer-info
[PeerId]: https://github.com/libp2p/js-peer-id
[PeerBook]: https://github.com/libp2p/js-peer-book
[multiaddr]: https://github.com/multiformats/js-multiaddr
[Connection]: https://github.com/libp2p/interface-connection
### Packages ### Packages
> List of packages currently in existance for libp2p List of packages currently in existence for libp2p
| Package | Version | Dependencies | DevDependencies | | Package | Version | Dependencies | DevDependencies |
|---------|---------|--------------|-----------------| |---------|---------|--------------|-----------------|
@ -115,7 +252,7 @@ Defined by [interface-libp2p](https://github.com/libp2p/interface-libp2p)
## Contribute ## Contribute
THe libp2p implementation in JavaScript is a work in progress. As such, there's a few things you can do right now to help out: The libp2p implementation in JavaScript is a work in progress. As such, there are a few things you can do right now to help out:
- Go through the modules and **check out existing issues**. This would be especially useful for modules in active development. Some knowledge of IPFS/libp2p may be required, as well as the infrasture behind it - for instance, you may need to read up on p2p and more complex operations like muxing to be able to help technically. - Go through the modules and **check out existing issues**. This would be especially useful for modules in active development. Some knowledge of IPFS/libp2p may be required, as well as the infrasture behind it - for instance, you may need to read up on p2p and more complex operations like muxing to be able to help technically.
- **Perform code reviews**. Most of this has been developed by @diasdavid, which means that more eyes will help a) speed the project along b) ensure quality and c) reduce possible future bugs. - **Perform code reviews**. Most of this has been developed by @diasdavid, which means that more eyes will help a) speed the project along b) ensure quality and c) reduce possible future bugs.

View File

@ -1,6 +1,6 @@
{ {
"name": "libp2p", "name": "libp2p",
"version": "0.3.1", "version": "0.8.0",
"description": "JavaScript Skeleton for libp2p bundles", "description": "JavaScript Skeleton for libp2p bundles",
"main": "src/index.js", "main": "src/index.js",
"scripts": { "scripts": {
@ -32,25 +32,27 @@
"bugs": { "bugs": {
"url": "https://github.com/libp2p/js-libp2p/issues" "url": "https://github.com/libp2p/js-libp2p/issues"
}, },
"homepage": "https://github.com/diasdavid/js-libp2p", "homepage": "https://github.com/libp2p/js-libp2p",
"devDependencies": { "devDependencies": {
"aegir": "^11.0.1",
"chai": "^3.5.0", "chai": "^3.5.0",
"aegir": "^9.1.2", "dirty-chai": "^1.2.2",
"pre-commit": "^1.1.1" "pre-commit": "^1.2.2"
}, },
"dependencies": { "dependencies": {
"libp2p-ping": "^0.3.0", "libp2p-ping": "~0.3.2",
"libp2p-swarm": "^0.26.3", "libp2p-swarm": "~0.29.0",
"mafmt": "^2.1.2", "mafmt": "^2.1.8",
"multiaddr": "^2.1.1", "multiaddr": "^2.3.0",
"peer-book": "^0.3.0", "peer-book": "~0.4.0",
"peer-id": "^0.8.0", "peer-id": "~0.8.6",
"peer-info": "^0.8.1" "peer-info": "~0.9.2"
}, },
"contributors": [ "contributors": [
"David Dias <daviddias.p@gmail.com>", "David Dias <daviddias.p@gmail.com>",
"Friedel Ziegelmayer <dignifiedquire@gmail.com>", "Friedel Ziegelmayer <dignifiedquire@gmail.com>",
"Richard Littauer <richard.littauer@gmail.com>", "Richard Littauer <richard.littauer@gmail.com>",
"greenkeeperio-bot <support@greenkeeper.io>" "greenkeeperio-bot <support@greenkeeper.io>",
"mayerwin <mayerwin@users.noreply.github.com>"
] ]
} }

View File

@ -3,20 +3,21 @@
const Swarm = require('libp2p-swarm') const Swarm = require('libp2p-swarm')
const PeerId = require('peer-id') const PeerId = require('peer-id')
const PeerInfo = require('peer-info') const PeerInfo = require('peer-info')
const mafmt = require('mafmt')
const PeerBook = require('peer-book') const PeerBook = require('peer-book')
const multiaddr = require('multiaddr') const multiaddr = require('multiaddr')
const mafmt = require('mafmt') const EventEmitter = require('events').EventEmitter
const EE = require('events').EventEmitter
const assert = require('assert') const assert = require('assert')
const Ping = require('libp2p-ping') const Ping = require('libp2p-ping')
const setImmediate = require('async/setImmediate')
exports = module.exports exports = module.exports
const OFFLINE_ERROR_MESSAGE = 'The libp2p node is not started yet' const OFFLINE_ERROR_MESSAGE = 'The libp2p node is not started yet'
const IPFS_CODE = 421
class Node { class Node extends EventEmitter {
constructor (_modules, _peerInfo, _peerBook) { constructor (_modules, _peerInfo, _peerBook, _options) {
super()
assert(_modules, 'requires modules to equip libp2p with features') assert(_modules, 'requires modules to equip libp2p with features')
assert(_peerInfo, 'requires a PeerInfo instance') assert(_peerInfo, 'requires a PeerInfo instance')
@ -25,9 +26,7 @@ class Node {
this.peerBook = _peerBook || new PeerBook() this.peerBook = _peerBook || new PeerBook()
this.isOnline = false this.isOnline = false
this.discovery = new EE() this.swarm = new Swarm(this.peerInfo, this.peerBook)
this.swarm = new Swarm(this.peerInfo)
// Attach stream multiplexers // Attach stream multiplexers
if (this.modules.connection.muxer) { if (this.modules.connection.muxer) {
@ -40,14 +39,15 @@ class Node {
// If muxer exists, we can use Identify // If muxer exists, we can use Identify
this.swarm.connection.reuse() this.swarm.connection.reuse()
// Received incommind dial and muxer upgrade happened, reuse this // Received incommind dial and muxer upgrade happened,
// muxed connection // reuse this muxed connection
this.swarm.on('peer-mux-established', (peerInfo) => { this.swarm.on('peer-mux-established', (peerInfo) => {
this.emit('peer:connect', peerInfo)
this.peerBook.put(peerInfo) this.peerBook.put(peerInfo)
}) })
this.swarm.on('peer-mux-closed', (peerInfo) => { this.swarm.on('peer-mux-closed', (peerInfo) => {
this.peerBook.removeByB58String(peerInfo.id.toB58String()) this.emit('peer:disconnect', peerInfo)
}) })
} }
@ -61,13 +61,12 @@ class Node {
} }
// Attach discovery mechanisms // Attach discovery mechanisms
if (this.discovery) { if (this.modules.discovery) {
let discoveries = this.modules.discovery let discoveries = this.modules.discovery
discoveries = Array.isArray(discoveries) ? discoveries : [discoveries] discoveries = Array.isArray(discoveries) ? discoveries : [discoveries]
discoveries.forEach((discovery) => { discoveries.forEach((discovery) => {
discovery.on('peer', (peerInfo) => { discovery.on('peer', (peerInfo) => this.emit('peer:discovery', peerInfo))
this.discovery.emit('peer', peerInfo)
})
}) })
} }
@ -92,7 +91,19 @@ class Node {
let transports = this.modules.transport let transports = this.modules.transport
transports = Array.isArray(transports) ? transports : [transports] transports = Array.isArray(transports) ? transports : [transports]
const multiaddrs = this.peerInfo.multiaddrs
// so that we can have webrtc-star addrs without adding manually the id
const maOld = []
const maNew = []
this.peerInfo.multiaddrs.forEach((ma) => {
if (!mafmt.IPFS.matches(ma)) {
maOld.push(ma)
maNew.push(ma.encapsulate('/ipfs/' + this.peerInfo.id.toB58String()))
}
})
this.peerInfo.multiaddrs.replace(maOld, maNew)
const multiaddrs = this.peerInfo.multiaddrs.toArray()
transports.forEach((transport) => { transports.forEach((transport) => {
if (transport.filter(multiaddrs).length > 0) { if (transport.filter(multiaddrs).length > 0) {
@ -115,6 +126,13 @@ class Node {
} }
this.isOnline = true this.isOnline = true
if (this.modules.discovery) {
this.modules.discovery.forEach((discovery) => {
setImmediate(() => discovery.start(() => {}))
})
}
callback() callback()
}) })
} }
@ -124,145 +142,57 @@ class Node {
*/ */
stop (callback) { stop (callback) {
this.isOnline = false this.isOnline = false
if (this.modules.discovery) {
this.modules.discovery.forEach((discovery) => {
setImmediate(() => discovery.stop(() => {}))
})
}
this.swarm.close(callback) this.swarm.close(callback)
} }
// isOn () {
// Ping return this.isOnline
//
// TODO
pingById (id, callback) {
assert(this.isOnline, OFFLINE_ERROR_MESSAGE)
callback(new Error('not implemented yet'))
} }
// TODO ping (peer, callback) {
pingByMultiaddr (maddr, callback) { assert(this.isOn(), OFFLINE_ERROR_MESSAGE)
assert(this.isOnline, OFFLINE_ERROR_MESSAGE) const peerInfo = this._getPeerInfo(peer)
callback(new Error('not implemented yet'))
}
pingByPeerInfo (peerInfo, callback) {
assert(this.isOnline, OFFLINE_ERROR_MESSAGE)
callback(null, new Ping(this.swarm, peerInfo)) callback(null, new Ping(this.swarm, peerInfo))
} }
// dial (peer, protocol, callback) {
// Dialing methods assert(this.isOn(), OFFLINE_ERROR_MESSAGE)
//
// TODO
dialById (id, protocol, callback) {
// NOTE: dialById only works if a previous dial was made. This will
// change once we have PeerRouting
assert(this.isOnline, OFFLINE_ERROR_MESSAGE)
if (typeof protocol === 'function') { if (typeof protocol === 'function') {
callback = protocol callback = protocol
protocol = undefined protocol = undefined
} }
callback(new Error('not implemented yet')) let peerInfo
}
dialByMultiaddr (maddr, protocol, callback) {
assert(this.isOnline, OFFLINE_ERROR_MESSAGE)
if (typeof protocol === 'function') {
callback = protocol
protocol = undefined
}
if (typeof maddr === 'string') {
maddr = multiaddr(maddr)
}
if (!mafmt.IPFS.matches(maddr.toString())) {
return callback(new Error('multiaddr not valid'))
}
const ipfsIdB58String = maddr.stringTuples().filter((tuple) => {
if (tuple[0] === IPFS_CODE) {
return true
}
})[0][1]
let peer
try { try {
peer = this.peerBook.getByB58String(ipfsIdB58String) peerInfo = this._getPeerInfo(peer)
} catch (err) { } catch (err) {
peer = new PeerInfo(PeerId.createFromB58String(ipfsIdB58String)) return callback(err)
} }
peer.multiaddr.add(maddr) this.swarm.dial(peerInfo, protocol, (err, conn) => {
this.dialByPeerInfo(peer, protocol, callback)
}
dialByPeerInfo (peer, protocol, callback) {
assert(this.isOnline, OFFLINE_ERROR_MESSAGE)
if (typeof protocol === 'function') {
callback = protocol
protocol = undefined
}
this.swarm.dial(peer, protocol, (err, conn) => {
if (err) { if (err) {
return callback(err) return callback(err)
} }
this.peerBook.put(peer) this.peerBook.put(peerInfo)
callback(null, conn) callback(null, conn)
}) })
} }
// hangUp (peer, callback) {
// Disconnecting (hangUp) methods assert(this.isOn(), OFFLINE_ERROR_MESSAGE)
// const peerInfo = this._getPeerInfo(peer)
hangUpById (id, callback) { this.swarm.hangUp(peerInfo, callback)
// TODO
callback(new Error('not implemented yet'))
} }
hangUpByMultiaddr (maddr, callback) {
assert(this.isOnline, OFFLINE_ERROR_MESSAGE)
if (typeof maddr === 'string') {
maddr = multiaddr(maddr)
}
if (!mafmt.IPFS.matches(maddr.toString())) {
return callback(new Error('multiaddr not valid'))
}
const ipfsIdB58String = maddr.stringTuples().filter((tuple) => {
if (tuple[0] === IPFS_CODE) {
return true
}
})[0][1]
try {
const pi = this.peerBook.getByB58String(ipfsIdB58String)
this.hangUpByPeerInfo(pi, callback)
} catch (err) {
// already disconnected
callback()
}
}
hangUpByPeerInfo (peer, callback) {
assert(this.isOnline, OFFLINE_ERROR_MESSAGE)
this.peerBook.removeByB58String(peer.id.toB58String())
this.swarm.hangUp(peer, callback)
}
//
// Protocol multiplexing handling
//
handle (protocol, handlerFunc, matchFunc) { handle (protocol, handlerFunc, matchFunc) {
this.swarm.handle(protocol, handlerFunc, matchFunc) this.swarm.handle(protocol, handlerFunc, matchFunc)
} }
@ -270,6 +200,36 @@ class Node {
unhandle (protocol) { unhandle (protocol) {
this.swarm.unhandle(protocol) this.swarm.unhandle(protocol)
} }
/*
* Helper method to check the data type of peer and convert it to PeerInfo
*/
_getPeerInfo (peer) {
let p
if (PeerInfo.isPeerInfo(peer)) {
p = peer
} else if (multiaddr.isMultiaddr(peer)) {
const peerIdB58Str = peer.getPeerId()
try {
p = this.peerBook.get(peerIdB58Str)
} catch (err) {
p = new PeerInfo(PeerId.createFromB58String(peerIdB58Str))
}
p.multiaddrs.add(peer)
} else if (PeerId.isPeerId(peer)) {
const peerIdB58Str = peer.toB58String()
try {
p = this.peerBook.get(peerIdB58Str)
} catch (err) {
// TODO this is where PeerRouting comes into place
throw new Error('No knowledge about: ' + peerIdB58Str)
}
} else {
throw new Error('peer type not recognized')
}
return p
}
} }
module.exports = Node module.exports = Node

View File

@ -1,12 +1,14 @@
/* eslint-env mocha */ /* eslint-env mocha */
'use strict' 'use strict'
const expect = require('chai').expect const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const libp2p = require('../src') const libp2p = require('../src')
describe('libp2p', () => { describe('libp2p', () => {
it('the skeleton is fine, now go build your own libp2p bundle', () => { it('the skeleton is fine, now go build your own libp2p bundle', () => {
expect(libp2p).to.exist expect(libp2p).to.exist()
}) })
}) })