mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-07-15 08:41:35 +00:00
Compare commits
35 Commits
Author | SHA1 | Date | |
---|---|---|---|
da83721d6d | |||
1414e45969 | |||
9e35fbc316 | |||
30728753cf | |||
afdbe3deac | |||
ce58805e90 | |||
b5303fd788 | |||
aa78d2ef15 | |||
5a4641980d | |||
f4ec35573e | |||
524e6f8433 | |||
fad9cb22e0 | |||
e1b158fbb9 | |||
1837d6e95e | |||
4bce6aa0b9 | |||
4d11edd62c | |||
a8984c6cd3 | |||
0882dcea3b | |||
b3d8132ea6 | |||
a317a8b011 | |||
8bed8f39ff | |||
58c0c7c03e | |||
f662fdcf36 | |||
5608178247 | |||
dcd58693f5 | |||
8bf05e6db6 | |||
0589d53616 | |||
eb2528c1d6 | |||
141cf90ca0 | |||
f4ec459a7b | |||
56a7842664 | |||
be8fc9daf1 | |||
f39e8f0da9 | |||
ed0c2cb6c1 | |||
c6592c5797 |
@ -39,5 +39,12 @@ 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
|
43
CHANGELOG.md
43
CHANGELOG.md
@ -1,3 +1,46 @@
|
||||
<a name="0.27.4"></a>
|
||||
## [0.27.4](https://github.com/libp2p/js-libp2p/compare/v0.27.3...v0.27.4) (2020-03-31)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* only use a single export ([#596](https://github.com/libp2p/js-libp2p/issues/596)) ([3072875](https://github.com/libp2p/js-libp2p/commit/3072875))
|
||||
* pass libp2p to discovery services ([#597](https://github.com/libp2p/js-libp2p/issues/597)) ([9e35fbc](https://github.com/libp2p/js-libp2p/commit/9e35fbc))
|
||||
* **test:** improve flakey random walk discovery test ([#574](https://github.com/libp2p/js-libp2p/issues/574)) ([f4ec355](https://github.com/libp2p/js-libp2p/commit/f4ec355))
|
||||
* remove use of assert module ([#561](https://github.com/libp2p/js-libp2p/issues/561)) ([a8984c6](https://github.com/libp2p/js-libp2p/commit/a8984c6))
|
||||
|
||||
|
||||
|
||||
<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)
|
||||
|
||||
|
@ -37,7 +37,7 @@ One of following:
|
||||
|
||||
<!--
|
||||
This is for you! Please read, and then delete this text before posting it.
|
||||
The js-ipfs issues are only for bug reports and directly actionable features.
|
||||
The js-libp2p issues are only for bug reports and directly actionable features.
|
||||
|
||||
Read https://github.com/ipfs/community/blob/master/CONTRIBUTING.md#reporting-issues if your issue doesn't fit either of those categories.
|
||||
-->
|
||||
|
71
README.md
71
README.md
@ -5,12 +5,14 @@
|
||||
<h3 align="center">The JavaScript implementation of the libp2p Networking Stack.</h3>
|
||||
|
||||
<p align="center">
|
||||
<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://protocol.ai"><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.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://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://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>
|
||||
<a href="https://www.npmjs.com/package/libp2p"><img src="https://img.shields.io/npm/dm/libp2p.svg" /></a>
|
||||
<a href="https://www.jsdelivr.com/package/npm/libp2p"><img src="https://data.jsdelivr.com/v1/package/npm/libp2p/badge"/></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@ -30,6 +32,9 @@
|
||||
|
||||
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)
|
||||
@ -132,49 +137,45 @@ List of packages currently in existence for libp2p
|
||||
| Package | Version | Deps | CI | Coverage | Lead Maintainer |
|
||||
| ---------|---------|---------|---------|---------|--------- |
|
||||
| **libp2p** |
|
||||
| [`libp2p`](//github.com/libp2p/js-libp2p) | [](//github.com/libp2p/js-libp2p/releases) | [](https://david-dm.org/libp2p/js-libp2p) | [](https://travis-ci.com/libp2p/js-libp2p) | [](https://codecov.io/gh/libp2p/js-libp2p) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-daemon`](//github.com/libp2p/js-libp2p-daemon) | [](//github.com/libp2p/js-libp2p-daemon/releases) | [](https://david-dm.org/libp2p/js-libp2p-daemon) | [](https://travis-ci.com/libp2p/js-libp2p-daemon) | [](https://codecov.io/gh/libp2p/js-libp2p-daemon) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-daemon-client`](//github.com/libp2p/js-libp2p-daemon-client) | [](//github.com/libp2p/js-libp2p-daemon-client/releases) | [](https://david-dm.org/libp2p/js-libp2p-daemon-client) | [](https://travis-ci.com/libp2p/js-libp2p-daemon-client) | [](https://codecov.io/gh/libp2p/js-libp2p-daemon-client) | [Vasco Santos](mailto:santos.vasco10@gmail.com) |
|
||||
| [`libp2p-interfaces`](//github.com/libp2p/js-interfaces) | [](//github.com/libp2p/js-interfaces/releases) | [](https://david-dm.org/libp2p/js-interfaces) | [](https://travis-ci.com/libp2p/js-interfaces) | [](https://codecov.io/gh/libp2p/js-interfaces) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`interop-libp2p`](//github.com/libp2p/interop) | [](//github.com/libp2p/interop/releases) | [](https://david-dm.org/libp2p/interop) | [](https://travis-ci.com/libp2p/interop) | [](https://codecov.io/gh/libp2p/interop) | [Vasco Santos](mailto:santos.vasco10@gmail.com) |
|
||||
| [`libp2p`](//github.com/libp2p/js-libp2p) | [](//github.com/libp2p/js-libp2p/releases) | [](https://david-dm.org/libp2p/js-libp2p) | [](https://travis-ci.com/libp2p/js-libp2p) | [](https://codecov.io/gh/libp2p/js-libp2p) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-daemon`](//github.com/libp2p/js-libp2p-daemon) | [](//github.com/libp2p/js-libp2p-daemon/releases) | [](https://david-dm.org/libp2p/js-libp2p-daemon) | [](https://travis-ci.com/libp2p/js-libp2p-daemon) | [](https://codecov.io/gh/libp2p/js-libp2p-daemon) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-daemon-client`](//github.com/libp2p/js-libp2p-daemon-client) | [](//github.com/libp2p/js-libp2p-daemon-client/releases) | [](https://david-dm.org/libp2p/js-libp2p-daemon-client) | [](https://travis-ci.com/libp2p/js-libp2p-daemon-client) | [](https://codecov.io/gh/libp2p/js-libp2p-daemon-client) | [Vasco Santos](mailto:santos.vasco10@gmail.com) |
|
||||
| [`libp2p-interfaces`](//github.com/libp2p/js-interfaces) | [](//github.com/libp2p/js-interfaces/releases) | [](https://david-dm.org/libp2p/js-interfaces) | [](https://travis-ci.com/libp2p/js-interfaces) | [](https://codecov.io/gh/libp2p/js-interfaces) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`interop-libp2p`](//github.com/libp2p/interop) | [](//github.com/libp2p/interop/releases) | [](https://david-dm.org/libp2p/interop) | [](https://travis-ci.com/libp2p/interop) | [](https://codecov.io/gh/libp2p/interop) | [Vasco Santos](mailto:santos.vasco10@gmail.com) |
|
||||
| **transports** |
|
||||
| [`libp2p-tcp`](//github.com/libp2p/js-libp2p-tcp) | [](//github.com/libp2p/js-libp2p-tcp/releases) | [](https://david-dm.org/libp2p/js-libp2p-tcp) | [](https://travis-ci.com/libp2p/js-libp2p-tcp) | [](https://codecov.io/gh/libp2p/js-libp2p-tcp) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-utp`](//github.com/libp2p/js-libp2p-utp) | [](//github.com/libp2p/js-libp2p-utp/releases) | [](https://david-dm.org/libp2p/js-libp2p-utp) | [](https://travis-ci.com/libp2p/js-libp2p-utp) | [](https://codecov.io/gh/libp2p/js-libp2p-utp) | [Vasco Santos](mailto:santos.vasco10@gmail.com) |
|
||||
| [`libp2p-webrtc-direct`](//github.com/libp2p/js-libp2p-webrtc-direct) | [](//github.com/libp2p/js-libp2p-webrtc-direct/releases) | [](https://david-dm.org/libp2p/js-libp2p-webrtc-direct) | [](https://travis-ci.com/libp2p/js-libp2p-webrtc-direct) | [](https://codecov.io/gh/libp2p/js-libp2p-webrtc-direct) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-webrtc-star`](//github.com/libp2p/js-libp2p-webrtc-star) | [](//github.com/libp2p/js-libp2p-webrtc-star/releases) | [](https://david-dm.org/libp2p/js-libp2p-webrtc-star) | [](https://travis-ci.com/libp2p/js-libp2p-webrtc-star) | [](https://codecov.io/gh/libp2p/js-libp2p-webrtc-star) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-websockets`](//github.com/libp2p/js-libp2p-websockets) | [](//github.com/libp2p/js-libp2p-websockets/releases) | [](https://david-dm.org/libp2p/js-libp2p-websockets) | [](https://travis-ci.com/libp2p/js-libp2p-websockets) | [](https://codecov.io/gh/libp2p/js-libp2p-websockets) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-websocket-star`](//github.com/libp2p/js-libp2p-websocket-star) | [](//github.com/libp2p/js-libp2p-websocket-star/releases) | [](https://david-dm.org/libp2p/js-libp2p-websocket-star) | [](https://travis-ci.com/libp2p/js-libp2p-websocket-star) | [](https://codecov.io/gh/libp2p/js-libp2p-websocket-star) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-tcp`](//github.com/libp2p/js-libp2p-tcp) | [](//github.com/libp2p/js-libp2p-tcp/releases) | [](https://david-dm.org/libp2p/js-libp2p-tcp) | [](https://travis-ci.com/libp2p/js-libp2p-tcp) | [](https://codecov.io/gh/libp2p/js-libp2p-tcp) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-webrtc-direct`](//github.com/libp2p/js-libp2p-webrtc-direct) | [](//github.com/libp2p/js-libp2p-webrtc-direct/releases) | [](https://david-dm.org/libp2p/js-libp2p-webrtc-direct) | [](https://travis-ci.com/libp2p/js-libp2p-webrtc-direct) | [](https://codecov.io/gh/libp2p/js-libp2p-webrtc-direct) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-webrtc-star`](//github.com/libp2p/js-libp2p-webrtc-star) | [](//github.com/libp2p/js-libp2p-webrtc-star/releases) | [](https://david-dm.org/libp2p/js-libp2p-webrtc-star) | [](https://travis-ci.com/libp2p/js-libp2p-webrtc-star) | [](https://codecov.io/gh/libp2p/js-libp2p-webrtc-star) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-websockets`](//github.com/libp2p/js-libp2p-websockets) | [](//github.com/libp2p/js-libp2p-websockets/releases) | [](https://david-dm.org/libp2p/js-libp2p-websockets) | [](https://travis-ci.com/libp2p/js-libp2p-websockets) | [](https://codecov.io/gh/libp2p/js-libp2p-websockets) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| **secure channels** |
|
||||
| [`libp2p-secio`](//github.com/libp2p/js-libp2p-secio) | [](//github.com/libp2p/js-libp2p-secio/releases) | [](https://david-dm.org/libp2p/js-libp2p-secio) | [](https://travis-ci.com/libp2p/js-libp2p-secio) | [](https://codecov.io/gh/libp2p/js-libp2p-secio) | [Friedel Ziegelmayer](mailto:dignifiedquire@gmail.com) |
|
||||
| [`libp2p-secio`](//github.com/libp2p/js-libp2p-secio) | [](//github.com/libp2p/js-libp2p-secio/releases) | [](https://david-dm.org/libp2p/js-libp2p-secio) | [](https://travis-ci.com/libp2p/js-libp2p-secio) | [](https://codecov.io/gh/libp2p/js-libp2p-secio) | [Friedel Ziegelmayer](mailto:dignifiedquire@gmail.com) |
|
||||
| **stream multiplexers** |
|
||||
| [`libp2p-mplex`](//github.com/libp2p/js-libp2p-mplex) | [](//github.com/libp2p/js-libp2p-mplex/releases) | [](https://david-dm.org/libp2p/js-libp2p-mplex) | [](https://travis-ci.com/libp2p/js-libp2p-mplex) | [](https://codecov.io/gh/libp2p/js-libp2p-mplex) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-spdy`](//github.com/libp2p/js-libp2p-spdy) | [](//github.com/libp2p/js-libp2p-spdy/releases) | [](https://david-dm.org/libp2p/js-libp2p-spdy) | [](https://travis-ci.com/libp2p/js-libp2p-spdy) | [](https://codecov.io/gh/libp2p/js-libp2p-spdy) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-mplex`](//github.com/libp2p/js-libp2p-mplex) | [](//github.com/libp2p/js-libp2p-mplex/releases) | [](https://david-dm.org/libp2p/js-libp2p-mplex) | [](https://travis-ci.com/libp2p/js-libp2p-mplex) | [](https://codecov.io/gh/libp2p/js-libp2p-mplex) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-spdy`](//github.com/libp2p/js-libp2p-spdy) | [](//github.com/libp2p/js-libp2p-spdy/releases) | [](https://david-dm.org/libp2p/js-libp2p-spdy) | [](https://travis-ci.com/libp2p/js-libp2p-spdy) | [](https://codecov.io/gh/libp2p/js-libp2p-spdy) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| **peer discovery** |
|
||||
| [`libp2p-bootstrap`](//github.com/libp2p/js-libp2p-bootstrap) | [](//github.com/libp2p/js-libp2p-bootstrap/releases) | [](https://david-dm.org/libp2p/js-libp2p-bootstrap) | [](https://travis-ci.com/libp2p/js-libp2p-bootstrap) | [](https://codecov.io/gh/libp2p/js-libp2p-bootstrap) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-kad-dht`](//github.com/libp2p/js-libp2p-kad-dht) | [](//github.com/libp2p/js-libp2p-kad-dht/releases) | [](https://david-dm.org/libp2p/js-libp2p-kad-dht) | [](https://travis-ci.com/libp2p/js-libp2p-kad-dht) | [](https://codecov.io/gh/libp2p/js-libp2p-kad-dht) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-mdns`](//github.com/libp2p/js-libp2p-mdns) | [](//github.com/libp2p/js-libp2p-mdns/releases) | [](https://david-dm.org/libp2p/js-libp2p-mdns) | [](https://travis-ci.com/libp2p/js-libp2p-mdns) | [](https://codecov.io/gh/libp2p/js-libp2p-mdns) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-rendezvous`](//github.com/libp2p/js-libp2p-rendezvous) | [](//github.com/libp2p/js-libp2p-rendezvous/releases) | [](https://david-dm.org/libp2p/js-libp2p-rendezvous) | [](https://travis-ci.com/libp2p/js-libp2p-rendezvous) | [](https://codecov.io/gh/libp2p/js-libp2p-rendezvous) | [Vasco Santos](mailto:santos.vasco10@gmail.com) |
|
||||
| [`libp2p-webrtc-star`](//github.com/libp2p/js-libp2p-webrtc-star) | [](//github.com/libp2p/js-libp2p-webrtc-star/releases) | [](https://david-dm.org/libp2p/js-libp2p-webrtc-star) | [](https://travis-ci.com/libp2p/js-libp2p-webrtc-star) | [](https://codecov.io/gh/libp2p/js-libp2p-webrtc-star) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-websocket-star`](//github.com/libp2p/js-libp2p-websocket-star) | [](//github.com/libp2p/js-libp2p-websocket-star/releases) | [](https://david-dm.org/libp2p/js-libp2p-websocket-star) | [](https://travis-ci.com/libp2p/js-libp2p-websocket-star) | [](https://codecov.io/gh/libp2p/js-libp2p-websocket-star) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-bootstrap`](//github.com/libp2p/js-libp2p-bootstrap) | [](//github.com/libp2p/js-libp2p-bootstrap/releases) | [](https://david-dm.org/libp2p/js-libp2p-bootstrap) | [](https://travis-ci.com/libp2p/js-libp2p-bootstrap) | [](https://codecov.io/gh/libp2p/js-libp2p-bootstrap) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-kad-dht`](//github.com/libp2p/js-libp2p-kad-dht) | [](//github.com/libp2p/js-libp2p-kad-dht/releases) | [](https://david-dm.org/libp2p/js-libp2p-kad-dht) | [](https://travis-ci.com/libp2p/js-libp2p-kad-dht) | [](https://codecov.io/gh/libp2p/js-libp2p-kad-dht) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-mdns`](//github.com/libp2p/js-libp2p-mdns) | [](//github.com/libp2p/js-libp2p-mdns/releases) | [](https://david-dm.org/libp2p/js-libp2p-mdns) | [](https://travis-ci.com/libp2p/js-libp2p-mdns) | [](https://codecov.io/gh/libp2p/js-libp2p-mdns) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-webrtc-star`](//github.com/libp2p/js-libp2p-webrtc-star) | [](//github.com/libp2p/js-libp2p-webrtc-star/releases) | [](https://david-dm.org/libp2p/js-libp2p-webrtc-star) | [](https://travis-ci.com/libp2p/js-libp2p-webrtc-star) | [](https://codecov.io/gh/libp2p/js-libp2p-webrtc-star) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| **content routing** |
|
||||
| [`libp2p-delegated-content-routing`](//github.com/libp2p/js-libp2p-delegated-content-routing) | [](//github.com/libp2p/js-libp2p-delegated-content-routing/releases) | [](https://david-dm.org/libp2p/js-libp2p-delegated-content-routing) | [](https://travis-ci.com/libp2p/js-libp2p-delegated-content-routing) | [](https://codecov.io/gh/libp2p/js-libp2p-delegated-content-routing) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-kad-dht`](//github.com/libp2p/js-libp2p-kad-dht) | [](//github.com/libp2p/js-libp2p-kad-dht/releases) | [](https://david-dm.org/libp2p/js-libp2p-kad-dht) | [](https://travis-ci.com/libp2p/js-libp2p-kad-dht) | [](https://codecov.io/gh/libp2p/js-libp2p-kad-dht) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-delegated-content-routing`](//github.com/libp2p/js-libp2p-delegated-content-routing) | [](//github.com/libp2p/js-libp2p-delegated-content-routing/releases) | [](https://david-dm.org/libp2p/js-libp2p-delegated-content-routing) | [](https://travis-ci.com/libp2p/js-libp2p-delegated-content-routing) | [](https://codecov.io/gh/libp2p/js-libp2p-delegated-content-routing) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-kad-dht`](//github.com/libp2p/js-libp2p-kad-dht) | [](//github.com/libp2p/js-libp2p-kad-dht/releases) | [](https://david-dm.org/libp2p/js-libp2p-kad-dht) | [](https://travis-ci.com/libp2p/js-libp2p-kad-dht) | [](https://codecov.io/gh/libp2p/js-libp2p-kad-dht) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| **peer routing** |
|
||||
| [`libp2p-delegated-peer-routing`](//github.com/libp2p/js-libp2p-delegated-peer-routing) | [](//github.com/libp2p/js-libp2p-delegated-peer-routing/releases) | [](https://david-dm.org/libp2p/js-libp2p-delegated-peer-routing) | [](https://travis-ci.com/libp2p/js-libp2p-delegated-peer-routing) | [](https://codecov.io/gh/libp2p/js-libp2p-delegated-peer-routing) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-kad-dht`](//github.com/libp2p/js-libp2p-kad-dht) | [](//github.com/libp2p/js-libp2p-kad-dht/releases) | [](https://david-dm.org/libp2p/js-libp2p-kad-dht) | [](https://travis-ci.com/libp2p/js-libp2p-kad-dht) | [](https://codecov.io/gh/libp2p/js-libp2p-kad-dht) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-delegated-peer-routing`](//github.com/libp2p/js-libp2p-delegated-peer-routing) | [](//github.com/libp2p/js-libp2p-delegated-peer-routing/releases) | [](https://david-dm.org/libp2p/js-libp2p-delegated-peer-routing) | [](https://travis-ci.com/libp2p/js-libp2p-delegated-peer-routing) | [](https://codecov.io/gh/libp2p/js-libp2p-delegated-peer-routing) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-kad-dht`](//github.com/libp2p/js-libp2p-kad-dht) | [](//github.com/libp2p/js-libp2p-kad-dht/releases) | [](https://david-dm.org/libp2p/js-libp2p-kad-dht) | [](https://travis-ci.com/libp2p/js-libp2p-kad-dht) | [](https://codecov.io/gh/libp2p/js-libp2p-kad-dht) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| **utilities** |
|
||||
| [`libp2p-crypto`](//github.com/libp2p/js-libp2p-crypto) | [](//github.com/libp2p/js-libp2p-crypto/releases) | [](https://david-dm.org/libp2p/js-libp2p-crypto) | [](https://travis-ci.com/libp2p/js-libp2p-crypto) | [](https://codecov.io/gh/libp2p/js-libp2p-crypto) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-crypto-secp256k1`](//github.com/libp2p/js-libp2p-crypto-secp256k1) | [](//github.com/libp2p/js-libp2p-crypto-secp256k1/releases) | [](https://david-dm.org/libp2p/js-libp2p-crypto-secp256k1) | [](https://travis-ci.com/libp2p/js-libp2p-crypto-secp256k1) | [](https://codecov.io/gh/libp2p/js-libp2p-crypto-secp256k1) | [Friedel Ziegelmayer](mailto:dignifiedquire@gmail.com) |
|
||||
| [`libp2p-crypto`](//github.com/libp2p/js-libp2p-crypto) | [](//github.com/libp2p/js-libp2p-crypto/releases) | [](https://david-dm.org/libp2p/js-libp2p-crypto) | [](https://travis-ci.com/libp2p/js-libp2p-crypto) | [](https://codecov.io/gh/libp2p/js-libp2p-crypto) | [Jacob Heun](mailto:jacobheun@gmail.com) |
|
||||
| [`libp2p-crypto-secp256k1`](//github.com/libp2p/js-libp2p-crypto-secp256k1) | [](//github.com/libp2p/js-libp2p-crypto-secp256k1/releases) | [](https://david-dm.org/libp2p/js-libp2p-crypto-secp256k1) | [](https://travis-ci.com/libp2p/js-libp2p-crypto-secp256k1) | [](https://codecov.io/gh/libp2p/js-libp2p-crypto-secp256k1) | [Friedel Ziegelmayer](mailto:dignifiedquire@gmail.com) |
|
||||
| **data types** |
|
||||
| [`peer-id`](//github.com/libp2p/js-peer-id) | [](//github.com/libp2p/js-peer-id/releases) | [](https://david-dm.org/libp2p/js-peer-id) | [](https://travis-ci.com/libp2p/js-peer-id) | [](https://codecov.io/gh/libp2p/js-peer-id) | [Vasco Santos](mailto:santos.vasco10@gmail.com) |
|
||||
| [`peer-info`](//github.com/libp2p/js-peer-info) | [](//github.com/libp2p/js-peer-info/releases) | [](https://david-dm.org/libp2p/js-peer-info) | [](https://travis-ci.com/libp2p/js-peer-info) | [](https://codecov.io/gh/libp2p/js-peer-info) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`peer-id`](//github.com/libp2p/js-peer-id) | [](//github.com/libp2p/js-peer-id/releases) | [](https://david-dm.org/libp2p/js-peer-id) | [](https://travis-ci.com/libp2p/js-peer-id) | [](https://codecov.io/gh/libp2p/js-peer-id) | [Vasco Santos](mailto:santos.vasco10@gmail.com) |
|
||||
| [`peer-info`](//github.com/libp2p/js-peer-info) | [](//github.com/libp2p/js-peer-info/releases) | [](https://david-dm.org/libp2p/js-peer-info) | [](https://travis-ci.com/libp2p/js-peer-info) | [](https://codecov.io/gh/libp2p/js-peer-info) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| **pubsub** |
|
||||
| [`libp2p-pubsub`](//github.com/libp2p/js-libp2p-pubsub) | [](//github.com/libp2p/js-libp2p-pubsub/releases) | [](https://david-dm.org/libp2p/js-libp2p-pubsub) | [](https://travis-ci.com/libp2p/js-libp2p-pubsub) | [](https://codecov.io/gh/libp2p/js-libp2p-pubsub) | [Vasco Santos](mailto:santos.vasco10@gmail.com) |
|
||||
| [`libp2p-floodsub`](//github.com/libp2p/js-libp2p-floodsub) | [](//github.com/libp2p/js-libp2p-floodsub/releases) | [](https://david-dm.org/libp2p/js-libp2p-floodsub) | [](https://travis-ci.com/libp2p/js-libp2p-floodsub) | [](https://codecov.io/gh/libp2p/js-libp2p-floodsub) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-gossipsub`](//github.com/ChainSafe/gossipsub-js) | [](//github.com/ChainSafe/gossipsub-js/releases) | [](https://david-dm.org/ChainSafe/gossipsub-js) | [](https://travis-ci.com/ChainSafe/gossipsub-js) | [](https://codecov.io/gh/ChainSafe/gossipsub-js) | [Cayman Nava](mailto:caymannava@gmail.com) |
|
||||
| [`libp2p-pubsub`](//github.com/libp2p/js-libp2p-pubsub) | [](//github.com/libp2p/js-libp2p-pubsub/releases) | [](https://david-dm.org/libp2p/js-libp2p-pubsub) | [](https://travis-ci.com/libp2p/js-libp2p-pubsub) | [](https://codecov.io/gh/libp2p/js-libp2p-pubsub) | [Vasco Santos](mailto:santos.vasco10@gmail.com) |
|
||||
| [`libp2p-floodsub`](//github.com/libp2p/js-libp2p-floodsub) | [](//github.com/libp2p/js-libp2p-floodsub/releases) | [](https://david-dm.org/libp2p/js-libp2p-floodsub) | [](https://travis-ci.com/libp2p/js-libp2p-floodsub) | [](https://codecov.io/gh/libp2p/js-libp2p-floodsub) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
|
||||
| [`libp2p-gossipsub`](//github.com/ChainSafe/gossipsub-js) | [](//github.com/ChainSafe/gossipsub-js/releases) | [](https://david-dm.org/ChainSafe/gossipsub-js) | [](https://travis-ci.com/ChainSafe/gossipsub-js) | [](https://codecov.io/gh/ChainSafe/gossipsub-js) | [Cayman Nava](mailto:caymannava@gmail.com) |
|
||||
| **extensions** |
|
||||
| [`libp2p-nat-mgnr`](//github.com/libp2p/js-libp2p-nat-mgnr) | [](//github.com/libp2p/js-libp2p-nat-mgnr/releases) | [](https://david-dm.org/libp2p/js-libp2p-nat-mgnr) | [](https://travis-ci.com/libp2p/js-libp2p-nat-mgnr) | [](https://codecov.io/gh/libp2p/js-libp2p-nat-mgnr) | N/A |
|
||||
| [`libp2p-utils`](//github.com/libp2p/js-libp2p-utils) | [](//github.com/libp2p/js-libp2p-utils/releases) | [](https://david-dm.org/libp2p/js-libp2p-utils) | [](https://travis-ci.com/libp2p/js-libp2p-utils) | [](https://codecov.io/gh/libp2p/js-libp2p-utils) | [Vasco Santos](mailto:santos.vasco10@gmail.com) |
|
||||
| [`libp2p-nat-mgnr`](//github.com/libp2p/js-libp2p-nat-mgnr) | [](//github.com/libp2p/js-libp2p-nat-mgnr/releases) | [](https://david-dm.org/libp2p/js-libp2p-nat-mgnr) | [](https://travis-ci.com/libp2p/js-libp2p-nat-mgnr) | [](https://codecov.io/gh/libp2p/js-libp2p-nat-mgnr) | N/A |
|
||||
| [`libp2p-utils`](//github.com/libp2p/js-libp2p-utils) | [](//github.com/libp2p/js-libp2p-utils/releases) | [](https://david-dm.org/libp2p/js-libp2p-utils) | [](https://travis-ci.com/libp2p/js-libp2p-utils) | [](https://codecov.io/gh/libp2p/js-libp2p-utils) | [Vasco Santos](mailto:santos.vasco10@gmail.com) |
|
||||
|
||||
## Contribute
|
||||
|
||||
|
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](https://github.com/libp2p/js-peer-info) | peerInfo instance (it will be created if not provided) |
|
||||
| [options.peerInfo] | [`PeerInfo`][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` option is not required and will be generated if it is not provided.
|
||||
Note: The [`PeerInfo`][peer-info] 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][] that contains the [PeerId][], Keys and [multiaddrs][multiaddr] of the libp2p Node (optional when using `.create`).
|
||||
- `peerInfo`: instance of [`PeerInfo`][peer-info] that contains the [`PeerId`][peer-id], 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,15 +174,13 @@ 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](https://github.com/libp2p/js-peer-info), [PeerId][peer-id], [multiaddr](https://github.com/multiformats/js-multiaddr), `string` | peer to dial |
|
||||
| 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 |
|
||||
| [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 |
|
||||
|
||||
@ -217,7 +215,7 @@ Dials to another peer in the network and selects a protocol to communicate with
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| peer | [PeerInfo](https://github.com/libp2p/js-peer-info), [PeerId][peer-id], [multiaddr](https://github.com/multiformats/js-multiaddr), `string` | peer to dial |
|
||||
| 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 |
|
||||
| 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 |
|
||||
@ -250,7 +248,7 @@ Attempts to gracefully close an open connection to the given peer. If the connec
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| peer | [PeerInfo](https://github.com/libp2p/js-peer-info), [PeerId][peer-id], [multiaddr](https://github.com/multiformats/js-multiaddr), `string` | peer to hang up |
|
||||
| peer | [`PeerInfo`][peer-info]\|[`PeerId`][peer-id]\|[`Multiaddr`][multiaddr]\|`string` | peer to hang up |
|
||||
|
||||
#### Returns
|
||||
|
||||
@ -321,7 +319,7 @@ Pings a given peer and get the operation's latency.
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| peer | `PeerInfo|PeerId|Multiaddr|string` | peer to ping |
|
||||
| peer | [`PeerInfo`][peer-info]\|[`PeerId`][peer-id]\|[`Multiaddr`][multiaddr]\|`string` | peer to ping |
|
||||
|
||||
#### Returns
|
||||
|
||||
@ -374,7 +372,7 @@ Once a content router succeeds, the iteration will stop. If the DHT is enabled,
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| cid | [`CID`](https://github.com/multiformats/js-cid) | cid to find |
|
||||
| cid | [`CID`][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 |
|
||||
@ -383,7 +381,7 @@ Once a content router succeeds, the iteration will stop. If the DHT is enabled,
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `AsyncIterator<PeerInfo>` | Async iterator for [`PeerInfo`](https://github.com/libp2p/js-peer-info) |
|
||||
| `AsyncIterator<PeerInfo>` | Async iterator for [`PeerInfo`][peer-info] |
|
||||
|
||||
#### Example
|
||||
|
||||
@ -404,7 +402,7 @@ Iterates over all content routers in parallel, in order to notify it is a provid
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| cid | [`CID`](https://github.com/multiformats/js-cid) | cid to provide |
|
||||
| cid | [`CID`][cid] | cid to provide |
|
||||
|
||||
#### Returns
|
||||
|
||||
@ -649,7 +647,7 @@ Enables users to change the value of certain peers in a range of 0 to 1. Peers w
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| peerId | `PeerId` | The peer to set the value for |
|
||||
| peerId | [`PeerId`][peer-id] | The peer to set the value for |
|
||||
| value | `number` | The value of the peer from 0 to 1 |
|
||||
|
||||
#### Returns
|
||||
@ -677,7 +675,7 @@ const peerIdStrings = libp2p.metrics.peers
|
||||
|
||||
### metrics.peers
|
||||
|
||||
An array of `PeerId` strings of each peer currently being tracked.
|
||||
An array of [`PeerId`][peer-id] strings of each peer currently being tracked.
|
||||
|
||||
#### Example
|
||||
|
||||
@ -697,7 +695,7 @@ const protocols = libp2p.metrics.protocols
|
||||
|
||||
### metrics.forPeer
|
||||
|
||||
Returns the [`Stats`](#stats) object for a given `PeerId` if it is being tracked.
|
||||
Returns the [`Stats`](#stats) object for a given [`PeerId`][peer-id] if it is being tracked.
|
||||
|
||||
`libp2p.metrics.forPeer(peerId)`
|
||||
|
||||
@ -705,7 +703,7 @@ Returns the [`Stats`](#stats) object for a given `PeerId` if it is being tracked
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| peerId | `PeerId` | The peer to get stats for |
|
||||
| peerId | [`PeerId`][peer-id] | The peer to get stats for |
|
||||
|
||||
#### Returns
|
||||
|
||||
@ -762,7 +760,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][https://github.com/libp2p/js-peer-info]
|
||||
- `peer`: instance of [`PeerInfo`][peer-info]
|
||||
|
||||
#### A new connection to a peer has been opened
|
||||
|
||||
@ -770,7 +768,7 @@ This event will be triggered anytime a new Connection is established to another
|
||||
|
||||
`libp2p.on('peer:connect', (peer) => {})`
|
||||
|
||||
- `peer`: instance of [PeerInfo][https://github.com/libp2p/js-peer-info]
|
||||
- `peer`: instance of [`PeerInfo`][peer-info]
|
||||
|
||||
#### An existing connection to a peer has been closed
|
||||
|
||||
@ -778,7 +776,7 @@ This event will be triggered anytime we are disconnected from another peer, rega
|
||||
|
||||
`libp2p.on('peer:disconnect', (peer) => {})`
|
||||
|
||||
- `peer`: instance of [PeerInfo][https://github.com/libp2p/js-peer-info]
|
||||
- `peer`: instance of [`PeerInfo`][peer-info]
|
||||
|
||||
## Types
|
||||
|
||||
@ -800,5 +798,8 @@ 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
|
||||
|
178
doc/migrations/v0.26-v0.27.md
Normal file
178
doc/migrations/v0.26-v0.27.md
Normal file
@ -0,0 +1,178 @@
|
||||
# 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
|
@ -1,3 +1,7 @@
|
||||
❗❗Outdated: This example is still not refactored with the `0.27.*` release.
|
||||
WIP on [libp2p/js-libp2p#507](https://github.com/libp2p/js-libp2p/pull/507)
|
||||
======
|
||||
|
||||
# Delegated Routing with Libp2p and IPFS
|
||||
|
||||
This example shows how to use delegated peer and content routing. The [Peer and Content Routing Example](../peer-and-content-routing) focuses
|
||||
|
@ -17,11 +17,9 @@
|
||||
|
||||
"transports",
|
||||
["libp2p/js-libp2p-tcp", "libp2p-tcp"],
|
||||
["libp2p/js-libp2p-utp", "libp2p-utp"],
|
||||
["libp2p/js-libp2p-webrtc-direct", "libp2p-webrtc-direct"],
|
||||
["libp2p/js-libp2p-webrtc-star", "libp2p-webrtc-star"],
|
||||
["libp2p/js-libp2p-websockets", "libp2p-websockets"],
|
||||
["libp2p/js-libp2p-websocket-star", "libp2p-websocket-star"],
|
||||
|
||||
"secure channels",
|
||||
["libp2p/js-libp2p-secio", "libp2p-secio"],
|
||||
@ -34,9 +32,7 @@
|
||||
["libp2p/js-libp2p-bootstrap", "libp2p-bootstrap"],
|
||||
["libp2p/js-libp2p-kad-dht", "libp2p-kad-dht"],
|
||||
["libp2p/js-libp2p-mdns", "libp2p-mdns"],
|
||||
["libp2p/js-libp2p-rendezvous", "libp2p-rendezvous"],
|
||||
["libp2p/js-libp2p-webrtc-star", "libp2p-webrtc-star"],
|
||||
["libp2p/js-libp2p-websocket-star", "libp2p-websocket-star"],
|
||||
|
||||
"content routing",
|
||||
["libp2p/js-libp2p-delegated-content-routing", "libp2p-delegated-content-routing"],
|
||||
|
89
package.json
89
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "libp2p",
|
||||
"version": "0.27.0",
|
||||
"version": "0.27.4",
|
||||
"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": "^1.1.2",
|
||||
"err-code": "^2.0.0",
|
||||
"hashlru": "^2.3.0",
|
||||
"it-all": "^1.0.1",
|
||||
"it-buffer": "^0.1.1",
|
||||
@ -58,15 +58,16 @@
|
||||
"latency-monitor": "~0.2.1",
|
||||
"libp2p-crypto": "^0.17.1",
|
||||
"libp2p-interfaces": "^0.2.3",
|
||||
"libp2p-utils": "^0.1.2",
|
||||
"mafmt": "^7.0.0",
|
||||
"merge-options": "^2.0.0",
|
||||
"moving-average": "^1.0.0",
|
||||
"multiaddr": "^7.2.1",
|
||||
"multistream-select": "^0.15.0",
|
||||
"mutable-proxy": "^1.0.0",
|
||||
"p-any": "^2.1.0",
|
||||
"p-any": "^3.0.0",
|
||||
"p-fifo": "^1.0.0",
|
||||
"p-settle": "^3.1.0",
|
||||
"p-settle": "^4.0.0",
|
||||
"peer-id": "^0.13.4",
|
||||
"peer-info": "^0.17.0",
|
||||
"protons": "^1.0.1",
|
||||
@ -76,13 +77,14 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nodeutils/defaults-deep": "^1.1.0",
|
||||
"abortable-iterator": "^2.1.0",
|
||||
"aegir": "^20.5.1",
|
||||
"abortable-iterator": "^3.0.0",
|
||||
"aegir": "^21.3.0",
|
||||
"chai": "^4.2.0",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"cids": "^0.7.1",
|
||||
"cids": "^0.8.0",
|
||||
"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",
|
||||
@ -98,68 +100,53 @@
|
||||
"libp2p-tcp": "^0.14.1",
|
||||
"libp2p-webrtc-star": "^0.17.0",
|
||||
"libp2p-websockets": "^0.13.1",
|
||||
"nock": "^10.0.6",
|
||||
"nock": "^12.0.0",
|
||||
"p-defer": "^3.0.0",
|
||||
"p-times": "^2.1.0",
|
||||
"p-wait-for": "^3.1.0",
|
||||
"sinon": "^8.1.0",
|
||||
"sinon": "^9.0.0",
|
||||
"streaming-iterables": "^4.1.0",
|
||||
"wrtc": "^0.4.1"
|
||||
},
|
||||
"contributors": [
|
||||
"Aditya Bose <13054902+adbose@users.noreply.github.com>",
|
||||
"Alan Shaw <alan.shaw@protocol.ai>",
|
||||
"Alan Shaw <alan@tableflip.io>",
|
||||
"Alex Potsides <alex@achingbrain.net>",
|
||||
"Andrew Nesbitt <andrewnez@gmail.com>",
|
||||
"Chris Bratlien <chrisbratlien@gmail.com>",
|
||||
"Chris Dostert <chrisdostert@users.noreply.github.com>",
|
||||
"Daijiro Wachi <daijiro.wachi@gmail.com>",
|
||||
"David Dias <daviddias.p@gmail.com>",
|
||||
"Didrik Nordström <didrik.nordstrom@gmail.com>",
|
||||
"Diogo Silva <fsdiogo@gmail.com>",
|
||||
"Dmitriy Ryajov <dryajov@gmail.com>",
|
||||
"Elven <mon.samuel@qq.com>",
|
||||
"Fei Liu <liu.feiwood@gmail.com>",
|
||||
"Florian-Merle <florian.david.merle@gmail.com>",
|
||||
"Friedel Ziegelmayer <dignifiedquire@gmail.com>",
|
||||
"Giovanni T. Parra <fiatjaf@gmail.com>",
|
||||
"Guy Sviry <32539816+guysv@users.noreply.github.com>",
|
||||
"Henrique Dias <hacdias@gmail.com>",
|
||||
"Hugo Dias <mail@hugodias.me>",
|
||||
"Hugo Dias <hugomrdias@gmail.com>",
|
||||
"Irakli Gozalishvili <rfobic@gmail.com>",
|
||||
"Jacob Heun <jacobheun@gmail.com>",
|
||||
"Joel Gustafson <joelg@mit.edu>",
|
||||
"John Rees <johnrees@users.noreply.github.com>",
|
||||
"João Santos <joaosantos15@users.noreply.github.com>",
|
||||
"Kevin Kwok <antimatter15@gmail.com>",
|
||||
"Lars Gierth <lgierth@users.noreply.github.com>",
|
||||
"Maciej Krüger <mkg20001@gmail.com>",
|
||||
"Marcin Tojek <mtojek@users.noreply.github.com>",
|
||||
"Nuno Nogueira <nunofmn@gmail.com>",
|
||||
"Pedro Teixeira <pedro@protocol.ai>",
|
||||
"Vasco Santos <vasco.santos@moxy.studio>",
|
||||
"Alan Shaw <alan@tableflip.io>",
|
||||
"Pedro Teixeira <i@pgte.me>",
|
||||
"RasmusErik Voel Jensen <github@solsort.com>",
|
||||
"Friedel Ziegelmayer <dignifiedquire@gmail.com>",
|
||||
"Maciej Krüger <mkg20001@gmail.com>",
|
||||
"Alex Potsides <alex@achingbrain.net>",
|
||||
"dirkmc <dirkmdev@gmail.com>",
|
||||
"Volker Mische <volker.mische@gmail.com>",
|
||||
"Hugo Dias <mail@hugodias.me>",
|
||||
"Richard Littauer <richard.littauer@gmail.com>",
|
||||
"ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com>",
|
||||
"Andrew Nesbitt <andrewnez@gmail.com>",
|
||||
"Elven <mon.samuel@qq.com>",
|
||||
"Giovanni T. Parra <fiatjaf@gmail.com>",
|
||||
"Ryan Bell <ryan@piing.net>",
|
||||
"Thomas Eizinger <thomas@eizinger.io>",
|
||||
"Henrique Dias <hacdias@gmail.com>",
|
||||
"Kevin Kwok <antimatter15@gmail.com>",
|
||||
"Nuno Nogueira <nunofmn@gmail.com>",
|
||||
"Florian-Merle <florian.david.merle@gmail.com>",
|
||||
"RasmusErik Voel Jensen <github@solsort.com>",
|
||||
"Fei Liu <liu.feiwood@gmail.com>",
|
||||
"Soeren <nikorpoulsen@gmail.com>",
|
||||
"Sönke Hahn <soenkehahn@gmail.com>",
|
||||
"Thomas Eizinger <thomas@eizinger.io>",
|
||||
"Tiago Alves <alvesjtiago@gmail.com>",
|
||||
"Vasco Santos <vasco.santos@moxy.studio>",
|
||||
"Vasco Santos <vasco.santos@ua.pt>",
|
||||
"Volker Mische <volker.mische@gmail.com>",
|
||||
"Dmitriy Ryajov <dryajov@gmail.com>",
|
||||
"Diogo Silva <fsdiogo@gmail.com>",
|
||||
"Didrik Nordström <didrik.nordstrom@gmail.com>",
|
||||
"Yusef Napora <yusef@napora.org>",
|
||||
"Zane Starr <zcstarr@gmail.com>",
|
||||
"a1300 <a1300@users.noreply.github.com>",
|
||||
"dirkmc <dirkmdev@gmail.com>",
|
||||
"Daijiro Wachi <daijiro.wachi@gmail.com>",
|
||||
"Chris Bratlien <chrisbratlien@gmail.com>",
|
||||
"ebinks <elizabethjbinks@gmail.com>",
|
||||
"greenkeeperio-bot <support@greenkeeper.io>",
|
||||
"Cayman <caymannava@gmail.com>",
|
||||
"isan_rivkin <isanrivkin@gmail.com>",
|
||||
"mayerwin <mayerwin@users.noreply.github.com>",
|
||||
"phillmac <phillmac@users.noreply.github.com>",
|
||||
"swedneck <40505480+swedneck@users.noreply.github.com>",
|
||||
"ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com>"
|
||||
"Irakli Gozalishvili <rfobic@gmail.com>",
|
||||
"Joel Gustafson <joelg@mit.edu>"
|
||||
]
|
||||
}
|
||||
|
@ -1,3 +0,0 @@
|
||||
# PDD Test Stories Implementation
|
||||
|
||||
> Implementation of the Compliance tests from https://github.com/libp2p/interop
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
'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')))
|
||||
})
|
||||
})
|
@ -1,98 +0,0 @@
|
||||
'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')))
|
||||
})
|
||||
})
|
@ -1,54 +0,0 @@
|
||||
'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'))
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
@ -1,49 +0,0 @@
|
||||
'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')
|
||||
})
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
@ -1,54 +0,0 @@
|
||||
'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'))
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
@ -1,49 +0,0 @@
|
||||
'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
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
@ -1,42 +0,0 @@
|
||||
'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)
|
||||
})
|
||||
})
|
@ -1,42 +0,0 @@
|
||||
'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)
|
||||
})
|
||||
})
|
@ -10,13 +10,13 @@ const { CircuitRelay: CircuitPB } = require('./protocol')
|
||||
const debug = require('debug')
|
||||
const log = debug('libp2p:circuit')
|
||||
log.error = debug('libp2p:circuit:error')
|
||||
const toConnection = require('libp2p-utils/src/stream-to-ma-conn')
|
||||
|
||||
const { relay: multicodec } = require('./multicodec')
|
||||
const createListener = require('./listener')
|
||||
const { handleCanHop, handleHop, hop } = require('./circuit/hop')
|
||||
const { handleStop } = require('./circuit/stop')
|
||||
const StreamHandler = require('./circuit/stream-handler')
|
||||
const toConnection = require('./stream-to-conn')
|
||||
|
||||
class Circuit {
|
||||
/**
|
||||
|
@ -1,49 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const abortable = require('abortable-iterator')
|
||||
const log = require('debug')('libp2p:circuit:stream')
|
||||
|
||||
// Convert a duplex iterable into a MultiaddrConnection
|
||||
// https://github.com/libp2p/interface-transport#multiaddrconnection
|
||||
module.exports = ({ stream, remoteAddr, localAddr }, options = {}) => {
|
||||
const { sink, source } = stream
|
||||
const maConn = {
|
||||
async sink (source) {
|
||||
if (options.signal) {
|
||||
source = abortable(source, options.signal)
|
||||
}
|
||||
|
||||
try {
|
||||
await sink(source)
|
||||
} catch (err) {
|
||||
// If aborted we can safely ignore
|
||||
if (err.type !== 'aborted') {
|
||||
// If the source errored the socket will already have been destroyed by
|
||||
// toIterable.duplex(). If the socket errored it will already be
|
||||
// destroyed. There's nothing to do here except log the error & return.
|
||||
log(err)
|
||||
}
|
||||
}
|
||||
close()
|
||||
},
|
||||
|
||||
source: options.signal ? abortable(source, options.signal) : source,
|
||||
conn: stream,
|
||||
localAddr,
|
||||
remoteAddr,
|
||||
timeline: { open: Date.now() },
|
||||
|
||||
close () {
|
||||
sink([])
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
function close () {
|
||||
if (!maConn.timeline.close) {
|
||||
maConn.timeline.close = Date.now()
|
||||
}
|
||||
}
|
||||
|
||||
return maConn
|
||||
}
|
@ -1,11 +1,15 @@
|
||||
'use strict'
|
||||
|
||||
const assert = require('assert')
|
||||
const errcode = require('err-code')
|
||||
const mergeOptions = require('merge-options')
|
||||
const LatencyMonitor = require('latency-monitor').default
|
||||
const debug = require('debug')('libp2p:connection-manager')
|
||||
const retimer = require('retimer')
|
||||
|
||||
const {
|
||||
ERR_INVALID_PARAMETERS
|
||||
} = require('../errors')
|
||||
|
||||
const defaultOptions = {
|
||||
maxConnections: Infinity,
|
||||
minConnections: 0,
|
||||
@ -38,10 +42,9 @@ class ConnectionManager {
|
||||
this._registrar = libp2p.registrar
|
||||
this._peerId = libp2p.peerInfo.id.toB58String()
|
||||
this._options = mergeOptions.call({ ignoreUndefined: true }, defaultOptions, options)
|
||||
assert(
|
||||
this._options.maxConnections > this._options.minConnections,
|
||||
'Connection Manager maxConnections must be greater than minConnections'
|
||||
)
|
||||
if (this._options.maxConnections < this._options.minConnections) {
|
||||
throw errcode(new Error('Connection Manager maxConnections must be greater than minConnections'), ERR_INVALID_PARAMETERS)
|
||||
}
|
||||
|
||||
debug('options: %j', this._options)
|
||||
|
||||
|
@ -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'), 'ERR_NO_DIAL_MULTIADDRS')
|
||||
throw errCode(new Error('The dial request has no addresses'), codes.ERR_NO_VALID_ADDRESSES)
|
||||
}
|
||||
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'), 'ERR_ALREADY_ABORTED')
|
||||
if (options.signal.aborted) throw errCode(new Error('already aborted'), codes.ERR_ALREADY_ABORTED)
|
||||
return this.transportManager.dial(addr, options)
|
||||
}
|
||||
|
||||
@ -197,8 +197,7 @@ class Dialer {
|
||||
try {
|
||||
peer = PeerId.createFromCID(peer.getPeerId())
|
||||
} catch (err) {
|
||||
// Couldn't get the PeerId, just use the address
|
||||
return peer
|
||||
throw errCode(new Error('The multiaddr did not contain a valid peer id'), codes.ERR_INVALID_PEER)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ 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',
|
||||
@ -19,6 +20,7 @@ exports.codes = {
|
||||
ERR_HOP_REQUEST_FAILED: 'ERR_HOP_REQUEST_FAILED',
|
||||
ERR_INVALID_KEY: 'ERR_INVALID_KEY',
|
||||
ERR_INVALID_MESSAGE: 'ERR_INVALID_MESSAGE',
|
||||
ERR_INVALID_PARAMETERS: 'ERR_INVALID_PARAMETERS',
|
||||
ERR_INVALID_PEER: 'ERR_INVALID_PEER',
|
||||
ERR_MUXER_UNAVAILABLE: 'ERR_MUXER_UNAVAILABLE',
|
||||
ERR_TIMEOUT: 'ERR_TIMEOUT',
|
||||
|
@ -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 } = require('streaming-iterables')
|
||||
const { collect, take, consume } = require('streaming-iterables')
|
||||
|
||||
const PeerInfo = require('peer-info')
|
||||
const PeerId = require('peer-id')
|
||||
@ -114,7 +114,8 @@ class IdentifyService {
|
||||
protocols: Array.from(this._protocols.keys())
|
||||
}],
|
||||
pb.encode(Message),
|
||||
stream
|
||||
stream,
|
||||
consume
|
||||
)
|
||||
} catch (err) {
|
||||
// Just log errors
|
||||
@ -153,6 +154,7 @@ class IdentifyService {
|
||||
async identify (connection) {
|
||||
const { stream } = await connection.newStream(MULTICODEC_IDENTIFY)
|
||||
const [data] = await pipe(
|
||||
[],
|
||||
stream,
|
||||
lp.decode(),
|
||||
take(1),
|
||||
@ -242,7 +244,8 @@ class IdentifyService {
|
||||
pipe(
|
||||
[message],
|
||||
lp.encode(),
|
||||
stream
|
||||
stream,
|
||||
consume
|
||||
)
|
||||
}
|
||||
|
||||
@ -255,6 +258,7 @@ class IdentifyService {
|
||||
*/
|
||||
async _handlePush ({ connection, stream }) {
|
||||
const [data] = await pipe(
|
||||
[],
|
||||
stream,
|
||||
lp.decode(),
|
||||
take(1),
|
||||
|
@ -478,7 +478,7 @@ class Libp2p extends EventEmitter {
|
||||
let discoveryService
|
||||
|
||||
if (typeof DiscoveryService === 'function') {
|
||||
discoveryService = new DiscoveryService(Object.assign({}, config, { peerInfo: this.peerInfo }))
|
||||
discoveryService = new DiscoveryService(Object.assign({}, config, { peerInfo: this.peerInfo, libp2p: this }))
|
||||
} else {
|
||||
discoveryService = DiscoveryService
|
||||
}
|
||||
@ -504,14 +504,13 @@ class Libp2p extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Libp2p
|
||||
/**
|
||||
* Like `new Libp2p(options)` except it will create a `PeerInfo`
|
||||
* instance if one is not provided in options.
|
||||
* @param {object} options Libp2p configuration options
|
||||
* @returns {Libp2p}
|
||||
*/
|
||||
module.exports.create = async (options = {}) => {
|
||||
Libp2p.create = async function create (options = {}) {
|
||||
if (options.peerInfo) {
|
||||
return new Libp2p(options)
|
||||
}
|
||||
@ -521,3 +520,5 @@ module.exports.create = async (options = {}) => {
|
||||
options.peerInfo = peerInfo
|
||||
return new Libp2p(options)
|
||||
}
|
||||
|
||||
module.exports = Libp2p
|
||||
|
@ -1,6 +1,6 @@
|
||||
'use strict'
|
||||
|
||||
const assert = require('assert')
|
||||
const errcode = require('err-code')
|
||||
const debug = require('debug')
|
||||
const log = debug('libp2p:peer-store')
|
||||
log.error = debug('libp2p:peer-store:error')
|
||||
@ -9,6 +9,9 @@ const { EventEmitter } = require('events')
|
||||
|
||||
const PeerId = require('peer-id')
|
||||
const PeerInfo = require('peer-info')
|
||||
const {
|
||||
ERR_INVALID_PARAMETERS
|
||||
} = require('../errors')
|
||||
|
||||
/**
|
||||
* Responsible for managing known peers, as well as their addresses and metadata
|
||||
@ -46,7 +49,9 @@ class PeerStore extends EventEmitter {
|
||||
* @return {PeerInfo}
|
||||
*/
|
||||
put (peerInfo, options = { silent: false }) {
|
||||
assert(PeerInfo.isPeerInfo(peerInfo), 'peerInfo must be an instance of peer-info')
|
||||
if (!PeerInfo.isPeerInfo(peerInfo)) {
|
||||
throw errcode(new Error('peerInfo must be an instance of peer-info'), ERR_INVALID_PARAMETERS)
|
||||
}
|
||||
|
||||
let peer
|
||||
// Already know the peer?
|
||||
@ -67,7 +72,9 @@ class PeerStore extends EventEmitter {
|
||||
* @return {PeerInfo}
|
||||
*/
|
||||
add (peerInfo) {
|
||||
assert(PeerInfo.isPeerInfo(peerInfo), 'peerInfo must be an instance of peer-info')
|
||||
if (!PeerInfo.isPeerInfo(peerInfo)) {
|
||||
throw errcode(new Error('peerInfo must be an instance of peer-info'), ERR_INVALID_PARAMETERS)
|
||||
}
|
||||
|
||||
// Create new instance and add values to it
|
||||
const newPeerInfo = new PeerInfo(peerInfo.id)
|
||||
@ -105,7 +112,10 @@ class PeerStore extends EventEmitter {
|
||||
* @return {PeerInfo}
|
||||
*/
|
||||
update (peerInfo) {
|
||||
assert(PeerInfo.isPeerInfo(peerInfo), 'peerInfo must be an instance of peer-info')
|
||||
if (!PeerInfo.isPeerInfo(peerInfo)) {
|
||||
throw errcode(new Error('peerInfo must be an instance of peer-info'), ERR_INVALID_PARAMETERS)
|
||||
}
|
||||
|
||||
const id = peerInfo.id.toB58String()
|
||||
const recorded = this.peers.get(id)
|
||||
|
||||
@ -207,7 +217,9 @@ class PeerStore extends EventEmitter {
|
||||
* @returns {void}
|
||||
*/
|
||||
replace (peerInfo) {
|
||||
assert(PeerInfo.isPeerInfo(peerInfo), 'peerInfo must be an instance of peer-info')
|
||||
if (!PeerInfo.isPeerInfo(peerInfo)) {
|
||||
throw errcode(new Error('peerInfo must be an instance of peer-info'), ERR_INVALID_PARAMETERS)
|
||||
}
|
||||
|
||||
this.remove(peerInfo.id.toB58String())
|
||||
this.add(peerInfo)
|
||||
@ -224,12 +236,17 @@ class PeerStore extends EventEmitter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the known multiaddrs for a given `PeerInfo`
|
||||
* Returns the known multiaddrs for a given `PeerInfo`. All returned multiaddrs
|
||||
* will include the encapsulated `PeerId` of the peer.
|
||||
* @param {PeerInfo} peer
|
||||
* @returns {Array<Multiaddr>}
|
||||
*/
|
||||
multiaddrsForPeer (peer) {
|
||||
return this.put(peer, true).multiaddrs.toArray()
|
||||
return this.put(peer, true).multiaddrs.toArray().map(addr => {
|
||||
const idString = addr.getPeerId()
|
||||
if (idString && idString === peer.id.toB58String()) return addr
|
||||
return addr.encapsulate(`/p2p/${peer.id.toB58String()}`)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 } = require('streaming-iterables')
|
||||
const { collect, take } = require('streaming-iterables')
|
||||
|
||||
const { PROTOCOL, PING_LENGTH } = require('./constants')
|
||||
|
||||
@ -29,6 +29,7 @@ async function ping (node, peer) {
|
||||
const [result] = await pipe(
|
||||
[data],
|
||||
stream,
|
||||
stream => take(1, stream),
|
||||
toBuffer,
|
||||
collect
|
||||
)
|
||||
|
@ -1,10 +1,13 @@
|
||||
'use strict'
|
||||
|
||||
const pipe = require('it-pipe')
|
||||
const assert = require('assert')
|
||||
const errcode = require('err-code')
|
||||
const duplexPair = require('it-pair/duplex')
|
||||
const crypto = require('libp2p-crypto')
|
||||
const Errors = require('./errors')
|
||||
const {
|
||||
ERR_INVALID_PARAMETERS
|
||||
} = require('../errors')
|
||||
const {
|
||||
createBoxStream,
|
||||
createUnboxStream,
|
||||
@ -40,7 +43,9 @@ class Protector {
|
||||
* @returns {*} A protected duplex iterable
|
||||
*/
|
||||
async protect (connection) {
|
||||
assert(connection, Errors.NO_HANDSHAKE_CONNECTION)
|
||||
if (!connection) {
|
||||
throw errcode(new Error(Errors.NO_HANDSHAKE_CONNECTION), ERR_INVALID_PARAMETERS)
|
||||
}
|
||||
|
||||
// Exchange nonces
|
||||
log('protecting the connection')
|
||||
|
@ -1,10 +1,13 @@
|
||||
'use strict'
|
||||
|
||||
const assert = require('assert')
|
||||
const debug = require('debug')
|
||||
const errcode = require('err-code')
|
||||
const log = debug('libp2p:peer-store')
|
||||
log.error = debug('libp2p:peer-store:error')
|
||||
|
||||
const {
|
||||
ERR_INVALID_PARAMETERS
|
||||
} = require('./errors')
|
||||
const Topology = require('libp2p-interfaces/src/topology')
|
||||
const { Connection } = require('libp2p-interfaces/src/connection')
|
||||
const PeerInfo = require('peer-info')
|
||||
@ -71,8 +74,13 @@ class Registrar {
|
||||
* @returns {void}
|
||||
*/
|
||||
onConnect (peerInfo, conn) {
|
||||
assert(PeerInfo.isPeerInfo(peerInfo), 'peerInfo must be an instance of peer-info')
|
||||
assert(Connection.isConnection(conn), 'conn must be an instance of interface-connection')
|
||||
if (!PeerInfo.isPeerInfo(peerInfo)) {
|
||||
throw errcode(new Error('peerInfo must be an instance of peer-info'), ERR_INVALID_PARAMETERS)
|
||||
}
|
||||
|
||||
if (!Connection.isConnection(conn)) {
|
||||
throw errcode(new Error('conn must be an instance of interface-connection'), ERR_INVALID_PARAMETERS)
|
||||
}
|
||||
|
||||
const id = peerInfo.id.toB58String()
|
||||
const storedConn = this.connections.get(id)
|
||||
@ -93,7 +101,9 @@ class Registrar {
|
||||
* @returns {void}
|
||||
*/
|
||||
onDisconnect (peerInfo, connection, error) {
|
||||
assert(PeerInfo.isPeerInfo(peerInfo), 'peerInfo must be an instance of peer-info')
|
||||
if (!PeerInfo.isPeerInfo(peerInfo)) {
|
||||
throw errcode(new Error('peerInfo must be an instance of peer-info'), ERR_INVALID_PARAMETERS)
|
||||
}
|
||||
|
||||
const id = peerInfo.id.toB58String()
|
||||
let storedConn = this.connections.get(id)
|
||||
@ -116,7 +126,9 @@ class Registrar {
|
||||
* @returns {Connection}
|
||||
*/
|
||||
getConnection (peerInfo) {
|
||||
assert(PeerInfo.isPeerInfo(peerInfo), 'peerInfo must be an instance of peer-info')
|
||||
if (!PeerInfo.isPeerInfo(peerInfo)) {
|
||||
throw errcode(new Error('peerInfo must be an instance of peer-info'), ERR_INVALID_PARAMETERS)
|
||||
}
|
||||
|
||||
const connections = this.connections.get(peerInfo.id.toB58String())
|
||||
// Return the first, open connection
|
||||
@ -132,9 +144,9 @@ class Registrar {
|
||||
* @return {string} registrar identifier
|
||||
*/
|
||||
register (topology) {
|
||||
assert(
|
||||
Topology.isTopology(topology),
|
||||
'topology must be an instance of interfaces/topology')
|
||||
if (!Topology.isTopology(topology)) {
|
||||
throw errcode(new Error('topology must be an instance of interfaces/topology'), ERR_INVALID_PARAMETERS)
|
||||
}
|
||||
|
||||
// Create topology
|
||||
const id = (parseInt(Math.random() * 1e9)).toString(36) + Date.now()
|
||||
|
@ -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(stream, protocol)
|
||||
connection.addStream(muxedStream, { protocol })
|
||||
this._onStream({ connection, stream, protocol })
|
||||
} catch (err) {
|
||||
log.error(err)
|
||||
|
@ -43,7 +43,7 @@ describe('DHT subsystem operates correctly', () => {
|
||||
remoteLibp2p.start()
|
||||
])
|
||||
|
||||
remAddr = remoteLibp2p.transportManager.getAddrs()[0]
|
||||
remAddr = libp2p.peerStore.multiaddrsForPeer(remotePeerInfo)[0]
|
||||
})
|
||||
|
||||
afterEach(() => Promise.all([
|
||||
@ -98,7 +98,7 @@ describe('DHT subsystem operates correctly', () => {
|
||||
await libp2p.start()
|
||||
await remoteLibp2p.start()
|
||||
|
||||
remAddr = remoteLibp2p.transportManager.getAddrs()[0]
|
||||
remAddr = libp2p.peerStore.multiaddrsForPeer(remotePeerInfo)[0]
|
||||
})
|
||||
|
||||
afterEach(() => Promise.all([
|
||||
|
@ -6,9 +6,11 @@ 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
|
||||
@ -32,4 +34,40 @@ 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,20 +34,25 @@ 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')
|
||||
const unsupportedAddr = multiaddr('/ip4/127.0.0.1/tcp/9999/ws/p2p/QmckxVrJw1Yo8LqvmDJNUmdAsKtSbiKWmrXJFyKmUraBoN')
|
||||
|
||||
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
|
||||
@ -56,7 +61,7 @@ describe('Dialing (direct, TCP)', () => {
|
||||
|
||||
await remoteTM.listen([listenAddr])
|
||||
|
||||
remoteAddr = remoteTM.getAddrs()[0]
|
||||
remoteAddr = remoteTM.getAddrs()[0].encapsulate(`/p2p/${remotePeerId.toB58String()}`)
|
||||
})
|
||||
|
||||
after(() => remoteTM.close())
|
||||
@ -66,7 +71,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 })
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
|
||||
const connection = await dialer.connectToPeer(remoteAddr)
|
||||
expect(connection).to.exist()
|
||||
@ -74,7 +79,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 })
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
|
||||
const dialable = Dialer.getDialable(remoteAddr.toString())
|
||||
const connection = await dialer.connectToPeer(dialable)
|
||||
@ -83,7 +88,7 @@ describe('Dialing (direct, TCP)', () => {
|
||||
})
|
||||
|
||||
it('should fail to connect to an unsupported multiaddr', async () => {
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
|
||||
await expect(dialer.connectToPeer(unsupportedAddr))
|
||||
.to.eventually.be.rejectedWith(AggregateError)
|
||||
@ -140,6 +145,7 @@ 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) => {
|
||||
@ -224,7 +230,7 @@ describe('Dialing (direct, TCP)', () => {
|
||||
remoteLibp2p.handle('/echo/1.0.0', ({ stream }) => pipe(stream, stream))
|
||||
|
||||
await remoteLibp2p.start()
|
||||
remoteAddr = remoteLibp2p.transportManager.getAddrs()[0]
|
||||
remoteAddr = remoteLibp2p.transportManager.getAddrs()[0].encapsulate(`/p2p/${remotePeerId.toB58String()}`)
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
@ -235,6 +241,28 @@ 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,
|
||||
@ -267,10 +295,8 @@ 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(remotePeer)
|
||||
const connection = await libp2p.dial(remotePeerInfo)
|
||||
expect(connection).to.exist()
|
||||
const { stream, protocol } = await connection.newStream('/echo/1.0.0')
|
||||
expect(stream).to.exist()
|
||||
@ -306,7 +332,7 @@ describe('Dialing (direct, TCP)', () => {
|
||||
}
|
||||
})
|
||||
|
||||
const connection = await libp2p.dial(`${remoteAddr.toString()}/p2p/${remotePeerInfo.id.toB58String()}`)
|
||||
const connection = await libp2p.dial(`${remoteAddr.toString()}`)
|
||||
expect(connection).to.exist()
|
||||
expect(connection.stat.timeline.close).to.not.exist()
|
||||
await libp2p.hangUp(connection.remotePeer)
|
||||
@ -337,33 +363,6 @@ 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,
|
||||
@ -405,10 +404,9 @@ 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(fullAddress)
|
||||
return libp2p.dial(remoteAddr)
|
||||
}))
|
||||
|
||||
// All should succeed and we should have ten results
|
||||
|
@ -21,6 +21,7 @@ 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')
|
||||
|
||||
@ -29,13 +30,15 @@ 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')
|
||||
const unsupportedAddr = multiaddr('/ip4/127.0.0.1/tcp/9999/ws/p2p/QmckxVrJw1Yo8LqvmDJNUmdAsKtSbiKWmrXJFyKmUraBoN')
|
||||
const remoteAddr = MULTIADDRS_WEBSOCKETS[0]
|
||||
|
||||
describe('Dialing (direct, WebSockets)', () => {
|
||||
let localTM
|
||||
let peerStore
|
||||
|
||||
before(() => {
|
||||
peerStore = new PeerStore()
|
||||
localTM = new TransportManager({
|
||||
libp2p: {},
|
||||
upgrader: mockUpgrader,
|
||||
@ -49,13 +52,13 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
})
|
||||
|
||||
it('should have appropriate defaults', () => {
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
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 })
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
const maxPerPeer = Constants.MAX_PER_PEER_DIALS
|
||||
expect(dialer.tokens).to.have.length(Constants.MAX_PARALLEL_DIALS)
|
||||
const tokens = dialer.getTokens(maxPerPeer + 1)
|
||||
@ -64,14 +67,14 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
})
|
||||
|
||||
it('should not return tokens if non are left', () => {
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
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 })
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
const tokens = dialer.getTokens(1)
|
||||
expect(tokens).to.have.length(1)
|
||||
expect(dialer.tokens).to.have.length(Constants.MAX_PARALLEL_DIALS - 1)
|
||||
@ -107,7 +110,7 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
})
|
||||
|
||||
it('should fail to connect to an unsupported multiaddr', async () => {
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
|
||||
await expect(dialer.connectToPeer(unsupportedAddr))
|
||||
.to.eventually.be.rejectedWith(AggregateError)
|
||||
|
@ -123,11 +123,10 @@ 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)
|
||||
@ -142,16 +141,15 @@ 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}/p2p/${relayIdString}`)])
|
||||
await dstLibp2p.transportManager.listen([multiaddr(`/p2p-circuit${relayAddr}`)])
|
||||
expect(dstLibp2p.transportManager.getAddrs()).to.have.deep.members([...tcpAddrs, dialAddr.decapsulate('p2p')])
|
||||
|
||||
// Tamper with the our multiaddrs for the circuit message
|
||||
|
@ -12,6 +12,7 @@ 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')
|
||||
@ -203,16 +204,17 @@ describe('Identify', () => {
|
||||
})
|
||||
|
||||
sinon.spy(libp2p.identifyService, 'identify')
|
||||
sinon.spy(libp2p.peerStore, 'replace')
|
||||
const peerStoreSpy = sinon.spy(libp2p.peerStore, 'replace')
|
||||
|
||||
const connection = await libp2p.dialer.connectToPeer(remoteAddr)
|
||||
expect(connection).to.exist()
|
||||
// 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
|
||||
|
||||
expect(libp2p.peerStore.replace.callCount).to.equal(1)
|
||||
// Wait for peer store to be updated
|
||||
await pWaitFor(() => peerStoreSpy.callCount === 1)
|
||||
expect(libp2p.identifyService.identify.callCount).to.equal(1)
|
||||
|
||||
// The connection should have no open streams
|
||||
expect(connection.streams).to.have.length(0)
|
||||
await connection.close()
|
||||
})
|
||||
|
||||
@ -247,6 +249,9 @@ describe('Identify', () => {
|
||||
const results = await call.returnValue
|
||||
expect(results.length).to.equal(1)
|
||||
}
|
||||
|
||||
// Verify the streams close
|
||||
await pWaitFor(() => connection.streams.length === 0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -139,17 +139,21 @@ describe('peer discovery scenarios', () => {
|
||||
},
|
||||
dht: {
|
||||
randomWalk: {
|
||||
enabled: true,
|
||||
enabled: false,
|
||||
delay: 1000, // start the first query quickly
|
||||
interval: 10000,
|
||||
timeout: 1000
|
||||
timeout: 5000
|
||||
},
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
libp2p = new Libp2p(getConfig(peerInfo))
|
||||
const localConfig = getConfig(peerInfo)
|
||||
// Only run random walk on our local node
|
||||
localConfig.config.dht.randomWalk.enabled = true
|
||||
libp2p = new Libp2p(localConfig)
|
||||
|
||||
const remoteLibp2p1 = new Libp2p(getConfig(remotePeerInfo1))
|
||||
const remoteLibp2p2 = new Libp2p(getConfig(remotePeerInfo2))
|
||||
|
||||
@ -161,6 +165,7 @@ describe('peer discovery scenarios', () => {
|
||||
})
|
||||
|
||||
await Promise.all([
|
||||
libp2p.start(),
|
||||
remoteLibp2p1.start(),
|
||||
remoteLibp2p2.start()
|
||||
])
|
||||
@ -173,8 +178,6 @@ describe('peer discovery scenarios', () => {
|
||||
remoteLibp2p2.dial(remotePeerInfo1)
|
||||
])
|
||||
|
||||
libp2p.start()
|
||||
|
||||
await deferred.promise
|
||||
return Promise.all([
|
||||
remoteLibp2p1.stop(),
|
||||
|
@ -160,6 +160,27 @@ describe('peer-store', () => {
|
||||
expect(removed).to.eql(true)
|
||||
expect(peerStore.peers.size).to.equal(0)
|
||||
})
|
||||
|
||||
it('should be able to get the multiaddrs for a peer', async () => {
|
||||
const [peerInfo, relayInfo] = await peerUtils.createPeerInfo({ number: 2 })
|
||||
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')
|
||||
const ma3 = multiaddr(`/ip4/127.0.0.1/tcp/4003/ws/p2p/${relayInfo.id.toB58String()}/p2p-circuit`)
|
||||
|
||||
peerInfo.multiaddrs.add(ma1)
|
||||
peerInfo.multiaddrs.add(ma2)
|
||||
peerInfo.multiaddrs.add(ma3)
|
||||
|
||||
const multiaddrs = peerStore.multiaddrsForPeer(peerInfo)
|
||||
const expectedAddrs = [
|
||||
ma1.encapsulate(`/p2p/${id.toB58String()}`),
|
||||
ma2.encapsulate(`/p2p/${id.toB58String()}`),
|
||||
ma3.encapsulate(`/p2p/${id.toB58String()}`)
|
||||
]
|
||||
|
||||
expect(multiaddrs).to.eql(expectedAddrs)
|
||||
})
|
||||
})
|
||||
|
||||
describe('peer-store on discovery', () => {
|
||||
|
@ -26,7 +26,6 @@ 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 })
|
||||
@ -73,9 +72,8 @@ 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(remAddr, multicodec)
|
||||
const connection = await libp2p.dialProtocol(remotePeerInfo, multicodec)
|
||||
expect(connection).to.exist()
|
||||
|
||||
libp2p.pubsub.subscribe(topic, (msg) => {
|
||||
|
@ -21,7 +21,6 @@ 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 })
|
||||
@ -44,8 +43,6 @@ describe('Pubsub subsystem operates correctly', () => {
|
||||
libp2p.start(),
|
||||
remoteLibp2p.start()
|
||||
])
|
||||
|
||||
remAddr = remoteLibp2p.transportManager.getAddrs()[0]
|
||||
})
|
||||
|
||||
afterEach(() => Promise.all([
|
||||
@ -58,7 +55,7 @@ describe('Pubsub subsystem operates correctly', () => {
|
||||
})
|
||||
|
||||
it('should get notified of connected peers on dial', async () => {
|
||||
const connection = await libp2p.dialProtocol(remAddr, subsystemMulticodecs)
|
||||
const connection = await libp2p.dialProtocol(remotePeerInfo, subsystemMulticodecs)
|
||||
|
||||
expect(connection).to.exist()
|
||||
|
||||
@ -74,7 +71,7 @@ describe('Pubsub subsystem operates correctly', () => {
|
||||
const data = 'hey!'
|
||||
const libp2pId = libp2p.peerInfo.id.toB58String()
|
||||
|
||||
await libp2p.dialProtocol(remAddr, subsystemMulticodecs)
|
||||
await libp2p.dialProtocol(remotePeerInfo, subsystemMulticodecs)
|
||||
|
||||
let subscribedTopics = libp2p.pubsub.getTopics()
|
||||
expect(subscribedTopics).to.not.include(topic)
|
||||
@ -115,8 +112,6 @@ describe('Pubsub subsystem operates correctly', () => {
|
||||
|
||||
await libp2p.start()
|
||||
await remoteLibp2p.start()
|
||||
|
||||
remAddr = remoteLibp2p.transportManager.getAddrs()[0]
|
||||
})
|
||||
|
||||
afterEach(() => Promise.all([
|
||||
@ -129,7 +124,7 @@ describe('Pubsub subsystem operates correctly', () => {
|
||||
})
|
||||
|
||||
it('should get notified of connected peers after starting', async () => {
|
||||
const connection = await libp2p.dial(remAddr)
|
||||
const connection = await libp2p.dial(remotePeerInfo)
|
||||
|
||||
expect(connection).to.exist()
|
||||
expect(libp2p.pubsub._pubsub.peers.size).to.be.eql(0)
|
||||
@ -150,7 +145,7 @@ describe('Pubsub subsystem operates correctly', () => {
|
||||
const topic = 'test-topic'
|
||||
const data = 'hey!'
|
||||
|
||||
await libp2p.dial(remAddr)
|
||||
await libp2p.dial(remotePeerInfo)
|
||||
|
||||
remoteLibp2p.pubsub.start()
|
||||
|
||||
|
@ -29,7 +29,7 @@ describe('registrar on dial', () => {
|
||||
}))
|
||||
|
||||
await remoteLibp2p.transportManager.listen([listenAddr])
|
||||
remoteAddr = remoteLibp2p.transportManager.getAddrs()[0]
|
||||
remoteAddr = remoteLibp2p.transportManager.getAddrs()[0].encapsulate(`/p2p/${remotePeerInfo.id.toB58String()}`)
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
|
Reference in New Issue
Block a user