mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-07-08 13:21:34 +00:00
Compare commits
53 Commits
Author | SHA1 | Date | |
---|---|---|---|
0263b899e3 | |||
fb92e672ee | |||
2e326e1619 | |||
e4e9761c99 | |||
a5b7de1b6b | |||
9a7a381f85 | |||
1f00855e6e | |||
8aa932a491 | |||
babb90fe17 | |||
2f9070a725 | |||
a48ec65961 | |||
031ecb3fe7 | |||
c6bdd869be | |||
dee0340806 | |||
a4b41b0f9a | |||
291e79fc99 | |||
59ea9c388f | |||
300936f2f3 | |||
9f4ec2a915 | |||
c7f4368007 | |||
9ff04779f5 | |||
f73c045767 | |||
8840c9b250 | |||
df4c99df4a | |||
6e05a0b239 | |||
c781abc30c | |||
6a66931ba4 | |||
426fc27b26 | |||
d6325dee90 | |||
f74bc0596d | |||
8f9e82b0fb | |||
9724fa190e | |||
721da9ab41 | |||
d27bd2b912 | |||
2c23d9a718 | |||
a6623c1ba2 | |||
5d4d94e75f | |||
a4b97b9627 | |||
3584209947 | |||
b5209fc456 | |||
932d8772da | |||
baee2b7945 | |||
153f8884fa | |||
b71f77dcf7 | |||
8dc8e0530b | |||
4ed0ce16af | |||
cbb7290a97 | |||
63b10c01e3 | |||
11c21b6999 | |||
109ee51d7b | |||
09182b43bf | |||
a130ab2dc1 | |||
13355bf179 |
73
CHANGELOG.md
Normal file
73
CHANGELOG.md
Normal file
@ -0,0 +1,73 @@
|
||||
<a name="0.9.1"></a>
|
||||
## [0.9.1](https://github.com/libp2p/js-libp2p/compare/v0.9.0...v0.9.1) (2017-04-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* do not use assert in async funcs ([#88](https://github.com/libp2p/js-libp2p/issues/88)) ([2e326e1](https://github.com/libp2p/js-libp2p/commit/2e326e1))
|
||||
|
||||
|
||||
|
||||
<a name="0.9.0"></a>
|
||||
# [0.9.0](https://github.com/libp2p/js-libp2p/compare/v0.8.0...v0.9.0) (2017-04-06)
|
||||
|
||||
|
||||
|
||||
<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)
|
||||
|
||||
|
||||
|
185
README.md
185
README.md
@ -56,24 +56,193 @@ npm install --save libp2p
|
||||
|
||||
## Usage
|
||||
|
||||
> **Disclaimer - We haven't solidified [libp2p interface](https://github.com/libp2p/interface-libp2p) yet, it might change at anytime.**
|
||||
|
||||
### 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 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')
|
||||
const DHT = require('libp2p-kad-dht')
|
||||
|
||||
## Linting
|
||||
class Node extends libp2p {
|
||||
constructor (peerInfo, peerBook, options) {
|
||||
options = options || {}
|
||||
|
||||
```sh
|
||||
> npm run lint
|
||||
const modules = {
|
||||
transport: [
|
||||
new TCP(),
|
||||
new WS()
|
||||
],
|
||||
connection: {
|
||||
muxer: [
|
||||
spdy
|
||||
],
|
||||
crypto: [
|
||||
secio
|
||||
]
|
||||
},
|
||||
discovery: [
|
||||
new MulticastDNS(peerInfo, 'your-identifier')
|
||||
],
|
||||
// DHT is passed as its own enabling PeerRouting, ContentRouting and DHT itself components
|
||||
dht: DHT
|
||||
}
|
||||
|
||||
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.peerRouting.findPeer(id, callback)`
|
||||
|
||||
> Looks up for multiaddrs of a peer in the DHT
|
||||
|
||||
- `id`: instance of [PeerId][]
|
||||
|
||||
#### `libp2p.contentRouting.findProviders(key, timeout, callback)`
|
||||
|
||||
- `key`: Buffer
|
||||
- `timeout`: Number miliseconds
|
||||
|
||||
#### `libp2p.contentRouting.provide(key, callback)`
|
||||
|
||||
- `key`: Buffer
|
||||
|
||||
#### `libp2p.dht.put(key, value, callback)`
|
||||
|
||||
- `key`: Buffer
|
||||
- `value`: Buffer
|
||||
|
||||
#### `libp2p.dht.get(key, callback)`
|
||||
|
||||
- `key`: Buffer
|
||||
|
||||
#### `libp2p.dht.getMany(key, nVals, callback)`
|
||||
|
||||
- `key`: Buffer
|
||||
- `nVals`: Number
|
||||
|
||||
#### `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
|
||||
|
||||
List of packages currently in existence for libp2p
|
||||
|
21
package.json
21
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "libp2p",
|
||||
"version": "0.5.1",
|
||||
"version": "0.9.1",
|
||||
"description": "JavaScript Skeleton for libp2p bundles",
|
||||
"main": "src/index.js",
|
||||
"scripts": {
|
||||
@ -32,20 +32,21 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/libp2p/js-libp2p/issues"
|
||||
},
|
||||
"homepage": "https://github.com/diasdavid/js-libp2p",
|
||||
"homepage": "https://github.com/libp2p/js-libp2p",
|
||||
"devDependencies": {
|
||||
"aegir": "^11.0.1",
|
||||
"chai": "^3.5.0",
|
||||
"aegir": "^9.4.0",
|
||||
"dirty-chai": "^1.2.2",
|
||||
"pre-commit": "^1.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"libp2p-ping": "^0.3.0",
|
||||
"libp2p-swarm": "^0.26.13",
|
||||
"mafmt": "^2.1.6",
|
||||
"multiaddr": "^2.2.0",
|
||||
"peer-book": "^0.3.0",
|
||||
"peer-id": "^0.8.1",
|
||||
"peer-info": "^0.8.2"
|
||||
"libp2p-ping": "~0.3.2",
|
||||
"libp2p-swarm": "~0.29.1",
|
||||
"mafmt": "^2.1.8",
|
||||
"multiaddr": "^2.3.0",
|
||||
"peer-book": "~0.4.0",
|
||||
"peer-id": "~0.8.7",
|
||||
"peer-info": "~0.9.2"
|
||||
},
|
||||
"contributors": [
|
||||
"David Dias <daviddias.p@gmail.com>",
|
||||
|
337
src/index.js
337
src/index.js
@ -1,22 +1,27 @@
|
||||
'use strict'
|
||||
|
||||
const EventEmitter = require('events').EventEmitter
|
||||
const assert = require('assert')
|
||||
|
||||
const setImmediate = require('async/setImmediate')
|
||||
const each = require('async/each')
|
||||
const series = require('async/series')
|
||||
|
||||
const Ping = require('libp2p-ping')
|
||||
const Swarm = require('libp2p-swarm')
|
||||
const PeerId = require('peer-id')
|
||||
const PeerInfo = require('peer-info')
|
||||
const PeerBook = require('peer-book')
|
||||
const multiaddr = require('multiaddr')
|
||||
const mafmt = require('mafmt')
|
||||
const EE = require('events').EventEmitter
|
||||
const assert = require('assert')
|
||||
const Ping = require('libp2p-ping')
|
||||
const multiaddr = require('multiaddr')
|
||||
|
||||
exports = module.exports
|
||||
|
||||
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, _options) {
|
||||
super()
|
||||
assert(_modules, 'requires modules to equip libp2p with features')
|
||||
assert(_peerInfo, 'requires a PeerInfo instance')
|
||||
|
||||
@ -25,29 +30,26 @@ class Node {
|
||||
this.peerBook = _peerBook || new PeerBook()
|
||||
this.isOnline = false
|
||||
|
||||
this.discovery = new EE()
|
||||
|
||||
this.swarm = new Swarm(this.peerInfo)
|
||||
this.swarm = new Swarm(this.peerInfo, this.peerBook)
|
||||
|
||||
// Attach stream multiplexers
|
||||
if (this.modules.connection.muxer) {
|
||||
let muxers = this.modules.connection.muxer
|
||||
muxers = Array.isArray(muxers) ? muxers : [muxers]
|
||||
muxers.forEach((muxer) => {
|
||||
this.swarm.connection.addStreamMuxer(muxer)
|
||||
})
|
||||
muxers.forEach((muxer) => this.swarm.connection.addStreamMuxer(muxer))
|
||||
|
||||
// If muxer exists, we can use Identify
|
||||
this.swarm.connection.reuse()
|
||||
|
||||
// Received incommind dial and muxer upgrade happened, reuse this
|
||||
// muxed connection
|
||||
// Received incommind dial and muxer upgrade happened,
|
||||
// reuse this muxed connection
|
||||
this.swarm.on('peer-mux-established', (peerInfo) => {
|
||||
this.emit('peer:connect', peerInfo)
|
||||
this.peerBook.put(peerInfo)
|
||||
})
|
||||
|
||||
this.swarm.on('peer-mux-closed', (peerInfo) => {
|
||||
this.peerBook.removeByB58String(peerInfo.id.toB58String())
|
||||
this.emit('peer:disconnect', peerInfo)
|
||||
})
|
||||
}
|
||||
|
||||
@ -64,19 +66,70 @@ class Node {
|
||||
if (this.modules.discovery) {
|
||||
let discoveries = this.modules.discovery
|
||||
discoveries = Array.isArray(discoveries) ? discoveries : [discoveries]
|
||||
|
||||
discoveries.forEach((discovery) => {
|
||||
discovery.on('peer', (peerInfo) => {
|
||||
this.discovery.emit('peer', peerInfo)
|
||||
})
|
||||
discovery.on('peer', (peerInfo) => this.emit('peer:discovery', peerInfo))
|
||||
})
|
||||
}
|
||||
|
||||
// Mount default protocols
|
||||
Ping.mount(this.swarm)
|
||||
|
||||
// Not fully implemented in js-libp2p yet
|
||||
this.routing = undefined
|
||||
this.records = undefined
|
||||
// dht provided components (peerRouting, contentRouting, dht)
|
||||
if (_modules.DHT) {
|
||||
this._dht = new this.modules.DHT(this, 20, _options.DHT && _options.DHT.datastore)
|
||||
}
|
||||
|
||||
this.peerRouting = {
|
||||
findPeer: (id, callback) => {
|
||||
if (!this._dht) {
|
||||
return callback(new Error('DHT is not available'))
|
||||
}
|
||||
|
||||
this._dht.findPeer(id, callback)
|
||||
}
|
||||
}
|
||||
|
||||
this.contentRouting = {
|
||||
findProviders: (key, timeout, callback) => {
|
||||
if (!this._dht) {
|
||||
return callback(new Error('DHT is not available'))
|
||||
}
|
||||
|
||||
this._dht.findProviders(key, timeout, callback)
|
||||
},
|
||||
provide: (key, callback) => {
|
||||
if (!this._dht) {
|
||||
return callback(new Error('DHT is not available'))
|
||||
}
|
||||
|
||||
this._dht.provide(key, callback)
|
||||
}
|
||||
}
|
||||
|
||||
this.dht = {
|
||||
put: (key, value, callback) => {
|
||||
if (!this._dht) {
|
||||
return callback(new Error('DHT is not available'))
|
||||
}
|
||||
|
||||
this._dht.put(key, value, callback)
|
||||
},
|
||||
get: (key, callback) => {
|
||||
if (!this._dht) {
|
||||
return callback(new Error('DHT is not available'))
|
||||
}
|
||||
|
||||
this._dht.get(key, callback)
|
||||
},
|
||||
getMany (key, nVals, callback) {
|
||||
if (!this._dht) {
|
||||
return callback(new Error('DHT is not available'))
|
||||
}
|
||||
|
||||
this._dht.getMany(key, nVals, callback)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -92,7 +145,19 @@ class Node {
|
||||
let transports = this.modules.transport
|
||||
|
||||
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) => {
|
||||
if (transport.filter(multiaddrs).length > 0) {
|
||||
@ -106,24 +171,30 @@ class Node {
|
||||
}
|
||||
})
|
||||
|
||||
this.swarm.listen((err) => {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
if (ws) {
|
||||
this.swarm.transport.add(ws.tag || ws.constructor.name, ws)
|
||||
}
|
||||
series([
|
||||
(cb) => this.swarm.listen(cb),
|
||||
(cb) => {
|
||||
// listeners on, libp2p is on
|
||||
this.isOnline = true
|
||||
|
||||
this.isOnline = true
|
||||
if (ws) {
|
||||
// always add dialing on websockets
|
||||
this.swarm.transport.add(ws.tag || ws.constructor.name, ws)
|
||||
}
|
||||
|
||||
if (this.modules.discovery) {
|
||||
this.modules.discovery.forEach((discovery) => {
|
||||
setImmediate(() => discovery.start(() => {}))
|
||||
})
|
||||
// all transports need to be setup before discover starts
|
||||
if (this.modules.discovery) {
|
||||
return each(this.modules.discovery, (d, cb) => d.start(cb), cb)
|
||||
}
|
||||
cb()
|
||||
},
|
||||
(cb) => {
|
||||
if (this._dht) {
|
||||
return this._dht.start(cb)
|
||||
}
|
||||
cb()
|
||||
}
|
||||
|
||||
callback()
|
||||
})
|
||||
], callback)
|
||||
}
|
||||
|
||||
/*
|
||||
@ -138,145 +209,67 @@ class Node {
|
||||
})
|
||||
}
|
||||
|
||||
this.swarm.close(callback)
|
||||
series([
|
||||
(cb) => {
|
||||
if (this._dht) {
|
||||
return this._dht.stop(cb)
|
||||
}
|
||||
cb()
|
||||
},
|
||||
(cb) => this.swarm.close(cb)
|
||||
], callback)
|
||||
}
|
||||
|
||||
//
|
||||
// Ping
|
||||
//
|
||||
|
||||
// TODO
|
||||
pingById (id, callback) {
|
||||
assert(this.isOnline, OFFLINE_ERROR_MESSAGE)
|
||||
callback(new Error('not implemented yet'))
|
||||
isOn () {
|
||||
return this.isOnline
|
||||
}
|
||||
|
||||
// TODO
|
||||
pingByMultiaddr (maddr, callback) {
|
||||
assert(this.isOnline, OFFLINE_ERROR_MESSAGE)
|
||||
callback(new Error('not implemented yet'))
|
||||
}
|
||||
|
||||
pingByPeerInfo (peerInfo, callback) {
|
||||
assert(this.isOnline, OFFLINE_ERROR_MESSAGE)
|
||||
callback(null, new Ping(this.swarm, peerInfo))
|
||||
}
|
||||
|
||||
//
|
||||
// Dialing methods
|
||||
//
|
||||
|
||||
// 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') {
|
||||
callback = protocol
|
||||
protocol = undefined
|
||||
}
|
||||
|
||||
callback(new Error('not implemented yet'))
|
||||
}
|
||||
|
||||
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 {
|
||||
peer = this.peerBook.getByB58String(ipfsIdB58String)
|
||||
} catch (err) {
|
||||
peer = new PeerInfo(PeerId.createFromB58String(ipfsIdB58String))
|
||||
}
|
||||
|
||||
peer.multiaddr.add(maddr)
|
||||
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) => {
|
||||
ping (peer, callback) {
|
||||
assert(this.isOn(), OFFLINE_ERROR_MESSAGE)
|
||||
this._getPeerInfo(peer, (err, peerInfo) => {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
this.peerBook.put(peer)
|
||||
callback(null, conn)
|
||||
|
||||
callback(null, new Ping(this.swarm, peerInfo))
|
||||
})
|
||||
}
|
||||
|
||||
//
|
||||
// Disconnecting (hangUp) methods
|
||||
//
|
||||
dial (peer, protocol, callback) {
|
||||
assert(this.isOn(), OFFLINE_ERROR_MESSAGE)
|
||||
|
||||
hangUpById (id, 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 (typeof protocol === 'function') {
|
||||
callback = protocol
|
||||
protocol = undefined
|
||||
}
|
||||
|
||||
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
|
||||
this._getPeerInfo(peer, (err, peerInfo) => {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
})[0][1]
|
||||
|
||||
try {
|
||||
const pi = this.peerBook.getByB58String(ipfsIdB58String)
|
||||
this.hangUpByPeerInfo(pi, callback)
|
||||
} catch (err) {
|
||||
// already disconnected
|
||||
callback()
|
||||
}
|
||||
this.swarm.dial(peerInfo, protocol, (err, conn) => {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
this.peerBook.put(peerInfo)
|
||||
callback(null, conn)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
hangUpByPeerInfo (peer, callback) {
|
||||
assert(this.isOnline, OFFLINE_ERROR_MESSAGE)
|
||||
hangUp (peer, callback) {
|
||||
assert(this.isOn(), OFFLINE_ERROR_MESSAGE)
|
||||
|
||||
this.peerBook.removeByB58String(peer.id.toB58String())
|
||||
this.swarm.hangUp(peer, callback)
|
||||
this._getPeerInfo(peer, (err, peerInfo) => {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
this.swarm.hangUp(peerInfo, callback)
|
||||
})
|
||||
}
|
||||
|
||||
//
|
||||
// Protocol multiplexing handling
|
||||
//
|
||||
|
||||
handle (protocol, handlerFunc, matchFunc) {
|
||||
this.swarm.handle(protocol, handlerFunc, matchFunc)
|
||||
}
|
||||
@ -284,6 +277,38 @@ class Node {
|
||||
unhandle (protocol) {
|
||||
this.swarm.unhandle(protocol)
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper method to check the data type of peer and convert it to PeerInfo
|
||||
*/
|
||||
_getPeerInfo (peer, callback) {
|
||||
let p
|
||||
// PeerInfo
|
||||
if (PeerInfo.isPeerInfo(peer)) {
|
||||
p = peer
|
||||
// Multiaddr instance (not string)
|
||||
} 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)
|
||||
// PeerId
|
||||
} else if (PeerId.isPeerId(peer)) {
|
||||
const peerIdB58Str = peer.toB58String()
|
||||
try {
|
||||
p = this.peerBook.get(peerIdB58Str)
|
||||
} catch (err) {
|
||||
return this.peerRouting.findPeer(peer, callback)
|
||||
}
|
||||
} else {
|
||||
return setImmediate(() => callback(new Error('peer type not recognized')))
|
||||
}
|
||||
|
||||
setImmediate(() => callback(null, p))
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Node
|
||||
|
@ -1,12 +1,14 @@
|
||||
/* eslint-env mocha */
|
||||
'use strict'
|
||||
|
||||
const expect = require('chai').expect
|
||||
const chai = require('chai')
|
||||
chai.use(require('dirty-chai'))
|
||||
const expect = chai.expect
|
||||
|
||||
const libp2p = require('../src')
|
||||
|
||||
describe('libp2p', () => {
|
||||
it('the skeleton is fine, now go build your own libp2p bundle', () => {
|
||||
expect(libp2p).to.exist
|
||||
expect(libp2p).to.exist()
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user