mirror of https://github.com/waku-org/js-waku.git
Fix-up new bootstrap API
This commit is contained in:
parent
e47335f4c0
commit
284644b822
|
@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Test: Upgrade nim-waku node to v0.6.
|
- Test: Upgrade nim-waku node to v0.6.
|
||||||
- **Breaking**: Renamed `getBootstrapNodes` to `getNodesFromHostedJson`.
|
- **Breaking**: Renamed `getBootstrapNodes` to `getNodesFromHostedJson`.
|
||||||
- Minimum node version changed to 16.
|
- Minimum node version changed to 16.
|
||||||
|
- **Breaking**: Changed `Waku.create` bootstrap option from `{ bootstrap: boolean }` to `{ bootstrap: BootstrapOptions }`.
|
||||||
|
Replace `{ boostrap: true }` with `{ boostrap: { default: true } }` to retain same behaviour.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ export const PrivateMessageContentTopic =
|
||||||
'/eth-pm-wallet/1/private-message/proto';
|
'/eth-pm-wallet/1/private-message/proto';
|
||||||
|
|
||||||
export async function initWaku(): Promise<Waku> {
|
export async function initWaku(): Promise<Waku> {
|
||||||
const waku = await Waku.create({ bootstrap: true });
|
const waku = await Waku.create({ bootstrap: { default: true } });
|
||||||
|
|
||||||
// Wait to be connected to at least one peer
|
// Wait to be connected to at least one peer
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
|
|
|
@ -9,7 +9,7 @@ export const PublicKeyContentTopic = '/eth-pm/1/public-key/proto';
|
||||||
export const PrivateMessageContentTopic = '/eth-pm/1/private-message/proto';
|
export const PrivateMessageContentTopic = '/eth-pm/1/private-message/proto';
|
||||||
|
|
||||||
export async function initWaku(): Promise<Waku> {
|
export async function initWaku(): Promise<Waku> {
|
||||||
const waku = await Waku.create({ bootstrap: true });
|
const waku = await Waku.create({ bootstrap: { default: true } });
|
||||||
|
|
||||||
// Wait to be connected to at least one peer
|
// Wait to be connected to at least one peer
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
import { useEffect, useReducer, useState } from 'react';
|
import { useEffect, useReducer, useState } from 'react';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
import { PageDirection, getBootstrapNodes, Waku, WakuMessage } from 'js-waku';
|
import {
|
||||||
|
PageDirection,
|
||||||
|
getNodesFromHostedJson,
|
||||||
|
Waku,
|
||||||
|
WakuMessage,
|
||||||
|
} from 'js-waku';
|
||||||
import handleCommand from './command';
|
import handleCommand from './command';
|
||||||
import Room from './Room';
|
import Room from './Room';
|
||||||
import { WakuContext } from './WakuContext';
|
import { WakuContext } from './WakuContext';
|
||||||
|
@ -175,7 +180,9 @@ async function initWaku(setter: (waku: Waku) => void) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
bootstrap: getBootstrapNodes.bind({}, selectFleetEnv()),
|
bootstrap: {
|
||||||
|
getPeers: getNodesFromHostedJson.bind({}, selectFleetEnv()),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
setter(waku);
|
setter(waku);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import debug from 'debug';
|
import debug from 'debug';
|
||||||
|
import { Multiaddr } from 'multiaddr';
|
||||||
|
|
||||||
import { DnsNodeDiscovery } from './dns';
|
import { DnsNodeDiscovery } from './dns';
|
||||||
|
|
||||||
|
@ -6,7 +7,9 @@ import { getNodesFromHostedJson, getPseudoRandomSubset } from './index';
|
||||||
|
|
||||||
const dbg = debug('waku:discovery:bootstrap');
|
const dbg = debug('waku:discovery:bootstrap');
|
||||||
|
|
||||||
const DefaultMaxPeers = 1;
|
export const DefaultMaxPeers = 1;
|
||||||
|
|
||||||
|
export type BootstrapFn = () => Promise<Multiaddr[]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup discovery method used to bootstrap.
|
* Setup discovery method used to bootstrap.
|
||||||
|
@ -17,11 +20,11 @@ export interface BootstrapOptions {
|
||||||
/**
|
/**
|
||||||
* The maximum of peers to connect to as part of the bootstrap process.
|
* The maximum of peers to connect to as part of the bootstrap process.
|
||||||
*
|
*
|
||||||
* @default 1
|
* @default {{DefaultMaxPeers}}
|
||||||
*/
|
*/
|
||||||
maxPeers?: number;
|
maxPeers?: number;
|
||||||
/**
|
/**
|
||||||
* Use the default discovery method.
|
* Use the default discovery method. Overrides all other options but `maxPeers`
|
||||||
*
|
*
|
||||||
* The default discovery method is likely to change overtime as new discovery
|
* The default discovery method is likely to change overtime as new discovery
|
||||||
* methods are implemented.
|
* methods are implemented.
|
||||||
|
@ -36,7 +39,7 @@ export interface BootstrapOptions {
|
||||||
/**
|
/**
|
||||||
* Getter that retrieve multiaddrs of peers to connect to.
|
* Getter that retrieve multiaddrs of peers to connect to.
|
||||||
*/
|
*/
|
||||||
getPeers?: () => Promise<string[]>;
|
getPeers?: () => Promise<string[] | Multiaddr[]>;
|
||||||
/**
|
/**
|
||||||
* An EIP-1459 ENR Tree URL. For example:
|
* An EIP-1459 ENR Tree URL. For example:
|
||||||
* "enrtree://AOFTICU2XWDULNLZGRMQS4RIZPAZEHYMV4FYHAPW563HNRAOERP7C@test.nodes.vac.dev"
|
* "enrtree://AOFTICU2XWDULNLZGRMQS4RIZPAZEHYMV4FYHAPW563HNRAOERP7C@test.nodes.vac.dev"
|
||||||
|
@ -47,69 +50,54 @@ export interface BootstrapOptions {
|
||||||
/**
|
/**
|
||||||
* Parse the bootstrap options and returns an async function that returns node addresses upon invocation.
|
* Parse the bootstrap options and returns an async function that returns node addresses upon invocation.
|
||||||
*/
|
*/
|
||||||
export function parseBootstrap(
|
export function parseBootstrap(opts: BootstrapOptions): BootstrapFn {
|
||||||
options:
|
const maxPeers = opts.maxPeers ?? DefaultMaxPeers;
|
||||||
| BootstrapOptions
|
|
||||||
| boolean
|
|
||||||
| string[]
|
|
||||||
| (() => string[] | Promise<string[]>)
|
|
||||||
): undefined | (() => Promise<string[]>) {
|
|
||||||
if (
|
|
||||||
Object.keys(options).includes('default') ||
|
|
||||||
Object.keys(options).includes('maxPeers') ||
|
|
||||||
Object.keys(options).includes('peers') ||
|
|
||||||
Object.keys(options).includes('getPeers') ||
|
|
||||||
Object.keys(options).includes('enrUrl')
|
|
||||||
) {
|
|
||||||
const opts = options as unknown as BootstrapOptions;
|
|
||||||
const maxPeers = opts.maxPeers || DefaultMaxPeers;
|
|
||||||
|
|
||||||
if (opts.default) {
|
if (opts.default) {
|
||||||
dbg('Bootstrap: Use hosted list of peers.');
|
dbg('Bootstrap: Use hosted list of peers.');
|
||||||
|
|
||||||
return getNodesFromHostedJson.bind({}, undefined, undefined, maxPeers);
|
return getNodesFromHostedJson.bind({}, undefined, undefined, maxPeers);
|
||||||
} else if (opts.peers !== undefined && opts.peers.length > 0) {
|
} else if (opts.peers !== undefined && opts.peers.length > 0) {
|
||||||
dbg('Bootstrap: Use provided list of peers.');
|
dbg('Bootstrap: Use provided list of peers.');
|
||||||
|
|
||||||
const allPeers: string[] = opts.peers;
|
const allPeers: Multiaddr[] = opts.peers.map(
|
||||||
return (): Promise<string[]> => {
|
(node: string) => new Multiaddr(node)
|
||||||
const peers = getPseudoRandomSubset(allPeers, maxPeers);
|
|
||||||
return Promise.resolve(peers);
|
|
||||||
};
|
|
||||||
} else if (typeof opts.getPeers === 'function') {
|
|
||||||
dbg('Bootstrap: Use provided getPeers function.');
|
|
||||||
const getPeers = opts.getPeers;
|
|
||||||
|
|
||||||
return async (): Promise<string[]> => {
|
|
||||||
const allPeers = await getPeers();
|
|
||||||
return getPseudoRandomSubset(allPeers, maxPeers);
|
|
||||||
};
|
|
||||||
} else if (opts.enrUrl) {
|
|
||||||
const enrUrl = opts.enrUrl;
|
|
||||||
dbg('Bootstrap: Use provided EIP-1459 ENR Tree URL.');
|
|
||||||
|
|
||||||
const dns = DnsNodeDiscovery.dnsOverHttp();
|
|
||||||
// TODO: The `toString` is incorrect.
|
|
||||||
return (): Promise<string[]> =>
|
|
||||||
dns
|
|
||||||
.getPeers(maxPeers, [enrUrl])
|
|
||||||
.then((peers) => peers.map((peer) => peer.toString()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dbg(
|
|
||||||
'WARN: This bootstrap method will be deprecated, use `BootstrapOptions` instead'
|
|
||||||
);
|
);
|
||||||
if (options === true) {
|
const peers = getPseudoRandomSubset(allPeers, maxPeers);
|
||||||
return getNodesFromHostedJson;
|
return (): Promise<Multiaddr[]> => Promise.resolve(peers);
|
||||||
} else if (Array.isArray(options)) {
|
} else if (typeof opts.getPeers === 'function') {
|
||||||
return (): Promise<string[]> => {
|
dbg('Bootstrap: Use provided getPeers function.');
|
||||||
return Promise.resolve(options as string[]);
|
const getPeers = opts.getPeers;
|
||||||
};
|
|
||||||
} else if (typeof options === 'function') {
|
return async (): Promise<Multiaddr[]> => {
|
||||||
return async (): Promise<string[]> => {
|
const allPeers = await getPeers();
|
||||||
return options();
|
return getPseudoRandomSubset<string | Multiaddr>(allPeers, maxPeers).map(
|
||||||
};
|
(node) => new Multiaddr(node)
|
||||||
}
|
);
|
||||||
|
};
|
||||||
|
} else if (opts.enrUrl) {
|
||||||
|
const enrUrl = opts.enrUrl;
|
||||||
|
dbg('Bootstrap: Use provided EIP-1459 ENR Tree URL.');
|
||||||
|
|
||||||
|
const dns = DnsNodeDiscovery.dnsOverHttp();
|
||||||
|
|
||||||
|
return async (): Promise<Multiaddr[]> => {
|
||||||
|
const enrs = await dns.getPeers(maxPeers, [enrUrl]);
|
||||||
|
const addresses: Multiaddr[] = [];
|
||||||
|
enrs.forEach((enr) => {
|
||||||
|
if (!enr.multiaddrs) return;
|
||||||
|
|
||||||
|
enr.multiaddrs.forEach((ma: Multiaddr) => {
|
||||||
|
// Only return secure websocket addresses
|
||||||
|
if (ma.protoNames().includes('wss')) {
|
||||||
|
addresses.push(ma);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return addresses;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
dbg('No bootstrap method specified, no peer will be returned');
|
||||||
|
return (): Promise<Multiaddr[]> => Promise.resolve([]);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ export async function getNodesFromHostedJson(
|
||||||
path: string[] = ['fleets', 'wakuv2.prod', 'waku-websocket'],
|
path: string[] = ['fleets', 'wakuv2.prod', 'waku-websocket'],
|
||||||
url = 'https://fleets.status.im/',
|
url = 'https://fleets.status.im/',
|
||||||
wantedNumber: number = DefaultWantedNumber
|
wantedNumber: number = DefaultWantedNumber
|
||||||
): Promise<string[]> {
|
): Promise<Multiaddr[]> {
|
||||||
if (wantedNumber <= 0) {
|
if (wantedNumber <= 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -54,12 +54,12 @@ export async function getNodesFromHostedJson(
|
||||||
|
|
||||||
if (Array.isArray(nodes)) {
|
if (Array.isArray(nodes)) {
|
||||||
return getPseudoRandomSubset(nodes, wantedNumber).map(
|
return getPseudoRandomSubset(nodes, wantedNumber).map(
|
||||||
(node: string) => node
|
(node: string) => new Multiaddr(node)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof nodes === 'string') {
|
if (typeof nodes === 'string') {
|
||||||
return [nodes];
|
return [new Multiaddr(nodes)];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof nodes === 'object') {
|
if (typeof nodes === 'object') {
|
||||||
|
|
|
@ -3,10 +3,10 @@ import { shuffle } from 'libp2p-gossipsub/src/utils';
|
||||||
export { getNodesFromHostedJson } from './hosted_json';
|
export { getNodesFromHostedJson } from './hosted_json';
|
||||||
export { parseBootstrap } from './bootstrap';
|
export { parseBootstrap } from './bootstrap';
|
||||||
|
|
||||||
export function getPseudoRandomSubset(
|
export function getPseudoRandomSubset<T>(
|
||||||
values: string[],
|
values: T[],
|
||||||
wantedNumber: number
|
wantedNumber: number
|
||||||
): string[] {
|
): T[] {
|
||||||
if (values.length <= wantedNumber) {
|
if (values.length <= wantedNumber) {
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ describe('Waku Dial [node only]', function () {
|
||||||
|
|
||||||
waku = await Waku.create({
|
waku = await Waku.create({
|
||||||
staticNoiseKey: NOISE_KEY_1,
|
staticNoiseKey: NOISE_KEY_1,
|
||||||
bootstrap: true,
|
bootstrap: { default: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
const connectedPeerID: PeerId = await new Promise((resolve) => {
|
const connectedPeerID: PeerId = await new Promise((resolve) => {
|
||||||
|
@ -68,7 +68,7 @@ describe('Waku Dial [node only]', function () {
|
||||||
libp2p: {
|
libp2p: {
|
||||||
modules: { transport: [TCP] },
|
modules: { transport: [TCP] },
|
||||||
},
|
},
|
||||||
bootstrap: [multiAddrWithId],
|
bootstrap: { peers: [multiAddrWithId] },
|
||||||
});
|
});
|
||||||
|
|
||||||
const connectedPeerID: PeerId = await new Promise((resolve) => {
|
const connectedPeerID: PeerId = await new Promise((resolve) => {
|
||||||
|
@ -102,8 +102,10 @@ describe('Waku Dial [node only]', function () {
|
||||||
libp2p: {
|
libp2p: {
|
||||||
modules: { transport: [TCP] },
|
modules: { transport: [TCP] },
|
||||||
},
|
},
|
||||||
bootstrap: () => {
|
bootstrap: {
|
||||||
return [multiAddrWithId];
|
getPeers: async () => {
|
||||||
|
return [multiAddrWithId];
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { Multiaddr, multiaddr } from 'multiaddr';
|
||||||
import PeerId from 'peer-id';
|
import PeerId from 'peer-id';
|
||||||
|
|
||||||
import { parseBootstrap } from './discovery';
|
import { parseBootstrap } from './discovery';
|
||||||
|
import { BootstrapOptions } from './discovery/bootstrap';
|
||||||
import { getPeersForProtocol } from './select_peer';
|
import { getPeersForProtocol } from './select_peer';
|
||||||
import { LightPushCodec, WakuLightPush } from './waku_light_push';
|
import { LightPushCodec, WakuLightPush } from './waku_light_push';
|
||||||
import { WakuMessage } from './waku_message';
|
import { WakuMessage } from './waku_message';
|
||||||
|
@ -86,12 +87,12 @@ export interface CreateOptions {
|
||||||
/**
|
/**
|
||||||
* Use libp2p-bootstrap to discover and connect to new nodes.
|
* Use libp2p-bootstrap to discover and connect to new nodes.
|
||||||
*
|
*
|
||||||
* See [BootstrapOptions] for available parameters.
|
* See [[BootstrapOptions]] for available parameters.
|
||||||
*
|
*
|
||||||
* Note: It overrides any other peerDiscovery modules that may have been set via
|
* Note: It overrides any other peerDiscovery modules that may have been set via
|
||||||
* {@link CreateOptions.libp2p}.
|
* {@link CreateOptions.libp2p}.
|
||||||
*/
|
*/
|
||||||
bootstrap?: boolean | string[] | (() => string[] | Promise<string[]>);
|
bootstrap?: BootstrapOptions;
|
||||||
decryptionKeys?: Array<Uint8Array | string>;
|
decryptionKeys?: Array<Uint8Array | string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue