@streamr/dht 100.0.0-testnet-one.4 → 100.0.0-testnet-two.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.
Files changed (307) hide show
  1. package/dist/src/connection/ConnectionLockHandler.d.ts +11 -11
  2. package/dist/src/connection/ConnectionLockHandler.js.map +1 -1
  3. package/dist/src/connection/ConnectionLockRpcLocal.d.ts +3 -3
  4. package/dist/src/connection/ConnectionLockRpcLocal.js +4 -4
  5. package/dist/src/connection/ConnectionLockRpcLocal.js.map +1 -1
  6. package/dist/src/connection/ConnectionLockRpcRemote.d.ts +3 -5
  7. package/dist/src/connection/ConnectionLockRpcRemote.js +4 -7
  8. package/dist/src/connection/ConnectionLockRpcRemote.js.map +1 -1
  9. package/dist/src/connection/ConnectionManager.d.ts +4 -6
  10. package/dist/src/connection/ConnectionManager.js +48 -46
  11. package/dist/src/connection/ConnectionManager.js.map +1 -1
  12. package/dist/src/connection/ConnectorFacade.d.ts +2 -2
  13. package/dist/src/connection/ConnectorFacade.js +2 -1
  14. package/dist/src/connection/ConnectorFacade.js.map +1 -1
  15. package/dist/src/connection/ManagedConnection.d.ts +3 -6
  16. package/dist/src/connection/ManagedConnection.js +6 -10
  17. package/dist/src/connection/ManagedConnection.js.map +1 -1
  18. package/dist/src/connection/connectivityChecker.js +1 -0
  19. package/dist/src/connection/connectivityChecker.js.map +1 -1
  20. package/dist/src/connection/simulator/Simulator.d.ts +0 -3
  21. package/dist/src/connection/simulator/Simulator.js +3 -51
  22. package/dist/src/connection/simulator/Simulator.js.map +1 -1
  23. package/dist/src/connection/simulator/SimulatorConnector.js +5 -5
  24. package/dist/src/connection/simulator/SimulatorConnector.js.map +1 -1
  25. package/dist/src/connection/webrtc/NodeWebrtcConnection.js +2 -2
  26. package/dist/src/connection/webrtc/NodeWebrtcConnection.js.map +1 -1
  27. package/dist/src/connection/webrtc/WebrtcConnector.d.ts +0 -1
  28. package/dist/src/connection/webrtc/WebrtcConnector.js +7 -9
  29. package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
  30. package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.d.ts +2 -2
  31. package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js +11 -12
  32. package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js.map +1 -1
  33. package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.d.ts +2 -5
  34. package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.js +1 -4
  35. package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.js.map +1 -1
  36. package/dist/src/connection/websocket/AutoCertifierClientFacade.d.ts +1 -2
  37. package/dist/src/connection/websocket/AutoCertifierClientFacade.js +3 -4
  38. package/dist/src/connection/websocket/AutoCertifierClientFacade.js.map +1 -1
  39. package/dist/src/connection/websocket/ClientWebsocket.js.map +1 -1
  40. package/dist/src/connection/websocket/WebsocketConnector.d.ts +2 -7
  41. package/dist/src/connection/websocket/WebsocketConnector.js +32 -38
  42. package/dist/src/connection/websocket/WebsocketConnector.js.map +1 -1
  43. package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.d.ts +3 -2
  44. package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.js +8 -10
  45. package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.js.map +1 -1
  46. package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.d.ts +3 -6
  47. package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.js +0 -3
  48. package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.js.map +1 -1
  49. package/dist/src/connection/websocket/WebsocketServer.d.ts +1 -4
  50. package/dist/src/connection/websocket/WebsocketServer.js +11 -12
  51. package/dist/src/connection/websocket/WebsocketServer.js.map +1 -1
  52. package/dist/src/dht/DhtNode.d.ts +10 -13
  53. package/dist/src/dht/DhtNode.js +39 -52
  54. package/dist/src/dht/DhtNode.js.map +1 -1
  55. package/dist/src/dht/DhtNodeRpcLocal.d.ts +0 -1
  56. package/dist/src/dht/DhtNodeRpcLocal.js.map +1 -1
  57. package/dist/src/dht/DhtNodeRpcRemote.d.ts +7 -7
  58. package/dist/src/dht/DhtNodeRpcRemote.js +8 -7
  59. package/dist/src/dht/DhtNodeRpcRemote.js.map +1 -1
  60. package/dist/src/dht/ExternalApiRpcLocal.d.ts +5 -4
  61. package/dist/src/dht/ExternalApiRpcLocal.js +3 -2
  62. package/dist/src/dht/ExternalApiRpcLocal.js.map +1 -1
  63. package/dist/src/dht/ExternalApiRpcRemote.d.ts +2 -2
  64. package/dist/src/dht/ExternalApiRpcRemote.js +2 -0
  65. package/dist/src/dht/ExternalApiRpcRemote.js.map +1 -1
  66. package/dist/src/dht/PeerManager.d.ts +13 -14
  67. package/dist/src/dht/PeerManager.js +45 -60
  68. package/dist/src/dht/PeerManager.js.map +1 -1
  69. package/dist/src/dht/contact/Contact.d.ts +2 -2
  70. package/dist/src/dht/contact/Contact.js +2 -2
  71. package/dist/src/dht/contact/Contact.js.map +1 -1
  72. package/dist/src/dht/contact/ContactList.d.ts +7 -7
  73. package/dist/src/dht/contact/ContactList.js +3 -3
  74. package/dist/src/dht/contact/ContactList.js.map +1 -1
  75. package/dist/src/dht/contact/RandomContactList.d.ts +4 -4
  76. package/dist/src/dht/contact/RandomContactList.js +12 -11
  77. package/dist/src/dht/contact/RandomContactList.js.map +1 -1
  78. package/dist/src/dht/contact/RpcRemote.d.ts +7 -4
  79. package/dist/src/dht/contact/RpcRemote.js +5 -2
  80. package/dist/src/dht/contact/RpcRemote.js.map +1 -1
  81. package/dist/src/dht/contact/SortedContactList.d.ts +13 -13
  82. package/dist/src/dht/contact/SortedContactList.js +33 -29
  83. package/dist/src/dht/contact/SortedContactList.js.map +1 -1
  84. package/dist/src/dht/discovery/DiscoverySession.d.ts +2 -4
  85. package/dist/src/dht/discovery/DiscoverySession.js +19 -20
  86. package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
  87. package/dist/src/dht/discovery/PeerDiscovery.d.ts +2 -5
  88. package/dist/src/dht/discovery/PeerDiscovery.js +12 -20
  89. package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
  90. package/dist/src/dht/recursive-operation/RecursiveOperationManager.d.ts +36 -0
  91. package/dist/src/dht/recursive-operation/RecursiveOperationManager.js +165 -0
  92. package/dist/src/dht/recursive-operation/RecursiveOperationManager.js.map +1 -0
  93. package/dist/src/dht/recursive-operation/RecursiveOperationRpcLocal.d.ts +14 -0
  94. package/dist/src/dht/{find/FindRpcLocal.js → recursive-operation/RecursiveOperationRpcLocal.js} +7 -7
  95. package/dist/src/dht/recursive-operation/RecursiveOperationRpcLocal.js.map +1 -0
  96. package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.d.ts +6 -0
  97. package/dist/src/dht/{routing/FindRpcRemote.js → recursive-operation/RecursiveOperationRpcRemote.js} +11 -11
  98. package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.js.map +1 -0
  99. package/dist/src/dht/recursive-operation/RecursiveOperationSession.d.ts +42 -0
  100. package/dist/src/dht/recursive-operation/RecursiveOperationSession.js +182 -0
  101. package/dist/src/dht/recursive-operation/RecursiveOperationSession.js.map +1 -0
  102. package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.d.ts +12 -0
  103. package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.js +17 -0
  104. package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.js.map +1 -0
  105. package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.d.ts +6 -0
  106. package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.js +21 -0
  107. package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.js.map +1 -0
  108. package/dist/src/dht/routing/Router.d.ts +4 -19
  109. package/dist/src/dht/routing/Router.js +41 -33
  110. package/dist/src/dht/routing/Router.js.map +1 -1
  111. package/dist/src/dht/routing/RouterRpcLocal.js +6 -5
  112. package/dist/src/dht/routing/RouterRpcLocal.js.map +1 -1
  113. package/dist/src/dht/routing/RouterRpcRemote.d.ts +2 -2
  114. package/dist/src/dht/routing/RouterRpcRemote.js +7 -7
  115. package/dist/src/dht/routing/RouterRpcRemote.js.map +1 -1
  116. package/dist/src/dht/routing/RoutingSession.d.ts +20 -16
  117. package/dist/src/dht/routing/RoutingSession.js +37 -45
  118. package/dist/src/dht/routing/RoutingSession.js.map +1 -1
  119. package/dist/src/dht/store/LocalDataStore.d.ts +11 -13
  120. package/dist/src/dht/store/LocalDataStore.js +36 -56
  121. package/dist/src/dht/store/LocalDataStore.js.map +1 -1
  122. package/dist/src/dht/store/StoreManager.d.ts +33 -0
  123. package/dist/src/dht/store/StoreManager.js +186 -0
  124. package/dist/src/dht/store/StoreManager.js.map +1 -0
  125. package/dist/src/dht/store/StoreRpcLocal.d.ts +8 -40
  126. package/dist/src/dht/store/StoreRpcLocal.js +13 -229
  127. package/dist/src/dht/store/StoreRpcLocal.js.map +1 -1
  128. package/dist/src/dht/store/StoreRpcRemote.d.ts +5 -5
  129. package/dist/src/dht/store/StoreRpcRemote.js +4 -5
  130. package/dist/src/dht/store/StoreRpcRemote.js.map +1 -1
  131. package/dist/src/exports.d.ts +2 -0
  132. package/dist/src/exports.js.map +1 -1
  133. package/dist/src/helpers/MapWithTtl.d.ts +14 -0
  134. package/dist/src/helpers/MapWithTtl.js +59 -0
  135. package/dist/src/helpers/MapWithTtl.js.map +1 -0
  136. package/dist/src/helpers/PeerID.d.ts +2 -0
  137. package/dist/src/helpers/PeerID.js +4 -0
  138. package/dist/src/helpers/PeerID.js.map +1 -1
  139. package/dist/src/helpers/nodeId.d.ts +5 -0
  140. package/dist/src/helpers/nodeId.js +18 -1
  141. package/dist/src/helpers/nodeId.js.map +1 -1
  142. package/dist/src/helpers/peerIdFromPeerDescriptor.d.ts +2 -1
  143. package/dist/src/helpers/peerIdFromPeerDescriptor.js +2 -1
  144. package/dist/src/helpers/peerIdFromPeerDescriptor.js.map +1 -1
  145. package/dist/src/helpers/protoClasses.js +2 -3
  146. package/dist/src/helpers/protoClasses.js.map +1 -1
  147. package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +21 -22
  148. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +18 -18
  149. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
  150. package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +36 -60
  151. package/dist/src/proto/packages/dht/protos/DhtRpc.js +34 -53
  152. package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
  153. package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +11 -12
  154. package/dist/src/rpc-protocol/DhtCallContext.d.ts +2 -1
  155. package/dist/src/rpc-protocol/DhtCallContext.js.map +1 -1
  156. package/dist/src/rpc-protocol/DhtRpcOptions.d.ts +2 -1
  157. package/dist/src/transport/ITransport.d.ts +9 -1
  158. package/dist/src/transport/ITransport.js +5 -0
  159. package/dist/src/transport/ITransport.js.map +1 -1
  160. package/dist/src/transport/ListeningRpcCommunicator.js +1 -1
  161. package/dist/src/transport/ListeningRpcCommunicator.js.map +1 -1
  162. package/dist/src/transport/RoutingRpcCommunicator.d.ts +2 -1
  163. package/dist/src/transport/RoutingRpcCommunicator.js +16 -11
  164. package/dist/src/transport/RoutingRpcCommunicator.js.map +1 -1
  165. package/jest.config.js +4 -1
  166. package/karma-setup.js +2 -0
  167. package/karma.config.js +11 -7
  168. package/package.json +6 -7
  169. package/protos/DhtRpc.proto +17 -23
  170. package/src/connection/ConnectionLockHandler.ts +15 -15
  171. package/src/connection/ConnectionLockRpcLocal.ts +8 -9
  172. package/src/connection/ConnectionLockRpcRemote.ts +7 -16
  173. package/src/connection/ConnectionManager.ts +58 -55
  174. package/src/connection/ConnectorFacade.ts +3 -0
  175. package/src/connection/ManagedConnection.ts +12 -30
  176. package/src/connection/connectivityChecker.ts +1 -0
  177. package/src/connection/simulator/Simulator.ts +5 -36
  178. package/src/connection/simulator/SimulatorConnector.ts +8 -8
  179. package/src/connection/webrtc/BrowserWebrtcConnection.ts +0 -3
  180. package/src/connection/webrtc/NodeWebrtcConnection.ts +3 -4
  181. package/src/connection/webrtc/WebrtcConnector.ts +11 -13
  182. package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +16 -16
  183. package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +3 -13
  184. package/src/connection/websocket/AutoCertifierClientFacade.ts +4 -6
  185. package/src/connection/websocket/ClientWebsocket.ts +1 -0
  186. package/src/connection/websocket/WebsocketConnector.ts +43 -56
  187. package/src/connection/websocket/WebsocketConnectorRpcLocal.ts +11 -13
  188. package/src/connection/websocket/WebsocketConnectorRpcRemote.ts +4 -15
  189. package/src/connection/websocket/WebsocketServer.ts +14 -17
  190. package/src/dht/DhtNode.ts +67 -69
  191. package/src/dht/DhtNodeRpcLocal.ts +0 -1
  192. package/src/dht/DhtNodeRpcRemote.ts +13 -13
  193. package/src/dht/ExternalApiRpcLocal.ts +16 -6
  194. package/src/dht/ExternalApiRpcRemote.ts +5 -3
  195. package/src/dht/PeerManager.ts +73 -90
  196. package/src/dht/contact/Contact.ts +5 -4
  197. package/src/dht/contact/ContactList.ts +9 -9
  198. package/src/dht/contact/RandomContactList.ts +14 -14
  199. package/src/dht/contact/RpcRemote.ts +10 -7
  200. package/src/dht/contact/SortedContactList.ts +48 -45
  201. package/src/dht/discovery/DiscoverySession.ts +25 -25
  202. package/src/dht/discovery/PeerDiscovery.ts +16 -37
  203. package/src/dht/recursive-operation/RecursiveOperationManager.ts +240 -0
  204. package/src/dht/{find/FindRpcLocal.ts → recursive-operation/RecursiveOperationRpcLocal.ts} +9 -9
  205. package/src/dht/{routing/FindRpcRemote.ts → recursive-operation/RecursiveOperationRpcRemote.ts} +10 -10
  206. package/src/dht/recursive-operation/RecursiveOperationSession.ts +224 -0
  207. package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +25 -0
  208. package/src/dht/{find/FindSessionRpcRemote.ts → recursive-operation/RecursiveOperationSessionRpcRemote.ts} +8 -8
  209. package/src/dht/routing/Router.ts +45 -64
  210. package/src/dht/routing/RouterRpcLocal.ts +7 -6
  211. package/src/dht/routing/RouterRpcRemote.ts +9 -10
  212. package/src/dht/routing/RoutingSession.ts +59 -68
  213. package/src/dht/store/LocalDataStore.ts +47 -66
  214. package/src/dht/store/StoreManager.ts +217 -0
  215. package/src/dht/store/StoreRpcLocal.ts +26 -302
  216. package/src/dht/store/StoreRpcRemote.ts +9 -11
  217. package/src/exports.ts +2 -0
  218. package/src/helpers/MapWithTtl.ts +71 -0
  219. package/src/helpers/PeerID.ts +5 -0
  220. package/src/helpers/nodeId.ts +20 -0
  221. package/src/helpers/peerIdFromPeerDescriptor.ts +5 -3
  222. package/src/helpers/protoClasses.ts +4 -6
  223. package/src/proto/packages/dht/protos/DhtRpc.client.ts +31 -32
  224. package/src/proto/packages/dht/protos/DhtRpc.server.ts +11 -12
  225. package/src/proto/packages/dht/protos/DhtRpc.ts +49 -80
  226. package/src/rpc-protocol/DhtCallContext.ts +2 -1
  227. package/src/rpc-protocol/DhtRpcOptions.ts +2 -1
  228. package/src/transport/ITransport.ts +10 -1
  229. package/src/transport/ListeningRpcCommunicator.ts +1 -1
  230. package/src/transport/RoutingRpcCommunicator.ts +18 -12
  231. package/test/benchmark/Find.test.ts +8 -21
  232. package/test/benchmark/KademliaCorrectness.test.ts +11 -20
  233. package/test/benchmark/SortedContactListBenchmark.test.ts +9 -9
  234. package/test/benchmark/kademlia-simulation/Contact.ts +9 -8
  235. package/test/benchmark/kademlia-simulation/KademliaSimulation.ts +2 -2
  236. package/test/benchmark/kademlia-simulation/SimulationNode.ts +17 -17
  237. package/test/end-to-end/Layer0-Layer1.test.ts +10 -14
  238. package/test/end-to-end/Layer0.test.ts +15 -18
  239. package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +7 -9
  240. package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +4 -10
  241. package/test/end-to-end/Layer0Webrtc.test.ts +5 -6
  242. package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +8 -16
  243. package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +6 -13
  244. package/test/end-to-end/WebsocketConnectionRequest.test.ts +5 -6
  245. package/test/end-to-end/memory-leak.test.ts +6 -8
  246. package/test/integration/ConnectionLocking.test.ts +6 -13
  247. package/test/integration/ConnectionManager.test.ts +26 -43
  248. package/test/integration/DhtJoinPeerDiscovery.test.ts +5 -10
  249. package/test/integration/DhtNodeExternalAPI.test.ts +16 -22
  250. package/test/integration/DhtNodeRpcRemote.test.ts +13 -22
  251. package/test/integration/DhtRpc.test.ts +13 -18
  252. package/test/integration/Find.test.ts +10 -10
  253. package/test/integration/Layer1-scale.test.ts +17 -28
  254. package/test/integration/Mock-Layer1-Layer0.test.ts +25 -43
  255. package/test/integration/MultipleEntryPointJoining.test.ts +7 -7
  256. package/test/integration/ReplicateData.test.ts +28 -30
  257. package/test/integration/RouteMessage.test.ts +30 -27
  258. package/test/integration/RouterRpcRemote.test.ts +12 -18
  259. package/test/integration/RpcErrors.test.ts +8 -21
  260. package/test/integration/ScaleDownDht.test.ts +11 -10
  261. package/test/integration/SimultaneousConnections.test.ts +43 -67
  262. package/test/integration/Store.test.ts +23 -36
  263. package/test/integration/StoreAndDelete.test.ts +30 -50
  264. package/test/integration/StoreOnDhtWithTwoNodes.test.ts +16 -37
  265. package/test/integration/StoreRpcRemote.test.ts +20 -30
  266. package/test/integration/WebrtcConnectionManagement.test.ts +3 -13
  267. package/test/integration/WebrtcConnectorRpc.test.ts +3 -9
  268. package/test/integration/WebsocketConnectionManagement.test.ts +7 -10
  269. package/test/integration/WebsocketConnectorRpc.test.ts +8 -17
  270. package/test/unit/ConnectivityHelpers.test.ts +9 -17
  271. package/test/unit/DuplicateDetector.test.ts +7 -4
  272. package/test/unit/LocalDataStore.test.ts +66 -77
  273. package/test/unit/PeerManager.test.ts +31 -0
  274. package/test/unit/RandomContactList.test.ts +13 -8
  275. package/test/unit/{Finder.test.ts → RecursiveOperationManager.test.ts} +38 -43
  276. package/test/unit/RecursiveOperationSession.test.ts +68 -0
  277. package/test/unit/Router.test.ts +15 -22
  278. package/test/unit/RoutingSession.test.ts +23 -25
  279. package/test/unit/SortedContactList.test.ts +41 -26
  280. package/test/unit/StoreManager.test.ts +132 -0
  281. package/test/unit/WebsocketConnector.test.ts +27 -35
  282. package/test/unit/customMatchers.test.ts +16 -0
  283. package/test/utils/FakeTransport.ts +44 -0
  284. package/test/utils/customMatchers.ts +70 -0
  285. package/test/utils/mock/MockRpcCommunicator.ts +7 -0
  286. package/test/utils/mock/Router.ts +3 -2
  287. package/test/utils/mock/mockDataEntry.ts +36 -0
  288. package/test/utils/utils.ts +49 -87
  289. package/dist/src/dht/find/FindRpcLocal.d.ts +0 -14
  290. package/dist/src/dht/find/FindRpcLocal.js.map +0 -1
  291. package/dist/src/dht/find/FindSession.d.ts +0 -44
  292. package/dist/src/dht/find/FindSession.js +0 -150
  293. package/dist/src/dht/find/FindSession.js.map +0 -1
  294. package/dist/src/dht/find/FindSessionRpcLocal.d.ts +0 -12
  295. package/dist/src/dht/find/FindSessionRpcLocal.js +0 -17
  296. package/dist/src/dht/find/FindSessionRpcLocal.js.map +0 -1
  297. package/dist/src/dht/find/FindSessionRpcRemote.d.ts +0 -6
  298. package/dist/src/dht/find/FindSessionRpcRemote.js +0 -21
  299. package/dist/src/dht/find/FindSessionRpcRemote.js.map +0 -1
  300. package/dist/src/dht/find/Finder.d.ts +0 -49
  301. package/dist/src/dht/find/Finder.js +0 -197
  302. package/dist/src/dht/find/Finder.js.map +0 -1
  303. package/dist/src/dht/routing/FindRpcRemote.d.ts +0 -6
  304. package/dist/src/dht/routing/FindRpcRemote.js.map +0 -1
  305. package/src/dht/find/FindSession.ts +0 -183
  306. package/src/dht/find/FindSessionRpcLocal.ts +0 -25
  307. package/src/dht/find/Finder.ts +0 -295
@@ -0,0 +1,240 @@
1
+ import {
2
+ DataEntry,
3
+ PeerDescriptor,
4
+ RecursiveOperation,
5
+ RecursiveOperationRequest,
6
+ RouteMessageAck,
7
+ RouteMessageError,
8
+ RouteMessageWrapper
9
+ } from '../../proto/packages/dht/protos/DhtRpc'
10
+ import { Router } from '../routing/Router'
11
+ import { RoutingMode } from '../routing/RoutingSession'
12
+ import { areEqualPeerDescriptors, getNodeIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
13
+ import { Logger, areEqualBinaries, hexToBinary, runAndWaitForEvents3, wait } from '@streamr/utils'
14
+ import { RoutingRpcCommunicator } from '../../transport/RoutingRpcCommunicator'
15
+ import { RecursiveOperationSessionRpcRemote } from './RecursiveOperationSessionRpcRemote'
16
+ import { RecursiveOperationSession, RecursiveOperationSessionEvents } from './RecursiveOperationSession'
17
+ import { DhtNodeRpcRemote } from '../DhtNodeRpcRemote'
18
+ import { ITransport } from '../../transport/ITransport'
19
+ import { LocalDataStore } from '../store/LocalDataStore'
20
+ import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator'
21
+ import { RecursiveOperationSessionRpcClient } from '../../proto/packages/dht/protos/DhtRpc.client'
22
+ import { SortedContactList } from '../contact/SortedContactList'
23
+ import { getPreviousPeer } from '../routing/getPreviousPeer'
24
+ import { createRouteMessageAck } from '../routing/RouterRpcLocal'
25
+ import { ServiceID } from '../../types/ServiceID'
26
+ import { RecursiveOperationRpcLocal } from './RecursiveOperationRpcLocal'
27
+ import { NodeID, getNodeIdFromBinary } from '../../helpers/nodeId'
28
+ import { getDistance } from '../PeerManager'
29
+
30
+ interface RecursiveOperationManagerConfig {
31
+ rpcCommunicator: RoutingRpcCommunicator
32
+ sessionTransport: ITransport
33
+ connections: Map<NodeID, DhtNodeRpcRemote>
34
+ router: Router
35
+ localPeerDescriptor: PeerDescriptor
36
+ serviceId: ServiceID
37
+ localDataStore: LocalDataStore
38
+ addContact: (contact: PeerDescriptor) => void
39
+ }
40
+
41
+ export interface RecursiveOperationResult { closestNodes: Array<PeerDescriptor>, dataEntries?: Array<DataEntry> }
42
+
43
+ const logger = new Logger(module)
44
+
45
+ export class RecursiveOperationManager {
46
+
47
+ private ongoingSessions: Map<string, RecursiveOperationSession> = new Map()
48
+ private stopped = false
49
+ private readonly config: RecursiveOperationManagerConfig
50
+
51
+ constructor(config: RecursiveOperationManagerConfig) {
52
+ this.config = config
53
+ this.registerLocalRpcMethods()
54
+ }
55
+
56
+ private registerLocalRpcMethods() {
57
+ const rpcLocal = new RecursiveOperationRpcLocal({
58
+ doRouteRequest: (routedMessage: RouteMessageWrapper) => this.doRouteRequest(routedMessage),
59
+ addContact: (contact: PeerDescriptor) => this.config.addContact(contact),
60
+ isMostLikelyDuplicate: (requestId: string) => this.config.router.isMostLikelyDuplicate(requestId),
61
+ addToDuplicateDetector: (requestId: string) => this.config.router.addToDuplicateDetector(requestId)
62
+ })
63
+ this.config.rpcCommunicator.registerRpcMethod(
64
+ RouteMessageWrapper,
65
+ RouteMessageAck,
66
+ 'routeRequest',
67
+ async (routedMessage: RouteMessageWrapper) => {
68
+ if (this.stopped) {
69
+ return createRouteMessageAck(routedMessage, RouteMessageError.STOPPED)
70
+ } else {
71
+ return rpcLocal.routeRequest(routedMessage)
72
+ }
73
+ }
74
+ )
75
+ }
76
+
77
+ public async execute(
78
+ targetId: Uint8Array,
79
+ operation: RecursiveOperation,
80
+ excludedPeer?: PeerDescriptor,
81
+ waitForCompletion = true
82
+ ): Promise<RecursiveOperationResult> {
83
+ if (this.stopped) {
84
+ return { closestNodes: [] }
85
+ }
86
+ const session = new RecursiveOperationSession({
87
+ transport: this.config.sessionTransport,
88
+ targetId,
89
+ localPeerDescriptor: this.config.localPeerDescriptor,
90
+ // TODO use config option or named constant?
91
+ waitedRoutingPathCompletions: this.config.connections.size > 1 ? 2 : 1,
92
+ operation,
93
+ // TODO would it make sense to give excludedPeer as one of the fields RecursiveOperationSession?
94
+ doRouteRequest: (routedMessage: RouteMessageWrapper) => {
95
+ return this.doRouteRequest(routedMessage, excludedPeer)
96
+ }
97
+ })
98
+ if (this.config.connections.size === 0) {
99
+ const data = this.config.localDataStore.getEntries(targetId)
100
+ session.onResponseReceived(
101
+ [this.config.localPeerDescriptor],
102
+ [this.config.localPeerDescriptor],
103
+ Array.from(data.values()),
104
+ true
105
+ )
106
+ return session.getResults()
107
+ }
108
+ this.ongoingSessions.set(session.getId(), session)
109
+ if (waitForCompletion === true) {
110
+ try {
111
+ await runAndWaitForEvents3<RecursiveOperationSessionEvents>(
112
+ [() => session.start(this.config.serviceId)],
113
+ [[session, 'completed']],
114
+ // TODO use config option or named constant?
115
+ 15000
116
+ )
117
+ } catch (err) {
118
+ logger.debug(`start failed with error ${err}`)
119
+ }
120
+ } else {
121
+ session.start(this.config.serviceId)
122
+ // Wait for delete operation to be sent out by the router
123
+ // TODO: Add a feature to wait for the router to pass the message?
124
+ await wait(50)
125
+ }
126
+ if (operation === RecursiveOperation.FETCH_DATA) {
127
+ const dataEntries = Array.from(this.config.localDataStore.getEntries(targetId).values())
128
+ if (dataEntries.length > 0) {
129
+ this.sendResponse([], this.config.localPeerDescriptor, session.getId(), [], dataEntries, true)
130
+ }
131
+ } else if (operation === RecursiveOperation.DELETE_DATA) {
132
+ this.config.localDataStore.markAsDeleted(targetId, getNodeIdFromPeerDescriptor(this.config.localPeerDescriptor))
133
+ }
134
+ this.ongoingSessions.delete(session.getId())
135
+ session.stop()
136
+ return session.getResults()
137
+ }
138
+
139
+ private sendResponse(
140
+ routingPath: PeerDescriptor[],
141
+ targetPeerDescriptor: PeerDescriptor,
142
+ serviceId: ServiceID,
143
+ closestNodes: PeerDescriptor[],
144
+ dataEntries: DataEntry[],
145
+ noCloserNodesFound: boolean = false
146
+ ): void {
147
+ const isOwnNode = areEqualPeerDescriptors(this.config.localPeerDescriptor, targetPeerDescriptor)
148
+ if (isOwnNode && this.ongoingSessions.has(serviceId)) {
149
+ this.ongoingSessions.get(serviceId)!
150
+ .onResponseReceived(routingPath, closestNodes, dataEntries, noCloserNodesFound)
151
+ } else {
152
+ // TODO use config option or named constant?
153
+ const remoteCommunicator = new ListeningRpcCommunicator(serviceId, this.config.sessionTransport, { rpcRequestTimeout: 15000 })
154
+ const rpcRemote = new RecursiveOperationSessionRpcRemote(
155
+ this.config.localPeerDescriptor,
156
+ targetPeerDescriptor,
157
+ serviceId,
158
+ remoteCommunicator,
159
+ RecursiveOperationSessionRpcClient,
160
+ // TODO use config option or named constant?
161
+ 10000
162
+ )
163
+ rpcRemote.sendResponse(routingPath, closestNodes, dataEntries, noCloserNodesFound)
164
+ remoteCommunicator.destroy()
165
+ }
166
+ }
167
+
168
+ private doRouteRequest(routedMessage: RouteMessageWrapper, excludedPeer?: PeerDescriptor): RouteMessageAck {
169
+ if (this.stopped) {
170
+ return createRouteMessageAck(routedMessage, RouteMessageError.STOPPED)
171
+ }
172
+ const targetId = getNodeIdFromBinary(routedMessage.target)
173
+ const request = (routedMessage.message!.body as { recursiveOperationRequest: RecursiveOperationRequest }).recursiveOperationRequest
174
+ // TODO use config option or named constant?
175
+ const closestPeersToDestination = this.getClosestConnections(routedMessage.target, 5)
176
+ const dataEntries = (request.operation === RecursiveOperation.FETCH_DATA)
177
+ ? Array.from(this.config.localDataStore.getEntries(hexToBinary(targetId)).values())
178
+ : []
179
+ if (request.operation === RecursiveOperation.DELETE_DATA) {
180
+ this.config.localDataStore.markAsDeleted(hexToBinary(targetId), getNodeIdFromPeerDescriptor(routedMessage.sourcePeer!))
181
+ }
182
+ if (areEqualBinaries(this.config.localPeerDescriptor.nodeId, routedMessage.target)) {
183
+ // TODO this is also very similar case to what we do at line 255, could simplify the code paths?
184
+ this.sendResponse(
185
+ routedMessage.routingPath,
186
+ routedMessage.sourcePeer!,
187
+ request.sessionId,
188
+ closestPeersToDestination,
189
+ dataEntries,
190
+ true
191
+ )
192
+ return createRouteMessageAck(routedMessage)
193
+ } else {
194
+ const ack = this.config.router.doRouteMessage(routedMessage, RoutingMode.RECURSIVE, excludedPeer)
195
+ if ((ack.error === undefined) || (ack.error === RouteMessageError.NO_TARGETS)) {
196
+ const noCloserContactsFound = (ack.error === RouteMessageError.NO_TARGETS) ||
197
+ (
198
+ closestPeersToDestination.length > 0
199
+ && getPreviousPeer(routedMessage)
200
+ && !this.isPeerCloserToIdThanSelf(closestPeersToDestination[0], targetId)
201
+ )
202
+ this.sendResponse(
203
+ routedMessage.routingPath,
204
+ routedMessage.sourcePeer!,
205
+ request.sessionId,
206
+ closestPeersToDestination,
207
+ dataEntries,
208
+ noCloserContactsFound
209
+ )
210
+ }
211
+ return ack
212
+ }
213
+ }
214
+
215
+ private getClosestConnections(nodeId: Uint8Array, limit: number): PeerDescriptor[] {
216
+ const connectedPeers = Array.from(this.config.connections.values())
217
+ const closestPeers = new SortedContactList<DhtNodeRpcRemote>({
218
+ referenceId: getNodeIdFromBinary(nodeId),
219
+ maxSize: limit,
220
+ allowToContainReferenceId: true,
221
+ emitEvents: false
222
+ })
223
+ closestPeers.addContacts(connectedPeers)
224
+ return closestPeers.getClosestContacts(limit).map((peer) => peer.getPeerDescriptor())
225
+ }
226
+
227
+ private isPeerCloserToIdThanSelf(peer: PeerDescriptor, compareToId: NodeID): boolean {
228
+ const distance1 = getDistance(getNodeIdFromPeerDescriptor(peer), compareToId)
229
+ const distance2 = getDistance(getNodeIdFromPeerDescriptor(this.config.localPeerDescriptor), compareToId)
230
+ return distance1 < distance2
231
+ }
232
+
233
+ public stop(): void {
234
+ this.stopped = true
235
+ this.ongoingSessions.forEach((session, _id) => {
236
+ session.stop()
237
+ })
238
+ this.ongoingSessions.clear()
239
+ }
240
+ }
@@ -1,35 +1,35 @@
1
1
  import { Logger } from '@streamr/utils'
2
2
  import { PeerDescriptor, RouteMessageAck, RouteMessageError, RouteMessageWrapper } from '../../proto/packages/dht/protos/DhtRpc'
3
- import { IFindRpc } from '../../proto/packages/dht/protos/DhtRpc.server'
3
+ import { IRecursiveOperationRpc } from '../../proto/packages/dht/protos/DhtRpc.server'
4
4
  import { getNodeIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
5
5
  import { createRouteMessageAck } from '../routing/RouterRpcLocal'
6
6
  import { getPreviousPeer } from '../routing/getPreviousPeer'
7
7
 
8
8
  const logger = new Logger(module)
9
9
 
10
- interface FindRpcLocalConfig {
11
- doRouteFindRequest: (routedMessage: RouteMessageWrapper) => RouteMessageAck
10
+ interface RecursiveOperationRpcLocalConfig {
11
+ doRouteRequest: (routedMessage: RouteMessageWrapper) => RouteMessageAck
12
12
  addContact: (contact: PeerDescriptor, setActive?: boolean) => void
13
13
  isMostLikelyDuplicate: (requestId: string) => boolean
14
14
  addToDuplicateDetector: (requestId: string) => void
15
15
  }
16
16
 
17
- export class FindRpcLocal implements IFindRpc {
17
+ export class RecursiveOperationRpcLocal implements IRecursiveOperationRpc {
18
18
 
19
- private readonly config: FindRpcLocalConfig
19
+ private readonly config: RecursiveOperationRpcLocalConfig
20
20
 
21
- constructor(config: FindRpcLocalConfig) {
21
+ constructor(config: RecursiveOperationRpcLocalConfig) {
22
22
  this.config = config
23
23
  }
24
24
 
25
- async routeFindRequest(routedMessage: RouteMessageWrapper): Promise<RouteMessageAck> {
25
+ async routeRequest(routedMessage: RouteMessageWrapper): Promise<RouteMessageAck> {
26
26
  if (this.config.isMostLikelyDuplicate(routedMessage.requestId)) {
27
27
  return createRouteMessageAck(routedMessage, RouteMessageError.DUPLICATE)
28
28
  }
29
29
  const senderId = getNodeIdFromPeerDescriptor(getPreviousPeer(routedMessage) ?? routedMessage.sourcePeer!)
30
- logger.trace(`Received routeFindRequest call from ${senderId}`)
30
+ logger.trace(`Received routeRequest call from ${senderId}`)
31
31
  this.config.addContact(routedMessage.sourcePeer!, true)
32
32
  this.config.addToDuplicateDetector(routedMessage.requestId)
33
- return this.config.doRouteFindRequest(routedMessage)
33
+ return this.config.doRouteRequest(routedMessage)
34
34
  }
35
35
  }
@@ -1,18 +1,18 @@
1
- import { RouteMessageWrapper } from '../../proto/packages/dht/protos/DhtRpc'
1
+ import { Logger } from '@streamr/utils'
2
2
  import { v4 } from 'uuid'
3
3
  import { getNodeIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
4
+ import { RouteMessageWrapper } from '../../proto/packages/dht/protos/DhtRpc'
5
+ import { RecursiveOperationRpcClient } from '../../proto/packages/dht/protos/DhtRpc.client'
4
6
  import { RpcRemote } from '../contact/RpcRemote'
5
- import { Logger } from '@streamr/utils'
6
- import { IFindRpcClient } from '../../proto/packages/dht/protos/DhtRpc.client'
7
- import { getPreviousPeer } from './getPreviousPeer'
7
+ import { getPreviousPeer } from '../routing/getPreviousPeer'
8
8
 
9
9
  const logger = new Logger(module)
10
10
 
11
- export class FindRpcRemote extends RpcRemote<IFindRpcClient> {
11
+ export class RecursiveOperationRpcRemote extends RpcRemote<RecursiveOperationRpcClient> {
12
12
 
13
- async routeFindRequest(params: RouteMessageWrapper): Promise<boolean> {
13
+ async routeRequest(params: RouteMessageWrapper): Promise<boolean> {
14
14
  const message: RouteMessageWrapper = {
15
- destinationPeer: params.destinationPeer,
15
+ target: params.target,
16
16
  sourcePeer: params.sourcePeer,
17
17
  message: params.message,
18
18
  requestId: params.requestId ?? v4(),
@@ -20,10 +20,10 @@ export class FindRpcRemote extends RpcRemote<IFindRpcClient> {
20
20
  routingPath: params.routingPath
21
21
  }
22
22
  const options = this.formDhtRpcOptions({
23
- doNotConnect: true
23
+ connect: false
24
24
  })
25
25
  try {
26
- const ack = await this.getClient().routeFindRequest(message, options)
26
+ const ack = await this.getClient().routeRequest(message, options)
27
27
  if (ack.error !== undefined) {
28
28
  logger.trace('Next hop responded with error ' + ack.error)
29
29
  return false
@@ -34,7 +34,7 @@ export class FindRpcRemote extends RpcRemote<IFindRpcClient> {
34
34
  ? getNodeIdFromPeerDescriptor(previousPeer)
35
35
  : getNodeIdFromPeerDescriptor(params.sourcePeer!)
36
36
  // eslint-disable-next-line max-len
37
- logger.debug(`Failed to send routeFindRequest message from ${fromNode} to ${getNodeIdFromPeerDescriptor(this.getPeerDescriptor())} with: ${err}`)
37
+ logger.debug(`Failed to send routeRequest message from ${fromNode} to ${getNodeIdFromPeerDescriptor(this.getPeerDescriptor())} with: ${err}`)
38
38
  return false
39
39
  }
40
40
  return true
@@ -0,0 +1,224 @@
1
+ import EventEmitter from 'eventemitter3'
2
+ import { v4 } from 'uuid'
3
+ import {
4
+ DataEntry,
5
+ PeerDescriptor,
6
+ RecursiveOperationResponse,
7
+ RecursiveOperation,
8
+ RouteMessageWrapper,
9
+ RouteMessageAck,
10
+ RecursiveOperationRequest,
11
+ Message,
12
+ MessageType
13
+ } from '../../proto/packages/dht/protos/DhtRpc'
14
+ import { ITransport } from '../../transport/ITransport'
15
+ import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator'
16
+ import { Contact } from '../contact/Contact'
17
+ import { SortedContactList } from '../contact/SortedContactList'
18
+ import { RecursiveOperationResult } from './RecursiveOperationManager'
19
+ import { getNodeIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
20
+ import { ServiceID } from '../../types/ServiceID'
21
+ import { RecursiveOperationSessionRpcLocal } from './RecursiveOperationSessionRpcLocal'
22
+ import { NodeID, areEqualNodeIds, getNodeIdFromBinary } from '../../helpers/nodeId'
23
+
24
+ export interface RecursiveOperationSessionEvents {
25
+ completed: () => void
26
+ }
27
+
28
+ export interface RecursiveOperationSessionConfig {
29
+ transport: ITransport
30
+ targetId: Uint8Array
31
+ localPeerDescriptor: PeerDescriptor
32
+ waitedRoutingPathCompletions: number
33
+ operation: RecursiveOperation
34
+ doRouteRequest: (routedMessage: RouteMessageWrapper) => RouteMessageAck
35
+ }
36
+
37
+ export class RecursiveOperationSession extends EventEmitter<RecursiveOperationSessionEvents> {
38
+
39
+ private readonly id = v4()
40
+ private readonly rpcCommunicator: ListeningRpcCommunicator
41
+ private results: SortedContactList<Contact>
42
+ private foundData: Map<NodeID, DataEntry> = new Map()
43
+ private allKnownHops: Set<NodeID> = new Set()
44
+ private reportedHops: Set<NodeID> = new Set()
45
+ private timeoutTask?: NodeJS.Timeout
46
+ private completionEventEmitted = false
47
+ private noCloserNodesReceivedCounter = 0
48
+ private readonly config: RecursiveOperationSessionConfig
49
+
50
+ constructor(config: RecursiveOperationSessionConfig) {
51
+ super()
52
+ this.config = config
53
+ this.results = new SortedContactList({
54
+ referenceId: getNodeIdFromBinary(config.targetId),
55
+ maxSize: 10, // TODO use config option or named constant?
56
+ allowToContainReferenceId: true,
57
+ emitEvents: false
58
+ })
59
+ this.rpcCommunicator = new ListeningRpcCommunicator(this.id, config.transport, {
60
+ rpcRequestTimeout: 15000 // TODO use config option or named constant?
61
+ })
62
+ this.registerLocalRpcMethods()
63
+ }
64
+
65
+ private registerLocalRpcMethods() {
66
+ const rpcLocal = new RecursiveOperationSessionRpcLocal({
67
+ onResponseReceived: (routingPath: PeerDescriptor[], nodes: PeerDescriptor[], dataEntries: DataEntry[], noCloserNodesFound: boolean) => {
68
+ this.onResponseReceived(routingPath, nodes, dataEntries, noCloserNodesFound)
69
+ }
70
+ })
71
+ this.rpcCommunicator.registerRpcNotification(RecursiveOperationResponse, 'sendResponse',
72
+ (req: RecursiveOperationResponse) => rpcLocal.sendResponse(req))
73
+ }
74
+
75
+ public start(serviceId: ServiceID): void {
76
+ const routeMessage = this.wrapRequest(serviceId)
77
+ this.config.doRouteRequest(routeMessage)
78
+ }
79
+
80
+ private wrapRequest(serviceId: ServiceID): RouteMessageWrapper {
81
+ const request: RecursiveOperationRequest = {
82
+ sessionId: this.getId(),
83
+ operation: this.config.operation
84
+ }
85
+ const msg: Message = {
86
+ messageType: MessageType.RECURSIVE_OPERATION_REQUEST,
87
+ messageId: v4(),
88
+ serviceId,
89
+ body: {
90
+ oneofKind: 'recursiveOperationRequest',
91
+ recursiveOperationRequest: request
92
+ }
93
+ }
94
+ const routeMessage: RouteMessageWrapper = {
95
+ message: msg,
96
+ requestId: v4(),
97
+ target: this.config.targetId,
98
+ sourcePeer: this.config.localPeerDescriptor,
99
+ reachableThrough: [],
100
+ routingPath: []
101
+ }
102
+ return routeMessage
103
+ }
104
+
105
+ private isCompleted(): boolean {
106
+ const unreportedHops: Set<NodeID> = new Set(this.allKnownHops)
107
+ this.reportedHops.forEach((id) => {
108
+ unreportedHops.delete(id)
109
+ })
110
+ if (this.noCloserNodesReceivedCounter >= 1 && unreportedHops.size === 0) {
111
+ if (this.config.operation === RecursiveOperation.FETCH_DATA
112
+ && (this.hasNonStaleData() || this.noCloserNodesReceivedCounter >= this.config.waitedRoutingPathCompletions)) {
113
+ return true
114
+ } else if (this.config.operation === RecursiveOperation.FETCH_DATA) {
115
+ return false
116
+ }
117
+ return true
118
+ }
119
+ return false
120
+ }
121
+
122
+ private hasNonStaleData(): boolean {
123
+ return Array.from(this.foundData.values()).some((entry) => entry.stale === false)
124
+ }
125
+
126
+ public onResponseReceived(
127
+ routingPath: PeerDescriptor[],
128
+ nodes: PeerDescriptor[],
129
+ dataEntries: DataEntry[],
130
+ noCloserNodesFound: boolean
131
+ ): void {
132
+ this.addKnownHops(routingPath)
133
+ if (routingPath.length >= 1) {
134
+ this.setHopAsReported(routingPath[routingPath.length - 1])
135
+ }
136
+ nodes.forEach((descriptor: PeerDescriptor) => {
137
+ this.results.addContact(new Contact(descriptor))
138
+ })
139
+ this.processFoundData(dataEntries)
140
+ if (noCloserNodesFound) {
141
+ this.onNoCloserPeersFound()
142
+ }
143
+ }
144
+
145
+ private addKnownHops(routingPath: PeerDescriptor[]) {
146
+ const localNodeId = getNodeIdFromPeerDescriptor(this.config.localPeerDescriptor)
147
+ routingPath.forEach((desc) => {
148
+ const newNodeId = getNodeIdFromPeerDescriptor(desc)
149
+ if (!areEqualNodeIds(localNodeId, newNodeId)) {
150
+ this.allKnownHops.add(newNodeId)
151
+ }
152
+ })
153
+ }
154
+
155
+ private setHopAsReported(desc: PeerDescriptor) {
156
+ const localNodeId = getNodeIdFromPeerDescriptor(this.config.localPeerDescriptor)
157
+ const newNodeId = getNodeIdFromPeerDescriptor(desc)
158
+ if (!areEqualNodeIds(localNodeId, newNodeId)) {
159
+ this.reportedHops.add(newNodeId)
160
+ }
161
+ if (this.isCompleted()) {
162
+ if (!this.completionEventEmitted && this.isCompleted()) {
163
+ if (this.timeoutTask) {
164
+ clearTimeout(this.timeoutTask)
165
+ this.timeoutTask = undefined
166
+ }
167
+ this.emit('completed')
168
+ this.completionEventEmitted = true
169
+ }
170
+ }
171
+ }
172
+
173
+ private processFoundData(dataEntries: DataEntry[]): void {
174
+ dataEntries.forEach((entry) => {
175
+ const creatorNodeId = getNodeIdFromBinary(entry.creator)
176
+ const existingEntry = this.foundData.get(creatorNodeId)
177
+ if (!existingEntry || existingEntry.createdAt! < entry.createdAt!
178
+ || (existingEntry.createdAt! <= entry.createdAt! && entry.deleted)) {
179
+ this.foundData.set(creatorNodeId, entry)
180
+ }
181
+ })
182
+ }
183
+
184
+ private onNoCloserPeersFound(): void {
185
+ this.noCloserNodesReceivedCounter += 1
186
+ if (this.isCompleted()) {
187
+ this.emit('completed')
188
+ this.completionEventEmitted = true
189
+ if (this.timeoutTask) {
190
+ clearTimeout(this.timeoutTask)
191
+ this.timeoutTask = undefined
192
+ }
193
+ } else {
194
+ if (!this.timeoutTask && !this.completionEventEmitted) {
195
+ this.timeoutTask = setTimeout(() => {
196
+ if (!this.completionEventEmitted) {
197
+ this.emit('completed')
198
+ this.completionEventEmitted = true
199
+ }
200
+ }, 4000) // TODO use config option or named constant?
201
+ }
202
+ }
203
+ }
204
+
205
+ public getResults(): RecursiveOperationResult {
206
+ return {
207
+ closestNodes: this.results.getAllContacts().map((contact) => contact.getPeerDescriptor()),
208
+ dataEntries: Array.from(this.foundData.values())
209
+ }
210
+ }
211
+
212
+ public getId(): string {
213
+ return this.id
214
+ }
215
+
216
+ public stop(): void {
217
+ if (this.timeoutTask) {
218
+ clearTimeout(this.timeoutTask)
219
+ this.timeoutTask = undefined
220
+ }
221
+ this.rpcCommunicator.destroy()
222
+ this.emit('completed')
223
+ }
224
+ }
@@ -0,0 +1,25 @@
1
+ import { IRecursiveOperationSessionRpc } from '../../proto/packages/dht/protos/DhtRpc.server'
2
+ import { Empty } from '../../proto/google/protobuf/empty'
3
+ import { DataEntry, RecursiveOperationResponse, PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
4
+ import { Logger } from '@streamr/utils'
5
+
6
+ const logger = new Logger(module)
7
+
8
+ interface RecursiveOperationSessionRpcLocalConfig {
9
+ onResponseReceived: (routingPath: PeerDescriptor[], nodes: PeerDescriptor[], dataEntries: DataEntry[], noCloserNodesFound: boolean) => void
10
+ }
11
+
12
+ export class RecursiveOperationSessionRpcLocal implements IRecursiveOperationSessionRpc {
13
+
14
+ private readonly config: RecursiveOperationSessionRpcLocalConfig
15
+
16
+ constructor(config: RecursiveOperationSessionRpcLocalConfig) {
17
+ this.config = config
18
+ }
19
+
20
+ async sendResponse(report: RecursiveOperationResponse): Promise<Empty> {
21
+ logger.trace('RecursiveOperationResponse arrived: ' + JSON.stringify(report))
22
+ this.config.onResponseReceived(report.routingPath, report.closestConnectedPeers, report.dataEntries, report.noCloserNodesFound)
23
+ return {}
24
+ }
25
+ }
@@ -1,30 +1,30 @@
1
+ import { Logger } from '@streamr/utils'
1
2
  import {
2
3
  DataEntry,
3
4
  PeerDescriptor,
4
- FindResponse
5
+ RecursiveOperationResponse
5
6
  } from '../../proto/packages/dht/protos/DhtRpc'
6
- import { IFindSessionRpcClient } from '../../proto/packages/dht/protos/DhtRpc.client'
7
- import { Logger } from '@streamr/utils'
7
+ import { RecursiveOperationSessionRpcClient } from '../../proto/packages/dht/protos/DhtRpc.client'
8
8
  import { RpcRemote } from '../contact/RpcRemote'
9
9
 
10
10
  const logger = new Logger(module)
11
11
 
12
- export class FindSessionRpcRemote extends RpcRemote<IFindSessionRpcClient> {
12
+ export class RecursiveOperationSessionRpcRemote extends RpcRemote<RecursiveOperationSessionRpcClient> {
13
13
 
14
- sendFindResponse(
14
+ sendResponse(
15
15
  routingPath: PeerDescriptor[],
16
16
  closestNodes: PeerDescriptor[],
17
17
  dataEntries: DataEntry[],
18
18
  noCloserNodesFound: boolean
19
19
  ): void {
20
- const report: FindResponse = {
20
+ const report: RecursiveOperationResponse = {
21
21
  routingPath,
22
22
  closestConnectedPeers: closestNodes,
23
23
  dataEntries,
24
24
  noCloserNodesFound
25
25
  }
26
- this.getClient().sendFindResponse(report, this.formDhtRpcOptions()).catch((_e) => {
27
- logger.trace('Failed to send FindResponse')
26
+ this.getClient().sendResponse(report, this.formDhtRpcOptions()).catch((_e) => {
27
+ logger.trace('Failed to send RecursiveOperationResponse')
28
28
  })
29
29
  }
30
30
  }