Compare commits

...

23 Commits

Author SHA1 Message Date
Vasco Santos
e0597b35b9 chore: release version v0.30.13 2021-08-19 13:28:31 +02:00
Vasco Santos
4e494ad3d5 chore: update contributors 2021-08-19 13:28:30 +02:00
Vasco Santos
356f4f7d48 chore: add uint8array to deps in 0.30.x line 2021-08-19 13:26:47 +02:00
Vasco Santos
8e1743cac4 chore: release version v0.30.12 2021-03-27 13:43:36 +01:00
Vasco Santos
3ea95ce642 chore: update contributors 2021-03-27 13:43:35 +01:00
Alex Potsides
c4cae29ef3 chore: do not look up external IP during test (#906)
The NAT manager test will throw if the current computer is behind a
double NAT as at runtime it won't be possible to map external ports.

We don't care about that during the test so configure a fake external
IP so the test will still test the shut-down functionality on a computer
that is behind a double NAT.
2021-03-27 13:15:35 +01:00
Alex Potsides
a7128f07ec fix: the API of es6-promisify is not the same as promisify-es6 (#905) 2021-03-26 18:13:07 +01:00
Vasco Santos
c3e147df6b chore: delegates config md properties for client (#903) 2021-03-24 09:35:17 +01:00
Vasco Santos
b89445274d chore: release version v0.30.11 2021-03-23 09:51:32 +01:00
Vasco Santos
b9e3bcd91e chore: update contributors 2021-03-23 09:51:32 +01:00
Vasco Santos
f5c1cd1fb0 fix: interface-datastore update 2021-03-23 09:39:28 +01:00
Vasco Santos
975e4b0fe0 chore: increase bundle size 2021-03-23 09:39:28 +01:00
Vasco Santos
9504f1951a fix: connection direction should be only inbound or outbound 2021-03-23 09:39:28 +01:00
Vasco Santos
8e1fc78353 chore: release version v0.30.10 2021-03-09 18:52:37 +01:00
Vasco Santos
8895a092b6 chore: update contributors 2021-03-09 18:52:37 +01:00
TJKoury
f2f361998d chore: swap promisify to maintained package (#896)
Co-authored-by: Vasco Santos <vasco.santos@moxy.studio>
2021-03-09 16:55:38 +01:00
Vasco Santos
5f702f3481 fix: conn mgr access to moving averages record object (#897)
* fix: conn mgr access to moving averages record object

* chore: remove node 12

* chore: add parcel workaround
2021-03-09 16:51:41 +01:00
Philipp Muens
03b34cac7d docs: fix link to connection encryption example (#894) 2021-03-02 13:07:52 +01:00
Aleksei
9c67364caa Add an example of webrtc-direct (#868)
Co-authored-by: Vasco Santos <vasco.santos@moxy.studio>
2021-02-25 16:34:02 +01:00
Vasco Santos
a1424826e7 chore: release version v0.30.9 2021-02-25 15:31:26 +01:00
Vasco Santos
3d5bba070b chore: update contributors 2021-02-25 15:31:26 +01:00
Vasco Santos
3f314d5e90 fix: transport manager fault tolerance should include tolerance to transport listen fail (#893) 2021-02-25 15:23:07 +01:00
Miguel Mota
4ee3e1973b chore: minor grammar fixes on discovery example (#890) 2021-02-18 11:36:35 +01:00
21 changed files with 474 additions and 49 deletions

View File

@@ -48,7 +48,7 @@ const after = async () => {
}
module.exports = {
bundlesize: { maxSize: '220kB' },
bundlesize: { maxSize: '223kB' },
hooks: {
pre: before,
post: after

View File

@@ -27,7 +27,7 @@ jobs:
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
node: [12, 14]
node: [14]
fail-fast: true
steps:
- uses: actions/checkout@v2
@@ -92,7 +92,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- run: yarn
- run: cd examples && yarn && npm run test -- echo
- run: cd examples && yarn && npm run test -- echo
test-libp2p-in-the-browser-example:
needs: check
runs-on: macos-latest
@@ -135,3 +135,10 @@ jobs:
- uses: actions/checkout@v2
- run: yarn
- run: cd examples && yarn && npm run test -- transports
test-webrtc-direct-example:
needs: check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: yarn
- run: cd examples && yarn && npm run test -- webrtc-direct

View File

@@ -1,3 +1,44 @@
## [0.30.13](https://github.com/libp2p/js-libp2p/compare/v0.30.12...v0.30.13) (2021-08-19)
## [0.30.12](https://github.com/libp2p/js-libp2p/compare/v0.30.11...v0.30.12) (2021-03-27)
### Bug Fixes
* the API of es6-promisify is not the same as promisify-es6 ([#905](https://github.com/libp2p/js-libp2p/issues/905)) ([a7128f0](https://github.com/libp2p/js-libp2p/commit/a7128f07ec8d4b729145ecfc6ad1d585ffddea46))
## [0.30.11](https://github.com/libp2p/js-libp2p/compare/v0.30.10...v0.30.11) (2021-03-23)
### Bug Fixes
* connection direction should be only inbound or outbound ([9504f19](https://github.com/libp2p/js-libp2p/commit/9504f1951a3cca55bb7b4e25e4934e4024034ee8))
* interface-datastore update ([f5c1cd1](https://github.com/libp2p/js-libp2p/commit/f5c1cd1fb07bc73cf9d9da3c2eb4327bed4279a4))
## [0.30.10](https://github.com/libp2p/js-libp2p/compare/v0.30.9...v0.30.10) (2021-03-09)
### Bug Fixes
* conn mgr access to moving averages record object ([#897](https://github.com/libp2p/js-libp2p/issues/897)) ([5f702f3](https://github.com/libp2p/js-libp2p/commit/5f702f3481afd4ad4fbc89f0e9b75a6d56b03520))
## [0.30.9](https://github.com/libp2p/js-libp2p/compare/v0.30.8...v0.30.9) (2021-02-25)
### Bug Fixes
* transport manager fault tolerance should include tolerance to transport listen fail ([#893](https://github.com/libp2p/js-libp2p/issues/893)) ([3f314d5](https://github.com/libp2p/js-libp2p/commit/3f314d5e90f74583b721386d0c9c5d8363cd4de7))
## [0.30.8](https://github.com/libp2p/js-libp2p/compare/v0.30.7...v0.30.8) (2021-02-11)

View File

@@ -400,13 +400,13 @@ const PeerId = require('peer-id')
const peerId = await PeerId.create()
const delegatedPeerRouting = new DelegatedPeerRouter(ipfsHttpClient({
host: 'node0.delegate.ipfs.io' // In production you should setup your own delegates
host: 'node0.delegate.ipfs.io', // In production you should setup your own delegates
protocol: 'https',
port: 443
}))
const delegatedContentRouting = new DelegatedContentRouter(peerId, ipfsHttpClient({
host: 'node0.delegate.ipfs.io' // In production you should setup your own delegates
host: 'node0.delegate.ipfs.io', // In production you should setup your own delegates
protocol: 'https',
port: 443
}))

View File

@@ -8,7 +8,7 @@ Let us know if you find any issues, or if you want to contribute and add a new t
- [Transports](./transports)
- [Protocol and Stream Muxing](./protocol-and-stream-muxing)
- [Encrypted Communications](./encrypted-communications)
- [Connection Encryption](./connection-encryption)
- [Discovery Mechanisms](./discovery-mechanisms)
- [Peer and Content Routing](./peer-and-content-routing)
- [PubSub](./pubsub)

View File

@@ -2,13 +2,13 @@
A Peer Discovery module enables libp2p to find peers to connect to. Think of these mechanisms as ways to join the rest of the network, as railing points.
With these system, a libp2p node can both have a set of nodes to always connect on boot (bootstraper nodes), discover nodes through locality (e.g connected in the same LAN) or through serendipity (random walks on a DHT).
With this system, a libp2p node can both have a set of nodes to always connect on boot (bootstraper nodes), discover nodes through locality (e.g connected in the same LAN) or through serendipity (random walks on a DHT).
These mechanisms save configuration and enable a node to operate without any explicit dials, it will just work. Once new peers are discovered, their known data is stored in the peer's PeerStore.
## 1. Bootstrap list of Peers when booting a node
For this demo, we will connect to IPFS default bootstrapper nodes and so, we will need to support the same set of features those nodes have, that are: TCP, mplex and NOISE. You can see the complete example at [1.js](./1.js).
For this demo, we will connect to IPFS default bootstrapper nodes and so, we will need to support the same set of features those nodes have, that are: TCP, mplex, and NOISE. You can see the complete example at [1.js](./1.js).
First, we create our libp2p node.
@@ -16,7 +16,7 @@ First, we create our libp2p node.
const Libp2p = require('libp2p')
const Bootstrap = require('libp2p-bootstrap')
const node = Libp2p.create({
const node = await Libp2p.create({
modules: {
transport: [ TCP ],
streamMuxer: [ Mplex ],
@@ -203,7 +203,7 @@ const createNode = async (bootstrapers) => {
}
```
We will use the `libp2p-relay-server` as bootstrap nodes for the libp2p nodes, so that they establish a connection with the relay after starting. As a result, after they establish a connection with the relay, the pubsub discovery will kick in an the relay will advertise them.
We will use the `libp2p-relay-server` as bootstrap nodes for the libp2p nodes, so that they establish a connection with the relay after starting. As a result, after they establish a connection with the relay, the pubsub discovery will kick in and the relay will advertise them.
```js
const relay = await createRelayServer({
@@ -254,5 +254,5 @@ This is really useful when running libp2p in constrained environments like a bro
There are plenty more Peer Discovery Mechanisms out there, you can:
- Find one in [libp2p-webrtc-star](https://github.com/libp2p/js-libp2p-webrtc-star). Yes, a transport with discovery capabilities! This happens because WebRTC requires a rendezvous point for peers to exchange [SDP](https://tools.ietf.org/html/rfc4317) offer, which means we have one or more points that can introduce peers to each other. Think of it as MulticastDNS for the Web, as in MulticastDNS only works in LAN.
- Any DHT will offer you a discovery capability. You can simple _random-walk_ the routing tables to find other peers to connect to. For example [libp2p-kad-dht](https://github.com/libp2p/js-libp2p-kad-dht) can be used for peer discovery. An example how to configure it to enable random walks can be found [here](https://github.com/libp2p/js-libp2p/blob/v0.28.4/doc/CONFIGURATION.md#customizing-dht).
- Any DHT will offer you a discovery capability. You can simple _random-walk_ the routing tables to find other peers to connect to. For example [libp2p-kad-dht](https://github.com/libp2p/js-libp2p-kad-dht) can be used for peer discovery. An example of how to configure it to enable random walks can be found [here](https://github.com/libp2p/js-libp2p/blob/v0.28.4/doc/CONFIGURATION.md#customizing-dht).
- You can create your own Discovery service, a registry, a list, a radio beacon, you name it!

View File

@@ -15,7 +15,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"@babel/preset-env": "^7.8.3",
"@babel/preset-env": "^7.13.0",
"libp2p": "../../",
"libp2p-bootstrap": "^0.12.1",
"libp2p-mplex": "^0.10.0",
@@ -24,11 +24,11 @@
"libp2p-websockets": "^0.14.0"
},
"devDependencies": {
"@babel/cli": "^7.8.3",
"@babel/core": "^7.8.3",
"@babel/cli": "^7.13.10",
"@babel/core": "^7.13.0",
"babel-plugin-syntax-async-functions": "^6.13.0",
"babel-plugin-transform-regenerator": "^6.26.0",
"babel-polyfill": "^6.26.0",
"parcel-bundler": "^1.12.4"
"parcel-bundler": "1.12.3"
}
}

View File

@@ -0,0 +1,33 @@
### Webrtc-direct example
An example that uses [js-libp2p-webrtc-direct](https://github.com/libp2p/js-libp2p-webrtc-direct) for connecting
nodejs libp2p and browser libp2p clients. To run the example:
## 0. Run a nodejs libp2p listener
When in the root folder of this example, type `node listener.js` in terminal. You should see an address that listens for
incoming connections. Below is just an example of such address. In your case the suffix hash (`peerId`) will be different.
```bash
$ node listener.js
Listening on:
/ip4/127.0.0.1/tcp/9090/http/p2p-webrtc-direct/p2p/QmUKQCzEUhhhobcNSrXU5uzxTqbvF1BjMCGNGZzZU14Kgd
```
## 1. Prepare a browser libp2p dialer
Confirm that the above address is the same as the field `list` in `public/dialer.js`:
```js
peerDiscovery: {
[Bootstrap.tag]: {
enabled: true,
// paste the address into `list`
list: ['/ip4/127.0.0.1/tcp/9090/http/p2p-webrtc-direct/p2p/QmUKQCzEUhhhobcNSrXU5uzxTqbvF1BjMCGNGZzZU14Kgd']
}
}
```
## 2. Run a browser libp2p dialer
When in the root folder of this example, type `npm run dev` in terminal. You should see an address where you can browse
the running client. Open this address in your browser. In console
logs you should see logs about successful connection with the node client. In the output of node client you should see
a log message about successful connection as well.

View File

@@ -0,0 +1,57 @@
import 'babel-polyfill'
const Libp2p = require('libp2p')
const WebRTCDirect = require('libp2p-webrtc-direct')
const Mplex = require('libp2p-mplex')
const {NOISE} = require('libp2p-noise')
const Bootstrap = require('libp2p-bootstrap')
document.addEventListener('DOMContentLoaded', async () => {
// use the same peer id as in `listener.js` to avoid copy-pasting of listener's peer id into `peerDiscovery`
const hardcodedPeerId = '12D3KooWCuo3MdXfMgaqpLC5Houi1TRoFqgK9aoxok4NK5udMu8m'
const libp2p = await Libp2p.create({
modules: {
transport: [WebRTCDirect],
streamMuxer: [Mplex],
connEncryption: [NOISE],
peerDiscovery: [Bootstrap]
},
config: {
peerDiscovery: {
[Bootstrap.tag]: {
enabled: true,
list: [`/ip4/127.0.0.1/tcp/9090/http/p2p-webrtc-direct/p2p/${hardcodedPeerId}`]
}
}
}
})
const status = document.getElementById('status')
const output = document.getElementById('output')
output.textContent = ''
function log (txt) {
console.info(txt)
output.textContent += `${txt.trim()}\n`
}
// Listen for new peers
libp2p.on('peer:discovery', (peerId) => {
log(`Found peer ${peerId.toB58String()}`)
})
// Listen for new connections to peers
libp2p.connectionManager.on('peer:connect', (connection) => {
log(`Connected to ${connection.remotePeer.toB58String()}`)
})
// Listen for peers disconnecting
libp2p.connectionManager.on('peer:disconnect', (connection) => {
log(`Disconnected from ${connection.remotePeer.toB58String()}`)
})
await libp2p.start()
status.innerText = 'libp2p started!'
log(`libp2p id is ${libp2p.peerId.toB58String()}`)
})

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js-libp2p parcel.js browser example</title>
</head>
<body>
<header>
<h1 id="status">Starting libp2p...</h1>
</header>
<main>
<pre id="output"></pre>
</main>
<script src="./dialer.js"></script>
</body>
</html>

View File

@@ -0,0 +1,44 @@
const Libp2p = require('libp2p')
const Bootstrap = require('libp2p-bootstrap')
const WebRTCDirect = require('libp2p-webrtc-direct')
const Mplex = require('libp2p-mplex')
const {NOISE} = require('libp2p-noise')
const PeerId = require('peer-id')
;(async () => {
// hardcoded peer id to avoid copy-pasting of listener's peer id into the dialer's bootstrap list
// generated with cmd `peer-id --type=ed25519`
const hardcodedPeerId = await PeerId.createFromJSON({
"id": "12D3KooWCuo3MdXfMgaqpLC5Houi1TRoFqgK9aoxok4NK5udMu8m",
"privKey": "CAESQAG6Ld7ev6nnD0FKPs033/j0eQpjWilhxnzJ2CCTqT0+LfcWoI2Vr+zdc1vwk7XAVdyoCa2nwUR3RJebPWsF1/I=",
"pubKey": "CAESIC33FqCNla/s3XNb8JO1wFXcqAmtp8FEd0SXmz1rBdfy"
})
const node = await Libp2p.create({
peerId: hardcodedPeerId,
addresses: {
listen: ['/ip4/127.0.0.1/tcp/9090/http/p2p-webrtc-direct']
},
modules: {
transport: [WebRTCDirect],
streamMuxer: [Mplex],
connEncryption: [NOISE]
},
config: {
peerDiscovery: {
[Bootstrap.tag]: {
enabled: false,
}
}
}
})
node.connectionManager.on('peer:connect', (connection) => {
console.info(`Connected to ${connection.remotePeer.toB58String()}!`)
})
await node.start()
console.log('Listening on:')
node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`))
})()

View File

@@ -0,0 +1,31 @@
{
"name": "webrtc-direct",
"version": "0.0.1",
"private": true,
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "parcel build index.html",
"start": "parcel index.html"
},
"license": "ISC",
"devDependencies": {
"@babel/cli": "^7.13.10",
"@babel/core": "^7.13.10",
"babel-plugin-syntax-async-functions": "^6.13.0",
"babel-plugin-transform-regenerator": "^6.26.0",
"babel-polyfill": "^6.26.0",
"parcel-bundler": "1.12.3"
},
"dependencies": {
"libp2p": "../../",
"libp2p-bootstrap": "^0.12.1",
"libp2p-mplex": "^0.10.1",
"libp2p-noise": "^2.0.1",
"libp2p-webrtc-direct": "^0.5.0",
"peer-id": "^0.14.3"
},
"browser": {
"ipfs": "ipfs/dist/index.min.js"
}
}

View File

@@ -0,0 +1,93 @@
'use strict'
const path = require('path')
const execa = require('execa')
const pDefer = require('p-defer')
const uint8ArrayToString = require('uint8arrays/to-string')
const { chromium } = require('playwright');
function startNode (name, args = []) {
return execa('node', [path.join(__dirname, name), ...args], {
cwd: path.resolve(__dirname),
all: true
})
}
function startBrowser (name, args = []) {
return execa('parcel', [path.join(__dirname, name), ...args], {
preferLocal: true,
localDir: __dirname,
cwd: __dirname,
all: true
})
}
async function test () {
// Step 1, listener process
const listenerProcReady = pDefer()
let listenerOutput = ''
process.stdout.write('listener.js\n')
const listenerProc = startNode('listener.js')
listenerProc.all.on('data', async (data) => {
process.stdout.write(data)
listenerOutput += uint8ArrayToString(data)
if (listenerOutput.includes('Listening on:') && listenerOutput.includes('12D3KooWCuo3MdXfMgaqpLC5Houi1TRoFqgK9aoxok4NK5udMu8m')) {
listenerProcReady.resolve()
}
})
await listenerProcReady.promise
process.stdout.write('==================================================================\n')
// Step 2, dialer process
process.stdout.write('dialer.js\n')
let dialerUrl = ''
const dialerProc = startBrowser('index.html')
dialerProc.all.on('data', async (chunk) => {
/**@type {string} */
const out = chunk.toString()
if (out.includes('Server running at')) {
dialerUrl = out.replace('Server running at ', '')
}
if (out.includes('✨ Built in ')) {
try {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(dialerUrl);
await page.waitForFunction(selector => document.querySelector(selector).innerText === 'libp2p started!', '#status')
await page.waitForFunction(
selector => {
const text = document.querySelector(selector).innerText
return text.includes('libp2p id is') &&
text.includes('Found peer') &&
text.includes('Connected to')
},
'#output',
{ timeout: 10000 }
)
await browser.close();
} catch (err) {
console.error(err)
process.exit(1)
} finally {
dialerProc.cancel()
listenerProc.kill()
}
}
})
await Promise.all([
listenerProc,
dialerProc,
]).catch((err) => {
if (err.signal !== 'SIGTERM') {
throw err
}
})
}
module.exports = test

View File

@@ -1,6 +1,6 @@
{
"name": "libp2p",
"version": "0.30.8",
"version": "0.30.13",
"description": "JavaScript implementation of libp2p, a modular peer to peer network stack",
"leadMaintainer": "Jacob Heun <jacobheun@gmail.com>",
"main": "src/index.js",
@@ -63,6 +63,7 @@
"class-is": "^1.1.0",
"debug": "^4.3.1",
"err-code": "^2.0.0",
"es6-promisify": "^6.1.1",
"events": "^3.2.0",
"hashlru": "^2.3.0",
"interface-datastore": "^3.0.3",
@@ -97,18 +98,19 @@
"p-settle": "^4.0.1",
"peer-id": "^0.14.2",
"private-ip": "^2.0.0",
"promisify-es6": "^1.0.3",
"protons": "^2.0.0",
"retimer": "^2.0.0",
"sanitize-filename": "^1.6.3",
"set-delayed-interval": "^1.0.0",
"streaming-iterables": "^5.0.2",
"timeout-abort-controller": "^1.1.1",
"uint8arrays": "^2.1.3",
"varint": "^6.0.0",
"xsalsa20": "^1.0.2"
},
"devDependencies": {
"@nodeutils/defaults-deep": "^1.1.0",
"@types/es6-promisify": "^6.0.0",
"abortable-iterator": "^3.0.0",
"aegir": "^29.2.0",
"chai-bytes": "^0.1.2",
@@ -156,43 +158,60 @@
"Hugo Dias <mail@hugodias.me>",
"Volker Mische <volker.mische@gmail.com>",
"dirkmc <dirkmdev@gmail.com>",
"Chris Dostert <chrisdostert@users.noreply.github.com>",
"Richard Littauer <richard.littauer@gmail.com>",
"a1300 <matthias-knopp@gmx.net>",
"Ryan Bell <ryan@piing.net>",
"Andrew Nesbitt <andrewnez@gmail.com>",
"Elven <mon.samuel@qq.com>",
"Giovanni T. Parra <fiatjaf@gmail.com>",
"Samlior <samlior@foxmail.com>",
"Thomas Eizinger <thomas@eizinger.io>",
"Andrew Nesbitt <andrewnez@gmail.com>",
"ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com>",
"Giovanni T. Parra <fiatjaf@gmail.com>",
"Ryan Bell <ryan@piing.net>",
"Thomas Eizinger <thomas@eizinger.io>",
"Samlior <samlior@foxmail.com>",
"acolytec3 <17355484+acolytec3@users.noreply.github.com>",
"Didrik Nordström <didrik@betamos.se>",
"Irakli Gozalishvili <rfobic@gmail.com>",
"Joel Gustafson <joelg@mit.edu>",
"John Rees <johnrees@users.noreply.github.com>",
"João Santos <joaosantos15@users.noreply.github.com>",
"Julien Bouquillon <contact@revolunet.com>",
"Kevin Kwok <antimatter15@gmail.com>",
"Kevin Lacker <lacker@gmail.com>",
"Ethan Lam <elmemphis2000@gmail.com>",
"Lars Gierth <lgierth@users.noreply.github.com>",
"Marcin Tojek <mtojek@users.noreply.github.com>",
"Michael Burns <5170+mburns@users.noreply.github.com>",
"Miguel Mota <miguelmota2@gmail.com>",
"Nuno Nogueira <nunofmn@gmail.com>",
"Dmitriy Ryajov <dryajov@gmail.com>",
"Philipp Muens <raute1337@gmx.de>",
"RasmusErik Voel Jensen <github@solsort.com>",
"Diogo Silva <fsdiogo@gmail.com>",
"Aditya Bose <13054902+adbose@users.noreply.github.com>",
"Smite Chow <xiaopengyou@live.com>",
"Soeren <nikorpoulsen@gmail.com>",
"Sönke Hahn <soenkehahn@gmail.com>",
"TJKoury <TJKoury@gmail.com>",
"Tiago Alves <alvesjtiago@gmail.com>",
"Daijiro Wachi <daijiro.wachi@gmail.com>",
"Yusef Napora <yusef@napora.org>",
"Zane Starr <zcstarr@gmail.com>",
"robertkiel <robert.kiel@validitylabs.org>",
"Cindy Wu <ciindy.wu@gmail.com>",
"Chris Bratlien <chrisbratlien@gmail.com>",
"ebinks <elizabethjbinks@gmail.com>",
"Francis Gulotta <wizard@roborooter.com>",
"Florian-Merle <florian.david.merle@gmail.com>",
"Yusef Napora <yusef@napora.org>",
"Zane Starr <zcstarr@gmail.com>",
"Bernd Strehl <bernd.strehl@gmail.com>",
"Henrique Dias <hacdias@gmail.com>",
"ebinks <elizabethjbinks@gmail.com>",
"Ethan Lam <elmemphis2000@gmail.com>",
"isan_rivkin <isanrivkin@gmail.com>",
"mayerwin <mayerwin@users.noreply.github.com>",
"phillmac <phillmac@users.noreply.github.com>",
"robertkiel <robert.kiel@validitylabs.org>",
"shresthagrawal <34920931+shresthagrawal@users.noreply.github.com>",
"swedneck <40505480+swedneck@users.noreply.github.com>",
"Aleksei <vozhdb@gmail.com>",
"Fei Liu <liu.feiwood@gmail.com>",
"Felipe Martins <felipebrasil93@gmail.com>",
"Fei Liu <liu.feiwood@gmail.com>"
"Florian-Merle <florian.david.merle@gmail.com>",
"Francis Gulotta <wizard@roborooter.com>",
"Dmitriy Ryajov <dryajov@gmail.com>",
"Guy Sviry <32539816+guysv@users.noreply.github.com>",
"Henrique Dias <hacdias@gmail.com>",
"Irakli Gozalishvili <rfobic@gmail.com>",
"Diogo Silva <fsdiogo@gmail.com>",
"Joel Gustafson <joelg@mit.edu>"
]
}

View File

@@ -14,7 +14,7 @@ require('node-forge/lib/sha512')
/**
* @typedef {import('peer-id')} PeerId
* @typedef {import('interface-datastore/src/types').Datastore} Datastore
* @typedef {import('interface-datastore').Datastore} Datastore
*/
const keyPrefix = '/pkcs8/'

View File

@@ -82,7 +82,7 @@ class Stats extends EventEmitter {
/**
* Returns a clone of the internal movingAverages
*
* @returns {MovingAverage}
* @returns {Object}
*/
get movingAverages () {
return Object.assign({}, this._movingAverages)

View File

@@ -2,7 +2,7 @@
const NatAPI = require('@motrix/nat-api')
const debug = require('debug')
const promisify = require('promisify-es6')
const { promisify } = require('es6-promisify')
const Multiaddr = require('multiaddr')
const log = Object.assign(debug('libp2p:nat'), {
error: debug('libp2p:nat:err')
@@ -132,14 +132,32 @@ class NatManager {
}
const client = new NatAPI(this._options)
const map = promisify(client.map, { context: client })
const destroy = promisify(client.destroy, { context: client })
const externalIp = promisify(client.externalIp, { context: client })
/** @type {(...any) => any} */
const map = promisify(client.map.bind(client))
/** @type {(...any) => any} */
const destroy = promisify(client.destroy.bind(client))
/** @type {(...any) => any} */
const externalIp = promisify(client.externalIp.bind(client))
// these are all network operations so add a retry
this._client = {
// these are all network operations so add a retry
/**
* @param {...any} args
* @returns {Promise<void>}
*/
map: (...args) => retry(() => map(...args), { onFailedAttempt: log.error, unref: true }),
/**
* @param {...any} args
* @returns {Promise<void>}
*/
destroy: (...args) => retry(() => destroy(...args), { onFailedAttempt: log.error, unref: true }),
/**
* @param {...any} args
* @returns {Promise<string>}
*/
externalIp: (...args) => retry(() => externalIp(...args), { onFailedAttempt: log.error, unref: true })
}

View File

@@ -196,7 +196,7 @@ class TransportManager {
// listening on remote addresses as they may be offline. We could then potentially
// just wait for any (`p-any`) listener to succeed on each transport before returning
const isListening = results.find(r => r.isFulfilled === true)
if (!isListening) {
if (!isListening && this.faultTolerance !== FAULT_TOLERANCE.NO_FATAL) {
throw errCode(new Error(`Transport (${key}) could not listen on any available address`), codes.ERR_NO_VALID_ADDRESSES)
}
}

View File

@@ -201,7 +201,7 @@ class Upgrader {
* @private
* @param {object} options
* @param {string} options.cryptoProtocol - The crypto protocol that was negotiated
* @param {string} options.direction - One of ['inbound', 'outbound']
* @param {'inbound' | 'outbound'} options.direction - One of ['inbound', 'outbound']
* @param {MultiaddrConnection} options.maConn - The transport layer connection
* @param {MuxedStream | MultiaddrConnection} options.upgradedConn - A duplex connection returned from multiplexer and/or crypto selection
* @param {MuxerFactory} [options.Muxer] - The muxer to be used for muxing

View File

@@ -3,6 +3,7 @@
const { expect } = require('aegir/utils/chai')
const sinon = require('sinon')
const { networkInterfaces } = require('os')
const AddressManager = require('../../src/address-manager')
const TransportManager = require('../../src/transport-manager')
const Transport = require('libp2p-tcp')
@@ -156,7 +157,7 @@ describe('Nat Manager (TCP)', () => {
natManager,
addressManager
} = await createNatManager([
'/ip6/::/tcp/5001'
'/ip6/::/tcp/0'
])
let observed = addressManager.getObservedAddrs().map(ma => ma.toString())
@@ -173,7 +174,7 @@ describe('Nat Manager (TCP)', () => {
natManager,
addressManager
} = await createNatManager([
'/ip6/::1/tcp/5001'
'/ip6/::1/tcp/0'
])
let observed = addressManager.getObservedAddrs().map(ma => ma.toString())
@@ -207,7 +208,7 @@ describe('Nat Manager (TCP)', () => {
natManager,
addressManager
} = await createNatManager([
'/ip4/127.0.0.1/tcp/5900'
'/ip4/127.0.0.1/tcp/0'
])
let observed = addressManager.getObservedAddrs().map(ma => ma.toString())
@@ -224,7 +225,7 @@ describe('Nat Manager (TCP)', () => {
natManager,
addressManager
} = await createNatManager([
'/ip4/0.0.0.0/tcp/5900/sctp/49832'
'/ip4/0.0.0.0/tcp/0/sctp/0'
])
let observed = addressManager.getObservedAddrs().map(ma => ma.toString())
@@ -241,4 +242,50 @@ describe('Nat Manager (TCP)', () => {
new NatManager({ ttl: 5 }) // eslint-disable-line no-new
}).to.throw().with.property('code', ERR_INVALID_PARAMETERS)
})
it('shuts the nat api down when stopping', async function () {
function findRoutableAddress () {
const interfaces = networkInterfaces()
for (const name of Object.keys(interfaces)) {
for (const iface of interfaces[name]) {
// Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
if (iface.family === 'IPv4' && !iface.internal) {
return iface.address
}
}
}
}
const addr = findRoutableAddress()
if (!addr) {
// skip test if no non-loopback address is found
this.skip()
}
const {
natManager
} = await createNatManager([
`/ip4/${addr}/tcp/0`
], {
// so we don't try to look up the current computer's external address
externalIp: '184.12.31.4'
})
// use the actual nat manager client not the stub
delete natManager._client
await natManager._start()
const client = natManager._client
expect(client).to.be.ok()
// ensure the client was stopped
const spy = sinon.spy(client, 'destroy')
await natManager.stop()
expect(spy.called).to.be.true()
})
})

View File

@@ -209,7 +209,7 @@ describe('libp2p.transportManager (dial only)', () => {
throw new Error('it should fail to start if multiaddr fails to listen')
})
it('does not fail to start if multiaddr fails to listen when supporting dial only mode', async () => {
it('does not fail to start if provided listen multiaddr are not compatible to configured transports (when supporting dial only mode)', async () => {
libp2p = new Libp2p({
peerId,
addresses: {
@@ -226,4 +226,22 @@ describe('libp2p.transportManager (dial only)', () => {
await libp2p.start()
})
it('does not fail to start if provided listen multiaddr fail to listen on configured transports (when supporting dial only mode)', async () => {
libp2p = new Libp2p({
peerId,
addresses: {
listen: [multiaddr('/ip4/127.0.0.1/tcp/12345/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3/p2p-circuit')]
},
transportManager: {
faultTolerance: FaultTolerance.NO_FATAL
},
modules: {
transport: [Transport],
connEncryption: [Crypto]
}
})
await libp2p.start()
})
})