diff --git a/examples/auto-relay/README.md b/examples/auto-relay/README.md index 44d2bddc33..7065a0e4dc 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,7 @@ const node = await Libp2p.create({ }, addresses: { listen: ['/ip4/0.0.0.0/tcp/0/ws'] - // announceFilter: TODO check "What is next?" section + // announceFilter: (addresses) => addresses // TODO check "What is next?" section }, config: { relay: { @@ -46,27 +46,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 +80,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 +105,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 +148,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,19 +162,27 @@ 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 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 +})()