@waku/discovery 0.0.7-00f2e75.0 → 0.0.7-0e49a1e.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,181 +1,44 @@
1
- import type { IEnr, NodeCapabilityCount, Waku2 } from "@waku/interfaces";
1
+ import type { IEnr } from "@waku/interfaces";
2
2
  import { Logger } from "@waku/utils";
3
3
 
4
4
  const log = new Logger("discovery:fetch_nodes");
5
5
 
6
6
  /**
7
- * Fetch nodes using passed [[getNode]] until all wanted capabilities are
8
- * fulfilled or the number of [[getNode]] call exceeds the sum of
9
- * [[wantedNodeCapabilityCount]] plus [[errorTolerance]].
7
+ * Fetch nodes using passed [[getNode]] until it has been called [[maxGet]]
8
+ * times, or it has returned empty or duplicate results more than [[maxErrors]]
9
+ * times.
10
10
  */
11
- export async function fetchNodesUntilCapabilitiesFulfilled(
12
- wantedNodeCapabilityCount: Partial<NodeCapabilityCount>,
13
- errorTolerance: number,
14
- getNode: () => Promise<IEnr | null>
15
- ): Promise<IEnr[]> {
16
- const wanted = {
17
- relay: wantedNodeCapabilityCount.relay ?? 0,
18
- store: wantedNodeCapabilityCount.store ?? 0,
19
- filter: wantedNodeCapabilityCount.filter ?? 0,
20
- lightPush: wantedNodeCapabilityCount.lightPush ?? 0
21
- };
22
-
23
- const maxSearches =
24
- wanted.relay + wanted.store + wanted.filter + wanted.lightPush;
25
-
26
- const actual = {
27
- relay: 0,
28
- store: 0,
29
- filter: 0,
30
- lightPush: 0
31
- };
11
+ export async function* fetchNodes(
12
+ getNode: () => Promise<IEnr | null>,
13
+ maxGet: number = 10,
14
+ maxErrors: number = 3
15
+ ): AsyncGenerator<IEnr> {
16
+ const peerNodeIds = new Set();
32
17
 
33
18
  let totalSearches = 0;
34
- const peers: IEnr[] = [];
19
+ let erroneousSearches = 0;
35
20
 
36
21
  while (
37
- !isSatisfied(wanted, actual) &&
38
- totalSearches < maxSearches + errorTolerance
22
+ totalSearches < maxGet &&
23
+ erroneousSearches < maxErrors // Allows a couple of empty results before calling it quit
39
24
  ) {
40
- const peer = await getNode();
41
- if (peer && isNewPeer(peer, peers)) {
42
- // ENRs without a waku2 key are ignored.
43
- if (peer.waku2) {
44
- if (helpsSatisfyCapabilities(peer.waku2, wanted, actual)) {
45
- addCapabilities(peer.waku2, actual);
46
- peers.push(peer);
47
- }
48
- }
49
- log.info(
50
- `got new peer candidate from DNS address=${peer.nodeId}@${peer.ip}`
51
- );
52
- }
53
-
54
25
  totalSearches++;
55
- }
56
- return peers;
57
- }
58
-
59
- /**
60
- * Fetch nodes using passed [[getNode]] until all wanted capabilities are
61
- * fulfilled or the number of [[getNode]] call exceeds the sum of
62
- * [[wantedNodeCapabilityCount]] plus [[errorTolerance]].
63
- */
64
- export async function* yieldNodesUntilCapabilitiesFulfilled(
65
- wantedNodeCapabilityCount: Partial<NodeCapabilityCount>,
66
- errorTolerance: number,
67
- getNode: () => Promise<IEnr | null>
68
- ): AsyncGenerator<IEnr> {
69
- const wanted = {
70
- relay: wantedNodeCapabilityCount.relay ?? 0,
71
- store: wantedNodeCapabilityCount.store ?? 0,
72
- filter: wantedNodeCapabilityCount.filter ?? 0,
73
- lightPush: wantedNodeCapabilityCount.lightPush ?? 0
74
- };
75
26
 
76
- const maxSearches =
77
- wanted.relay + wanted.store + wanted.filter + wanted.lightPush;
78
-
79
- const actual = {
80
- relay: 0,
81
- store: 0,
82
- filter: 0,
83
- lightPush: 0
84
- };
85
-
86
- let totalSearches = 0;
87
- const peerNodeIds = new Set();
88
-
89
- while (
90
- !isSatisfied(wanted, actual) &&
91
- totalSearches < maxSearches + errorTolerance
92
- ) {
93
27
  const peer = await getNode();
94
- if (peer && peer.nodeId && !peerNodeIds.has(peer.nodeId)) {
28
+ if (!peer || !peer.nodeId) {
29
+ erroneousSearches++;
30
+ continue;
31
+ }
32
+
33
+ if (!peerNodeIds.has(peer.nodeId)) {
95
34
  peerNodeIds.add(peer.nodeId);
96
35
  // ENRs without a waku2 key are ignored.
97
36
  if (peer.waku2) {
98
- if (helpsSatisfyCapabilities(peer.waku2, wanted, actual)) {
99
- addCapabilities(peer.waku2, actual);
100
- yield peer;
101
- }
37
+ yield peer;
102
38
  }
103
39
  log.info(
104
40
  `got new peer candidate from DNS address=${peer.nodeId}@${peer.ip}`
105
41
  );
106
42
  }
107
- totalSearches++;
108
43
  }
109
44
  }
110
-
111
- function isSatisfied(
112
- wanted: NodeCapabilityCount,
113
- actual: NodeCapabilityCount
114
- ): boolean {
115
- return (
116
- actual.relay >= wanted.relay &&
117
- actual.store >= wanted.store &&
118
- actual.filter >= wanted.filter &&
119
- actual.lightPush >= wanted.lightPush
120
- );
121
- }
122
-
123
- function isNewPeer(peer: IEnr, peers: IEnr[]): boolean {
124
- if (!peer.nodeId) return false;
125
-
126
- for (const existingPeer of peers) {
127
- if (peer.nodeId === existingPeer.nodeId) {
128
- return false;
129
- }
130
- }
131
-
132
- return true;
133
- }
134
-
135
- function addCapabilities(node: Waku2, total: NodeCapabilityCount): void {
136
- if (node.relay) total.relay += 1;
137
- if (node.store) total.store += 1;
138
- if (node.filter) total.filter += 1;
139
- if (node.lightPush) total.lightPush += 1;
140
- }
141
-
142
- /**
143
- * Checks if the proposed ENR [[node]] helps satisfy the [[wanted]] capabilities,
144
- * considering the [[actual]] capabilities of nodes retrieved so far..
145
- *
146
- * @throws If the function is called when the wanted capabilities are already fulfilled.
147
- */
148
- function helpsSatisfyCapabilities(
149
- node: Waku2,
150
- wanted: NodeCapabilityCount,
151
- actual: NodeCapabilityCount
152
- ): boolean {
153
- if (isSatisfied(wanted, actual)) {
154
- throw "Internal Error: Waku2 wanted capabilities are already fulfilled";
155
- }
156
-
157
- const missing = missingCapabilities(wanted, actual);
158
-
159
- return (
160
- (missing.relay && node.relay) ||
161
- (missing.store && node.store) ||
162
- (missing.filter && node.filter) ||
163
- (missing.lightPush && node.lightPush)
164
- );
165
- }
166
-
167
- /**
168
- * Return a [[Waku2]] Object for which capabilities are set to true if they are
169
- * [[wanted]] yet missing from [[actual]].
170
- */
171
- function missingCapabilities(
172
- wanted: NodeCapabilityCount,
173
- actual: NodeCapabilityCount
174
- ): Waku2 {
175
- return {
176
- relay: actual.relay < wanted.relay,
177
- store: actual.store < wanted.store,
178
- filter: actual.filter < wanted.filter,
179
- lightPush: actual.lightPush < wanted.lightPush
180
- };
181
- }