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`.
|
- Ran `npm audit fix`.
|
||||||
- `Waku.dial` accepts protocols expected from the peer. Defaults to Waku Relay only.
|
- `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.
|
- 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
|
### Removed
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { useEffect, useReducer, useState } from "react";
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
import {
|
import {
|
||||||
PageDirection,
|
PageDirection,
|
||||||
getNodesFromHostedJson,
|
getPredefinedBootstrapNodes,
|
||||||
Waku,
|
Waku,
|
||||||
WakuMessage,
|
WakuMessage,
|
||||||
} from "js-waku";
|
} from "js-waku";
|
||||||
|
@ -12,6 +12,7 @@ import { WakuContext } from "./WakuContext";
|
||||||
import { ThemeProvider } from "@livechat/ui-kit";
|
import { ThemeProvider } from "@livechat/ui-kit";
|
||||||
import { generate } from "server-name-generator";
|
import { generate } from "server-name-generator";
|
||||||
import { Message } from "./Message";
|
import { Message } from "./Message";
|
||||||
|
import { Fleet } from "js-waku/lib/discovery/predefined";
|
||||||
|
|
||||||
const themes = {
|
const themes = {
|
||||||
AuthorName: {
|
AuthorName: {
|
||||||
|
@ -184,7 +185,8 @@ async function initWaku(setter: (waku: Waku) => void) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
bootstrap: {
|
bootstrap: {
|
||||||
getPeers: getNodesFromHostedJson.bind({}, selectFleetEnv()),
|
getPeers: () =>
|
||||||
|
Promise.resolve(getPredefinedBootstrapNodes(selectFleetEnv())),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -197,9 +199,9 @@ async function initWaku(setter: (waku: Waku) => void) {
|
||||||
function selectFleetEnv() {
|
function selectFleetEnv() {
|
||||||
// Works with react-scripts
|
// Works with react-scripts
|
||||||
if (process?.env?.NODE_ENV === "development") {
|
if (process?.env?.NODE_ENV === "development") {
|
||||||
return ["fleets", "wakuv2.test", "waku-websocket"];
|
return Fleet.Test;
|
||||||
} else {
|
} 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 discovery from "./lib/discovery";
|
||||||
|
|
||||||
export * as enr from "./lib/enr";
|
export * as enr from "./lib/enr";
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Multiaddr } from "multiaddr";
|
||||||
|
|
||||||
import { DnsNodeDiscovery } from "./dns";
|
import { DnsNodeDiscovery } from "./dns";
|
||||||
|
|
||||||
import { getNodesFromHostedJson, getPseudoRandomSubset } from "./index";
|
import { getPredefinedBootstrapNodes, getPseudoRandomSubset } from "./index";
|
||||||
|
|
||||||
const dbg = debug("waku:discovery:bootstrap");
|
const dbg = debug("waku:discovery:bootstrap");
|
||||||
|
|
||||||
|
@ -57,12 +57,11 @@ export class Bootstrap {
|
||||||
if (opts.default) {
|
if (opts.default) {
|
||||||
dbg("Use hosted list of peers.");
|
dbg("Use hosted list of peers.");
|
||||||
|
|
||||||
this.getBootstrapPeers = getNodesFromHostedJson.bind(
|
this.getBootstrapPeers = (): Promise<Multiaddr[]> => {
|
||||||
{},
|
return Promise.resolve(
|
||||||
undefined,
|
getPredefinedBootstrapNodes(undefined, maxPeers)
|
||||||
undefined,
|
|
||||||
maxPeers
|
|
||||||
);
|
);
|
||||||
|
};
|
||||||
} else if (opts.peers !== undefined && opts.peers.length > 0) {
|
} else if (opts.peers !== undefined && opts.peers.length > 0) {
|
||||||
const allPeers: Multiaddr[] = opts.peers.map(
|
const allPeers: Multiaddr[] = opts.peers.map(
|
||||||
(node: string) => new Multiaddr(node)
|
(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 { expect } from "chai";
|
||||||
|
|
||||||
import { getNodesFromHostedJson, getPseudoRandomSubset } from "./index";
|
import { fleets } from "./predefined";
|
||||||
|
|
||||||
|
import { getPseudoRandomSubset } from "./index";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -51,14 +53,15 @@ describe("Discovery [live data]", function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Returns nodes from default hosted JSON [live data]", async function () {
|
it("Check pre-defined nodes against hosted JSON [live data]", async function () {
|
||||||
const res = await getNodesFromHostedJson(
|
const res = await fetch("https://fleets.status.im/");
|
||||||
["fleets", "wakuv2.prod", "waku-websocket"],
|
const nodes = await res.json();
|
||||||
"https://fleets.status.im/",
|
|
||||||
3
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(res.length).to.eq(3);
|
expect(fleets.fleets["wakuv2.prod"]["waku-websocket"]).to.deep.eq(
|
||||||
expect(res[0].toString()).to.not.be.undefined;
|
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";
|
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 { Bootstrap, BootstrapOptions } from "./bootstrap";
|
||||||
export { DnsClient, DnsNodeDiscovery, SearchContext } from "./dns";
|
export { DnsClient, DnsNodeDiscovery, SearchContext } from "./dns";
|
||||||
export { Endpoints, DnsOverHttps } from "./dns_over_https";
|
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