mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-07-09 22:01:34 +00:00
Compare commits
17 Commits
v0.24.0-rc
...
v0.24.0
Author | SHA1 | Date | |
---|---|---|---|
2e4459b315 | |||
2a5232b541 | |||
44915b3723 | |||
64bba57255 | |||
88ebd1fc09 | |||
92cd591da4 | |||
320d84f541 | |||
970deec2a4 | |||
714b6ec2b9 | |||
f71fdfdf35 | |||
e92053da9a | |||
17b5f73b3d | |||
c18d2a4147 | |||
f1baa7e0b1 | |||
4abc868ab3 | |||
40e840d5fd | |||
9518eb44b3 |
@ -1,3 +1,8 @@
|
||||
<a name="0.24.0"></a>
|
||||
# [0.24.0](https://github.com/libp2p/js-libp2p/compare/v0.24.0-rc.3...v0.24.0) (2018-11-16)
|
||||
|
||||
|
||||
|
||||
<a name="0.23.1"></a>
|
||||
## [0.23.1](https://github.com/libp2p/js-libp2p/compare/v0.23.0...v0.23.1) (2018-08-13)
|
||||
|
||||
|
@ -261,12 +261,12 @@ Required keys in the `options` object:
|
||||
- `key`: Buffer
|
||||
- `options`: object of options
|
||||
- `options.maxTimeout`: Number milliseconds
|
||||
- `options.maxNumProviders` maximum number of providers to find
|
||||
|
||||
#### `libp2p.contentRouting.provide(key, callback)`
|
||||
|
||||
- `key`: Buffer
|
||||
|
||||
|
||||
#### `libp2p.handle(protocol, handlerFunc [, matchFunc])`
|
||||
|
||||
> Handle new protocol
|
||||
|
29
appveyor.yml
29
appveyor.yml
@ -1,29 +0,0 @@
|
||||
# Warning: This file is automatically synced from https://github.com/ipfs/ci-sync so if you want to change it, please change it there and ask someone to sync all repositories.
|
||||
version: "{build}"
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- nodejs_version: "6"
|
||||
- nodejs_version: "8"
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
install:
|
||||
# Install Node.js
|
||||
- ps: Install-Product node $env:nodejs_version
|
||||
|
||||
# Upgrade npm
|
||||
- npm install -g npm
|
||||
|
||||
# Output our current versions for debugging
|
||||
- node --version
|
||||
- npm --version
|
||||
|
||||
# Install our package dependencies
|
||||
- npm install
|
||||
|
||||
test_script:
|
||||
- npm run test:node
|
||||
|
||||
build: off
|
22
circle.yml
22
circle.yml
@ -1,22 +0,0 @@
|
||||
machine:
|
||||
node:
|
||||
version: 8.11.3
|
||||
|
||||
test:
|
||||
post:
|
||||
- npm run coverage -- --upload --providers coveralls
|
||||
|
||||
dependencies:
|
||||
pre:
|
||||
- google-chrome --version
|
||||
- curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
|
||||
- for v in $(curl http://archive.ubuntu.com/ubuntu/pool/main/n/nss/ | grep "href=" | grep "libnss3.*deb\"" -o | grep -o "libnss3.*deb" | grep "3.28" | grep "14.04"); do curl -L -o $v http://archive.ubuntu.com/ubuntu/pool/main/n/nss/$v; done && rm libnss3-tools*_i386.deb libnss3-dev*_i386.deb
|
||||
- sudo dpkg -i google-chrome.deb || true
|
||||
- sudo dpkg -i libnss3*.deb || true
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install -f || true
|
||||
- sudo dpkg -i libnss3*.deb
|
||||
- sudo apt-get install -f
|
||||
- sudo apt-get install --only-upgrade lsb-base
|
||||
- sudo dpkg -i google-chrome.deb
|
||||
- google-chrome --version
|
@ -10,4 +10,4 @@ This example creates a simple chat app in your terminal.
|
||||
1. Run the listener in window 1, `node listener.js`
|
||||
2. Run the dialer in window 2, `node dialer.js`
|
||||
3. Type a message in either window and hit _enter_
|
||||
4. Tell youself secrets to your hearts content!
|
||||
4. Tell yourself secrets to your hearts content!
|
||||
|
@ -3,7 +3,7 @@
|
||||
const TCP = require('libp2p-tcp')
|
||||
const MulticastDNS = require('libp2p-mdns')
|
||||
const WS = require('libp2p-websockets')
|
||||
const Bootstrap = require('libp2p-railing')
|
||||
const Bootstrap = require('libp2p-bootstrap')
|
||||
const spdy = require('libp2p-spdy')
|
||||
const KadDHT = require('libp2p-kad-dht')
|
||||
const mplex = require('libp2p-mplex')
|
||||
|
@ -18,8 +18,8 @@ various Peer Discovery modules and see the impact it has on your Peer count.
|
||||
1. Install IPFS locally if you dont already have it. [Install Guide](https://docs.ipfs.io/introduction/install/)
|
||||
2. Run the IPFS daemon: `ipfs daemon`
|
||||
3. The daemon will output a line about its API address, like `API server listening on /ip4/127.0.0.1/tcp/8080`
|
||||
4. In another window output the addresses of the node: `ipfs id`. Make note of the websocket address, is will contain `/ws/` in the address.
|
||||
5. In `./src/libp2p-bundle.js` replace the `delegatedApiOptions` host and port of your node if they are different.
|
||||
4. In another window output the addresses of the node: `ipfs id`. Make note of the websocket address, it will contain `/ws/` in the address.
|
||||
5. In `./src/libp2p-bundle.js` check if the host and port of your node are correct, according to the previous step. If they are different, replace them.
|
||||
6. In `./src/App.js` replace `BootstrapNode` with your nodes Websocket address from step 4.
|
||||
7. Start this example:
|
||||
|
||||
|
@ -6,7 +6,7 @@ const TCP = require('libp2p-tcp')
|
||||
const Mplex = require('libp2p-mplex')
|
||||
const SECIO = require('libp2p-secio')
|
||||
const PeerInfo = require('peer-info')
|
||||
const Bootstrap = require('libp2p-railing')
|
||||
const Bootstrap = require('libp2p-bootstrap')
|
||||
const waterfall = require('async/waterfall')
|
||||
const defaultsDeep = require('@nodeutils/defaults-deep')
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
const TCP = require('libp2p-tcp')
|
||||
const MulticastDNS = require('libp2p-mdns')
|
||||
const WS = require('libp2p-websockets')
|
||||
const Bootstrap = require('libp2p-railing')
|
||||
const Bootstrap = require('libp2p-bootstrap')
|
||||
const spdy = require('libp2p-spdy')
|
||||
const KadDHT = require('libp2p-kad-dht')
|
||||
const mplex = require('libp2p-mplex')
|
||||
|
@ -37,4 +37,4 @@ And that's it, from now on, all your libp2p communications are encrypted. Try ru
|
||||
|
||||
If you want to want to learn more about how SECIO works, you can read the [great write up done by Dominic Tarr](https://github.com/auditdrivencrypto/secure-channel/blob/master/prior-art.md#ipfss-secure-channel).
|
||||
|
||||
Importante note: SECIO hasn't been audited and so, we do not recommend to trust its security. We intent to move to TLS 1.3 once the specification is finalized and an implementation exists that we can use.
|
||||
Important note: SECIO hasn't been audited and so, we do not recommend to trust its security. We intent to move to TLS 1.3 once the specification is finalized and an implementation exists that we can use.
|
||||
|
@ -17,11 +17,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"detect-dom-ready": "^1.0.2",
|
||||
"libp2p-bootstrap": "~0.9.3",
|
||||
"libp2p-mplex": "~0.8.0",
|
||||
"libp2p-railing": "~0.9.1",
|
||||
"libp2p-secio": "~0.10.0",
|
||||
"libp2p-spdy": "~0.12.1",
|
||||
"libp2p-webrtc-star": "~0.15.3",
|
||||
"libp2p-websocket-star": "~0.8.1",
|
||||
"libp2p-websockets": "~0.12.0",
|
||||
"peer-info": "~0.14.1"
|
||||
}
|
||||
|
@ -2,15 +2,16 @@
|
||||
|
||||
const WebRTCStar = require('libp2p-webrtc-star')
|
||||
const WebSockets = require('libp2p-websockets')
|
||||
const WebSocketStar = require('libp2p-websocket-star')
|
||||
const Mplex = require('libp2p-mplex')
|
||||
const SPDY = require('libp2p-spdy')
|
||||
const SECIO = require('libp2p-secio')
|
||||
const Bootstrap = require('libp2p-railing')
|
||||
const Bootstrap = require('libp2p-bootstrap')
|
||||
const defaultsDeep = require('@nodeutils/defaults-deep')
|
||||
const libp2p = require('../../../../')
|
||||
|
||||
// Find this list at: https://github.com/ipfs/js-ipfs/blob/master/src/core/runtime/config-browser.json
|
||||
const bootstrapers = [
|
||||
const bootstrapList = [
|
||||
'/dns4/ams-1.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd',
|
||||
'/dns4/sfo-1.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx',
|
||||
'/dns4/lon-1.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3',
|
||||
@ -19,19 +20,21 @@ const bootstrapers = [
|
||||
'/dns4/sgp-1.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu',
|
||||
'/dns4/nyc-1.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm',
|
||||
'/dns4/nyc-2.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64',
|
||||
'/dns4/wss0.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmZMxNdpMkewiVZLMRxaNxUeZpDUb34pWjZ1kZvsd16Zic',
|
||||
'/dns4/wss1.bootstrap.libp2p.io/tcp/443/wss/ipfs/Qmbut9Ywz9YEDrz8ySBSgWyJk41Uvm2QJPhwDJzJyGFsD6'
|
||||
'/dns4/node0.preload.ipfs.io/tcp/443/wss/ipfs/QmZMxNdpMkewiVZLMRxaNxUeZpDUb34pWjZ1kZvsd16Zic',
|
||||
'/dns4/node0.preload.ipfs.io/tcp/443/wss/ipfs/Qmbut9Ywz9YEDrz8ySBSgWyJk41Uvm2QJPhwDJzJyGFsD6'
|
||||
]
|
||||
|
||||
class Node extends libp2p {
|
||||
constructor (_options) {
|
||||
const wrtcStar = new WebRTCStar({ id: _options.peerInfo.id })
|
||||
const wsstar = new WebSocketStar({ id: _options.peerInfo.id })
|
||||
|
||||
const defaults = {
|
||||
modules: {
|
||||
transport: [
|
||||
wrtcStar,
|
||||
new WebSockets()
|
||||
WebSockets,
|
||||
wsstar
|
||||
],
|
||||
streamMuxer: [
|
||||
Mplex,
|
||||
@ -42,6 +45,7 @@ class Node extends libp2p {
|
||||
],
|
||||
peerDiscovery: [
|
||||
wrtcStar.discovery,
|
||||
wsstar.discovery,
|
||||
Bootstrap
|
||||
]
|
||||
},
|
||||
@ -55,14 +59,14 @@ class Node extends libp2p {
|
||||
},
|
||||
bootstrap: {
|
||||
interval: 10000,
|
||||
enabled: false,
|
||||
list: bootstrapers
|
||||
enabled: true,
|
||||
list: bootstrapList
|
||||
}
|
||||
},
|
||||
relay: {
|
||||
enabled: false,
|
||||
enabled: true,
|
||||
hop: {
|
||||
enabled: false,
|
||||
enabled: true,
|
||||
active: false
|
||||
}
|
||||
},
|
||||
@ -70,6 +74,9 @@ class Node extends libp2p {
|
||||
dht: false,
|
||||
pubsub: false
|
||||
}
|
||||
},
|
||||
connectionManager: {
|
||||
maxPeers: 50
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* eslint-disable no-console */
|
||||
/* eslint no-console: ["error", { allow: ["log"] }] */
|
||||
/* eslint max-nested-callbacks: ["error", 5] */
|
||||
'use strict'
|
||||
|
||||
const domReady = require('detect-dom-ready')
|
||||
@ -13,13 +14,25 @@ domReady(() => {
|
||||
return console.log('Could not create the Node, check if your browser has WebRTC Support', err)
|
||||
}
|
||||
|
||||
node.on('peer:discovery', (peerInfo) => {
|
||||
console.log('Discovered a peer')
|
||||
const idStr = peerInfo.id.toB58String()
|
||||
console.log('Discovered: ' + idStr)
|
||||
let connections = {}
|
||||
|
||||
node.on('peer:discovery', (peerInfo) => {
|
||||
const idStr = peerInfo.id.toB58String()
|
||||
if (connections[idStr]) {
|
||||
// If we're already trying to connect to this peer, dont dial again
|
||||
return
|
||||
}
|
||||
console.log('Discovered a peer:', idStr)
|
||||
|
||||
connections[idStr] = true
|
||||
node.dial(peerInfo, (err, conn) => {
|
||||
if (err) { return console.log('Failed to dial:', idStr) }
|
||||
if (err) {
|
||||
// Prevent immediate connection retries from happening
|
||||
// and include a 10s jitter
|
||||
const timeToNextDial = 25 * 1000 + (Math.random(0) * 10000).toFixed(0)
|
||||
console.log('Failed to dial:', idStr)
|
||||
setTimeout(() => delete connections[idStr], timeToNextDial)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@ -34,8 +47,10 @@ domReady(() => {
|
||||
|
||||
node.on('peer:disconnect', (peerInfo) => {
|
||||
const idStr = peerInfo.id.toB58String()
|
||||
delete connections[idStr]
|
||||
console.log('Lost connection to: ' + idStr)
|
||||
document.getElementById(idStr).remove()
|
||||
const el = document.getElementById(idStr)
|
||||
el && el.remove()
|
||||
})
|
||||
|
||||
node.start((err) => {
|
||||
|
50
package.json
50
package.json
@ -1,9 +1,13 @@
|
||||
{
|
||||
"name": "libp2p",
|
||||
"version": "0.23.1",
|
||||
"version": "0.24.0",
|
||||
"description": "JavaScript base class for libp2p bundles",
|
||||
"leadMaintainer": "Jacob Heun <jacobheun@gmail.com>",
|
||||
"main": "src/index.js",
|
||||
"files": [
|
||||
"dist",
|
||||
"src"
|
||||
],
|
||||
"scripts": {
|
||||
"lint": "aegir lint",
|
||||
"build": "aegir build",
|
||||
@ -38,51 +42,52 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "^2.6.1",
|
||||
"debug": "^4.0.1",
|
||||
"debug": "^4.1.0",
|
||||
"err-code": "^1.1.2",
|
||||
"fsm-event": "^2.1.0",
|
||||
"joi": "^13.6.0",
|
||||
"joi": "^14.0.6",
|
||||
"joi-browser": "^13.4.0",
|
||||
"libp2p-connection-manager": "~0.0.2",
|
||||
"libp2p-floodsub": "~0.15.0",
|
||||
"libp2p-ping": "~0.8.0",
|
||||
"libp2p-switch": "~0.41.0",
|
||||
"libp2p-floodsub": "~0.15.1",
|
||||
"libp2p-ping": "~0.8.3",
|
||||
"libp2p-switch": "~0.41.2",
|
||||
"libp2p-websockets": "~0.12.0",
|
||||
"mafmt": "^6.0.2",
|
||||
"multiaddr": "^5.0.0",
|
||||
"nock": "^9.4.3",
|
||||
"multiaddr": "^5.0.2",
|
||||
"peer-book": "~0.8.0",
|
||||
"peer-id": "~0.11.0",
|
||||
"peer-id": "~0.12.0",
|
||||
"peer-info": "~0.14.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nodeutils/defaults-deep": "^1.1.0",
|
||||
"aegir": "^15.2.0",
|
||||
"chai": "^4.1.2",
|
||||
"aegir": "^17.0.1",
|
||||
"chai": "^4.2.0",
|
||||
"chai-checkmark": "^1.0.1",
|
||||
"cids": "~0.5.3",
|
||||
"cids": "~0.5.5",
|
||||
"dirty-chai": "^2.0.1",
|
||||
"electron-webrtc": "~0.3.0",
|
||||
"interface-datastore": "~0.6.0",
|
||||
"libp2p-bootstrap": "~0.9.3",
|
||||
"libp2p-circuit": "~0.2.1",
|
||||
"libp2p-circuit": "~0.3.0",
|
||||
"libp2p-delegated-content-routing": "~0.2.2",
|
||||
"libp2p-delegated-peer-routing": "~0.2.2",
|
||||
"libp2p-kad-dht": "~0.10.5",
|
||||
"libp2p-kad-dht": "~0.11.1",
|
||||
"libp2p-mdns": "~0.12.0",
|
||||
"libp2p-mplex": "~0.8.2",
|
||||
"libp2p-secio": "~0.10.0",
|
||||
"libp2p-spdy": "~0.12.1",
|
||||
"libp2p-mplex": "~0.8.4",
|
||||
"libp2p-secio": "~0.10.1",
|
||||
"libp2p-spdy": "~0.13.0",
|
||||
"libp2p-tcp": "~0.13.0",
|
||||
"libp2p-webrtc-star": "~0.15.5",
|
||||
"libp2p-websocket-star": "~0.8.1",
|
||||
"libp2p-websocket-star-rendezvous": "~0.2.3",
|
||||
"libp2p-websocket-star": "~0.9.0",
|
||||
"libp2p-websocket-star-rendezvous": "~0.2.4",
|
||||
"lodash.times": "^4.3.2",
|
||||
"nock": "^10.0.2",
|
||||
"pull-goodbye": "0.0.2",
|
||||
"pull-serializer": "~0.3.2",
|
||||
"pull-stream": "^3.6.9",
|
||||
"sinon": "^6.3.4",
|
||||
"sinon": "^7.1.1",
|
||||
"webrtcsupport": "^2.2.0",
|
||||
"wrtc": "~0.2.0"
|
||||
"wrtc": "~0.3.2"
|
||||
},
|
||||
"contributors": [
|
||||
"Alan Shaw <alan@tableflip.io>",
|
||||
@ -96,6 +101,7 @@
|
||||
"Florian-Merle <florian.david.merle@gmail.com>",
|
||||
"Friedel Ziegelmayer <dignifiedquire@gmail.com>",
|
||||
"Giovanni T. Parra <fiatjaf@gmail.com>",
|
||||
"Henrique Dias <hacdias@gmail.com>",
|
||||
"Hugo Dias <hugomrdias@gmail.com>",
|
||||
"Irakli Gozalishvili <rfobic@gmail.com>",
|
||||
"Jacob Heun <jacobheun@gmail.com>",
|
||||
@ -113,6 +119,8 @@
|
||||
"Ryan Bell <ryan@piing.net>",
|
||||
"Sönke Hahn <soenkehahn@gmail.com>",
|
||||
"Tiago Alves <alvesjtiago@gmail.com>",
|
||||
"Vasco Santos <vasco.santos@ua.pt>",
|
||||
"Vasco Santos <vasco.santos@moxy.studio>",
|
||||
"Volker Mische <volker.mische@gmail.com>",
|
||||
"Zane Starr <zcstarr@gmail.com>",
|
||||
"greenkeeperio-bot <support@greenkeeper.io>",
|
||||
|
@ -7,6 +7,7 @@ const ModuleSchema = Joi.alternatives().try(Joi.func(), Joi.object())
|
||||
const OptionsSchema = Joi.object({
|
||||
// TODO: create proper validators for the generics
|
||||
connectionManager: Joi.object(),
|
||||
datastore: Joi.object(),
|
||||
peerInfo: Joi.object().required(),
|
||||
peerBook: Joi.object(),
|
||||
modules: Joi.object().keys({
|
||||
|
@ -20,14 +20,11 @@ module.exports = (node) => {
|
||||
* @param {CID} key The CID key of the content to find
|
||||
* @param {object} options
|
||||
* @param {number} options.maxTimeout How long the query should run
|
||||
* @param {number} options.maxNumProviders - maximum number of providers to find
|
||||
* @param {function(Error, Result<Array>)} callback
|
||||
* @returns {void}
|
||||
*/
|
||||
findProviders: (key, options, callback) => {
|
||||
if (!routers.length) {
|
||||
return callback(errCode(new Error('No content routers available'), 'NO_ROUTERS_AVAILABLE'))
|
||||
}
|
||||
|
||||
if (typeof options === 'function') {
|
||||
callback = options
|
||||
options = {}
|
||||
@ -37,6 +34,10 @@ module.exports = (node) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (!routers.length) {
|
||||
return callback(errCode(new Error('No content routers available'), 'NO_ROUTERS_AVAILABLE'))
|
||||
}
|
||||
|
||||
const tasks = routers.map((router) => {
|
||||
return (cb) => router.findProviders(key, options, (err, results) => {
|
||||
if (err) {
|
||||
|
@ -3,7 +3,7 @@
|
||||
const PeerId = require('peer-id')
|
||||
const PeerInfo = require('peer-info')
|
||||
const multiaddr = require('multiaddr')
|
||||
const setImmediate = require('async/setImmediate')
|
||||
const errCode = require('err-code')
|
||||
|
||||
module.exports = (node) => {
|
||||
/*
|
||||
@ -20,16 +20,21 @@ module.exports = (node) => {
|
||||
try {
|
||||
peer = multiaddr(peer)
|
||||
} catch (err) {
|
||||
return setImmediate(() => callback(err))
|
||||
return callback(
|
||||
errCode(err, 'ERR_INVALID_MULTIADDR')
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const peerIdB58Str = peer.getPeerId()
|
||||
|
||||
if (!peerIdB58Str) {
|
||||
return setImmediate(() => {
|
||||
callback(new Error('peer multiaddr instance or string must include peerId'))
|
||||
})
|
||||
return callback(
|
||||
errCode(
|
||||
new Error('peer multiaddr instance or string must include peerId'),
|
||||
'ERR_INVALID_MULTIADDR'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
@ -48,9 +53,14 @@ module.exports = (node) => {
|
||||
return node.peerRouting.findPeer(peer, callback)
|
||||
}
|
||||
} else {
|
||||
return setImmediate(() => callback(new Error('peer type not recognized')))
|
||||
return callback(
|
||||
errCode(
|
||||
new Error(`${p} is not a valid peer type`),
|
||||
'ERR_INVALID_PEER_TYPE'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
setImmediate(() => callback(null, p))
|
||||
callback(null, p)
|
||||
}
|
||||
}
|
||||
|
23
src/index.js
23
src/index.js
@ -41,6 +41,7 @@ class Node extends EventEmitter {
|
||||
// and add default values where appropriate
|
||||
_options = validateConfig(_options)
|
||||
|
||||
this.datastore = _options.datastore
|
||||
this.peerInfo = _options.peerInfo
|
||||
this.peerBook = _options.peerBook || new PeerBook()
|
||||
|
||||
@ -50,7 +51,10 @@ class Node extends EventEmitter {
|
||||
this._transport = [] // Transport instances/references
|
||||
this._discovery = [] // Discovery service instances/references
|
||||
|
||||
// create the switch, and listen for errors
|
||||
this._switch = new Switch(this.peerInfo, this.peerBook, _options.switch)
|
||||
this._switch.on('error', (...args) => this.emit('error', ...args))
|
||||
|
||||
this.stats = this._switch.stats
|
||||
this.connectionManager = new ConnectionManager(this, _options.connectionManager)
|
||||
|
||||
@ -100,9 +104,7 @@ class Node extends EventEmitter {
|
||||
this._dht = new DHT(this._switch, {
|
||||
kBucketSize: this._config.dht.kBucketSize || 20,
|
||||
enabledDiscovery,
|
||||
// TODO make datastore an option of libp2p itself so
|
||||
// that other things can use it as well
|
||||
datastore: dht.datastore
|
||||
datastore: this.datastore
|
||||
})
|
||||
}
|
||||
|
||||
@ -163,6 +165,21 @@ class Node extends EventEmitter {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides EventEmitter.emit to conditionally emit errors
|
||||
* if there is a handler. If not, errors will be logged.
|
||||
* @param {string} eventName
|
||||
* @param {...any} args
|
||||
* @returns {void}
|
||||
*/
|
||||
emit (eventName, ...args) {
|
||||
if (eventName === 'error' && !this._events.error) {
|
||||
log.error(...args)
|
||||
} else {
|
||||
super.emit(eventName, ...args)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the libp2p node and all sub services
|
||||
*
|
||||
|
@ -22,15 +22,15 @@ module.exports = (node) => {
|
||||
* @returns {void}
|
||||
*/
|
||||
findPeer: (id, options, callback) => {
|
||||
if (!routers.length) {
|
||||
callback(errCode(new Error('No peer routers available'), 'NO_ROUTERS_AVAILABLE'))
|
||||
}
|
||||
|
||||
if (typeof options === 'function') {
|
||||
callback = options
|
||||
options = {}
|
||||
}
|
||||
|
||||
if (!routers.length) {
|
||||
callback(errCode(new Error('No peer routers available'), 'NO_ROUTERS_AVAILABLE'))
|
||||
}
|
||||
|
||||
const tasks = routers.map((router) => {
|
||||
return (cb) => router.findPeer(id, options, (err, result) => {
|
||||
if (err) {
|
||||
|
@ -107,6 +107,22 @@ describe('.contentRouting', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('nodeE.contentRouting.findProviders with limited number of providers', (done) => {
|
||||
parallel([
|
||||
(cb) => nodeA.contentRouting.provide(cid, cb),
|
||||
(cb) => nodeB.contentRouting.provide(cid, cb),
|
||||
(cb) => nodeC.contentRouting.provide(cid, cb)
|
||||
], (err) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
nodeE.contentRouting.findProviders(cid, { maxNumProviders: 2 }, (err, providers) => {
|
||||
expect(err).to.not.exist()
|
||||
expect(providers).to.have.length(2)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('nodeC.contentRouting.findProviders for non existing record (timeout)', (done) => {
|
||||
const cid = new CID('QmTp9VkYvnHyrqKQuFPiuZkiX9gPcqj6x5LJ1rmWuSnnnn')
|
||||
|
||||
@ -367,4 +383,29 @@ describe('.contentRouting', () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('no routers', () => {
|
||||
let nodeA
|
||||
before((done) => {
|
||||
createNode('/ip4/0.0.0.0/tcp/0', (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
nodeA = node
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('.findProviders should return an error with no options', (done) => {
|
||||
nodeA.contentRouting.findProviders('a cid', (err) => {
|
||||
expect(err).to.exist()
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('.findProviders should return an error with options', (done) => {
|
||||
nodeA.contentRouting.findProviders('a cid', { maxTimeout: 5000 }, (err) => {
|
||||
expect(err).to.exist()
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -80,4 +80,25 @@ describe('libp2p creation', () => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('should not throw errors from switch if node has no error listeners', (done) => {
|
||||
createNode([], {}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
node._switch.emit('error', new Error('bad things'))
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('should emit errors from switch if node has error listeners', (done) => {
|
||||
const error = new Error('bad things')
|
||||
createNode([], {}, (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
node.once('error', (err) => {
|
||||
expect(err).to.eql(error)
|
||||
done()
|
||||
})
|
||||
node._switch.emit('error', error)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -6,14 +6,18 @@ const chai = require('chai')
|
||||
chai.use(require('dirty-chai'))
|
||||
const expect = chai.expect
|
||||
|
||||
const MemoryStore = require('interface-datastore').MemoryDatastore
|
||||
|
||||
const createNode = require('./utils/create-node')
|
||||
|
||||
describe('.dht', () => {
|
||||
describe('enabled', () => {
|
||||
let nodeA
|
||||
const datastore = new MemoryStore()
|
||||
|
||||
before(function (done) {
|
||||
createNode('/ip4/0.0.0.0/tcp/0', {
|
||||
datastore,
|
||||
config: {
|
||||
EXPERIMENTAL: {
|
||||
dht: true
|
||||
|
@ -11,7 +11,7 @@ describe('getPeerInfo', () => {
|
||||
it('should callback with error for invalid string multiaddr', (done) => {
|
||||
getPeerInfo(null)('INVALID MULTIADDR', (err) => {
|
||||
expect(err).to.exist()
|
||||
expect(err.message).to.contain('must start with a "/"')
|
||||
expect(err.code).to.eql('ERR_INVALID_MULTIADDR')
|
||||
done()
|
||||
})
|
||||
})
|
||||
@ -19,7 +19,15 @@ describe('getPeerInfo', () => {
|
||||
it('should callback with error for invalid non-peer multiaddr', (done) => {
|
||||
getPeerInfo(null)('/ip4/8.8.8.8/tcp/1080', (err) => {
|
||||
expect(err).to.exist()
|
||||
expect(err.message).to.equal('peer multiaddr instance or string must include peerId')
|
||||
expect(err.code).to.equal('ERR_INVALID_MULTIADDR')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('should callback with error for invalid non-peer multiaddr', (done) => {
|
||||
getPeerInfo(null)(undefined, (err) => {
|
||||
expect(err).to.exist()
|
||||
expect(err.code).to.eql('ERR_INVALID_PEER_TYPE')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
@ -29,10 +29,12 @@ describe('multiaddr trim', () => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
const multiaddrs = node.peerInfo.multiaddrs.toArray()
|
||||
expect(multiaddrs.length).to.be.at.least(2)
|
||||
// ensure the p2p-webrtc-direct address has been trimmed
|
||||
multiaddrs.forEach((addr) => {
|
||||
expect(() => addr.decapsulate('/ip4/0.0.0.0/tcp/999/wss/p2p-webrtc-direct')).to.throw()
|
||||
})
|
||||
|
||||
expect(multiaddrs.length).to.at.least(2)
|
||||
expect(multiaddrs[0].toString())
|
||||
.to.match(/^\/ip4\/127\.0\.0\.1\/tcp\/[0-9]+\/ws\/ipfs\/\w+$/)
|
||||
node.stop(done)
|
||||
})
|
||||
})
|
||||
|
@ -266,4 +266,29 @@ describe('.peerRouting', () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('no routers', () => {
|
||||
let nodeA
|
||||
before((done) => {
|
||||
createNode('/ip4/0.0.0.0/tcp/0', (err, node) => {
|
||||
expect(err).to.not.exist()
|
||||
nodeA = node
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('.findPeer should return an error with no options', (done) => {
|
||||
nodeA.peerRouting.findPeer('a cid', (err) => {
|
||||
expect(err).to.exist()
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('.findPeer should return an error with options', (done) => {
|
||||
nodeA.peerRouting.findPeer('a cid', { maxTimeout: 5000 }, (err) => {
|
||||
expect(err).to.exist()
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -28,8 +28,6 @@ function teardown (nodeA, nodeB, callback) {
|
||||
|
||||
describe('stream muxing', () => {
|
||||
it('spdy only', function (done) {
|
||||
this.timeout(5 * 1000)
|
||||
|
||||
let nodeA
|
||||
let nodeB
|
||||
|
||||
|
Reference in New Issue
Block a user