@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
package/LICENSE ADDED
@@ -0,0 +1,4 @@
1
+ This project is dual licensed under MIT and Apache-2.0.
2
+
3
+ MIT: https://www.opensource.org/licenses/mit
4
+ Apache-2.0: https://www.apache.org/licenses/license-2.0
package/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # js-libp2p-kad-dht <!-- omit in toc -->
2
+
3
+ [![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io)
4
+ [![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/)
5
+ [![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs)
6
+ [![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io)
7
+ [![Build Status](https://github.com/libp2p/js-libp2p-kad-dht/actions/workflows/js-test-and-release.yml/badge.svg?branch=main)](https://github.com/libp2p/js-libp2p-kad-dht/actions/workflows/js-test-and-release.yml)
8
+ [![Coverage Status](https://coveralls.io/repos/github/libp2p/js-libp2p-kad-dht/badge.svg?branch=master)](https://coveralls.io/github/libp2p/js-libp2p-kad-dht?branch=master)
9
+ [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-kad-dht.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-kad-dht)
10
+ [![Bundle Size](https://flat.badgen.net/bundlephobia/minzip/libp2p-kad-dht)](https://bundlephobia.com/result?p=libp2p-kad-dht)
11
+ [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard)
12
+ [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
13
+ ![](https://img.shields.io/badge/npm-%3E%3D3.0.0-orange.svg?style=flat-square)
14
+ ![](https://img.shields.io/badge/Node.js-%3E%3D6.0.0-orange.svg?style=flat-square)
15
+
16
+ > JavaScript implementation of the Kademlia DHT for libp2p, based on [go-libp2p-kad-dht](https://github.com/libp2p/go-libp2p-kad-dht).
17
+
18
+ ## Table of Contents <!-- omit in toc -->
19
+
20
+ - [Install](#install)
21
+ - [npm](#npm)
22
+ - [Use in Node.js](#use-in-nodejs)
23
+ - [API](#api)
24
+ - [Custom secondary DHT in libp2p](#custom-secondary-dht-in-libp2p)
25
+ - [Peer Routing](#peer-routing)
26
+ - [Content Routing](#content-routing)
27
+ - [Peer Discovery](#peer-discovery)
28
+ - [Spec](#spec)
29
+ - [Contribute](#contribute)
30
+ - [License](#license)
31
+ - [Contribution](#contribution)
32
+ ## Install
33
+
34
+ ### npm
35
+
36
+ ```sh
37
+ > npm i @libp2p/kad-dht
38
+ ```
39
+
40
+ ### Use in Node.js
41
+
42
+ ```js
43
+ import { create } from '@libp2p/kad-dht'
44
+ ```
45
+
46
+ ## API
47
+
48
+ See https://libp2p.github.io/js-libp2p-kad-dht for the auto generated docs.
49
+
50
+ The libp2p-kad-dht module offers 3 APIs: Peer Routing, Content Routing and Peer Discovery.
51
+
52
+ ### Custom secondary DHT in libp2p
53
+
54
+ ```js
55
+ import { create } from '@libp2p/kad-dht'
56
+
57
+ /**
58
+ * @param {Libp2p} libp2p
59
+ */
60
+ async function addDHT(libp2p) {
61
+ const customDHT = create({
62
+ libp2p,
63
+ protocolPrefix: '/custom'
64
+ })
65
+ await customDHT.start()
66
+
67
+ return customDHT
68
+ }
69
+ ```
70
+
71
+ Note that you may want to supply your own peer discovery function and datastore
72
+ ### Peer Routing
73
+
74
+ [![](https://raw.githubusercontent.com/libp2p/js-libp2p-interfaces/master/src/peer-routing/img/badge.png)](https://github.com/libp2p/js-libp2p-interfaces/tree/master/packages/interfaces/src/peer-routing)
75
+
76
+ ### Content Routing
77
+
78
+ [![](https://raw.githubusercontent.com/libp2p/js-libp2p-interfaces/master/src/content-routing/img/badge.png)](https://github.com/libp2p/js-libp2p-interfaces/tree/master/packages/interfaces/src/content-routing)
79
+
80
+ ### Peer Discovery
81
+
82
+ [![](https://raw.githubusercontent.com/libp2p/js-libp2p-interfaces/master/src/peer-discovery/img/badge.png)](https://github.com/libp2p/js-libp2p-interfaces/tree/master/packages/interfaces/src/peer-discovery)
83
+
84
+ ## Spec
85
+
86
+ js-libp2p-kad-dht follows the [libp2p/kad-dht spec](https://github.com/libp2p/specs/tree/master/kad-dht) and implements the algorithms described in the [IPFS DHT documentation](https://docs.ipfs.io/concepts/dht/).
87
+
88
+ ## Contribute
89
+
90
+ Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/js-libp2p-ipfs/issues)!
91
+
92
+ This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
93
+
94
+ [![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md)
95
+
96
+ ## License
97
+
98
+ Licensed under either of
99
+
100
+ * Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / http://www.apache.org/licenses/LICENSE-2.0)
101
+ * MIT ([LICENSE-MIT](LICENSE-MIT) / http://opensource.org/licenses/MIT)
102
+
103
+ ### Contribution
104
+
105
+ Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
@@ -0,0 +1,20 @@
1
+ export declare const second = 1000;
2
+ export declare const minute: number;
3
+ export declare const hour: number;
4
+ export declare const MAX_RECORD_AGE: number;
5
+ export declare const PROTOCOL_DHT = "/kad/1.0.0";
6
+ export declare const RECORD_KEY_PREFIX = "/dht/record";
7
+ export declare const PROVIDER_KEY_PREFIX = "/dht/provider";
8
+ export declare const PROVIDERS_LRU_CACHE_SIZE = 256;
9
+ export declare const PROVIDERS_VALIDITY: number;
10
+ export declare const PROVIDERS_CLEANUP_INTERVAL: number;
11
+ export declare const READ_MESSAGE_TIMEOUT: number;
12
+ export declare const GET_MANY_RECORD_COUNT = 16;
13
+ export declare const K = 20;
14
+ export declare const ALPHA = 3;
15
+ export declare const QUERY_SELF_INTERVAL: number;
16
+ export declare const QUERY_SELF_TIMEOUT: number;
17
+ export declare const TABLE_REFRESH_INTERVAL: number;
18
+ export declare const TABLE_REFRESH_QUERY_TIMEOUT: number;
19
+ export declare const DEFAULT_QUERY_TIMEOUT: number;
20
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,MAAM,OAAO,CAAA;AAC1B,eAAO,MAAM,MAAM,QAAc,CAAA;AACjC,eAAO,MAAM,IAAI,QAAc,CAAA;AAE/B,eAAO,MAAM,cAAc,QAAY,CAAA;AAEvC,eAAO,MAAM,YAAY,eAAe,CAAA;AAExC,eAAO,MAAM,iBAAiB,gBAAgB,CAAA;AAE9C,eAAO,MAAM,mBAAmB,kBAAkB,CAAA;AAElD,eAAO,MAAM,wBAAwB,MAAM,CAAA;AAE3C,eAAO,MAAM,kBAAkB,QAAY,CAAA;AAE3C,eAAO,MAAM,0BAA0B,QAAO,CAAA;AAE9C,eAAO,MAAM,oBAAoB,QAAc,CAAA;AAG/C,eAAO,MAAM,qBAAqB,KAAK,CAAA;AAGvC,eAAO,MAAM,CAAC,KAAK,CAAA;AAGnB,eAAO,MAAM,KAAK,IAAI,CAAA;AAGtB,eAAO,MAAM,mBAAmB,QAAqB,CAAA;AAGrD,eAAO,MAAM,kBAAkB,QAAsB,CAAA;AAGrD,eAAO,MAAM,sBAAsB,QAAqB,CAAA;AAGxD,eAAO,MAAM,2BAA2B,QAAsB,CAAA;AAG9D,eAAO,MAAM,qBAAqB,QAAsB,CAAA"}
@@ -0,0 +1,34 @@
1
+ // MaxRecordAge specifies the maximum time that any node will hold onto a record
2
+ // from the time its received. This does not apply to any other forms of validity that
3
+ // the record may contain.
4
+ // For example, a record may contain an ipns entry with an EOL saying its valid
5
+ // until the year 2020 (a great time in the future). For that record to stick around
6
+ // it must be rebroadcasted more frequently than once every 'MaxRecordAge'
7
+ export const second = 1000;
8
+ export const minute = 60 * second;
9
+ export const hour = 60 * minute;
10
+ export const MAX_RECORD_AGE = 36 * hour;
11
+ export const PROTOCOL_DHT = '/kad/1.0.0';
12
+ export const RECORD_KEY_PREFIX = '/dht/record';
13
+ export const PROVIDER_KEY_PREFIX = '/dht/provider';
14
+ export const PROVIDERS_LRU_CACHE_SIZE = 256;
15
+ export const PROVIDERS_VALIDITY = 24 * hour;
16
+ export const PROVIDERS_CLEANUP_INTERVAL = hour;
17
+ export const READ_MESSAGE_TIMEOUT = 10 * second;
18
+ // The number of records that will be retrieved on a call to getMany()
19
+ export const GET_MANY_RECORD_COUNT = 16;
20
+ // K is the maximum number of requests to perform before returning failure
21
+ export const K = 20;
22
+ // Alpha is the concurrency for asynchronous requests
23
+ export const ALPHA = 3;
24
+ // How often we look for our closest DHT neighbours
25
+ export const QUERY_SELF_INTERVAL = Number(5 * minute);
26
+ // How long to look for our closest DHT neighbours for
27
+ export const QUERY_SELF_TIMEOUT = Number(30 * second);
28
+ // How often we try to find new peers
29
+ export const TABLE_REFRESH_INTERVAL = Number(5 * minute);
30
+ // How how long to look for new peers for
31
+ export const TABLE_REFRESH_QUERY_TIMEOUT = Number(30 * second);
32
+ // When a timeout is not specified, run a query for this long
33
+ export const DEFAULT_QUERY_TIMEOUT = Number(30 * second);
34
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,sFAAsF;AACtF,0BAA0B;AAC1B,+EAA+E;AAC/E,oFAAoF;AACpF,0EAA0E;AAE1E,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAA;AAC1B,MAAM,CAAC,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,CAAA;AACjC,MAAM,CAAC,MAAM,IAAI,GAAG,EAAE,GAAG,MAAM,CAAA;AAE/B,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,GAAG,IAAI,CAAA;AAEvC,MAAM,CAAC,MAAM,YAAY,GAAG,YAAY,CAAA;AAExC,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAA;AAE9C,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAA;AAElD,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAA;AAE3C,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,CAAA;AAE3C,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,CAAA;AAE9C,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,GAAG,MAAM,CAAA;AAE/C,sEAAsE;AACtE,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAA;AAEvC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAA;AAEnB,qDAAqD;AACrD,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAA;AAEtB,mDAAmD;AACnD,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAA;AAErD,sDAAsD;AACtD,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,CAAA;AAErD,qCAAqC;AACrC,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAA;AAExD,yCAAyC;AACzC,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,CAAA;AAE9D,6DAA6D;AAC7D,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,CAAA"}
@@ -0,0 +1,55 @@
1
+ import { Libp2pRecord } from '@libp2p/record';
2
+ import type { PeerId } from '@libp2p/interfaces/peer-id';
3
+ import type { Validators, Selectors, ValueEvent, QueryOptions } from '@libp2p/interfaces/dht';
4
+ import type { Datastore } from 'interface-datastore';
5
+ import type { PeerRouting } from '../peer-routing/index.js';
6
+ import type { QueryManager } from '../query/manager.js';
7
+ import type { RoutingTable } from '../routing-table/index.js';
8
+ import type { Network } from '../network.js';
9
+ import type { AbortOptions } from '@libp2p/interfaces';
10
+ export interface ContentFetchingOptions {
11
+ peerId: PeerId;
12
+ datastore: Datastore;
13
+ validators: Validators;
14
+ selectors: Selectors;
15
+ peerRouting: PeerRouting;
16
+ queryManager: QueryManager;
17
+ routingTable: RoutingTable;
18
+ network: Network;
19
+ lan: boolean;
20
+ }
21
+ export declare class ContentFetching {
22
+ private readonly log;
23
+ private readonly peerId;
24
+ private readonly datastore;
25
+ private readonly validators;
26
+ private readonly selectors;
27
+ private readonly peerRouting;
28
+ private readonly queryManager;
29
+ private readonly routingTable;
30
+ private readonly network;
31
+ constructor(options: ContentFetchingOptions);
32
+ putLocal(key: Uint8Array, rec: Uint8Array): Promise<void>;
33
+ /**
34
+ * Attempt to retrieve the value for the given key from
35
+ * the local datastore
36
+ */
37
+ getLocal(key: Uint8Array): Promise<Libp2pRecord>;
38
+ /**
39
+ * Send the best record found to any peers that have an out of date record
40
+ */
41
+ sendCorrectionRecord(key: Uint8Array, vals: ValueEvent[], best: Uint8Array, options?: AbortOptions): AsyncGenerator<import("@libp2p/interfaces/dht").SendingQueryEvent | import("@libp2p/interfaces/dht").PeerResponseEvent | import("@libp2p/interfaces/dht").QueryErrorEvent | import("@libp2p/interfaces/dht").DialingPeerEvent, void, unknown>;
42
+ /**
43
+ * Store the given key/value pair in the DHT
44
+ */
45
+ put(key: Uint8Array, value: Uint8Array, options?: AbortOptions): AsyncGenerator<import("@libp2p/interfaces/dht").SendingQueryEvent | import("@libp2p/interfaces/dht").PeerResponseEvent | import("@libp2p/interfaces/dht").QueryErrorEvent | import("@libp2p/interfaces/dht").ProviderEvent | ValueEvent | import("@libp2p/interfaces/dht").AddingPeerEvent | import("@libp2p/interfaces/dht").DialingPeerEvent, void, undefined>;
46
+ /**
47
+ * Get the value to the given key
48
+ */
49
+ get(key: Uint8Array, options?: QueryOptions): AsyncGenerator<import("@libp2p/interfaces/dht").QueryEvent, void, unknown>;
50
+ /**
51
+ * Get the `n` values to the given key without sorting
52
+ */
53
+ getMany(key: Uint8Array, options?: QueryOptions): AsyncGenerator<import("@libp2p/interfaces/dht").QueryEvent, void, unknown>;
54
+ }
55
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/content-fetching/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAgB7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAC7F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAE5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAGtD,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,SAAS,CAAA;IACpB,UAAU,EAAE,UAAU,CAAA;IACtB,SAAS,EAAE,SAAS,CAAA;IACpB,WAAW,EAAE,WAAW,CAAA;IACxB,YAAY,EAAE,YAAY,CAAA;IAC1B,YAAY,EAAE,YAAY,CAAA;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,EAAE,OAAO,CAAA;CACb;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAEpB,OAAO,EAAE,sBAAsB;IAatC,QAAQ,CAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU;IAKhD;;;OAGG;IACG,QAAQ,CAAE,GAAG,EAAE,UAAU;IAiB/B;;OAEG;IACK,oBAAoB,CAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,GAAE,YAAiB;IA6C/G;;OAEG;IACK,GAAG,CAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,GAAE,YAAiB;IAoD3E;;OAEG;IACK,GAAG,CAAE,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,YAAiB;IAyCxD;;OAEG;IACK,OAAO,CAAE,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,YAAiB;CAkC7D"}
@@ -0,0 +1,190 @@
1
+ import errcode from 'err-code';
2
+ import { equals as uint8ArrayEquals } from 'uint8arrays/equals';
3
+ import { Libp2pRecord } from '@libp2p/record';
4
+ import { verifyRecord } from '@libp2p/record/validators';
5
+ import { bestRecord } from '@libp2p/record/selectors';
6
+ import parallel from 'it-parallel';
7
+ import map from 'it-map';
8
+ import { valueEvent, queryErrorEvent } from '../query/events.js';
9
+ import { Message, MESSAGE_TYPE } from '../message/index.js';
10
+ import { pipe } from 'it-pipe';
11
+ import { ALPHA } from '../constants.js';
12
+ import { createPutRecord, convertBuffer, bufferToRecordKey } from '../utils.js';
13
+ import { logger } from '@libp2p/logger';
14
+ export class ContentFetching {
15
+ constructor(options) {
16
+ const { peerId, datastore, validators, selectors, peerRouting, queryManager, routingTable, network, lan } = options;
17
+ this.log = logger(`libp2p:kad-dht:${lan ? 'lan' : 'wan'}:content-fetching:${peerId.toString()}`);
18
+ this.peerId = peerId;
19
+ this.datastore = datastore;
20
+ this.validators = validators;
21
+ this.selectors = selectors;
22
+ this.peerRouting = peerRouting;
23
+ this.queryManager = queryManager;
24
+ this.routingTable = routingTable;
25
+ this.network = network;
26
+ }
27
+ async putLocal(key, rec) {
28
+ const dsKey = bufferToRecordKey(key);
29
+ await this.datastore.put(dsKey, rec);
30
+ }
31
+ /**
32
+ * Attempt to retrieve the value for the given key from
33
+ * the local datastore
34
+ */
35
+ async getLocal(key) {
36
+ this.log('getLocal %b', key);
37
+ const dsKey = bufferToRecordKey(key);
38
+ this.log('fetching record for key %k', dsKey);
39
+ const raw = await this.datastore.get(dsKey);
40
+ this.log('found %k in local datastore', dsKey);
41
+ const rec = Libp2pRecord.deserialize(raw);
42
+ await verifyRecord(this.validators, rec);
43
+ return rec;
44
+ }
45
+ /**
46
+ * Send the best record found to any peers that have an out of date record
47
+ */
48
+ async *sendCorrectionRecord(key, vals, best, options = {}) {
49
+ this.log('sendCorrection for %b', key);
50
+ const fixupRec = await createPutRecord(key, best);
51
+ for (const { value, from } of vals) {
52
+ // no need to do anything
53
+ if (uint8ArrayEquals(value, best)) {
54
+ this.log('record was ok');
55
+ continue;
56
+ }
57
+ // correct ourself
58
+ if (this.peerId.equals(from)) {
59
+ try {
60
+ const dsKey = bufferToRecordKey(key);
61
+ this.log(`Storing corrected record for key ${dsKey.toString()}`);
62
+ await this.datastore.put(dsKey, fixupRec);
63
+ }
64
+ catch (err) {
65
+ this.log.error('Failed error correcting self', err);
66
+ }
67
+ continue;
68
+ }
69
+ // send correction
70
+ let sentCorrection = false;
71
+ const request = new Message(MESSAGE_TYPE.PUT_VALUE, key, 0);
72
+ request.record = Libp2pRecord.deserialize(fixupRec);
73
+ for await (const event of this.network.sendRequest(from, request, options)) {
74
+ if (event.name === 'PEER_RESPONSE' && (event.record != null) && uint8ArrayEquals(event.record.value, Libp2pRecord.deserialize(fixupRec).value)) {
75
+ sentCorrection = true;
76
+ }
77
+ yield event;
78
+ }
79
+ if (!sentCorrection) {
80
+ yield queryErrorEvent({ from, error: errcode(new Error('value not put correctly'), 'ERR_PUT_VALUE_INVALID') });
81
+ }
82
+ this.log.error('Failed error correcting entry');
83
+ }
84
+ }
85
+ /**
86
+ * Store the given key/value pair in the DHT
87
+ */
88
+ async *put(key, value, options = {}) {
89
+ this.log('put key %b value %b', key, value);
90
+ // create record in the dht format
91
+ const record = await createPutRecord(key, value);
92
+ // store the record locally
93
+ const dsKey = bufferToRecordKey(key);
94
+ this.log(`storing record for key ${dsKey.toString()}`);
95
+ await this.datastore.put(dsKey, record);
96
+ // put record to the closest peers
97
+ yield* pipe(this.peerRouting.getClosestPeers(key, { signal: options.signal }), (source) => map(source, (event) => {
98
+ return async () => {
99
+ if (event.name !== 'FINAL_PEER') {
100
+ return [event];
101
+ }
102
+ const events = [];
103
+ const msg = new Message(MESSAGE_TYPE.PUT_VALUE, key, 0);
104
+ msg.record = Libp2pRecord.deserialize(record);
105
+ for await (const putEvent of this.network.sendRequest(event.peer.id, msg, options)) {
106
+ events.push(putEvent);
107
+ if (putEvent.name !== 'PEER_RESPONSE') {
108
+ continue;
109
+ }
110
+ if (!(putEvent.record != null && uint8ArrayEquals(putEvent.record.value, Libp2pRecord.deserialize(record).value))) {
111
+ events.push(queryErrorEvent({ from: event.peer.id, error: errcode(new Error('value not put correctly'), 'ERR_PUT_VALUE_INVALID') }));
112
+ }
113
+ }
114
+ return events;
115
+ };
116
+ }), (source) => parallel(source, {
117
+ ordered: false,
118
+ concurrency: ALPHA
119
+ }), async function* (source) {
120
+ for await (const events of source) {
121
+ yield* events;
122
+ }
123
+ });
124
+ }
125
+ /**
126
+ * Get the value to the given key
127
+ */
128
+ async *get(key, options = {}) {
129
+ this.log('get %b', key);
130
+ const vals = [];
131
+ for await (const event of this.getMany(key, options)) {
132
+ if (event.name === 'VALUE') {
133
+ vals.push(event);
134
+ }
135
+ yield event;
136
+ }
137
+ if (vals.length === 0) {
138
+ return;
139
+ }
140
+ const records = vals.map((v) => v.value);
141
+ let i = 0;
142
+ try {
143
+ i = bestRecord(this.selectors, key, records);
144
+ }
145
+ catch (err) {
146
+ // Assume the first record if no selector available
147
+ if (err.code !== 'ERR_NO_SELECTOR_FUNCTION_FOR_RECORD_KEY') {
148
+ throw err;
149
+ }
150
+ }
151
+ const best = records[i];
152
+ this.log('GetValue %b %b', key, best);
153
+ if (best == null) {
154
+ throw errcode(new Error('best value was not found'), 'ERR_NOT_FOUND');
155
+ }
156
+ yield* this.sendCorrectionRecord(key, vals, best, options);
157
+ yield vals[i];
158
+ }
159
+ /**
160
+ * Get the `n` values to the given key without sorting
161
+ */
162
+ async *getMany(key, options = {}) {
163
+ this.log('getMany values for %b', key);
164
+ try {
165
+ const localRec = await this.getLocal(key);
166
+ yield valueEvent({
167
+ value: localRec.value,
168
+ from: this.peerId
169
+ });
170
+ }
171
+ catch (err) {
172
+ this.log('error getting local value for %b', key, err);
173
+ }
174
+ const id = await convertBuffer(key);
175
+ const rtp = this.routingTable.closestPeers(id);
176
+ this.log('found %d peers in routing table', rtp.length);
177
+ const self = this; // eslint-disable-line @typescript-eslint/no-this-alias
178
+ const getValueQuery = async function* ({ peer, signal }) {
179
+ for await (const event of self.peerRouting.getValueOrPeers(peer, key, { signal })) {
180
+ yield event;
181
+ if (event.name === 'PEER_RESPONSE' && (event.record != null)) {
182
+ yield valueEvent({ from: peer, value: event.record.value });
183
+ }
184
+ }
185
+ };
186
+ // we have peers, lets send the actual query to them
187
+ yield* this.queryManager.run(key, rtp, getValueQuery, options);
188
+ }
189
+ }
190
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/content-fetching/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { PeerId } from '@libp2p/interfaces/peer-id';
2
+ import type { QueryEvent, QueryOptions } from '@libp2p/interfaces/dht';
3
+ import type { PeerRouting } from '../peer-routing/index.js';
4
+ import type { QueryManager } from '../query/manager.js';
5
+ import type { RoutingTable } from '../routing-table/index.js';
6
+ import type { Network } from '../network.js';
7
+ import type { Providers } from '../providers.js';
8
+ import type { PeerStore } from '@libp2p/interfaces/peer-store';
9
+ import type { CID } from 'multiformats/cid';
10
+ import type { AbortOptions } from '@libp2p/interfaces';
11
+ import type { Multiaddr } from '@multiformats/multiaddr';
12
+ export interface ContentRoutingOptions {
13
+ peerId: PeerId;
14
+ network: Network;
15
+ peerRouting: PeerRouting;
16
+ queryManager: QueryManager;
17
+ routingTable: RoutingTable;
18
+ providers: Providers;
19
+ peerStore: PeerStore;
20
+ lan: boolean;
21
+ }
22
+ export declare class ContentRouting {
23
+ private readonly log;
24
+ private readonly peerId;
25
+ private readonly network;
26
+ private readonly peerRouting;
27
+ private readonly queryManager;
28
+ private readonly routingTable;
29
+ private readonly providers;
30
+ private readonly peerStore;
31
+ constructor(options: ContentRoutingOptions);
32
+ /**
33
+ * Announce to the network that we can provide the value for a given key and
34
+ * are contactable on the given multiaddrs
35
+ */
36
+ provide(key: CID, multiaddrs: Multiaddr[], options?: AbortOptions): AsyncGenerator<import("@libp2p/interfaces/dht").SendingQueryEvent | import("@libp2p/interfaces/dht").PeerResponseEvent | import("@libp2p/interfaces/dht").QueryErrorEvent | import("@libp2p/interfaces/dht").ProviderEvent | import("@libp2p/interfaces/dht").ValueEvent | import("@libp2p/interfaces/dht").AddingPeerEvent | import("@libp2p/interfaces/dht").DialingPeerEvent, void, undefined>;
37
+ /**
38
+ * Search the dht for up to `K` providers of the given CID.
39
+ */
40
+ findProviders(key: CID, options: QueryOptions): AsyncGenerator<QueryEvent, void, unknown>;
41
+ }
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/content-routing/index.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAE5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AAE9D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAIxD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,WAAW,CAAA;IACxB,YAAY,EAAE,YAAY,CAAA;IAC1B,YAAY,EAAE,YAAY,CAAA;IAC1B,SAAS,EAAE,SAAS,CAAA;IACpB,SAAS,EAAE,SAAS,CAAA;IACpB,GAAG,EAAE,OAAO,CAAA;CACb;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;gBAExB,OAAO,EAAE,qBAAqB;IAa3C;;;OAGG;IACK,OAAO,CAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,OAAO,GAAE,YAAiB;IA+D9E;;OAEG;IACK,aAAa,CAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY;CAqEvD"}
@@ -0,0 +1,129 @@
1
+ import { Message, MESSAGE_TYPE } from '../message/index.js';
2
+ import parallel from 'it-parallel';
3
+ import map from 'it-map';
4
+ import { convertBuffer } from '../utils.js';
5
+ import { ALPHA } from '../constants.js';
6
+ import { pipe } from 'it-pipe';
7
+ import { queryErrorEvent, peerResponseEvent, providerEvent } from '../query/events.js';
8
+ import { logger } from '@libp2p/logger';
9
+ import { base58btc } from 'multiformats/bases/base58';
10
+ export class ContentRouting {
11
+ constructor(options) {
12
+ const { peerId, network, peerRouting, queryManager, routingTable, providers, peerStore, lan } = options;
13
+ this.log = logger(`libp2p:kad-dht:${lan ? 'lan' : 'wan'}:content-routing`);
14
+ this.peerId = peerId;
15
+ this.network = network;
16
+ this.peerRouting = peerRouting;
17
+ this.queryManager = queryManager;
18
+ this.routingTable = routingTable;
19
+ this.providers = providers;
20
+ this.peerStore = peerStore;
21
+ }
22
+ /**
23
+ * Announce to the network that we can provide the value for a given key and
24
+ * are contactable on the given multiaddrs
25
+ */
26
+ async *provide(key, multiaddrs, options = {}) {
27
+ this.log('provide %s', key);
28
+ // Add peer as provider
29
+ await this.providers.addProvider(key, this.peerId);
30
+ const msg = new Message(MESSAGE_TYPE.ADD_PROVIDER, key.bytes, 0);
31
+ msg.providerPeers = [{
32
+ id: this.peerId,
33
+ multiaddrs,
34
+ protocols: []
35
+ }];
36
+ let sent = 0;
37
+ const maybeNotifyPeer = (event) => {
38
+ return async () => {
39
+ if (event.name !== 'FINAL_PEER') {
40
+ return [event];
41
+ }
42
+ const events = [];
43
+ this.log('putProvider %s to %p', key, event.peer.id);
44
+ try {
45
+ this.log('sending provider record for %s to %p', key, event.peer.id);
46
+ for await (const sendEvent of this.network.sendMessage(event.peer.id, msg, options)) {
47
+ if (sendEvent.name === 'PEER_RESPONSE') {
48
+ this.log('sent provider record for %s to %p', key, event.peer.id);
49
+ sent++;
50
+ }
51
+ events.push(sendEvent);
52
+ }
53
+ }
54
+ catch (err) {
55
+ this.log.error('error sending provide record to peer %p', event.peer.id, err);
56
+ events.push(queryErrorEvent({ from: event.peer.id, error: err }));
57
+ }
58
+ return events;
59
+ };
60
+ };
61
+ // Notify closest peers
62
+ yield* pipe(this.peerRouting.getClosestPeers(key.multihash.bytes, options), (source) => map(source, (event) => maybeNotifyPeer(event)), (source) => parallel(source, {
63
+ ordered: false,
64
+ concurrency: ALPHA
65
+ }), async function* (source) {
66
+ for await (const events of source) {
67
+ yield* events;
68
+ }
69
+ });
70
+ this.log('sent provider records to %d peers', sent);
71
+ }
72
+ /**
73
+ * Search the dht for up to `K` providers of the given CID.
74
+ */
75
+ async *findProviders(key, options) {
76
+ const toFind = this.routingTable.kBucketSize;
77
+ const target = key.multihash.bytes;
78
+ const id = await convertBuffer(target);
79
+ const self = this; // eslint-disable-line @typescript-eslint/no-this-alias
80
+ this.log('findProviders %c', key);
81
+ const provs = await this.providers.getProviders(key);
82
+ // yield values if we have some, also slice because maybe we got lucky and already have too many?
83
+ if (provs.length > 0) {
84
+ const providers = [];
85
+ for (const peerId of provs.slice(0, toFind)) {
86
+ providers.push({
87
+ id: peerId,
88
+ multiaddrs: ((await this.peerStore.addressBook.get(peerId)) ?? []).map(address => address.multiaddr),
89
+ protocols: []
90
+ });
91
+ }
92
+ yield peerResponseEvent({ from: this.peerId, messageType: MESSAGE_TYPE.GET_PROVIDERS, providers });
93
+ yield providerEvent({ from: this.peerId, providers: providers });
94
+ }
95
+ // All done
96
+ if (provs.length >= toFind) {
97
+ return;
98
+ }
99
+ /**
100
+ * The query function to use on this particular disjoint path
101
+ */
102
+ const findProvidersQuery = async function* ({ peer, signal }) {
103
+ const request = new Message(MESSAGE_TYPE.GET_PROVIDERS, target, 0);
104
+ yield* self.network.sendRequest(peer, request, { signal });
105
+ };
106
+ const providers = new Set(provs.map(p => p.toString(base58btc)));
107
+ for await (const event of this.queryManager.run(target, this.routingTable.closestPeers(id), findProvidersQuery, options)) {
108
+ yield event;
109
+ if (event.name === 'PEER_RESPONSE') {
110
+ this.log('Found %d provider entries for %c and %d closer peers', event.providers.length, key, event.closer.length);
111
+ const newProviders = [];
112
+ for (const peer of event.providers) {
113
+ if (providers.has(peer.id.toString(base58btc))) {
114
+ continue;
115
+ }
116
+ providers.add(peer.id.toString(base58btc));
117
+ newProviders.push(peer);
118
+ }
119
+ if (newProviders.length > 0) {
120
+ yield providerEvent({ from: event.from, providers: newProviders });
121
+ }
122
+ if (providers.size === toFind) {
123
+ return;
124
+ }
125
+ }
126
+ }
127
+ }
128
+ }
129
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/content-routing/index.ts"],"names":[],"mappings":"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"}