mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-07-10 14:21:33 +00:00
Compare commits
92 Commits
v0.27.3
...
refactor/a
Author | SHA1 | Date | |
---|---|---|---|
7e1a9d677b | |||
1ba1ca7714 | |||
691e9b7f7b | |||
751a22741f | |||
461faca1ca | |||
31d1b2369a | |||
83409deaa6 | |||
c44e6e33ed | |||
999d086278 | |||
122a114d96 | |||
21362b5cbe | |||
0840739a00 | |||
f182f5bcd9 | |||
a1717dac6a | |||
dec8dc450f | |||
0d4b2bd23d | |||
fdb48c8df5 | |||
506af15b6b | |||
9f0f08f586 | |||
6ca19c5ef4 | |||
24c3ce6f8d | |||
56a1825639 | |||
92ed56657c | |||
9900beb243 | |||
4a871bbf8b | |||
a39889c4ea | |||
9bbe93c772 | |||
cc65a4b06f | |||
9c884a72b0 | |||
3ee1e22242 | |||
45f47023d2 | |||
af96dcc499 | |||
f540112835 | |||
3d30cb18cd | |||
64cbf90e02 | |||
7fc1900343 | |||
ad15d4ed09 | |||
600f761009 | |||
a2f31d99d2 | |||
edaa67dfd0 | |||
9b10e09cc0 | |||
8c6ad79630 | |||
1838a641d9 | |||
3cadeb39cb | |||
43440aa8a6 | |||
7c3371bf17 | |||
43b98e64b6 | |||
962081f448 | |||
754fbc2d0b | |||
0a8f9f3238 | |||
3b52236dee | |||
c7dcfe5e48 | |||
3b06283ad8 | |||
74bfe6bea5 | |||
53ce404260 | |||
43a3b85f1a | |||
e8bf12b68a | |||
7d1cb5423f | |||
c4be5f4aaf | |||
a37c5c0144 | |||
24c603741f | |||
ea62c52701 | |||
f9fe44f6b7 | |||
d5405dbb08 | |||
571fd3b7d1 | |||
cba2c6d8b2 | |||
f8540fa3ed | |||
0cacfe29a5 | |||
c4bc00be9c | |||
f3eb1f1201 | |||
dbb9e57311 | |||
11ed6bd14c | |||
fc22c36ba7 | |||
b518391a47 | |||
997ee166b0 | |||
acbbc0f84e | |||
995640ee2f | |||
b316cdd19b | |||
1ea945ad24 | |||
c37703dc17 | |||
86b275a0d3 | |||
3c79d33db9 | |||
34d57f8989 | |||
ced2dbf318 | |||
44d47087d1 | |||
797d8f0cf1 | |||
f3e276eb79 | |||
138bb0bbae | |||
af364b070b | |||
10c8553c58 | |||
a7d5e67e06 | |||
4f8043d259 |
@ -39,12 +39,5 @@ jobs:
|
||||
script:
|
||||
- npx aegir test -t browser -t webworker -- --browsers FirefoxHeadless
|
||||
|
||||
- stage: test
|
||||
name: interop
|
||||
script:
|
||||
- cd node_modules/interop-libp2p
|
||||
- npm install
|
||||
- LIBP2P_JS=${TRAVIS_BUILD_DIR}/src/index.js npx aegir test -t node --bail
|
||||
|
||||
notifications:
|
||||
email: false
|
68
CHANGELOG.md
68
CHANGELOG.md
@ -1,71 +1,3 @@
|
||||
<a name="0.27.3"></a>
|
||||
## [0.27.3](https://github.com/libp2p/js-libp2p/compare/v0.27.2...v0.27.3) (2020-02-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* dont allow multiaddr dials without a peer id ([#558](https://github.com/libp2p/js-libp2p/issues/558)) ([a317a8b](https://github.com/libp2p/js-libp2p/commit/a317a8b))
|
||||
|
||||
|
||||
|
||||
<a name="0.27.2"></a>
|
||||
## [0.27.2](https://github.com/libp2p/js-libp2p/compare/v0.27.1...v0.27.2) (2020-02-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* ensure identify streams are closed ([#551](https://github.com/libp2p/js-libp2p/issues/551)) ([f662fdc](https://github.com/libp2p/js-libp2p/commit/f662fdc))
|
||||
|
||||
|
||||
|
||||
<a name="0.27.1"></a>
|
||||
## [0.27.1](https://github.com/libp2p/js-libp2p/compare/v0.27.0...v0.27.1) (2020-02-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* stop stream after first pong received ([#545](https://github.com/libp2p/js-libp2p/issues/545)) ([be8fc9d](https://github.com/libp2p/js-libp2p/commit/be8fc9d))
|
||||
|
||||
|
||||
|
||||
<a name="0.27.0"></a>
|
||||
# [0.27.0](https://github.com/libp2p/js-libp2p/compare/v0.26.2...v0.27.0) (2020-01-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* clean up peer discovery flow ([#494](https://github.com/libp2p/js-libp2p/issues/494)) ([12fc069](https://github.com/libp2p/js-libp2p/commit/12fc069))
|
||||
* clean up pending dials abort per feedback ([633b0c2](https://github.com/libp2p/js-libp2p/commit/633b0c2))
|
||||
* conn mngr min/max connection values ([#528](https://github.com/libp2p/js-libp2p/issues/528)) ([ba4681b](https://github.com/libp2p/js-libp2p/commit/ba4681b))
|
||||
* correct release readme ([ce8e60b](https://github.com/libp2p/js-libp2p/commit/ce8e60b))
|
||||
* examples readme typos ([#481](https://github.com/libp2p/js-libp2p/issues/481)) ([35ac02d](https://github.com/libp2p/js-libp2p/commit/35ac02d))
|
||||
* make dialer configurable ([#521](https://github.com/libp2p/js-libp2p/issues/521)) ([4ca481b](https://github.com/libp2p/js-libp2p/commit/4ca481b))
|
||||
* performance bottleneck in stat.js ([#463](https://github.com/libp2p/js-libp2p/issues/463)) ([93a1e42](https://github.com/libp2p/js-libp2p/commit/93a1e42))
|
||||
* registrar should filter the disconnected conn ([#532](https://github.com/libp2p/js-libp2p/issues/532)) ([bb2e56e](https://github.com/libp2p/js-libp2p/commit/bb2e56e))
|
||||
* release tokens as soon as they are available ([2570a1b](https://github.com/libp2p/js-libp2p/commit/2570a1b))
|
||||
* replace peerInfo addresses with listen addresses ([#485](https://github.com/libp2p/js-libp2p/issues/485)) ([1999606](https://github.com/libp2p/js-libp2p/commit/1999606))
|
||||
* stop discoveries ([#530](https://github.com/libp2p/js-libp2p/issues/530)) ([4222c49](https://github.com/libp2p/js-libp2p/commit/4222c49))
|
||||
* token release logic ([90ecc57](https://github.com/libp2p/js-libp2p/commit/90ecc57))
|
||||
* upgrader should not need muxers ([#517](https://github.com/libp2p/js-libp2p/issues/517)) ([5d7ee50](https://github.com/libp2p/js-libp2p/commit/5d7ee50))
|
||||
* use toB58String everywhere to be consistent ([#537](https://github.com/libp2p/js-libp2p/issues/537)) ([c1038be](https://github.com/libp2p/js-libp2p/commit/c1038be))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* abort all pending dials on stop ([ba02764](https://github.com/libp2p/js-libp2p/commit/ba02764))
|
||||
* add early token recycling in ([a5b54a7](https://github.com/libp2p/js-libp2p/commit/a5b54a7))
|
||||
* add libp2p.connections getter ([#522](https://github.com/libp2p/js-libp2p/issues/522)) ([6445fda](https://github.com/libp2p/js-libp2p/commit/6445fda))
|
||||
* add token based dialer ([e445a17](https://github.com/libp2p/js-libp2p/commit/e445a17))
|
||||
* allow transport options to be passed on creation ([#524](https://github.com/libp2p/js-libp2p/issues/524)) ([c339be1](https://github.com/libp2p/js-libp2p/commit/c339be1))
|
||||
* coalescing dial support ([#518](https://github.com/libp2p/js-libp2p/issues/518)) ([15f7c2a](https://github.com/libp2p/js-libp2p/commit/15f7c2a))
|
||||
* discovery modules ([#486](https://github.com/libp2p/js-libp2p/issues/486)) ([18a062e](https://github.com/libp2p/js-libp2p/commit/18a062e))
|
||||
* discovery modules from transports should be added ([#510](https://github.com/libp2p/js-libp2p/issues/510)) ([f1eb373](https://github.com/libp2p/js-libp2p/commit/f1eb373))
|
||||
* peer store ([#470](https://github.com/libp2p/js-libp2p/issues/470)) ([582094a](https://github.com/libp2p/js-libp2p/commit/582094a))
|
||||
* registrar ([#471](https://github.com/libp2p/js-libp2p/issues/471)) ([9d52b80](https://github.com/libp2p/js-libp2p/commit/9d52b80))
|
||||
* support peer-id instances in peer store operations ([#491](https://github.com/libp2p/js-libp2p/issues/491)) ([8da9fc9](https://github.com/libp2p/js-libp2p/commit/8da9fc9))
|
||||
|
||||
|
||||
|
||||
<a name="0.27.0-rc.0"></a>
|
||||
# [0.27.0-rc.0](https://github.com/libp2p/js-libp2p/compare/v0.27.0-pre.2...v0.27.0-rc.0) (2020-01-24)
|
||||
|
||||
|
@ -5,10 +5,10 @@
|
||||
<h3 align="center">The JavaScript implementation of the libp2p Networking Stack.</h3>
|
||||
|
||||
<p align="center">
|
||||
<a href="http://protocol.ai"><img src="https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square" /></a>
|
||||
<a href="http://ipn.io"><img src="https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square" /></a>
|
||||
<a href="http://libp2p.io/"><img src="https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square" /></a>
|
||||
<a href="http://webchat.freenode.net/?channels=%23libp2p"><img src="https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square" /></a>
|
||||
<a href="https://riot.im/app/#/room/#libp2p:matrix.org"><img src="https://img.shields.io/badge/matrix-%23libp2p%3Apermaweb.io-blue.svg?style=flat-square" /> </a>
|
||||
<a href="https://riot.permaweb.io/#/room/#libp2p:permaweb.io"><img src="https://img.shields.io/badge/matrix-%23libp2p%3Apermaweb.io-blue.svg?style=flat-square" /> </a>
|
||||
<a href="https://discord.gg/66KBrm2"><img src="https://img.shields.io/discord/475789330380488707?color=blueviolet&label=discord&style=flat-square" /></a>
|
||||
<a href="https://discuss.libp2p.io"><img src="https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg" /></a>
|
||||
</p>
|
||||
@ -30,9 +30,6 @@
|
||||
|
||||
We've come a long way, but this project is still in Alpha, lots of development is happening, API might change, beware of the Dragons 🐉..
|
||||
|
||||
The documentation in the master branch may contain changes from a pre-release.
|
||||
If you are looking for the documentation of the latest release, you can view the latest release on [**npm**](https://www.npmjs.com/package/libp2p), or select the tag in github that matches the version you are looking for.
|
||||
|
||||
**Want to get started?** Check our [examples folder](/examples).
|
||||
|
||||
[**`Weekly Core Dev Calls`**](https://github.com/ipfs/pm/issues/650)
|
||||
|
39
doc/API.md
39
doc/API.md
@ -51,7 +51,7 @@ Creates an instance of Libp2p.
|
||||
| [options.datastore] | `Object` | must implement [ipfs/interface-datastore](https://github.com/ipfs/interface-datastore) (in memory datastore will be used if not provided) |
|
||||
| [options.dialer] | `Object` | libp2p Dialer configuration
|
||||
| [options.metrics] | `Object` | libp2p Metrics configuration
|
||||
| [options.peerInfo] | [`PeerInfo`][peer-info] | peerInfo instance (it will be created if not provided) |
|
||||
| [options.peerInfo] | [PeerInfo](https://github.com/libp2p/js-peer-info) | peerInfo instance (it will be created if not provided) |
|
||||
|
||||
For Libp2p configurations and modules details read the [Configuration Document](./CONFIGURATION.md).
|
||||
|
||||
@ -73,7 +73,7 @@ const options = {}
|
||||
const libp2p = await Libp2p.create(options)
|
||||
```
|
||||
|
||||
Note: The [`PeerInfo`][peer-info] option is not required and will be generated if it is not provided.
|
||||
Note: The `PeerInfo` option is not required and will be generated if it is not provided.
|
||||
|
||||
<details><summary>Alternative</summary>
|
||||
As an alternative, it is possible to create a Libp2p instance with the constructor:
|
||||
@ -92,7 +92,7 @@ const libp2p = new Libp2p(options)
|
||||
|
||||
Required keys in the `options` object:
|
||||
|
||||
- `peerInfo`: instance of [`PeerInfo`][peer-info] that contains the [`PeerId`][peer-id], Keys and [multiaddrs][multiaddr] of the libp2p Node (optional when using `.create`).
|
||||
- `peerInfo`: instance of [PeerInfo][] that contains the [PeerId][], Keys and [multiaddrs][multiaddr] of the libp2p Node (optional when using `.create`).
|
||||
- `modules.transport`: An array that must include at least 1 compliant transport. See [modules that implement the transport interface](https://github.com/libp2p/js-interfaces/tree/master/src/transport#modules-that-implement-the-interface).
|
||||
|
||||
</details>
|
||||
@ -174,13 +174,15 @@ for (const [peerId, connections] of libp2p.connections) {
|
||||
|
||||
### dial
|
||||
|
||||
Dials to another peer in the network and establishes the connection.
|
||||
|
||||
`dial(peer, options)`
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| peer | [`PeerInfo`][peer-info]\|[`PeerId`][peer-id]\|[`Multiaddr`][multiaddr]\|`string` | The peer to dial. If a [`Multiaddr`][multiaddr] or its string is provided, it **must** include the peer id |
|
||||
| peer | [PeerInfo](https://github.com/libp2p/js-peer-info), [PeerId][peer-id], [multiaddr](https://github.com/multiformats/js-multiaddr), `string` | peer to dial |
|
||||
| [options] | `Object` | dial options |
|
||||
| [options.signal] | [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) | An `AbortSignal` instance obtained from an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) that can be used to abort the connection before it completes |
|
||||
|
||||
@ -215,7 +217,7 @@ Dials to another peer in the network and selects a protocol to communicate with
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| peer | [`PeerInfo`][peer-info]\|[`PeerId`][peer-id]\|[`Multiaddr`][multiaddr]\|`string` | The peer to dial. If a [`Multiaddr`][multiaddr] or its string is provided, it **must** include the peer id |
|
||||
| peer | [PeerInfo](https://github.com/libp2p/js-peer-info), [PeerId][peer-id], [multiaddr](https://github.com/multiformats/js-multiaddr), `string` | peer to dial |
|
||||
| protocols | `String|Array<String>` | A list of protocols (or single protocol) to negotiate with. Protocols are attempted in order until a match is made. (e.g '/ipfs/bitswap/1.1.0') |
|
||||
| [options] | `Object` | dial options |
|
||||
| [options.signal] | [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) | An `AbortSignal` instance obtained from an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) that can be used to abort the connection before it completes |
|
||||
@ -248,7 +250,7 @@ Attempts to gracefully close an open connection to the given peer. If the connec
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| peer | [`PeerInfo`][peer-info]\|[`PeerId`][peer-id]\|[`Multiaddr`][multiaddr]\|`string` | peer to hang up |
|
||||
| peer | [PeerInfo](https://github.com/libp2p/js-peer-info), [PeerId][peer-id], [multiaddr](https://github.com/multiformats/js-multiaddr), `string` | peer to hang up |
|
||||
|
||||
#### Returns
|
||||
|
||||
@ -319,7 +321,7 @@ Pings a given peer and get the operation's latency.
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| peer | [`PeerInfo`][peer-info]\|[`PeerId`][peer-id]\|[`Multiaddr`][multiaddr]\|`string` | peer to ping |
|
||||
| peer | `PeerInfo|PeerId|Multiaddr|string` | peer to ping |
|
||||
|
||||
#### Returns
|
||||
|
||||
@ -372,7 +374,7 @@ Once a content router succeeds, the iteration will stop. If the DHT is enabled,
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| cid | [`CID`][cid] | cid to find |
|
||||
| cid | [`CID`](https://github.com/multiformats/js-cid) | cid to find |
|
||||
| options | `Object` | operation options |
|
||||
| options.timeout | `number` | maximum time the query should run |
|
||||
| options.maxNumProviders | `number` | maximum number of providers to find |
|
||||
@ -381,7 +383,7 @@ Once a content router succeeds, the iteration will stop. If the DHT is enabled,
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `AsyncIterator<PeerInfo>` | Async iterator for [`PeerInfo`][peer-info] |
|
||||
| `AsyncIterator<PeerInfo>` | Async iterator for [`PeerInfo`](https://github.com/libp2p/js-peer-info) |
|
||||
|
||||
#### Example
|
||||
|
||||
@ -402,7 +404,7 @@ Iterates over all content routers in parallel, in order to notify it is a provid
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| cid | [`CID`][cid] | cid to provide |
|
||||
| cid | [`CID`](https://github.com/multiformats/js-cid) | cid to provide |
|
||||
|
||||
#### Returns
|
||||
|
||||
@ -647,7 +649,7 @@ Enables users to change the value of certain peers in a range of 0 to 1. Peers w
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| peerId | [`PeerId`][peer-id] | The peer to set the value for |
|
||||
| peerId | `PeerId` | The peer to set the value for |
|
||||
| value | `number` | The value of the peer from 0 to 1 |
|
||||
|
||||
#### Returns
|
||||
@ -675,7 +677,7 @@ const peerIdStrings = libp2p.metrics.peers
|
||||
|
||||
### metrics.peers
|
||||
|
||||
An array of [`PeerId`][peer-id] strings of each peer currently being tracked.
|
||||
An array of `PeerId` strings of each peer currently being tracked.
|
||||
|
||||
#### Example
|
||||
|
||||
@ -695,7 +697,7 @@ const protocols = libp2p.metrics.protocols
|
||||
|
||||
### metrics.forPeer
|
||||
|
||||
Returns the [`Stats`](#stats) object for a given [`PeerId`][peer-id] if it is being tracked.
|
||||
Returns the [`Stats`](#stats) object for a given `PeerId` if it is being tracked.
|
||||
|
||||
`libp2p.metrics.forPeer(peerId)`
|
||||
|
||||
@ -703,7 +705,7 @@ Returns the [`Stats`](#stats) object for a given [`PeerId`][peer-id] if it is be
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| peerId | [`PeerId`][peer-id] | The peer to get stats for |
|
||||
| peerId | `PeerId` | The peer to get stats for |
|
||||
|
||||
#### Returns
|
||||
|
||||
@ -760,7 +762,7 @@ Once you have a libp2p instance, you can listen to several events it emits, so t
|
||||
If `autoDial` option is `true`, applications should **not** attempt to connect to the peer
|
||||
unless they are performing a specific action. See [peer discovery and auto dial](./PEER_DISCOVERY.md) for more information.
|
||||
|
||||
- `peer`: instance of [`PeerInfo`][peer-info]
|
||||
- `peer`: instance of [PeerInfo][https://github.com/libp2p/js-peer-info]
|
||||
|
||||
#### A new connection to a peer has been opened
|
||||
|
||||
@ -768,7 +770,7 @@ This event will be triggered anytime a new Connection is established to another
|
||||
|
||||
`libp2p.on('peer:connect', (peer) => {})`
|
||||
|
||||
- `peer`: instance of [`PeerInfo`][peer-info]
|
||||
- `peer`: instance of [PeerInfo][https://github.com/libp2p/js-peer-info]
|
||||
|
||||
#### An existing connection to a peer has been closed
|
||||
|
||||
@ -776,7 +778,7 @@ This event will be triggered anytime we are disconnected from another peer, rega
|
||||
|
||||
`libp2p.on('peer:disconnect', (peer) => {})`
|
||||
|
||||
- `peer`: instance of [`PeerInfo`][peer-info]
|
||||
- `peer`: instance of [PeerInfo][https://github.com/libp2p/js-peer-info]
|
||||
|
||||
## Types
|
||||
|
||||
@ -798,8 +800,5 @@ This event will be triggered anytime we are disconnected from another peer, rega
|
||||
- `['300000']<MovingAverage>`: The [MovingAverage](https://www.npmjs.com/package/moving-averages) at a 5 minute interval.
|
||||
- `['900000']<MovingAverage>`: The [MovingAverage](https://www.npmjs.com/package/moving-averages) at a 15 minute interval.
|
||||
|
||||
[cid]: https://github.com/multiformats/js-cid
|
||||
[connection]: https://github.com/libp2p/js-interfaces/tree/master/src/connection
|
||||
[multiaddr]: https://github.com/multiformats/js-multiaddr
|
||||
[peer-id]: https://github.com/libp2p/js-peer-id
|
||||
[peer-info]: https://github.com/libp2p/js-peer-info
|
||||
|
@ -1,178 +0,0 @@
|
||||
# Migrating to the new API
|
||||
|
||||
A migration guide for refactoring your application code from libp2p v0.26.x to v0.27.0.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Migrating from callbacks](#migrating-from-callbacks)
|
||||
- [Pull Streams to Streaming Iterables](#pull-streams-to-streaming-iterables)
|
||||
- [Sample API Migrations](#sample-api-migrations)
|
||||
- [Registering Protocol Handlers](#registering-protocol-handlers)
|
||||
- [Dialing and Sending Data](#dialing-and-sending-data)
|
||||
- [Checking if a peer is connected](#checking-if-a-peer-is-connected)
|
||||
- [Pinging another peer](#pinging-another-peer)
|
||||
- [Pubsub](#pubsub)
|
||||
- [Getting subscribers](#getting-subscribers)
|
||||
- [Getting subscribed topics](#getting-subscribed-topics)
|
||||
|
||||
## Migrating from callbacks
|
||||
|
||||
Callbacks are no longer supported in the libp2p API, as the API has now fully moved to async / await. You can see a full list of the available methods in the [API readme][api]
|
||||
|
||||
**Before**
|
||||
```js
|
||||
libp2p.start((err) => {
|
||||
if (err) throw err
|
||||
console.log('libp2p started')
|
||||
})
|
||||
```
|
||||
|
||||
**After**
|
||||
```js
|
||||
await libp2p.start()
|
||||
console.log('libp2p started')
|
||||
```
|
||||
|
||||
## Pull Streams to Streaming Iterables
|
||||
|
||||
The libp2p API no longer supports Pull Streams and has migrated to [Streaming Iterables][streaming_iterable]. If you would like to continue using Pull Streams in your application code, or need additional time to migrate your code base, you can leverage the conversion modules [async-iterator-to-pull-stream](https://github.com/alanshaw/async-iterator-to-pull-stream) and [pull-stream-to-async-iterator](https://github.com/alanshaw/pull-stream-to-async-iterator).
|
||||
|
||||
For a growing list of async iterator modules, you should follow the [it-awesome repo][it_awesome].
|
||||
|
||||
## Sample API Migrations
|
||||
|
||||
### Registering Protocol Handlers
|
||||
|
||||
Protocol registration is very similar to how it previously was, however, the handler now takes a single parameter containing the incoming stream and its protocol. Additionally, you can now pass an array of protocols to `.handle`, but a single string is still supported.
|
||||
|
||||
**Before**
|
||||
```js
|
||||
const pull = require('pull-stream')
|
||||
libp2p.handle('/echo/1.0.0', (protocol, conn) => pull(conn, conn))
|
||||
```
|
||||
|
||||
**After**
|
||||
```js
|
||||
const pipe = require('it-pipe')
|
||||
libp2p.handle(['/echo/1.0.0'], ({ protocol, stream }) => pipe(stream, stream))
|
||||
```
|
||||
|
||||
### Dialing and Sending Data
|
||||
|
||||
`dialProtocol` no longer takes a callback, and will now return a [Streaming Iterable][streaming_iterable] and the protocol that was successfully negotiated. The new stream can be used with async iterator modules, see [it-awesome][it_awesome], instead of pull streams.
|
||||
|
||||
**Before**
|
||||
```js
|
||||
const pull = require('pull-stream')
|
||||
libp2p.dialProtocol(peerInfo, '/echo/1.0.0', (err, conn) => {
|
||||
if (err) { throw err }
|
||||
pull(
|
||||
pull.values(['hey']),
|
||||
conn,
|
||||
pull.drain((data) => {
|
||||
console.log('received echo:', data.toString())
|
||||
}, (err) => {
|
||||
if (err) { throw err }
|
||||
})
|
||||
)
|
||||
})
|
||||
```
|
||||
|
||||
**After**
|
||||
```js
|
||||
const pipe = require('it-pipe')
|
||||
const { protocol, stream } = await libp2p.dialProtocol(peerInfo, '/echo/1.0.0')
|
||||
await pipe(
|
||||
['hey'],
|
||||
stream,
|
||||
async function (source) {
|
||||
for await (const data of source) {
|
||||
console.log('received echo:', data.toString())
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Checking if a peer is connected
|
||||
|
||||
`peerInfo.isConnected` has been deprecated. libp2p now tracks all connections centrally and will no longer update the state of `peerInfo.isConnected`. Consumers should switch to using `libp2p.registrar.getConnection(peerInfo)`, which will return an open connection to that peer if one exists.
|
||||
|
||||
**Before**
|
||||
```js
|
||||
if (peerInfo.isConnected()) {
|
||||
// ...do something if connected
|
||||
}
|
||||
```
|
||||
|
||||
**After**
|
||||
```js
|
||||
const connection = libp2p.registrar.getConnection(peerInfo)
|
||||
if (connection) {
|
||||
// ...do something if connected
|
||||
}
|
||||
```
|
||||
|
||||
### Pinging another peer
|
||||
|
||||
`libp2p.ping` will no longer callback with a `Ping` event emitter. The internal logic has been simplified to give more flexibility to the API. `libp2p.ping` will now execute a single ping and return the latency.
|
||||
|
||||
**Before**
|
||||
```js
|
||||
libp2p.ping(peerInfo, (err, ping) => {
|
||||
if (err) throw err
|
||||
ping.once('ping', (latency) => {
|
||||
console.log('Latency is %s ms', latency)
|
||||
ping.stop()
|
||||
})
|
||||
|
||||
ping.start()
|
||||
})
|
||||
```
|
||||
|
||||
**After**
|
||||
```js
|
||||
const latency = await libp2p.ping(peerInfo)
|
||||
console.log('Latency is %s ms', latency)
|
||||
```
|
||||
|
||||
### Pubsub
|
||||
|
||||
#### Getting subscribers
|
||||
|
||||
`libp2p.pubsub.peers()` is now `libp2p.pubsub.getSubscribers()` and is no longer an asynchronous action.
|
||||
|
||||
**Before**
|
||||
```js
|
||||
libp2p.pubsub.peers(topic, (err, subscribers) => {
|
||||
if (err) throw err
|
||||
console.log('Subscribers:', subscribers)
|
||||
})
|
||||
```
|
||||
|
||||
**After**
|
||||
```js
|
||||
const subscribers = libp2p.pubsub.getSubscribers(topic)
|
||||
console.log('Subscribers:', subscribers)
|
||||
```
|
||||
|
||||
#### Getting subscribed topics
|
||||
|
||||
`libp2p.pubsub.ls()` is now `libp2p.pubsub.getTopics()` and is no longer an asynchronous action.
|
||||
|
||||
**Before**
|
||||
```js
|
||||
libp2p.pubsub.ls((err, topics) => {
|
||||
if (err) throw err
|
||||
console.log('Topics:', topics)
|
||||
})
|
||||
```
|
||||
|
||||
**After**
|
||||
```js
|
||||
const topics = libp2p.pubsub.getTopics()
|
||||
console.log('Topics:', topics)
|
||||
```
|
||||
|
||||
[api]: ../API.md
|
||||
[it_awesome]: https://github.com/alanshaw/it-awesome
|
||||
[streaming_iterable]: ../STREAMING_ITERABLES.md
|
12
package.json
12
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "libp2p",
|
||||
"version": "0.27.3",
|
||||
"version": "0.27.0-rc.0",
|
||||
"description": "JavaScript implementation of libp2p, a modular peer to peer network stack",
|
||||
"leadMaintainer": "Jacob Heun <jacobheun@gmail.com>",
|
||||
"main": "src/index.js",
|
||||
@ -47,7 +47,7 @@
|
||||
"bignumber.js": "^9.0.0",
|
||||
"class-is": "^1.1.0",
|
||||
"debug": "^4.1.1",
|
||||
"err-code": "^2.0.0",
|
||||
"err-code": "^1.1.2",
|
||||
"hashlru": "^2.3.0",
|
||||
"it-all": "^1.0.1",
|
||||
"it-buffer": "^0.1.1",
|
||||
@ -76,14 +76,13 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nodeutils/defaults-deep": "^1.1.0",
|
||||
"abortable-iterator": "^3.0.0",
|
||||
"abortable-iterator": "^2.1.0",
|
||||
"aegir": "^20.5.1",
|
||||
"chai": "^4.2.0",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"cids": "^0.7.1",
|
||||
"delay": "^4.3.0",
|
||||
"dirty-chai": "^2.0.1",
|
||||
"interop-libp2p": "~0.0.1",
|
||||
"it-concat": "^1.0.0",
|
||||
"it-pair": "^1.0.0",
|
||||
"it-pushable": "^1.4.0",
|
||||
@ -99,7 +98,7 @@
|
||||
"libp2p-tcp": "^0.14.1",
|
||||
"libp2p-webrtc-star": "^0.17.0",
|
||||
"libp2p-websockets": "^0.13.1",
|
||||
"nock": "^11.7.2",
|
||||
"nock": "^10.0.6",
|
||||
"p-defer": "^3.0.0",
|
||||
"p-times": "^2.1.0",
|
||||
"p-wait-for": "^3.1.0",
|
||||
@ -113,7 +112,6 @@
|
||||
"Alan Shaw <alan@tableflip.io>",
|
||||
"Alex Potsides <alex@achingbrain.net>",
|
||||
"Andrew Nesbitt <andrewnez@gmail.com>",
|
||||
"Cayman <caymannava@gmail.com>",
|
||||
"Chris Bratlien <chrisbratlien@gmail.com>",
|
||||
"Chris Dostert <chrisdostert@users.noreply.github.com>",
|
||||
"Daijiro Wachi <daijiro.wachi@gmail.com>",
|
||||
@ -155,14 +153,12 @@
|
||||
"Yusef Napora <yusef@napora.org>",
|
||||
"Zane Starr <zcstarr@gmail.com>",
|
||||
"a1300 <a1300@users.noreply.github.com>",
|
||||
"dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>",
|
||||
"dirkmc <dirkmdev@gmail.com>",
|
||||
"ebinks <elizabethjbinks@gmail.com>",
|
||||
"greenkeeperio-bot <support@greenkeeper.io>",
|
||||
"isan_rivkin <isanrivkin@gmail.com>",
|
||||
"mayerwin <mayerwin@users.noreply.github.com>",
|
||||
"phillmac <phillmac@users.noreply.github.com>",
|
||||
"shresthagrawal <34920931+shresthagrawal@users.noreply.github.com>",
|
||||
"swedneck <40505480+swedneck@users.noreply.github.com>",
|
||||
"ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com>"
|
||||
]
|
||||
|
3
pdd/README.md
Normal file
3
pdd/README.md
Normal 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
20
pdd/package.json
Normal 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"
|
||||
}
|
||||
}
|
104
pdd/pdd-the-ipfs-bundle--story-1--peer-a.js
Normal file
104
pdd/pdd-the-ipfs-bundle--story-1--peer-a.js
Normal 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/p2p/${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')))
|
||||
})
|
||||
})
|
98
pdd/pdd-the-ipfs-bundle--story-1--peer-b.js
Normal file
98
pdd/pdd-the-ipfs-bundle--story-1--peer-b.js
Normal 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/p2p/${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')))
|
||||
})
|
||||
})
|
0
pdd/pdd-the-ipfs-bundle--story-2--peer-a.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-2--peer-a.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-2--peer-b.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-2--peer-b.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-3--peer-a.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-3--peer-a.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-3--peer-b.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-3--peer-b.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-3--peer-c.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-3--peer-c.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-4--peer-a.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-4--peer-a.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-4--peer-b.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-4--peer-b.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-4--peer-c.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-4--peer-c.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-4--peer-d.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-4--peer-d.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-4--peer-e.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-4--peer-e.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-5--peer-a.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-5--peer-a.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-5--peer-b.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-5--peer-b.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-5--peer-c.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-5--peer-c.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-5--peer-d.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-5--peer-d.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-5--peer-e.js
Normal file
0
pdd/pdd-the-ipfs-bundle--story-5--peer-e.js
Normal file
54
pdd/pdd-transport--story-1--peer-a.js
Normal file
54
pdd/pdd-transport--story-1--peer-a.js
Normal 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/p2p/${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'))
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
49
pdd/pdd-transport--story-1--peer-b.js
Normal file
49
pdd/pdd-transport--story-1--peer-b.js
Normal 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')
|
||||
})
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
54
pdd/pdd-transport--story-2--peer-a.js
Normal file
54
pdd/pdd-transport--story-2--peer-a.js
Normal 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/p2p/${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'))
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
49
pdd/pdd-transport--story-2--peer-b.js
Normal file
49
pdd/pdd-transport--story-2--peer-b.js
Normal 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
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
42
pdd/pdd-transport--story-3--peer-a.js
Normal file
42
pdd/pdd-transport--story-3--peer-a.js
Normal 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/p2p/${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)
|
||||
})
|
||||
})
|
42
pdd/pdd-transport--story-3--peer-b.js
Normal file
42
pdd/pdd-transport--story-3--peer-b.js
Normal 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/p2p/${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)
|
||||
})
|
||||
})
|
@ -70,7 +70,7 @@ class Dialer {
|
||||
async connectToPeer (peer, options = {}) {
|
||||
const dialTarget = this._createDialTarget(peer)
|
||||
if (dialTarget.addrs.length === 0) {
|
||||
throw errCode(new Error('The dial request has no addresses'), codes.ERR_NO_VALID_ADDRESSES)
|
||||
throw errCode(new Error('The dial request has no addresses'), 'ERR_NO_DIAL_MULTIADDRS')
|
||||
}
|
||||
const pendingDial = this._pendingDials.get(dialTarget.id) || this._createPendingDial(dialTarget, options)
|
||||
|
||||
@ -136,7 +136,7 @@ class Dialer {
|
||||
*/
|
||||
_createPendingDial (dialTarget, options) {
|
||||
const dialAction = (addr, options) => {
|
||||
if (options.signal.aborted) throw errCode(new Error('already aborted'), codes.ERR_ALREADY_ABORTED)
|
||||
if (options.signal.aborted) throw errCode(new Error('already aborted'), 'ERR_ALREADY_ABORTED')
|
||||
return this.transportManager.dial(addr, options)
|
||||
}
|
||||
|
||||
@ -197,7 +197,8 @@ class Dialer {
|
||||
try {
|
||||
peer = PeerId.createFromCID(peer.getPeerId())
|
||||
} catch (err) {
|
||||
throw errCode(new Error('The multiaddr did not contain a valid peer id'), codes.ERR_INVALID_PEER)
|
||||
// Couldn't get the PeerId, just use the address
|
||||
return peer
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,6 @@ exports.codes = {
|
||||
ERR_CONNECTION_ENDED: 'ERR_CONNECTION_ENDED',
|
||||
ERR_CONNECTION_FAILED: 'ERR_CONNECTION_FAILED',
|
||||
ERR_NODE_NOT_STARTED: 'ERR_NODE_NOT_STARTED',
|
||||
ERR_ALREADY_ABORTED: 'ERR_ALREADY_ABORTED',
|
||||
ERR_NO_VALID_ADDRESSES: 'ERR_NO_VALID_ADDRESSES',
|
||||
ERR_DISCOVERED_SELF: 'ERR_DISCOVERED_SELF',
|
||||
ERR_DUPLICATE_TRANSPORT: 'ERR_DUPLICATE_TRANSPORT',
|
||||
|
@ -4,7 +4,7 @@ const debug = require('debug')
|
||||
const pb = require('it-protocol-buffers')
|
||||
const lp = require('it-length-prefixed')
|
||||
const pipe = require('it-pipe')
|
||||
const { collect, take, consume } = require('streaming-iterables')
|
||||
const { collect, take } = require('streaming-iterables')
|
||||
|
||||
const PeerInfo = require('peer-info')
|
||||
const PeerId = require('peer-id')
|
||||
@ -114,8 +114,7 @@ class IdentifyService {
|
||||
protocols: Array.from(this._protocols.keys())
|
||||
}],
|
||||
pb.encode(Message),
|
||||
stream,
|
||||
consume
|
||||
stream
|
||||
)
|
||||
} catch (err) {
|
||||
// Just log errors
|
||||
@ -154,7 +153,6 @@ class IdentifyService {
|
||||
async identify (connection) {
|
||||
const { stream } = await connection.newStream(MULTICODEC_IDENTIFY)
|
||||
const [data] = await pipe(
|
||||
[],
|
||||
stream,
|
||||
lp.decode(),
|
||||
take(1),
|
||||
@ -244,8 +242,7 @@ class IdentifyService {
|
||||
pipe(
|
||||
[message],
|
||||
lp.encode(),
|
||||
stream,
|
||||
consume
|
||||
stream
|
||||
)
|
||||
}
|
||||
|
||||
@ -258,7 +255,6 @@ class IdentifyService {
|
||||
*/
|
||||
async _handlePush ({ connection, stream }) {
|
||||
const [data] = await pipe(
|
||||
[],
|
||||
stream,
|
||||
lp.decode(),
|
||||
take(1),
|
||||
|
@ -224,16 +224,12 @@ class PeerStore extends EventEmitter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the known multiaddrs for a given `PeerInfo`. All returned multiaddrs
|
||||
* will include the encapsulated `PeerId` of the peer.
|
||||
* Returns the known multiaddrs for a given `PeerInfo`
|
||||
* @param {PeerInfo} peer
|
||||
* @returns {Array<Multiaddr>}
|
||||
*/
|
||||
multiaddrsForPeer (peer) {
|
||||
return this.put(peer, true).multiaddrs.toArray().map(addr => {
|
||||
if (addr.getPeerId()) return addr
|
||||
return addr.encapsulate(`/p2p/${peer.id.toB58String()}`)
|
||||
})
|
||||
return this.put(peer, true).multiaddrs.toArray()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ const errCode = require('err-code')
|
||||
const crypto = require('libp2p-crypto')
|
||||
const pipe = require('it-pipe')
|
||||
const { toBuffer } = require('it-buffer')
|
||||
const { collect, take } = require('streaming-iterables')
|
||||
const { collect } = require('streaming-iterables')
|
||||
|
||||
const { PROTOCOL, PING_LENGTH } = require('./constants')
|
||||
|
||||
@ -29,7 +29,6 @@ async function ping (node, peer) {
|
||||
const [result] = await pipe(
|
||||
[data],
|
||||
stream,
|
||||
stream => take(1, stream),
|
||||
toBuffer,
|
||||
collect
|
||||
)
|
||||
|
@ -231,7 +231,7 @@ class Upgrader {
|
||||
const { stream, protocol } = await mss.handle(Array.from(this.protocols.keys()))
|
||||
log('%s: incoming stream opened on %s', direction, protocol)
|
||||
if (this.metrics) this.metrics.trackStream({ stream, remotePeer, protocol })
|
||||
connection.addStream(muxedStream, { protocol })
|
||||
connection.addStream(stream, protocol)
|
||||
this._onStream({ connection, stream, protocol })
|
||||
} catch (err) {
|
||||
log.error(err)
|
||||
|
@ -43,7 +43,7 @@ describe('DHT subsystem operates correctly', () => {
|
||||
remoteLibp2p.start()
|
||||
])
|
||||
|
||||
remAddr = libp2p.peerStore.multiaddrsForPeer(remotePeerInfo)[0]
|
||||
remAddr = remoteLibp2p.transportManager.getAddrs()[0]
|
||||
})
|
||||
|
||||
afterEach(() => Promise.all([
|
||||
@ -98,7 +98,7 @@ describe('DHT subsystem operates correctly', () => {
|
||||
await libp2p.start()
|
||||
await remoteLibp2p.start()
|
||||
|
||||
remAddr = libp2p.peerStore.multiaddrsForPeer(remotePeerInfo)[0]
|
||||
remAddr = remoteLibp2p.transportManager.getAddrs()[0]
|
||||
})
|
||||
|
||||
afterEach(() => Promise.all([
|
||||
|
@ -6,11 +6,9 @@ chai.use(require('dirty-chai'))
|
||||
const { expect } = chai
|
||||
|
||||
const pTimes = require('p-times')
|
||||
const pipe = require('it-pipe')
|
||||
|
||||
const peerUtils = require('../utils/creators/peer')
|
||||
const baseOptions = require('../utils/base-options')
|
||||
const { PROTOCOL } = require('../../src/ping/constants')
|
||||
|
||||
describe('ping', () => {
|
||||
let nodes
|
||||
@ -34,40 +32,4 @@ describe('ping', () => {
|
||||
const averageLatency = latencies.reduce((p, c) => p + c, 0) / latencies.length
|
||||
expect(averageLatency).to.be.a('Number')
|
||||
})
|
||||
|
||||
it('only waits for the first response to arrive', async () => {
|
||||
nodes[1].handle(PROTOCOL, async ({ connection, stream }) => {
|
||||
let firstInvocation = true
|
||||
|
||||
await pipe(
|
||||
stream,
|
||||
function (stream) {
|
||||
const output = {
|
||||
[Symbol.asyncIterator]: () => output,
|
||||
next: async () => {
|
||||
if (firstInvocation) {
|
||||
firstInvocation = false
|
||||
|
||||
for await (const data of stream) {
|
||||
return {
|
||||
value: data,
|
||||
done: false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return new Promise() // never resolve
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output
|
||||
},
|
||||
stream
|
||||
)
|
||||
})
|
||||
|
||||
const latency = await nodes[0].ping(nodes[1].peerInfo)
|
||||
|
||||
expect(latency).to.be.a('Number')
|
||||
})
|
||||
})
|
||||
|
@ -34,25 +34,20 @@ const Peers = require('../fixtures/peers')
|
||||
const { createPeerInfo } = require('../utils/creators/peer')
|
||||
|
||||
const listenAddr = multiaddr('/ip4/127.0.0.1/tcp/0')
|
||||
const unsupportedAddr = multiaddr('/ip4/127.0.0.1/tcp/9999/ws/p2p/QmckxVrJw1Yo8LqvmDJNUmdAsKtSbiKWmrXJFyKmUraBoN')
|
||||
const unsupportedAddr = multiaddr('/ip4/127.0.0.1/tcp/9999/ws')
|
||||
|
||||
describe('Dialing (direct, TCP)', () => {
|
||||
let remoteTM
|
||||
let localTM
|
||||
let peerStore
|
||||
let remoteAddr
|
||||
|
||||
before(async () => {
|
||||
const [remotePeerId] = await Promise.all([
|
||||
PeerId.createFromJSON(Peers[0])
|
||||
])
|
||||
remoteTM = new TransportManager({
|
||||
libp2p: {},
|
||||
upgrader: mockUpgrader
|
||||
})
|
||||
remoteTM.add(Transport.prototype[Symbol.toStringTag], Transport)
|
||||
|
||||
peerStore = new PeerStore()
|
||||
localTM = new TransportManager({
|
||||
libp2p: {},
|
||||
upgrader: mockUpgrader
|
||||
@ -61,7 +56,7 @@ describe('Dialing (direct, TCP)', () => {
|
||||
|
||||
await remoteTM.listen([listenAddr])
|
||||
|
||||
remoteAddr = remoteTM.getAddrs()[0].encapsulate(`/p2p/${remotePeerId.toB58String()}`)
|
||||
remoteAddr = remoteTM.getAddrs()[0]
|
||||
})
|
||||
|
||||
after(() => remoteTM.close())
|
||||
@ -71,7 +66,7 @@ describe('Dialing (direct, TCP)', () => {
|
||||
})
|
||||
|
||||
it('should be able to connect to a remote node via its multiaddr', async () => {
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
|
||||
const connection = await dialer.connectToPeer(remoteAddr)
|
||||
expect(connection).to.exist()
|
||||
@ -79,7 +74,7 @@ describe('Dialing (direct, TCP)', () => {
|
||||
})
|
||||
|
||||
it('should be able to connect to a remote node via its stringified multiaddr', async () => {
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
|
||||
const dialable = Dialer.getDialable(remoteAddr.toString())
|
||||
const connection = await dialer.connectToPeer(dialable)
|
||||
@ -88,7 +83,7 @@ describe('Dialing (direct, TCP)', () => {
|
||||
})
|
||||
|
||||
it('should fail to connect to an unsupported multiaddr', async () => {
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
|
||||
await expect(dialer.connectToPeer(unsupportedAddr))
|
||||
.to.eventually.be.rejectedWith(AggregateError)
|
||||
@ -145,7 +140,6 @@ describe('Dialing (direct, TCP)', () => {
|
||||
it('should abort dials on queue task timeout', async () => {
|
||||
const dialer = new Dialer({
|
||||
transportManager: localTM,
|
||||
peerStore,
|
||||
timeout: 50
|
||||
})
|
||||
sinon.stub(localTM, 'dial').callsFake(async (addr, options) => {
|
||||
@ -230,7 +224,7 @@ describe('Dialing (direct, TCP)', () => {
|
||||
remoteLibp2p.handle('/echo/1.0.0', ({ stream }) => pipe(stream, stream))
|
||||
|
||||
await remoteLibp2p.start()
|
||||
remoteAddr = remoteLibp2p.transportManager.getAddrs()[0].encapsulate(`/p2p/${remotePeerId.toB58String()}`)
|
||||
remoteAddr = remoteLibp2p.transportManager.getAddrs()[0]
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
@ -241,28 +235,6 @@ describe('Dialing (direct, TCP)', () => {
|
||||
|
||||
after(() => remoteLibp2p.stop())
|
||||
|
||||
it('should fail if no peer id is provided', async () => {
|
||||
libp2p = new Libp2p({
|
||||
peerInfo,
|
||||
modules: {
|
||||
transport: [Transport],
|
||||
streamMuxer: [Muxer],
|
||||
connEncryption: [Crypto]
|
||||
}
|
||||
})
|
||||
|
||||
sinon.spy(libp2p.dialer, 'connectToPeer')
|
||||
|
||||
try {
|
||||
await libp2p.dial(remoteLibp2p.transportManager.getAddrs()[0])
|
||||
} catch (err) {
|
||||
expect(err).to.have.property('code', ErrorCodes.ERR_INVALID_PEER)
|
||||
return
|
||||
}
|
||||
|
||||
expect.fail('dial should have failed')
|
||||
})
|
||||
|
||||
it('should use the dialer for connecting to a multiaddr', async () => {
|
||||
libp2p = new Libp2p({
|
||||
peerInfo,
|
||||
@ -295,8 +267,10 @@ describe('Dialing (direct, TCP)', () => {
|
||||
})
|
||||
|
||||
sinon.spy(libp2p.dialer, 'connectToPeer')
|
||||
const remotePeer = new PeerInfo(remoteLibp2p.peerInfo.id)
|
||||
remotePeer.multiaddrs.add(remoteAddr)
|
||||
|
||||
const connection = await libp2p.dial(remotePeerInfo)
|
||||
const connection = await libp2p.dial(remotePeer)
|
||||
expect(connection).to.exist()
|
||||
const { stream, protocol } = await connection.newStream('/echo/1.0.0')
|
||||
expect(stream).to.exist()
|
||||
@ -332,7 +306,7 @@ describe('Dialing (direct, TCP)', () => {
|
||||
}
|
||||
})
|
||||
|
||||
const connection = await libp2p.dial(`${remoteAddr.toString()}`)
|
||||
const connection = await libp2p.dial(`${remoteAddr.toString()}/p2p/${remotePeerInfo.id.toB58String()}`)
|
||||
expect(connection).to.exist()
|
||||
expect(connection.stat.timeline.close).to.not.exist()
|
||||
await libp2p.hangUp(connection.remotePeer)
|
||||
@ -363,6 +337,33 @@ describe('Dialing (direct, TCP)', () => {
|
||||
expect(libp2p.upgrader.protector.protect.callCount).to.equal(1)
|
||||
})
|
||||
|
||||
it('should coalesce parallel dials to the same peer (no id in multiaddr)', async () => {
|
||||
libp2p = new Libp2p({
|
||||
peerInfo,
|
||||
modules: {
|
||||
transport: [Transport],
|
||||
streamMuxer: [Muxer],
|
||||
connEncryption: [Crypto]
|
||||
}
|
||||
})
|
||||
const dials = 10
|
||||
|
||||
const dialResults = await Promise.all([...new Array(dials)].map((_, index) => {
|
||||
if (index % 2 === 0) return libp2p.dial(remoteLibp2p.peerInfo)
|
||||
return libp2p.dial(remoteLibp2p.peerInfo.multiaddrs.toArray()[0])
|
||||
}))
|
||||
|
||||
// All should succeed and we should have ten results
|
||||
expect(dialResults).to.have.length(10)
|
||||
for (const connection of dialResults) {
|
||||
expect(Connection.isConnection(connection)).to.equal(true)
|
||||
}
|
||||
|
||||
// We will have two connections, since the multiaddr dial doesn't have a peer id
|
||||
expect(libp2p.connectionManager._connections.size).to.equal(2)
|
||||
expect(remoteLibp2p.connectionManager._connections.size).to.equal(2)
|
||||
})
|
||||
|
||||
it('should coalesce parallel dials to the same peer (id in multiaddr)', async () => {
|
||||
libp2p = new Libp2p({
|
||||
peerInfo,
|
||||
@ -404,9 +405,10 @@ describe('Dialing (direct, TCP)', () => {
|
||||
const error = new Error('Boom')
|
||||
sinon.stub(libp2p.transportManager, 'dial').callsFake(() => Promise.reject(error))
|
||||
|
||||
const fullAddress = remoteAddr.encapsulate(`/p2p/${remoteLibp2p.peerInfo.id.toB58String()}`)
|
||||
const dialResults = await pSettle([...new Array(dials)].map((_, index) => {
|
||||
if (index % 2 === 0) return libp2p.dial(remoteLibp2p.peerInfo)
|
||||
return libp2p.dial(remoteAddr)
|
||||
return libp2p.dial(fullAddress)
|
||||
}))
|
||||
|
||||
// All should succeed and we should have ten results
|
||||
|
@ -21,7 +21,6 @@ const { AbortError } = require('libp2p-interfaces/src/transport/errors')
|
||||
const { codes: ErrorCodes } = require('../../src/errors')
|
||||
const Constants = require('../../src/constants')
|
||||
const Dialer = require('../../src/dialer')
|
||||
const PeerStore = require('../../src/peer-store')
|
||||
const TransportManager = require('../../src/transport-manager')
|
||||
const Libp2p = require('../../src')
|
||||
|
||||
@ -30,15 +29,13 @@ const { MULTIADDRS_WEBSOCKETS } = require('../fixtures/browser')
|
||||
const mockUpgrader = require('../utils/mockUpgrader')
|
||||
const createMockConnection = require('../utils/mockConnection')
|
||||
const { createPeerId } = require('../utils/creators/peer')
|
||||
const unsupportedAddr = multiaddr('/ip4/127.0.0.1/tcp/9999/ws/p2p/QmckxVrJw1Yo8LqvmDJNUmdAsKtSbiKWmrXJFyKmUraBoN')
|
||||
const unsupportedAddr = multiaddr('/ip4/127.0.0.1/tcp/9999/ws')
|
||||
const remoteAddr = MULTIADDRS_WEBSOCKETS[0]
|
||||
|
||||
describe('Dialing (direct, WebSockets)', () => {
|
||||
let localTM
|
||||
let peerStore
|
||||
|
||||
before(() => {
|
||||
peerStore = new PeerStore()
|
||||
localTM = new TransportManager({
|
||||
libp2p: {},
|
||||
upgrader: mockUpgrader,
|
||||
@ -52,13 +49,13 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
})
|
||||
|
||||
it('should have appropriate defaults', () => {
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
expect(dialer.concurrency).to.equal(Constants.MAX_PARALLEL_DIALS)
|
||||
expect(dialer.timeout).to.equal(Constants.DIAL_TIMEOUT)
|
||||
})
|
||||
|
||||
it('should limit the number of tokens it provides', () => {
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
const maxPerPeer = Constants.MAX_PER_PEER_DIALS
|
||||
expect(dialer.tokens).to.have.length(Constants.MAX_PARALLEL_DIALS)
|
||||
const tokens = dialer.getTokens(maxPerPeer + 1)
|
||||
@ -67,14 +64,14 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
})
|
||||
|
||||
it('should not return tokens if non are left', () => {
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
sinon.stub(dialer, 'tokens').value([])
|
||||
const tokens = dialer.getTokens(1)
|
||||
expect(tokens.length).to.equal(0)
|
||||
})
|
||||
|
||||
it('should NOT be able to return a token twice', () => {
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
const tokens = dialer.getTokens(1)
|
||||
expect(tokens).to.have.length(1)
|
||||
expect(dialer.tokens).to.have.length(Constants.MAX_PARALLEL_DIALS - 1)
|
||||
@ -110,7 +107,7 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
})
|
||||
|
||||
it('should fail to connect to an unsupported multiaddr', async () => {
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
|
||||
await expect(dialer.connectToPeer(unsupportedAddr))
|
||||
.to.eventually.be.rejectedWith(AggregateError)
|
||||
|
@ -123,10 +123,11 @@ describe('Dialing (via relay, TCP)', () => {
|
||||
})
|
||||
|
||||
it('dialer should stay connected to an already connected relay on hop failure', async () => {
|
||||
const relayAddr = relayLibp2p.transportManager.getAddrs()[0]
|
||||
const relayIdString = relayLibp2p.peerInfo.id.toB58String()
|
||||
const relayAddr = relayLibp2p.transportManager.getAddrs()[0].encapsulate(`/p2p/${relayIdString}`)
|
||||
|
||||
const dialAddr = relayAddr
|
||||
.encapsulate(`/p2p/${relayIdString}`)
|
||||
.encapsulate(`/p2p-circuit/p2p/${dstLibp2p.peerInfo.id.toB58String()}`)
|
||||
|
||||
await srcLibp2p.dial(relayAddr)
|
||||
@ -141,15 +142,16 @@ describe('Dialing (via relay, TCP)', () => {
|
||||
})
|
||||
|
||||
it('destination peer should stay connected to an already connected relay on hop failure', async () => {
|
||||
const relayAddr = relayLibp2p.transportManager.getAddrs()[0]
|
||||
const relayIdString = relayLibp2p.peerInfo.id.toB58String()
|
||||
const relayAddr = relayLibp2p.transportManager.getAddrs()[0].encapsulate(`/p2p/${relayIdString}`)
|
||||
|
||||
const dialAddr = relayAddr
|
||||
.encapsulate(`/p2p/${relayIdString}`)
|
||||
.encapsulate(`/p2p-circuit/p2p/${dstLibp2p.peerInfo.id.toB58String()}`)
|
||||
|
||||
// Connect the destination peer and the relay
|
||||
const tcpAddrs = dstLibp2p.transportManager.getAddrs()
|
||||
await dstLibp2p.transportManager.listen([multiaddr(`/p2p-circuit${relayAddr}`)])
|
||||
await dstLibp2p.transportManager.listen([multiaddr(`/p2p-circuit${relayAddr}/p2p/${relayIdString}`)])
|
||||
expect(dstLibp2p.transportManager.getAddrs()).to.have.deep.members([...tcpAddrs, dialAddr.decapsulate('p2p')])
|
||||
|
||||
// Tamper with the our multiaddrs for the circuit message
|
||||
|
@ -12,7 +12,6 @@ const PeerId = require('peer-id')
|
||||
const PeerInfo = require('peer-info')
|
||||
const duplexPair = require('it-pair/duplex')
|
||||
const multiaddr = require('multiaddr')
|
||||
const pWaitFor = require('p-wait-for')
|
||||
|
||||
const { codes: Errors } = require('../../src/errors')
|
||||
const { IdentifyService, multicodecs } = require('../../src/identify')
|
||||
@ -204,17 +203,16 @@ describe('Identify', () => {
|
||||
})
|
||||
|
||||
sinon.spy(libp2p.identifyService, 'identify')
|
||||
const peerStoreSpy = sinon.spy(libp2p.peerStore, 'replace')
|
||||
sinon.spy(libp2p.peerStore, 'replace')
|
||||
|
||||
const connection = await libp2p.dialer.connectToPeer(remoteAddr)
|
||||
expect(connection).to.exist()
|
||||
|
||||
// Wait for peer store to be updated
|
||||
await pWaitFor(() => peerStoreSpy.callCount === 1)
|
||||
// Wait for nextTick to trigger the identify call
|
||||
await delay(1)
|
||||
expect(libp2p.identifyService.identify.callCount).to.equal(1)
|
||||
await libp2p.identifyService.identify.firstCall.returnValue
|
||||
|
||||
// The connection should have no open streams
|
||||
expect(connection.streams).to.have.length(0)
|
||||
expect(libp2p.peerStore.replace.callCount).to.equal(1)
|
||||
await connection.close()
|
||||
})
|
||||
|
||||
@ -249,9 +247,6 @@ describe('Identify', () => {
|
||||
const results = await call.returnValue
|
||||
expect(results.length).to.equal(1)
|
||||
}
|
||||
|
||||
// Verify the streams close
|
||||
await pWaitFor(() => connection.streams.length === 0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -160,24 +160,6 @@ describe('peer-store', () => {
|
||||
expect(removed).to.eql(true)
|
||||
expect(peerStore.peers.size).to.equal(0)
|
||||
})
|
||||
|
||||
it('should be able to remove a peer from store through its b58str id', async () => {
|
||||
const [peerInfo] = await peerUtils.createPeerInfo()
|
||||
const id = peerInfo.id
|
||||
const ma1 = multiaddr('/ip4/127.0.0.1/tcp/4001')
|
||||
const ma2 = multiaddr('/ip4/127.0.0.1/tcp/4002/ws')
|
||||
|
||||
peerInfo.multiaddrs.add(ma1)
|
||||
peerInfo.multiaddrs.add(ma2)
|
||||
|
||||
const multiaddrs = peerStore.multiaddrsForPeer(peerInfo)
|
||||
const expectedAddrs = [
|
||||
ma1.encapsulate(`/p2p/${id.toB58String()}`),
|
||||
ma2.encapsulate(`/p2p/${id.toB58String()}`)
|
||||
]
|
||||
|
||||
expect(multiaddrs).to.eql(expectedAddrs)
|
||||
})
|
||||
})
|
||||
|
||||
describe('peer-store on discovery', () => {
|
||||
|
@ -26,6 +26,7 @@ const remoteListenAddr = multiaddr('/ip4/127.0.0.1/tcp/0')
|
||||
describe('Pubsub subsystem is able to use different implementations', () => {
|
||||
let peerInfo, remotePeerInfo
|
||||
let libp2p, remoteLibp2p
|
||||
let remAddr
|
||||
|
||||
beforeEach(async () => {
|
||||
[peerInfo, remotePeerInfo] = await peerUtils.createPeerInfo({ number: 2 })
|
||||
@ -72,8 +73,9 @@ describe('Pubsub subsystem is able to use different implementations', () => {
|
||||
])
|
||||
|
||||
const libp2pId = libp2p.peerInfo.id.toB58String()
|
||||
remAddr = remoteLibp2p.transportManager.getAddrs()[0]
|
||||
|
||||
const connection = await libp2p.dialProtocol(remotePeerInfo, multicodec)
|
||||
const connection = await libp2p.dialProtocol(remAddr, multicodec)
|
||||
expect(connection).to.exist()
|
||||
|
||||
libp2p.pubsub.subscribe(topic, (msg) => {
|
||||
|
@ -21,6 +21,7 @@ const remoteListenAddr = multiaddr('/ip4/127.0.0.1/tcp/0')
|
||||
describe('Pubsub subsystem operates correctly', () => {
|
||||
let peerInfo, remotePeerInfo
|
||||
let libp2p, remoteLibp2p
|
||||
let remAddr
|
||||
|
||||
beforeEach(async () => {
|
||||
[peerInfo, remotePeerInfo] = await peerUtils.createPeerInfo({ number: 2 })
|
||||
@ -43,6 +44,8 @@ describe('Pubsub subsystem operates correctly', () => {
|
||||
libp2p.start(),
|
||||
remoteLibp2p.start()
|
||||
])
|
||||
|
||||
remAddr = remoteLibp2p.transportManager.getAddrs()[0]
|
||||
})
|
||||
|
||||
afterEach(() => Promise.all([
|
||||
@ -55,7 +58,7 @@ describe('Pubsub subsystem operates correctly', () => {
|
||||
})
|
||||
|
||||
it('should get notified of connected peers on dial', async () => {
|
||||
const connection = await libp2p.dialProtocol(remotePeerInfo, subsystemMulticodecs)
|
||||
const connection = await libp2p.dialProtocol(remAddr, subsystemMulticodecs)
|
||||
|
||||
expect(connection).to.exist()
|
||||
|
||||
@ -71,7 +74,7 @@ describe('Pubsub subsystem operates correctly', () => {
|
||||
const data = 'hey!'
|
||||
const libp2pId = libp2p.peerInfo.id.toB58String()
|
||||
|
||||
await libp2p.dialProtocol(remotePeerInfo, subsystemMulticodecs)
|
||||
await libp2p.dialProtocol(remAddr, subsystemMulticodecs)
|
||||
|
||||
let subscribedTopics = libp2p.pubsub.getTopics()
|
||||
expect(subscribedTopics).to.not.include(topic)
|
||||
@ -112,6 +115,8 @@ describe('Pubsub subsystem operates correctly', () => {
|
||||
|
||||
await libp2p.start()
|
||||
await remoteLibp2p.start()
|
||||
|
||||
remAddr = remoteLibp2p.transportManager.getAddrs()[0]
|
||||
})
|
||||
|
||||
afterEach(() => Promise.all([
|
||||
@ -124,7 +129,7 @@ describe('Pubsub subsystem operates correctly', () => {
|
||||
})
|
||||
|
||||
it('should get notified of connected peers after starting', async () => {
|
||||
const connection = await libp2p.dial(remotePeerInfo)
|
||||
const connection = await libp2p.dial(remAddr)
|
||||
|
||||
expect(connection).to.exist()
|
||||
expect(libp2p.pubsub._pubsub.peers.size).to.be.eql(0)
|
||||
@ -145,7 +150,7 @@ describe('Pubsub subsystem operates correctly', () => {
|
||||
const topic = 'test-topic'
|
||||
const data = 'hey!'
|
||||
|
||||
await libp2p.dial(remotePeerInfo)
|
||||
await libp2p.dial(remAddr)
|
||||
|
||||
remoteLibp2p.pubsub.start()
|
||||
|
||||
|
@ -29,7 +29,7 @@ describe('registrar on dial', () => {
|
||||
}))
|
||||
|
||||
await remoteLibp2p.transportManager.listen([listenAddr])
|
||||
remoteAddr = remoteLibp2p.transportManager.getAddrs()[0].encapsulate(`/p2p/${remotePeerInfo.id.toB58String()}`)
|
||||
remoteAddr = remoteLibp2p.transportManager.getAddrs()[0]
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
|
Reference in New Issue
Block a user