mirror of https://github.com/waku-org/js-waku.git
Predefine bootstrap node (#528)
This commit is contained in:
parent
9e6cb1faaa
commit
146c67e43e
|
@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Ran `npm audit fix`.
|
||||
- `Waku.dial` accepts protocols expected from the peer. Defaults to Waku Relay only.
|
||||
- Deprecated `hexToBuf` & `bufToHex` in favour of `hexToBytes` & `bytesToHex` to move towards removing the `buffer` polyfill.
|
||||
- **Breaking**: Replaced `getNodesFromHostedJson` with `getPredefinedBootstrapNodes`. Now, it uses a hardcoded list of nodes.
|
||||
|
||||
### Removed
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import { useEffect, useReducer, useState } from "react";
|
|||
import "./App.css";
|
||||
import {
|
||||
PageDirection,
|
||||
getNodesFromHostedJson,
|
||||
getPredefinedBootstrapNodes,
|
||||
Waku,
|
||||
WakuMessage,
|
||||
} from "js-waku";
|
||||
|
@ -12,6 +12,7 @@ import { WakuContext } from "./WakuContext";
|
|||
import { ThemeProvider } from "@livechat/ui-kit";
|
||||
import { generate } from "server-name-generator";
|
||||
import { Message } from "./Message";
|
||||
import { Fleet } from "js-waku/lib/discovery/predefined";
|
||||
|
||||
const themes = {
|
||||
AuthorName: {
|
||||
|
@ -184,7 +185,8 @@ async function initWaku(setter: (waku: Waku) => void) {
|
|||
},
|
||||
},
|
||||
bootstrap: {
|
||||
getPeers: getNodesFromHostedJson.bind({}, selectFleetEnv()),
|
||||
getPeers: () =>
|
||||
Promise.resolve(getPredefinedBootstrapNodes(selectFleetEnv())),
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -197,9 +199,9 @@ async function initWaku(setter: (waku: Waku) => void) {
|
|||
function selectFleetEnv() {
|
||||
// Works with react-scripts
|
||||
if (process?.env?.NODE_ENV === "development") {
|
||||
return ["fleets", "wakuv2.test", "waku-websocket"];
|
||||
return Fleet.Test;
|
||||
} else {
|
||||
return ["fleets", "wakuv2.prod", "waku-websocket"];
|
||||
return Fleet.Prod;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export { getNodesFromHostedJson } from "./lib/discovery";
|
||||
export { getPredefinedBootstrapNodes } from "./lib/discovery";
|
||||
export * as discovery from "./lib/discovery";
|
||||
|
||||
export * as enr from "./lib/enr";
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Multiaddr } from "multiaddr";
|
|||
|
||||
import { DnsNodeDiscovery } from "./dns";
|
||||
|
||||
import { getNodesFromHostedJson, getPseudoRandomSubset } from "./index";
|
||||
import { getPredefinedBootstrapNodes, getPseudoRandomSubset } from "./index";
|
||||
|
||||
const dbg = debug("waku:discovery:bootstrap");
|
||||
|
||||
|
@ -57,12 +57,11 @@ export class Bootstrap {
|
|||
if (opts.default) {
|
||||
dbg("Use hosted list of peers.");
|
||||
|
||||
this.getBootstrapPeers = getNodesFromHostedJson.bind(
|
||||
{},
|
||||
undefined,
|
||||
undefined,
|
||||
maxPeers
|
||||
this.getBootstrapPeers = (): Promise<Multiaddr[]> => {
|
||||
return Promise.resolve(
|
||||
getPredefinedBootstrapNodes(undefined, maxPeers)
|
||||
);
|
||||
};
|
||||
} else if (opts.peers !== undefined && opts.peers.length > 0) {
|
||||
const allPeers: Multiaddr[] = opts.peers.map(
|
||||
(node: string) => new Multiaddr(node)
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
/**
|
||||
* GET list of nodes from remote HTTP host.
|
||||
*
|
||||
* Default behavior is to return nodes hosted by Status.
|
||||
*
|
||||
* @param path The property path to access the node list. The result should be
|
||||
* a string, a string array or an object. If the result is an object then the
|
||||
* values of the objects are used as multiaddresses. For example, if the GET
|
||||
* request returns `{ foo: { bar: [address1, address2] } }` then `path` should be
|
||||
* `[ "foo", "bar" ]`.
|
||||
* @param url Remote host containing bootstrap peers in JSON format.
|
||||
* @param wantedNumber The number of connections desired. Defaults to [DefaultWantedNumber].
|
||||
*
|
||||
* @returns An array of multiaddresses.
|
||||
* @throws If the remote host is unreachable or the response cannot be parsed
|
||||
* according to the passed _path_.
|
||||
*/
|
||||
import debug from "debug";
|
||||
import { Multiaddr } from "multiaddr";
|
||||
|
||||
import { getPseudoRandomSubset } from "./index";
|
||||
const dbg = debug("waku:discovery");
|
||||
|
||||
const DefaultWantedNumber = 1;
|
||||
|
||||
export async function getNodesFromHostedJson(
|
||||
path: string[] = ["fleets", "wakuv2.prod", "waku-websocket"],
|
||||
url = "https://fleets.status.im/",
|
||||
wantedNumber: number = DefaultWantedNumber
|
||||
): Promise<Multiaddr[]> {
|
||||
if (wantedNumber <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const res = await fetch(url);
|
||||
let nodes = await res.json();
|
||||
|
||||
for (const prop of path) {
|
||||
if (nodes[prop] === undefined) {
|
||||
dbg(
|
||||
`Failed to retrieve bootstrap nodes: ${prop} does not exist on `,
|
||||
nodes
|
||||
);
|
||||
throw `Failed to retrieve bootstrap nodes: ${prop} does not exist on ${JSON.stringify(
|
||||
nodes
|
||||
)}`;
|
||||
}
|
||||
nodes = nodes[prop];
|
||||
}
|
||||
|
||||
if (Array.isArray(nodes)) {
|
||||
return getPseudoRandomSubset(nodes, wantedNumber).map(
|
||||
(node: string) => new Multiaddr(node)
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof nodes === "string") {
|
||||
return [new Multiaddr(nodes)];
|
||||
}
|
||||
|
||||
if (typeof nodes === "object") {
|
||||
nodes = Object.values(nodes) as string[];
|
||||
nodes = nodes.map((node: string) => new Multiaddr(node));
|
||||
return getPseudoRandomSubset(nodes, wantedNumber);
|
||||
}
|
||||
|
||||
throw `Failed to retrieve bootstrap nodes: response format is not supported: ${JSON.stringify(
|
||||
nodes
|
||||
)}`;
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
import { expect } from "chai";
|
||||
|
||||
import { getNodesFromHostedJson, getPseudoRandomSubset } from "./index";
|
||||
import { fleets } from "./predefined";
|
||||
|
||||
import { getPseudoRandomSubset } from "./index";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
|
@ -51,14 +53,15 @@ describe("Discovery [live data]", function () {
|
|||
}
|
||||
});
|
||||
|
||||
it("Returns nodes from default hosted JSON [live data]", async function () {
|
||||
const res = await getNodesFromHostedJson(
|
||||
["fleets", "wakuv2.prod", "waku-websocket"],
|
||||
"https://fleets.status.im/",
|
||||
3
|
||||
);
|
||||
it("Check pre-defined nodes against hosted JSON [live data]", async function () {
|
||||
const res = await fetch("https://fleets.status.im/");
|
||||
const nodes = await res.json();
|
||||
|
||||
expect(res.length).to.eq(3);
|
||||
expect(res[0].toString()).to.not.be.undefined;
|
||||
expect(fleets.fleets["wakuv2.prod"]["waku-websocket"]).to.deep.eq(
|
||||
nodes.fleets["wakuv2.prod"]["waku-websocket"]
|
||||
);
|
||||
expect(fleets.fleets["wakuv2.test"]["waku-websocket"]).to.deep.eq(
|
||||
nodes.fleets["wakuv2.test"]["waku-websocket"]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { shuffle } from "libp2p-gossipsub/src/utils";
|
||||
|
||||
export { getNodesFromHostedJson } from "./hosted_json";
|
||||
export { getPredefinedBootstrapNodes } from "./predefined";
|
||||
export * as predefined from "./predefined";
|
||||
export { Bootstrap, BootstrapOptions } from "./bootstrap";
|
||||
export { DnsClient, DnsNodeDiscovery, SearchContext } from "./dns";
|
||||
export { Endpoints, DnsOverHttps } from "./dns_over_https";
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
import { Multiaddr } from "multiaddr";
|
||||
|
||||
import { getPseudoRandomSubset } from "./index";
|
||||
|
||||
export const DefaultWantedNumber = 1;
|
||||
|
||||
export enum Fleet {
|
||||
Prod = "prod",
|
||||
Test = "test",
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list of pre-defined (hardcoded) bootstrap nodes.
|
||||
*
|
||||
* Default behavior is to return nodes of the nim-waku Status Prod fleet.
|
||||
*
|
||||
* @param fleet The fleet to be returned. Defaults to production fleet.
|
||||
* @param wantedNumber The number of connections desired. Defaults to [[DefaultWantedNumber]].
|
||||
*
|
||||
* @returns An array of multiaddresses.
|
||||
*/
|
||||
export function getPredefinedBootstrapNodes(
|
||||
fleet: Fleet = Fleet.Prod,
|
||||
wantedNumber: number = DefaultWantedNumber
|
||||
): Multiaddr[] {
|
||||
if (wantedNumber <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
let nodes;
|
||||
switch (fleet) {
|
||||
case Fleet.Prod:
|
||||
nodes = fleets.fleets["wakuv2.prod"]["waku-websocket"];
|
||||
break;
|
||||
case Fleet.Test:
|
||||
nodes = fleets.fleets["wakuv2.test"]["waku-websocket"];
|
||||
break;
|
||||
default:
|
||||
nodes = fleets.fleets["wakuv2.prod"]["waku-websocket"];
|
||||
}
|
||||
|
||||
nodes = Object.values(nodes) as string[];
|
||||
|
||||
nodes = nodes.map((node: string) => new Multiaddr(node));
|
||||
return getPseudoRandomSubset(nodes, wantedNumber);
|
||||
}
|
||||
|
||||
export const fleets = {
|
||||
fleets: {
|
||||
"wakuv2.prod": {
|
||||
"waku-websocket": {
|
||||
"node-01.ac-cn-hongkong-c.wakuv2.prod":
|
||||
"/dns4/node-01.ac-cn-hongkong-c.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD",
|
||||
"node-01.do-ams3.wakuv2.prod":
|
||||
"/dns4/node-01.do-ams3.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
|
||||
"node-01.gc-us-central1-a.wakuv2.prod":
|
||||
"/dns4/node-01.gc-us-central1-a.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA",
|
||||
},
|
||||
},
|
||||
"wakuv2.test": {
|
||||
"waku-websocket": {
|
||||
"node-01.ac-cn-hongkong-c.wakuv2.test":
|
||||
"/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm",
|
||||
"node-01.do-ams3.wakuv2.test":
|
||||
"/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
|
||||
"node-01.gc-us-central1-a.wakuv2.test":
|
||||
"/dns4/node-01.gc-us-central1-a.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
Loading…
Reference in New Issue