Skip to content

Commit

Permalink
docs: fix examples in documentation (#1379)
Browse files Browse the repository at this point in the history
This PR fixes all the errors in the code snippets in the readme files contained in the examples directory and it fixes the doc/GETTING_STARTED.md file.

I have also updated the old package names, e.g. `libp2p-websockets` -> `@libp2p/websockets`.

Resolves #1367 and resolves #1361

Co-authored-by: saul <saul@organicdesign.nz>
  • Loading branch information
Saul and saul authored Sep 22, 2022
1 parent a11260c commit 6219841
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 240 deletions.
43 changes: 20 additions & 23 deletions doc/GETTING_STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ Now that we have libp2p installed, let's configure the minimum needed to get you

Libp2p uses Transports to establish connections between peers over the network. Transports are the components responsible for performing the actual exchange of data between libp2p nodes. You can configure any number of Transports, but you only need 1 to start with. Supporting more Transports will improve the ability of your node to speak to a larger number of nodes on the network, as matching Transports are required for two nodes to communicate with one another.

You should select Transports according to the runtime of your application; Node.js or the browser. You can see a list of some of the available Transports in the [configuration readme](./CONFIGURATION.md#transport). For this guide let's install `libp2p-websockets`, as it can be used in both Node.js and the browser.
You should select Transports according to the runtime of your application; Node.js or the browser. You can see a list of some of the available Transports in the [configuration readme](./CONFIGURATION.md#transport). For this guide let's install `@libp2p/websockets`, as it can be used in both Node.js and the browser.

Start by installing `libp2p-websockets`:
Start by installing `@libp2p/websockets`:

```sh
npm install libp2p-websockets
npm install @libp2p/websockets
```

Now that we have the module installed, let's configure libp2p to use the Transport. We'll use the [`Libp2p.create`](./API.md#create) method, which takes a single configuration object as its only parameter. We can add the Transport by passing it into the `modules.transport` array:
Expand All @@ -66,13 +66,13 @@ If you want to know more about libp2p transports, you should read the following

Encryption is an important part of communicating on the libp2p network. Every connection must be encrypted to help ensure security for everyone. As such, Connection Encryption (Crypto) is a required component of libp2p.

There are a growing number of Crypto modules being developed for libp2p. As those are released they will be tracked in the [Connection Encryption section of the configuration readme](./CONFIGURATION.md#connection-encryption). For now, we are going to configure our node to use the `libp2p-noise` module.
There are a growing number of Crypto modules being developed for libp2p. As those are released they will be tracked in the [Connection Encryption section of the configuration readme](./CONFIGURATION.md#connection-encryption). For now, we are going to configure our node to use the `@chainsafe/libp2p-noise` module.

```sh
npm install @chainsafe/libp2p-noise
```

With `libp2p-noise` installed, we can add it to our existing configuration by importing it and adding it to the `modules.connEncryption` array:
With `@chainsafe/libp2p-noise` installed, we can add it to our existing configuration by importing it and adding it to the `modules.connEncryption` array:

```js
import { createLibp2p } from 'libp2p'
Expand All @@ -96,12 +96,12 @@ If you want to know more about libp2p connection encryption, you should read the

While multiplexers are not strictly required, they are highly recommended as they improve the effectiveness and efficiency of connections for the various protocols libp2p runs. Adding a multiplexer to your configuration will allow libp2p to run several of its internal protocols, like Identify, as well as allow your application to easily run any number of protocols over a single connection.

Looking at the [available stream multiplexing](./CONFIGURATION.md#stream-multiplexing) modules, js-libp2p currently only supports `libp2p-mplex`, so we will use that here. Bear in mind that future libp2p Transports might have `multiplexing` capabilities already built-in (such as `QUIC`).
Looking at the [available stream multiplexing](./CONFIGURATION.md#stream-multiplexing) modules, js-libp2p currently only supports `@libp2p/mplex`, so we will use that here. Bear in mind that future libp2p Transports might have `multiplexing` capabilities already built-in (such as `QUIC`).

You can install `libp2p-mplex` and add it to your libp2p node as follows in the next example.
You can install `@libp2p/mplex` and add it to your libp2p node as follows in the next example.

```sh
npm install libp2p-mplex
npm install @libp2p/mplex
```

```js
Expand Down Expand Up @@ -148,12 +148,9 @@ const node = await createLibp2p({
await node.start()
console.log('libp2p has started')

const listenAddrs = node.transportManager.getAddrs()
const listenAddrs = node.getMultiaddrs()
console.log('libp2p is listening on the following addresses: ', listenAddrs)

const advertiseAddrs = node.multiaddrs
console.log('libp2p is advertising the following addresses: ', advertiseAddrs)

// stop libp2p
await node.stop()
console.log('libp2p has stopped')
Expand All @@ -170,17 +167,17 @@ Peer discovery is an important part of creating a well connected libp2p node. A
For each discovered peer libp2p will emit a `peer:discovery` event which includes metadata about that peer. You can read the [Events](./API.md#events) in the API doc to learn more.

Looking at the [available peer discovery](./CONFIGURATION.md#peer-discovery) protocols, there are several options to be considered:
- If you already know the addresses of some other network peers, you should consider using `libp2p-bootstrap` as this is the easiest way of getting your peer into the network.
- If it is likely that you will have other peers on your local network, `libp2p-mdns` is a must if you're node is not running in the browser. It allows peers to discover each other when on the same local network.
- If your application is browser based you can use the `libp2p-webrtc-star` Transport, which includes a rendezvous based peer sharing service.
- A random walk approach can be used via `libp2p-kad-dht`, to crawl the network and find new peers along the way.
- If you already know the addresses of some other network peers, you should consider using `@libp2p/bootstrap` as this is the easiest way of getting your peer into the network.
- If it is likely that you will have other peers on your local network, `@libp2p/mdns` is a must if you're node is not running in the browser. It allows peers to discover each other when on the same local network.
- If your application is browser based you can use the `@libp2p/webrtc-star` Transport, which includes a rendezvous based peer sharing service.
- A random walk approach can be used via `@libp2p/kad-dht`, to crawl the network and find new peers along the way.

For this guide we will configure `libp2p-bootstrap` as this is useful for joining the public network.
For this guide we will configure `@libp2p/bootstrap` as this is useful for joining the public network.

Let's install `libp2p-bootstrap`.
Let's install `@libp2p/bootstrap`.

```sh
npm install libp2p-bootstrap
npm install @libp2p/bootstrap
```

We can provide specific configurations for each protocol within a `config.peerDiscovery` property in the options as shown below.
Expand Down Expand Up @@ -221,12 +218,12 @@ const node = await createLibp2p({
}
})

node.on('peer:discovery', (peer) => {
console.log('Discovered %s', peer.id.toB58String()) // Log discovered peer
node.addEventListener('peer:discovery', (evt) => {
console.log('Discovered %s', evt.detail.id.toString()) // Log discovered peer
})

node.connectionManager.on('peer:connect', (connection) => {
console.log('Connected to %s', connection.remotePeer.toB58String()) // Log connected peer
node.connectionManager.addEventListener('peer:connect', (evt) => {
console.log('Connected to %s', evt.detail.remotePeer.toString()) // Log connected peer
})

// start libp2p
Expand Down
18 changes: 9 additions & 9 deletions examples/auto-relay/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { Mplex } from '@libp2p/mplex'
const node = await createLibp2p({
transports: [new WebSockets()],
connectionEncryption: [new Noise()],
streamMuxers: [new Mplex()]
streamMuxers: [new Mplex()],
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0/ws']
// TODO check "What is next?" section
Expand All @@ -43,9 +43,9 @@ const node = await createLibp2p({

await node.start()

console.log(`Node started with id ${node.peerId.toB58String()}`)
console.log(`Node started with id ${node.peerId.toString()}`)
console.log('Listening on:')
node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`))
node.getMultiaddrs().forEach((ma) => console.log(ma.toString()))
```

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.
Expand Down Expand Up @@ -94,17 +94,17 @@ const node = await createLibp2p({
})

await node.start()
console.log(`Node started with id ${node.peerId.toB58String()}`)
console.log(`Node started with id ${node.peerId.toString()}`)

const conn = await node.dial(relayAddr)

console.log(`Connected to the HOP relay ${conn.remotePeer.toString()}`)

// Wait for connection and relay to be bind for the example purpose
node.peerStore.on('change:multiaddrs', ({ peerId }) => {
node.peerStore.addEventListener('change:multiaddrs', (evt) => {
// Updated self multiaddrs?
if (peerId.equals(node.peerId)) {
console.log(`Advertising with a relay address of ${node.multiaddrs[0].toString()}/p2p/${node.peerId.toB58String()}`)
if (evt.detail.peerId.equals(node.peerId)) {
console.log(`Advertising with a relay address of ${node.getMultiaddrs()[0].toString()}`)
}
})
```
Expand Down Expand Up @@ -151,7 +151,7 @@ const node = await createLibp2p({
})

await node.start()
console.log(`Node started with id ${node.peerId.toB58String()}`)
console.log(`Node started with id ${node.peerId.toString()}`)

const conn = await node.dial(autoRelayNodeAddr)
console.log(`Connected to the auto relay node via ${conn.remoteAddr.toString()}`)
Expand All @@ -176,4 +176,4 @@ As you can see from the output, the remote address of the established connection

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.
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.
112 changes: 70 additions & 42 deletions examples/discovery-mechanisms/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ First, we create our libp2p node.
```JavaScript
import { createLibp2p } from 'libp2p'
import { Bootstrap } from '@libp2p/bootstrap'
import { TCP } from '@libp2p/tcp'
import { Mplex } from '@libp2p/mplex'
import { Noise } from '@chainsafe/libp2p-noise'

const node = await createLibp2p({
transports: [
Expand Down Expand Up @@ -52,7 +55,6 @@ Now, once we create and start the node, we can listen for events such as `peer:d

```JavaScript
const node = await createLibp2p({
peerId,
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0']
},
Expand All @@ -73,13 +75,13 @@ const node = await createLibp2p({
]
})

node.connectionManager.on('peer:connect', (connection) => {
console.log('Connection established to:', connection.remotePeer.toB58String()) // Emitted when a new connection has been created
node.connectionManager.addEventListener('peer:connect', (evt) => {
console.log('Connection established to:', evt.detail.remotePeer.toString()) // Emitted when a new connection has been created
})

node.on('peer:discovery', (peerId) => {
node.addEventListener('peer:discovery', (evt) => {
// No need to dial, autoDial is on
console.log('Discovered:', peerId.toB58String())
console.log('Discovered:', evt.detail.id.toString())
})

await node.start()
Expand All @@ -105,16 +107,19 @@ Connection established to: QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb

## 2. MulticastDNS to find other peers in the network

For this example, we need `libp2p-mdns`, go ahead and `npm install` it. You can find the complete solution at [2.js](./2.js).
For this example, we need `@libp2p/mdns`, go ahead and `npm install` it. You can find the complete solution at [2.js](./2.js).

Update your libp2p configuration to include MulticastDNS.

```JavaScript
import { createLibp2p } from 'libp2p'
import { MulticastDNS } from '@libp2p/mdns'
import { TCP } from '@libp2p/tcp'
import { Mplex } from '@libp2p/mplex'
import { Noise } from '@chainsafe/libp2p-noise'

const createNode = () => {
return Libp2p.create({
return createLibp2p({
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0']
},
Expand Down Expand Up @@ -144,8 +149,8 @@ const [node1, node2] = await Promise.all([
createNode()
])

node1.on('peer:discovery', (peer) => console.log('Discovered:', peerId.toB58String()))
node2.on('peer:discovery', (peer) => console.log('Discovered:', peerId.toB58String()))
node1.addEventListener('peer:discovery', (evt) => console.log('Discovered:', evt.detail.id.toString()))
node2.addEventListener('peer:discovery', (evt) => console.log('Discovered:', evt.detail.id.toString()))

await Promise.all([
node1.start(),
Expand All @@ -163,7 +168,7 @@ Discovered: QmRcXXhtG8vTqwVBRonKWtV4ovDoC1Fe56WYtcrw694eiJ

## 3. Pubsub based Peer Discovery

For this example, we need [`libp2p-pubsub-peer-discovery`](https://github.com/libp2p/js-libp2p-pubsub-peer-discovery/), go ahead and `npm install` it. You also need to spin up a set of [`libp2p-relay-servers`](https://github.com/libp2p/js-libp2p-relay-server). These servers act as relay servers and a peer discovery source.
For this example, we need [`@libp2p/pubsub-peer-discovery`](https://github.com/libp2p/js-libp2p-pubsub-peer-discovery/), go ahead and `npm install` it. You also need to spin up a set of [`libp2p-relay-servers`](https://github.com/libp2p/js-libp2p-relay-server). These servers act as relay servers and a peer discovery source.

In the context of this example, we will create and run the `libp2p-relay-server` in the same code snippet. You can find the complete solution at [3.js](./3.js).

Expand All @@ -174,33 +179,35 @@ import { createLibp2p } from 'libp2p'
import { TCP } from '@libp2p/tcp'
import { Mplex } from '@libp2p/mplex'
import { Noise } from '@chainsafe/libp2p-noise'
import { Gossipsub } from 'libp2p-gossipsub'
import { GossipSub } from '@chainsafe/libp2p-gossipsub'
import { Bootstrap } from '@libp2p/bootstrap'
const PubsubPeerDiscovery from 'libp2p-pubsub-peer-discovery')
import { PubSubPeerDiscovery } from '@libp2p/pubsub-peer-discovery'

const createNode = async (bootstrapers) => {
const node = await createLibp2p({
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0']
},
transports: [
new TCP()
],
streamMuxers: [
new Mplex()
],
connectionEncryption: [
new Noise()
],
peerDiscovery: [
new Bootstrap({
interval: 60e3,
list: bootstrapers
}),
new PubsubPeerDiscovery({
interval: 1000
})
])
new TCP()
],
streamMuxers: [
new Mplex()
],
connectionEncryption: [
new Noise()
],
pubsub: new GossipSub({ allowPublishToZeroPeers: true }),
peerDiscovery: [
new Bootstrap({
interval: 60e3,
list: bootstrapers
}),
new PubSubPeerDiscovery({
interval: 1000
})
]
})

return node
}
Expand All @@ -209,28 +216,49 @@ 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 and the relay will advertise them.

```js
const relay = await createRelayServer({
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0']
}
const relay = await createLibp2p({
addresses: {
listen: [
'/ip4/0.0.0.0/tcp/0'
]
},
transports: [new TCP()],
streamMuxers: [new Mplex()],
connectionEncryption: [new Noise()],
pubsub: new GossipSub({ allowPublishToZeroPeers: true }),
peerDiscovery: [
new PubSubPeerDiscovery({
interval: 1000
})
],
relay: {
enabled: true, // Allows you to dial and accept relayed connections. Does not make you a relay.
hop: {
enabled: true // Allows you to be a relay for other peers
}
}
})
console.log(`libp2p relay starting with id: ${relay.peerId.toB58String()}`)

console.log(`libp2p relay starting with id: ${relay.peerId.toString()}`)

await relay.start()
const relayMultiaddrs = relay.multiaddrs.map((m) => `${m.toString()}/p2p/${relay.peerId.toB58String()}`)

const relayMultiaddrs = relay.getMultiaddrs()

const [node1, node2] = await Promise.all([
createNode(relayMultiaddrs),
createNode(relayMultiaddrs)
])

node1.on('peer:discovery', (peerId) => {
console.log(`Peer ${node1.peerId.toB58String()} discovered: ${peerId.toB58String()}`)
node1.addEventListener('peer:discovery', (evt) => {
console.log(`Peer ${node1.peerId.toString()} discovered: ${evt.detail.id.toString()}`)
})
node2.on('peer:discovery', (peerId) => {
console.log(`Peer ${node2.peerId.toB58String()} discovered: ${peerId.toB58String()}`)
node2.addEventListener('peer:discovery', (evt) => {
console.log(`Peer ${node2.peerId.toString()} discovered: ${evt.detail.id.toString()}`)
})

;[node1, node2].forEach((node, index) => console.log(`Node ${index} starting with id: ${node.peerId.toB58String()}`))
;[node1, node2].forEach((node, index) => console.log(`Node ${index} starting with id: ${node.peerId.toString()}`))

await Promise.all([
node1.start(),
node2.start()
Expand Down Expand Up @@ -258,6 +286,6 @@ This is really useful when running libp2p in constrained environments like a bro

There are plenty more Peer Discovery Mechanisms out there, you can:

- Find one in [libp2p-webrtc-star](https://github.com/libp2p/js-libp2p-webrtc-star). Yes, a transport with discovery capabilities! This happens because WebRTC requires a rendezvous point for peers to exchange [SDP](https://tools.ietf.org/html/rfc4317) offer, which means we have one or more points that can introduce peers to each other. Think of it as MulticastDNS for the Web, as in MulticastDNS only works in LAN.
- Any DHT will offer you a discovery capability. You can simple _random-walk_ the routing tables to find other peers to connect to. For example [libp2p-kad-dht](https://github.com/libp2p/js-libp2p-kad-dht) can be used for peer discovery. An example 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).
- 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 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!
Loading

0 comments on commit 6219841

Please sign in to comment.