mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-07-20 19:11:58 +00:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
e0597b35b9 | ||
|
4e494ad3d5 | ||
|
356f4f7d48 | ||
|
8e1743cac4 | ||
|
3ea95ce642 | ||
|
c4cae29ef3 | ||
|
a7128f07ec | ||
|
c3e147df6b | ||
|
b89445274d | ||
|
b9e3bcd91e | ||
|
f5c1cd1fb0 | ||
|
975e4b0fe0 | ||
|
9504f1951a | ||
|
8e1fc78353 | ||
|
8895a092b6 | ||
|
f2f361998d | ||
|
5f702f3481 | ||
|
03b34cac7d | ||
|
9c67364caa | ||
|
a1424826e7 | ||
|
3d5bba070b | ||
|
3f314d5e90 | ||
|
4ee3e1973b |
@@ -48,7 +48,7 @@ const after = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
bundlesize: { maxSize: '220kB' },
|
bundlesize: { maxSize: '223kB' },
|
||||||
hooks: {
|
hooks: {
|
||||||
pre: before,
|
pre: before,
|
||||||
post: after
|
post: after
|
||||||
|
9
.github/workflows/main.yml
vendored
9
.github/workflows/main.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [windows-latest, ubuntu-latest, macos-latest]
|
os: [windows-latest, ubuntu-latest, macos-latest]
|
||||||
node: [12, 14]
|
node: [14]
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -135,3 +135,10 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: yarn
|
- run: yarn
|
||||||
- run: cd examples && yarn && npm run test -- transports
|
- 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
|
||||||
|
41
CHANGELOG.md
41
CHANGELOG.md
@@ -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)
|
## [0.30.8](https://github.com/libp2p/js-libp2p/compare/v0.30.7...v0.30.8) (2021-02-11)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -400,13 +400,13 @@ const PeerId = require('peer-id')
|
|||||||
const peerId = await PeerId.create()
|
const peerId = await PeerId.create()
|
||||||
|
|
||||||
const delegatedPeerRouting = new DelegatedPeerRouter(ipfsHttpClient({
|
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',
|
protocol: 'https',
|
||||||
port: 443
|
port: 443
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const delegatedContentRouting = new DelegatedContentRouter(peerId, ipfsHttpClient({
|
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',
|
protocol: 'https',
|
||||||
port: 443
|
port: 443
|
||||||
}))
|
}))
|
||||||
|
@@ -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)
|
- [Transports](./transports)
|
||||||
- [Protocol and Stream Muxing](./protocol-and-stream-muxing)
|
- [Protocol and Stream Muxing](./protocol-and-stream-muxing)
|
||||||
- [Encrypted Communications](./encrypted-communications)
|
- [Connection Encryption](./connection-encryption)
|
||||||
- [Discovery Mechanisms](./discovery-mechanisms)
|
- [Discovery Mechanisms](./discovery-mechanisms)
|
||||||
- [Peer and Content Routing](./peer-and-content-routing)
|
- [Peer and Content Routing](./peer-and-content-routing)
|
||||||
- [PubSub](./pubsub)
|
- [PubSub](./pubsub)
|
||||||
|
@@ -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.
|
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.
|
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
|
## 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.
|
First, we create our libp2p node.
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ First, we create our libp2p node.
|
|||||||
const Libp2p = require('libp2p')
|
const Libp2p = require('libp2p')
|
||||||
const Bootstrap = require('libp2p-bootstrap')
|
const Bootstrap = require('libp2p-bootstrap')
|
||||||
|
|
||||||
const node = Libp2p.create({
|
const node = await Libp2p.create({
|
||||||
modules: {
|
modules: {
|
||||||
transport: [ TCP ],
|
transport: [ TCP ],
|
||||||
streamMuxer: [ Mplex ],
|
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
|
```js
|
||||||
const relay = await createRelayServer({
|
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:
|
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.
|
- 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!
|
- You can create your own Discovery service, a registry, a list, a radio beacon, you name it!
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/preset-env": "^7.8.3",
|
"@babel/preset-env": "^7.13.0",
|
||||||
"libp2p": "../../",
|
"libp2p": "../../",
|
||||||
"libp2p-bootstrap": "^0.12.1",
|
"libp2p-bootstrap": "^0.12.1",
|
||||||
"libp2p-mplex": "^0.10.0",
|
"libp2p-mplex": "^0.10.0",
|
||||||
@@ -24,11 +24,11 @@
|
|||||||
"libp2p-websockets": "^0.14.0"
|
"libp2p-websockets": "^0.14.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.8.3",
|
"@babel/cli": "^7.13.10",
|
||||||
"@babel/core": "^7.8.3",
|
"@babel/core": "^7.13.0",
|
||||||
"babel-plugin-syntax-async-functions": "^6.13.0",
|
"babel-plugin-syntax-async-functions": "^6.13.0",
|
||||||
"babel-plugin-transform-regenerator": "^6.26.0",
|
"babel-plugin-transform-regenerator": "^6.26.0",
|
||||||
"babel-polyfill": "^6.26.0",
|
"babel-polyfill": "^6.26.0",
|
||||||
"parcel-bundler": "^1.12.4"
|
"parcel-bundler": "1.12.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
33
examples/webrtc-direct/README.md
Normal file
33
examples/webrtc-direct/README.md
Normal 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.
|
57
examples/webrtc-direct/dialer.js
Normal file
57
examples/webrtc-direct/dialer.js
Normal 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()}`)
|
||||||
|
|
||||||
|
})
|
17
examples/webrtc-direct/index.html
Normal file
17
examples/webrtc-direct/index.html
Normal 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>
|
44
examples/webrtc-direct/listener.js
Normal file
44
examples/webrtc-direct/listener.js
Normal 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()}`))
|
||||||
|
|
||||||
|
})()
|
31
examples/webrtc-direct/package.json
Normal file
31
examples/webrtc-direct/package.json
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
93
examples/webrtc-direct/test.js
Normal file
93
examples/webrtc-direct/test.js
Normal 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
|
59
package.json
59
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "libp2p",
|
"name": "libp2p",
|
||||||
"version": "0.30.8",
|
"version": "0.30.13",
|
||||||
"description": "JavaScript implementation of libp2p, a modular peer to peer network stack",
|
"description": "JavaScript implementation of libp2p, a modular peer to peer network stack",
|
||||||
"leadMaintainer": "Jacob Heun <jacobheun@gmail.com>",
|
"leadMaintainer": "Jacob Heun <jacobheun@gmail.com>",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
@@ -63,6 +63,7 @@
|
|||||||
"class-is": "^1.1.0",
|
"class-is": "^1.1.0",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"err-code": "^2.0.0",
|
"err-code": "^2.0.0",
|
||||||
|
"es6-promisify": "^6.1.1",
|
||||||
"events": "^3.2.0",
|
"events": "^3.2.0",
|
||||||
"hashlru": "^2.3.0",
|
"hashlru": "^2.3.0",
|
||||||
"interface-datastore": "^3.0.3",
|
"interface-datastore": "^3.0.3",
|
||||||
@@ -97,18 +98,19 @@
|
|||||||
"p-settle": "^4.0.1",
|
"p-settle": "^4.0.1",
|
||||||
"peer-id": "^0.14.2",
|
"peer-id": "^0.14.2",
|
||||||
"private-ip": "^2.0.0",
|
"private-ip": "^2.0.0",
|
||||||
"promisify-es6": "^1.0.3",
|
|
||||||
"protons": "^2.0.0",
|
"protons": "^2.0.0",
|
||||||
"retimer": "^2.0.0",
|
"retimer": "^2.0.0",
|
||||||
"sanitize-filename": "^1.6.3",
|
"sanitize-filename": "^1.6.3",
|
||||||
"set-delayed-interval": "^1.0.0",
|
"set-delayed-interval": "^1.0.0",
|
||||||
"streaming-iterables": "^5.0.2",
|
"streaming-iterables": "^5.0.2",
|
||||||
"timeout-abort-controller": "^1.1.1",
|
"timeout-abort-controller": "^1.1.1",
|
||||||
|
"uint8arrays": "^2.1.3",
|
||||||
"varint": "^6.0.0",
|
"varint": "^6.0.0",
|
||||||
"xsalsa20": "^1.0.2"
|
"xsalsa20": "^1.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nodeutils/defaults-deep": "^1.1.0",
|
"@nodeutils/defaults-deep": "^1.1.0",
|
||||||
|
"@types/es6-promisify": "^6.0.0",
|
||||||
"abortable-iterator": "^3.0.0",
|
"abortable-iterator": "^3.0.0",
|
||||||
"aegir": "^29.2.0",
|
"aegir": "^29.2.0",
|
||||||
"chai-bytes": "^0.1.2",
|
"chai-bytes": "^0.1.2",
|
||||||
@@ -156,43 +158,60 @@
|
|||||||
"Hugo Dias <mail@hugodias.me>",
|
"Hugo Dias <mail@hugodias.me>",
|
||||||
"Volker Mische <volker.mische@gmail.com>",
|
"Volker Mische <volker.mische@gmail.com>",
|
||||||
"dirkmc <dirkmdev@gmail.com>",
|
"dirkmc <dirkmdev@gmail.com>",
|
||||||
|
"Chris Dostert <chrisdostert@users.noreply.github.com>",
|
||||||
"Richard Littauer <richard.littauer@gmail.com>",
|
"Richard Littauer <richard.littauer@gmail.com>",
|
||||||
"a1300 <matthias-knopp@gmx.net>",
|
"a1300 <matthias-knopp@gmx.net>",
|
||||||
"Ryan Bell <ryan@piing.net>",
|
|
||||||
"Andrew Nesbitt <andrewnez@gmail.com>",
|
|
||||||
"Elven <mon.samuel@qq.com>",
|
"Elven <mon.samuel@qq.com>",
|
||||||
"Giovanni T. Parra <fiatjaf@gmail.com>",
|
"Andrew Nesbitt <andrewnez@gmail.com>",
|
||||||
"Samlior <samlior@foxmail.com>",
|
|
||||||
"Thomas Eizinger <thomas@eizinger.io>",
|
|
||||||
"ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@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>",
|
"Didrik Nordström <didrik@betamos.se>",
|
||||||
"Irakli Gozalishvili <rfobic@gmail.com>",
|
"John Rees <johnrees@users.noreply.github.com>",
|
||||||
"Joel Gustafson <joelg@mit.edu>",
|
"João Santos <joaosantos15@users.noreply.github.com>",
|
||||||
"Julien Bouquillon <contact@revolunet.com>",
|
"Julien Bouquillon <contact@revolunet.com>",
|
||||||
"Kevin Kwok <antimatter15@gmail.com>",
|
"Kevin Kwok <antimatter15@gmail.com>",
|
||||||
"Kevin Lacker <lacker@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>",
|
"Nuno Nogueira <nunofmn@gmail.com>",
|
||||||
"Dmitriy Ryajov <dryajov@gmail.com>",
|
"Philipp Muens <raute1337@gmx.de>",
|
||||||
"RasmusErik Voel Jensen <github@solsort.com>",
|
"RasmusErik Voel Jensen <github@solsort.com>",
|
||||||
"Diogo Silva <fsdiogo@gmail.com>",
|
"Aditya Bose <13054902+adbose@users.noreply.github.com>",
|
||||||
"Smite Chow <xiaopengyou@live.com>",
|
"Smite Chow <xiaopengyou@live.com>",
|
||||||
"Soeren <nikorpoulsen@gmail.com>",
|
"Soeren <nikorpoulsen@gmail.com>",
|
||||||
"Sönke Hahn <soenkehahn@gmail.com>",
|
"Sönke Hahn <soenkehahn@gmail.com>",
|
||||||
|
"TJKoury <TJKoury@gmail.com>",
|
||||||
"Tiago Alves <alvesjtiago@gmail.com>",
|
"Tiago Alves <alvesjtiago@gmail.com>",
|
||||||
"Daijiro Wachi <daijiro.wachi@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>",
|
"Cindy Wu <ciindy.wu@gmail.com>",
|
||||||
"Chris Bratlien <chrisbratlien@gmail.com>",
|
"Chris Bratlien <chrisbratlien@gmail.com>",
|
||||||
"ebinks <elizabethjbinks@gmail.com>",
|
"Yusef Napora <yusef@napora.org>",
|
||||||
"Francis Gulotta <wizard@roborooter.com>",
|
"Zane Starr <zcstarr@gmail.com>",
|
||||||
"Florian-Merle <florian.david.merle@gmail.com>",
|
|
||||||
"Bernd Strehl <bernd.strehl@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>",
|
"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>",
|
"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>"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@ require('node-forge/lib/sha512')
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('peer-id')} PeerId
|
* @typedef {import('peer-id')} PeerId
|
||||||
* @typedef {import('interface-datastore/src/types').Datastore} Datastore
|
* @typedef {import('interface-datastore').Datastore} Datastore
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const keyPrefix = '/pkcs8/'
|
const keyPrefix = '/pkcs8/'
|
||||||
|
@@ -82,7 +82,7 @@ class Stats extends EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* Returns a clone of the internal movingAverages
|
* Returns a clone of the internal movingAverages
|
||||||
*
|
*
|
||||||
* @returns {MovingAverage}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
get movingAverages () {
|
get movingAverages () {
|
||||||
return Object.assign({}, this._movingAverages)
|
return Object.assign({}, this._movingAverages)
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
const NatAPI = require('@motrix/nat-api')
|
const NatAPI = require('@motrix/nat-api')
|
||||||
const debug = require('debug')
|
const debug = require('debug')
|
||||||
const promisify = require('promisify-es6')
|
const { promisify } = require('es6-promisify')
|
||||||
const Multiaddr = require('multiaddr')
|
const Multiaddr = require('multiaddr')
|
||||||
const log = Object.assign(debug('libp2p:nat'), {
|
const log = Object.assign(debug('libp2p:nat'), {
|
||||||
error: debug('libp2p:nat:err')
|
error: debug('libp2p:nat:err')
|
||||||
@@ -132,14 +132,32 @@ class NatManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const client = new NatAPI(this._options)
|
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 = {
|
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 }),
|
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 }),
|
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 })
|
externalIp: (...args) => retry(() => externalIp(...args), { onFailedAttempt: log.error, unref: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -196,7 +196,7 @@ class TransportManager {
|
|||||||
// listening on remote addresses as they may be offline. We could then potentially
|
// 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
|
// just wait for any (`p-any`) listener to succeed on each transport before returning
|
||||||
const isListening = results.find(r => r.isFulfilled === true)
|
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)
|
throw errCode(new Error(`Transport (${key}) could not listen on any available address`), codes.ERR_NO_VALID_ADDRESSES)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -201,7 +201,7 @@ class Upgrader {
|
|||||||
* @private
|
* @private
|
||||||
* @param {object} options
|
* @param {object} options
|
||||||
* @param {string} options.cryptoProtocol - The crypto protocol that was negotiated
|
* @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 {MultiaddrConnection} options.maConn - The transport layer connection
|
||||||
* @param {MuxedStream | MultiaddrConnection} options.upgradedConn - A duplex connection returned from multiplexer and/or crypto selection
|
* @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
|
* @param {MuxerFactory} [options.Muxer] - The muxer to be used for muxing
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
const { expect } = require('aegir/utils/chai')
|
const { expect } = require('aegir/utils/chai')
|
||||||
const sinon = require('sinon')
|
const sinon = require('sinon')
|
||||||
|
const { networkInterfaces } = require('os')
|
||||||
const AddressManager = require('../../src/address-manager')
|
const AddressManager = require('../../src/address-manager')
|
||||||
const TransportManager = require('../../src/transport-manager')
|
const TransportManager = require('../../src/transport-manager')
|
||||||
const Transport = require('libp2p-tcp')
|
const Transport = require('libp2p-tcp')
|
||||||
@@ -156,7 +157,7 @@ describe('Nat Manager (TCP)', () => {
|
|||||||
natManager,
|
natManager,
|
||||||
addressManager
|
addressManager
|
||||||
} = await createNatManager([
|
} = await createNatManager([
|
||||||
'/ip6/::/tcp/5001'
|
'/ip6/::/tcp/0'
|
||||||
])
|
])
|
||||||
|
|
||||||
let observed = addressManager.getObservedAddrs().map(ma => ma.toString())
|
let observed = addressManager.getObservedAddrs().map(ma => ma.toString())
|
||||||
@@ -173,7 +174,7 @@ describe('Nat Manager (TCP)', () => {
|
|||||||
natManager,
|
natManager,
|
||||||
addressManager
|
addressManager
|
||||||
} = await createNatManager([
|
} = await createNatManager([
|
||||||
'/ip6/::1/tcp/5001'
|
'/ip6/::1/tcp/0'
|
||||||
])
|
])
|
||||||
|
|
||||||
let observed = addressManager.getObservedAddrs().map(ma => ma.toString())
|
let observed = addressManager.getObservedAddrs().map(ma => ma.toString())
|
||||||
@@ -207,7 +208,7 @@ describe('Nat Manager (TCP)', () => {
|
|||||||
natManager,
|
natManager,
|
||||||
addressManager
|
addressManager
|
||||||
} = await createNatManager([
|
} = await createNatManager([
|
||||||
'/ip4/127.0.0.1/tcp/5900'
|
'/ip4/127.0.0.1/tcp/0'
|
||||||
])
|
])
|
||||||
|
|
||||||
let observed = addressManager.getObservedAddrs().map(ma => ma.toString())
|
let observed = addressManager.getObservedAddrs().map(ma => ma.toString())
|
||||||
@@ -224,7 +225,7 @@ describe('Nat Manager (TCP)', () => {
|
|||||||
natManager,
|
natManager,
|
||||||
addressManager
|
addressManager
|
||||||
} = await createNatManager([
|
} = 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())
|
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
|
new NatManager({ ttl: 5 }) // eslint-disable-line no-new
|
||||||
}).to.throw().with.property('code', ERR_INVALID_PARAMETERS)
|
}).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()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@@ -209,7 +209,7 @@ describe('libp2p.transportManager (dial only)', () => {
|
|||||||
throw new Error('it should fail to start if multiaddr fails to listen')
|
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({
|
libp2p = new Libp2p({
|
||||||
peerId,
|
peerId,
|
||||||
addresses: {
|
addresses: {
|
||||||
@@ -226,4 +226,22 @@ describe('libp2p.transportManager (dial only)', () => {
|
|||||||
|
|
||||||
await libp2p.start()
|
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()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user