From 43b7afa164e6a3754b4a5fdcae9da6215fd385ea Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Thu, 29 Oct 2020 20:27:25 +0100 Subject: [PATCH 1/5] chore: auto relay example --- examples/auto-relay/README.md | 163 ++++++++++++++++++++++++++++++ examples/auto-relay/auto-relay.js | 45 +++++++++ examples/auto-relay/other-node.js | 27 +++++ examples/auto-relay/relay.js | 37 +++++++ 4 files changed, 272 insertions(+) create mode 100644 examples/auto-relay/README.md create mode 100644 examples/auto-relay/auto-relay.js create mode 100644 examples/auto-relay/other-node.js create mode 100644 examples/auto-relay/relay.js diff --git a/examples/auto-relay/README.md b/examples/auto-relay/README.md new file mode 100644 index 0000000000..44d2bddc33 --- /dev/null +++ b/examples/auto-relay/README.md @@ -0,0 +1,163 @@ +# Auto relay + +Auto Relay enables libp2p nodes to dynamically find and bind to relays on the network. Once binding (listening) is done, the node can and should advertise its addresses to the network, allowing any other node to dial it over its bound relay(s). +While direct connections to nodes are preferable, it's not always possible to do so due to NATs or browser limitations. + +## 0. Setup the example + +Before moving into the examples, you should run `npm install` on the top level folder of libp2p, in order to install all the dependencies needed for these examples. + +This example comes with 3 main files to run. A `relay.js` file to be used in the first step, a `auto-relay.js` file to be used in the second step and a `other-node.js` file to be used on the third step. All of this scripts will run their own libp2p node, which will interact with the previous ones. This way, you need to have all of them running as you proceed. + +## 1. Set up a relay node + +Aiming to support nodes with connectivity difficulties, you will need to set up a relay node for the former nodes to bind. + +The relay node will need to have its relay subsystem enabled, as well as its HOP capability. It can be configured as follows: + +```js +const Libp2p = require('libp2p') +const Websockets = require('libp2p-websockets') +const { NOISE } = require('libp2p-noise') +const MPLEX = require('libp2p-mplex') + +const node = await Libp2p.create({ + modules: { + transport: [Websockets], + connEncryption: [NOISE], + streamMuxer: [MPLEX] + }, + addresses: { + listen: ['/ip4/0.0.0.0/tcp/0/ws'] + // announceFilter: TODO check "What is next?" section + }, + config: { + relay: { + enabled: true, + hop: { + enabled: true + }, + advertise: { + enabled: true, + } + } + } +}) + +await node.start() + +console.log(`Node started. ${node.peerId.toB58String()}`) +console.log('Listening on:') +node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`)) +``` + +The Relay HOP advertise functionality is **NOT** required to be enabled. However, if you are interested in advertising on the network that this node is available to be used as a HOP Relay you can enable it. + +Once you start your relay node with `node relay.js`, it should print out something similar to the following: + +```sh +Node started. QmQKCBm87HQMbFqy14oqC85pMmnRrj6iD46ggM6reqNpsd +Listening on: +/ip4/127.0.0.1/tcp/58941/ws/p2p/QmQKCBm87HQMbFqy14oqC85pMmnRrj6iD46ggM6reqNpsd +/ip4/192.168.1.120/tcp/58941/ws/p2p/QmQKCBm87HQMbFqy14oqC85pMmnRrj6iD46ggM6reqNpsd +``` + +TODO: Docker Image with a repo + +## 2. Set up a node with Auto Relay Enabled + +One of the typical use cases for Auto Relay is nodes behind a NAT or browser nodes thanks to their limitations regarding listening for new connections. + +```js +const Libp2p = require('libp2p') +const Websockets = require('libp2p-websockets') +const { NOISE } = require('libp2p-noise') +const MPLEX = require('libp2p-mplex') + +// TODO: get the relay address from the previous step +const relayAddr = undefined + +const node = await Libp2p.create({ + modules: { + transport: [Websockets], + connEncryption: [NOISE], + streamMuxer: [MPLEX] + }, + config: { + relay: { + enabled: true, + autoRelay: { + enabled: true, + maxListeners: 2 + } + } + } +}) + +await node.start() +console.log(`Node started. ${node.peerId.toB58String()}`) +console.log('Listening on:') +node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`)) + +await node.dial(relayAddr) +console.log('connected to the HOP relay') +console.log('Listening on:') +node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`)) +``` + +Before starting your node leveraging auto relay, you need to fill in the `relayAddr` in the code with the relay listening address from step 1. + +Once you start your auto relay node with `node auto-relay.js`, it should print out something similar to the following: + +```sh +Node started. QmSmhZ1pTV5ox7DUfG8QPSwyNyXGsWUeTCEWXfH7MVXLfi +connected to the HOP relay +Listening on: +/ip4/192.168.1.120/tcp/60288/ws/p2p/QmNusKcZR1WNKEJqvPeKtPfzHxAviqH5P2RxyKRqynV6WD/p2p-circuit/p2p/QmSmhZ1pTV5ox7DUfG8QPSwyNyXGsWUeTCEWXfH7MVXLfi +``` + +Per the address, it is possible to verify that the auto relay node is listening on the circuit relay node address. + +Instead of dialing this relay manually, you could set up this node with the Bootstrap module and provide it in the bootstrap list. + +## 3. Set up another node for testing connectivity + +Now that you have set up a relay node and a node leveraging that relay with auto relay, you can test connecting to the auto relay node via the relay. + +```js +const Libp2p = require('libp2p') +const Websockets = require('libp2p-websockets') +const { NOISE } = require('libp2p-noise') +const MPLEX = require('libp2p-mplex') + +// TODO: get the auto relay address from the previous step +const autoRelayNodeAddr = undefined + +const node = await Libp2p.create({ + modules: { + transport: [Websockets], + connEncryption: [NOISE], + streamMuxer: [MPLEX] + } +}) + +await node.start() + +const conn = await node.dial(autoRelayNodeAddr) +console.log(`Connected to the auto relay node via ${conn.remoteAddr.toString()}`) +``` + +Before starting your node leveraging auto relay, you need to fill in the `autoRelayNodeAddr` in the code with the relay listening address from step 2. + +Once you start your test node with `node other-relay.js`, it should print out something similar to the following: + +```sh +Connected to the auto relay node via /ip4/192.168.1.120/tcp/61470/ws/p2p/Qme1DfXDeaMEPNsUrG8EFXj2JDqzpgy9LuD6mpqpBsNwTm/p2p-circuit/p2p/Qmch46oemLTk6HJX1Yzm8gVRLPvBStoMQNniB37mX34RqM +``` + +## 4. What is next? + +- Private addr +- Use `webrtc-star` for discovering other peers (will get both announced addresses that might be used on peer exchange/DHT queries) + - Check libp2p in the browser example... +- Infra guide? diff --git a/examples/auto-relay/auto-relay.js b/examples/auto-relay/auto-relay.js new file mode 100644 index 0000000000..589cfcf8fe --- /dev/null +++ b/examples/auto-relay/auto-relay.js @@ -0,0 +1,45 @@ +'use strict' + +const Libp2p = require('libp2p') +const Websockets = require('libp2p-websockets') +const { NOISE } = require('libp2p-noise') +const MPLEX = require('libp2p-mplex') + +const pWaitFor = require('p-wait-for') + +// TODO: get the relay address from the previous step) +const relayAddr = '/ip4/192.168.1.120/tcp/61470/ws/p2p/Qme1DfXDeaMEPNsUrG8EFXj2JDqzpgy9LuD6mpqpBsNwTm' +if (!relayAddr) { + throw new Error('the relay address needs to be specified') +} + +; (async () => { + const node = await Libp2p.create({ + modules: { + transport: [Websockets], + connEncryption: [NOISE], + streamMuxer: [MPLEX] + }, + config: { + relay: { + enabled: true, + autoRelay: { + enabled: true, + maxListeners: 2 + } + } + } + }) + + await node.start() + console.log(`Node started. ${node.peerId.toB58String()}`) + + await node.dial(relayAddr) + + // Wait for connection and relay to be bind + await pWaitFor(() => node.multiaddrs.length > 0) + + console.log('connected to the HOP relay') + console.log('Listening on:') + node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`)) +})() diff --git a/examples/auto-relay/other-node.js b/examples/auto-relay/other-node.js new file mode 100644 index 0000000000..a36e96b0b3 --- /dev/null +++ b/examples/auto-relay/other-node.js @@ -0,0 +1,27 @@ +'use strict' + +const Libp2p = require('libp2p') +const Websockets = require('libp2p-websockets') +const { NOISE } = require('libp2p-noise') +const MPLEX = require('libp2p-mplex') + +;(async () => { + // TODO: get the auto relay address from the previous step + const autoRelayNodeAddr = '/ip4/192.168.1.120/tcp/61470/ws/p2p/Qme1DfXDeaMEPNsUrG8EFXj2JDqzpgy9LuD6mpqpBsNwTm/p2p-circuit/p2p/Qmch46oemLTk6HJX1Yzm8gVRLPvBStoMQNniB37mX34RqM' + if (!autoRelayNodeAddr) { + throw new Error('the auto relay node address needs to be specified') + } + + const node = await Libp2p.create({ + modules: { + transport: [Websockets], + connEncryption: [NOISE], + streamMuxer: [MPLEX] + } + }) + + await node.start() + + const conn = await node.dial(autoRelayNodeAddr) + console.log(`Connected to the auto relay node via ${conn.remoteAddr.toString()}`) +})() \ No newline at end of file diff --git a/examples/auto-relay/relay.js b/examples/auto-relay/relay.js new file mode 100644 index 0000000000..7c60e93b5e --- /dev/null +++ b/examples/auto-relay/relay.js @@ -0,0 +1,37 @@ +'use strict' + +const Libp2p = require('libp2p') +const Websockets = require('libp2p-websockets') +const { NOISE } = require('libp2p-noise') +const MPLEX = require('libp2p-mplex') + +;(async () => { + const node = await Libp2p.create({ + modules: { + transport: [Websockets], + connEncryption: [NOISE], + streamMuxer: [MPLEX] + }, + addresses: { + listen: ['/ip4/0.0.0.0/tcp/0/ws'] + // announceFilter: TODO check production section + }, + config: { + relay: { + enabled: true, + hop: { + enabled: true + }, + advertise: { + enabled: true, + } + } + } + }) + + await node.start() + + console.log(`Node started. ${node.peerId.toB58String()}`) + console.log('Listening on:') + node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`)) +})() \ No newline at end of file From 2bd1a2f0e7d7ed58ede4b7bc38bef8c237f79e05 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Wed, 4 Nov 2020 16:17:10 +0100 Subject: [PATCH 2/5] chore: update examples to use process arguments --- examples/auto-relay/README.md | 91 ++++++++++++++++++++----------- examples/auto-relay/auto-relay.js | 11 ++-- examples/auto-relay/other-node.js | 12 ++-- examples/auto-relay/relay.js | 4 +- 4 files changed, 73 insertions(+), 45 deletions(-) diff --git a/examples/auto-relay/README.md b/examples/auto-relay/README.md index 44d2bddc33..ab7ac8a01f 100644 --- a/examples/auto-relay/README.md +++ b/examples/auto-relay/README.md @@ -1,17 +1,17 @@ # Auto relay -Auto Relay enables libp2p nodes to dynamically find and bind to relays on the network. Once binding (listening) is done, the node can and should advertise its addresses to the network, allowing any other node to dial it over its bound relay(s). +Auto Relay enables libp2p nodes to dynamically find and bind to relays on the network. Once binding (listening) is done, the node can and should advertise its addresses on the network, allowing any other node to dial it over its bound relay(s). While direct connections to nodes are preferable, it's not always possible to do so due to NATs or browser limitations. ## 0. Setup the example -Before moving into the examples, you should run `npm install` on the top level folder of libp2p, in order to install all the dependencies needed for these examples. +Before moving into the examples, you should run `npm install` on the top level `js-libp2p` folder, in order to install all the dependencies needed for this example. -This example comes with 3 main files to run. A `relay.js` file to be used in the first step, a `auto-relay.js` file to be used in the second step and a `other-node.js` file to be used on the third step. All of this scripts will run their own libp2p node, which will interact with the previous ones. This way, you need to have all of them running as you proceed. +This example comes with 3 main files. A `relay.js` file to be used in the first step, a `auto-relay.js` file to be used in the second step and a `other-node.js` file to be used on the third step. All of this scripts will run their own libp2p node, which will interact with the previous ones. This way, you need to have all of them running as you proceed. ## 1. Set up a relay node -Aiming to support nodes with connectivity difficulties, you will need to set up a relay node for the former nodes to bind. +Aiming to support nodes with connectivity issues, you will need to set up a relay node for the former nodes to bind. The relay node will need to have its relay subsystem enabled, as well as its HOP capability. It can be configured as follows: @@ -29,7 +29,9 @@ const node = await Libp2p.create({ }, addresses: { listen: ['/ip4/0.0.0.0/tcp/0/ws'] - // announceFilter: TODO check "What is next?" section + // TODO check "What is next?" section + // announce: ['/dns4/auto-relay.libp2p.io/tcp/443/wss/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3'] + // announceFilter: (addresses) => addresses }, config: { relay: { @@ -46,27 +48,33 @@ const node = await Libp2p.create({ await node.start() -console.log(`Node started. ${node.peerId.toB58String()}`) +console.log(`Node started: ${node.peerId.toB58String()}`) console.log('Listening on:') node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`)) ``` The Relay HOP advertise functionality is **NOT** required to be enabled. However, if you are interested in advertising on the network that this node is available to be used as a HOP Relay you can enable it. -Once you start your relay node with `node relay.js`, it should print out something similar to the following: +You should now run the following to start the relay node: ```sh -Node started. QmQKCBm87HQMbFqy14oqC85pMmnRrj6iD46ggM6reqNpsd +node relay.js +``` + +This should print out something similar to the following: + +```sh +Node started: QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3 Listening on: -/ip4/127.0.0.1/tcp/58941/ws/p2p/QmQKCBm87HQMbFqy14oqC85pMmnRrj6iD46ggM6reqNpsd -/ip4/192.168.1.120/tcp/58941/ws/p2p/QmQKCBm87HQMbFqy14oqC85pMmnRrj6iD46ggM6reqNpsd +/ip4/127.0.0.1/tcp/61592/ws/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3 +/ip4/192.168.1.120/tcp/61592/ws/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3 ``` TODO: Docker Image with a repo ## 2. Set up a node with Auto Relay Enabled -One of the typical use cases for Auto Relay is nodes behind a NAT or browser nodes thanks to their limitations regarding listening for new connections. +One of the typical use cases for Auto Relay is nodes behind a NAT or browser nodes thanks to their limitations regarding listening for new connections. For running a libp2p node that automatically binds itself to connected HOP relays, you can see the following: ```js const Libp2p = require('libp2p') @@ -74,8 +82,12 @@ const Websockets = require('libp2p-websockets') const { NOISE } = require('libp2p-noise') const MPLEX = require('libp2p-mplex') -// TODO: get the relay address from the previous step -const relayAddr = undefined +const pWaitFor = require('p-wait-for') + +const relayAddr = process.argv[2] +if (!relayAddr) { + throw new Error('the relay address needs to be specified as a parameter') +} const node = await Libp2p.create({ modules: { @@ -95,34 +107,42 @@ const node = await Libp2p.create({ }) await node.start() -console.log(`Node started. ${node.peerId.toB58String()}`) -console.log('Listening on:') -node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`)) +console.log(`Node started: ${node.peerId.toB58String()}`) await node.dial(relayAddr) + +// Wait for connection and relay to be bind for the example purpose +await pWaitFor(() => node.multiaddrs.length > 0) + console.log('connected to the HOP relay') console.log('Listening on:') node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`)) ``` -Before starting your node leveraging auto relay, you need to fill in the `relayAddr` in the code with the relay listening address from step 1. +As you can see in the code, we need to provide the `relayAddr` as a process argument. This node will dial the relay and automatically bind to the relay. -Once you start your auto relay node with `node auto-relay.js`, it should print out something similar to the following: +You should now run the following to start the relay node: ```sh -Node started. QmSmhZ1pTV5ox7DUfG8QPSwyNyXGsWUeTCEWXfH7MVXLfi +node auto-relay.js /ip4/192.168.1.120/tcp/58941/ws/p2p/QmQKCBm87HQMbFqy14oqC85pMmnRrj6iD46ggM6reqNpsd +``` + +This should print out something similar to the following: + +```sh +Node started: QmerrWofKF358JE6gv3z74cEAyL7z1KqhuUoVfGEynqjRm connected to the HOP relay Listening on: -/ip4/192.168.1.120/tcp/60288/ws/p2p/QmNusKcZR1WNKEJqvPeKtPfzHxAviqH5P2RxyKRqynV6WD/p2p-circuit/p2p/QmSmhZ1pTV5ox7DUfG8QPSwyNyXGsWUeTCEWXfH7MVXLfi +/ip4/192.168.1.120/tcp/61592/ws/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3/p2p-circuit/p2p/QmerrWofKF358JE6gv3z74cEAyL7z1KqhuUoVfGEynqjRm ``` Per the address, it is possible to verify that the auto relay node is listening on the circuit relay node address. -Instead of dialing this relay manually, you could set up this node with the Bootstrap module and provide it in the bootstrap list. +Instead of dialing this relay manually, you could set up this node with the Bootstrap module and provide it in the bootstrap list. Moreover, you can use other `peer-discovery` modules to discover peers in the network and the node will automatically bind to the relays that support HOP until reaching the maximum number of listeners. ## 3. Set up another node for testing connectivity -Now that you have set up a relay node and a node leveraging that relay with auto relay, you can test connecting to the auto relay node via the relay. +Now that you have a relay node and a node bound to that relay, you can test connecting to the auto relay node via the relay. ```js const Libp2p = require('libp2p') @@ -130,8 +150,10 @@ const Websockets = require('libp2p-websockets') const { NOISE } = require('libp2p-noise') const MPLEX = require('libp2p-mplex') -// TODO: get the auto relay address from the previous step -const autoRelayNodeAddr = undefined +const autoRelayNodeAddr = process.argv[2] +if (!autoRelayNodeAddr) { + throw new Error('the auto relay node address needs to be specified') +} const node = await Libp2p.create({ modules: { @@ -142,22 +164,29 @@ const node = await Libp2p.create({ }) await node.start() +console.log(`Node started: ${node.peerId.toB58String()}`) const conn = await node.dial(autoRelayNodeAddr) console.log(`Connected to the auto relay node via ${conn.remoteAddr.toString()}`) ``` -Before starting your node leveraging auto relay, you need to fill in the `autoRelayNodeAddr` in the code with the relay listening address from step 2. +You should now run the following to start the relay node using the listen address from step 2: -Once you start your test node with `node other-relay.js`, it should print out something similar to the following: +```sh +node other-node.js /ip4/192.168.1.120/tcp/58941/ws/p2p/QmQKCBm87HQMbFqy14oqC85pMmnRrj6iD46ggM6reqNpsd +``` + +Once you start your test node, it should print out something similar to the following: ```sh -Connected to the auto relay node via /ip4/192.168.1.120/tcp/61470/ws/p2p/Qme1DfXDeaMEPNsUrG8EFXj2JDqzpgy9LuD6mpqpBsNwTm/p2p-circuit/p2p/Qmch46oemLTk6HJX1Yzm8gVRLPvBStoMQNniB37mX34RqM +Node started: Qme7iEzDxFoFhhkrsrkHkMnM11aPYjysaehP4NZeUfVMKG +Connected to the auto relay node via /ip4/192.168.1.120/tcp/61592/ws/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3/p2p-circuit/p2p/QmerrWofKF358JE6gv3z74cEAyL7z1KqhuUoVfGEynqjRm ``` +As you can see from the output, the remote address of the established connection uses the relayed connection. + ## 4. What is next? -- Private addr -- Use `webrtc-star` for discovering other peers (will get both announced addresses that might be used on peer exchange/DHT queries) - - Check libp2p in the browser example... -- Infra guide? +Before moving into production, there are a few things that you should take into account. + +A relay node should not advertise its private address in a real world scenario, as the node would not be reachable by others. You should provide an array of public addresses in the libp2p `addresses.announce` option. If you are using websockets, bear in mind that due to browser’s security policies you cannot establish unencrypted connection from secure context. The simplest solution is to setup SSL with nginx and proxy to the node and setup a domain name for the certificate. diff --git a/examples/auto-relay/auto-relay.js b/examples/auto-relay/auto-relay.js index 589cfcf8fe..6a2a4c4b25 100644 --- a/examples/auto-relay/auto-relay.js +++ b/examples/auto-relay/auto-relay.js @@ -7,13 +7,12 @@ const MPLEX = require('libp2p-mplex') const pWaitFor = require('p-wait-for') -// TODO: get the relay address from the previous step) -const relayAddr = '/ip4/192.168.1.120/tcp/61470/ws/p2p/Qme1DfXDeaMEPNsUrG8EFXj2JDqzpgy9LuD6mpqpBsNwTm' +const relayAddr = process.argv[2] if (!relayAddr) { - throw new Error('the relay address needs to be specified') + throw new Error('the relay address needs to be specified as a parameter') } -; (async () => { +;(async () => { const node = await Libp2p.create({ modules: { transport: [Websockets], @@ -32,11 +31,11 @@ if (!relayAddr) { }) await node.start() - console.log(`Node started. ${node.peerId.toB58String()}`) + console.log(`Node started: ${node.peerId.toB58String()}`) await node.dial(relayAddr) - // Wait for connection and relay to be bind + // Wait for connection and relay to be bind for the example purpose await pWaitFor(() => node.multiaddrs.length > 0) console.log('connected to the HOP relay') diff --git a/examples/auto-relay/other-node.js b/examples/auto-relay/other-node.js index a36e96b0b3..386fa027a7 100644 --- a/examples/auto-relay/other-node.js +++ b/examples/auto-relay/other-node.js @@ -5,13 +5,12 @@ const Websockets = require('libp2p-websockets') const { NOISE } = require('libp2p-noise') const MPLEX = require('libp2p-mplex') -;(async () => { - // TODO: get the auto relay address from the previous step - const autoRelayNodeAddr = '/ip4/192.168.1.120/tcp/61470/ws/p2p/Qme1DfXDeaMEPNsUrG8EFXj2JDqzpgy9LuD6mpqpBsNwTm/p2p-circuit/p2p/Qmch46oemLTk6HJX1Yzm8gVRLPvBStoMQNniB37mX34RqM' - if (!autoRelayNodeAddr) { - throw new Error('the auto relay node address needs to be specified') - } +const autoRelayNodeAddr = process.argv[2] +if (!autoRelayNodeAddr) { + throw new Error('the auto relay node address needs to be specified') +} +;(async () => { const node = await Libp2p.create({ modules: { transport: [Websockets], @@ -21,6 +20,7 @@ const MPLEX = require('libp2p-mplex') }) await node.start() + console.log(`Node started: ${node.peerId.toB58String()}`) const conn = await node.dial(autoRelayNodeAddr) console.log(`Connected to the auto relay node via ${conn.remoteAddr.toString()}`) diff --git a/examples/auto-relay/relay.js b/examples/auto-relay/relay.js index 7c60e93b5e..e046e042e8 100644 --- a/examples/auto-relay/relay.js +++ b/examples/auto-relay/relay.js @@ -31,7 +31,7 @@ const MPLEX = require('libp2p-mplex') await node.start() - console.log(`Node started. ${node.peerId.toB58String()}`) + console.log(`Node started: ${node.peerId.toB58String()}`) console.log('Listening on:') node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`)) -})() \ No newline at end of file +})() From a09ac4a8076d0f865aa96b0857105e61392e93de Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Fri, 6 Nov 2020 16:28:12 +0100 Subject: [PATCH 3/5] chore: add test setup for node tests and test for auto-relay --- .travis.yml | 7 +++ examples/auto-relay/test.js | 94 ++++++++++++++++++++++++++++++++++++ examples/package.json | 16 +++++++ examples/test-all.js | 33 +++++++++++++ examples/test.js | 95 +++++++++++++++++++++++++++++++++++++ examples/utils.js | 61 ++++++++++++++++++++++++ package.json | 1 + 7 files changed, 307 insertions(+) create mode 100644 examples/auto-relay/test.js create mode 100644 examples/package.json create mode 100644 examples/test-all.js create mode 100644 examples/test.js create mode 100644 examples/utils.js diff --git a/.travis.yml b/.travis.yml index bb21bd4028..55def3faff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,5 +46,12 @@ jobs: - npm install - LIBP2P_JS=${TRAVIS_BUILD_DIR}/src/index.js npx aegir test -t node --bail + - stage: test + name: example - auto-relay + script: + - cd examples + - npm install + - npm run test -- auto-relay + notifications: email: false \ No newline at end of file diff --git a/examples/auto-relay/test.js b/examples/auto-relay/test.js new file mode 100644 index 0000000000..dff3f841d9 --- /dev/null +++ b/examples/auto-relay/test.js @@ -0,0 +1,94 @@ +'use strict' + +const path = require('path') +const execa = require('execa') +const pDefer = require('p-defer') +const uint8ArrayToString = require('uint8arrays/to-string') + +function startProcess (name, args = []) { + return execa('node', [path.join(__dirname, name), ...args], { + cwd: path.resolve(__dirname), + all: true + }) +} + +async function test () { + let output1 = '' + let output2 = '' + let output3 = '' + let relayAddr + let autoRelayAddr + + const proc1Ready = pDefer() + const proc2Ready = pDefer() + + // Step 1 process + process.stdout.write('relay.js\n') + + const proc1 = startProcess('relay.js') + proc1.all.on('data', async (data) => { + process.stdout.write(data) + + output1 += uint8ArrayToString(data) + + if (output1.includes('Listening on:') && output1.includes('/p2p/')) { + relayAddr = output1.trim().split('Listening on:\n')[1].split('\n')[0] + proc1Ready.resolve() + } + }) + + await proc1Ready.promise + process.stdout.write('==================================================================\n') + + // Step 2 process + process.stdout.write('auto-relay.js\n') + + const proc2 = startProcess('auto-relay.js', [relayAddr]) + proc2.all.on('data', async (data) => { + process.stdout.write(data) + + output2 += uint8ArrayToString(data) + + if (output2.includes('Listening on:') && output2.includes('/p2p/')) { + autoRelayAddr = output2.trim().split('Listening on:\n')[1] + proc2Ready.resolve() + } + }) + + await proc2Ready.promise + process.stdout.write('==================================================================\n') + + // Step 3 process + process.stdout.write('other-node.js\n') + + const proc3 = startProcess('other-node.js', [autoRelayAddr]) + proc3.all.on('data', async (data) => { + process.stdout.write(data) + + output3 += uint8ArrayToString(data) + + if (output3.includes('Connected to the auto relay node via')) { + const remoteAddr = output3.trim().split('Connected to the auto relay node via ')[1] + + if (remoteAddr === autoRelayAddr) { + proc3.kill() + proc2.kill() + proc1.kill() + } else { + throw new Error('other-node did not dial through the relay') + } + } + }) + + await Promise.all([ + proc1, + proc2, + proc3 + ]).catch((err) => { + if (err.signal !== 'SIGTERM') { + throw err + } + }) +} + +module.exports = test \ No newline at end of file diff --git a/examples/package.json b/examples/package.json new file mode 100644 index 0000000000..feaf656d1b --- /dev/null +++ b/examples/package.json @@ -0,0 +1,16 @@ +{ + "name": "libp2p-examples", + "version": "1.0.0", + "description": "Examples of how to use libp2p", + "scripts": { + "test": "node ./test.js", + "test:all": "node ./test-all.js" + }, + "license": "MIT", + "dependencies": { + "execa": "^2.1.0", + "fs-extra": "^8.1.0", + "p-defer": "^3.0.0", + "which": "^2.0.1" + } +} diff --git a/examples/test-all.js b/examples/test-all.js new file mode 100644 index 0000000000..3ee99e45fa --- /dev/null +++ b/examples/test-all.js @@ -0,0 +1,33 @@ +'use strict' + +process.on('unhandedRejection', (err) => { + console.error(err) + + process.exit(1) +}) + +const path = require('path') +const fs = require('fs') +const { + waitForOutput +} = require('./utils') + +async function testAll () { + for (const dir of fs.readdirSync(__dirname)) { + if (dir === 'node_modules' || dir === 'tests_output') { + continue + } + + const stats = fs.statSync(path.join(__dirname, dir)) + + if (!stats.isDirectory()) { + continue + } + + await waitForOutput('npm info ok', 'npm', ['test', '--', dir], { + cwd: __dirname + }) + } +} + +testAll() diff --git a/examples/test.js b/examples/test.js new file mode 100644 index 0000000000..3da6eccdb9 --- /dev/null +++ b/examples/test.js @@ -0,0 +1,95 @@ +'use strict' + +process.env.NODE_ENV = 'test' +process.env.CI = true // needed for some "clever" build tools + +const fs = require('fs-extra') +const path = require('path') +const execa = require('execa') +const dir = path.join(__dirname, process.argv[2]) + +testExample(dir) + .then(() => {}, (err) => { + if (err.exitCode) { + process.exit(err.exitCode) + } + + console.error(err) + process.exit(1) + }) + +async function testExample (dir) { + await installDeps(dir) + await build(dir) + await runTest(dir) + // TODO: add browser test setup +} + +async function installDeps (dir) { + if (!fs.existsSync(path.join(dir, 'package.json'))) { + console.info('Nothing to install in', dir) + return + } + + if (fs.existsSync(path.join(dir, 'node_modules'))) { + console.info('Dependencies already installed in', dir) + return + } + + const proc = execa.command('npm install', { + cwd: dir + }) + proc.all.on('data', (data) => { + process.stdout.write(data) + }) + + await proc +} + +async function build (dir) { + const pkgJson = path.join(dir, 'package.json') + + if (!fs.existsSync(pkgJson)) { + console.info('Nothing to build in', dir) + return + } + + const pkg = require(pkgJson) + let build + + if (pkg.scripts.bundle) { + build = 'bundle' + } + + if (pkg.scripts.build) { + build = 'build' + } + + if (!build) { + console.info('No "build" or "bundle" script in', pkgJson) + return + } + + const proc = execa('npm', ['run', build], { + cwd: dir + }) + proc.all.on('data', (data) => { + process.stdout.write(data) + }) + + await proc +} + +async function runTest (dir) { + console.info('Running node tests in', dir) + const testFile = path.join(dir, 'test.js') + + if (!fs.existsSync(testFile)) { + console.info('Nothing to test in', dir) + return + } + + const runTest = require(testFile) + + await runTest() +} \ No newline at end of file diff --git a/examples/utils.js b/examples/utils.js new file mode 100644 index 0000000000..aec6df5418 --- /dev/null +++ b/examples/utils.js @@ -0,0 +1,61 @@ +'use strict' + +const execa = require('execa') +const fs = require('fs-extra') +const which = require('which') + +async function isExecutable (command) { + try { + await fs.access(command, fs.constants.X_OK) + + return true + } catch (err) { + if (err.code === 'ENOENT') { + return isExecutable(await which(command)) + } + + if (err.code === 'EACCES') { + return false + } + + throw err + } +} + +async function waitForOutput (expectedOutput, command, args = [], opts = {}) { + if (!await isExecutable(command)) { + args.unshift(command) + command = 'node' + } + + const proc = execa(command, args, opts) + let output = '' + let time = 120000 + + let timeout = setTimeout(() => { + throw new Error(`Did not see "${expectedOutput}" in output from "${[command].concat(args).join(' ')}" after ${time/1000}s`) + }, time) + + proc.all.on('data', (data) => { + process.stdout.write(data) + + output += data.toString('utf8') + + if (output.includes(expectedOutput)) { + clearTimeout(timeout) + proc.kill() + } + }) + + try { + await proc + } catch (err) { + if (!err.killed) { + throw err + } + } +} + +module.exports = { + waitForOutput +} diff --git a/package.json b/package.json index b1ae4c5ebe..042a9a0664 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "test": "npm run test:node && npm run test:browser", "test:node": "aegir test -t node -f \"./test/**/*.{node,spec}.js\"", "test:browser": "aegir test -t browser", + "test:examples": "cd examples && npm run test:all", "release": "aegir release -t node -t browser", "release-minor": "aegir release --type minor -t node -t browser", "release-major": "aegir release --type major -t node -t browser", From 56234490d727baead7b6006b72132792238925b4 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Thu, 12 Nov 2020 12:05:00 +0100 Subject: [PATCH 4/5] chore: apply suggestions from code review --- .travis.yml | 1 + examples/auto-relay/README.md | 58 +++++++++---------- examples/auto-relay/auto-relay.js | 44 -------------- .../auto-relay/{other-node.js => dialer.js} | 16 ++--- examples/auto-relay/listener.js | 50 ++++++++++++++++ examples/auto-relay/relay.js | 11 ++-- examples/auto-relay/test.js | 14 ++--- 7 files changed, 103 insertions(+), 91 deletions(-) delete mode 100644 examples/auto-relay/auto-relay.js rename examples/auto-relay/{other-node.js => dialer.js} (66%) create mode 100644 examples/auto-relay/listener.js diff --git a/.travis.yml b/.travis.yml index 55def3faff..47f1fcb07a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,6 +47,7 @@ jobs: - LIBP2P_JS=${TRAVIS_BUILD_DIR}/src/index.js npx aegir test -t node --bail - stage: test + if: type = pull_request name: example - auto-relay script: - cd examples diff --git a/examples/auto-relay/README.md b/examples/auto-relay/README.md index ab7ac8a01f..fbb3b7a046 100644 --- a/examples/auto-relay/README.md +++ b/examples/auto-relay/README.md @@ -5,13 +5,13 @@ While direct connections to nodes are preferable, it's not always possible to do ## 0. Setup the example -Before moving into the examples, you should run `npm install` on the top level `js-libp2p` folder, in order to install all the dependencies needed for this example. +Before moving into the examples, you should run `npm install` on the top level `js-libp2p` folder, in order to install all the dependencies needed for this example. Once the install finishes, you should move into the example folder with `cd examples/auto-relay`. -This example comes with 3 main files. A `relay.js` file to be used in the first step, a `auto-relay.js` file to be used in the second step and a `other-node.js` file to be used on the third step. All of this scripts will run their own libp2p node, which will interact with the previous ones. This way, you need to have all of them running as you proceed. +This example comes with 3 main files. A `relay.js` file to be used in the first step, a `listener.js` file to be used in the second step and a `dialer.js` file to be used on the third step. All of these scripts will run their own libp2p node, which will interact with the previous ones. All nodes must be running in order for you to proceed. ## 1. Set up a relay node -Aiming to support nodes with connectivity issues, you will need to set up a relay node for the former nodes to bind. +In the first step of this example, we need to configure and run a relay node in order for our target node to bind to for accepting inbound connections. The relay node will need to have its relay subsystem enabled, as well as its HOP capability. It can be configured as follows: @@ -31,7 +31,6 @@ const node = await Libp2p.create({ listen: ['/ip4/0.0.0.0/tcp/0/ws'] // TODO check "What is next?" section // announce: ['/dns4/auto-relay.libp2p.io/tcp/443/wss/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3'] - // announceFilter: (addresses) => addresses }, config: { relay: { @@ -48,12 +47,12 @@ const node = await Libp2p.create({ await node.start() -console.log(`Node started: ${node.peerId.toB58String()}`) +console.log(`Node started with id ${node.peerId.toB58String()}`) console.log('Listening on:') node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`)) ``` -The Relay HOP advertise functionality is **NOT** required to be enabled. However, if you are interested in advertising on the network that this node is available to be used as a HOP Relay you can enable it. +The Relay HOP advertise functionality is **NOT** required to be enabled. However, if you are interested in advertising on the network that this node is available to be used as a HOP Relay you can enable it. A content router module or Rendezvous needs to be configured to leverage this option. You should now run the following to start the relay node: @@ -64,17 +63,15 @@ node relay.js This should print out something similar to the following: ```sh -Node started: QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3 +Node started with id QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3 Listening on: /ip4/127.0.0.1/tcp/61592/ws/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3 /ip4/192.168.1.120/tcp/61592/ws/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3 ``` -TODO: Docker Image with a repo +## 2. Set up a listener node with Auto Relay Enabled -## 2. Set up a node with Auto Relay Enabled - -One of the typical use cases for Auto Relay is nodes behind a NAT or browser nodes thanks to their limitations regarding listening for new connections. For running a libp2p node that automatically binds itself to connected HOP relays, you can see the following: +One of the typical use cases for Auto Relay is nodes behind a NAT or browser nodes due to their inability to expose a public address. For running a libp2p node that automatically binds itself to connected HOP relays, you can see the following: ```js const Libp2p = require('libp2p') @@ -82,8 +79,6 @@ const Websockets = require('libp2p-websockets') const { NOISE } = require('libp2p-noise') const MPLEX = require('libp2p-mplex') -const pWaitFor = require('p-wait-for') - const relayAddr = process.argv[2] if (!relayAddr) { throw new Error('the relay address needs to be specified as a parameter') @@ -107,40 +102,45 @@ const node = await Libp2p.create({ }) await node.start() -console.log(`Node started: ${node.peerId.toB58String()}`) +console.log(`Node started with id ${node.peerId.toB58String()}`) -await node.dial(relayAddr) +const conn = await node.dial(relayAddr) // Wait for connection and relay to be bind for the example purpose -await pWaitFor(() => node.multiaddrs.length > 0) +await new Promise((resolve) => { + node.peerStore.on('change:multiaddrs', ({ peerId }) => { + // Updated self multiaddrs? + if (peerId.equals(node.peerId)) { + resolve() + } + }) +}) -console.log('connected to the HOP relay') -console.log('Listening on:') -node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`)) +console.log(`Connected to the HOP relay ${conn.remotePeer.toString()}`) +console.log(`Advertising with a relay address of ${node.multiaddrs[0].toString()}/p2p/${node.peerId.toB58String()}`) ``` -As you can see in the code, we need to provide the `relayAddr` as a process argument. This node will dial the relay and automatically bind to the relay. +As you can see in the code, we need to provide the relay address, `relayAddr`, as a process argument. This node will dial the provided relay address and automatically bind to it. -You should now run the following to start the relay node: +You should now run the following to start the node running Auto Relay: ```sh -node auto-relay.js /ip4/192.168.1.120/tcp/58941/ws/p2p/QmQKCBm87HQMbFqy14oqC85pMmnRrj6iD46ggM6reqNpsd +node listener.js /ip4/192.168.1.120/tcp/58941/ws/p2p/QmQKCBm87HQMbFqy14oqC85pMmnRrj6iD46ggM6reqNpsd ``` This should print out something similar to the following: ```sh -Node started: QmerrWofKF358JE6gv3z74cEAyL7z1KqhuUoVfGEynqjRm -connected to the HOP relay -Listening on: -/ip4/192.168.1.120/tcp/61592/ws/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3/p2p-circuit/p2p/QmerrWofKF358JE6gv3z74cEAyL7z1KqhuUoVfGEynqjRm +Node started with id QmerrWofKF358JE6gv3z74cEAyL7z1KqhuUoVfGEynqjRm +Connected to the HOP relay QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3 +Advertising with a relay address of /ip4/192.168.1.120/tcp/61592/ws/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3/p2p-circuit/p2p/QmerrWofKF358JE6gv3z74cEAyL7z1KqhuUoVfGEynqjRm ``` Per the address, it is possible to verify that the auto relay node is listening on the circuit relay node address. Instead of dialing this relay manually, you could set up this node with the Bootstrap module and provide it in the bootstrap list. Moreover, you can use other `peer-discovery` modules to discover peers in the network and the node will automatically bind to the relays that support HOP until reaching the maximum number of listeners. -## 3. Set up another node for testing connectivity +## 3. Set up a dialer node for testing connectivity Now that you have a relay node and a node bound to that relay, you can test connecting to the auto relay node via the relay. @@ -164,7 +164,7 @@ const node = await Libp2p.create({ }) await node.start() -console.log(`Node started: ${node.peerId.toB58String()}`) +console.log(`Node started with id ${node.peerId.toB58String()}`) const conn = await node.dial(autoRelayNodeAddr) console.log(`Connected to the auto relay node via ${conn.remoteAddr.toString()}`) @@ -173,7 +173,7 @@ console.log(`Connected to the auto relay node via ${conn.remoteAddr.toString()}` You should now run the following to start the relay node using the listen address from step 2: ```sh -node other-node.js /ip4/192.168.1.120/tcp/58941/ws/p2p/QmQKCBm87HQMbFqy14oqC85pMmnRrj6iD46ggM6reqNpsd +node dialer.js /ip4/192.168.1.120/tcp/58941/ws/p2p/QmQKCBm87HQMbFqy14oqC85pMmnRrj6iD46ggM6reqNpsd ``` Once you start your test node, it should print out something similar to the following: diff --git a/examples/auto-relay/auto-relay.js b/examples/auto-relay/auto-relay.js deleted file mode 100644 index 6a2a4c4b25..0000000000 --- a/examples/auto-relay/auto-relay.js +++ /dev/null @@ -1,44 +0,0 @@ -'use strict' - -const Libp2p = require('libp2p') -const Websockets = require('libp2p-websockets') -const { NOISE } = require('libp2p-noise') -const MPLEX = require('libp2p-mplex') - -const pWaitFor = require('p-wait-for') - -const relayAddr = process.argv[2] -if (!relayAddr) { - throw new Error('the relay address needs to be specified as a parameter') -} - -;(async () => { - const node = await Libp2p.create({ - modules: { - transport: [Websockets], - connEncryption: [NOISE], - streamMuxer: [MPLEX] - }, - config: { - relay: { - enabled: true, - autoRelay: { - enabled: true, - maxListeners: 2 - } - } - } - }) - - await node.start() - console.log(`Node started: ${node.peerId.toB58String()}`) - - await node.dial(relayAddr) - - // Wait for connection and relay to be bind for the example purpose - await pWaitFor(() => node.multiaddrs.length > 0) - - console.log('connected to the HOP relay') - console.log('Listening on:') - node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`)) -})() diff --git a/examples/auto-relay/other-node.js b/examples/auto-relay/dialer.js similarity index 66% rename from examples/auto-relay/other-node.js rename to examples/auto-relay/dialer.js index 386fa027a7..ebf5fd1249 100644 --- a/examples/auto-relay/other-node.js +++ b/examples/auto-relay/dialer.js @@ -5,12 +5,12 @@ const Websockets = require('libp2p-websockets') const { NOISE } = require('libp2p-noise') const MPLEX = require('libp2p-mplex') -const autoRelayNodeAddr = process.argv[2] -if (!autoRelayNodeAddr) { - throw new Error('the auto relay node address needs to be specified') -} +async function main () { + const autoRelayNodeAddr = process.argv[2] + if (!autoRelayNodeAddr) { + throw new Error('the auto relay node address needs to be specified') + } -;(async () => { const node = await Libp2p.create({ modules: { transport: [Websockets], @@ -20,8 +20,10 @@ if (!autoRelayNodeAddr) { }) await node.start() - console.log(`Node started: ${node.peerId.toB58String()}`) + console.log(`Node started with id ${node.peerId.toB58String()}`) const conn = await node.dial(autoRelayNodeAddr) console.log(`Connected to the auto relay node via ${conn.remoteAddr.toString()}`) -})() \ No newline at end of file +} + +main() diff --git a/examples/auto-relay/listener.js b/examples/auto-relay/listener.js new file mode 100644 index 0000000000..9fc10e943f --- /dev/null +++ b/examples/auto-relay/listener.js @@ -0,0 +1,50 @@ +'use strict' + +const Libp2p = require('libp2p') +const Websockets = require('libp2p-websockets') +const { NOISE } = require('libp2p-noise') +const MPLEX = require('libp2p-mplex') + +async function main () { + const relayAddr = process.argv[2] + if (!relayAddr) { + throw new Error('the relay address needs to be specified as a parameter') + } + + const node = await Libp2p.create({ + modules: { + transport: [Websockets], + connEncryption: [NOISE], + streamMuxer: [MPLEX] + }, + config: { + relay: { + enabled: true, + autoRelay: { + enabled: true, + maxListeners: 2 + } + } + } + }) + + await node.start() + console.log(`Node started with id ${node.peerId.toB58String()}`) + + const conn = await node.dial(relayAddr) + + // Wait for connection and relay to be bind for the example purpose + await new Promise((resolve) => { + node.peerStore.on('change:multiaddrs', ({ peerId }) => { + // Updated self multiaddrs? + if (peerId.equals(node.peerId)) { + resolve() + } + }) + }) + + console.log(`Connected to the HOP relay ${conn.remotePeer.toString()}`) + console.log(`Advertising with a relay address of ${node.multiaddrs[0].toString()}/p2p/${node.peerId.toB58String()}`) +} + +main() diff --git a/examples/auto-relay/relay.js b/examples/auto-relay/relay.js index e046e042e8..2a18c3a769 100644 --- a/examples/auto-relay/relay.js +++ b/examples/auto-relay/relay.js @@ -5,7 +5,7 @@ const Websockets = require('libp2p-websockets') const { NOISE } = require('libp2p-noise') const MPLEX = require('libp2p-mplex') -;(async () => { +async function main () { const node = await Libp2p.create({ modules: { transport: [Websockets], @@ -14,7 +14,8 @@ const MPLEX = require('libp2p-mplex') }, addresses: { listen: ['/ip4/0.0.0.0/tcp/0/ws'] - // announceFilter: TODO check production section + // TODO check "What is next?" section + // announce: ['/dns4/auto-relay.libp2p.io/tcp/443/wss/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3'] }, config: { relay: { @@ -31,7 +32,9 @@ const MPLEX = require('libp2p-mplex') await node.start() - console.log(`Node started: ${node.peerId.toB58String()}`) + console.log(`Node started with id ${node.peerId.toB58String()}`) console.log('Listening on:') node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`)) -})() +} + +main() diff --git a/examples/auto-relay/test.js b/examples/auto-relay/test.js index dff3f841d9..0eaf8cc3ae 100644 --- a/examples/auto-relay/test.js +++ b/examples/auto-relay/test.js @@ -41,16 +41,16 @@ async function test () { process.stdout.write('==================================================================\n') // Step 2 process - process.stdout.write('auto-relay.js\n') + process.stdout.write('listener.js\n') - const proc2 = startProcess('auto-relay.js', [relayAddr]) + const proc2 = startProcess('listener.js', [relayAddr]) proc2.all.on('data', async (data) => { process.stdout.write(data) output2 += uint8ArrayToString(data) - if (output2.includes('Listening on:') && output2.includes('/p2p/')) { - autoRelayAddr = output2.trim().split('Listening on:\n')[1] + if (output2.includes('Advertising with a relay address of') && output2.includes('/p2p/')) { + autoRelayAddr = output2.trim().split('Advertising with a relay address of ')[1] proc2Ready.resolve() } }) @@ -59,9 +59,9 @@ async function test () { process.stdout.write('==================================================================\n') // Step 3 process - process.stdout.write('other-node.js\n') + process.stdout.write('dialer.js\n') - const proc3 = startProcess('other-node.js', [autoRelayAddr]) + const proc3 = startProcess('dialer.js', [autoRelayAddr]) proc3.all.on('data', async (data) => { process.stdout.write(data) @@ -75,7 +75,7 @@ async function test () { proc2.kill() proc1.kill() } else { - throw new Error('other-node did not dial through the relay') + throw new Error('dialer did not dial through the relay') } } }) From 05bdb1f52487b3c506fed6a4420dfdec7f4c761b Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Mon, 16 Nov 2020 16:13:44 +0100 Subject: [PATCH 5/5] chore: do not use promise for multiaddrs event on example --- examples/auto-relay/listener.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/examples/auto-relay/listener.js b/examples/auto-relay/listener.js index 9fc10e943f..0f94374067 100644 --- a/examples/auto-relay/listener.js +++ b/examples/auto-relay/listener.js @@ -33,18 +33,15 @@ async function main () { const conn = await node.dial(relayAddr) - // Wait for connection and relay to be bind for the example purpose - await new Promise((resolve) => { - node.peerStore.on('change:multiaddrs', ({ peerId }) => { - // Updated self multiaddrs? - if (peerId.equals(node.peerId)) { - resolve() - } - }) - }) - console.log(`Connected to the HOP relay ${conn.remotePeer.toString()}`) - console.log(`Advertising with a relay address of ${node.multiaddrs[0].toString()}/p2p/${node.peerId.toB58String()}`) + + // Wait for connection and relay to be bind for the example purpose + node.peerStore.on('change:multiaddrs', ({ peerId }) => { + // Updated self multiaddrs? + if (peerId.equals(node.peerId)) { + console.log(`Advertising with a relay address of ${node.multiaddrs[0].toString()}/p2p/${node.peerId.toB58String()}`) + } + }) } main()