Compare commits

...

47 Commits

Author SHA1 Message Date
7733ba5cd7 chore: release version v0.16.3 2018-02-08 08:11:24 +00:00
52bf826ec6 chore: update contributors 2018-02-08 08:11:24 +00:00
10619afbe6 chore: release version v0.16.2 2018-02-07 09:50:30 +00:00
3debabdd26 chore: update contributors 2018-02-07 09:50:30 +00:00
56e095983a chore: update npm ignore 2018-02-07 09:50:01 +00:00
ebdb696742 chore: release version v0.16.1 2018-02-07 09:45:01 +00:00
721e6ee9ce chore: update contributors 2018-02-07 09:45:01 +00:00
98f2903088 chore: release version v0.16.0 2018-02-07 08:39:08 +00:00
3dda282dfd chore: update contributors 2018-02-07 08:39:08 +00:00
03faf69212 test: fix linting 2018-02-07 08:37:03 +00:00
0062a4b5eb docs: update examples 2018-02-07 08:37:03 +00:00
f7f85dce0a test: update tests to new API 2018-02-07 08:37:03 +00:00
59df82a675 docs: dialProtocol 2018-02-07 08:37:03 +00:00
6651401f0b feat: dialProtocol and small refactor 2018-02-07 08:37:03 +00:00
cd43863db6 chore: use pre-push 2018-02-07 07:31:10 +00:00
23e8293b75 feat: use libp2p-switch 2018-02-07 07:31:10 +00:00
68c170a40d docs: Add ws-star and ws-star-rendezvous (#158) 2018-02-07 07:07:53 +00:00
bd8a35aaf9 feat: add explicit error for case peer id not included in multiaddr (#155) 2018-02-05 12:36:20 +01:00
248d86d050 fix typo (#152) 2018-01-27 23:26:57 -08:00
8225b11082 fix typo (#153) 2018-01-27 23:26:52 -08:00
1355af2b51 docs: fix typos (#154) 2018-01-27 23:26:46 -08:00
a85f041843 chore: release version v0.15.2 2018-01-27 18:51:45 -08:00
2c0cda2a7c chore: update contributors 2018-01-27 18:51:45 -08:00
b4ba267589 chore: update deps 2018-01-27 18:48:44 -08:00
4c81f39ebe chore: release version v0.15.1 2018-01-16 06:16:15 -08:00
76922383ab chore: update contributors 2018-01-16 06:16:15 -08:00
3fc57ff397 chore: bump timeout on after 2018-01-16 06:13:42 -08:00
13b36dcaa6 chore: update deps 2018-01-16 06:03:04 -08:00
61bebd10fc fix: typo in DHT setup (#151)
I think there was a typo that would have ignored passed options and fallback to defaults for DHT datastore.
2018-01-16 05:58:12 -08:00
97cde1ccb4 test: Various pdd fixes (#150)
* fix(pdd): url for interop pkg was pointing to non-existing branch

* fix(pdd): case-sensitive names

peer-B.json does not _actually_ exist

* fix(pdd): story 2 peer b
2018-01-10 14:53:24 +00:00
07b0cdc30e docs: note the Connection type on .handle and .dial docs (#149) 2018-01-07 18:47:02 +00:00
73b6d60e32 docs: update to new URL format on the browser example 2018-01-07 17:17:22 +00:00
808f7495a9 chore: release version v0.15.0 2018-01-07 17:09:57 +00:00
ae21a6facf chore: update contributors 2018-01-07 17:09:56 +00:00
3aba3fd176 chore: update deps (#148) 2018-01-07 17:00:24 +00:00
dc2da39a19 docs: tcp/443 on webrtc-star example. (#147)
according to https://github.com/libp2p/js-libp2p-webrtc-star/issues/134 and my own fiddling with this example.
2018-01-06 14:28:20 +00:00
f8b441fff5 docs: Update README.md (#143)
added missing backtick
2018-01-02 07:18:41 +00:00
190ad54f9e PDD Compliance Tests (#137)
* transport story 1 done

* c

* transport series 2

* transports story 3

* the ipfs-bundle story 1
2017-12-18 10:23:34 +00:00
582f8bed2e docs: fix links on examples peer and content routing (#141) 2017-12-18 09:53:30 +00:00
59de0da19c chore: release version v0.14.3 2017-12-15 08:25:08 +00:00
0caf600c9a chore: update contributors 2017-12-15 08:25:08 +00:00
a4943b4509 chore: update npm ignore 2017-12-15 08:24:49 +00:00
c128873a07 chore: release version v0.14.2 2017-12-15 07:15:05 +00:00
5e2b6df04a chore: update contributors 2017-12-15 07:15:05 +00:00
8d2d8c98a0 chore: release version v0.14.1 2017-12-15 07:10:42 +00:00
30bf5bb161 chore: update contributors 2017-12-15 07:10:42 +00:00
c88eaf416c fix: prevent "The libp2p node is not started yet" when stopping (#138) 2017-12-15 07:08:44 +00:00
51 changed files with 943 additions and 364 deletions

View File

@ -1,7 +1,16 @@
**/node_modules/
**/*.log
test/repo-tests*
img
docs
examples
# Logs
logs
*.log
coverage
# Runtime data
pids
*.pid
@ -16,13 +25,13 @@ coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# node-waf configuration
.lock-wscript
# Optional npm cache directory
.npm
build
# Optional REPL history
.node_repl_history
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
test
test

View File

@ -1,3 +1,70 @@
<a name="0.16.3"></a>
## [0.16.3](https://github.com/libp2p/js-libp2p/compare/v0.16.2...v0.16.3) (2018-02-08)
<a name="0.16.2"></a>
## [0.16.2](https://github.com/libp2p/js-libp2p/compare/v0.16.1...v0.16.2) (2018-02-07)
<a name="0.16.1"></a>
## [0.16.1](https://github.com/libp2p/js-libp2p/compare/v0.16.0...v0.16.1) (2018-02-07)
<a name="0.16.0"></a>
# [0.16.0](https://github.com/libp2p/js-libp2p/compare/v0.15.2...v0.16.0) (2018-02-07)
### Features
* add explicit error for case peer id not included in multiaddr ([#155](https://github.com/libp2p/js-libp2p/issues/155)) ([bd8a35a](https://github.com/libp2p/js-libp2p/commit/bd8a35a))
* dialProtocol and small refactor ([6651401](https://github.com/libp2p/js-libp2p/commit/6651401))
* use libp2p-switch ([23e8293](https://github.com/libp2p/js-libp2p/commit/23e8293))
<a name="0.15.2"></a>
## [0.15.2](https://github.com/libp2p/js-libp2p/compare/v0.15.1...v0.15.2) (2018-01-28)
<a name="0.15.1"></a>
## [0.15.1](https://github.com/libp2p/js-libp2p/compare/v0.15.0...v0.15.1) (2018-01-16)
### Bug Fixes
* typo in DHT setup ([#151](https://github.com/libp2p/js-libp2p/issues/151)) ([61bebd1](https://github.com/libp2p/js-libp2p/commit/61bebd1))
<a name="0.15.0"></a>
# [0.15.0](https://github.com/libp2p/js-libp2p/compare/v0.14.3...v0.15.0) (2018-01-07)
<a name="0.14.3"></a>
## [0.14.3](https://github.com/libp2p/js-libp2p/compare/v0.14.2...v0.14.3) (2017-12-15)
<a name="0.14.2"></a>
## [0.14.2](https://github.com/libp2p/js-libp2p/compare/v0.14.1...v0.14.2) (2017-12-15)
<a name="0.14.1"></a>
## [0.14.1](https://github.com/libp2p/js-libp2p/compare/v0.14.0...v0.14.1) (2017-12-15)
### Bug Fixes
* prevent "The libp2p node is not started yet" when stopping ([#138](https://github.com/libp2p/js-libp2p/issues/138)) ([c88eaf4](https://github.com/libp2p/js-libp2p/commit/c88eaf4))
<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)

View File

@ -158,16 +158,26 @@ class Node extends libp2p {
`callback` is a function with the following `function (err) {}` signature, where `err` is an Error in case stopping the node fails.
#### `libp2p.dial(peer [, protocol, callback])`
#### `libp2p.dial(peer, callback)`
> Dials to another peer in the network.
> Dials to another peer in the network, establishes the connection.
- `peer`: can be an instance of [PeerInfo][], [PeerId][] or [multiaddr][]
- `protocol`: String that defines the protocol (e.g '/ipfs/bitswap/1.1.0')
- `peer`: can be an instance of [PeerInfo][], [PeerId][], [multiaddr][], or a multiaddr string
- `callback`: Function with signature `function (err, conn) {}` where `conn` is a [Connection](https://github.com/libp2p/interface-connection) object
`callback` is a function with the following `function (err, conn) {}` signature, where `err` is an Error in of failure to dial the connection and `conn` is a [Connection][] instance in case of a protocol selected, if not it is undefined.
#### `libp2p.hangUp(peer, callback)
#### `libp2p.dialProtocol(peer, protocol, callback)`
> Dials to another peer in the network and selects a protocol to talk with that peer.
- `peer`: can be an instance of [PeerInfo][], [PeerId][], [multiaddr][], or a multiaddr string
- `protocol`: String that defines the protocol (e.g '/ipfs/bitswap/1.1.0')
- `callback`: Function with signature `function (err, conn) {}` where `conn` is a [Connection](https://github.com/libp2p/interface-connection) object
`callback` is a function with the following `function (err, conn) {}` signature, where `err` is an Error in of failure to dial the connection and `conn` is a [Connection][] instance in case of a protocol selected, if not it is undefined.
#### `libp2p.hangUp(peer, callback)`
> Closes an open connection with a peer, graciously.
@ -196,7 +206,7 @@ class Node extends libp2p {
> Handle new protocol
- `protocol`: String that defines the protocol (e.g '/ipfs/bitswap/1.1.0')
- `handlerFunc`: Function with signature `function (protocol, conn) {}`
- `handlerFunc`: Function with signature `function (protocol, conn) {}` where `conn` is a [Connection](https://github.com/libp2p/interface-connection) object
- `matchFunc`: Function for matching on protocol (exact matching, semver, etc). Default to exact match.
#### `libp2p.unhandle(protocol)`
@ -310,6 +320,8 @@ List of packages currently in existence for libp2p
| [`libp2p-utp`](//github.com/libp2p/js-libp2p-utp) | [![npm](https://img.shields.io/npm/v/libp2p-utp.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-utp/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-utp.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-utp) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-utp/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-utp?type=dev) |
| [`libp2p-websockets`](//github.com/libp2p/js-libp2p-websockets) | [![npm](https://img.shields.io/npm/v/libp2p-websockets.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-websockets/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-websockets.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websockets) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-websockets/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websockets?type=dev) |
| [`libp2p-webrtc-star`](//github.com/libp2p/js-libp2p-webrtc-star) | [![npm](https://img.shields.io/npm/v/libp2p-webrtc-star.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-webrtc-star/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-webrtc-star.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-webrtc-star) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-webrtc-star/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-webrtc-star?type=dev) |
| [`libp2p-websocket-star`](//github.com/libp2p/js-libp2p-websocket-star) | [![npm](https://img.shields.io/npm/v/libp2p-websocket-star.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-websocket-star/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-websocket-star.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websocket-star) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-websocket-star/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websocket-star?type=dev) |
| [`libp2p-websocket-star-rendezvous`](//github.com/libp2p/js-libp2p-websocket-star-rendezvous) | [![npm](https://img.shields.io/npm/v/libp2p-websocket-star-rendezvous.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-websocket-star-rendezvous/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-websocket-star-rendezvous.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websocket-star-rendezvous) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-websocket-star-rendezvous/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websocket-star-rendezvous?type=dev) |
| **Connection Upgrades** |
| [`interface-connection`](//github.com/libp2p/interface-connection) | [![npm](https://img.shields.io/npm/v/interface-connection.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/interface-connection/releases) | [![Dependency Status](https://david-dm.org/libp2p/interface-connection.svg?style=flat-square)](https://david-dm.org/libp2p/interface-connection) | [![devDependency Status](https://david-dm.org/libp2p/interface-connection/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/interface-connection?type=dev) |
| **Stream Muxers** |

View File

@ -10,8 +10,8 @@ Let us know if you find any issue or if you want to contribute and add a new tut
- [Protocol and Stream Muxing](./protocol-and-stream-muxing)
- [Encrypted Communications](./encrypted-communications)
- [Discovery Mechanisms](./discovery-mechanisms)
- [Peer Routing](./peer-routing)
- [Content Routing](./content-routing)
- [Peer Routing](./peer-and-content-routing)
- [Content Routing](./peer-and-content-routing)
- [PubSub](./pubsub)
- [NAT Traversal](./nat-traversal)
- Circuit Relay (future)

View File

@ -47,7 +47,7 @@ async.parallel([
console.log(ma.toString() + '/ipfs/' + idListener.toB58String())
})
nodeDialer.dial(peerListener, '/chat/1.0.0', (err, conn) => {
nodeDialer.dialProtocol(peerListener, '/chat/1.0.0', (err, conn) => {
if (err) {
throw err
}

View File

@ -38,7 +38,7 @@ async.parallel([
'/ipfs/' + dialerId.toB58String()))
console.log('Dialing to peer:', listenerMultiaddr.toString())
dialerNode.dial(listenerPeerInfo, '/echo/1.0.0', (err, conn) => {
dialerNode.dialProtocol(listenerPeerInfo, '/echo/1.0.0', (err, conn) => {
if (err) { throw err }
console.log('nodeA dialed to nodeB on protocol: /echo/1.0.0')

View File

@ -52,7 +52,7 @@ parallel([
)
})
node1.dial(node2.peerInfo, '/a-protocol', (err, conn) => {
node1.dialProtocol(node2.peerInfo, '/a-protocol', (err, conn) => {
if (err) { throw err }
pull(pull.values(['This information is sent out encrypted to the other peer']), conn)
})

View File

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

View File

@ -75,20 +75,20 @@ parallel([
})
*/
node1.dial(node2.peerInfo, '/your-protocol', (err, conn) => {
node1.dialProtocol(node2.peerInfo, '/your-protocol', (err, conn) => {
if (err) { throw err }
pull(pull.values(['my own protocol, wow!']), conn)
})
/*
node1.dial(node2.peerInfo, '/another-protocol/1.0.0', (err, conn) => {
node1.dialProtocol(node2.peerInfo, '/another-protocol/1.0.0', (err, conn) => {
if (err) { throw err }
pull(pull.values(['semver me please']), conn)
})
*/
/*
node1.dial(node2.peerInfo, '/custom-match-func/some-query', (err, conn) => {
node1.dialProtocol(node2.peerInfo, '/custom-match-func/some-query', (err, conn) => {
if (err) { throw err }
pull(pull.values(['do I fall into your criteria?']), conn)
})

View File

@ -60,17 +60,17 @@ parallel([
})
series([
(cb) => node1.dial(node2.peerInfo, '/a', (err, conn) => {
(cb) => node1.dialProtocol(node2.peerInfo, '/a', (err, conn) => {
if (err) { throw err }
pull(pull.values(['protocol (a)']), conn)
cb()
}),
(cb) => node1.dial(node2.peerInfo, '/b', (err, conn) => {
(cb) => node1.dialProtocol(node2.peerInfo, '/b', (err, conn) => {
if (err) { throw err }
pull(pull.values(['protocol (b)']), conn)
cb()
}),
(cb) => node1.dial(node2.peerInfo, '/b', (err, conn) => {
(cb) => node1.dialProtocol(node2.peerInfo, '/b', (err, conn) => {
if (err) { throw err }
pull(pull.values(['another conn on protocol (b)']), conn)
cb()

View File

@ -30,7 +30,7 @@ node2.handle('/your-protocol', (protocol, conn) => {
After the protocol is _handled_, now we can dial to it.
```JavaScript
node1.dial(node2.peerInfo, '/your-protocol', (err, conn) => {
node1.dialProtocol(node2.peerInfo, '/your-protocol', (err, conn) => {
if (err) { throw err }
pull(pull.values(['my own protocol, wow!']), conn)
})
@ -47,7 +47,7 @@ node2.handle('/another-protocol/1.0.1', (protocol, conn) => {
)
})
// ...
node1.dial(node2.peerInfo, '/another-protocol/1.0.0', (err, conn) => {
node1.dialProtocol(node2.peerInfo, '/another-protocol/1.0.0', (err, conn) => {
if (err) { throw err }
pull(pull.values(['semver me please']), conn)
})
@ -74,7 +74,7 @@ node2.handle('/custom-match-func', (protocol, conn) => {
}
})
// ...
node1.dial(node2.peerInfo, '/custom-match-func/some-query', (err, conn) => {
node1.dialProtocol(node2.peerInfo, '/custom-match-func/some-query', (err, conn) => {
if (err) { throw err }
pull(pull.values(['do I fall into your criteria?']), conn)
})
@ -129,17 +129,17 @@ node2.handle('/b', (protocol, conn) => {
})
series([
(cb) => node1.dial(node2.peerInfo, '/a', (err, conn) => {
(cb) => node1.dialProtocol(node2.peerInfo, '/a', (err, conn) => {
if (err) { throw err }
pull(pull.values(['protocol (a)']), conn)
cb()
}),
(cb) => node1.dial(node2.peerInfo, '/b', (err, conn) => {
(cb) => node1.dialProtocol(node2.peerInfo, '/b', (err, conn) => {
if (err) { throw err }
pull(pull.values(['protocol (b)']), conn)
cb()
}),
(cb) => node1.dial(node2.peerInfo, '/b', (err, conn) => {
(cb) => node1.dialProtocol(node2.peerInfo, '/b', (err, conn) => {
if (err) { throw err }
pull(pull.values(['another conn on protocol (b)']), conn)
cb()
@ -158,9 +158,9 @@ another protocol (b)
# 3. Bidirectional connections
There is one last trick on _protocol and stream multiplexing_ that libp2p uses to make everyone's life easier and that is _biderectional connection_.
There is one last trick on _protocol and stream multiplexing_ that libp2p uses to make everyone's life easier and that is _bidirectional connection_.
With the aid of both mechanisms, we can reuse an incomming connection to dial streams out too, this is specially useful when you are behind tricky NAT, firewalls or if you are running in a browser, where you can have listening addrs, but you can dial out. By dialing out, you enable other peers to talk with you in Protocols that they want, simply by opening a new multiplexed stream.
With the aid of both mechanisms, we can reuse an incomming connection to dial streams out too, this is specially useful when you are behind tricky NAT, firewalls or if you are running in a browser, where you can't have listening addrs, but you can dial out. By dialing out, you enable other peers to talk with you in Protocols that they want, simply by opening a new multiplexed stream.
You can see this working on example [3.js](./3.js). The result should look like the following:

View File

@ -54,7 +54,7 @@ parallel([
)
})
node1.dial(node2.peerInfo, '/print', (err, conn) => {
node1.dialProtocol(node2.peerInfo, '/print', (err, conn) => {
if (err) { throw err }
pull(pull.values(['Hello', ' ', 'p2p', ' ', 'world', '!']), conn)

View File

@ -66,19 +66,19 @@ parallel([
node2.handle('/print', print)
node3.handle('/print', print)
node1.dial(node2.peerInfo, '/print', (err, conn) => {
node1.dialProtocol(node2.peerInfo, '/print', (err, conn) => {
if (err) { throw err }
pull(pull.values(['node 1 dialed to node 2 successfully']), conn)
})
node2.dial(node3.peerInfo, '/print', (err, conn) => {
node2.dialProtocol(node3.peerInfo, '/print', (err, conn) => {
if (err) { throw err }
pull(pull.values(['node 2 dialed to node 3 successfully']), conn)
})
node3.dial(node1.peerInfo, '/print', (err, conn) => {
node3.dialProtocol(node1.peerInfo, '/print', (err, conn) => {
if (err) {
console.log('node 3 failed to dial to node 1 with:', err.message)
}

View File

@ -143,7 +143,7 @@ parallel([
)
})
node1.dial(node2.peerInfo, '/print', (err, conn) => {
node1.dialProtocol(node2.peerInfo, '/print', (err, conn) => {
if (err) { throw err }
pull(pull.values(['Hello', ' ', 'p2p', ' ', 'world', '!']), conn)
@ -240,21 +240,21 @@ parallel([
node3.handle('/print', print)
// node 1 (TCP) dials to node 2 (TCP+WebSockets)
node1.dial(node2.peerInfo, '/print', (err, conn) => {
node1.dialProtocol(node2.peerInfo, '/print', (err, conn) => {
if (err) { throw err }
pull(pull.values(['node 1 dialed to node 2 successfully']), conn)
})
// node 2 (TCP+WebSockets) dials to node 2 (WebSockets)
node2.dial(node3.peerInfo, '/print', (err, conn) => {
node2.dialProtocol(node3.peerInfo, '/print', (err, conn) => {
if (err) { throw err }
pull(pull.values(['node 2 dialed to node 3 successfully']), conn)
})
// node 3 (WebSockets) attempts to dial to node 1 (TCP)
node3.dial(node1.peerInfo, '/print', (err, conn) => {
node3.dialProtocol(node1.peerInfo, '/print', (err, conn) => {
if (err) {
console.log('node 3 failed to dial to node 1 with:', err.message)
}
@ -298,8 +298,8 @@ As expected, we created 3 nodes, node 1 with TCP, node 2 with TCP+WebSockets and
Today there are already 3 transports available, one in the works and plenty to come, you can find these at [interface-transport implementations](https://github.com/libp2p/interface-transport#modules-that-implement-the-interface) list.
Adding more transports is done through the same way as you added TCP and WebSockets. Some transports might offer extra functionalities but for what is libp2p concern, as long as it follows the interface defined at the [spec](https://github.com/libp2p/interface-transport#api), it will be able to use it.
Adding more transports is done through the same way as you added TCP and WebSockets. Some transports might offer extra functionalities, but as far as libp2p is concerned, if it follows the interface defined at the [spec](https://github.com/libp2p/interface-transport#api) it will be able to use it.
If you decide to implement a transport yourself, please consider adding to the list so that others can use it as well.
Hope this tutorial was useful. We are always looking to improve it, contributions are welcome!
Hope this tutorial was useful. We are always looking to improve it, so contributions are welcome!

View File

@ -1,6 +1,6 @@
{
"name": "libp2p",
"version": "0.14.0",
"version": "0.16.3",
"description": "JavaScript base class for libp2p bundles",
"main": "src/index.js",
"scripts": {
@ -26,7 +26,7 @@
"node": ">=6.0.0",
"npm": ">=3.0.0"
},
"pre-commit": [
"pre-push": [
"lint",
"test"
],
@ -39,27 +39,27 @@
"dependencies": {
"async": "^2.6.0",
"libp2p-ping": "~0.6.0",
"libp2p-swarm": "~0.34.0",
"libp2p-switch": "~0.36.0",
"mafmt": "^3.0.2",
"multiaddr": "^3.0.1",
"peer-book": "~0.5.2",
"peer-id": "~0.10.3",
"peer-info": "~0.11.3"
"multiaddr": "^3.0.2",
"peer-book": "~0.5.4",
"peer-id": "~0.10.5",
"peer-info": "~0.11.6"
},
"devDependencies": {
"aegir": "^12.2.0",
"aegir": "^12.4.0",
"chai": "^4.1.2",
"cids": "~0.5.2",
"dirty-chai": "^2.0.1",
"electron-webrtc": "~0.3.0",
"libp2p-circuit": "~0.1.4",
"libp2p-kad-dht": "~0.6.0",
"libp2p-mdns": "~0.9.1",
"libp2p-kad-dht": "~0.6.3",
"libp2p-mdns": "~0.9.2",
"libp2p-multiplex": "~0.5.1",
"libp2p-railing": "~0.7.1",
"libp2p-secio": "~0.8.1",
"libp2p-secio": "~0.9.1",
"libp2p-spdy": "~0.11.0",
"libp2p-tcp": "~0.11.1",
"libp2p-tcp": "~0.11.5",
"libp2p-webrtc-star": "~0.13.3",
"libp2p-websockets": "~0.10.4",
"libp2p-websocket-star": "~0.7.2",
@ -70,17 +70,22 @@
"pull-serializer": "~0.3.2",
"pull-stream": "^3.6.1",
"safe-buffer": "^5.1.1",
"sinon": "^4.1.3",
"wrtc": "0.0.63"
"sinon": "^4.2.2",
"wrtc": "0.0.65"
},
"contributors": [
"Chris Bratlien <chrisbratlien@gmail.com>",
"Chris Dostert <chrisdostert@users.noreply.github.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>",
"Giovanni T. Parra <fiatjaf@gmail.com>",
"Irakli Gozalishvili <rfobic@gmail.com>",
"Joel Gustafson <joelg@mit.edu>",
"John Rees <johnrees@users.noreply.github.com>",
"Kevin Kwok <antimatter15@gmail.com>",
"Lars Gierth <lgierth@users.noreply.github.com>",
"Maciej Krüger <mkg20001@gmail.com>",
"Nuno Nogueira <nunofmn@gmail.com>",
@ -88,6 +93,7 @@
"RasmusErik Voel Jensen <github@solsort.com>",
"Richard Littauer <richard.littauer@gmail.com>",
"Ryan Bell <ryan@piing.net>",
"Tiago Alves <alvesjtiago@gmail.com>",
"greenkeeperio-bot <support@greenkeeper.io>",
"mayerwin <mayerwin@users.noreply.github.com>",
"ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com>"

3
pdd/README.md Normal file
View File

@ -0,0 +1,3 @@
# PDD Test Stories Implementation
> Implementation of the Compliance tests from https://github.com/libp2p/interop

20
pdd/package.json Normal file
View File

@ -0,0 +1,20 @@
{
"name": "pdd-impl",
"version": "0.0.0",
"description": "PDD Test Stories implementation",
"repository": {
"type": "git",
"url": " "
},
"keywords": [
"PDD",
"libp2p"
],
"author": "David Dias <daviddias@ipfs.io>",
"license": "MIT",
"dependencies": {
"libp2p": "file:./..",
"libp2p-interop": "github:libp2p/interop#master",
"tape": "^4.8.0"
}
}

View File

@ -0,0 +1,104 @@
'use strict'
const test = require('tape')
const libp2p = require('libp2p')
const TCP = require('libp2p-tcp')
const WebSockets = require('libp2p-websockets')
const SECIO = require('libp2p-secio')
const Multiplex = require('libp2p-multiplex')
const Railing = require('libp2p-railing')
const MulticastDNS = require('libp2p-mdns')
const KadDHT = require('libp2p-kad-dht')
const PeerInfo = require('peer-info')
const pull = require('pull-stream')
const waterfall = require('async/waterfall')
const series = require('async/series')
const PeerA = require('libp2p-interop/peer-a.json')
const PeerB = require('libp2p-interop/peer-b.json')
class IPFSBundle extends libp2p {
constructor (peerInfo, options) {
options = Object.assign({ bootstrap: [] }, options)
const modules = {
transport: [
new TCP(),
new WebSockets()
],
connection: {
muxer: [
Multiplex
],
crypto: [
SECIO
]
},
discovery: [
new MulticastDNS(peerInfo, 'ipfs.local'),
new Railing(options.bootstrap)
],
DHT: KadDHT
}
super(modules, peerInfo, undefined, options)
}
}
test('story 1 - peerA', (t) => {
t.plan(10)
let node
waterfall([
(cb) => PeerInfo.create(PeerA, cb),
(peerInfo, cb) => {
peerInfo.multiaddrs.add('/ip4/127.0.0.1/tcp/10000')
node = new IPFSBundle(peerInfo)
node.start(cb)
}
], (err) => {
t.ifErr(err, 'created Node successfully')
t.ok(node.isStarted(), 'PeerA is Running')
const peerBAddr = `/ip4/127.0.0.1/tcp/10001/ipfs/${PeerB.id}`
node.handle('/time/1.0.0', (protocol, conn) => {
pull(
pull.values([Date.now().toString()]),
conn,
pull.onEnd((err) => {
t.ifErr(err)
t.pass('Sent time successfully')
})
)
})
series([
(cb) => setTimeout(cb, 5 * 1000), // time to run both scripts
(cb) => node.ping(peerBAddr, (err, p) => {
t.ifErr(err, 'initiated Ping to PeerB')
p.once('error', (err) => t.ifErr(err, 'Ping should not fail'))
p.once('ping', (time) => {
t.pass('ping PeerB successfully')
p.stop()
cb()
})
}),
(cb) => node.dial(peerBAddr, '/echo/1.0.0', (err, conn) => {
t.ifErr(err, 'dial successful')
const data = Buffer.from('Hey')
pull(
pull.values([data]),
conn,
pull.collect((err, values) => {
t.ifErr(err, 'Received echo back')
t.deepEqual(values[0], data)
cb()
})
)
}),
(cb) => setTimeout(cb, 2 * 1000) // time to both finish
], () => node.stop((err) => t.ifErr(err, 'PeerA has stopped')))
})
})

View File

@ -0,0 +1,98 @@
'use strict'
const test = require('tape')
const libp2p = require('libp2p')
const TCP = require('libp2p-tcp')
const WebSockets = require('libp2p-websockets')
const SECIO = require('libp2p-secio')
const Multiplex = require('libp2p-multiplex')
const Railing = require('libp2p-railing')
const MulticastDNS = require('libp2p-mdns')
const KadDHT = require('libp2p-kad-dht')
const PeerInfo = require('peer-info')
const pull = require('pull-stream')
const waterfall = require('async/waterfall')
const series = require('async/series')
const PeerA = require('libp2p-interop/peer-a.json')
const PeerB = require('libp2p-interop/peer-b.json')
class IPFSBundle extends libp2p {
constructor (peerInfo, options) {
options = Object.assign({ bootstrap: [] }, options)
const modules = {
transport: [
new TCP(),
new WebSockets()
],
connection: {
muxer: [
Multiplex
],
crypto: [
SECIO
]
},
discovery: [
new MulticastDNS(peerInfo, 'ipfs.local'),
new Railing(options.bootstrap)
],
DHT: KadDHT
}
super(modules, peerInfo, undefined, options)
}
}
test('story 1 - peerA', (t) => {
t.plan(8)
let node
waterfall([
(cb) => PeerInfo.create(PeerB, cb),
(peerInfo, cb) => {
peerInfo.multiaddrs.add('/ip4/127.0.0.1/tcp/10001')
node = new IPFSBundle(peerInfo)
node.start(cb)
}
], (err) => {
t.ifErr(err, 'created Node successfully')
t.ok(node.isStarted(), 'PeerB is Running')
const peerAAddr = `/ip4/127.0.0.1/tcp/10000/ipfs/${PeerA.id}`
node.handle('/echo/1.0.0', (protocol, conn) => {
pull(
conn,
conn,
pull.onEnd((err) => t.ifErr(err, 'echo was successful'))
)
})
series([
(cb) => setTimeout(cb, 5 * 1000), // time to run both scripts
(cb) => node.ping(peerAAddr, (err, p) => {
t.ifErr(err, 'initiated Ping to PeerA')
p.once('error', (err) => t.ifErr(err, 'Ping should not fail'))
p.once('ping', (time) => {
t.pass('ping PeerA successfully')
p.stop()
cb()
})
}),
(cb) => node.dial(peerAAddr, '/time/1.0.0', (err, conn) => {
t.ifErr(err, 'dial successful')
pull(
pull.values([]),
conn,
pull.collect((err, values) => {
t.ifErr(err, 'Received time')
cb()
})
)
}),
(cb) => setTimeout(cb, 2 * 1000) // time to both finish
], () => node.stop((err) => t.ifErr(err, 'PeerB has stopped')))
})
})

View File

@ -0,0 +1,54 @@
'use strict'
const test = require('tape')
const libp2p = require('libp2p')
const TCP = require('libp2p-tcp')
const PeerInfo = require('peer-info')
const waterfall = require('async/waterfall')
const pull = require('pull-stream')
const PeerA = require('libp2p-interop/peer-a.json')
const PeerB = require('libp2p-interop/peer-b.json')
class MyBundle extends libp2p {
constructor (peerInfo) {
const modules = {
transport: [new TCP()]
}
super(modules, peerInfo)
}
}
test('story 1 - peerA', (t) => {
t.plan(6)
let node
waterfall([
(cb) => PeerInfo.create(PeerA, cb),
(peerInfo, cb) => {
peerInfo.multiaddrs.add('/ip4/127.0.0.1/tcp/10000')
node = new MyBundle(peerInfo)
node.start(cb)
}
], (err) => {
t.ifErr(err, 'created Node')
t.ok(node.isStarted(), 'PeerA is running')
const PeerBAddr = `/ip4/127.0.0.1/tcp/10001/ipfs/${PeerB.id}`
node.dial(PeerBAddr, '/echo/1.0.0', (err, conn) => {
t.ifErr(err, 'dial successful')
const data = Buffer.from('Heey')
pull(
pull.values([data]),
conn,
pull.collect((err, values) => {
t.ifErr(err, 'Received echo back')
t.deepEqual(values[0], data)
node.stop((err) => t.ifErr(err, 'PeerA has stopped'))
})
)
})
})
})

View File

@ -0,0 +1,49 @@
'use strict'
const test = require('tape')
const libp2p = require('libp2p')
const TCP = require('libp2p-tcp')
const PeerInfo = require('peer-info')
const waterfall = require('async/waterfall')
const pull = require('pull-stream')
const PeerB = require('libp2p-interop/peer-b.json')
class MyBundle extends libp2p {
constructor (peerInfo) {
const modules = {
transport: [new TCP()]
}
super(modules, peerInfo)
}
}
test('story 1 - peerB', (t) => {
t.plan(5)
let node
waterfall([
(cb) => PeerInfo.create(PeerB, cb),
(peerInfo, cb) => {
peerInfo.multiaddrs.add('/ip4/127.0.0.1/tcp/10001')
node = new MyBundle(peerInfo)
node.start(cb)
}
], (err) => {
t.ifErr(err)
t.ok(node.isStarted(), 'PeerB is running')
node.handle('/echo/1.0.0', (protocol, conn) => {
pull(
conn,
conn,
pull.onEnd((err) => {
t.ifErr(err)
t.pass('Received End of Connection')
node.stop((err) => {
t.ifErr(err, 'PeerB has stopped')
})
})
)
})
})
})

View File

@ -0,0 +1,54 @@
'use strict'
const test = require('tape')
const libp2p = require('libp2p')
const WebSockets = require('libp2p-websockets')
const PeerInfo = require('peer-info')
const waterfall = require('async/waterfall')
const pull = require('pull-stream')
const PeerA = require('libp2p-interop/peer-a.json')
const PeerB = require('libp2p-interop/peer-b.json')
class MyBundle extends libp2p {
constructor (peerInfo) {
const modules = {
transport: [new WebSockets()]
}
super(modules, peerInfo)
}
}
test('story 2 - peerA', (t) => {
t.plan(6)
let node
waterfall([
(cb) => PeerInfo.create(PeerA, cb),
(peerInfo, cb) => {
peerInfo.multiaddrs.add('/ip4/127.0.0.1/tcp/10000/ws')
node = new MyBundle(peerInfo)
node.start(cb)
}
], (err) => {
t.ifErr(err, 'created Node')
t.ok(node.isStarted(), 'PeerA is running')
const PeerBAddr = `/ip4/127.0.0.1/tcp/10001/ws/ipfs/${PeerB.id}`
node.dial(PeerBAddr, '/echo/1.0.0', (err, conn) => {
t.ifErr(err, 'dial successful')
const data = Buffer.from('Heey')
pull(
pull.values([data]),
conn,
pull.collect((err, values) => {
t.ifErr(err, 'Received echo back')
t.deepEqual(values[0], data)
node.stop((err) => t.ifErr(err, 'PeerA has stopped'))
})
)
})
})
})

View File

@ -0,0 +1,49 @@
'use strict'
const test = require('tape')
const libp2p = require('libp2p')
const WebSockets = require('libp2p-websockets')
const PeerInfo = require('peer-info')
const waterfall = require('async/waterfall')
const pull = require('pull-stream')
const PeerB = require('libp2p-interop/peer-b.json')
class MyBundle extends libp2p {
constructor (peerInfo) {
const modules = {
transport: [new WebSockets()]
}
super(modules, peerInfo)
}
}
test('story 2 - peerB', (t) => {
t.plan(5)
let node
waterfall([
(cb) => PeerInfo.create(PeerB, cb),
(peerInfo, cb) => {
peerInfo.multiaddrs.add('/ip4/127.0.0.1/tcp/10001/ws')
node = new MyBundle(peerInfo)
node.start(cb)
}
], (err) => {
t.ifErr(err)
t.ok(node.isStarted(), 'PeerB is running')
node.handle('/echo/1.0.0', (protocol, conn) => {
pull(
conn,
pull.through(v => v, err => {
t.ifErr(err)
t.pass('Received End of Connection')
node.stop((err) => {
t.ifErr(err, 'PeerB has stopped')
})
}),
conn
)
})
})
})

View File

@ -0,0 +1,42 @@
'use strict'
const test = require('tape')
const libp2p = require('libp2p')
const TCP = require('libp2p-tcp')
const PeerInfo = require('peer-info')
const waterfall = require('async/waterfall')
const PeerA = require('libp2p-interop/peer-a.json')
const PeerB = require('libp2p-interop/peer-b.json')
class MyBundle extends libp2p {
constructor (peerInfo) {
const modules = {
transport: [new TCP()]
}
super(modules, peerInfo)
}
}
test('story 3 - peerA', (t) => {
t.plan(4)
let node
waterfall([
(cb) => PeerInfo.create(PeerA, cb),
(peerInfo, cb) => {
peerInfo.multiaddrs.add('/ip4/127.0.0.1/tcp/10000')
node = new MyBundle(peerInfo)
node.start(cb)
}
], (err) => {
t.ifErr(err, 'created Node')
t.ok(node.isStarted(), 'PeerA is running')
const PeerBAddr = `/ip4/127.0.0.1/tcp/10001/ws/ipfs/${PeerB.id}`
setTimeout(() => node.dial(PeerBAddr, '/echo/1.0.0', (err, conn) => {
t.ok(err, 'dial failed')
node.stop((err) => t.ifErr(err, 'PeerA has stopped'))
}), 1000)
})
})

View File

@ -0,0 +1,42 @@
'use strict'
const test = require('tape')
const libp2p = require('libp2p')
const WebSockets = require('libp2p-websockets')
const PeerInfo = require('peer-info')
const waterfall = require('async/waterfall')
const PeerA = require('libp2p-interop/peer-a.json')
const PeerB = require('libp2p-interop/peer-b.json')
class MyBundle extends libp2p {
constructor (peerInfo) {
const modules = {
transport: [new WebSockets()]
}
super(modules, peerInfo)
}
}
test('story 3 - peerB', (t) => {
t.plan(4)
let node
waterfall([
(cb) => PeerInfo.create(PeerB, cb),
(peerInfo, cb) => {
peerInfo.multiaddrs.add('/ip4/127.0.0.1/tcp/10000/ws')
node = new MyBundle(peerInfo)
node.start(cb)
}
], (err) => {
t.ifErr(err, 'created Node')
t.ok(node.isStarted(), 'PeerA is running')
const PeerAAddr = `/ip4/127.0.0.1/tcp/10000/ws/ipfs/${PeerA.id}`
setTimeout(() => node.dial(PeerAAddr, '/echo/1.0.0', (err, conn) => {
t.ok(err, 'dial failed')
node.stop((err) => t.ifErr(err, 'PeerA has stopped'))
}), 1000)
})
})

20
src/content-routing.js Normal file
View File

@ -0,0 +1,20 @@
'use strict'
module.exports = (node) => {
return {
findProviders: (key, timeout, callback) => {
if (!node._dht) {
return callback(new Error('DHT is not available'))
}
node._dht.findProviders(key, timeout, callback)
},
provide: (key, callback) => {
if (!node._dht) {
return callback(new Error('DHT is not available'))
}
node._dht.provide(key, callback)
}
}
}

27
src/dht.js Normal file
View File

@ -0,0 +1,27 @@
'use strict'
module.exports = (node) => {
return {
put: (key, value, callback) => {
if (!node._dht) {
return callback(new Error('DHT is not available'))
}
node._dht.put(key, value, callback)
},
get: (key, callback) => {
if (!node._dht) {
return callback(new Error('DHT is not available'))
}
node._dht.get(key, callback)
},
getMany (key, nVals, callback) {
if (!node._dht) {
return callback(new Error('DHT is not available'))
}
node._dht.getMany(key, nVals, callback)
}
}
}

48
src/get-peer-info.js Normal file
View File

@ -0,0 +1,48 @@
'use strict'
const PeerId = require('peer-id')
const PeerInfo = require('peer-info')
const multiaddr = require('multiaddr')
module.exports = (node) => {
/*
* Helper method to check the data type of peer and convert it to PeerInfo
*/
return function (peer, callback) {
let p
// PeerInfo
if (PeerInfo.isPeerInfo(peer)) {
p = peer
// Multiaddr instance or Multiaddr String
} else if (multiaddr.isMultiaddr(peer) || typeof peer === 'string') {
if (typeof peer === 'string') {
peer = multiaddr(peer)
}
const peerIdB58Str = peer.getPeerId()
if (!peerIdB58Str) {
throw new Error(`peer multiaddr instance or string must include peerId`)
}
try {
p = node.peerBook.get(peerIdB58Str)
} catch (err) {
p = new PeerInfo(PeerId.createFromB58String(peerIdB58Str))
}
p.multiaddrs.add(peer)
// PeerId
} else if (PeerId.isPeerId(peer)) {
const peerIdB58Str = peer.toB58String()
try {
p = node.peerBook.get(peerIdB58Str)
} catch (err) {
return node.peerRouting.findPeer(peer, callback)
}
} else {
return setImmediate(() => callback(new Error('peer type not recognized')))
}
setImmediate(() => callback(null, p))
}
}

View File

@ -7,12 +7,14 @@ const setImmediate = require('async/setImmediate')
const each = require('async/each')
const series = require('async/series')
const Ping = require('libp2p-ping')
const Swarm = require('libp2p-swarm')
const PeerId = require('peer-id')
const PeerInfo = require('peer-info')
const PeerBook = require('peer-book')
const multiaddr = require('multiaddr')
const Switch = require('libp2p-switch')
const Ping = require('libp2p-ping')
const peerRouting = require('./peer-routing')
const contentRouting = require('./content-routing')
const dht = require('./dht')
const getPeerInfo = require('./get-peer-info')
exports = module.exports
@ -31,28 +33,28 @@ class Node extends EventEmitter {
this._isStarted = false
this.swarm = new Swarm(this.peerInfo, this.peerBook)
this.switch = new Switch(this.peerInfo, this.peerBook)
// Attach stream multiplexers
if (this.modules.connection && this.modules.connection.muxer) {
let muxers = this.modules.connection.muxer
muxers = Array.isArray(muxers) ? muxers : [muxers]
muxers.forEach((muxer) => this.swarm.connection.addStreamMuxer(muxer))
muxers.forEach((muxer) => this.switch.connection.addStreamMuxer(muxer))
// If muxer exists, we can use Identify
this.swarm.connection.reuse()
this.switch.connection.reuse()
// If muxer exists, we can use Relay for listening/dialing
this.swarm.connection.enableCircuitRelay(_options.relay)
this.switch.connection.enableCircuitRelay(_options.relay)
// Received incommind dial and muxer upgrade happened,
// reuse this muxed connection
this.swarm.on('peer-mux-established', (peerInfo) => {
this.switch.on('peer-mux-established', (peerInfo) => {
this.emit('peer:connect', peerInfo)
this.peerBook.put(peerInfo)
})
this.swarm.on('peer-mux-closed', (peerInfo) => {
this.switch.on('peer-mux-closed', (peerInfo) => {
this.emit('peer:disconnect', peerInfo)
})
}
@ -62,7 +64,7 @@ class Node extends EventEmitter {
let cryptos = this.modules.connection.crypto
cryptos = Array.isArray(cryptos) ? cryptos : [cryptos]
cryptos.forEach((crypto) => {
this.swarm.connection.crypto(crypto.tag, crypto.encrypt)
this.switch.connection.crypto(crypto.tag, crypto.encrypt)
})
}
@ -76,67 +78,22 @@ class Node extends EventEmitter {
})
}
// Mount default protocols
Ping.mount(this.swarm)
// dht provided components (peerRouting, contentRouting, dht)
if (_modules.DHT) {
this._dht = new this.modules.DHT(this.swarm, {
this._dht = new this.modules.DHT(this.switch, {
kBucketSize: 20,
datastoer: _options.DHT && _options.DHT.datastore
datastore: _options.DHT && _options.DHT.datastore
})
}
this.peerRouting = {
findPeer: (id, callback) => {
if (!this._dht) {
return callback(new Error('DHT is not available'))
}
this.peerRouting = peerRouting(this)
this.contentRouting = contentRouting(this)
this.dht = dht(this)
this._dht.findPeer(id, callback)
}
}
this._getPeerInfo = getPeerInfo(this)
this.contentRouting = {
findProviders: (key, timeout, callback) => {
if (!this._dht) {
return callback(new Error('DHT is not available'))
}
this._dht.findProviders(key, timeout, callback)
},
provide: (key, callback) => {
if (!this._dht) {
return callback(new Error('DHT is not available'))
}
this._dht.provide(key, callback)
}
}
this.dht = {
put: (key, value, callback) => {
if (!this._dht) {
return callback(new Error('DHT is not available'))
}
this._dht.put(key, value, callback)
},
get: (key, callback) => {
if (!this._dht) {
return callback(new Error('DHT is not available'))
}
this._dht.get(key, callback)
},
getMany (key, nVals, callback) {
if (!this._dht) {
return callback(new Error('DHT is not available'))
}
this._dht.getMany(key, nVals, callback)
}
}
// Mount default protocols
Ping.mount(this.switch)
}
/*
@ -167,7 +124,7 @@ class Node extends EventEmitter {
const multiaddrs = this.peerInfo.multiaddrs.toArray()
transports.forEach((transport) => {
if (transport.filter(multiaddrs).length > 0) {
this.swarm.transport.add(
this.switch.transport.add(
transport.tag || transport.constructor.name, transport)
} else if (transport.constructor &&
transport.constructor.name === 'WebSockets') {
@ -178,11 +135,11 @@ class Node extends EventEmitter {
})
series([
(cb) => this.swarm.listen(cb),
(cb) => this.switch.start(cb),
(cb) => {
if (ws) {
// always add dialing on websockets
this.swarm.transport.add(ws.tag || ws.constructor.name, ws)
this.switch.transport.add(ws.tag || ws.constructor.name, ws)
}
// all transports need to be setup before discover starts
@ -224,8 +181,6 @@ class Node extends EventEmitter {
* Stop the libp2p node by closing its listeners and open connections
*/
stop (callback) {
this._isStarted = false
if (this.modules.discovery) {
this.modules.discovery.forEach((discovery) => {
setImmediate(() => discovery.stop(() => {}))
@ -239,30 +194,37 @@ class Node extends EventEmitter {
}
cb()
},
(cb) => this.swarm.close(cb),
(cb) => this.switch.stop(cb),
(cb) => {
this.emit('stop')
cb()
}
], callback)
], (err) => {
this._isStarted = false
callback(err)
})
}
isStarted () {
return this._isStarted
}
ping (peer, callback) {
dial (peer, callback) {
assert(this.isStarted(), NOT_STARTED_ERROR_MESSAGE)
this._getPeerInfo(peer, (err, peerInfo) => {
if (err) {
return callback(err)
}
callback(null, new Ping(this.swarm, peerInfo))
this._getPeerInfo(peer, (err, peerInfo) => {
if (err) { return callback(err) }
this.switch.dial(peerInfo, (err) => {
if (err) { return callback(err) }
this.peerBook.put(peerInfo)
callback()
})
})
}
dial (peer, protocol, callback) {
dialProtocol (peer, protocol, callback) {
assert(this.isStarted(), NOT_STARTED_ERROR_MESSAGE)
if (typeof protocol === 'function') {
@ -271,14 +233,10 @@ class Node extends EventEmitter {
}
this._getPeerInfo(peer, (err, peerInfo) => {
if (err) {
return callback(err)
}
if (err) { return callback(err) }
this.swarm.dial(peerInfo, protocol, (err, conn) => {
if (err) {
return callback(err)
}
this.switch.dial(peerInfo, protocol, (err, conn) => {
if (err) { return callback(err) }
this.peerBook.put(peerInfo)
callback(null, conn)
})
@ -289,52 +247,27 @@ class Node extends EventEmitter {
assert(this.isStarted(), NOT_STARTED_ERROR_MESSAGE)
this._getPeerInfo(peer, (err, peerInfo) => {
if (err) {
return callback(err)
}
if (err) { return callback(err) }
this.swarm.hangUp(peerInfo, callback)
this.switch.hangUp(peerInfo, callback)
})
}
ping (peer, callback) {
assert(this.isStarted(), NOT_STARTED_ERROR_MESSAGE)
this._getPeerInfo(peer, (err, peerInfo) => {
if (err) { return callback(err) }
callback(null, new Ping(this.switch, peerInfo))
})
}
handle (protocol, handlerFunc, matchFunc) {
this.swarm.handle(protocol, handlerFunc, matchFunc)
this.switch.handle(protocol, handlerFunc, matchFunc)
}
unhandle (protocol) {
this.swarm.unhandle(protocol)
}
/*
* Helper method to check the data type of peer and convert it to PeerInfo
*/
_getPeerInfo (peer, callback) {
let p
// PeerInfo
if (PeerInfo.isPeerInfo(peer)) {
p = peer
// Multiaddr instance (not string)
} else if (multiaddr.isMultiaddr(peer)) {
const peerIdB58Str = peer.getPeerId()
try {
p = this.peerBook.get(peerIdB58Str)
} catch (err) {
p = new PeerInfo(PeerId.createFromB58String(peerIdB58Str))
}
p.multiaddrs.add(peer)
// PeerId
} else if (PeerId.isPeerId(peer)) {
const peerIdB58Str = peer.toB58String()
try {
p = this.peerBook.get(peerIdB58Str)
} catch (err) {
return this.peerRouting.findPeer(peer, callback)
}
} else {
return setImmediate(() => callback(new Error('peer type not recognized')))
}
setImmediate(() => callback(null, p))
this.switch.unhandle(protocol)
}
}

13
src/peer-routing.js Normal file
View File

@ -0,0 +1,13 @@
'use strict'
module.exports = (node) => {
return {
findPeer: (id, callback) => {
if (!node._dht) {
return callback(new Error('DHT is not available'))
}
node._dht.findPeer(id, callback)
}
}
}

View File

@ -1,17 +1,16 @@
/* 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 tryEcho = require('./utils/try-echo')
const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const sinon = require('sinon')
@ -39,7 +38,7 @@ describe('circuit relay', function () {
node.start((err) => {
expect(err).to.not.exist()
handlerSpies.push(sinon.spy(node.swarm.transports[Circuit.tag].listeners[0].hopHandler, 'handle'))
handlerSpies.push(sinon.spy(node.switch.transports[Circuit.tag].listeners[0].hopHandler, 'handle'))
cb(node)
})
})
@ -153,25 +152,16 @@ describe('circuit relay', function () {
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) => {
it('dial from WS1 to TCP1 over any R', (done) => {
nodeWS1.dialProtocol(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()
})
)
tryEcho(conn, done)
})
})
it('should not dial - no R from WS2 to TCP1', (done) => {
nodeWS2.dial(nodeTCP2.peerInfo, '/echo/1.0.0', (err, conn) => {
it('fail to dial - no R from WS2 to TCP1', (done) => {
nodeWS2.dialProtocol(nodeTCP2.peerInfo, '/echo/1.0.0', (err, conn) => {
expect(err).to.exist()
expect(conn).to.not.exist()
done()
@ -182,43 +172,29 @@ describe('circuit relay', function () {
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) => {
it('dial from WS1 to TCP1 over R1', (done) => {
nodeWS1.dialProtocol(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()
})
)
tryEcho(conn, () => {
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) => {
it('dial from WS1 to TCP2 over R2', (done) => {
nodeWS1.dialProtocol(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()
})
)
tryEcho(conn, () => {
const addr = multiaddr(handlerSpies[1].args[2][0].dstPeer.addrs[0]).toString()
expect(addr).to.equal(`/ipfs/${nodeTCP2.peerInfo.id.toB58String()}`)
done()
})
})
})
})

View File

@ -6,24 +6,15 @@ 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')
const tryEcho = require('./utils/try-echo')
const createNode = utils.createNode
const echo = utils.echo
function test (nodeA, nodeB, callback) {
nodeA.dial(nodeB.peerInfo, '/echo/1.0.0', (err, conn) => {
nodeA.dialProtocol(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')])
callback()
})
)
tryEcho(conn, callback)
})
}
@ -136,7 +127,7 @@ describe('stream muxing', () => {
})
it('spdy + multiplex switched order', function (done) {
this.timeout(5000)
this.timeout(5 * 1000)
let nodeA
let nodeB
@ -170,7 +161,7 @@ describe('stream muxing', () => {
})
it('one without the other fails to establish a muxedConn', function (done) {
this.timeout(5000)
this.timeout(5 * 1000)
let nodeA
let nodeB
@ -200,12 +191,12 @@ describe('stream muxing', () => {
(cb) => setup(cb),
(cb) => {
// it will just 'warm up a conn'
expect(Object.keys(nodeA.swarm.muxers)).to.have.length(1)
expect(Object.keys(nodeB.swarm.muxers)).to.have.length(1)
expect(Object.keys(nodeA.switch.muxers)).to.have.length(1)
expect(Object.keys(nodeB.switch.muxers)).to.have.length(1)
nodeA.dial(nodeB.peerInfo, (err) => {
expect(err).to.not.exist()
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(0)
expect(Object.keys(nodeA.switch.muxedConns)).to.have.length(0)
cb()
})
},

View File

@ -12,6 +12,7 @@ const parallel = require('async/parallel')
const goodbye = require('pull-goodbye')
const serializer = require('pull-serializer')
const w = require('webrtcsupport')
const tryEcho = require('./utils/try-echo')
const Node = require('./utils/bundle.browser')
const rawPeer = require('./fixtures/test-peer.json')
@ -63,7 +64,7 @@ describe('transports', () => {
// General connectivity tests
it('libp2p.dial using Multiaddr nodeA to nodeB', (done) => {
it('.dial using Multiaddr', (done) => {
nodeA.dial(peerB.multiaddrs.toArray()[0], (err) => {
expect(err).to.not.exist()
@ -77,26 +78,18 @@ describe('transports', () => {
})
})
it('libp2p.dial using Multiaddr on Protocol nodeA to nodeB', (done) => {
nodeA.dial(peerB.multiaddrs.toArray()[0], '/echo/1.0.0', (err, conn) => {
it('.dialProtocol using Multiaddr', (done) => {
nodeA.dialProtocol(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()
})
)
tryEcho(conn, done)
})
})
it('libp2p.hangUp using Multiaddr nodeA to nodeB', (done) => {
it('.hangUp using Multiaddr', (done) => {
nodeA.hangUp(peerB.multiaddrs.toArray()[0], (err) => {
expect(err).to.not.exist()
@ -105,13 +98,13 @@ describe('transports', () => {
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)
expect(Object.keys(nodeA.switch.muxedConns)).to.have.length(0)
done()
}
})
})
it('libp2p.dial using PeerInfo nodeA to nodeB', (done) => {
it('.dial using PeerInfo', (done) => {
nodeA.dial(peerB, (err) => {
expect(err).to.not.exist()
@ -125,26 +118,18 @@ describe('transports', () => {
})
})
it('libp2p.dial using PeerInfo on Protocol nodeA to nodeB', (done) => {
nodeA.dial(peerB, '/echo/1.0.0', (err, conn) => {
it('.dialProtocol using PeerInfo', (done) => {
nodeA.dialProtocol(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()
})
)
tryEcho(conn, done)
})
})
it('libp2p.hangUp using PeerInfo nodeA to nodeB', (done) => {
it('.hangUp using PeerInfo', (done) => {
nodeA.hangUp(peerB, (err) => {
expect(err).to.not.exist()
setTimeout(check, 500)
@ -153,7 +138,7 @@ describe('transports', () => {
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)
expect(Object.keys(nodeA.switch.muxedConns)).to.have.length(0)
done()
}
})
@ -161,7 +146,7 @@ describe('transports', () => {
describe('stress', () => {
it('one big write', (done) => {
nodeA.dial(peerB, '/echo/1.0.0', (err, conn) => {
nodeA.dialProtocol(peerB, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
const rawMessage = Buffer.alloc(100000)
rawMessage.fill('a')
@ -180,7 +165,7 @@ describe('transports', () => {
})
it('many writes', (done) => {
nodeA.dial(peerB, '/echo/1.0.0', (err, conn) => {
nodeA.dialProtocol(peerB, '/echo/1.0.0', (err, conn) => {
expect(err).to.not.exist()
const s = serializer(goodbye({
@ -235,39 +220,30 @@ describe('transports', () => {
done()
})
it('listen on the two libp2p nodes', (done) => {
it('start two libp2p nodes', (done) => {
parallel([
(cb) => node1.start(cb),
(cb) => node2.start(cb)
], done)
})
it('handle a protocol on the first node', () => {
it('.handle echo on 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) => {
it('.dialProtocol from the second node to the first node', (done) => {
node1.dialProtocol(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()
})
)
tryEcho(conn, done)
}
})
})
@ -280,7 +256,7 @@ describe('transports', () => {
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)
expect(Object.keys(node1.switch.muxedConns)).to.have.length(0)
done()
}
})
@ -291,8 +267,8 @@ describe('transports', () => {
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)
expect(Object.keys(node1.switch.muxedConns).length).to.equal(1)
expect(Object.keys(node2.switch.muxedConns).length).to.equal(1)
done()
}
}
@ -355,28 +331,19 @@ describe('transports', () => {
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) => {
it('.dialProtocol from the second node to the first node', (done) => {
node1.dialProtocol(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()
})
)
tryEcho(conn, done)
}
})
})
@ -389,7 +356,7 @@ describe('transports', () => {
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)
expect(Object.keys(node1.switch.muxedConns)).to.have.length(0)
done()
}
})
@ -400,8 +367,8 @@ describe('transports', () => {
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)
expect(Object.keys(node1.switch.muxedConns).length).to.equal(1)
expect(Object.keys(node2.switch.muxedConns).length).to.equal(1)
done()
}
}

View File

@ -6,13 +6,13 @@ 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 tryEcho = require('./utils/try-echo')
const createNode = utils.createNode
const echo = utils.echo
@ -73,18 +73,10 @@ describe('transports', () => {
})
it('nodeA.dial nodeB using PeerInfo', (done) => {
nodeA.dial(nodeB.peerInfo, '/echo/1.0.0', (err, conn) => {
nodeA.dialProtocol(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()
})
)
tryEcho(conn, done)
})
})
@ -98,14 +90,14 @@ describe('transports', () => {
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(0)
expect(Object.keys(nodeA.switch.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)
expect(Object.keys(nodeB.switch.muxedConns)).to.have.length(0)
cb()
}
], done)
@ -113,8 +105,8 @@ describe('transports', () => {
})
})
it('nodeA.dial nodeB using multiaddr', (done) => {
nodeA.dial(nodeB.peerInfo.multiaddrs.toArray()[0], '/echo/1.0.0', (err, conn) => {
it('nodeA.dialProtocol nodeB using multiaddr', (done) => {
nodeA.dialProtocol(nodeB.peerInfo.multiaddrs.toArray()[0], '/echo/1.0.0', (err, conn) => {
// Some time for Identify to finish
setTimeout(check, 500)
@ -125,27 +117,17 @@ describe('transports', () => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(1)
expect(Object.keys(nodeA.switch.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)
expect(Object.keys(nodeA.switch.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()
})
)
})
], () => tryEcho(conn, done))
}
})
})
@ -161,14 +143,14 @@ describe('transports', () => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(0)
expect(Object.keys(nodeA.switch.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)
expect(Object.keys(nodeB.switch.muxedConns)).to.have.length(0)
cb()
}
], done)
@ -176,8 +158,8 @@ describe('transports', () => {
})
})
it('nodeA.dial nodeB using PeerId', (done) => {
nodeA.dial(nodeB.peerInfo.id, '/echo/1.0.0', (err, conn) => {
it('nodeA.dialProtocol nodeB using PeerId', (done) => {
nodeA.dialProtocol(nodeB.peerInfo.id, '/echo/1.0.0', (err, conn) => {
// Some time for Identify to finish
setTimeout(check, 500)
@ -187,26 +169,16 @@ describe('transports', () => {
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(1)
expect(Object.keys(nodeA.switch.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)
expect(Object.keys(nodeA.switch.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()
})
)
})
], () => tryEcho(conn, done))
}
})
})
@ -221,13 +193,13 @@ describe('transports', () => {
(cb) => {
const peers = nodeA.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeA.swarm.muxedConns)).to.have.length(0)
expect(Object.keys(nodeA.switch.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)
expect(Object.keys(nodeB.switch.muxedConns)).to.have.length(0)
cb()
}
], done)
@ -291,13 +263,13 @@ describe('transports', () => {
(cb) => {
const peers = nodeTCP.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeTCP.swarm.muxedConns)).to.have.length(1)
expect(Object.keys(nodeTCP.switch.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)
expect(Object.keys(nodeTCPnWS.switch.muxedConns)).to.have.length(1)
cb()
}
], done)
@ -315,14 +287,14 @@ describe('transports', () => {
(cb) => {
const peers = nodeTCP.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(1)
expect(Object.keys(nodeTCP.swarm.muxedConns)).to.have.length(0)
expect(Object.keys(nodeTCP.switch.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)
expect(Object.keys(nodeTCPnWS.switch.muxedConns)).to.have.length(0)
cb()
}
], done)
@ -342,13 +314,13 @@ describe('transports', () => {
(cb) => {
const peers = nodeTCPnWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(2)
expect(Object.keys(nodeTCPnWS.swarm.muxedConns)).to.have.length(1)
expect(Object.keys(nodeTCPnWS.switch.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)
expect(Object.keys(nodeWS.switch.muxedConns)).to.have.length(1)
cb()
}
], done)
@ -366,14 +338,14 @@ describe('transports', () => {
(cb) => {
const peers = nodeTCPnWS.peerBook.getAll()
expect(Object.keys(peers)).to.have.length(2)
expect(Object.keys(nodeTCPnWS.swarm.muxedConns)).to.have.length(0)
expect(Object.keys(nodeTCPnWS.switch.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)
expect(Object.keys(nodeWS.switch.muxedConns)).to.have.length(0)
cb()
}
], done)
@ -465,7 +437,9 @@ describe('transports', () => {
], done)
})
after((done) => {
after(function (done) {
this.timeout(10 * 1000)
parallel([
(cb) => nodeAll.stop(cb),
(cb) => nodeTCP.stop(cb),
@ -479,7 +453,7 @@ describe('transports', () => {
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)
expect(Object.keys(node.switch.muxedConns)).to.have.length(muxed)
})
callback()
}
@ -622,7 +596,7 @@ describe('transports', () => {
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)
expect(Object.keys(node.switch.muxedConns)).to.have.length(muxed)
})
done()
}

View File

@ -76,7 +76,7 @@ describe('Turbolence tests', () => {
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)
expect(Object.keys(nodeA.switch.muxedConns)).to.have.length(0)
done()
}
})

21
test/utils/try-echo.js Normal file
View File

@ -0,0 +1,21 @@
'use strict'
const pull = require('pull-stream')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
module.exports = (conn, callback) => {
const values = [Buffer.from('echo')]
pull(
pull.values(values),
conn,
pull.collect((err, _values) => {
expect(err).to.not.exist()
expect(_values).to.eql(values)
callback()
})
)
}