@waku/discovery 0.0.7-219b8cb.0 → 0.0.7-2a94244.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,18 +1,12 @@
1
1
  import type { DnsClient } from "@waku/interfaces";
2
- import { Endpoint } from "dns-query";
3
2
  export declare class DnsOverHttps implements DnsClient {
4
- private endpoints;
5
- private retries;
3
+ private resolver;
6
4
  /**
7
5
  * Create new Dns-Over-Http DNS client.
8
6
  *
9
- * @param endpoints The endpoints for Dns-Over-Https queries;
10
- * Defaults to using dns-query's API..
11
- * @param retries Retries if a given endpoint fails.
12
- *
13
7
  * @throws {code: string} If DNS query fails.
14
8
  */
15
- static create(endpoints?: Endpoint[], retries?: number): Promise<DnsOverHttps>;
9
+ static create(): Promise<DnsOverHttps>;
16
10
  private constructor();
17
11
  /**
18
12
  * Resolves a TXT record
@@ -1,26 +1,19 @@
1
1
  import { Logger } from "@waku/utils";
2
2
  import { bytesToUtf8 } from "@waku/utils/bytes";
3
- import { query, wellknown } from "dns-query";
3
+ import DnsOverHttpResolver from "dns-over-http-resolver";
4
4
  const log = new Logger("dns-over-https");
5
5
  export class DnsOverHttps {
6
- endpoints;
7
- retries;
6
+ resolver;
8
7
  /**
9
8
  * Create new Dns-Over-Http DNS client.
10
9
  *
11
- * @param endpoints The endpoints for Dns-Over-Https queries;
12
- * Defaults to using dns-query's API..
13
- * @param retries Retries if a given endpoint fails.
14
- *
15
10
  * @throws {code: string} If DNS query fails.
16
11
  */
17
- static async create(endpoints, retries) {
18
- const _endpoints = endpoints ?? (await wellknown.endpoints("doh"));
19
- return new DnsOverHttps(_endpoints, retries);
12
+ static async create() {
13
+ return new DnsOverHttps();
20
14
  }
21
- constructor(endpoints, retries = 3) {
22
- this.endpoints = endpoints;
23
- this.retries = retries;
15
+ constructor(resolver = new DnsOverHttpResolver()) {
16
+ this.resolver = resolver;
24
17
  }
25
18
  /**
26
19
  * Resolves a TXT record
@@ -32,13 +25,7 @@ export class DnsOverHttps {
32
25
  async resolveTXT(domain) {
33
26
  let answers;
34
27
  try {
35
- const res = await query({
36
- question: { type: "TXT", name: domain }
37
- }, {
38
- endpoints: this.endpoints,
39
- retries: this.retries
40
- });
41
- answers = res.answers;
28
+ answers = await this.resolver.resolveTxt(domain);
42
29
  }
43
30
  catch (error) {
44
31
  log.error("query failed: ", error);
@@ -46,9 +33,8 @@ export class DnsOverHttps {
46
33
  }
47
34
  if (!answers)
48
35
  throw new Error(`Could not resolve ${domain}`);
49
- const data = answers.map((a) => a.data);
50
36
  const result = [];
51
- data.forEach((d) => {
37
+ answers.forEach((d) => {
52
38
  if (typeof d === "string") {
53
39
  result.push(d);
54
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dns_over_https.js","sourceRoot":"","sources":["../../src/dns/dns_over_https.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAY,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEvD,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAEzC,MAAM,OAAO,YAAY;IAoBb;IACA;IApBV;;;;;;;;OAQG;IACI,MAAM,CAAC,KAAK,CAAC,MAAM,CACxB,SAAsB,EACtB,OAAgB;QAEhB,MAAM,UAAU,GAAG,SAAS,IAAI,CAAC,MAAM,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAEnE,OAAO,IAAI,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED,YACU,SAAqB,EACrB,UAAkB,CAAC;QADnB,cAAS,GAAT,SAAS,CAAY;QACrB,YAAO,GAAP,OAAO,CAAY;IAC1B,CAAC;IAEJ;;;;;;OAMG;IACI,KAAK,CAAC,UAAU,CAAC,MAAc;QACpC,IAAI,OAAO,CAAC;QACZ,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB;gBACE,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE;aACxC,EACD;gBACE,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,OAAO,EAAE,IAAI,CAAC,OAAO;aACtB,CACF,CAAC;YACF,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACtC,CAAC;QAED,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,MAAM,EAAE,CAAC,CAAC;QAE7D,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAED,CAAC;QAEtC,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YACjB,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC1B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5B,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;oBACf,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;wBAC3B,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAClB,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC/B,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
1
+ {"version":3,"file":"dns_over_https.js","sourceRoot":"","sources":["../../src/dns/dns_over_https.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,mBAAmB,MAAM,wBAAwB,CAAC;AAEzD,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAEzC,MAAM,OAAO,YAAY;IAUK;IAT5B;;;;OAIG;IACI,MAAM,CAAC,KAAK,CAAC,MAAM;QACxB,OAAO,IAAI,YAAY,EAAE,CAAC;IAC5B,CAAC;IAED,YAA4B,WAAW,IAAI,mBAAmB,EAAE;QAApC,aAAQ,GAAR,QAAQ,CAA4B;IAAG,CAAC;IAEpE;;;;;;OAMG;IACI,KAAK,CAAC,UAAU,CAAC,MAAc;QACpC,IAAI,OAAO,CAAC;QACZ,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACtC,CAAC;QAED,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,MAAM,EAAE,CAAC,CAAC;QAE7D,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YACpB,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC1B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5B,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;oBACf,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;wBAC3B,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAClB,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC/B,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
@@ -1,13 +1,11 @@
1
- import type { IEnr, NodeCapabilityCount } from "@waku/interfaces";
1
+ import type { IEnr } from "@waku/interfaces";
2
2
  /**
3
- * Fetch nodes using passed [[getNode]] until all wanted capabilities are
4
- * fulfilled or the number of [[getNode]] call exceeds the sum of
5
- * [[wantedNodeCapabilityCount]] plus [[errorTolerance]].
3
+ * Fetch nodes using passed [[getNode]]; results are validated before being
4
+ * returned. Stops when [[getNodes]] does not return any more nodes or the
5
+ * number call exceeds [[maxSearches]].
6
6
  */
7
- export declare function fetchNodesUntilCapabilitiesFulfilled(wantedNodeCapabilityCount: Partial<NodeCapabilityCount>, errorTolerance: number, getNode: () => Promise<IEnr | null>): Promise<IEnr[]>;
7
+ export declare function fetchAndValidateNodes(maxSearches: number | undefined, getNode: () => Promise<IEnr | null>): Promise<IEnr[]>;
8
8
  /**
9
- * Fetch nodes using passed [[getNode]] until all wanted capabilities are
10
- * fulfilled or the number of [[getNode]] call exceeds the sum of
11
- * [[wantedNodeCapabilityCount]] plus [[errorTolerance]].
9
+ * Fetch nodes using passed [[getNode]]
12
10
  */
13
- export declare function yieldNodesUntilCapabilitiesFulfilled(wantedNodeCapabilityCount: Partial<NodeCapabilityCount>, errorTolerance: number, getNode: () => Promise<IEnr | null>): AsyncGenerator<IEnr>;
11
+ export declare function yieldNodes(getNode: () => Promise<IEnr | null>): AsyncGenerator<IEnr>;
@@ -1,87 +1,47 @@
1
1
  import { Logger } from "@waku/utils";
2
2
  const log = new Logger("discovery:fetch_nodes");
3
3
  /**
4
- * Fetch nodes using passed [[getNode]] until all wanted capabilities are
5
- * fulfilled or the number of [[getNode]] call exceeds the sum of
6
- * [[wantedNodeCapabilityCount]] plus [[errorTolerance]].
4
+ * Fetch nodes using passed [[getNode]]; results are validated before being
5
+ * returned. Stops when [[getNodes]] does not return any more nodes or the
6
+ * number call exceeds [[maxSearches]].
7
7
  */
8
- export async function fetchNodesUntilCapabilitiesFulfilled(wantedNodeCapabilityCount, errorTolerance, getNode) {
9
- const wanted = {
10
- relay: wantedNodeCapabilityCount.relay ?? 0,
11
- store: wantedNodeCapabilityCount.store ?? 0,
12
- filter: wantedNodeCapabilityCount.filter ?? 0,
13
- lightPush: wantedNodeCapabilityCount.lightPush ?? 0
14
- };
15
- const maxSearches = wanted.relay + wanted.store + wanted.filter + wanted.lightPush;
16
- const actual = {
17
- relay: 0,
18
- store: 0,
19
- filter: 0,
20
- lightPush: 0
21
- };
8
+ export async function fetchAndValidateNodes(maxSearches = 10, getNode) {
22
9
  let totalSearches = 0;
10
+ let emptyResults = 0;
23
11
  const peers = [];
24
- while (!isSatisfied(wanted, actual) &&
25
- totalSearches < maxSearches + errorTolerance) {
12
+ while (totalSearches < maxSearches &&
13
+ emptyResults < 2 // Allows a couple of empty results before calling it quit
14
+ ) {
26
15
  const peer = await getNode();
27
16
  if (peer && isNewPeer(peer, peers)) {
28
17
  // ENRs without a waku2 key are ignored.
29
18
  if (peer.waku2) {
30
- if (helpsSatisfyCapabilities(peer.waku2, wanted, actual)) {
31
- addCapabilities(peer.waku2, actual);
32
- peers.push(peer);
33
- }
19
+ peers.push(peer);
34
20
  }
35
21
  log.info(`got new peer candidate from DNS address=${peer.nodeId}@${peer.ip}`);
36
22
  }
23
+ else {
24
+ emptyResults++;
25
+ }
37
26
  totalSearches++;
38
27
  }
39
28
  return peers;
40
29
  }
41
30
  /**
42
- * Fetch nodes using passed [[getNode]] until all wanted capabilities are
43
- * fulfilled or the number of [[getNode]] call exceeds the sum of
44
- * [[wantedNodeCapabilityCount]] plus [[errorTolerance]].
31
+ * Fetch nodes using passed [[getNode]]
45
32
  */
46
- export async function* yieldNodesUntilCapabilitiesFulfilled(wantedNodeCapabilityCount, errorTolerance, getNode) {
47
- const wanted = {
48
- relay: wantedNodeCapabilityCount.relay ?? 0,
49
- store: wantedNodeCapabilityCount.store ?? 0,
50
- filter: wantedNodeCapabilityCount.filter ?? 0,
51
- lightPush: wantedNodeCapabilityCount.lightPush ?? 0
52
- };
53
- const maxSearches = wanted.relay + wanted.store + wanted.filter + wanted.lightPush;
54
- const actual = {
55
- relay: 0,
56
- store: 0,
57
- filter: 0,
58
- lightPush: 0
59
- };
60
- let totalSearches = 0;
33
+ export async function* yieldNodes(getNode) {
61
34
  const peerNodeIds = new Set();
62
- while (!isSatisfied(wanted, actual) &&
63
- totalSearches < maxSearches + errorTolerance) {
64
- const peer = await getNode();
65
- if (peer && peer.nodeId && !peerNodeIds.has(peer.nodeId)) {
66
- peerNodeIds.add(peer.nodeId);
67
- // ENRs without a waku2 key are ignored.
68
- if (peer.waku2) {
69
- if (helpsSatisfyCapabilities(peer.waku2, wanted, actual)) {
70
- addCapabilities(peer.waku2, actual);
71
- yield peer;
72
- }
73
- }
74
- log.info(`got new peer candidate from DNS address=${peer.nodeId}@${peer.ip}`);
35
+ const peer = await getNode();
36
+ if (peer && peer.nodeId && !peerNodeIds.has(peer.nodeId)) {
37
+ peerNodeIds.add(peer.nodeId);
38
+ // ENRs without a waku2 key are ignored.
39
+ if (peer.waku2) {
40
+ yield peer;
75
41
  }
76
- totalSearches++;
42
+ log.info(`got new peer candidate from DNS address=${peer.nodeId}@${peer.ip}`);
77
43
  }
78
44
  }
79
- function isSatisfied(wanted, actual) {
80
- return (actual.relay >= wanted.relay &&
81
- actual.store >= wanted.store &&
82
- actual.filter >= wanted.filter &&
83
- actual.lightPush >= wanted.lightPush);
84
- }
85
45
  function isNewPeer(peer, peers) {
86
46
  if (!peer.nodeId)
87
47
  return false;
@@ -92,42 +52,4 @@ function isNewPeer(peer, peers) {
92
52
  }
93
53
  return true;
94
54
  }
95
- function addCapabilities(node, total) {
96
- if (node.relay)
97
- total.relay += 1;
98
- if (node.store)
99
- total.store += 1;
100
- if (node.filter)
101
- total.filter += 1;
102
- if (node.lightPush)
103
- total.lightPush += 1;
104
- }
105
- /**
106
- * Checks if the proposed ENR [[node]] helps satisfy the [[wanted]] capabilities,
107
- * considering the [[actual]] capabilities of nodes retrieved so far..
108
- *
109
- * @throws If the function is called when the wanted capabilities are already fulfilled.
110
- */
111
- function helpsSatisfyCapabilities(node, wanted, actual) {
112
- if (isSatisfied(wanted, actual)) {
113
- throw "Internal Error: Waku2 wanted capabilities are already fulfilled";
114
- }
115
- const missing = missingCapabilities(wanted, actual);
116
- return ((missing.relay && node.relay) ||
117
- (missing.store && node.store) ||
118
- (missing.filter && node.filter) ||
119
- (missing.lightPush && node.lightPush));
120
- }
121
- /**
122
- * Return a [[Waku2]] Object for which capabilities are set to true if they are
123
- * [[wanted]] yet missing from [[actual]].
124
- */
125
- function missingCapabilities(wanted, actual) {
126
- return {
127
- relay: actual.relay < wanted.relay,
128
- store: actual.store < wanted.store,
129
- filter: actual.filter < wanted.filter,
130
- lightPush: actual.lightPush < wanted.lightPush
131
- };
132
- }
133
55
  //# sourceMappingURL=fetch_nodes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch_nodes.js","sourceRoot":"","sources":["../../src/dns/fetch_nodes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch_nodes.js","sourceRoot":"","sources":["../../src/dns/fetch_nodes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAEhD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,cAAsB,EAAE,EACxB,OAAmC;IAEnC,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,MAAM,KAAK,GAAW,EAAE,CAAC;IAEzB,OACE,aAAa,GAAG,WAAW;QAC3B,YAAY,GAAG,CAAC,CAAC,0DAA0D;MAC3E,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,IAAI,IAAI,IAAI,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;YACnC,wCAAwC;YACxC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;YACD,GAAG,CAAC,IAAI,CACN,2CAA2C,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,EAAE,CACpE,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,YAAY,EAAE,CAAC;QACjB,CAAC;QAED,aAAa,EAAE,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,UAAU,CAC/B,OAAmC;IAEnC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAE,CAAC;IAE9B,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;IAC7B,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACzD,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7B,wCAAwC;QACxC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,CAAC;QACb,CAAC;QACD,GAAG,CAAC,IAAI,CACN,2CAA2C,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,EAAE,CACpE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAU,EAAE,KAAa;IAC1C,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAE/B,KAAK,MAAM,YAAY,IAAI,KAAK,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,EAAE,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@waku/discovery","version":"0.0.7-219b8cb.0","description":"Contains various discovery mechanisms: DNS Discovery (EIP-1459, Peer Exchange, Local Peer Cache Discovery.","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"type":"module","author":"Waku Team","homepage":"https://github.com/waku-org/js-waku/tree/master/packages/discovery#readme","repository":{"type":"git","url":"https://github.com/waku-org/js-waku.git"},"bugs":{"url":"https://github.com/waku-org/js-waku/issues"},"license":"MIT OR Apache-2.0","keywords":["waku","decentralized","secure","communication","web3","ethereum","dapps","privacy"],"scripts":{"build":"run-s build:**","build:esm":"tsc","build:bundle":"rollup --config rollup.config.js","fix":"run-s fix:*","fix:lint":"eslint src *.js --fix","check":"run-s check:*","check:lint":"eslint src --ext .ts","check:spelling":"cspell \"{README.md,src/**/*.ts}\"","check:tsc":"tsc -p tsconfig.dev.json","prepublish":"npm run build","reset-hard":"git clean -dfx -e .idea && git reset --hard && npm i && npm run build","test":"NODE_ENV=test run-s test:*","test:node":"NODE_ENV=test TS_NODE_PROJECT=./tsconfig.dev.json mocha 'src/**/*.spec.ts'","test:browser":"NODE_ENV=test karma start karma.conf.cjs"},"engines":{"node":">=20"},"dependencies":{"@waku/interfaces":"0.0.29-219b8cb.0","@waku/proto":"0.0.9-219b8cb.0","@waku/enr":"0.0.28-219b8cb.0","@waku/core":"0.0.34-219b8cb.0","@waku/utils":"0.0.22-219b8cb.0","debug":"^4.3.4","dns-query":"^0.11.2","hi-base32":"^0.5.1","uint8arrays":"^5.0.1"},"devDependencies":{"@libp2p/interface":"^2.1.3","@libp2p/peer-id":"5.0.1","@multiformats/multiaddr":"^12.3.0","@rollup/plugin-commonjs":"^25.0.7","@rollup/plugin-json":"^6.0.0","@rollup/plugin-node-resolve":"^15.2.3","@types/chai":"^4.3.11","@types/node-localstorage":"^1.3.3","@waku/build-utils":"*","chai":"^4.3.10","chai-as-promised":"^7.1.1","cspell":"^8.6.1","mocha":"^10.3.0","node-localstorage":"^3.0.5","npm-run-all":"^4.1.5","rollup":"^4.12.0","sinon":"^18.0.0"},"files":["dist","bundle","src/**/*.ts","!**/*.spec.*","!**/*.json","CHANGELOG.md","LICENSE","README.md"]}
1
+ {"name":"@waku/discovery","version":"0.0.7-2a94244.0","description":"Contains various discovery mechanisms: DNS Discovery (EIP-1459, Peer Exchange, Local Peer Cache Discovery.","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"type":"module","author":"Waku Team","homepage":"https://github.com/waku-org/js-waku/tree/master/packages/discovery#readme","repository":{"type":"git","url":"https://github.com/waku-org/js-waku.git"},"bugs":{"url":"https://github.com/waku-org/js-waku/issues"},"license":"MIT OR Apache-2.0","keywords":["waku","decentralized","secure","communication","web3","ethereum","dapps","privacy"],"scripts":{"build":"run-s build:**","build:esm":"tsc","build:bundle":"rollup --config rollup.config.js","fix":"run-s fix:*","fix:lint":"eslint src *.js --fix","check":"run-s check:*","check:lint":"eslint src --ext .ts","check:spelling":"cspell \"{README.md,src/**/*.ts}\"","check:tsc":"tsc -p tsconfig.dev.json","prepublish":"npm run build","reset-hard":"git clean -dfx -e .idea && git reset --hard && npm i && npm run build","test":"NODE_ENV=test run-s test:*","test:node":"NODE_ENV=test TS_NODE_PROJECT=./tsconfig.dev.json mocha 'src/**/*.spec.ts'","test:browser":"NODE_ENV=test karma start karma.conf.cjs"},"engines":{"node":">=20"},"dependencies":{"@waku/core":"0.0.34-2a94244.0","@waku/enr":"0.0.28-2a94244.0","@waku/interfaces":"0.0.29-2a94244.0","@waku/proto":"0.0.9-2a94244.0","@waku/utils":"0.0.22-2a94244.0","debug":"^4.3.4","dns-over-http-resolver":"^3.0.8","hi-base32":"^0.5.1","uint8arrays":"^5.0.1"},"devDependencies":{"@libp2p/interface":"^2.1.3","@libp2p/peer-id":"5.0.1","@multiformats/multiaddr":"^12.3.0","@rollup/plugin-commonjs":"^25.0.7","@rollup/plugin-json":"^6.0.0","@rollup/plugin-node-resolve":"^15.2.3","@types/chai":"^4.3.11","@types/node-localstorage":"^1.3.3","@waku/build-utils":"*","chai":"^4.3.10","chai-as-promised":"^7.1.1","cspell":"^8.6.1","mocha":"^10.3.0","node-localstorage":"^3.0.5","npm-run-all":"^4.1.5","rollup":"^4.12.0","sinon":"^18.0.0"},"files":["dist","bundle","src/**/*.ts","!**/*.spec.*","!**/*.json","CHANGELOG.md","LICENSE","README.md"]}
@@ -1,5 +1,3 @@
1
- import type { NodeCapabilityCount } from "@waku/interfaces";
2
-
3
1
  /**
4
2
  * The ENR tree for the different fleets.
5
3
  * SANDBOX and TEST fleets are for The Waku Network.
@@ -13,9 +11,3 @@ export const enrTree = {
13
11
  export const DEFAULT_BOOTSTRAP_TAG_NAME = "bootstrap";
14
12
  export const DEFAULT_BOOTSTRAP_TAG_VALUE = 50;
15
13
  export const DEFAULT_BOOTSTRAP_TAG_TTL = 100_000_000;
16
-
17
- export const DEFAULT_NODE_REQUIREMENTS: Partial<NodeCapabilityCount> = {
18
- store: 1,
19
- filter: 2,
20
- lightPush: 2
21
- };
package/src/dns/dns.ts CHANGED
@@ -1,25 +1,17 @@
1
1
  import { ENR, EnrDecoder } from "@waku/enr";
2
- import type {
3
- DnsClient,
4
- IEnr,
5
- NodeCapabilityCount,
6
- SearchContext
7
- } from "@waku/interfaces";
2
+ import type { DnsClient, IEnr, SearchContext } from "@waku/interfaces";
8
3
  import { Logger } from "@waku/utils";
9
4
 
10
5
  import { DnsOverHttps } from "./dns_over_https.js";
11
6
  import { ENRTree } from "./enrtree.js";
12
- import {
13
- fetchNodesUntilCapabilitiesFulfilled,
14
- yieldNodesUntilCapabilitiesFulfilled
15
- } from "./fetch_nodes.js";
7
+ import { fetchAndValidateNodes, yieldNodes } from "./fetch_nodes.js";
16
8
 
17
9
  const log = new Logger("discovery:dns");
18
10
 
19
11
  export class DnsNodeDiscovery {
20
12
  private readonly dns: DnsClient;
21
13
  private readonly _DNSTreeCache: { [key: string]: string };
22
- private readonly _errorTolerance: number = 10;
14
+ private readonly _maxSearch: number = 10;
23
15
 
24
16
  public static async dnsOverHttp(
25
17
  dnsClient?: DnsClient
@@ -31,16 +23,11 @@ export class DnsNodeDiscovery {
31
23
  }
32
24
 
33
25
  /**
34
- * Returns a list of verified peers listed in an EIP-1459 DNS tree. Method may
35
- * return fewer peers than requested if @link wantedNodeCapabilityCount requires
36
- * larger quantity of peers than available or the number of errors/duplicate
37
- * peers encountered by randomized search exceeds the sum of the fields of
38
- * @link wantedNodeCapabilityCount plus the @link _errorTolerance factor.
26
+ * Returns a list of verified peers listed in an EIP-1459 DNS tree. The
27
+ * underlying retrieval mechanism is capped by [[_maxSearch]] to avoid an
28
+ * infinite loop of DNS queries.
39
29
  */
40
- public async getPeers(
41
- enrTreeUrls: string[],
42
- wantedNodeCapabilityCount: Partial<NodeCapabilityCount>
43
- ): Promise<IEnr[]> {
30
+ public async getPeers(enrTreeUrls: string[]): Promise<IEnr[]> {
44
31
  const networkIndex = Math.floor(Math.random() * enrTreeUrls.length);
45
32
  const { publicKey, domain } = ENRTree.parseTree(enrTreeUrls[networkIndex]);
46
33
  const context: SearchContext = {
@@ -49,10 +36,8 @@ export class DnsNodeDiscovery {
49
36
  visits: {}
50
37
  };
51
38
 
52
- const peers = await fetchNodesUntilCapabilitiesFulfilled(
53
- wantedNodeCapabilityCount,
54
- this._errorTolerance,
55
- () => this._search(domain, context)
39
+ const peers = await fetchAndValidateNodes(this._maxSearch, () =>
40
+ this._search(domain, context)
56
41
  );
57
42
  log.info(
58
43
  "retrieved peers: ",
@@ -74,10 +59,7 @@ export class DnsNodeDiscovery {
74
59
  /**
75
60
  * {@inheritDoc getPeers}
76
61
  */
77
- public async *getNextPeer(
78
- enrTreeUrls: string[],
79
- wantedNodeCapabilityCount: Partial<NodeCapabilityCount>
80
- ): AsyncGenerator<IEnr> {
62
+ public async *getNextPeer(enrTreeUrls: string[]): AsyncGenerator<IEnr> {
81
63
  const networkIndex = Math.floor(Math.random() * enrTreeUrls.length);
82
64
  const { publicKey, domain } = ENRTree.parseTree(enrTreeUrls[networkIndex]);
83
65
  const context: SearchContext = {
@@ -86,11 +68,7 @@ export class DnsNodeDiscovery {
86
68
  visits: {}
87
69
  };
88
70
 
89
- for await (const peer of yieldNodesUntilCapabilitiesFulfilled(
90
- wantedNodeCapabilityCount,
91
- this._errorTolerance,
92
- () => this._search(domain, context)
93
- )) {
71
+ for await (const peer of yieldNodes(() => this._search(domain, context))) {
94
72
  yield peer;
95
73
  }
96
74
  }
@@ -9,8 +9,7 @@ import type {
9
9
  DiscoveryTrigger,
10
10
  DnsDiscOptions,
11
11
  DnsDiscoveryComponents,
12
- IEnr,
13
- NodeCapabilityCount
12
+ IEnr
14
13
  } from "@waku/interfaces";
15
14
  import { DNS_DISCOVERY_TAG } from "@waku/interfaces";
16
15
  import { encodeRelayShard, Logger } from "@waku/utils";
@@ -18,8 +17,7 @@ import { encodeRelayShard, Logger } from "@waku/utils";
18
17
  import {
19
18
  DEFAULT_BOOTSTRAP_TAG_NAME,
20
19
  DEFAULT_BOOTSTRAP_TAG_TTL,
21
- DEFAULT_BOOTSTRAP_TAG_VALUE,
22
- DEFAULT_NODE_REQUIREMENTS
20
+ DEFAULT_BOOTSTRAP_TAG_VALUE
23
21
  } from "./constants.js";
24
22
  import { DnsNodeDiscovery } from "./dns.js";
25
23
 
@@ -35,7 +33,7 @@ export class PeerDiscoveryDns
35
33
  private nextPeer: (() => AsyncGenerator<IEnr>) | undefined;
36
34
  private _started: boolean;
37
35
  private _components: DnsDiscoveryComponents;
38
- private _options: DnsDiscOptions;
36
+ private readonly _options: DnsDiscOptions;
39
37
 
40
38
  public constructor(
41
39
  components: DnsDiscoveryComponents,
@@ -65,14 +63,9 @@ export class PeerDiscoveryDns
65
63
  let { enrUrls } = this._options;
66
64
  if (!Array.isArray(enrUrls)) enrUrls = [enrUrls];
67
65
 
68
- const { wantedNodeCapabilityCount } = this._options;
69
66
  const dns = await DnsNodeDiscovery.dnsOverHttp();
70
67
 
71
- this.nextPeer = dns.getNextPeer.bind(
72
- dns,
73
- enrUrls,
74
- wantedNodeCapabilityCount
75
- );
68
+ this.nextPeer = dns.getNextPeer.bind(dns, enrUrls);
76
69
  }
77
70
 
78
71
  for await (const peerEnr of this.nextPeer()) {
@@ -143,9 +136,8 @@ export class PeerDiscoveryDns
143
136
  }
144
137
 
145
138
  export function wakuDnsDiscovery(
146
- enrUrls: string[],
147
- wantedNodeCapabilityCount: Partial<NodeCapabilityCount> = DEFAULT_NODE_REQUIREMENTS
139
+ enrUrls: string[]
148
140
  ): (components: DnsDiscoveryComponents) => PeerDiscoveryDns {
149
141
  return (components: DnsDiscoveryComponents) =>
150
- new PeerDiscoveryDns(components, { enrUrls, wantedNodeCapabilityCount });
142
+ new PeerDiscoveryDns(components, { enrUrls });
151
143
  }
@@ -1,7 +1,7 @@
1
1
  import type { DnsClient } from "@waku/interfaces";
2
2
  import { Logger } from "@waku/utils";
3
3
  import { bytesToUtf8 } from "@waku/utils/bytes";
4
- import { Endpoint, query, wellknown } from "dns-query";
4
+ import DnsOverHttpResolver from "dns-over-http-resolver";
5
5
 
6
6
  const log = new Logger("dns-over-https");
7
7
 
@@ -9,25 +9,13 @@ export class DnsOverHttps implements DnsClient {
9
9
  /**
10
10
  * Create new Dns-Over-Http DNS client.
11
11
  *
12
- * @param endpoints The endpoints for Dns-Over-Https queries;
13
- * Defaults to using dns-query's API..
14
- * @param retries Retries if a given endpoint fails.
15
- *
16
12
  * @throws {code: string} If DNS query fails.
17
13
  */
18
- public static async create(
19
- endpoints?: Endpoint[],
20
- retries?: number
21
- ): Promise<DnsOverHttps> {
22
- const _endpoints = endpoints ?? (await wellknown.endpoints("doh"));
23
-
24
- return new DnsOverHttps(_endpoints, retries);
14
+ public static async create(): Promise<DnsOverHttps> {
15
+ return new DnsOverHttps();
25
16
  }
26
17
 
27
- private constructor(
28
- private endpoints: Endpoint[],
29
- private retries: number = 3
30
- ) {}
18
+ private constructor(private resolver = new DnsOverHttpResolver()) {}
31
19
 
32
20
  /**
33
21
  * Resolves a TXT record
@@ -39,16 +27,7 @@ export class DnsOverHttps implements DnsClient {
39
27
  public async resolveTXT(domain: string): Promise<string[]> {
40
28
  let answers;
41
29
  try {
42
- const res = await query(
43
- {
44
- question: { type: "TXT", name: domain }
45
- },
46
- {
47
- endpoints: this.endpoints,
48
- retries: this.retries
49
- }
50
- );
51
- answers = res.answers;
30
+ answers = await this.resolver.resolveTxt(domain);
52
31
  } catch (error) {
53
32
  log.error("query failed: ", error);
54
33
  throw new Error("DNS query failed");
@@ -56,13 +35,9 @@ export class DnsOverHttps implements DnsClient {
56
35
 
57
36
  if (!answers) throw new Error(`Could not resolve ${domain}`);
58
37
 
59
- const data = answers.map((a) => a.data) as
60
- | Array<string | Uint8Array>
61
- | Array<Array<string | Uint8Array>>;
62
-
63
38
  const result: string[] = [];
64
39
 
65
- data.forEach((d) => {
40
+ answers.forEach((d) => {
66
41
  if (typeof d === "string") {
67
42
  result.push(d);
68
43
  } else if (Array.isArray(d)) {