mirror of https://github.com/waku-org/js-waku.git
Merge branch 'master' of github.com:waku-org/js-waku into chore/bump-noble-secp256k1
This commit is contained in:
commit
bad2b7506c
|
@ -16,6 +16,12 @@
|
|||
],
|
||||
"globals": { "BigInt": true, "console": true, "WebAssembly": true },
|
||||
"rules": {
|
||||
"prettier/prettier": [
|
||||
"error",
|
||||
{
|
||||
"trailingComma": "none"
|
||||
}
|
||||
],
|
||||
"comma-dangle": ["error", "never"],
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -89,7 +89,7 @@
|
|||
"@rollup/plugin-commonjs": "^24.0.1",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.1.0",
|
||||
"@types/chai": "^4.3.4",
|
||||
"@types/chai": "^4.3.5",
|
||||
"@types/debug": "^4.1.7",
|
||||
"@types/mocha": "^10.0.1",
|
||||
"@types/uuid": "^9.0.1",
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
"@rollup/plugin-commonjs": "^24.0.1",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.1.0",
|
||||
"@types/chai": "^4.3.4",
|
||||
"@types/chai": "^4.3.5",
|
||||
"@waku/build-utils": "*",
|
||||
"@waku/interfaces": "0.0.17",
|
||||
"chai": "^4.3.7",
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import type { NodeCapabilityCount } from "@waku/interfaces";
|
||||
|
||||
export const enrTree = {
|
||||
TEST: "enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@test.waku.nodes.status.im",
|
||||
PROD: "enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@prod.waku.nodes.status.im"
|
||||
};
|
||||
|
||||
export const DEFAULT_BOOTSTRAP_TAG_NAME = "bootstrap";
|
||||
export const DEFAULT_BOOTSTRAP_TAG_VALUE = 50;
|
||||
export const DEFAULT_BOOTSTRAP_TAG_TTL = 100_000_000;
|
||||
|
||||
export const DEFAULT_NODE_REQUIREMENTS: Partial<NodeCapabilityCount> = {
|
||||
store: 2,
|
||||
filter: 1,
|
||||
lightPush: 1
|
||||
};
|
|
@ -1,6 +1,7 @@
|
|||
import type { DnsClient } from "@waku/interfaces";
|
||||
import { expect } from "chai";
|
||||
|
||||
import { DnsClient, DnsNodeDiscovery } from "./dns.js";
|
||||
import { DnsNodeDiscovery } from "./dns.js";
|
||||
import testData from "./testdata.json" assert { type: "json" };
|
||||
|
||||
import { enrTree } from "./index.js";
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
import { ENR, EnrDecoder } from "@waku/enr";
|
||||
import type { IEnr } from "@waku/interfaces";
|
||||
import type {
|
||||
DnsClient,
|
||||
IEnr,
|
||||
NodeCapabilityCount,
|
||||
SearchContext
|
||||
} from "@waku/interfaces";
|
||||
import debug from "debug";
|
||||
|
||||
import { DnsOverHttps } from "./dns_over_https.js";
|
||||
|
@ -11,23 +16,6 @@ import {
|
|||
|
||||
const log = debug("waku:discovery:dns");
|
||||
|
||||
export type SearchContext = {
|
||||
domain: string;
|
||||
publicKey: string;
|
||||
visits: { [key: string]: boolean };
|
||||
};
|
||||
|
||||
export interface DnsClient {
|
||||
resolveTXT: (domain: string) => Promise<string[]>;
|
||||
}
|
||||
|
||||
export interface NodeCapabilityCount {
|
||||
relay: number;
|
||||
store: number;
|
||||
filter: number;
|
||||
lightPush: number;
|
||||
}
|
||||
|
||||
export class DnsNodeDiscovery {
|
||||
private readonly dns: DnsClient;
|
||||
private readonly _DNSTreeCache: { [key: string]: string };
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
import { CustomEvent, EventEmitter } from "@libp2p/interface/events";
|
||||
import type {
|
||||
PeerDiscovery,
|
||||
PeerDiscoveryEvents
|
||||
} from "@libp2p/interface/peer-discovery";
|
||||
import { peerDiscovery as symbol } from "@libp2p/interface/peer-discovery";
|
||||
import type { PeerInfo } from "@libp2p/interface/peer-info";
|
||||
import type {
|
||||
DnsDiscOptions,
|
||||
DnsDiscoveryComponents,
|
||||
IEnr,
|
||||
NodeCapabilityCount
|
||||
} from "@waku/interfaces";
|
||||
import debug from "debug";
|
||||
|
||||
import {
|
||||
DEFAULT_BOOTSTRAP_TAG_NAME,
|
||||
DEFAULT_BOOTSTRAP_TAG_TTL,
|
||||
DEFAULT_BOOTSTRAP_TAG_VALUE,
|
||||
DEFAULT_NODE_REQUIREMENTS
|
||||
} from "./constants.js";
|
||||
import { DnsNodeDiscovery } from "./dns.js";
|
||||
|
||||
const log = debug("waku:peer-discovery-dns");
|
||||
|
||||
/**
|
||||
* Parse options and expose function to return bootstrap peer addresses.
|
||||
*/
|
||||
export class PeerDiscoveryDns
|
||||
extends EventEmitter<PeerDiscoveryEvents>
|
||||
implements PeerDiscovery
|
||||
{
|
||||
private nextPeer: (() => AsyncGenerator<IEnr>) | undefined;
|
||||
private _started: boolean;
|
||||
private _components: DnsDiscoveryComponents;
|
||||
private _options: DnsDiscOptions;
|
||||
|
||||
constructor(components: DnsDiscoveryComponents, options: DnsDiscOptions) {
|
||||
super();
|
||||
this._started = false;
|
||||
this._components = components;
|
||||
this._options = options;
|
||||
|
||||
const { enrUrls } = options;
|
||||
log("Use following EIP-1459 ENR Tree URLs: ", enrUrls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start discovery process
|
||||
*/
|
||||
async start(): Promise<void> {
|
||||
log("Starting peer discovery via dns");
|
||||
|
||||
this._started = true;
|
||||
|
||||
if (this.nextPeer === undefined) {
|
||||
let { enrUrls } = this._options;
|
||||
if (!Array.isArray(enrUrls)) enrUrls = [enrUrls];
|
||||
|
||||
const { wantedNodeCapabilityCount } = this._options;
|
||||
const dns = await DnsNodeDiscovery.dnsOverHttp();
|
||||
|
||||
this.nextPeer = dns.getNextPeer.bind(
|
||||
dns,
|
||||
enrUrls,
|
||||
wantedNodeCapabilityCount
|
||||
);
|
||||
}
|
||||
|
||||
for await (const peerEnr of this.nextPeer()) {
|
||||
if (!this._started) {
|
||||
return;
|
||||
}
|
||||
|
||||
const peerInfo = peerEnr.peerInfo;
|
||||
|
||||
if (!peerInfo) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const tagsToUpdate = {
|
||||
tags: {
|
||||
[DEFAULT_BOOTSTRAP_TAG_NAME]: {
|
||||
value: this._options.tagValue ?? DEFAULT_BOOTSTRAP_TAG_VALUE,
|
||||
ttl: this._options.tagTTL ?? DEFAULT_BOOTSTRAP_TAG_TTL
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let isPeerChanged = false;
|
||||
const isPeerExists = await this._components.peerStore.has(peerInfo.id);
|
||||
|
||||
if (isPeerExists) {
|
||||
const peer = await this._components.peerStore.get(peerInfo.id);
|
||||
const hasBootstrapTag = peer.tags.has(DEFAULT_BOOTSTRAP_TAG_NAME);
|
||||
|
||||
if (!hasBootstrapTag) {
|
||||
isPeerChanged = true;
|
||||
await this._components.peerStore.merge(peerInfo.id, tagsToUpdate);
|
||||
}
|
||||
} else {
|
||||
isPeerChanged = true;
|
||||
await this._components.peerStore.save(peerInfo.id, tagsToUpdate);
|
||||
}
|
||||
|
||||
if (isPeerChanged) {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent<PeerInfo>("peer", { detail: peerInfo })
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop emitting events
|
||||
*/
|
||||
stop(): void {
|
||||
this._started = false;
|
||||
}
|
||||
|
||||
get [symbol](): true {
|
||||
return true;
|
||||
}
|
||||
|
||||
get [Symbol.toStringTag](): string {
|
||||
return "@waku/bootstrap";
|
||||
}
|
||||
}
|
||||
|
||||
export function wakuDnsDiscovery(
|
||||
enrUrls: string[],
|
||||
wantedNodeCapabilityCount: Partial<NodeCapabilityCount> = DEFAULT_NODE_REQUIREMENTS
|
||||
): (components: DnsDiscoveryComponents) => PeerDiscoveryDns {
|
||||
return (components: DnsDiscoveryComponents) =>
|
||||
new PeerDiscoveryDns(components, { enrUrls, wantedNodeCapabilityCount });
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
import type { DnsClient } from "@waku/interfaces";
|
||||
import { bytesToUtf8 } from "@waku/utils/bytes";
|
||||
import debug from "debug";
|
||||
import { Endpoint, query, wellknown } from "dns-query";
|
||||
|
||||
import { DnsClient } from "./dns.js";
|
||||
|
||||
const log = debug("waku:dns-over-https");
|
||||
|
||||
export class DnsOverHttps implements DnsClient {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import type { IEnr, Waku2 } from "@waku/interfaces";
|
||||
import type { IEnr, NodeCapabilityCount, Waku2 } from "@waku/interfaces";
|
||||
import debug from "debug";
|
||||
|
||||
import { NodeCapabilityCount } from "./dns.js";
|
||||
|
||||
const log = debug("waku:discovery:fetch_nodes");
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,170 +1,3 @@
|
|||
import { CustomEvent, EventEmitter } from "@libp2p/interface/events";
|
||||
import type {
|
||||
PeerDiscovery,
|
||||
PeerDiscoveryEvents
|
||||
} from "@libp2p/interface/peer-discovery";
|
||||
import { peerDiscovery as symbol } from "@libp2p/interface/peer-discovery";
|
||||
import type { PeerInfo } from "@libp2p/interface/peer-info";
|
||||
import type { PeerStore } from "@libp2p/interface/peer-store";
|
||||
import type { IEnr } from "@waku/interfaces";
|
||||
import debug from "debug";
|
||||
|
||||
import { DnsNodeDiscovery, NodeCapabilityCount } from "./dns.js";
|
||||
|
||||
export { NodeCapabilityCount };
|
||||
|
||||
const log = debug("waku:peer-discovery-dns");
|
||||
|
||||
const enrTree = {
|
||||
TEST: "enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@test.waku.nodes.status.im",
|
||||
PROD: "enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@prod.waku.nodes.status.im"
|
||||
};
|
||||
|
||||
const DEFAULT_BOOTSTRAP_TAG_NAME = "bootstrap";
|
||||
const DEFAULT_BOOTSTRAP_TAG_VALUE = 50;
|
||||
const DEFAULT_BOOTSTRAP_TAG_TTL = 100_000_000;
|
||||
|
||||
export interface DnsDiscoveryComponents {
|
||||
peerStore: PeerStore;
|
||||
}
|
||||
|
||||
export interface Options {
|
||||
/**
|
||||
* ENR URL to use for DNS discovery
|
||||
*/
|
||||
enrUrls: string | string[];
|
||||
/**
|
||||
* Specifies what type of nodes are wanted from the discovery process
|
||||
*/
|
||||
wantedNodeCapabilityCount: Partial<NodeCapabilityCount>;
|
||||
/**
|
||||
* Tag a bootstrap peer with this name before "discovering" it (default: 'bootstrap')
|
||||
*/
|
||||
tagName?: string;
|
||||
|
||||
/**
|
||||
* The bootstrap peer tag will have this value (default: 50)
|
||||
*/
|
||||
tagValue?: number;
|
||||
|
||||
/**
|
||||
* Cause the bootstrap peer tag to be removed after this number of ms (default: 2 minutes)
|
||||
*/
|
||||
tagTTL?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse options and expose function to return bootstrap peer addresses.
|
||||
*/
|
||||
export class PeerDiscoveryDns
|
||||
extends EventEmitter<PeerDiscoveryEvents>
|
||||
implements PeerDiscovery
|
||||
{
|
||||
private nextPeer: (() => AsyncGenerator<IEnr>) | undefined;
|
||||
private _started: boolean;
|
||||
private _components: DnsDiscoveryComponents;
|
||||
private _options: Options;
|
||||
|
||||
constructor(components: DnsDiscoveryComponents, options: Options) {
|
||||
super();
|
||||
this._started = false;
|
||||
this._components = components;
|
||||
this._options = options;
|
||||
|
||||
const { enrUrls } = options;
|
||||
log("Use following EIP-1459 ENR Tree URLs: ", enrUrls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start discovery process
|
||||
*/
|
||||
async start(): Promise<void> {
|
||||
log("Starting peer discovery via dns");
|
||||
|
||||
this._started = true;
|
||||
|
||||
if (this.nextPeer === undefined) {
|
||||
let { enrUrls } = this._options;
|
||||
if (!Array.isArray(enrUrls)) enrUrls = [enrUrls];
|
||||
|
||||
const { wantedNodeCapabilityCount } = this._options;
|
||||
const dns = await DnsNodeDiscovery.dnsOverHttp();
|
||||
|
||||
this.nextPeer = dns.getNextPeer.bind(
|
||||
dns,
|
||||
enrUrls,
|
||||
wantedNodeCapabilityCount
|
||||
);
|
||||
}
|
||||
|
||||
for await (const peerEnr of this.nextPeer()) {
|
||||
if (!this._started) {
|
||||
return;
|
||||
}
|
||||
|
||||
const peerInfo = peerEnr.peerInfo;
|
||||
|
||||
if (!peerInfo) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const tagsToUpdate = {
|
||||
tags: {
|
||||
[DEFAULT_BOOTSTRAP_TAG_NAME]: {
|
||||
value: this._options.tagValue ?? DEFAULT_BOOTSTRAP_TAG_VALUE,
|
||||
ttl: this._options.tagTTL ?? DEFAULT_BOOTSTRAP_TAG_TTL
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let isPeerChanged = false;
|
||||
const isPeerExists = await this._components.peerStore.has(peerInfo.id);
|
||||
|
||||
if (isPeerExists) {
|
||||
const peer = await this._components.peerStore.get(peerInfo.id);
|
||||
const hasBootstrapTag = peer.tags.has(DEFAULT_BOOTSTRAP_TAG_NAME);
|
||||
|
||||
if (!hasBootstrapTag) {
|
||||
isPeerChanged = true;
|
||||
await this._components.peerStore.merge(peerInfo.id, tagsToUpdate);
|
||||
}
|
||||
} else {
|
||||
isPeerChanged = true;
|
||||
await this._components.peerStore.save(peerInfo.id, tagsToUpdate);
|
||||
}
|
||||
|
||||
if (isPeerChanged) {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent<PeerInfo>("peer", { detail: peerInfo })
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop emitting events
|
||||
*/
|
||||
stop(): void {
|
||||
this._started = false;
|
||||
}
|
||||
|
||||
get [symbol](): true {
|
||||
return true;
|
||||
}
|
||||
|
||||
get [Symbol.toStringTag](): string {
|
||||
return "@waku/bootstrap";
|
||||
}
|
||||
}
|
||||
|
||||
export function wakuDnsDiscovery(
|
||||
enrUrls: string[],
|
||||
wantedNodeCapabilityCount: Partial<NodeCapabilityCount>
|
||||
): (components: DnsDiscoveryComponents) => PeerDiscoveryDns {
|
||||
return (components: DnsDiscoveryComponents) =>
|
||||
new PeerDiscoveryDns(components, { enrUrls, wantedNodeCapabilityCount });
|
||||
}
|
||||
|
||||
export { DnsNodeDiscovery, SearchContext, DnsClient } from "./dns.js";
|
||||
|
||||
export { enrTree };
|
||||
export { PeerDiscoveryDns, wakuDnsDiscovery } from "./dns_discovery.js";
|
||||
export { enrTree } from "./constants.js";
|
||||
export { DnsNodeDiscovery } from "./dns.js";
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
"@rollup/plugin-commonjs": "^24.0.1",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.1.0",
|
||||
"@types/chai": "^4.3.4",
|
||||
"@types/chai": "^4.3.5",
|
||||
"@types/mocha": "^10.0.1",
|
||||
"@waku/build-utils": "*",
|
||||
"@waku/interfaces": "0.0.17",
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import { PeerStore } from "@libp2p/interface/peer-store";
|
||||
|
||||
export type SearchContext = {
|
||||
domain: string;
|
||||
publicKey: string;
|
||||
visits: { [key: string]: boolean };
|
||||
};
|
||||
|
||||
export interface DnsClient {
|
||||
resolveTXT: (domain: string) => Promise<string[]>;
|
||||
}
|
||||
|
||||
export interface NodeCapabilityCount {
|
||||
relay: number;
|
||||
store: number;
|
||||
filter: number;
|
||||
lightPush: number;
|
||||
}
|
||||
|
||||
export interface DnsDiscoveryComponents {
|
||||
peerStore: PeerStore;
|
||||
}
|
||||
|
||||
export interface DnsDiscOptions {
|
||||
/**
|
||||
* ENR URL to use for DNS discovery
|
||||
*/
|
||||
enrUrls: string | string[];
|
||||
/**
|
||||
* Specifies what type of nodes are wanted from the discovery process
|
||||
*/
|
||||
wantedNodeCapabilityCount: Partial<NodeCapabilityCount>;
|
||||
/**
|
||||
* Tag a bootstrap peer with this name before "discovering" it (default: 'bootstrap')
|
||||
*/
|
||||
tagName?: string;
|
||||
|
||||
/**
|
||||
* The bootstrap peer tag will have this value (default: 50)
|
||||
*/
|
||||
tagValue?: number;
|
||||
|
||||
/**
|
||||
* Cause the bootstrap peer tag to be removed after this number of ms (default: 2 minutes)
|
||||
*/
|
||||
tagTTL?: number;
|
||||
}
|
|
@ -13,3 +13,4 @@ export * from "./receiver.js";
|
|||
export * from "./misc.js";
|
||||
export * from "./libp2p.js";
|
||||
export * from "./keep_alive_manager.js";
|
||||
export * from "./dns_discovery.js";
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
"@rollup/plugin-commonjs": "^24.0.1",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.1.0",
|
||||
"@types/chai": "^4.3.4",
|
||||
"@types/chai": "^4.3.5",
|
||||
"@types/mocha": "^10.0.1",
|
||||
"@waku/build-utils": "*",
|
||||
"chai": "^4.3.7",
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
"@rollup/plugin-commonjs": "^24.0.1",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.1.0",
|
||||
"@types/chai": "^4.3.4",
|
||||
"@types/chai": "^4.3.5",
|
||||
"@types/debug": "^4.1.7",
|
||||
"@types/mocha": "^10.0.1",
|
||||
"@waku/build-utils": "*",
|
||||
|
|
|
@ -68,10 +68,12 @@
|
|||
"aegir": "^40.0.11",
|
||||
"@libp2p/bootstrap": "^9.0.2",
|
||||
"@types/sinon": "^10.0.16",
|
||||
"@types/chai": "^4.3.4",
|
||||
"@types/dockerode": "^3.3.17",
|
||||
"@types/chai": "^4.3.5",
|
||||
"@types/dockerode": "^3.3.19",
|
||||
"@types/mocha": "^10.0.1",
|
||||
"@types/tail": "^2.2.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.57.0",
|
||||
"@typescript-eslint/parser": "^5.62.0",
|
||||
"@waku/sdk": "*",
|
||||
"@waku/dns-discovery": "*",
|
||||
"@waku/message-encryption": "*",
|
||||
|
|
Loading…
Reference in New Issue