Discovery & Bootstrap Nodes

Discovery & Bootstrap Nodes #

This guide explains the discovery and bootstrap mechanisms currently available in js-waku, their benefits and caveats and how to use them.

Node discovery is the mechanism that enables a Waku node to find other nodes. Waku is a modular protocol, several discovery mechanisms are and will be included in Waku so that developers can select the best mechanism(s) based for their use case and the user’s environment (e.g. mobile phone, desktop browser, server, etc).

When starting a Waku node, it needs to connect to other nodes to be able to send, receive and retrieve messages. Which means there needs to be a discovery mechanism that enable finding other nodes when not connected to any node. This is called bootstrapping.

Once connected, the node needs to find additional peers to have:

  • Enough peers in the Waku Relay mesh (target is 6),
  • Enough peers in reserve, in case current peers are overloaded or go offline,
  • Peers with specific Waku capabilities (e.g. Store, Light Push, Filter).

For now, we are focusing in making bootstrap discovery protocols available, research of other discovery protocols is in progress.

Default Bootstrap Mechanism #

The default bootstrap mechanism is to connect to the Status' nim-waku prod fleet.

To use:

const waku = await Waku.create({ bootstrap: { default: true } });

When creating a Waku node without passing the bootstrap option, the node does not connect to any remote peer or bootstrap node.

As the current strategy is to connect to nodes operated by Status, we want to ensure that developers consciously opt-in while providing a friendly developer experience.

We intend to change this in the future and enable bootstrap by default once we have implemented more decentralized strategies.

Predefined Bootstrap Nodes #

Addresses of nodes hosted by Status are predefined in the codebase:

https://github.com/status-im/js-waku/blob/e4024d5c7246535ddab28a4262006915d2db58be/src/lib/discovery/predefined.ts#L48

They can be accessed via the getPredefinedBootstrapNodes function.

Pros:

  • Low latency,
  • Low resource requirements.

Cons:

  • Prone to censorship: node ips can be blocked,
  • Limited: Static number of nodes,
  • Poor maintainability: Code needs to be changed to update the list.

Nwaku Prod Fleet #

The nwaku prod fleet run the latest nwaku release. The fleet aims to provide a stable, yet not warranted, service.

import { Waku } from "js-waku";

const waku = await Waku.create({
  bootstrap: {
    peers: getPredefinedBootstrapNodes(),
  },
});

Nwaku Test Fleet #

The nwaku test fleet run the latest commit from nwaku’s master branch. The fleet is subject to frequent database reset, hence messages are generally kept in store nodes for a few days at a time.

import { Waku, discovery } from "js-waku";

const waku = await Waku.create({
  bootstrap: {
    peers: getPredefinedBootstrapNodes(discovery.predefined.Fleet.Test),
  },
});

Use your own nodes #

Developers have the choice to run their own nwaku nodes and use them to bootstrap js-waku nodes.

There are two ways to set bootstrap nodes:

  1. Using an array of multiaddrs (as string or Multiaddr):
import { Waku } from "js-waku";

const waku = await Waku.create({
  bootstrap: {
    peers: [
      "/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm",
    ],
  },
});
  1. Passing an async function that returns an array of multiaddr (as string or Multiaddr):
import { Waku } from "js-waku";

const waku = await Waku.create({
  bootstrap: {
    getPeers: async () => {
      const addresses = [];
      // Fetch the multiaddrs from somewhere...
      return addresses;
    },
  },
});
Read Nwaku Service Node to learn how to run your own node.

Pros & Cons: Same than Predefined Bootstrap Nodes

DNS Discovery #

EIP-1459: Node Discovery via DNS has been implemented in js-waku, nwaku and go-waku with some modification on the ENR format.

DNS Discovery enables anyone to register an ENR tree in the TXT field of a domain name.

ENR is the format used to store node connection details (ip, port, multiaddr, etc).

This enables a separation of software development and operations as dApp developers can include one or several domain names to use for DNS discovery, while operators can handle the update of the dns record.

It also enables more decentralized bootstrapping as anyone can register a domain name and publish it for others to use.

While this method is implemented in js-waku, it is currently not recommended to use due to a bug in the websocket implementation of nwaku.

The nwaku prod fleet and test fleet have a websockify instance deployed alongside nwaku, acting as a work around the nwaku websocket bug.

Pros:

  • Low latency, low resource requirements,
  • Bootstrap list can be updated by editing a domain name: no code change is needed,
  • Can reference to a greater list of nodes by pointing to other domain names in the code or in the ENR tree.

Cons:

  • Prone to censorship: domain names can be blocked,
  • Limited: Static number of nodes, operators must provide their ENR to the domain owner to get their node listed.

Other Discovery Mechanisms #

Other discovery mechanisms such as gossipsub peer exchange, discv5, etc are currently being research and developed.

They aim to improve the current status quo in the following aspects:

  • More decentralized mechanisms: Less reliance on specific entities,
  • Less setup for node operators: Enabling their nodes to be discovered by connecting to bootstrap nodes, without having to update a domain name.