Compare commits

...

30 Commits

Author SHA1 Message Date
c7f20383d9 chore: release version v0.14.0 2017-12-14 07:39:37 +00:00
a86a95c19f chore: update contributors 2017-12-14 07:39:37 +00:00
1b7360fcfa fix: remove innactive multiaddrs (#131) 2017-12-14 07:27:13 +00:00
67ca37c356 chore: updating CI files (#132)
* Updating CI files

This commit updates all CI scripts to the latest version

* chore: update deps

* bump timout

* fix circle
2017-12-14 07:14:36 +00:00
0870068ebc docs: fix typo (#136) 2017-12-11 12:16:05 +00:00
8563395d32 chore: release version v0.13.3 2017-12-01 09:32:49 +00:00
ef3cae5b5a chore: update contributors 2017-12-01 09:32:49 +00:00
f602cd9f79 test: use that crypto puzzle! (#135) 2017-12-01 09:19:44 +00:00
ec956c1d42 chore: release version v0.13.2 2017-11-27 09:13:13 +00:00
c906f698e4 chore: update contributors 2017-11-27 09:13:12 +00:00
95f029eb7a feat: Bring libp2p-websocket-star to the Transports family! 🌟 (#122)
* test: add libp2p-websocket-star tests

* refactor: websocket-star-{signal => rendezvous}

* misc: Apply requested changes

* chore: update deps

* refactor: considerable amount of refactor, clean up test structure

* use right flag

* test: refactor transport tests
2017-11-27 09:10:36 +00:00
38a68a01b7 chore: Upgrade wrtc to 0.0.63 (#133)
For testing on CIs
2017-11-22 16:19:27 +00:00
c08aa517a0 chore: release version v0.13.1 2017-11-12 10:53:37 +00:00
8eac0f806e chore: update contributors 2017-11-12 10:53:37 +00:00
9fd092fddf chore: update deps 2017-11-12 10:51:13 +00:00
87ddc25bee chore: update example 2017-11-04 16:44:09 +00:00
efb2b67f19 chore: update example 2017-11-04 16:25:58 +00:00
7c0b4daf49 chore: update deps on browser example 2017-11-04 16:21:11 +00:00
aeb3ae1301 chore: update deps 2017-11-04 16:20:28 +00:00
97df76f9c5 chore: gitignore 2017-10-26 13:03:40 +01:00
3ad696445d chore: release version v0.13.0 2017-10-26 13:02:16 +01:00
30bec8d53b chore: update contributors 2017-10-26 13:02:16 +01:00
db2b5300b4 chore: update deps 2017-10-26 12:57:33 +01:00
df4d60df88 docs(examples): update browser /wss bootstrap list (#129) 2017-10-26 12:52:01 +01:00
29cc0afc64 feat: enable and test Circuit Relay
* feat: new super simplified API

* feat: append peer id to multiaddr if not there

* [WIP] Awesome DHT (#86)

* feat: integrate dht

* better interfaces

* docs: add documentation for peerRouting, contentRouting, dht

* fix: take in passed datastore

* fix: update usage of _getPeerInfo

* fix: getPeerInfo

* docs: update docs

* moar

feat: correctly handle p2p-circuit addrs when creating a peer info object

refactor: rework config options

* feat: adding circuit relaying

* feat: rework circuit relay for protobufs

* feat: circuit loading and tests

* fix: clean up _getPeerInfo to work with /p2p-circuit

* wip: tests cleaup

* test: clean up

* wip

* fix: bringing back test reworks and new aegir

* test: group tests

* test: clean up

* test: adjust test

* fix: use getPeerId to determine if the ipfs fragment is missing

* feat: adding circuit relaying

* feat: circuit loading and tests

* test: clean up

* wip

* feat: upgrade to latest aegir

* fix: removing unused tests

* feat: cleanup tests

* fix: create node defautl options

* chore: upgrade swarm to latest version

* fix: updated aegir and adjust timeouts

* feat: more timeouts

* chore: updating deps

* fix: circle ci builds

* test: timeouts
2017-10-26 12:51:36 +01:00
2504cbeb26 docs: add missing sections to the README (#128) 2017-10-22 10:27:36 +01:00
468cc421fa docs: update README.md (#124) 2017-10-22 10:19:50 +01:00
0b991e19d1 docs(examples): fix peer-content routing example scripts (#126). (#127) 2017-10-22 10:19:16 +01:00
2a81fc75a8 chore: update deps 2017-09-10 05:20:56 +01:00
e04c249d4d chore: update deps 2017-09-10 04:52:07 +01:00
41 changed files with 1695 additions and 1151 deletions

71
.aegir.js Normal file
View File

@ -0,0 +1,71 @@
'use strict'
const PeerInfo = require('peer-info')
const PeerId = require('peer-id')
const pull = require('pull-stream')
const parallel = require('async/parallel')
const rawPeer = require('./test/fixtures/test-peer.json')
const Node = require('./test/utils/bundle.node.js')
const sigServer = require('libp2p-webrtc-star/src/sig-server')
const WebSocketStarRendezvous = require('libp2p-websocket-star-rendezvous')
let wrtcRendezvous
let wsRendezvous
let node
const before = (done) => {
parallel([
(cb) => {
sigServer.start({
port: 15555
// cryptoChallenge: true TODO: needs https://github.com/libp2p/js-libp2p-webrtc-star/issues/128
}, (err, server) => {
if (err) { return cb(err) }
wrtcRendezvous = server
cb()
})
},
(cb) => {
WebSocketStarRendezvous.start({
port: 14444,
refreshPeerListIntervalMS: 1000,
strictMultiaddr: false,
cryptoChallenge: true
}, (err, _server) => {
if (err) { return cb(err) }
wsRendezvous = _server
cb()
})
},
(cb) => {
PeerId.createFromJSON(rawPeer, (err, peerId) => {
if (err) {
return done(err)
}
const peer = new PeerInfo(peerId)
peer.multiaddrs.add('/ip4/127.0.0.1/tcp/9200/ws')
node = new Node(peer)
node.handle('/echo/1.0.0', (protocol, conn) => pull(conn, conn))
node.start(cb)
})
}
], done)
}
const after = (done) => {
setTimeout(() => parallel(
[node, wrtcRendezvous, wsRendezvous].map((s) => {
return (cb) => s.stop(cb)
})
, done), 2000)
}
module.exports = {
hooks: {
pre: before,
post: after
}
}

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
docs
**/node_modules/
**/*.log
test/repo-tests*

View File

@ -1,3 +1,4 @@
# 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.
sudo: false
language: node_js
@ -14,7 +15,6 @@ script:
- npm run lint
- npm run test
- npm run coverage
- make test
before_script:
- export DISPLAY=:99.0

View File

@ -1,3 +1,43 @@
<a name="0.14.0"></a>
# [0.14.0](https://github.com/libp2p/js-libp2p/compare/v0.13.3...v0.14.0) (2017-12-14)
### Bug Fixes
* remove innactive multiaddrs ([#131](https://github.com/libp2p/js-libp2p/issues/131)) ([1b7360f](https://github.com/libp2p/js-libp2p/commit/1b7360f))
<a name="0.13.3"></a>
## [0.13.3](https://github.com/libp2p/js-libp2p/compare/v0.13.2...v0.13.3) (2017-12-01)
<a name="0.13.2"></a>
## [0.13.2](https://github.com/libp2p/js-libp2p/compare/v0.13.1...v0.13.2) (2017-11-27)
### Features
* Bring libp2p-websocket-star to the Transports family! 🌟 ([#122](https://github.com/libp2p/js-libp2p/issues/122)) ([95f029e](https://github.com/libp2p/js-libp2p/commit/95f029e))
<a name="0.13.1"></a>
## [0.13.1](https://github.com/libp2p/js-libp2p/compare/v0.13.0...v0.13.1) (2017-11-12)
<a name="0.13.0"></a>
# [0.13.0](https://github.com/libp2p/js-libp2p/compare/v0.12.4...v0.13.0) (2017-10-26)
### Features
* enable and test Circuit Relay ([29cc0af](https://github.com/libp2p/js-libp2p/commit/29cc0af))
<a name="0.12.4"></a>
## [0.12.4](https://github.com/libp2p/js-libp2p/compare/v0.12.3...v0.12.4) (2017-09-07)

View File

@ -48,7 +48,7 @@ We've come a long way, but this project is still in Alpha, lots of development i
## Background
libp2p is the product of a long and arduous quest to understand the evolution of the Internet networking stack. In order to build P2P applications, dev have long had to made custom ad-hoc solutions to fit their needs, sometimes making some hard assumptions about their runtimes and the state of the network at the time of their development. Today, looking back more than 20 years, we see a clear pattern in the types of mechanisms built around the Internet Protocol, IP, which can be found throughout many layers of the OSI layer system, libp2p distils these mechanisms into flat categories and defines clear interfaces that once exposed, enable other protocols and applications to use and swap them, enabling upgradability and adaptability for the runtime, without breaking the API.
libp2p is the product of a long and arduous quest to understand the evolution of the Internet networking stack. In order to build P2P applications, devs have long had to made custom ad-hoc solutions to fit their needs, sometimes making some hard assumptions about their runtimes and the state of the network at the time of their development. Today, looking back more than 20 years, we see a clear pattern in the types of mechanisms built around the Internet Protocol, IP, which can be found throughout many layers of the OSI layer system, libp2p distils these mechanisms into flat categories and defines clear interfaces that once exposed, enable other protocols and applications to use and swap them, enabling upgradability and adaptability for the runtime, without breaking the API.
We are in the process of writing better documentation, blog posts, tutorials and a formal specification. Today you can find:
@ -263,6 +263,42 @@ class Node extends libp2p {
[multiaddr]: https://github.com/multiformats/js-multiaddr
[Connection]: https://github.com/libp2p/interface-connection
## Development
**Clone and install dependencies:**
```sh
> git clone https://github.com/ipfs/js-ipfs.git
> cd js-ipfs
> npm install
```
### Tests
#### Run unit tests
```sh
# run all the unit tsts
> npm test
# run just Node.js tests
> npm run test:node
# run just Browser tests (Chrome)
> npm run test:browser
```
#### Run interop tests
```sh
N/A
```
#### Run benchmark tests
```sh
N/A
```
### Packages

29
appveyor.yml Normal file
View File

@ -0,0 +1,29 @@
# 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

2
ci/Jenkinsfile vendored Normal file
View File

@ -0,0 +1,2 @@
// 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.
javascript()

View File

@ -6,9 +6,13 @@ 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
- google-chrome --version

View File

@ -32,7 +32,7 @@ class MyBundle extends libp2p {
}
```
And that's it, from now on, all your libp2p communications are encrypted. Try running the exampme [1.js](./1.js) to see it working.
And that's it, from now on, all your libp2p communications are encrypted. Try running the example [1.js](./1.js) to see it working.
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).

View File

@ -10,20 +10,20 @@
},
"license": "MIT",
"devDependencies": {
"browserify": "^14.4.0",
"browserify": "^14.5.0",
"concat-stream": "^1.6.0",
"detect-dom-ready": "^1.0.2",
"node-static": "^0.7.9"
"node-static": "^0.7.10"
},
"dependencies": {
"detect-dom-ready": "^1.0.2",
"libp2p": "^0.11.0",
"libp2p-multiplex": "^0.4.4",
"libp2p-railing": "^0.6.1",
"libp2p-secio": "^0.7.1",
"libp2p-spdy": "^0.10.6",
"libp2p-webrtc-star": "^0.12.0",
"libp2p-websockets": "^0.10.1",
"peer-info": "^0.10.0"
"libp2p": "^0.13.0",
"libp2p-multiplex": "^0.5.0",
"libp2p-railing": "^0.7.1",
"libp2p-secio": "^0.8.1",
"libp2p-spdy": "^0.11.0",
"libp2p-webrtc-star": "^0.13.2",
"libp2p-websockets": "^0.10.4",
"peer-info": "^0.11.0"
}
}

View File

@ -19,7 +19,9 @@ const bootstrapers = [
'/dns4/sfo-3.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM',
'/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/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'
]
class Node extends libp2p {

View File

@ -10,7 +10,7 @@ function createNode (callback) {
}
const peerIdStr = peerInfo.id.toB58String()
const ma = `/libp2p-webrtc-star/dns4/star-signal.cloud.ipfs.team/wss/ipfs/${peerIdStr}`
const ma = `/dns4/star-signal.cloud.ipfs.team/wss/p2p-webrtc-star/ipfs/${peerIdStr}`
peerInfo.multiaddrs.add(ma)

View File

@ -13,4 +13,4 @@ Simple go into the folder [1](./1) and execute the following
# open your browser in port :9090
```
[Version Published on IPFS](http://ipfs.io/ipfs/QmcBnUWsPG9rFRnYUQH7FkgpxgUppnujcRvyVje77eiKwr)
[Version Published on IPFS](http://ipfs.io/ipfs/Qmbc1J7ehw1dNYachbkCWPto4RsnVvqCKNVzmYEod2gXcy)

View File

@ -53,7 +53,7 @@ parallel([
(cb) => node1.dial(node2.peerInfo, cb),
(cb) => node2.dial(node3.peerInfo, cb),
// Set up of the cons might take time
(cb) => setTimeout(cb, 100)
(cb) => setTimeout(cb, 300)
], (err) => {
if (err) { throw err }

View File

@ -54,7 +54,7 @@ parallel([
(cb) => node1.dial(node2.peerInfo, cb),
(cb) => node2.dial(node3.peerInfo, cb),
// Set up of the cons might take time
(cb) => setTimeout(cb, 100)
(cb) => setTimeout(cb, 300)
], (err) => {
if (err) { throw err }

View File

@ -74,10 +74,10 @@ parallel([
if (err) { throw err }
console.log('Addresses by which both peers are connected')
node1.peerBook
.getAllArray()
.forEach((peer) => console.log('node 1 to node 2:', peer.isConnected().toString()))
.getAllArray()
.forEach((peer) => console.log('node 1 to node 2:', peer.isConnected().toString()))
node2.peerBook
.getAllArray()
.forEach((peer) => console.log('node 2 to node 1:', peer.isConnected().toString()))
.getAllArray()
.forEach((peer) => console.log('node 2 to node 1:', peer.isConnected().toString()))
})
})

View File

@ -1,55 +0,0 @@
'use strict'
const gulp = require('gulp')
const Node = require('./test/nodejs-bundle/nodejs-bundle.js')
const PeerInfo = require('peer-info')
const PeerId = require('peer-id')
const pull = require('pull-stream')
const sigServer = require('libp2p-webrtc-star/src/sig-server')
let server
let node
const rawPeer = require('./test/browser-bundle/peer.json')
gulp.task('libnode:start', (done) => {
let count = 0
const ready = () => ++count === 2 ? done() : null
sigServer.start({ port: 15555 }, (err, _server) => {
if (err) {
throw err
}
server = _server
ready()
})
PeerId.createFromJSON(rawPeer, (err, peerId) => {
if (err) {
return done(err)
}
const peer = new PeerInfo(peerId)
peer.multiaddrs.add('/ip4/127.0.0.1/tcp/9200/ws')
node = new Node(peer)
node.handle('/echo/1.0.0', (protocol, conn) => pull(conn, conn))
node.start(() => ready())
})
})
gulp.task('libnode:stop', (done) => {
setTimeout(() => node.stop((err) => {
if (err) {
return done(err)
}
server.stop(done)
}), 2000)
})
gulp.task('test:browser:before', ['libnode:start'])
gulp.task('test:node:before', ['libnode:start'])
gulp.task('test:browser:after', ['libnode:stop'])
gulp.task('test:node:after', ['libnode:stop'])
require('aegir/gulp')(gulp)

View File

@ -1,19 +1,19 @@
{
"name": "libp2p",
"version": "0.12.4",
"version": "0.14.0",
"description": "JavaScript base class for libp2p bundles",
"main": "src/index.js",
"scripts": {
"test": "gulp test",
"test:node": "gulp test:node",
"test:browser": "gulp test:browser --dom",
"release": "gulp release --dom",
"release-minor": "gulp release --type minor --dom",
"release-major": "gulp release --type major --dom",
"build": "gulp build",
"lint": "aegir-lint",
"coverage": "aegir-coverage",
"coverage-publish": "aegir-coverage publish"
"lint": "aegir lint",
"build": "aegir build",
"test": "aegir test -t node -t browser",
"test:node": "aegir test -t node",
"test:browser": "aegir test -t browser",
"release": "aegir release -t node -t browser",
"release-minor": "aegir release --type minor -t node -t browser",
"release-major": "aegir release --type major -t node -t browser",
"coverage": "aegir coverage",
"coverage-publish": "aegir coverage --provider coveralls"
},
"repository": {
"type": "git",
@ -37,48 +37,59 @@
},
"homepage": "https://github.com/libp2p/js-libp2p",
"dependencies": {
"async": "^2.5.0",
"async": "^2.6.0",
"libp2p-ping": "~0.6.0",
"libp2p-swarm": "~0.32.3",
"mafmt": "^3.0.1",
"libp2p-swarm": "~0.34.0",
"mafmt": "^3.0.2",
"multiaddr": "^3.0.1",
"peer-book": "~0.5.0",
"peer-id": "~0.10.1",
"peer-info": "~0.11.0"
"peer-book": "~0.5.2",
"peer-id": "~0.10.3",
"peer-info": "~0.11.3"
},
"devDependencies": {
"aegir": "^11.0.2",
"aegir": "^12.2.0",
"chai": "^4.1.2",
"cids": "~0.5.2",
"dirty-chai": "^2.0.1",
"cids": "~0.5.1",
"libp2p-kad-dht": "~0.5.1",
"libp2p-mdns": "~0.9.0",
"libp2p-multiplex": "~0.5.0",
"libp2p-railing": "~0.7.0",
"electron-webrtc": "~0.3.0",
"libp2p-circuit": "~0.1.4",
"libp2p-kad-dht": "~0.6.0",
"libp2p-mdns": "~0.9.1",
"libp2p-multiplex": "~0.5.1",
"libp2p-railing": "~0.7.1",
"libp2p-secio": "~0.8.1",
"libp2p-spdy": "~0.11.0",
"libp2p-tcp": "~0.11.0",
"libp2p-webrtc-star": "~0.13.1",
"libp2p-websockets": "~0.10.1",
"libp2p-tcp": "~0.11.1",
"libp2p-webrtc-star": "~0.13.3",
"libp2p-websockets": "~0.10.4",
"libp2p-websocket-star": "~0.7.2",
"libp2p-websocket-star-rendezvous": "~0.2.2",
"lodash.times": "^4.3.2",
"pre-commit": "^1.2.2",
"pull-goodbye": "0.0.2",
"pull-serializer": "^0.3.2",
"pull-stream": "^3.6.0",
"pull-serializer": "~0.3.2",
"pull-stream": "^3.6.1",
"safe-buffer": "^5.1.1",
"electron-webrtc": "^0.3.0",
"wrtc": "0.0.62"
"sinon": "^4.1.3",
"wrtc": "0.0.63"
},
"contributors": [
"Chris Bratlien <chrisbratlien@gmail.com>",
"Daijiro Wachi <daijiro.wachi@gmail.com>",
"David Dias <daviddias.p@gmail.com>",
"Dmitriy Ryajov <dryajov@gmail.com>",
"Elven <mon.samuel@qq.com>",
"Friedel Ziegelmayer <dignifiedquire@gmail.com>",
"Joel Gustafson <joelg@mit.edu>",
"Lars Gierth <lgierth@users.noreply.github.com>",
"Maciej Krüger <mkg20001@gmail.com>",
"Nuno Nogueira <nunofmn@gmail.com>",
"Pedro Teixeira <i@pgte.me>",
"RasmusErik Voel Jensen <github@solsort.com>",
"Richard Littauer <richard.littauer@gmail.com>",
"Ryan Bell <ryan@piing.net>",
"greenkeeperio-bot <support@greenkeeper.io>",
"mayerwin <mayerwin@users.noreply.github.com>"
"mayerwin <mayerwin@users.noreply.github.com>",
"ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com>"
]
}
}

View File

@ -12,7 +12,6 @@ const Swarm = require('libp2p-swarm')
const PeerId = require('peer-id')
const PeerInfo = require('peer-info')
const PeerBook = require('peer-book')
const mafmt = require('mafmt')
const multiaddr = require('multiaddr')
exports = module.exports
@ -43,6 +42,9 @@ class Node extends EventEmitter {
// If muxer exists, we can use Identify
this.swarm.connection.reuse()
// If muxer exists, we can use Relay for listening/dialing
this.swarm.connection.enableCircuitRelay(_options.relay)
// Received incommind dial and muxer upgrade happened,
// reuse this muxed connection
this.swarm.on('peer-mux-established', (peerInfo) => {
@ -154,15 +156,15 @@ class Node extends EventEmitter {
// 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)) {
this.peerInfo.multiaddrs.toArray().forEach((ma) => {
if (!ma.getPeerId()) {
maOld.push(ma)
maNew.push(ma.encapsulate('/ipfs/' + this.peerInfo.id.toB58String()))
}
})
this.peerInfo.multiaddrs.replace(maOld, maNew)
const multiaddrs = this.peerInfo.multiaddrs.toArray()
const multiaddrs = this.peerInfo.multiaddrs.toArray()
transports.forEach((transport) => {
if (transport.filter(multiaddrs).length > 0) {
this.swarm.transport.add(
@ -198,6 +200,19 @@ class Node extends EventEmitter {
}
cb()
},
(cb) => {
// detect which multiaddrs we don't have a transport for and remove them
const multiaddrs = this.peerInfo.multiaddrs.toArray()
transports.forEach((transport) => {
multiaddrs.forEach((multiaddr) => {
if (!multiaddr.toString().match(/\/p2p-circuit($|\/)/) &&
!transports.find((transport) => transport.filter(multiaddr).length > 0)) {
this.peerInfo.multiaddrs.delete(multiaddr)
}
})
})
cb()
},
(cb) => {
this.emit('start')
cb()

View File

@ -1,121 +0,0 @@
/* eslint-env mocha */
'use strict'
const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const PeerInfo = require('peer-info')
const PeerId = require('peer-id')
const parallel = require('async/parallel')
const pull = require('pull-stream')
const Node = require('./browser-bundle')
describe('libp2p-ipfs-browser (webrtc only)', () => {
let peer1
let peer2
let node1
let node2
it('create two peerInfo with webrtc-star addrs', (done) => {
parallel([
(cb) => PeerId.create({ bits: 1024 }, cb),
(cb) => PeerId.create({ bits: 1024 }, cb)
], (err, ids) => {
expect(err).to.not.exist()
peer1 = new PeerInfo(ids[0])
const ma1 = '/ip4/127.0.0.1/tcp/15555/ws/p2p-webrtc-star/ipfs/' + ids[0].toB58String()
peer1.multiaddrs.add(ma1)
peer2 = new PeerInfo(ids[1])
const ma2 = '/ip4/127.0.0.1/tcp/15555/ws/p2p-webrtc-star/ipfs/' + ids[1].toB58String()
peer2.multiaddrs.add(ma2)
done()
})
})
it('create two libp2p nodes with those peers', (done) => {
node1 = new Node(peer1, null, { webRTCStar: true })
node2 = new Node(peer2, null, { webRTCStar: true })
done()
})
it('listen on the two libp2p nodes', (done) => {
parallel([
(cb) => node1.start(cb),
(cb) => node2.start(cb)
], done)
})
it('handle a protocol on the first node', () => {
node2.handle('/echo/1.0.0', (protocol, conn) => pull(conn, conn))
})
it('dial from the second node to the first node', (done) => {
node1.dial(peer2, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
const text = 'hello'
const peers1 = node1.peerBook.getAll()
expect(Object.keys(peers1)).to.have.length(1)
const peers2 = node2.peerBook.getAll()
expect(Object.keys(peers2)).to.have.length(1)
pull(
pull.values([Buffer.from(text)]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data[0].toString()).to.equal(text)
done()
})
)
}
})
})
it('node1 hangUp node2', (done) => {
node1.hangUp(peer2, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
const peers = node1.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(node1.swarm.muxedConns)).to.have.length(0)
done()
}
})
})
it('create a third node and check that discovery works', (done) => {
let counter = 0
function check () {
if (++counter === 3) {
expect(Object.keys(node1.swarm.muxedConns).length).to.equal(1)
expect(Object.keys(node2.swarm.muxedConns).length).to.equal(1)
done()
}
}
PeerId.create((err, id3) => {
expect(err).to.not.exist()
const peer3 = new PeerInfo(id3)
const ma3 = '/ip4/127.0.0.1/tcp/15555/ws/p2p-webrtc-star/ipfs/' + id3.toB58String()
peer3.multiaddrs.add(ma3)
node1.on('peer:discovery', (peerInfo) => node1.dial(peerInfo, check))
node2.on('peer:discovery', (peerInfo) => node2.dial(peerInfo, check))
const node3 = new Node(peer3, null, { webRTCStar: true })
node3.start(check)
})
})
})

View File

@ -1,201 +0,0 @@
/* eslint max-nested-callbacks: ["error", 8] */
/* eslint-env mocha */
'use strict'
const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const PeerInfo = require('peer-info')
const PeerId = require('peer-id')
const pull = require('pull-stream')
const goodbye = require('pull-goodbye')
const serializer = require('pull-serializer')
const Buffer = require('safe-buffer').Buffer
const Node = require('./browser-bundle')
const rawPeer = require('./peer.json')
describe('libp2p-ipfs-browser (websockets only)', () => {
let peerB
let nodeA
before((done) => {
const ma = '/ip4/127.0.0.1/tcp/9200/ws/ipfs/' + rawPeer.id
PeerId.createFromPrivKey(rawPeer.privKey, (err, id) => {
if (err) {
return done(err)
}
peerB = new PeerInfo(id)
peerB.multiaddrs.add(ma)
done()
})
})
after((done) => nodeA.stop(done))
it('create libp2pNode', (done) => {
PeerInfo.create((err, peerInfo) => {
expect(err).to.not.exist()
peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
nodeA = new Node(peerInfo)
done()
})
})
it('create libp2pNode with multiplex only', (done) => {
PeerInfo.create((err, peerInfo) => {
expect(err).to.not.exist()
const b = new Node(peerInfo, null, { muxer: ['multiplex'] })
expect(b.modules.connection.muxer).to.eql([require('libp2p-multiplex')])
done()
})
})
it('start libp2pNode', (done) => {
nodeA.start(done)
})
// General connectivity tests
it('libp2p.dial using Multiaddr nodeA to nodeB', (done) => {
nodeA.dial(peerB.multiaddrs.toArray()[0], (err) => {
expect(err).to.not.exist()
setTimeout(check, 500) // Some time for Identify to finish
function check () {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
done()
}
})
})
it('libp2p.dial using Multiaddr on Protocol nodeA to nodeB', (done) => {
nodeA.dial(peerB.multiaddrs.toArray()[0], '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
pull(
pull.values([Buffer.from('hey')]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data).to.eql([Buffer.from('hey')])
done()
})
)
})
})
it('libp2p.hangUp using Multiaddr nodeA to nodeB', (done) => {
nodeA.hangUp(peerB.multiaddrs.toArray()[0], (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(0)
done()
}
})
})
it('libp2p.dial using PeerInfo nodeA to nodeB', (done) => {
nodeA.dial(peerB, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500) // Some time for Identify to finish
function check () {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
done()
}
})
})
it('libp2p.dial using PeerInfo on Protocol nodeA to nodeB', (done) => {
nodeA.dial(peerB, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
const peers = nodeA.peerBook.getAll()
expect(err).to.not.exist()
expect(Object.keys(peers)).to.have.length(1)
pull(
pull.values([Buffer.from('hey')]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data).to.eql([Buffer.from('hey')])
done()
})
)
})
})
it('libp2p.hangUp using PeerInfo nodeA to nodeB', (done) => {
nodeA.hangUp(peerB, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
const peers = nodeA.peerBook.getAll()
expect(err).to.not.exist()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(0)
done()
}
})
})
describe('stress', () => {
it('one big write', (done) => {
nodeA.dial(peerB, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
const rawMessage = Buffer.alloc(100000)
rawMessage.fill('a')
const s = serializer(goodbye({
source: pull.values([rawMessage]),
sink: pull.collect((err, results) => {
expect(err).to.not.exist()
expect(results).to.have.length(1)
expect(Buffer.from(results[0])).to.have.length(rawMessage.length)
done()
})
}))
pull(s, conn, s)
})
})
it('many writes', (done) => {
nodeA.dial(peerB, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
const s = serializer(goodbye({
source: pull(
pull.infinite(),
pull.take(1000),
pull.map((val) => Buffer.from(val.toString()))
),
sink: pull.collect((err, result) => {
expect(err).to.not.exist()
expect(result).to.have.length(1000)
done()
})
}))
pull(s, conn, s)
})
})
})
})

View File

@ -1,7 +1,4 @@
'use strict'
const w = require('webrtcsupport')
require('./base')
require('./browser-bundle/websockets-only')
if (w.support) { require('./browser-bundle/webrtc-star-only') }
require('./transports.browser')

225
test/circuit-relay.node.js Normal file
View File

@ -0,0 +1,225 @@
/* eslint-env mocha */
'use strict'
const pull = require('pull-stream')
const waterfall = require('async/waterfall')
const series = require('async/series')
const parallel = require('async/parallel')
const utils = require('./utils/node')
const Circuit = require('libp2p-circuit')
const multiaddr = require('multiaddr')
const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const sinon = require('sinon')
describe('circuit relay', function () {
let handlerSpies = []
let relayNode1
let relayNode2
let nodeWS1
let nodeWS2
let nodeTCP1
let nodeTCP2
function setupNode (addrs, options, cb) {
if (typeof options === 'function') {
cb = options
options = {}
}
options = options || {}
return utils.createNode(addrs, options, (err, node) => {
expect(err).to.not.exist()
node.handle('/echo/1.0.0', utils.echo)
node.start((err) => {
expect(err).to.not.exist()
handlerSpies.push(sinon.spy(node.swarm.transports[Circuit.tag].listeners[0].hopHandler, 'handle'))
cb(node)
})
})
}
before(function (done) {
this.timeout(20000)
waterfall([
// set up passive relay
(cb) => setupNode([
'/ip4/0.0.0.0/tcp/0/ws',
'/ip4/0.0.0.0/tcp/0'
], {
relay: {
enabled: true,
hop: {
enabled: true,
active: false // passive relay
}
}
}, (node) => {
relayNode1 = node
cb()
}),
// setup active relay
(cb) => setupNode([
'/ip4/0.0.0.0/tcp/0/ws',
'/ip4/0.0.0.0/tcp/0'
], {
relay: {
enabled: true,
hop: {
enabled: true,
active: false // passive relay
}
}
}, (node) => {
relayNode2 = node
cb()
}),
// setup node with WS
(cb) => setupNode([
'/ip4/0.0.0.0/tcp/0/ws'
], {
relay: {
enabled: true
}
}, (node) => {
nodeWS1 = node
cb()
}),
// setup node with WS
(cb) => setupNode([
'/ip4/0.0.0.0/tcp/0/ws'
], {
relay: {
enabled: true
}
}, (node) => {
nodeWS2 = node
cb()
}),
// set up node with TCP and listening on relay1
(cb) => setupNode([
'/ip4/0.0.0.0/tcp/0',
`/ipfs/${relayNode1.peerInfo.id.toB58String()}/p2p-circuit`
], {
relay: {
enabled: true
}
}, (node) => {
nodeTCP1 = node
cb()
}),
// set up node with TCP and listening on relay2 over TCP transport
(cb) => setupNode([
'/ip4/0.0.0.0/tcp/0',
`/ip4/0.0.0.0/tcp/0/ipfs/${relayNode2.peerInfo.id.toB58String()}/p2p-circuit`
], {
relay: {
enabled: true
}
}, (node) => {
nodeTCP2 = node
cb()
})
], (err) => {
expect(err).to.not.exist()
series([
(cb) => nodeWS1.dial(relayNode1.peerInfo, cb),
(cb) => nodeWS1.dial(relayNode2.peerInfo, cb),
(cb) => nodeTCP1.dial(relayNode1.peerInfo, cb),
(cb) => nodeTCP2.dial(relayNode2.peerInfo, cb)
], done)
})
})
after((done) => {
parallel([
(cb) => relayNode1.stop(cb),
(cb) => relayNode2.stop(cb),
(cb) => nodeWS1.stop(cb),
(cb) => nodeWS2.stop(cb),
(cb) => nodeTCP1.stop(cb),
(cb) => nodeTCP2.stop(cb)
], done)
})
describe('any relay', function () {
this.timeout(20 * 1000)
it('should dial from WS1 to TCP1 over any R', (done) => {
nodeWS1.dial(nodeTCP1.peerInfo, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
expect(conn).to.exist()
pull(
pull.values(['hello']),
conn,
pull.collect((err, result) => {
expect(err).to.not.exist()
expect(result[0].toString()).to.equal('hello')
done()
})
)
})
})
it('should not dial - no R from WS2 to TCP1', (done) => {
nodeWS2.dial(nodeTCP2.peerInfo, '/echo/1.0.0', (err, conn) => {
expect(err).to.exist()
expect(conn).to.not.exist()
done()
})
})
})
describe('explicit relay', function () {
this.timeout(20 * 1000)
it('should dial from WS1 to TCP1 over R1', (done) => {
nodeWS1.dial(nodeTCP1.peerInfo, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
expect(conn).to.exist()
pull(
pull.values(['hello']),
conn,
pull.collect((err, result) => {
expect(err).to.not.exist()
expect(result[0].toString()).to.equal('hello')
const addr = multiaddr(handlerSpies[0].args[2][0].dstPeer.addrs[0]).toString()
expect(addr).to.equal(`/ipfs/${nodeTCP1.peerInfo.id.toB58String()}`)
done()
})
)
})
})
it('should dial from WS1 to TCP2 over R2', (done) => {
nodeWS1.dial(nodeTCP2.peerInfo, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
expect(conn).to.exist()
pull(
pull.values(['hello']),
conn,
pull.collect((err, result) => {
expect(err).to.not.exist()
expect(result[0].toString()).to.equal('hello')
const addr = multiaddr(handlerSpies[1].args[2][0].dstPeer.addrs[0]).toString()
expect(addr).to.equal(`/ipfs/${nodeTCP2.peerInfo.id.toB58String()}`)
done()
})
)
})
})
})
})

View File

@ -7,10 +7,10 @@ const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const parallel = require('async/parallel')
const utils = require('./utils')
const createNode = utils.createNode
const _times = require('lodash.times')
const CID = require('cids')
const utils = require('./utils/node')
const createNode = utils.createNode
describe('.contentRouting', () => {
let nodeA
@ -19,7 +19,8 @@ describe('.contentRouting', () => {
let nodeD
let nodeE
before((done) => {
before(function (done) {
this.timeout(5 * 1000)
const tasks = _times(5, () => (cb) => {
createNode('/ip4/0.0.0.0/tcp/0', {
mdns: false,

40
test/multiaddr-trim.js Normal file
View File

@ -0,0 +1,40 @@
/* eslint-env mocha */
'use strict'
const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const series = require('async/series')
const createNode = require('./utils/node').createNode
describe('multiaddr trim', () => {
it('non used multiaddrs get trimmed', (done) => {
let node
series([
(cb) => createNode([
'/ip4/0.0.0.0/tcp/999/wss/p2p-webrtc-direct',
'/ip4/127.0.0.1/tcp/55555/ws',
'/ip4/0.0.0.0/tcp/0/'
], (err, _node) => {
expect(err).to.not.exist()
node = _node
const multiaddrs = node.peerInfo.multiaddrs.toArray()
// multiaddrs.forEach((ma) => console.log(ma.toString()))
expect(multiaddrs).to.have.length(3)
cb()
}),
(cb) => node.start(cb)
], (err) => {
expect(err).to.not.exist()
const multiaddrs = node.peerInfo.multiaddrs.toArray()
// console.log('--')
// multiaddrs.forEach((ma) => console.log(ma.toString()))
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)
})
})
})

View File

@ -1,10 +1,10 @@
'use strict'
require('./base')
require('./nodejs-bundle/tcp')
require('./nodejs-bundle/tcp+websockets')
require('./nodejs-bundle/tcp+websockets+webrtc-star')
require('./nodejs-bundle/stream-muxing')
require('./nodejs-bundle/discovery')
require('./nodejs-bundle/peer-routing')
require('./nodejs-bundle/content-routing')
require('./transports.node')
require('./stream-muxing.node')
require('./peer-discovery.node')
require('./peer-routing.node')
require('./content-routing.node')
require('./circuit-relay.node')
require('./multiaddr-trim')

View File

@ -1,30 +0,0 @@
#! /usr/bin/env node
'use strict'
const Node = require('./nodejs-bundle')
const PeerInfo = require('peer-info')
const PeerId = require('peer-id')
const pull = require('pull-stream')
const idBak = require('./test-data/test-id.json')
PeerId.createFromJSON(idBak, (err, peerId) => {
if (err) {
throw err
}
const peerInfo = new PeerInfo(peerId)
peerInfo.multiaddrs.add('/ip4/127.0.0.1/tcp/12345')
const node = new Node(peerInfo)
node.handle('/echo/1.0.0', (protocol, conn) => pull(conn, conn))
node.start((err) => {
if (err) { throw err }
console.log('Spawned node started, env:', process.env.LIBP2P_MUXER)
})
})

View File

@ -1,246 +0,0 @@
/* eslint-env mocha */
'use strict'
const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const parallel = require('async/parallel')
const signalling = require('libp2p-webrtc-star/src/sig-server')
const WStar = require('libp2p-webrtc-star')
const wrtc = require('wrtc')
const utils = require('./utils')
const createNode = utils.createNode
const echo = utils.echo
describe('TCP + WebSockets + WebRTCStar', () => {
let nodeAll
let nodeTCP
let nodeWS
let nodeWStar
let ss
before((done) => {
parallel([
(cb) => {
signalling.start({ port: 24642 }, (err, server) => {
expect(err).to.not.exist()
ss = server
cb()
})
},
(cb) => {
const wstar = new WStar({wrtc: wrtc})
createNode([
'/ip4/0.0.0.0/tcp/0',
'/ip4/127.0.0.1/tcp/25011/ws',
'/ip4/127.0.0.1/tcp/24642/ws/p2p-webrtc-star'
], {
modules: {
transport: [wstar],
discovery: [wstar.discovery]
}
}, (err, node) => {
expect(err).to.not.exist()
nodeAll = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
})
},
(cb) => createNode([
'/ip4/0.0.0.0/tcp/0'
], (err, node) => {
expect(err).to.not.exist()
nodeTCP = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
}),
(cb) => createNode([
'/ip4/127.0.0.1/tcp/25022/ws'
], (err, node) => {
expect(err).to.not.exist()
nodeWS = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
}),
(cb) => {
const wstar = new WStar({wrtc: wrtc})
createNode([
'/ip4/127.0.0.1/tcp/24642/ws/p2p-webrtc-star'
], {
modules: {
transport: [wstar],
discovery: [wstar.discovery]
}
}, (err, node) => {
expect(err).to.not.exist()
nodeWStar = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
})
}
], done)
})
after((done) => {
parallel([
(cb) => nodeAll.stop(cb),
(cb) => nodeTCP.stop(cb),
(cb) => nodeWS.stop(cb),
(cb) => nodeWStar.stop(cb),
(cb) => ss.stop(done)
], done)
})
it('nodeAll.dial nodeTCP using PeerInfo', (done) => {
nodeAll.dial(nodeTCP.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeAll.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeAll.swarm.muxedConns)).to.have.length(1)
cb()
},
(cb) => {
const peers = nodeTCP.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeTCP.swarm.muxedConns)).to.have.length(1)
cb()
}
], done)
}
})
})
it('nodeAll.hangUp nodeTCP using PeerInfo', (done) => {
nodeAll.hangUp(nodeTCP.peerInfo, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeAll.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeAll.swarm.muxedConns)).to.have.length(0)
cb()
},
(cb) => {
const peers = nodeTCP.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeTCP.swarm.muxedConns)).to.have.length(0)
cb()
}
], done)
}
})
})
it('nodeAll.dial nodeWS using PeerInfo', (done) => {
nodeAll.dial(nodeWS.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeAll.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(2)
expect(Object.keys(nodeAll.swarm.muxedConns)).to.have.length(1)
cb()
},
(cb) => {
const peers = nodeWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeWS.swarm.muxedConns)).to.have.length(1)
cb()
}
], done)
}
})
})
it('nodeAll.hangUp nodeWS using PeerInfo', (done) => {
nodeAll.hangUp(nodeWS.peerInfo, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeAll.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(2)
expect(Object.keys(nodeAll.swarm.muxedConns)).to.have.length(0)
cb()
},
(cb) => {
const peers = nodeWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeWS.swarm.muxedConns)).to.have.length(0)
cb()
}
], done)
}
})
})
it('nodeAll.dial nodeWStar using PeerInfo', (done) => {
nodeAll.dial(nodeWStar.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeAll.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(3)
expect(Object.keys(nodeAll.swarm.muxedConns)).to.have.length(1)
cb()
},
(cb) => {
const peers = nodeWStar.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeAll.swarm.muxedConns)).to.have.length(1)
cb()
}
], done)
}
})
})
it('nodeAll.hangUp nodeWStar using PeerInfo', (done) => {
nodeAll.hangUp(nodeWStar.peerInfo, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeAll.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(3)
expect(Object.keys(nodeAll.swarm.muxedConns)).to.have.length(0)
cb()
},
(cb) => {
const peers = nodeWStar.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeWStar.swarm.muxedConns)).to.have.length(0)
cb()
}
], done)
}
})
})
})

View File

@ -1,167 +0,0 @@
/* eslint-env mocha */
'use strict'
const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const parallel = require('async/parallel')
// const multiaddr = require('multiaddr')
// const pull = require('pull-stream')
const utils = require('./utils')
const createNode = utils.createNode
const echo = utils.echo
describe('TCP + WebSockets', () => {
let nodeTCP
let nodeTCPnWS
let nodeWS
before((done) => {
parallel([
(cb) => createNode([
'/ip4/0.0.0.0/tcp/0'
], (err, node) => {
expect(err).to.not.exist()
nodeTCP = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
}),
(cb) => createNode([
'/ip4/0.0.0.0/tcp/0',
'/ip4/127.0.0.1/tcp/25011/ws'
], (err, node) => {
expect(err).to.not.exist()
nodeTCPnWS = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
}),
(cb) => createNode([
'/ip4/127.0.0.1/tcp/25022/ws'
], (err, node) => {
expect(err).to.not.exist()
nodeWS = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
})
], done)
})
after((done) => {
parallel([
(cb) => nodeTCP.stop(cb),
(cb) => nodeTCPnWS.stop(cb),
(cb) => nodeWS.stop(cb)
], done)
})
it('nodeTCP.dial nodeTCPnWS using PeerInfo', (done) => {
nodeTCP.dial(nodeTCPnWS.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeTCP.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeTCP.swarm.muxedConns)).to.have.length(1)
cb()
},
(cb) => {
const peers = nodeTCPnWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeTCPnWS.swarm.muxedConns)).to.have.length(1)
cb()
}
], done)
}
})
})
it('nodeTCP.hangUp nodeTCPnWS using PeerInfo', (done) => {
nodeTCP.hangUp(nodeTCPnWS.peerInfo, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeTCP.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeTCP.swarm.muxedConns)).to.have.length(0)
cb()
},
(cb) => {
const peers = nodeTCPnWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeTCPnWS.swarm.muxedConns)).to.have.length(0)
cb()
}
], done)
}
})
})
it('nodeTCPnWS.dial nodeWS using PeerInfo', (done) => {
nodeTCPnWS.dial(nodeWS.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeTCPnWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(2)
expect(Object.keys(nodeTCPnWS.swarm.muxedConns)).to.have.length(1)
cb()
},
(cb) => {
const peers = nodeWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeWS.swarm.muxedConns)).to.have.length(1)
cb()
}
], done)
}
})
})
it('nodeTCPnWS.hangUp nodeWS using PeerInfo', (done) => {
nodeTCPnWS.hangUp(nodeWS.peerInfo, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeTCPnWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(2)
expect(Object.keys(nodeTCPnWS.swarm.muxedConns)).to.have.length(0)
cb()
},
(cb) => {
const peers = nodeWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeWS.swarm.muxedConns)).to.have.length(0)
cb()
}
], done)
}
})
})
// Until https://github.com/libp2p/js-libp2p/issues/46 is resolved
// Everynode will be able to dial in WebSockets
it.skip('nodeTCP.dial nodeWS using PeerInfo is unsuccesful', (done) => {
nodeTCP.dial(nodeWS.peerInfo, (err) => {
expect(err).to.exist()
done()
})
})
})

View File

@ -1,234 +0,0 @@
/* eslint-env mocha */
'use strict'
const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const parallel = require('async/parallel')
const series = require('async/series')
const pull = require('pull-stream')
const utils = require('./utils')
const createNode = utils.createNode
const echo = utils.echo
describe('TCP only', () => {
let nodeA
let nodeB
before((done) => {
parallel([
(cb) => createNode('/ip4/0.0.0.0/tcp/0', (err, node) => {
expect(err).to.not.exist()
nodeA = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
}),
(cb) => createNode('/ip4/0.0.0.0/tcp/0', (err, node) => {
expect(err).to.not.exist()
nodeB = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
})
], done)
})
after((done) => {
parallel([
(cb) => nodeA.stop(cb),
(cb) => nodeB.stop(cb)
], done)
})
it('nodeA.dial nodeB using PeerInfo without proto (warmup)', (done) => {
nodeA.dial(nodeB.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(err).to.not.exist()
expect(Object.keys(peers)).to.have.length(1)
cb()
},
(cb) => {
const peers = nodeB.peerBook.getAll()
expect(err).to.not.exist()
expect(Object.keys(peers)).to.have.length(1)
cb()
}
], done)
}
})
})
it('nodeA.dial nodeB using PeerInfo', (done) => {
nodeA.dial(nodeB.peerInfo, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
pull(
pull.values([new Buffer('hey')]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data).to.be.eql([new Buffer('hey')])
done()
})
)
})
})
it('nodeA.hangUp nodeB using PeerInfo (first)', (done) => {
nodeA.hangUp(nodeB.peerInfo, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(0)
cb()
},
(cb) => {
const peers = nodeB.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeB.swarm.muxedConns)).to.have.length(0)
cb()
}
], done)
}
})
})
it('nodeA.dial nodeB using multiaddr', (done) => {
nodeA.dial(nodeB.peerInfo.multiaddrs.toArray()[0], '/echo/1.0.0', (err, conn) => {
// Some time for Identify to finish
setTimeout(check, 500)
function check () {
expect(err).to.not.exist()
series([
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(1)
cb()
},
(cb) => {
const peers = nodeB.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(1)
cb()
}
], () => {
pull(
pull.values([new Buffer('hey')]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data).to.be.eql([new Buffer('hey')])
done()
})
)
})
}
})
})
it('nodeA.hangUp nodeB using multiaddr (second)', (done) => {
nodeA.hangUp(nodeB.peerInfo.multiaddrs.toArray()[0], (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(0)
cb()
},
(cb) => {
const peers = nodeB.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeB.swarm.muxedConns)).to.have.length(0)
cb()
}
], done)
}
})
})
it('nodeA.dial nodeB using PeerId', (done) => {
nodeA.dial(nodeB.peerInfo.id, '/echo/1.0.0', (err, conn) => {
// Some time for Identify to finish
setTimeout(check, 500)
function check () {
expect(err).to.not.exist()
series([
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(1)
cb()
},
(cb) => {
const peers = nodeB.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(1)
cb()
}
], () => {
pull(
pull.values([new Buffer('hey')]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data).to.be.eql([new Buffer('hey')])
done()
})
)
})
}
})
})
it('nodeA.hangUp nodeB using PeerId (third)', (done) => {
nodeA.hangUp(nodeB.peerInfo.multiaddrs.toArray()[0], (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(0)
cb()
},
(cb) => {
const peers = nodeB.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeB.swarm.muxedConns)).to.have.length(0)
cb()
}
], done)
}
})
})
})

View File

@ -6,11 +6,11 @@ chai.use(require('dirty-chai'))
const expect = chai.expect
const signalling = require('libp2p-webrtc-star/src/sig-server')
const parallel = require('async/parallel')
const utils = require('./utils')
const utils = require('./utils/node')
const createNode = utils.createNode
const echo = utils.echo
describe('discovery', () => {
describe('peer discovery', () => {
let nodeA
let nodeB
let port = 24642
@ -60,7 +60,9 @@ describe('discovery', () => {
describe('MulticastDNS', () => {
setup({ mdns: true })
it('find a peer', (done) => {
it('find a peer', function (done) {
this.timeout(15 * 1000)
nodeA.once('peer:discovery', (peerInfo) => {
expect(nodeB.peerInfo.id.toB58String())
.to.eql(peerInfo.id.toB58String())
@ -73,7 +75,8 @@ describe('discovery', () => {
describe.skip('WebRTCStar', () => {
setup({ webRTCStar: true })
it('find a peer', (done) => {
it('find a peer', function (done) {
this.timeout(15 * 1000)
nodeA.once('peer:discovery', (peerInfo) => {
expect(nodeB.peerInfo.id.toB58String())
.to.eql(peerInfo.id.toB58String())
@ -88,7 +91,8 @@ describe('discovery', () => {
mdns: true
})
it('find a peer', (done) => {
it('find a peer', function (done) {
this.timeout(15 * 1000)
nodeA.once('peer:discovery', (peerInfo) => {
expect(nodeB.peerInfo.id.toB58String())
.to.eql(peerInfo.id.toB58String())

View File

@ -7,9 +7,9 @@ const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const parallel = require('async/parallel')
const utils = require('./utils')
const createNode = utils.createNode
const _times = require('lodash.times')
const utils = require('./utils/node')
const createNode = utils.createNode
describe('.peerRouting', () => {
let nodeA
@ -18,7 +18,9 @@ describe('.peerRouting', () => {
let nodeD
let nodeE
before((done) => {
before(function (done) {
this.timeout(5 * 1000)
const tasks = _times(5, () => (cb) => {
createNode('/ip4/0.0.0.0/tcp/0', {
mdns: false,

View File

@ -7,7 +7,7 @@ const expect = chai.expect
const parallel = require('async/parallel')
const series = require('async/series')
const pull = require('pull-stream')
const utils = require('./utils')
const utils = require('./utils/node')
const createNode = utils.createNode
const echo = utils.echo
@ -16,11 +16,11 @@ function test (nodeA, nodeB, callback) {
expect(err).to.not.exist()
pull(
pull.values([new Buffer('hey')]),
pull.values([Buffer.from('hey')]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data).to.be.eql([new Buffer('hey')])
expect(data).to.be.eql([Buffer.from('hey')])
callback()
})
)
@ -34,8 +34,10 @@ function teardown (nodeA, nodeB, callback) {
], callback)
}
describe('stream muxing', (done) => {
it('spdy only', (done) => {
describe('stream muxing', () => {
it('spdy only', function (done) {
this.timeout(5 * 1000)
let nodeA
let nodeB
@ -99,7 +101,9 @@ describe('stream muxing', (done) => {
], done)
})
it('spdy + multiplex', (done) => {
it('spdy + multiplex', function (done) {
this.timeout(5000)
let nodeA
let nodeB
@ -131,7 +135,9 @@ describe('stream muxing', (done) => {
], done)
})
it('spdy + multiplex switched order', (done) => {
it('spdy + multiplex switched order', function (done) {
this.timeout(5000)
let nodeA
let nodeB
@ -163,7 +169,9 @@ describe('stream muxing', (done) => {
], done)
})
it('one without the other fails to establish a muxedConn', (done) => {
it('one without the other fails to establish a muxedConn', function (done) {
this.timeout(5000)
let nodeA
let nodeB

424
test/transports.browser.js Normal file
View File

@ -0,0 +1,424 @@
/* eslint max-nested-callbacks: ["error", 8] */
/* eslint-env mocha */
'use strict'
const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const PeerInfo = require('peer-info')
const PeerId = require('peer-id')
const pull = require('pull-stream')
const parallel = require('async/parallel')
const goodbye = require('pull-goodbye')
const serializer = require('pull-serializer')
const w = require('webrtcsupport')
const Node = require('./utils/bundle.browser')
const rawPeer = require('./fixtures/test-peer.json')
describe('transports', () => {
describe('websockets', () => {
let peerB
let nodeA
before((done) => {
const ma = '/ip4/127.0.0.1/tcp/9200/ws/ipfs/' + rawPeer.id
PeerId.createFromPrivKey(rawPeer.privKey, (err, id) => {
if (err) {
return done(err)
}
peerB = new PeerInfo(id)
peerB.multiaddrs.add(ma)
done()
})
})
after((done) => nodeA.stop(done))
it('create libp2pNode', (done) => {
PeerInfo.create((err, peerInfo) => {
expect(err).to.not.exist()
peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
nodeA = new Node(peerInfo)
done()
})
})
it('create libp2pNode with multiplex only', (done) => {
PeerInfo.create((err, peerInfo) => {
expect(err).to.not.exist()
const b = new Node(peerInfo, null, { muxer: ['multiplex'] })
expect(b.modules.connection.muxer).to.eql([require('libp2p-multiplex')])
done()
})
})
it('start libp2pNode', (done) => {
nodeA.start(done)
})
// General connectivity tests
it('libp2p.dial using Multiaddr nodeA to nodeB', (done) => {
nodeA.dial(peerB.multiaddrs.toArray()[0], (err) => {
expect(err).to.not.exist()
setTimeout(check, 500) // Some time for Identify to finish
function check () {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
done()
}
})
})
it('libp2p.dial using Multiaddr on Protocol nodeA to nodeB', (done) => {
nodeA.dial(peerB.multiaddrs.toArray()[0], '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
pull(
pull.values([Buffer.from('hey')]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data).to.eql([Buffer.from('hey')])
done()
})
)
})
})
it('libp2p.hangUp using Multiaddr nodeA to nodeB', (done) => {
nodeA.hangUp(peerB.multiaddrs.toArray()[0], (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(0)
done()
}
})
})
it('libp2p.dial using PeerInfo nodeA to nodeB', (done) => {
nodeA.dial(peerB, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500) // Some time for Identify to finish
function check () {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
done()
}
})
})
it('libp2p.dial using PeerInfo on Protocol nodeA to nodeB', (done) => {
nodeA.dial(peerB, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
const peers = nodeA.peerBook.getAll()
expect(err).to.not.exist()
expect(Object.keys(peers)).to.have.length(1)
pull(
pull.values([Buffer.from('hey')]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data).to.eql([Buffer.from('hey')])
done()
})
)
})
})
it('libp2p.hangUp using PeerInfo nodeA to nodeB', (done) => {
nodeA.hangUp(peerB, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
const peers = nodeA.peerBook.getAll()
expect(err).to.not.exist()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(0)
done()
}
})
})
describe('stress', () => {
it('one big write', (done) => {
nodeA.dial(peerB, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
const rawMessage = Buffer.alloc(100000)
rawMessage.fill('a')
const s = serializer(goodbye({
source: pull.values([rawMessage]),
sink: pull.collect((err, results) => {
expect(err).to.not.exist()
expect(results).to.have.length(1)
expect(Buffer.from(results[0])).to.have.length(rawMessage.length)
done()
})
}))
pull(s, conn, s)
})
})
it('many writes', (done) => {
nodeA.dial(peerB, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
const s = serializer(goodbye({
source: pull(
pull.infinite(),
pull.take(1000),
pull.map((val) => Buffer.from(val.toString()))
),
sink: pull.collect((err, result) => {
expect(err).to.not.exist()
expect(result).to.have.length(1000)
done()
})
}))
pull(s, conn, s)
})
})
})
})
describe('webrtc-star', () => {
if (!w.support) { return console.log('NO WEBRTC SUPPORT') }
let peer1
let peer2
let node1
let node2
it('create two peerInfo with webrtc-star addrs', (done) => {
parallel([
(cb) => PeerId.create({ bits: 1024 }, cb),
(cb) => PeerId.create({ bits: 1024 }, cb)
], (err, ids) => {
expect(err).to.not.exist()
peer1 = new PeerInfo(ids[0])
const ma1 = '/ip4/127.0.0.1/tcp/15555/ws/p2p-webrtc-star/ipfs/' + ids[0].toB58String()
peer1.multiaddrs.add(ma1)
peer2 = new PeerInfo(ids[1])
const ma2 = '/ip4/127.0.0.1/tcp/15555/ws/p2p-webrtc-star/ipfs/' + ids[1].toB58String()
peer2.multiaddrs.add(ma2)
done()
})
})
it('create two libp2p nodes with those peers', (done) => {
node1 = new Node(peer1, null, { webRTCStar: true })
node2 = new Node(peer2, null, { webRTCStar: true })
done()
})
it('listen on the two libp2p nodes', (done) => {
parallel([
(cb) => node1.start(cb),
(cb) => node2.start(cb)
], done)
})
it('handle a protocol on the first node', () => {
node2.handle('/echo/1.0.0', (protocol, conn) => pull(conn, conn))
})
it('dial from the second node to the first node', (done) => {
node1.dial(peer2, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
const text = 'hello'
const peers1 = node1.peerBook.getAll()
expect(Object.keys(peers1)).to.have.length(1)
const peers2 = node2.peerBook.getAll()
expect(Object.keys(peers2)).to.have.length(1)
pull(
pull.values([Buffer.from(text)]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data[0].toString()).to.equal(text)
done()
})
)
}
})
})
it('node1 hangUp node2', (done) => {
node1.hangUp(peer2, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
const peers = node1.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(node1.swarm.muxedConns)).to.have.length(0)
done()
}
})
})
it('create a third node and check that discovery works', (done) => {
let counter = 0
function check () {
if (++counter === 3) {
expect(Object.keys(node1.swarm.muxedConns).length).to.equal(1)
expect(Object.keys(node2.swarm.muxedConns).length).to.equal(1)
done()
}
}
PeerId.create((err, id3) => {
expect(err).to.not.exist()
const peer3 = new PeerInfo(id3)
const ma3 = '/ip4/127.0.0.1/tcp/15555/ws/p2p-webrtc-star/ipfs/' + id3.toB58String()
peer3.multiaddrs.add(ma3)
node1.on('peer:discovery', (peerInfo) => node1.dial(peerInfo, check))
node2.on('peer:discovery', (peerInfo) => node2.dial(peerInfo, check))
const node3 = new Node(peer3, null, { webRTCStar: true })
node3.start(check)
})
})
})
describe('websocket-star', () => {
let peer1
let peer2
let node1
let node2
it('create two peerInfo with websocket-star addrs', (done) => {
parallel([
(cb) => PeerId.create({ bits: 1024 }, cb),
(cb) => PeerId.create({ bits: 1024 }, cb)
], (err, ids) => {
expect(err).to.not.exist()
peer1 = new PeerInfo(ids[0])
const ma1 = '/ip4/127.0.0.1/tcp/14444/ws/p2p-websocket-star/'
peer1.multiaddrs.add(ma1)
peer2 = new PeerInfo(ids[1])
const ma2 = '/ip4/127.0.0.1/tcp/14444/ws/p2p-websocket-star/'
peer2.multiaddrs.add(ma2)
done()
})
})
it('create two libp2p nodes with those peers', (done) => {
node1 = new Node(peer1, null, { wsStar: true })
node2 = new Node(peer2, null, { wsStar: true })
done()
})
it('listen on the two libp2p nodes', (done) => {
parallel([
(cb) => node1.start(cb),
(cb) => node2.start(cb)
], done)
})
it('handle a protocol on the first node', () => {
node2.handle('/echo/1.0.0', (protocol, conn) => pull(conn, conn))
})
it('dial from the second node to the first node', (done) => {
node1.dial(peer2, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
const text = 'hello'
const peers1 = node1.peerBook.getAll()
expect(Object.keys(peers1)).to.have.length(1)
const peers2 = node2.peerBook.getAll()
expect(Object.keys(peers2)).to.have.length(1)
pull(
pull.values([Buffer.from(text)]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data[0].toString()).to.equal(text)
done()
})
)
}
})
})
it('node1 hangUp node2', (done) => {
node1.hangUp(peer2, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
const peers = node1.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(node1.swarm.muxedConns)).to.have.length(0)
done()
}
})
})
it('create a third node and check that discovery works', (done) => {
let counter = 0
function check () {
if (++counter === 3) {
expect(Object.keys(node1.swarm.muxedConns).length).to.equal(1)
expect(Object.keys(node2.swarm.muxedConns).length).to.equal(1)
done()
}
}
PeerId.create((err, id3) => {
expect(err).to.not.exist()
const peer3 = new PeerInfo(id3)
const ma3 = '/ip4/127.0.0.1/tcp/14444/ws/p2p-websocket-star/ipfs/' + id3.toB58String()
peer3.multiaddrs.add(ma3)
node1.on('peer:discovery', (peerInfo) => node1.dial(peerInfo, check))
node2.on('peer:discovery', (peerInfo) => node2.dial(peerInfo, check))
const node3 = new Node(peer3, null, { wsStar: true })
node3.start(check)
})
})
})
})

678
test/transports.node.js Normal file
View File

@ -0,0 +1,678 @@
/* eslint-env mocha */
'use strict'
const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const parallel = require('async/parallel')
const series = require('async/series')
const pull = require('pull-stream')
const utils = require('./utils/node.js')
const signalling = require('libp2p-webrtc-star/src/sig-server')
const rendezvous = require('libp2p-websocket-star-rendezvous')
const WSStar = require('libp2p-websocket-star')
const WRTCStar = require('libp2p-webrtc-star')
const wrtc = require('wrtc')
const createNode = utils.createNode
const echo = utils.echo
describe('transports', () => {
describe('TCP only', () => {
let nodeA
let nodeB
before((done) => {
parallel([
(cb) => createNode('/ip4/0.0.0.0/tcp/0', (err, node) => {
expect(err).to.not.exist()
nodeA = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
}),
(cb) => createNode('/ip4/0.0.0.0/tcp/0', (err, node) => {
expect(err).to.not.exist()
nodeB = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
})
], done)
})
after((done) => {
parallel([
(cb) => nodeA.stop(cb),
(cb) => nodeB.stop(cb)
], done)
})
it('nodeA.dial nodeB using PeerInfo without proto (warmup)', (done) => {
nodeA.dial(nodeB.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(err).to.not.exist()
expect(Object.keys(peers)).to.have.length(1)
cb()
},
(cb) => {
const peers = nodeB.peerBook.getAll()
expect(err).to.not.exist()
expect(Object.keys(peers)).to.have.length(1)
cb()
}
], done)
}
})
})
it('nodeA.dial nodeB using PeerInfo', (done) => {
nodeA.dial(nodeB.peerInfo, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
pull(
pull.values([Buffer.from('hey')]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data).to.be.eql([Buffer.from('hey')])
done()
})
)
})
})
it('nodeA.hangUp nodeB using PeerInfo (first)', (done) => {
nodeA.hangUp(nodeB.peerInfo, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(0)
cb()
},
(cb) => {
const peers = nodeB.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeB.swarm.muxedConns)).to.have.length(0)
cb()
}
], done)
}
})
})
it('nodeA.dial nodeB using multiaddr', (done) => {
nodeA.dial(nodeB.peerInfo.multiaddrs.toArray()[0], '/echo/1.0.0', (err, conn) => {
// Some time for Identify to finish
setTimeout(check, 500)
function check () {
expect(err).to.not.exist()
series([
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(1)
cb()
},
(cb) => {
const peers = nodeB.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(1)
cb()
}
], () => {
pull(
pull.values([Buffer.from('hey')]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data).to.be.eql([Buffer.from('hey')])
done()
})
)
})
}
})
})
it('nodeA.hangUp nodeB using multiaddr (second)', (done) => {
nodeA.hangUp(nodeB.peerInfo.multiaddrs.toArray()[0], (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(0)
cb()
},
(cb) => {
const peers = nodeB.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeB.swarm.muxedConns)).to.have.length(0)
cb()
}
], done)
}
})
})
it('nodeA.dial nodeB using PeerId', (done) => {
nodeA.dial(nodeB.peerInfo.id, '/echo/1.0.0', (err, conn) => {
// Some time for Identify to finish
setTimeout(check, 500)
function check () {
expect(err).to.not.exist()
series([
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(1)
cb()
},
(cb) => {
const peers = nodeB.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(1)
cb()
}
], () => {
pull(
pull.values([Buffer.from('hey')]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data).to.eql([Buffer.from('hey')])
done()
})
)
})
}
})
})
it('nodeA.hangUp nodeB using PeerId (third)', (done) => {
nodeA.hangUp(nodeB.peerInfo.multiaddrs.toArray()[0], (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(0)
cb()
},
(cb) => {
const peers = nodeB.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeB.swarm.muxedConns)).to.have.length(0)
cb()
}
], done)
}
})
})
})
describe('TCP + WebSockets', () => {
let nodeTCP
let nodeTCPnWS
let nodeWS
before((done) => {
parallel([
(cb) => createNode([
'/ip4/0.0.0.0/tcp/0'
], (err, node) => {
expect(err).to.not.exist()
nodeTCP = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
}),
(cb) => createNode([
'/ip4/0.0.0.0/tcp/0',
'/ip4/127.0.0.1/tcp/25011/ws'
], (err, node) => {
expect(err).to.not.exist()
nodeTCPnWS = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
}),
(cb) => createNode([
'/ip4/127.0.0.1/tcp/25022/ws'
], (err, node) => {
expect(err).to.not.exist()
nodeWS = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
})
], done)
})
after((done) => {
parallel([
(cb) => nodeTCP.stop(cb),
(cb) => nodeTCPnWS.stop(cb),
(cb) => nodeWS.stop(cb)
], done)
})
it('nodeTCP.dial nodeTCPnWS using PeerInfo', (done) => {
nodeTCP.dial(nodeTCPnWS.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeTCP.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeTCP.swarm.muxedConns)).to.have.length(1)
cb()
},
(cb) => {
const peers = nodeTCPnWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeTCPnWS.swarm.muxedConns)).to.have.length(1)
cb()
}
], done)
}
})
})
it('nodeTCP.hangUp nodeTCPnWS using PeerInfo', (done) => {
nodeTCP.hangUp(nodeTCPnWS.peerInfo, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeTCP.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeTCP.swarm.muxedConns)).to.have.length(0)
cb()
},
(cb) => {
const peers = nodeTCPnWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeTCPnWS.swarm.muxedConns)).to.have.length(0)
cb()
}
], done)
}
})
})
it('nodeTCPnWS.dial nodeWS using PeerInfo', (done) => {
nodeTCPnWS.dial(nodeWS.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeTCPnWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(2)
expect(Object.keys(nodeTCPnWS.swarm.muxedConns)).to.have.length(1)
cb()
},
(cb) => {
const peers = nodeWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeWS.swarm.muxedConns)).to.have.length(1)
cb()
}
], done)
}
})
})
it('nodeTCPnWS.hangUp nodeWS using PeerInfo', (done) => {
nodeTCPnWS.hangUp(nodeWS.peerInfo, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
function check () {
parallel([
(cb) => {
const peers = nodeTCPnWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(2)
expect(Object.keys(nodeTCPnWS.swarm.muxedConns)).to.have.length(0)
cb()
},
(cb) => {
const peers = nodeWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeWS.swarm.muxedConns)).to.have.length(0)
cb()
}
], done)
}
})
})
// Until https://github.com/libp2p/js-libp2p/issues/46 is resolved
// Everynode will be able to dial in WebSockets
it.skip('nodeTCP.dial nodeWS using PeerInfo is unsuccesful', (done) => {
nodeTCP.dial(nodeWS.peerInfo, (err) => {
expect(err).to.exist()
done()
})
})
})
describe('TCP + WebSockets + WebRTCStar', () => {
let nodeAll
let nodeTCP
let nodeWS
let nodeWStar
let ss
before(function (done) {
this.timeout(5 * 1000)
parallel([
(cb) => {
signalling.start({ port: 24642 }, (err, server) => {
expect(err).to.not.exist()
ss = server
cb()
})
},
(cb) => {
const wstar = new WRTCStar({wrtc: wrtc})
createNode([
'/ip4/0.0.0.0/tcp/0',
'/ip4/127.0.0.1/tcp/25011/ws',
'/ip4/127.0.0.1/tcp/24642/ws/p2p-webrtc-star'
], {
modules: {
transport: [wstar],
discovery: [wstar.discovery]
}
}, (err, node) => {
expect(err).to.not.exist()
nodeAll = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
})
},
(cb) => createNode([
'/ip4/0.0.0.0/tcp/0'
], (err, node) => {
expect(err).to.not.exist()
nodeTCP = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
}),
(cb) => createNode([
'/ip4/127.0.0.1/tcp/25022/ws'
], (err, node) => {
expect(err).to.not.exist()
nodeWS = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
}),
(cb) => {
const wstar = new WRTCStar({wrtc: wrtc})
createNode([
'/ip4/127.0.0.1/tcp/24642/ws/p2p-webrtc-star'
], {
modules: {
transport: [wstar],
discovery: [wstar.discovery]
}
}, (err, node) => {
expect(err).to.not.exist()
nodeWStar = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
})
}
], done)
})
after((done) => {
parallel([
(cb) => nodeAll.stop(cb),
(cb) => nodeTCP.stop(cb),
(cb) => nodeWS.stop(cb),
(cb) => nodeWStar.stop(cb),
(cb) => ss.stop(cb)
], done)
})
function check (otherNode, muxed, peers, callback) {
let i = 1;
[nodeAll, otherNode].forEach((node) => {
expect(Object.keys(node.peerBook.getAll())).to.have.length(i-- ? peers : 1)
expect(Object.keys(node.swarm.muxedConns)).to.have.length(muxed)
})
callback()
}
it('nodeAll.dial nodeTCP using PeerInfo', (done) => {
nodeAll.dial(nodeTCP.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(() => check(nodeTCP, 1, 1, done), 500)
})
})
it('nodeAll.hangUp nodeTCP using PeerInfo', (done) => {
nodeAll.hangUp(nodeTCP.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(() => check(nodeTCP, 0, 1, done), 500)
})
})
it('nodeAll.dial nodeWS using PeerInfo', (done) => {
nodeAll.dial(nodeWS.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(() => check(nodeWS, 1, 2, done), 500)
})
})
it('nodeAll.hangUp nodeWS using PeerInfo', (done) => {
nodeAll.hangUp(nodeWS.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(() => check(nodeWS, 0, 2, done), 500)
})
})
it('nodeAll.dial nodeWStar using PeerInfo', function (done) {
this.timeout(40 * 1000)
nodeAll.dial(nodeWStar.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(() => check(nodeWStar, 1, 3, done), 500)
})
})
it('nodeAll.hangUp nodeWStar using PeerInfo', (done) => {
nodeAll.hangUp(nodeWStar.peerInfo, (err) => {
expect(err).to.not.exist()
setTimeout(() => check(nodeWStar, 0, 3, done), 500)
})
})
})
describe('TCP + WebSockets + WebSocketStar', () => {
let nodeAll
let nodeTCP
let nodeWS
let nodeWStar
let ss
before((done) => {
parallel([
(cb) => {
rendezvous.start({ port: 24642 }, (err, server) => {
expect(err).to.not.exist()
ss = server
cb()
})
},
(cb) => {
const wstar = new WSStar()
createNode([
'/ip4/0.0.0.0/tcp/0',
'/ip4/127.0.0.1/tcp/25011/ws',
'/ip4/127.0.0.1/tcp/24642/ws/p2p-websocket-star'
], {
modules: {
transport: [wstar],
discovery: [wstar.discovery]
}
}, (err, node) => {
expect(err).to.not.exist()
nodeAll = node
wstar.lazySetId(node.peerInfo.id)
node.handle('/echo/1.0.0', echo)
node.start(cb)
})
},
(cb) => createNode([
'/ip4/0.0.0.0/tcp/0'
], (err, node) => {
expect(err).to.not.exist()
nodeTCP = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
}),
(cb) => createNode([
'/ip4/127.0.0.1/tcp/25022/ws'
], (err, node) => {
expect(err).to.not.exist()
nodeWS = node
node.handle('/echo/1.0.0', echo)
node.start(cb)
}),
(cb) => {
const wstar = new WSStar({})
createNode([
'/ip4/127.0.0.1/tcp/24642/ws/p2p-websocket-star'
], {
modules: {
transport: [wstar],
discovery: [wstar.discovery]
}
}, (err, node) => {
expect(err).to.not.exist()
nodeWStar = node
wstar.lazySetId(node.peerInfo.id)
node.handle('/echo/1.0.0', echo)
node.start(cb)
})
}
], done)
})
after((done) => {
parallel([
(cb) => nodeAll.stop(cb),
(cb) => nodeTCP.stop(cb),
(cb) => nodeWS.stop(cb),
(cb) => nodeWStar.stop(cb),
(cb) => ss.stop(cb)
], done)
})
function check (otherNode, muxed, peers, done) {
let i = 1;
[nodeAll, otherNode].forEach((node) => {
expect(Object.keys(node.peerBook.getAll())).to.have.length(i-- ? peers : 1)
expect(Object.keys(node.swarm.muxedConns)).to.have.length(muxed)
})
done()
}
it('nodeAll.dial nodeTCP using PeerInfo', (done) => {
nodeAll.dial(nodeTCP.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(() => check(nodeTCP, 1, 1, done), 500)
})
})
it('nodeAll.hangUp nodeTCP using PeerInfo', (done) => {
nodeAll.hangUp(nodeTCP.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(() => check(nodeTCP, 0, 1, done), 500)
})
})
it('nodeAll.dial nodeWS using PeerInfo', (done) => {
nodeAll.dial(nodeWS.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(() => check(nodeWS, 1, 2, done), 500)
})
})
it('nodeAll.hangUp nodeWS using PeerInfo', (done) => {
nodeAll.hangUp(nodeWS.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(() => check(nodeWS, 0, 2, done), 500)
})
})
it('nodeAll.dial nodeWStar using PeerInfo', (done) => {
nodeAll.dial(nodeWStar.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(() => check(nodeWStar, 1, 3, done), 500)
})
})
it('nodeAll.hangUp nodeWStar using PeerInfo', (done) => {
nodeAll.hangUp(nodeWStar.peerInfo, (err) => {
expect(err).to.not.exist()
// Some time for Identify to finish
setTimeout(() => check(nodeWStar, 0, 3, done), 500)
})
})
})
})

View File

@ -7,9 +7,8 @@ const expect = chai.expect
const multiaddr = require('multiaddr')
const spawn = require('child_process').spawn
const path = require('path')
// const map = require('async/map')
const pull = require('pull-stream')
const utils = require('./utils')
const utils = require('./utils/node')
const createNode = utils.createNode
const echo = utils.echo
@ -57,11 +56,11 @@ describe('Turbolence tests', () => {
expect(Object.keys(peers)).to.have.length(1)
pull(
pull.values([new Buffer('hey')]),
pull.values([Buffer.from('hey')]),
conn,
pull.collect((err, data) => {
expect(err).to.not.exist()
expect(data).to.eql([new Buffer('hey')])
expect(data).to.eql([Buffer.from('hey')])
done()
})
)

View File

@ -2,6 +2,7 @@
const WS = require('libp2p-websockets')
const WebRTCStar = require('libp2p-webrtc-star')
const WebSocketStar = require('libp2p-websocket-star')
const spdy = require('libp2p-spdy')
const multiplex = require('libp2p-multiplex')
const secio = require('libp2p-secio')
@ -35,12 +36,14 @@ function getMuxers (options) {
class Node extends libp2p {
constructor (peerInfo, peerBook, options) {
options = options || {}
const webRTCStar = new WebRTCStar()
const wrtcStar = new WebRTCStar({ id: peerInfo.id })
const wsStar = new WebSocketStar({ id: peerInfo.id })
const modules = {
transport: [
new WS(),
webRTCStar
wrtcStar,
wsStar
],
connection: {
muxer: getMuxers(options.muxer),
@ -52,7 +55,11 @@ class Node extends libp2p {
}
if (options.webRTCStar) {
modules.discovery.push(webRTCStar.discovery)
modules.discovery.push(wrtcStar.discovery)
}
if (options.wsStar) {
modules.discovery.push(wsStar.discovery)
}
if (options.bootstrap) {

View File

@ -3,7 +3,7 @@
const chai = require('chai')
chai.use(require('dirty-chai'))
const Node = require('./nodejs-bundle')
const Node = require('./bundle.node')
const PeerInfo = require('peer-info')
const PeerId = require('peer-id')
const waterfall = require('async/waterfall')
@ -15,6 +15,8 @@ function createNode (multiaddrs, options, callback) {
options = {}
}
options = options || {}
if (!Array.isArray(multiaddrs)) {
multiaddrs = [multiaddrs]
}