@libp2p/kad-dht 0.28.6

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.
Files changed (166) hide show
  1. package/LICENSE +4 -0
  2. package/README.md +105 -0
  3. package/dist/src/constants.d.ts +20 -0
  4. package/dist/src/constants.d.ts.map +1 -0
  5. package/dist/src/constants.js +34 -0
  6. package/dist/src/constants.js.map +1 -0
  7. package/dist/src/content-fetching/index.d.ts +55 -0
  8. package/dist/src/content-fetching/index.d.ts.map +1 -0
  9. package/dist/src/content-fetching/index.js +190 -0
  10. package/dist/src/content-fetching/index.js.map +1 -0
  11. package/dist/src/content-routing/index.d.ts +42 -0
  12. package/dist/src/content-routing/index.d.ts.map +1 -0
  13. package/dist/src/content-routing/index.js +129 -0
  14. package/dist/src/content-routing/index.js.map +1 -0
  15. package/dist/src/dual-kad-dht.d.ts +65 -0
  16. package/dist/src/dual-kad-dht.d.ts.map +1 -0
  17. package/dist/src/dual-kad-dht.js +191 -0
  18. package/dist/src/dual-kad-dht.js.map +1 -0
  19. package/dist/src/index.d.ts +4 -0
  20. package/dist/src/index.d.ts.map +1 -0
  21. package/dist/src/index.js +15 -0
  22. package/dist/src/index.js.map +1 -0
  23. package/dist/src/kad-dht.d.ts +131 -0
  24. package/dist/src/kad-dht.d.ts.map +1 -0
  25. package/dist/src/kad-dht.js +268 -0
  26. package/dist/src/kad-dht.js.map +1 -0
  27. package/dist/src/message/dht.d.ts +297 -0
  28. package/dist/src/message/dht.js +921 -0
  29. package/dist/src/message/index.d.ts +32 -0
  30. package/dist/src/message/index.d.ts.map +1 -0
  31. package/dist/src/message/index.js +81 -0
  32. package/dist/src/message/index.js.map +1 -0
  33. package/dist/src/network.d.ts +60 -0
  34. package/dist/src/network.d.ts.map +1 -0
  35. package/dist/src/network.js +124 -0
  36. package/dist/src/network.js.map +1 -0
  37. package/dist/src/peer-list/index.d.ts +29 -0
  38. package/dist/src/peer-list/index.d.ts.map +1 -0
  39. package/dist/src/peer-list/index.js +44 -0
  40. package/dist/src/peer-list/index.js.map +1 -0
  41. package/dist/src/peer-list/peer-distance-list.d.ts +34 -0
  42. package/dist/src/peer-list/peer-distance-list.d.ts.map +1 -0
  43. package/dist/src/peer-list/peer-distance-list.js +64 -0
  44. package/dist/src/peer-list/peer-distance-list.js.map +1 -0
  45. package/dist/src/peer-routing/index.d.ts +71 -0
  46. package/dist/src/peer-routing/index.d.ts.map +1 -0
  47. package/dist/src/peer-routing/index.js +256 -0
  48. package/dist/src/peer-routing/index.js.map +1 -0
  49. package/dist/src/providers.d.ts +64 -0
  50. package/dist/src/providers.d.ts.map +1 -0
  51. package/dist/src/providers.js +208 -0
  52. package/dist/src/providers.js.map +1 -0
  53. package/dist/src/query/events.d.ts +46 -0
  54. package/dist/src/query/events.d.ts.map +1 -0
  55. package/dist/src/query/events.js +73 -0
  56. package/dist/src/query/events.js.map +1 -0
  57. package/dist/src/query/manager.d.ts +40 -0
  58. package/dist/src/query/manager.d.ts.map +1 -0
  59. package/dist/src/query/manager.js +140 -0
  60. package/dist/src/query/manager.js.map +1 -0
  61. package/dist/src/query/query-path.d.ts +58 -0
  62. package/dist/src/query/query-path.d.ts.map +1 -0
  63. package/dist/src/query/query-path.js +171 -0
  64. package/dist/src/query/query-path.js.map +1 -0
  65. package/dist/src/query/types.d.ts +16 -0
  66. package/dist/src/query/types.d.ts.map +1 -0
  67. package/dist/src/query/types.js +2 -0
  68. package/dist/src/query/types.js.map +1 -0
  69. package/dist/src/query-self.d.ts +31 -0
  70. package/dist/src/query-self.d.ts.map +1 -0
  71. package/dist/src/query-self.js +73 -0
  72. package/dist/src/query-self.js.map +1 -0
  73. package/dist/src/routing-table/generated-prefix-list-browser.d.ts +3 -0
  74. package/dist/src/routing-table/generated-prefix-list-browser.d.ts.map +1 -0
  75. package/dist/src/routing-table/generated-prefix-list-browser.js +1027 -0
  76. package/dist/src/routing-table/generated-prefix-list-browser.js.map +1 -0
  77. package/dist/src/routing-table/generated-prefix-list.d.ts +3 -0
  78. package/dist/src/routing-table/generated-prefix-list.d.ts.map +1 -0
  79. package/dist/src/routing-table/generated-prefix-list.js +4099 -0
  80. package/dist/src/routing-table/generated-prefix-list.js.map +1 -0
  81. package/dist/src/routing-table/index.d.ts +91 -0
  82. package/dist/src/routing-table/index.d.ts.map +1 -0
  83. package/dist/src/routing-table/index.js +183 -0
  84. package/dist/src/routing-table/index.js.map +1 -0
  85. package/dist/src/routing-table/refresh.d.ts +50 -0
  86. package/dist/src/routing-table/refresh.d.ts.map +1 -0
  87. package/dist/src/routing-table/refresh.js +204 -0
  88. package/dist/src/routing-table/refresh.js.map +1 -0
  89. package/dist/src/routing-table/types.d.ts +24 -0
  90. package/dist/src/routing-table/types.d.ts.map +1 -0
  91. package/dist/src/rpc/handlers/add-provider.d.ts +13 -0
  92. package/dist/src/rpc/handlers/add-provider.d.ts.map +1 -0
  93. package/dist/src/rpc/handlers/add-provider.js +42 -0
  94. package/dist/src/rpc/handlers/add-provider.js.map +1 -0
  95. package/dist/src/rpc/handlers/find-node.d.ts +18 -0
  96. package/dist/src/rpc/handlers/find-node.d.ts.map +1 -0
  97. package/dist/src/rpc/handlers/find-node.js +32 -0
  98. package/dist/src/rpc/handlers/find-node.js.map +1 -0
  99. package/dist/src/rpc/handlers/get-providers.d.ts +24 -0
  100. package/dist/src/rpc/handlers/get-providers.d.ts.map +1 -0
  101. package/dist/src/rpc/handlers/get-providers.js +60 -0
  102. package/dist/src/rpc/handlers/get-providers.js.map +1 -0
  103. package/dist/src/rpc/handlers/get-value.d.ts +27 -0
  104. package/dist/src/rpc/handlers/get-value.d.ts.map +1 -0
  105. package/dist/src/rpc/handlers/get-value.js +94 -0
  106. package/dist/src/rpc/handlers/get-value.js.map +1 -0
  107. package/dist/src/rpc/handlers/index.d.ts +13 -0
  108. package/dist/src/rpc/handlers/index.d.ts.map +1 -0
  109. package/dist/src/rpc/handlers/ping.d.ts +7 -0
  110. package/dist/src/rpc/handlers/ping.d.ts.map +1 -0
  111. package/dist/src/rpc/handlers/ping.js +9 -0
  112. package/dist/src/rpc/handlers/ping.js.map +1 -0
  113. package/dist/src/rpc/handlers/put-value.d.ts +18 -0
  114. package/dist/src/rpc/handlers/put-value.d.ts.map +1 -0
  115. package/dist/src/rpc/handlers/put-value.js +35 -0
  116. package/dist/src/rpc/handlers/put-value.js.map +1 -0
  117. package/dist/src/rpc/index.d.ts +38 -0
  118. package/dist/src/rpc/index.d.ts.map +1 -0
  119. package/dist/src/rpc/index.js +75 -0
  120. package/dist/src/rpc/index.js.map +1 -0
  121. package/dist/src/rpc/types.d.ts +6 -0
  122. package/dist/src/rpc/types.d.ts.map +1 -0
  123. package/dist/src/topology-listener.d.ts +33 -0
  124. package/dist/src/topology-listener.d.ts.map +1 -0
  125. package/dist/src/topology-listener.js +50 -0
  126. package/dist/src/topology-listener.js.map +1 -0
  127. package/dist/src/types.d.ts +143 -0
  128. package/dist/src/types.d.ts.map +1 -0
  129. package/dist/src/utils.d.ts +33 -0
  130. package/dist/src/utils.d.ts.map +1 -0
  131. package/dist/src/utils.js +89 -0
  132. package/dist/src/utils.js.map +1 -0
  133. package/package.json +200 -0
  134. package/src/constants.ts +50 -0
  135. package/src/content-fetching/index.ts +276 -0
  136. package/src/content-routing/index.ts +202 -0
  137. package/src/dual-kad-dht.ts +257 -0
  138. package/src/index.ts +21 -0
  139. package/src/kad-dht.ts +396 -0
  140. package/src/message/dht.d.ts +297 -0
  141. package/src/message/dht.js +921 -0
  142. package/src/message/dht.proto +75 -0
  143. package/src/message/index.ts +111 -0
  144. package/src/network.ts +185 -0
  145. package/src/peer-list/index.ts +54 -0
  146. package/src/peer-list/peer-distance-list.ts +93 -0
  147. package/src/peer-routing/index.ts +332 -0
  148. package/src/providers.ts +278 -0
  149. package/src/query/events.ts +126 -0
  150. package/src/query/manager.ts +188 -0
  151. package/src/query/query-path.ts +263 -0
  152. package/src/query/types.ts +22 -0
  153. package/src/query-self.ts +106 -0
  154. package/src/routing-table/generated-prefix-list-browser.ts +1026 -0
  155. package/src/routing-table/generated-prefix-list.ts +4098 -0
  156. package/src/routing-table/index.ts +265 -0
  157. package/src/routing-table/refresh.ts +263 -0
  158. package/src/rpc/handlers/add-provider.ts +63 -0
  159. package/src/rpc/handlers/find-node.ts +57 -0
  160. package/src/rpc/handlers/get-providers.ts +95 -0
  161. package/src/rpc/handlers/get-value.ts +130 -0
  162. package/src/rpc/handlers/ping.ts +13 -0
  163. package/src/rpc/handlers/put-value.ts +58 -0
  164. package/src/rpc/index.ts +118 -0
  165. package/src/topology-listener.ts +78 -0
  166. package/src/utils.ts +108 -0
@@ -0,0 +1,73 @@
1
+ import { MESSAGE_TYPE_LOOKUP } from '../message/index.js';
2
+ const MESSAGE_NAMES = [
3
+ 'PUT_VALUE',
4
+ 'GET_VALUE',
5
+ 'ADD_PROVIDER',
6
+ 'GET_PROVIDERS',
7
+ 'FIND_NODE',
8
+ 'PING'
9
+ ];
10
+ export function sendingQueryEvent(fields) {
11
+ return {
12
+ ...fields,
13
+ name: 'SENDING_QUERY',
14
+ type: 0,
15
+ // @ts-expect-error cannot look up values like this
16
+ messageName: MESSAGE_TYPE_LOOKUP[fields.type],
17
+ messageType: fields.type
18
+ };
19
+ }
20
+ export function peerResponseEvent(fields) {
21
+ return {
22
+ ...fields,
23
+ name: 'PEER_RESPONSE',
24
+ type: 1,
25
+ // @ts-expect-error cannot look up values like this
26
+ messageName: MESSAGE_NAMES[fields.messageType],
27
+ closer: (fields.closer != null) ? fields.closer : [],
28
+ providers: (fields.providers != null) ? fields.providers : []
29
+ };
30
+ }
31
+ export function finalPeerEvent(fields) {
32
+ return {
33
+ ...fields,
34
+ name: 'FINAL_PEER',
35
+ type: 2
36
+ };
37
+ }
38
+ export function queryErrorEvent(fields) {
39
+ return {
40
+ ...fields,
41
+ name: 'QUERY_ERROR',
42
+ type: 3
43
+ };
44
+ }
45
+ export function providerEvent(fields) {
46
+ return {
47
+ ...fields,
48
+ name: 'PROVIDER',
49
+ type: 4
50
+ };
51
+ }
52
+ export function valueEvent(fields) {
53
+ return {
54
+ ...fields,
55
+ name: 'VALUE',
56
+ type: 5
57
+ };
58
+ }
59
+ export function addingPeerEvent(fields) {
60
+ return {
61
+ ...fields,
62
+ name: 'ADDING_PEER',
63
+ type: 6
64
+ };
65
+ }
66
+ export function dialingPeerEvent(fields) {
67
+ return {
68
+ ...fields,
69
+ name: 'DIALING_PEER',
70
+ type: 7
71
+ };
72
+ }
73
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/query/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAMzD,MAAM,aAAa,GAAG;IACpB,WAAW;IACX,WAAW;IACX,cAAc;IACd,eAAe;IACf,WAAW;IACX,MAAM;CACP,CAAA;AAOD,MAAM,UAAU,iBAAiB,CAAE,MAAwB;IACzD,OAAO;QACL,GAAG,MAAM;QACT,IAAI,EAAE,eAAe;QACrB,IAAI,EAAE,CAAC;QACP,mDAAmD;QACnD,WAAW,EAAE,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC;QAC7C,WAAW,EAAE,MAAM,CAAC,IAAI;KACzB,CAAA;AACH,CAAC;AAUD,MAAM,UAAU,iBAAiB,CAAE,MAA8B;IAC/D,OAAO;QACL,GAAG,MAAM;QACT,IAAI,EAAE,eAAe;QACrB,IAAI,EAAE,CAAC;QACP,mDAAmD;QACnD,WAAW,EAAE,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC;QAC9C,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;QACpD,SAAS,EAAE,CAAC,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;KAC9D,CAAA;AACH,CAAC;AAOD,MAAM,UAAU,cAAc,CAAE,MAA4B;IAC1D,OAAO;QACL,GAAG,MAAM;QACT,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,CAAC;KACR,CAAA;AACH,CAAC;AAOD,MAAM,UAAU,eAAe,CAAE,MAAwB;IACvD,OAAO;QACL,GAAG,MAAM;QACT,IAAI,EAAE,aAAa;QACnB,IAAI,EAAE,CAAC;KACR,CAAA;AACH,CAAC;AAOD,MAAM,UAAU,aAAa,CAAE,MAA2B;IACxD,OAAO;QACL,GAAG,MAAM;QACT,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,CAAC;KACR,CAAA;AACH,CAAC;AAOD,MAAM,UAAU,UAAU,CAAE,MAAwB;IAClD,OAAO;QACL,GAAG,MAAM;QACT,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,CAAC;KACR,CAAA;AACH,CAAC;AAMD,MAAM,UAAU,eAAe,CAAE,MAAuB;IACtD,OAAO;QACL,GAAG,MAAM;QACT,IAAI,EAAE,aAAa;QACnB,IAAI,EAAE,CAAC;KACR,CAAA;AACH,CAAC;AAMD,MAAM,UAAU,gBAAgB,CAAE,MAA8B;IAC9D,OAAO;QACL,GAAG,MAAM;QACT,IAAI,EAAE,cAAc;QACpB,IAAI,EAAE,CAAC;KACR,CAAA;AACH,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type { PeerId } from '@libp2p/interfaces/peer-id';
2
+ import type { ComponentMetricsTracker } from '@libp2p/interfaces/metrics';
3
+ import type { Startable } from '@libp2p/interfaces';
4
+ import type { QueryFunc } from './types.js';
5
+ import type { QueryOptions } from '@libp2p/interfaces/dht';
6
+ export interface CleanUpEvents {
7
+ 'cleanup': CustomEvent;
8
+ }
9
+ export interface QueryManagerOptions {
10
+ peerId: PeerId;
11
+ lan?: boolean;
12
+ metrics?: ComponentMetricsTracker;
13
+ disjointPaths?: number;
14
+ alpha?: number;
15
+ }
16
+ /**
17
+ * Keeps track of all running queries
18
+ */
19
+ export declare class QueryManager implements Startable {
20
+ private readonly peerId;
21
+ private readonly lan;
22
+ private readonly metrics?;
23
+ disjointPaths: number;
24
+ private readonly alpha;
25
+ private readonly controllers;
26
+ private running;
27
+ private queries;
28
+ constructor(options: QueryManagerOptions);
29
+ isStarted(): boolean;
30
+ /**
31
+ * Starts the query manager
32
+ */
33
+ start(): Promise<void>;
34
+ /**
35
+ * Stops all queries
36
+ */
37
+ stop(): Promise<void>;
38
+ run(key: Uint8Array, peers: PeerId[], queryFunc: QueryFunc, options?: QueryOptions): AsyncGenerator<import("@libp2p/interfaces/dht").QueryEvent, void, unknown>;
39
+ }
40
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/query/manager.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAA;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAI1D,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,WAAW,CAAA;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,OAAO,CAAC,EAAE,uBAAuB,CAAA;IACjC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;GAEG;AACH,qBAAa,YAAa,YAAW,SAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAyB;IAC3C,aAAa,EAAE,MAAM,CAAA;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;IAClD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAQ;gBAEV,OAAO,EAAE,mBAAmB;IAYzC,SAAS;IAIT;;OAEG;IACG,KAAK;IAIX;;OAEG;IACG,IAAI;IAUF,GAAG,CAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,GAAE,YAAiB;CAwGhG"}
@@ -0,0 +1,140 @@
1
+ import { TimeoutController } from 'timeout-abort-controller';
2
+ import { anySignal } from 'any-signal';
3
+ import { ALPHA, K, DEFAULT_QUERY_TIMEOUT } from '../constants.js';
4
+ import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
5
+ import { queryPath } from './query-path.js';
6
+ import merge from 'it-merge';
7
+ import {
8
+ // @ts-expect-error only defined in node 15+
9
+ setMaxListeners } from 'events';
10
+ import { EventEmitter, CustomEvent } from '@libp2p/interfaces';
11
+ import { logger } from '@libp2p/logger';
12
+ const METRIC_RUNNING_QUERIES = 'running-queries';
13
+ /**
14
+ * Keeps track of all running queries
15
+ */
16
+ export class QueryManager {
17
+ constructor(options) {
18
+ const { peerId, lan = false, metrics, disjointPaths = K, alpha = ALPHA } = options;
19
+ this.peerId = peerId;
20
+ this.disjointPaths = disjointPaths ?? K;
21
+ this.controllers = new Set();
22
+ this.running = false;
23
+ this.alpha = alpha ?? ALPHA;
24
+ this.lan = lan;
25
+ this.metrics = metrics;
26
+ this.queries = 0;
27
+ }
28
+ isStarted() {
29
+ return this.running;
30
+ }
31
+ /**
32
+ * Starts the query manager
33
+ */
34
+ async start() {
35
+ this.running = true;
36
+ }
37
+ /**
38
+ * Stops all queries
39
+ */
40
+ async stop() {
41
+ this.running = false;
42
+ for (const controller of this.controllers) {
43
+ controller.abort();
44
+ }
45
+ this.controllers.clear();
46
+ }
47
+ async *run(key, peers, queryFunc, options = {}) {
48
+ if (!this.running) {
49
+ throw new Error('QueryManager not started');
50
+ }
51
+ let timeoutController;
52
+ if (options.signal == null) {
53
+ // don't let queries run forever
54
+ timeoutController = new TimeoutController(DEFAULT_QUERY_TIMEOUT);
55
+ options.signal = timeoutController.signal;
56
+ }
57
+ // allow us to stop queries on shut down
58
+ const abortController = new AbortController();
59
+ this.controllers.add(abortController);
60
+ const signals = [abortController.signal];
61
+ if (options.signal != null) {
62
+ signals.push(options.signal);
63
+ }
64
+ const signal = anySignal(signals);
65
+ // this signal will get listened to for every invocation of queryFunc
66
+ // so make sure we don't make a lot of noise in the logs
67
+ try {
68
+ if (setMaxListeners != null) {
69
+ setMaxListeners(0, signal);
70
+ }
71
+ }
72
+ catch { } // fails on node < 15.4
73
+ const log = logger(`libp2p:kad-dht:${this.lan ? 'lan' : 'wan'}:query:` + uint8ArrayToString(key, 'base58btc'));
74
+ // query a subset of peers up to `kBucketSize / 2` in length
75
+ const peersToQuery = peers.slice(0, Math.min(this.disjointPaths, peers.length));
76
+ const startTime = Date.now();
77
+ const cleanUp = new EventEmitter();
78
+ try {
79
+ log('query:start');
80
+ this.queries++;
81
+ this.metrics?.updateComponentMetric({
82
+ system: 'libp2p',
83
+ component: `kad-dht-${this.lan ? 'lan' : 'wan'}`,
84
+ metric: METRIC_RUNNING_QUERIES,
85
+ value: this.queries
86
+ });
87
+ if (peers.length === 0) {
88
+ log.error('Running query with no peers');
89
+ return;
90
+ }
91
+ // Create query paths from the starting peers
92
+ const paths = peersToQuery.map((peer, index) => {
93
+ return queryPath({
94
+ key,
95
+ startingPeer: peer,
96
+ ourPeerId: this.peerId,
97
+ signal,
98
+ query: queryFunc,
99
+ pathIndex: index,
100
+ numPaths: peersToQuery.length,
101
+ alpha: this.alpha,
102
+ cleanUp,
103
+ queryFuncTimeout: options.queryFuncTimeout,
104
+ log
105
+ });
106
+ });
107
+ // Execute the query along each disjoint path and yield their results as they become available
108
+ for await (const event of merge(...paths)) {
109
+ yield event;
110
+ if (event.name === 'QUERY_ERROR') {
111
+ log('error', event.error);
112
+ }
113
+ }
114
+ }
115
+ catch (err) {
116
+ if (!this.running && err.code === 'ERR_QUERY_ABORTED') {
117
+ // ignore query aborted errors that were thrown during query manager shutdown
118
+ }
119
+ else {
120
+ throw err;
121
+ }
122
+ }
123
+ finally {
124
+ this.controllers.delete(abortController);
125
+ if (timeoutController != null) {
126
+ timeoutController.clear();
127
+ }
128
+ this.queries--;
129
+ this.metrics?.updateComponentMetric({
130
+ system: 'libp2p',
131
+ component: `kad-dht-${this.lan ? 'lan' : 'wan'}`,
132
+ metric: METRIC_RUNNING_QUERIES,
133
+ value: this.queries
134
+ });
135
+ cleanUp.dispatchEvent(new CustomEvent('cleanup'));
136
+ log('query:done in %dms', Date.now() - startTime);
137
+ }
138
+ }
139
+ }
140
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/query/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type { PeerId } from '@libp2p/interfaces/peer-id';
2
+ import type { EventEmitter } from '@libp2p/interfaces';
3
+ import type { CleanUpEvents } from './manager.js';
4
+ import type { Logger } from '@libp2p/logger';
5
+ import type { QueryFunc } from '../query/types.js';
6
+ import type { QueryEvent } from '@libp2p/interfaces/dht';
7
+ export interface QueryPathOptions {
8
+ /**
9
+ * What are we trying to find
10
+ */
11
+ key: Uint8Array;
12
+ /**
13
+ * Where we start our query
14
+ */
15
+ startingPeer: PeerId;
16
+ /**
17
+ * Who we are
18
+ */
19
+ ourPeerId: PeerId;
20
+ /**
21
+ * When to stop querying
22
+ */
23
+ signal: AbortSignal;
24
+ /**
25
+ * The query function to run with each peer
26
+ */
27
+ query: QueryFunc;
28
+ /**
29
+ * How many concurrent node/value lookups to run
30
+ */
31
+ alpha: number;
32
+ /**
33
+ * How many concurrent node/value lookups to run
34
+ */
35
+ pathIndex: number;
36
+ /**
37
+ * How many concurrent node/value lookups to run
38
+ */
39
+ numPaths: number;
40
+ /**
41
+ * will emit a 'cleanup' event if the caller exits the for..await of early
42
+ */
43
+ cleanUp: EventEmitter<CleanUpEvents>;
44
+ /**
45
+ * A timeout for queryFunc in ms
46
+ */
47
+ queryFuncTimeout?: number;
48
+ /**
49
+ * Query log
50
+ */
51
+ log: Logger;
52
+ }
53
+ /**
54
+ * Walks a path through the DHT, calling the passed query function for
55
+ * every peer encountered that we have not seen before
56
+ */
57
+ export declare function queryPath(options: QueryPathOptions): AsyncGenerator<QueryEvent, void, undefined>;
58
+ //# sourceMappingURL=query-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-path.d.ts","sourceRoot":"","sources":["../../../src/query/query-path.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAElD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAIxD,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,GAAG,EAAE,UAAU,CAAA;IAEf;;OAEG;IACH,YAAY,EAAE,MAAM,CAAA;IAEpB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,MAAM,EAAE,WAAW,CAAA;IAEnB;;OAEG;IACH,KAAK,EAAE,SAAS,CAAA;IAEhB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;IAEb;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAEhB;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC,aAAa,CAAC,CAAA;IAEpC;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAEzB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAA;CACZ;AAED;;;GAGG;AACH,wBAAwB,SAAS,CAAE,OAAO,EAAE,gBAAgB,+CAkH3D"}
@@ -0,0 +1,171 @@
1
+ import Queue from 'p-queue';
2
+ import { xor } from 'uint8arrays/xor';
3
+ import { toString } from 'uint8arrays/to-string';
4
+ import defer from 'p-defer';
5
+ import errCode from 'err-code';
6
+ import { convertPeerId, convertBuffer } from '../utils.js';
7
+ import { TimeoutController } from 'timeout-abort-controller';
8
+ import { anySignal } from 'any-signal';
9
+ import { queryErrorEvent } from './events.js';
10
+ import { base58btc } from 'multiformats/bases/base58';
11
+ const MAX_XOR = BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF');
12
+ /**
13
+ * Walks a path through the DHT, calling the passed query function for
14
+ * every peer encountered that we have not seen before
15
+ */
16
+ export async function* queryPath(options) {
17
+ const { key, startingPeer, ourPeerId, signal, query, alpha, pathIndex, numPaths, cleanUp, queryFuncTimeout, log } = options;
18
+ // Only ALPHA node/value lookups are allowed at any given time for each process
19
+ // https://github.com/libp2p/specs/tree/master/kad-dht#alpha-concurrency-parameter-%CE%B1
20
+ const queue = new Queue({
21
+ concurrency: alpha
22
+ });
23
+ // perform lookups on kadId, not the actual value
24
+ const kadId = await convertBuffer(key);
25
+ // make sure we don't get trapped in a loop
26
+ const peersSeen = new Set();
27
+ /**
28
+ * Adds the passed peer to the query queue if it's not us and no
29
+ * other path has passed through this peer
30
+ */
31
+ function queryPeer(peer, peerKadId) {
32
+ if (peer == null) {
33
+ return;
34
+ }
35
+ peersSeen.add(peer.toString(base58btc));
36
+ const peerXor = BigInt('0x' + toString(xor(peerKadId, kadId), 'base16'));
37
+ queue.add(async () => {
38
+ let timeout;
39
+ const signals = [signal];
40
+ if (queryFuncTimeout != null) {
41
+ timeout = new TimeoutController(queryFuncTimeout);
42
+ signals.push(timeout.signal);
43
+ }
44
+ const compoundSignal = anySignal(signals);
45
+ try {
46
+ for await (const event of query({
47
+ key,
48
+ peer,
49
+ signal: compoundSignal,
50
+ pathIndex,
51
+ numPaths
52
+ })) {
53
+ if (compoundSignal.aborted) {
54
+ return;
55
+ }
56
+ // if there are closer peers and the query has not completed, continue the query
57
+ if (event.name === 'PEER_RESPONSE') {
58
+ for (const closerPeer of event.closer) {
59
+ if (peersSeen.has(closerPeer.id.toString(base58btc))) { // eslint-disable-line max-depth
60
+ log('already seen %p in query', closerPeer.id);
61
+ continue;
62
+ }
63
+ if (ourPeerId.equals(closerPeer.id)) { // eslint-disable-line max-depth
64
+ log('not querying ourselves');
65
+ continue;
66
+ }
67
+ const closerPeerKadId = await convertPeerId(closerPeer.id);
68
+ const closerPeerXor = BigInt('0x' + toString(xor(closerPeerKadId, kadId), 'base16'));
69
+ // only continue query if closer peer is actually closer
70
+ if (closerPeerXor > peerXor) { // eslint-disable-line max-depth
71
+ log('skipping %p as they are not closer to %b than %p', closerPeer.id, key, peer);
72
+ continue;
73
+ }
74
+ log('querying closer peer %p', closerPeer.id);
75
+ queryPeer(closerPeer.id, closerPeerKadId);
76
+ }
77
+ }
78
+ // TODO: we have upgraded to p-queue@7, this should no longer be necessary
79
+ queue.emit('completed', event);
80
+ }
81
+ timeout?.clear();
82
+ }
83
+ catch (err) {
84
+ if (signal.aborted) {
85
+ // TODO: we have upgraded to p-queue@7, this should no longer be necessary
86
+ queue.emit('error', err);
87
+ }
88
+ else {
89
+ // TODO: we have upgraded to p-queue@7, this should no longer be necessary
90
+ queue.emit('completed', queryErrorEvent({
91
+ from: peer,
92
+ error: err
93
+ }));
94
+ }
95
+ }
96
+ finally {
97
+ timeout?.clear();
98
+ }
99
+ }, {
100
+ // use xor value as the queue priority - closer peers should execute first
101
+ // subtract it from MAX_XOR because higher priority values execute sooner
102
+ // @ts-expect-error this is supposed to be a Number but it's ok to use BigInts
103
+ // as long as all priorities are BigInts since we won't mix BigInts and Number
104
+ // values in arithmetic operations
105
+ priority: MAX_XOR - peerXor
106
+ }).catch(err => {
107
+ log.error(err);
108
+ });
109
+ }
110
+ // begin the query with the starting peer
111
+ queryPeer(startingPeer, await convertPeerId(startingPeer));
112
+ // yield results as they come in
113
+ yield* toGenerator(queue, signal, cleanUp, log);
114
+ }
115
+ async function* toGenerator(queue, signal, cleanUp, log) {
116
+ let deferred = defer();
117
+ let running = true;
118
+ const results = [];
119
+ const cleanup = () => {
120
+ if (!running) {
121
+ return;
122
+ }
123
+ log('clean up queue, results %d, queue size %d, pending tasks %d', results.length, queue.size, queue.pending);
124
+ running = false;
125
+ queue.clear();
126
+ results.splice(0, results.length);
127
+ };
128
+ queue.on('completed', result => {
129
+ results.push(result);
130
+ deferred.resolve();
131
+ });
132
+ queue.on('error', err => {
133
+ log('queue error', err);
134
+ cleanup();
135
+ deferred.reject(err);
136
+ });
137
+ queue.on('idle', () => {
138
+ log('queue idle');
139
+ running = false;
140
+ deferred.resolve();
141
+ });
142
+ // clear the queue and throw if the query is aborted
143
+ signal.addEventListener('abort', () => {
144
+ log('abort queue');
145
+ const wasRunning = running;
146
+ cleanup();
147
+ if (wasRunning) {
148
+ deferred.reject(errCode(new Error('Query aborted'), 'ERR_QUERY_ABORTED'));
149
+ }
150
+ });
151
+ // the user broke out of the loop early, ensure we resolve the deferred result
152
+ // promise and clear the queue of any remaining jobs
153
+ cleanUp.addEventListener('cleanup', () => {
154
+ cleanup();
155
+ deferred.resolve();
156
+ });
157
+ while (running) { // eslint-disable-line no-unmodified-loop-condition
158
+ await deferred.promise;
159
+ deferred = defer();
160
+ // yield all available results
161
+ while (results.length > 0) {
162
+ const result = results.shift();
163
+ if (result != null) {
164
+ yield result;
165
+ }
166
+ }
167
+ }
168
+ // yield any remaining results
169
+ yield* results;
170
+ }
171
+ //# sourceMappingURL=query-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-path.js","sourceRoot":"","sources":["../../../src/query/query-path.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { PeerId } from '@libp2p/interfaces/peer-id';
2
+ import type { QueryEvent } from '@libp2p/interfaces/dht';
3
+ export interface QueryContext {
4
+ key: Uint8Array;
5
+ peer: PeerId;
6
+ signal: AbortSignal;
7
+ pathIndex: number;
8
+ numPaths: number;
9
+ }
10
+ /**
11
+ * Query function
12
+ */
13
+ export interface QueryFunc {
14
+ (context: QueryContext): AsyncIterable<QueryEvent>;
15
+ }
16
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/query/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAExD,MAAM,WAAW,YAAY;IAE3B,GAAG,EAAE,UAAU,CAAA;IAEf,IAAI,EAAE,MAAM,CAAA;IAEZ,MAAM,EAAE,WAAW,CAAA;IAEnB,SAAS,EAAE,MAAM,CAAA;IAEjB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,CAAC,OAAO,EAAE,YAAY,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;CACnD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/query/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ import type { PeerRouting } from './peer-routing/index.js';
2
+ import type { PeerId } from '@libp2p/interfaces/peer-id';
3
+ import type { Startable } from '@libp2p/interfaces';
4
+ export interface QuerySelfOptions {
5
+ peerId: PeerId;
6
+ lan: boolean;
7
+ peerRouting: PeerRouting;
8
+ count?: number;
9
+ interval?: number;
10
+ queryTimeout?: number;
11
+ }
12
+ /**
13
+ * Receives notifications of new peers joining the network that support the DHT protocol
14
+ */
15
+ export declare class QuerySelf implements Startable {
16
+ private readonly log;
17
+ private readonly peerId;
18
+ private readonly peerRouting;
19
+ private readonly count;
20
+ private readonly interval;
21
+ private readonly queryTimeout;
22
+ private running;
23
+ private timeoutId?;
24
+ private controller?;
25
+ constructor(options: QuerySelfOptions);
26
+ isStarted(): boolean;
27
+ start(): Promise<void>;
28
+ stop(): Promise<void>;
29
+ _querySelf(): void;
30
+ }
31
+ //# sourceMappingURL=query-self.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-self.d.ts","sourceRoot":"","sources":["../../src/query-self.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAGnD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,OAAO,CAAA;IACZ,WAAW,EAAE,WAAW,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,qBAAa,SAAU,YAAW,SAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAC,CAAc;IAChC,OAAO,CAAC,UAAU,CAAC,CAAiB;gBAEvB,OAAO,EAAE,gBAAgB;IAYtC,SAAS;IAIH,KAAK;IASL,IAAI;IAYV,UAAU;CAgCX"}
@@ -0,0 +1,73 @@
1
+ // @ts-expect-error setMaxListeners is missing from the types
2
+ import { setMaxListeners } from 'events';
3
+ import take from 'it-take';
4
+ import length from 'it-length';
5
+ import { QUERY_SELF_INTERVAL, QUERY_SELF_TIMEOUT, K } from './constants.js';
6
+ import { TimeoutController } from 'timeout-abort-controller';
7
+ import { anySignal } from 'any-signal';
8
+ import { logger } from '@libp2p/logger';
9
+ import { pipe } from 'it-pipe';
10
+ /**
11
+ * Receives notifications of new peers joining the network that support the DHT protocol
12
+ */
13
+ export class QuerySelf {
14
+ constructor(options) {
15
+ const { peerId, peerRouting, lan, count, interval, queryTimeout } = options;
16
+ this.log = logger(`libp2p:kad-dht:${lan ? 'lan' : 'wan'}:query-self`);
17
+ this.running = false;
18
+ this.peerId = peerId;
19
+ this.peerRouting = peerRouting;
20
+ this.count = count ?? K;
21
+ this.interval = interval ?? QUERY_SELF_INTERVAL;
22
+ this.queryTimeout = queryTimeout ?? QUERY_SELF_TIMEOUT;
23
+ }
24
+ isStarted() {
25
+ return this.running;
26
+ }
27
+ async start() {
28
+ if (this.running) {
29
+ return;
30
+ }
31
+ this.running = true;
32
+ this._querySelf();
33
+ }
34
+ async stop() {
35
+ this.running = false;
36
+ if (this.timeoutId != null) {
37
+ clearTimeout(this.timeoutId);
38
+ }
39
+ if (this.controller != null) {
40
+ this.controller.abort();
41
+ }
42
+ }
43
+ _querySelf() {
44
+ Promise.resolve().then(async () => {
45
+ const timeoutController = new TimeoutController(this.queryTimeout);
46
+ try {
47
+ this.controller = new AbortController();
48
+ const signal = anySignal([this.controller.signal, timeoutController.signal]);
49
+ // this controller will get used for lots of dial attempts so make sure we don't cause warnings to be logged
50
+ try {
51
+ if (setMaxListeners != null) {
52
+ setMaxListeners(Infinity, signal);
53
+ }
54
+ }
55
+ catch { } // fails on node < 15.4
56
+ const found = await pipe(this.peerRouting.getClosestPeers(this.peerId.toBytes(), {
57
+ signal
58
+ }), (source) => take(source, this.count), async (source) => await length(source));
59
+ this.log('query ran successfully - found %d peers', found);
60
+ }
61
+ catch (err) {
62
+ this.log('query error', err);
63
+ }
64
+ finally {
65
+ this.timeoutId = setTimeout(this._querySelf.bind(this), this.interval);
66
+ timeoutController.clear();
67
+ }
68
+ }).catch(err => {
69
+ this.log('query error', err);
70
+ });
71
+ }
72
+ }
73
+ //# sourceMappingURL=query-self.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-self.js","sourceRoot":"","sources":["../../src/query-self.ts"],"names":[],"mappings":"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"}