2022-02-04 14:12:00 +11:00
|
|
|
import debug from "debug";
|
|
|
|
|
import { Multiaddr } from "multiaddr";
|
2022-01-13 11:33:26 +11:00
|
|
|
|
2022-05-04 20:07:21 +10:00
|
|
|
import { DnsNodeDiscovery, NodeCapabilityCount } from "./dns";
|
2022-01-13 11:33:26 +11:00
|
|
|
|
2022-02-16 11:43:57 +11:00
|
|
|
import { getPredefinedBootstrapNodes, getPseudoRandomSubset } from "./index";
|
2022-01-13 11:33:26 +11:00
|
|
|
|
2022-02-04 14:12:00 +11:00
|
|
|
const dbg = debug("waku:discovery:bootstrap");
|
2022-01-13 11:33:26 +11:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Setup discovery method used to bootstrap.
|
|
|
|
|
*
|
2022-05-04 20:07:21 +10:00
|
|
|
* Only one method is used. [[default]], [[peers]], [[getPeers]] and [[enrUrl]] options are mutually exclusive.
|
2022-01-13 11:33:26 +11:00
|
|
|
*/
|
|
|
|
|
export interface BootstrapOptions {
|
|
|
|
|
/**
|
|
|
|
|
* The maximum of peers to connect to as part of the bootstrap process.
|
2022-05-04 20:07:21 +10:00
|
|
|
* This only applies if [[peers]] or [[getPeers]] is used.
|
2022-01-13 11:33:26 +11:00
|
|
|
*
|
2022-01-13 16:04:57 +11:00
|
|
|
* @default [[Bootstrap.DefaultMaxPeers]]
|
2022-01-13 11:33:26 +11:00
|
|
|
*/
|
|
|
|
|
maxPeers?: number;
|
|
|
|
|
/**
|
2022-01-13 14:28:45 +11:00
|
|
|
* Use the default discovery method. Overrides all other options but `maxPeers`
|
2022-01-13 11:33:26 +11:00
|
|
|
*
|
|
|
|
|
* The default discovery method is likely to change overtime as new discovery
|
|
|
|
|
* methods are implemented.
|
|
|
|
|
*
|
|
|
|
|
* @default false
|
|
|
|
|
*/
|
|
|
|
|
default?: boolean;
|
|
|
|
|
/**
|
|
|
|
|
* Multiaddrs of peers to connect to.
|
|
|
|
|
*/
|
2022-03-09 18:38:28 +11:00
|
|
|
peers?: string[] | Multiaddr[];
|
2022-01-13 11:33:26 +11:00
|
|
|
/**
|
|
|
|
|
* Getter that retrieve multiaddrs of peers to connect to.
|
|
|
|
|
*/
|
2022-01-13 14:28:45 +11:00
|
|
|
getPeers?: () => Promise<string[] | Multiaddr[]>;
|
2022-01-13 11:33:26 +11:00
|
|
|
/**
|
|
|
|
|
* An EIP-1459 ENR Tree URL. For example:
|
|
|
|
|
* "enrtree://AOFTICU2XWDULNLZGRMQS4RIZPAZEHYMV4FYHAPW563HNRAOERP7C@test.nodes.vac.dev"
|
2022-05-04 20:07:21 +10:00
|
|
|
*
|
|
|
|
|
* [[wantedNodeCapabilityCount]] MUST be passed when using this option.
|
2022-01-13 11:33:26 +11:00
|
|
|
*/
|
|
|
|
|
enrUrl?: string;
|
2022-05-04 20:07:21 +10:00
|
|
|
/**
|
|
|
|
|
* Specifies what node capabilities (protocol) must be returned.
|
|
|
|
|
* This only applies when [[enrUrl]] is passed (EIP-1459 DNS Discovery).
|
|
|
|
|
*/
|
|
|
|
|
wantedNodeCapabilityCount?: Partial<NodeCapabilityCount>;
|
2022-01-13 11:33:26 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2022-01-13 16:04:57 +11:00
|
|
|
* Parse options and expose function to return bootstrap peer addresses.
|
2022-05-04 20:07:21 +10:00
|
|
|
*
|
|
|
|
|
* @throws if an invalid combination of options is passed, see [[BootstrapOptions]] for details.
|
2022-01-13 11:33:26 +11:00
|
|
|
*/
|
2022-01-13 16:04:57 +11:00
|
|
|
export class Bootstrap {
|
|
|
|
|
public static DefaultMaxPeers = 1;
|
2022-01-13 14:28:45 +11:00
|
|
|
|
2022-01-13 16:04:57 +11:00
|
|
|
public readonly getBootstrapPeers: (() => Promise<Multiaddr[]>) | undefined;
|
2022-01-13 11:33:26 +11:00
|
|
|
|
2022-01-13 16:04:57 +11:00
|
|
|
constructor(opts: BootstrapOptions) {
|
|
|
|
|
const maxPeers = opts.maxPeers ?? Bootstrap.DefaultMaxPeers;
|
2022-01-13 11:33:26 +11:00
|
|
|
|
2022-01-13 16:04:57 +11:00
|
|
|
if (opts.default) {
|
2022-02-04 14:12:00 +11:00
|
|
|
dbg("Use hosted list of peers.");
|
2022-01-13 11:33:26 +11:00
|
|
|
|
2022-02-16 11:43:57 +11:00
|
|
|
this.getBootstrapPeers = (): Promise<Multiaddr[]> => {
|
|
|
|
|
return Promise.resolve(
|
|
|
|
|
getPredefinedBootstrapNodes(undefined, maxPeers)
|
|
|
|
|
);
|
|
|
|
|
};
|
2022-01-13 16:04:57 +11:00
|
|
|
} else if (opts.peers !== undefined && opts.peers.length > 0) {
|
|
|
|
|
const allPeers: Multiaddr[] = opts.peers.map(
|
2022-03-09 18:38:28 +11:00
|
|
|
(node: string | Multiaddr) => {
|
|
|
|
|
if (typeof node === "string") {
|
|
|
|
|
return new Multiaddr(node);
|
|
|
|
|
} else {
|
|
|
|
|
return node;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-01-13 16:04:57 +11:00
|
|
|
);
|
|
|
|
|
const peers = getPseudoRandomSubset(allPeers, maxPeers);
|
2022-01-20 13:00:58 +11:00
|
|
|
dbg(
|
2022-02-04 14:12:00 +11:00
|
|
|
"Use provided list of peers (reduced to maxPeers)",
|
2022-01-20 13:00:58 +11:00
|
|
|
allPeers.map((ma) => ma.toString())
|
|
|
|
|
);
|
2022-01-13 16:04:57 +11:00
|
|
|
this.getBootstrapPeers = (): Promise<Multiaddr[]> =>
|
|
|
|
|
Promise.resolve(peers);
|
2022-02-04 14:12:00 +11:00
|
|
|
} else if (typeof opts.getPeers === "function") {
|
|
|
|
|
dbg("Bootstrap: Use provided getPeers function.");
|
2022-01-13 16:04:57 +11:00
|
|
|
const getPeers = opts.getPeers;
|
|
|
|
|
|
|
|
|
|
this.getBootstrapPeers = async (): Promise<Multiaddr[]> => {
|
|
|
|
|
const allPeers = await getPeers();
|
|
|
|
|
return getPseudoRandomSubset<string | Multiaddr>(
|
|
|
|
|
allPeers,
|
|
|
|
|
maxPeers
|
|
|
|
|
).map((node) => new Multiaddr(node));
|
|
|
|
|
};
|
|
|
|
|
} else if (opts.enrUrl) {
|
2022-05-04 20:07:21 +10:00
|
|
|
const wantedNodeCapabilityCount = opts.wantedNodeCapabilityCount;
|
|
|
|
|
if (!wantedNodeCapabilityCount)
|
|
|
|
|
throw "`wantedNodeCapabilityCount` must be defined when using `enrUrl`";
|
2022-01-13 16:04:57 +11:00
|
|
|
const enrUrl = opts.enrUrl;
|
2022-02-04 14:12:00 +11:00
|
|
|
dbg("Use provided EIP-1459 ENR Tree URL.");
|
2022-01-13 11:33:26 +11:00
|
|
|
|
2022-01-13 16:04:57 +11:00
|
|
|
const dns = DnsNodeDiscovery.dnsOverHttp();
|
2022-01-13 11:33:26 +11:00
|
|
|
|
2022-01-13 16:04:57 +11:00
|
|
|
this.getBootstrapPeers = async (): Promise<Multiaddr[]> => {
|
2022-05-04 20:07:21 +10:00
|
|
|
const enrs = await dns.getPeers([enrUrl], wantedNodeCapabilityCount);
|
2022-01-17 14:21:23 +11:00
|
|
|
dbg(`Found ${enrs.length} peers`);
|
|
|
|
|
return enrs.map((enr) => enr.getFullMultiaddrs()).flat();
|
2022-01-13 16:04:57 +11:00
|
|
|
};
|
|
|
|
|
} else {
|
2022-02-04 14:12:00 +11:00
|
|
|
dbg("No bootstrap method specified, no peer will be returned");
|
2022-01-13 16:04:57 +11:00
|
|
|
this.getBootstrapPeers = undefined;
|
|
|
|
|
}
|
2022-01-13 11:33:26 +11:00
|
|
|
}
|
|
|
|
|
}
|