@streamr/dht 100.0.0-pretestnet.4 → 100.0.0-rc.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 (444) hide show
  1. package/README.md +90 -8
  2. package/dist/package.json +70 -0
  3. package/dist/src/connection/Connection.d.ts +1 -0
  4. package/dist/src/connection/Connection.js +10 -3
  5. package/dist/src/connection/Connection.js.map +1 -1
  6. package/dist/src/connection/ConnectionLockHandler.d.ts +14 -14
  7. package/dist/src/connection/ConnectionLockHandler.js +22 -16
  8. package/dist/src/connection/ConnectionLockHandler.js.map +1 -1
  9. package/dist/src/connection/ConnectionLockRpcLocal.d.ts +3 -3
  10. package/dist/src/connection/ConnectionLockRpcLocal.js +7 -6
  11. package/dist/src/connection/ConnectionLockRpcLocal.js.map +1 -1
  12. package/dist/src/connection/ConnectionLockRpcRemote.d.ts +4 -6
  13. package/dist/src/connection/ConnectionLockRpcRemote.js +10 -37
  14. package/dist/src/connection/ConnectionLockRpcRemote.js.map +1 -1
  15. package/dist/src/connection/ConnectionManager.d.ts +19 -20
  16. package/dist/src/connection/ConnectionManager.js +132 -117
  17. package/dist/src/connection/ConnectionManager.js.map +1 -1
  18. package/dist/src/connection/ConnectorFacade.d.ts +3 -2
  19. package/dist/src/connection/ConnectorFacade.js +10 -3
  20. package/dist/src/connection/ConnectorFacade.js.map +1 -1
  21. package/dist/src/connection/Handshaker.d.ts +3 -1
  22. package/dist/src/connection/Handshaker.js +18 -9
  23. package/dist/src/connection/Handshaker.js.map +1 -1
  24. package/dist/src/connection/IConnection.d.ts +2 -7
  25. package/dist/src/connection/IConnection.js +1 -8
  26. package/dist/src/connection/IConnection.js.map +1 -1
  27. package/dist/src/connection/ManagedConnection.d.ts +5 -7
  28. package/dist/src/connection/ManagedConnection.js +42 -26
  29. package/dist/src/connection/ManagedConnection.js.map +1 -1
  30. package/dist/src/connection/ManagedWebrtcConnection.js.map +1 -1
  31. package/dist/src/connection/connectivityChecker.d.ts +9 -0
  32. package/dist/src/connection/connectivityChecker.js +130 -0
  33. package/dist/src/connection/connectivityChecker.js.map +1 -0
  34. package/dist/src/connection/connectivityRequestHandler.d.ts +3 -0
  35. package/dist/src/connection/connectivityRequestHandler.js +101 -0
  36. package/dist/src/connection/connectivityRequestHandler.js.map +1 -0
  37. package/dist/src/connection/simulator/Simulator.d.ts +0 -3
  38. package/dist/src/connection/simulator/Simulator.js +34 -69
  39. package/dist/src/connection/simulator/Simulator.js.map +1 -1
  40. package/dist/src/connection/simulator/SimulatorConnection.js +27 -25
  41. package/dist/src/connection/simulator/SimulatorConnection.js.map +1 -1
  42. package/dist/src/connection/simulator/SimulatorConnector.js +16 -12
  43. package/dist/src/connection/simulator/SimulatorConnector.js.map +1 -1
  44. package/dist/src/connection/simulator/pings.js.map +1 -1
  45. package/dist/src/connection/webrtc/NodeWebrtcConnection.d.ts +2 -3
  46. package/dist/src/connection/webrtc/NodeWebrtcConnection.js +40 -27
  47. package/dist/src/connection/webrtc/NodeWebrtcConnection.js.map +1 -1
  48. package/dist/src/connection/webrtc/WebrtcConnector.d.ts +0 -2
  49. package/dist/src/connection/webrtc/WebrtcConnector.js +24 -25
  50. package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
  51. package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.d.ts +2 -2
  52. package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js +27 -20
  53. package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js.map +1 -1
  54. package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.d.ts +3 -6
  55. package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.js +2 -5
  56. package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.js.map +1 -1
  57. package/dist/src/connection/webrtc/iceServerAsString.js +1 -1
  58. package/dist/src/connection/webrtc/iceServerAsString.js.map +1 -1
  59. package/dist/src/connection/websocket/AutoCertifierClientFacade.d.ts +1 -2
  60. package/dist/src/connection/websocket/AutoCertifierClientFacade.js +6 -4
  61. package/dist/src/connection/websocket/AutoCertifierClientFacade.js.map +1 -1
  62. package/dist/src/connection/websocket/ClientWebsocket.d.ts +1 -0
  63. package/dist/src/connection/websocket/ClientWebsocket.js +14 -7
  64. package/dist/src/connection/websocket/ClientWebsocket.js.map +1 -1
  65. package/dist/src/connection/websocket/WebsocketConnector.d.ts +3 -9
  66. package/dist/src/connection/websocket/WebsocketConnector.js +142 -74
  67. package/dist/src/connection/websocket/WebsocketConnector.js.map +1 -1
  68. package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.d.ts +5 -3
  69. package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.js +9 -12
  70. package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.js.map +1 -1
  71. package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.d.ts +4 -7
  72. package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.js +7 -44
  73. package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.js.map +1 -1
  74. package/dist/src/connection/websocket/WebsocketServer.d.ts +1 -4
  75. package/dist/src/connection/websocket/WebsocketServer.js +49 -40
  76. package/dist/src/connection/websocket/WebsocketServer.js.map +1 -1
  77. package/dist/src/connection/websocket/{ServerWebsocket.d.ts → WebsocketServerConnection.d.ts} +8 -4
  78. package/dist/src/connection/websocket/WebsocketServerConnection.js +97 -0
  79. package/dist/src/connection/websocket/WebsocketServerConnection.js.map +1 -0
  80. package/dist/src/dht/DhtNode.d.ts +45 -49
  81. package/dist/src/dht/DhtNode.js +229 -317
  82. package/dist/src/dht/DhtNode.js.map +1 -1
  83. package/dist/src/dht/DhtNodeRpcLocal.d.ts +10 -9
  84. package/dist/src/dht/DhtNodeRpcLocal.js +19 -11
  85. package/dist/src/dht/DhtNodeRpcLocal.js.map +1 -1
  86. package/dist/src/dht/DhtNodeRpcRemote.d.ts +15 -10
  87. package/dist/src/dht/DhtNodeRpcRemote.js +38 -21
  88. package/dist/src/dht/DhtNodeRpcRemote.js.map +1 -1
  89. package/dist/src/dht/ExternalApiRpcLocal.d.ts +7 -6
  90. package/dist/src/dht/ExternalApiRpcLocal.js +9 -13
  91. package/dist/src/dht/ExternalApiRpcLocal.js.map +1 -1
  92. package/dist/src/dht/ExternalApiRpcRemote.d.ts +6 -5
  93. package/dist/src/dht/ExternalApiRpcRemote.js +10 -7
  94. package/dist/src/dht/ExternalApiRpcRemote.js.map +1 -1
  95. package/dist/src/dht/PeerManager.d.ts +61 -0
  96. package/dist/src/dht/PeerManager.js +288 -0
  97. package/dist/src/dht/PeerManager.js.map +1 -0
  98. package/dist/src/dht/contact/Contact.d.ts +2 -2
  99. package/dist/src/dht/contact/Contact.js +4 -3
  100. package/dist/src/dht/contact/Contact.js.map +1 -1
  101. package/dist/src/dht/contact/ContactList.d.ts +8 -8
  102. package/dist/src/dht/contact/ContactList.js +12 -7
  103. package/dist/src/dht/contact/ContactList.js.map +1 -1
  104. package/dist/src/dht/contact/RandomContactList.d.ts +4 -4
  105. package/dist/src/dht/contact/RandomContactList.js +13 -12
  106. package/dist/src/dht/contact/RandomContactList.js.map +1 -1
  107. package/dist/src/dht/contact/RingContactList.d.ts +31 -0
  108. package/dist/src/dht/contact/RingContactList.js +133 -0
  109. package/dist/src/dht/contact/RingContactList.js.map +1 -0
  110. package/dist/src/dht/contact/{Remote.d.ts → RpcRemote.d.ts} +8 -7
  111. package/dist/src/dht/contact/{Remote.js → RpcRemote.js} +16 -13
  112. package/dist/src/dht/contact/RpcRemote.js.map +1 -0
  113. package/dist/src/dht/contact/SortedContactList.d.ts +29 -15
  114. package/dist/src/dht/contact/SortedContactList.js +79 -42
  115. package/dist/src/dht/contact/SortedContactList.js.map +1 -1
  116. package/dist/src/dht/contact/ringIdentifiers.d.ts +16 -0
  117. package/dist/src/dht/contact/ringIdentifiers.js +54 -0
  118. package/dist/src/dht/contact/ringIdentifiers.js.map +1 -0
  119. package/dist/src/dht/discovery/DiscoverySession.d.ts +8 -18
  120. package/dist/src/dht/discovery/DiscoverySession.js +32 -48
  121. package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
  122. package/dist/src/dht/discovery/PeerDiscovery.d.ts +16 -12
  123. package/dist/src/dht/discovery/PeerDiscovery.js +82 -39
  124. package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
  125. package/dist/src/dht/discovery/RingDiscoverySession.d.ts +29 -0
  126. package/dist/src/dht/discovery/RingDiscoverySession.js +123 -0
  127. package/dist/src/dht/discovery/RingDiscoverySession.js.map +1 -0
  128. package/dist/src/dht/recursive-operation/RecursiveOperationManager.d.ts +36 -0
  129. package/dist/src/dht/recursive-operation/RecursiveOperationManager.js +166 -0
  130. package/dist/src/dht/recursive-operation/RecursiveOperationManager.js.map +1 -0
  131. package/dist/src/dht/recursive-operation/RecursiveOperationRpcLocal.d.ts +14 -0
  132. package/dist/src/dht/recursive-operation/RecursiveOperationRpcLocal.js +26 -0
  133. package/dist/src/dht/recursive-operation/RecursiveOperationRpcLocal.js.map +1 -0
  134. package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.d.ts +6 -0
  135. package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.js +44 -0
  136. package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.js.map +1 -0
  137. package/dist/src/dht/recursive-operation/RecursiveOperationSession.d.ts +44 -0
  138. package/dist/src/dht/recursive-operation/RecursiveOperationSession.js +187 -0
  139. package/dist/src/dht/recursive-operation/RecursiveOperationSession.js.map +1 -0
  140. package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.d.ts +14 -0
  141. package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.js +20 -0
  142. package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.js.map +1 -0
  143. package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.d.ts +6 -0
  144. package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.js +21 -0
  145. package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.js.map +1 -0
  146. package/dist/src/dht/routing/DuplicateDetector.d.ts +2 -4
  147. package/dist/src/dht/routing/DuplicateDetector.js +10 -15
  148. package/dist/src/dht/routing/DuplicateDetector.js.map +1 -1
  149. package/dist/src/dht/routing/Router.d.ts +11 -27
  150. package/dist/src/dht/routing/Router.js +92 -58
  151. package/dist/src/dht/routing/Router.js.map +1 -1
  152. package/dist/src/dht/routing/RouterRpcLocal.d.ts +3 -4
  153. package/dist/src/dht/routing/RouterRpcLocal.js +17 -16
  154. package/dist/src/dht/routing/RouterRpcLocal.js.map +1 -1
  155. package/dist/src/dht/routing/RouterRpcRemote.d.ts +3 -3
  156. package/dist/src/dht/routing/RouterRpcRemote.js +29 -20
  157. package/dist/src/dht/routing/RouterRpcRemote.js.map +1 -1
  158. package/dist/src/dht/routing/RoutingSession.d.ts +29 -21
  159. package/dist/src/dht/routing/RoutingSession.js +93 -68
  160. package/dist/src/dht/routing/RoutingSession.js.map +1 -1
  161. package/dist/src/dht/routing/RoutingTablesCache.d.ts +24 -0
  162. package/dist/src/dht/routing/RoutingTablesCache.js +46 -0
  163. package/dist/src/dht/routing/RoutingTablesCache.js.map +1 -0
  164. package/dist/src/dht/routing/getPreviousPeer.js.map +1 -1
  165. package/dist/src/dht/store/LocalDataStore.d.ts +9 -14
  166. package/dist/src/dht/store/LocalDataStore.js +46 -72
  167. package/dist/src/dht/store/LocalDataStore.js.map +1 -1
  168. package/dist/src/dht/store/StoreManager.d.ts +33 -0
  169. package/dist/src/dht/store/StoreManager.js +182 -0
  170. package/dist/src/dht/store/StoreManager.js.map +1 -0
  171. package/dist/src/dht/store/StoreRpcLocal.d.ts +11 -41
  172. package/dist/src/dht/store/StoreRpcLocal.js +27 -234
  173. package/dist/src/dht/store/StoreRpcLocal.js.map +1 -1
  174. package/dist/src/dht/store/StoreRpcRemote.d.ts +6 -7
  175. package/dist/src/dht/store/StoreRpcRemote.js +10 -20
  176. package/dist/src/dht/store/StoreRpcRemote.js.map +1 -1
  177. package/dist/src/exports.d.ts +5 -3
  178. package/dist/src/exports.js +10 -8
  179. package/dist/src/exports.js.map +1 -1
  180. package/dist/src/helpers/AddressTools.js +2 -0
  181. package/dist/src/helpers/AddressTools.js.map +1 -1
  182. package/dist/src/helpers/Connectivity.js.map +1 -1
  183. package/dist/src/helpers/MapWithTtl.d.ts +14 -0
  184. package/dist/src/helpers/MapWithTtl.js +60 -0
  185. package/dist/src/helpers/MapWithTtl.js.map +1 -0
  186. package/dist/src/helpers/createPeerDescriptor.d.ts +3 -0
  187. package/dist/src/helpers/createPeerDescriptor.js +57 -0
  188. package/dist/src/helpers/createPeerDescriptor.js.map +1 -0
  189. package/dist/src/helpers/createPeerDescriptorSignaturePayload.d.ts +2 -0
  190. package/dist/src/helpers/createPeerDescriptorSignaturePayload.js +30 -0
  191. package/dist/src/helpers/createPeerDescriptorSignaturePayload.js.map +1 -0
  192. package/dist/src/helpers/debugHelpers.js.map +1 -1
  193. package/dist/src/helpers/errors.js +2 -0
  194. package/dist/src/helpers/errors.js.map +1 -1
  195. package/dist/src/helpers/offering.d.ts +4 -0
  196. package/dist/src/helpers/offering.js +18 -0
  197. package/dist/src/helpers/offering.js.map +1 -0
  198. package/dist/src/helpers/protoClasses.js +2 -3
  199. package/dist/src/helpers/protoClasses.js.map +1 -1
  200. package/dist/src/helpers/protoToString.js.map +1 -1
  201. package/dist/src/helpers/version.d.ts +6 -0
  202. package/dist/src/helpers/version.js +38 -0
  203. package/dist/src/helpers/version.js.map +1 -0
  204. package/dist/src/identifiers.d.ts +10 -0
  205. package/dist/src/identifiers.js +31 -0
  206. package/dist/src/identifiers.js.map +1 -0
  207. package/dist/src/proto/google/protobuf/any.js +8 -8
  208. package/dist/src/proto/google/protobuf/any.js.map +1 -1
  209. package/dist/src/proto/google/protobuf/empty.js +2 -4
  210. package/dist/src/proto/google/protobuf/empty.js.map +1 -1
  211. package/dist/src/proto/google/protobuf/timestamp.js +10 -10
  212. package/dist/src/proto/google/protobuf/timestamp.js.map +1 -1
  213. package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +46 -49
  214. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +63 -54
  215. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
  216. package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +226 -232
  217. package/dist/src/proto/packages/dht/protos/DhtRpc.js +146 -168
  218. package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
  219. package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +26 -29
  220. package/dist/src/proto/packages/proto-rpc/protos/ProtoRpc.js +1 -1
  221. package/dist/src/rpc-protocol/DhtCallContext.d.ts +2 -2
  222. package/dist/src/rpc-protocol/DhtCallContext.js +8 -0
  223. package/dist/src/rpc-protocol/DhtCallContext.js.map +1 -1
  224. package/dist/src/rpc-protocol/DhtRpcOptions.d.ts +2 -1
  225. package/dist/src/transport/ITransport.d.ts +10 -2
  226. package/dist/src/transport/ITransport.js +5 -0
  227. package/dist/src/transport/ITransport.js.map +1 -1
  228. package/dist/src/transport/ListeningRpcCommunicator.js +3 -1
  229. package/dist/src/transport/ListeningRpcCommunicator.js.map +1 -1
  230. package/dist/src/transport/RoutingRpcCommunicator.d.ts +4 -2
  231. package/dist/src/transport/RoutingRpcCommunicator.js +19 -12
  232. package/dist/src/transport/RoutingRpcCommunicator.js.map +1 -1
  233. package/jest.config.js +4 -1
  234. package/karma-setup.js +2 -0
  235. package/karma.config.js +13 -9
  236. package/package.json +16 -13
  237. package/protos/DhtRpc.proto +76 -76
  238. package/src/connection/Connection.ts +6 -1
  239. package/src/connection/ConnectionLockHandler.ts +30 -22
  240. package/src/connection/ConnectionLockRpcLocal.ts +7 -12
  241. package/src/connection/ConnectionLockRpcRemote.ts +9 -19
  242. package/src/connection/ConnectionManager.ts +132 -138
  243. package/src/connection/ConnectorFacade.ts +10 -9
  244. package/src/connection/Handshaker.ts +23 -11
  245. package/src/connection/IConnection.ts +2 -8
  246. package/src/connection/ManagedConnection.ts +34 -35
  247. package/src/connection/connectivityChecker.ts +109 -0
  248. package/src/connection/connectivityRequestHandler.ts +103 -0
  249. package/src/connection/simulator/Simulator.ts +6 -37
  250. package/src/connection/simulator/SimulatorConnection.ts +23 -25
  251. package/src/connection/simulator/SimulatorConnector.ts +11 -11
  252. package/src/connection/webrtc/BrowserWebrtcConnection.ts +17 -25
  253. package/src/connection/webrtc/NodeWebrtcConnection.ts +24 -26
  254. package/src/connection/webrtc/WebrtcConnector.ts +18 -29
  255. package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +29 -24
  256. package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +4 -14
  257. package/src/connection/webrtc/iceServerAsString.ts +1 -1
  258. package/src/connection/websocket/AutoCertifierClientFacade.ts +4 -6
  259. package/src/connection/websocket/ClientWebsocket.ts +10 -4
  260. package/src/connection/websocket/WebsocketConnector.ts +120 -97
  261. package/src/connection/websocket/WebsocketConnectorRpcLocal.ts +13 -15
  262. package/src/connection/websocket/WebsocketConnectorRpcRemote.ts +7 -27
  263. package/src/connection/websocket/WebsocketServer.ts +50 -53
  264. package/src/connection/websocket/WebsocketServerConnection.ts +104 -0
  265. package/src/dht/DhtNode.ts +289 -410
  266. package/src/dht/DhtNodeRpcLocal.ts +25 -17
  267. package/src/dht/DhtNodeRpcRemote.ts +43 -27
  268. package/src/dht/ExternalApiRpcLocal.ts +30 -17
  269. package/src/dht/ExternalApiRpcRemote.ts +14 -11
  270. package/src/dht/PeerManager.ts +339 -0
  271. package/src/dht/contact/Contact.ts +4 -4
  272. package/src/dht/contact/ContactList.ts +11 -10
  273. package/src/dht/contact/RandomContactList.ts +15 -15
  274. package/src/dht/contact/RingContactList.ts +151 -0
  275. package/src/dht/contact/{Remote.ts → RpcRemote.ts} +16 -19
  276. package/src/dht/contact/SortedContactList.ts +120 -72
  277. package/src/dht/contact/ringIdentifiers.ts +62 -0
  278. package/src/dht/discovery/DiscoverySession.ts +36 -61
  279. package/src/dht/discovery/PeerDiscovery.ts +98 -43
  280. package/src/dht/discovery/RingDiscoverySession.ts +160 -0
  281. package/src/dht/recursive-operation/RecursiveOperationManager.ts +246 -0
  282. package/src/dht/recursive-operation/RecursiveOperationRpcLocal.ts +34 -0
  283. package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +43 -0
  284. package/src/dht/recursive-operation/RecursiveOperationSession.ts +232 -0
  285. package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +35 -0
  286. package/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.ts +30 -0
  287. package/src/dht/routing/DuplicateDetector.ts +9 -21
  288. package/src/dht/routing/Router.ts +95 -92
  289. package/src/dht/routing/RouterRpcLocal.ts +16 -18
  290. package/src/dht/routing/RouterRpcRemote.ts +26 -24
  291. package/src/dht/routing/RoutingSession.ts +119 -98
  292. package/src/dht/routing/RoutingTablesCache.ts +58 -0
  293. package/src/dht/routing/getPreviousPeer.ts +1 -1
  294. package/src/dht/store/LocalDataStore.ts +47 -77
  295. package/src/dht/store/StoreManager.ts +209 -0
  296. package/src/dht/store/StoreRpcLocal.ts +39 -308
  297. package/src/dht/store/StoreRpcRemote.ts +13 -31
  298. package/src/exports.ts +13 -3
  299. package/src/helpers/AddressTools.ts +2 -0
  300. package/src/helpers/MapWithTtl.ts +71 -0
  301. package/src/helpers/createPeerDescriptor.ts +57 -0
  302. package/src/helpers/createPeerDescriptorSignaturePayload.ts +28 -0
  303. package/src/helpers/offering.ts +15 -0
  304. package/src/helpers/protoClasses.ts +4 -6
  305. package/src/helpers/version.ts +32 -0
  306. package/src/identifiers.ts +29 -0
  307. package/src/proto/google/protobuf/any.ts +4 -4
  308. package/src/proto/google/protobuf/empty.ts +2 -4
  309. package/src/proto/google/protobuf/timestamp.ts +4 -4
  310. package/src/proto/packages/dht/protos/DhtRpc.client.ts +65 -68
  311. package/src/proto/packages/dht/protos/DhtRpc.server.ts +27 -30
  312. package/src/proto/packages/dht/protos/DhtRpc.ts +297 -313
  313. package/src/proto/packages/proto-rpc/protos/ProtoRpc.ts +1 -1
  314. package/src/rpc-protocol/DhtCallContext.ts +2 -2
  315. package/src/rpc-protocol/DhtRpcOptions.ts +2 -1
  316. package/src/transport/ITransport.ts +11 -2
  317. package/src/transport/ListeningRpcCommunicator.ts +1 -1
  318. package/src/transport/RoutingRpcCommunicator.ts +21 -14
  319. package/test/RandomGraphSimulation.ts +3 -2
  320. package/test/benchmark/Find.test.ts +13 -28
  321. package/test/benchmark/KademliaCorrectness.test.ts +24 -28
  322. package/test/benchmark/RingCorrectness.test.ts +157 -0
  323. package/test/benchmark/SortedContactListBenchmark.test.ts +151 -0
  324. package/test/benchmark/WebsocketServerMemoryLeak.test.ts +41 -0
  325. package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +72 -0
  326. package/test/benchmark/kademlia-simulation/Contact.ts +9 -9
  327. package/test/benchmark/kademlia-simulation/KademliaSimulation.ts +11 -11
  328. package/test/benchmark/kademlia-simulation/SimulationNode.ts +29 -25
  329. package/test/data/generateGroundTruthData.ts +7 -6
  330. package/test/end-to-end/Layer0-Layer1.test.ts +11 -15
  331. package/test/end-to-end/Layer0.test.ts +19 -22
  332. package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +19 -21
  333. package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +26 -28
  334. package/test/end-to-end/Layer0Webrtc.test.ts +19 -19
  335. package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +10 -18
  336. package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +8 -15
  337. package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +2 -2
  338. package/test/end-to-end/WebsocketConnectionRequest.test.ts +8 -9
  339. package/test/end-to-end/memory-leak.test.ts +19 -24
  340. package/test/integration/ConnectionLocking.test.ts +66 -60
  341. package/test/integration/ConnectionManager.test.ts +43 -63
  342. package/test/integration/ConnectivityChecking.test.ts +52 -0
  343. package/test/integration/DhtJoinPeerDiscovery.test.ts +8 -12
  344. package/test/integration/DhtNodeExternalAPI.test.ts +17 -21
  345. package/test/integration/DhtNodeRpcRemote.test.ts +19 -26
  346. package/test/integration/DhtRpc.test.ts +20 -24
  347. package/test/integration/Find.test.ts +10 -12
  348. package/test/integration/Layer1-scale.test.ts +25 -37
  349. package/test/integration/Mock-Layer1-Layer0.test.ts +39 -59
  350. package/test/integration/MultipleEntryPointJoining.test.ts +14 -14
  351. package/test/integration/ReplicateData.test.ts +106 -0
  352. package/test/integration/RouteMessage.test.ts +42 -68
  353. package/test/integration/RouterRpcRemote.test.ts +19 -24
  354. package/test/integration/ScaleDownDht.test.ts +14 -12
  355. package/test/integration/SimultaneousConnections.test.ts +112 -111
  356. package/test/integration/Store.test.ts +43 -27
  357. package/test/integration/StoreAndDelete.test.ts +36 -48
  358. package/test/integration/StoreOnDhtWithThreeNodes.test.ts +59 -0
  359. package/test/integration/StoreOnDhtWithTwoNodes.test.ts +17 -37
  360. package/test/integration/StoreRpcRemote.test.ts +20 -32
  361. package/test/integration/WebrtcConnectionManagement.test.ts +39 -25
  362. package/test/integration/WebrtcConnectorRpc.test.ts +6 -11
  363. package/test/integration/WebsocketConnectionManagement.test.ts +87 -22
  364. package/test/integration/WebsocketConnectorRpc.test.ts +14 -24
  365. package/test/integration/{RpcErrors.test.ts → rpc-connections-over-webrpc.test.ts} +15 -26
  366. package/test/unit/AddressTools.test.ts +4 -0
  367. package/test/unit/ConnectivityHelpers.test.ts +9 -17
  368. package/test/unit/DuplicateDetector.test.ts +8 -5
  369. package/test/unit/LocalDataStore.test.ts +78 -75
  370. package/test/unit/PeerManager.test.ts +33 -0
  371. package/test/unit/RandomContactList.test.ts +12 -9
  372. package/test/unit/RecursiveOperationManager.test.ts +157 -0
  373. package/test/unit/RecursiveOperationSession.test.ts +68 -0
  374. package/test/unit/Router.test.ts +52 -35
  375. package/test/unit/RoutingSession.test.ts +79 -0
  376. package/test/unit/SortedContactList.test.ts +61 -30
  377. package/test/unit/StoreManager.test.ts +138 -0
  378. package/test/unit/WebsocketConnector.test.ts +27 -35
  379. package/test/unit/connectivityRequestHandler.test.ts +104 -0
  380. package/test/unit/createPeerDescriptor.test.ts +69 -0
  381. package/test/unit/customMatchers.test.ts +16 -0
  382. package/test/unit/version.test.ts +18 -0
  383. package/test/utils/FakeTransport.ts +47 -0
  384. package/test/utils/customMatchers.ts +71 -0
  385. package/test/utils/mock/MockRpcCommunicator.ts +7 -0
  386. package/test/utils/mock/Router.ts +13 -3
  387. package/test/utils/mock/Transport.ts +1 -1
  388. package/test/utils/mock/mockDataEntry.ts +38 -0
  389. package/test/utils/utils.ts +104 -107
  390. package/tsconfig.browser.json +2 -1
  391. package/tsconfig.jest.json +4 -2
  392. package/tsconfig.node.json +4 -2
  393. package/dist/src/connection/ConnectivityChecker.d.ts +0 -17
  394. package/dist/src/connection/ConnectivityChecker.js +0 -208
  395. package/dist/src/connection/ConnectivityChecker.js.map +0 -1
  396. package/dist/src/connection/websocket/ServerWebsocket.js +0 -100
  397. package/dist/src/connection/websocket/ServerWebsocket.js.map +0 -1
  398. package/dist/src/dht/contact/Remote.js.map +0 -1
  399. package/dist/src/dht/find/FindRpcLocal.d.ts +0 -14
  400. package/dist/src/dht/find/FindRpcLocal.js +0 -25
  401. package/dist/src/dht/find/FindRpcLocal.js.map +0 -1
  402. package/dist/src/dht/find/FindSession.d.ts +0 -44
  403. package/dist/src/dht/find/FindSession.js +0 -145
  404. package/dist/src/dht/find/FindSession.js.map +0 -1
  405. package/dist/src/dht/find/FindSessionRpcLocal.d.ts +0 -12
  406. package/dist/src/dht/find/FindSessionRpcLocal.js +0 -17
  407. package/dist/src/dht/find/FindSessionRpcLocal.js.map +0 -1
  408. package/dist/src/dht/find/FindSessionRpcRemote.d.ts +0 -6
  409. package/dist/src/dht/find/FindSessionRpcRemote.js +0 -21
  410. package/dist/src/dht/find/FindSessionRpcRemote.js.map +0 -1
  411. package/dist/src/dht/find/Finder.d.ts +0 -49
  412. package/dist/src/dht/find/Finder.js +0 -184
  413. package/dist/src/dht/find/Finder.js.map +0 -1
  414. package/dist/src/dht/routing/FindRpcRemote.d.ts +0 -6
  415. package/dist/src/dht/routing/FindRpcRemote.js +0 -41
  416. package/dist/src/dht/routing/FindRpcRemote.js.map +0 -1
  417. package/dist/src/helpers/PeerID.d.ts +0 -24
  418. package/dist/src/helpers/PeerID.js +0 -78
  419. package/dist/src/helpers/PeerID.js.map +0 -1
  420. package/dist/src/helpers/UUID.d.ts +0 -8
  421. package/dist/src/helpers/UUID.js +0 -36
  422. package/dist/src/helpers/UUID.js.map +0 -1
  423. package/dist/src/helpers/kademliaId.d.ts +0 -1
  424. package/dist/src/helpers/kademliaId.js +0 -14
  425. package/dist/src/helpers/kademliaId.js.map +0 -1
  426. package/dist/src/helpers/peerIdFromPeerDescriptor.d.ts +0 -6
  427. package/dist/src/helpers/peerIdFromPeerDescriptor.js +0 -23
  428. package/dist/src/helpers/peerIdFromPeerDescriptor.js.map +0 -1
  429. package/src/connection/ConnectivityChecker.ts +0 -199
  430. package/src/connection/websocket/ServerWebsocket.ts +0 -114
  431. package/src/dht/find/FindRpcLocal.ts +0 -35
  432. package/src/dht/find/FindSession.ts +0 -178
  433. package/src/dht/find/FindSessionRpcLocal.ts +0 -25
  434. package/src/dht/find/FindSessionRpcRemote.ts +0 -30
  435. package/src/dht/find/Finder.ts +0 -275
  436. package/src/dht/routing/FindRpcRemote.ts +0 -40
  437. package/src/helpers/PeerID.ts +0 -88
  438. package/src/helpers/UUID.ts +0 -35
  439. package/src/helpers/kademliaId.ts +0 -8
  440. package/src/helpers/peerIdFromPeerDescriptor.ts +0 -20
  441. package/test/integration/MigrateData.test.ts +0 -204
  442. package/test/unit/Finder.test.ts +0 -110
  443. package/test/unit/PeerID.test.ts +0 -22
  444. package/test/unit/UUID.test.ts +0 -55
@@ -1,43 +1,44 @@
1
1
  import { DhtNodeRpcRemote } from '../DhtNodeRpcRemote'
2
2
  import { SortedContactList } from '../contact/SortedContactList'
3
- import { PeerID, PeerIDKey } from '../../helpers/PeerID'
4
- import { getNodeIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
5
3
  import { Logger } from '@streamr/utils'
6
4
  import EventEmitter from 'eventemitter3'
7
5
  import { v4 } from 'uuid'
8
6
  import { PeerDescriptor, RouteMessageWrapper } from '../../proto/packages/dht/protos/DhtRpc'
9
7
  import { RouterRpcRemote } from './RouterRpcRemote'
10
8
  import { RoutingRpcCommunicator } from '../../transport/RoutingRpcCommunicator'
11
- import { FindRpcClient, RouterRpcClient } from '../../proto/packages/dht/protos/DhtRpc.client'
12
- import { toProtoRpcClient } from '@streamr/proto-rpc'
9
+ import { RecursiveOperationRpcClient, RouterRpcClient } from '../../proto/packages/dht/protos/DhtRpc.client'
13
10
  import { Contact } from '../contact/Contact'
14
- import { FindRpcRemote } from './FindRpcRemote'
15
- import { EXISTING_CONNECTION_TIMEOUT } from '../contact/Remote'
11
+ import { RecursiveOperationRpcRemote } from '../recursive-operation/RecursiveOperationRpcRemote'
12
+ import { EXISTING_CONNECTION_TIMEOUT } from '../contact/RpcRemote'
16
13
  import { getPreviousPeer } from './getPreviousPeer'
14
+ import { DhtAddress, areEqualPeerDescriptors, getDhtAddressFromRaw, getNodeIdFromPeerDescriptor } from '../../identifiers'
15
+ import { pull } from 'lodash'
16
+ import { RoutingTable, RoutingTablesCache } from './RoutingTablesCache'
17
17
 
18
18
  const logger = new Logger(module)
19
19
 
20
20
  const MAX_FAILED_HOPS = 2
21
+ const ROUTING_TABLE_MAX_SIZE = 20
21
22
 
22
- class RemoteContact extends Contact {
23
+ export class RoutingRemoteContact extends Contact {
23
24
 
24
25
  private routerRpcRemote: RouterRpcRemote
25
- private findRpcRemote: FindRpcRemote
26
+ private recursiveOperationRpcRemote: RecursiveOperationRpcRemote
26
27
 
27
- constructor(peer: DhtNodeRpcRemote, localPeerDescriptor: PeerDescriptor, rpcCommunicator: RoutingRpcCommunicator) {
28
- super(peer.getPeerDescriptor())
28
+ constructor(peer: PeerDescriptor, localPeerDescriptor: PeerDescriptor, rpcCommunicator: RoutingRpcCommunicator) {
29
+ super(peer)
29
30
  this.routerRpcRemote = new RouterRpcRemote(
30
31
  localPeerDescriptor,
31
- peer.getPeerDescriptor(),
32
- peer.getServiceId(),
33
- toProtoRpcClient(new RouterRpcClient(rpcCommunicator.getRpcClientTransport())),
32
+ peer,
33
+ rpcCommunicator,
34
+ RouterRpcClient,
34
35
  EXISTING_CONNECTION_TIMEOUT
35
36
  )
36
- this.findRpcRemote = new FindRpcRemote(
37
+ this.recursiveOperationRpcRemote = new RecursiveOperationRpcRemote(
37
38
  localPeerDescriptor,
38
- peer.getPeerDescriptor(),
39
- peer.getServiceId(),
40
- toProtoRpcClient(new FindRpcClient(rpcCommunicator.getRpcClientTransport())),
39
+ peer,
40
+ rpcCommunicator,
41
+ RecursiveOperationRpcClient,
41
42
  EXISTING_CONNECTION_TIMEOUT
42
43
  )
43
44
  }
@@ -46,84 +47,70 @@ class RemoteContact extends Contact {
46
47
  return this.routerRpcRemote
47
48
  }
48
49
 
49
- getFindRpcRemote(): FindRpcRemote {
50
- return this.findRpcRemote
50
+ getRecursiveOperationRpcRemote(): RecursiveOperationRpcRemote {
51
+ return this.recursiveOperationRpcRemote
51
52
  }
52
53
  }
53
54
 
54
55
  export interface RoutingSessionEvents {
55
56
  // This event is emitted when a peer responds with a success ack
56
57
  // to routeMessage call
57
- routingSucceeded: (sessionId: string) => void
58
- partialSuccess: (sessionId: string) => void
59
-
58
+ routingSucceeded: () => void
59
+ partialSuccess: () => void
60
60
  // This event is emitted when all the candidates have been gone
61
61
  // through, and none of them responds with a success ack
62
- routingFailed: (sessionId: string) => void
63
- stopped: (sessionId: string) => void
62
+ routingFailed: () => void
63
+ stopped: () => void
64
64
  }
65
65
 
66
- export enum RoutingMode { ROUTE, FORWARD, FIND }
66
+ export enum RoutingMode { ROUTE, FORWARD, RECURSIVE }
67
+
68
+ interface RoutingSessionConfig {
69
+ rpcCommunicator: RoutingRpcCommunicator
70
+ localPeerDescriptor: PeerDescriptor
71
+ routedMessage: RouteMessageWrapper
72
+ connections: Map<DhtAddress, DhtNodeRpcRemote>
73
+ parallelism: number
74
+ mode: RoutingMode
75
+ excludedNodeIds: Set<DhtAddress>
76
+ routingTablesCache: RoutingTablesCache
77
+ }
67
78
 
68
79
  export class RoutingSession extends EventEmitter<RoutingSessionEvents> {
69
80
 
70
81
  public readonly sessionId = v4()
71
- private readonly rpcCommunicator: RoutingRpcCommunicator
72
- private ongoingRequests: Set<PeerIDKey> = new Set()
73
- private contactList: SortedContactList<RemoteContact>
74
- private readonly localPeerDescriptor: PeerDescriptor
75
- private readonly messageToRoute: RouteMessageWrapper
76
- private connections: Map<PeerIDKey, DhtNodeRpcRemote>
77
- private readonly parallelism: number
82
+ private ongoingRequests: Set<DhtAddress> = new Set()
83
+ private contactedPeers: Set<DhtAddress> = new Set()
78
84
  private failedHopCounter = 0
79
85
  private successfulHopCounter = 0
80
- private readonly mode: RoutingMode = RoutingMode.ROUTE
81
86
  private stopped = false
87
+ private readonly config: RoutingSessionConfig
82
88
 
83
- constructor(
84
- rpcCommunicator: RoutingRpcCommunicator,
85
- localPeerDescriptor: PeerDescriptor,
86
- messageToRoute: RouteMessageWrapper,
87
- connections: Map<PeerIDKey, DhtNodeRpcRemote>,
88
- parallelism: number,
89
- mode: RoutingMode = RoutingMode.ROUTE,
90
- excludedPeerIDs?: PeerID[]
91
- ) {
89
+ constructor(config: RoutingSessionConfig) {
92
90
  super()
93
- this.rpcCommunicator = rpcCommunicator
94
- this.localPeerDescriptor = localPeerDescriptor
95
- this.messageToRoute = messageToRoute
96
- this.connections = connections
97
- this.parallelism = parallelism
98
- this.mode = mode
99
- const previousPeer = getPreviousPeer(messageToRoute)
100
- const previousId = previousPeer ? PeerID.fromValue(previousPeer.kademliaId) : undefined
101
- this.contactList = new SortedContactList(
102
- PeerID.fromValue(this.messageToRoute.destinationPeer!.kademliaId),
103
- 10000,
104
- undefined,
105
- true,
106
- previousId,
107
- excludedPeerIDs
108
- )
91
+ this.config = config
109
92
  }
110
93
 
111
- private onRequestFailed(peerId: PeerID) {
94
+ private onRequestFailed(nodeId: DhtAddress) {
112
95
  logger.trace('onRequestFailed() sessionId: ' + this.sessionId)
113
96
  if (this.stopped) {
114
97
  return
115
98
  }
116
- if (this.ongoingRequests.has(peerId.toKey())) {
117
- this.ongoingRequests.delete(peerId.toKey())
99
+ if (this.ongoingRequests.has(nodeId)) {
100
+ this.ongoingRequests.delete(nodeId)
101
+ }
102
+ this.deleteParallelRootIfSource(nodeId)
103
+ this.failedHopCounter += 1
104
+ if (this.failedHopCounter >= MAX_FAILED_HOPS) {
105
+ logger.trace(`Stopping routing after ${MAX_FAILED_HOPS} failed attempts for sessionId: ${this.sessionId}`)
106
+ this.emitFailure()
107
+ return
118
108
  }
119
- const contacts = this.findMoreContacts()
109
+ const contacts = this.updateAndGetRoutablePeers()
120
110
  if (contacts.length === 0 && this.ongoingRequests.size === 0) {
121
111
  logger.trace('routing failed, emitting routingFailed sessionId: ' + this.sessionId)
122
- // TODO should call this.stop() so that we do cleanup? (after the emitFailure call)
123
- this.stopped = true
124
112
  this.emitFailure()
125
113
  } else {
126
- this.failedHopCounter += 1
127
114
  logger.trace('routing failed, retrying to route sessionId: ' + this.sessionId + ' failedHopCounter: ' + this.failedHopCounter)
128
115
  this.sendMoreRequests(contacts)
129
116
  }
@@ -131,9 +118,9 @@ export class RoutingSession extends EventEmitter<RoutingSessionEvents> {
131
118
 
132
119
  private emitFailure() {
133
120
  if (this.successfulHopCounter >= 1) {
134
- this.emit('partialSuccess', this.sessionId)
121
+ this.emit('partialSuccess')
135
122
  } else {
136
- this.emit('routingFailed', this.sessionId)
123
+ this.emit('routingFailed')
137
124
  }
138
125
  }
139
126
 
@@ -143,44 +130,65 @@ export class RoutingSession extends EventEmitter<RoutingSessionEvents> {
143
130
  return
144
131
  }
145
132
  this.successfulHopCounter += 1
146
- const contacts = this.findMoreContacts()
147
- if (this.successfulHopCounter >= this.parallelism || contacts.length === 0) {
148
- // TODO should call this.stop() so that we do cleanup? (after the routingSucceeded call)
149
- this.stopped = true
150
- this.emit('routingSucceeded', this.sessionId)
133
+ if (this.successfulHopCounter >= this.config.parallelism) {
134
+ this.emit('routingSucceeded')
135
+ return
136
+ }
137
+ const contacts = this.updateAndGetRoutablePeers()
138
+ if (contacts.length === 0) {
139
+ this.emit('routingSucceeded')
151
140
  } else if (contacts.length > 0 && this.ongoingRequests.size === 0) {
152
141
  this.sendMoreRequests(contacts)
153
142
  }
154
143
  }
155
144
 
156
- private async sendRouteMessageRequest(contact: RemoteContact): Promise<boolean> {
145
+ private async sendRouteMessageRequest(contact: RoutingRemoteContact): Promise<boolean> {
157
146
  if (this.stopped) {
158
147
  return false
159
148
  }
160
149
  const msg = {
161
- ...this.messageToRoute,
162
- routingPath: this.messageToRoute.routingPath.concat([this.localPeerDescriptor])
150
+ ...this.config.routedMessage,
151
+ routingPath: this.config.routedMessage.routingPath.concat([this.config.localPeerDescriptor])
163
152
  }
164
- if (this.mode === RoutingMode.FORWARD) {
153
+ if (this.config.mode === RoutingMode.FORWARD) {
165
154
  return contact.getRouterRpcRemote().forwardMessage(msg)
166
- } else if (this.mode === RoutingMode.FIND) {
167
- return contact.getFindRpcRemote().routeFindRequest(msg)
155
+ } else if (this.config.mode === RoutingMode.RECURSIVE) {
156
+ return contact.getRecursiveOperationRpcRemote().routeRequest(msg)
168
157
  } else {
169
158
  return contact.getRouterRpcRemote().routeMessage(msg)
170
159
  }
171
160
  }
172
161
 
173
- findMoreContacts(): RemoteContact[] {
174
- logger.trace('findMoreContacts() sessionId: ' + this.sessionId)
175
- // the contents of the connections might have changed between the rounds
176
- // addContacts() will only add new contacts that were not there yet
177
- const contacts = Array.from(this.connections.values())
178
- .map((peer) => new RemoteContact(peer, this.localPeerDescriptor, this.rpcCommunicator))
179
- this.contactList.addContacts(contacts)
180
- return this.contactList.getUncontactedContacts(this.parallelism)
162
+ updateAndGetRoutablePeers(): RoutingRemoteContact[] {
163
+ logger.trace('getRoutablePeers() sessionId: ' + this.sessionId)
164
+ const previousPeer = getPreviousPeer(this.config.routedMessage)
165
+ const previousId = previousPeer ? getNodeIdFromPeerDescriptor(previousPeer) : undefined
166
+ const targetId = getDhtAddressFromRaw(this.config.routedMessage.target)
167
+ let routingTable: RoutingTable
168
+ if (this.config.routingTablesCache.has(targetId, previousId)) {
169
+ routingTable = this.config.routingTablesCache.get(targetId, previousId)!
170
+ } else {
171
+ routingTable = new SortedContactList<RoutingRemoteContact>({
172
+ referenceId: getDhtAddressFromRaw(this.config.routedMessage.target),
173
+ maxSize: ROUTING_TABLE_MAX_SIZE,
174
+ allowToContainReferenceId: true,
175
+ nodeIdDistanceLimit: previousId,
176
+ emitEvents: false
177
+ })
178
+ const contacts = Array.from(this.config.connections.values())
179
+ .map((peer) => new RoutingRemoteContact(
180
+ peer.getPeerDescriptor(),
181
+ this.config.localPeerDescriptor,
182
+ this.config.rpcCommunicator
183
+ ))
184
+ routingTable.addContacts(contacts)
185
+ this.config.routingTablesCache.set(targetId, routingTable, previousId)
186
+ }
187
+ return routingTable.getAllContacts()
188
+ .filter((contact) => !this.contactedPeers.has(contact.getNodeId()) && !this.config.excludedNodeIds.has(contact.getNodeId()))
181
189
  }
182
190
 
183
- sendMoreRequests(uncontacted: RemoteContact[]): void {
191
+ sendMoreRequests(uncontacted: RoutingRemoteContact[]): void {
184
192
  logger.trace('sendMoreRequests() sessionId: ' + this.sessionId)
185
193
  if (this.stopped) {
186
194
  return
@@ -189,24 +197,20 @@ export class RoutingSession extends EventEmitter<RoutingSessionEvents> {
189
197
  this.emitFailure()
190
198
  return
191
199
  }
192
- if (this.failedHopCounter >= MAX_FAILED_HOPS) {
193
- logger.trace(`Stopping routing after ${MAX_FAILED_HOPS} failed attempts for sessionId: ${this.sessionId}`)
194
- this.emitFailure()
195
- return
196
- }
197
- while ((this.ongoingRequests.size < this.parallelism) && (uncontacted.length > 0) && !this.stopped) {
200
+ while ((this.ongoingRequests.size < this.config.parallelism) && (uncontacted.length > 0) && !this.stopped) {
198
201
  const nextPeer = uncontacted.shift()
199
202
  // eslint-disable-next-line max-len
200
203
  logger.trace(`Sending routeMessage request to contact: ${getNodeIdFromPeerDescriptor(nextPeer!.getPeerDescriptor())} (sessionId=${this.sessionId})`)
201
- this.contactList.setContacted(nextPeer!.getPeerId())
202
- this.ongoingRequests.add(nextPeer!.getPeerId().toKey())
204
+ this.contactedPeers.add(nextPeer!.getNodeId())
205
+ this.ongoingRequests.add(nextPeer!.getNodeId())
206
+ this.addParallelRootIfSource(nextPeer!.getNodeId())
203
207
  setImmediate(async () => {
204
208
  try {
205
209
  const succeeded = await this.sendRouteMessageRequest(nextPeer!)
206
210
  if (succeeded) {
207
211
  this.onRequestSucceeded()
208
212
  } else {
209
- this.onRequestFailed(nextPeer!.getPeerId())
213
+ this.onRequestFailed(nextPeer!.getNodeId())
210
214
  }
211
215
  } catch (e) {
212
216
  logger.debug('Unable to route message ', { error: e })
@@ -217,10 +221,27 @@ export class RoutingSession extends EventEmitter<RoutingSessionEvents> {
217
221
  }
218
222
  }
219
223
 
224
+ private addParallelRootIfSource(nodeId: DhtAddress) {
225
+ if (
226
+ this.config.mode === RoutingMode.RECURSIVE
227
+ && areEqualPeerDescriptors(this.config.localPeerDescriptor, this.config.routedMessage.sourcePeer!)
228
+ ) {
229
+ this.config.routedMessage.parallelRootNodeIds.push(nodeId)
230
+ }
231
+ }
232
+
233
+ private deleteParallelRootIfSource(nodeId: DhtAddress) {
234
+ if (
235
+ this.config.mode === RoutingMode.RECURSIVE
236
+ && areEqualPeerDescriptors(this.config.localPeerDescriptor, this.config.routedMessage.sourcePeer!)
237
+ ) {
238
+ pull(this.config.routedMessage.parallelRootNodeIds, nodeId)
239
+ }
240
+ }
241
+
220
242
  public stop(): void {
221
243
  this.stopped = true
222
- this.contactList.stop()
223
- this.emit('stopped', this.sessionId)
244
+ this.emit('stopped')
224
245
  this.removeAllListeners()
225
246
  }
226
247
  }
@@ -0,0 +1,58 @@
1
+ import { DhtAddress } from '../../identifiers'
2
+ import { SortedContactList } from '../contact/SortedContactList'
3
+ import { RoutingRemoteContact } from './RoutingSession'
4
+ import { LRUCache } from 'lru-cache'
5
+
6
+ type RoutingTableID = string
7
+ export type RoutingTable = Pick<SortedContactList<RoutingRemoteContact>, 'getAllContacts' | 'addContacts' | 'addContact' | 'removeContact' | 'stop'>
8
+
9
+ const createRoutingTableId = (targetId: DhtAddress, previousId?: DhtAddress): RoutingTableID => {
10
+ return targetId + (previousId ? previousId : '')
11
+ }
12
+
13
+ const DEFAULT_LRU_OPTIONS = {
14
+ max: 1000,
15
+ maxAge: 15 * 1000
16
+ }
17
+
18
+ /**
19
+ * RoutingTablesCache is a cache for routing tables.
20
+ * It is used to store the routing tables for a specific targetId and previousId.
21
+ * Storing the previousId is important as it is used as a minimum distance for the contacts in the table.
22
+ * Calculating a RoutingTable from scratch is an O(n log n) operation (n = number of connections of a node)
23
+ * However,
24
+ * - Adding a contact to a RoutingTable is an O(log n) operation.
25
+ * - Deleting a contact from a RoutingTable is an O(1) operation.
26
+ * Thus, holding the most frequently used routing tables in memory to be updated on
27
+ * connections and disconnections is hugely beneficial in terms of performance.
28
+ */
29
+
30
+ export class RoutingTablesCache {
31
+
32
+ private readonly tables: LRUCache<RoutingTableID, RoutingTable> = new LRUCache(DEFAULT_LRU_OPTIONS)
33
+
34
+ get(targetId: DhtAddress, previousId?: DhtAddress): RoutingTable | undefined {
35
+ return this.tables.get(createRoutingTableId(targetId, previousId))
36
+ }
37
+
38
+ set(targetId: DhtAddress, table: RoutingTable, previousId?: DhtAddress): void {
39
+ this.tables.set(createRoutingTableId(targetId, previousId), table)
40
+ }
41
+
42
+ has(targetId: DhtAddress, previousId?: DhtAddress): boolean {
43
+ return this.tables.has(createRoutingTableId(targetId, previousId))
44
+ }
45
+
46
+ onNodeDisconnected(nodeId: DhtAddress): void {
47
+ this.tables.forEach((table) => table.removeContact(nodeId))
48
+ }
49
+
50
+ onNodeConnected(remote: RoutingRemoteContact): void {
51
+ this.tables.forEach((table) => table.addContact(remote))
52
+ }
53
+
54
+ reset(): void {
55
+ this.tables.forEach((table) => table.stop())
56
+ this.tables.clear()
57
+ }
58
+ }
@@ -2,5 +2,5 @@ import { last } from 'lodash'
2
2
  import { PeerDescriptor, RouteMessageWrapper } from '../../proto/packages/dht/protos/DhtRpc'
3
3
 
4
4
  export const getPreviousPeer = (routeMessage: RouteMessageWrapper): PeerDescriptor | undefined => {
5
- return last(routeMessage.routingPath!)
5
+ return last(routeMessage.routingPath)
6
6
  }
@@ -1,114 +1,84 @@
1
- import { PeerID, PeerIDKey } from '../../helpers/PeerID'
2
- import { DataEntry, PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
3
- import { keyFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
1
+ import { DataEntry } from '../../proto/packages/dht/protos/DhtRpc'
2
+ import { MapWithTtl } from '../../helpers/MapWithTtl'
3
+ import { DhtAddress, getDhtAddressFromRaw } from '../../identifiers'
4
4
 
5
- const MIN_TTL = 1 * 1000
6
- const MAX_TTL = 300 * 1000
5
+ export class LocalDataStore {
7
6
 
8
- const createTtlValue = (ttl: number): number => {
9
- if (ttl < MIN_TTL) {
10
- return MIN_TTL
11
- } else if (ttl > MAX_TTL) {
12
- return MAX_TTL
13
- } else {
14
- return ttl
15
- }
16
- }
7
+ private readonly maxTtl: number
17
8
 
18
- interface LocalDataEntry {
19
- dataEntry: DataEntry
20
- ttlTimeout: NodeJS.Timeout
21
- }
9
+ constructor(maxTtl: number) {
10
+ this.maxTtl = maxTtl
11
+ }
22
12
 
23
- export class LocalDataStore {
24
13
  // A map into which each node can store one value per data key
25
14
  // The first key is the key of the data, the second key is the
26
- // PeerID of the storer of the data
27
- private store: Map<PeerIDKey, Map<PeerIDKey, LocalDataEntry>> = new Map()
15
+ // DhtAddress of the creator of the data
16
+ private store: Map<DhtAddress, MapWithTtl<DhtAddress, DataEntry>> = new Map()
28
17
 
29
18
  public storeEntry(dataEntry: DataEntry): boolean {
30
- const publisherKey = PeerID.fromValue(dataEntry.storer!.kademliaId).toKey()
31
- const dataKey = PeerID.fromValue(dataEntry.kademliaId).toKey()
32
-
33
- if (!this.store.has(dataKey)) {
34
- this.store.set(dataKey, new Map())
19
+ const key = getDhtAddressFromRaw(dataEntry.key)
20
+ const creatorNodeId = getDhtAddressFromRaw(dataEntry.creator)
21
+ if (!this.store.has(key)) {
22
+ this.store.set(key, new MapWithTtl((e) => Math.min(e.ttl, this.maxTtl)))
35
23
  }
36
-
37
- if (this.store.get(dataKey)!.has(publisherKey)) {
38
- const storedMillis = (dataEntry.storerTime!.seconds * 1000) + (dataEntry.storerTime!.nanos / 1000000)
39
- const oldLocalEntry = this.store.get(dataKey)!.get(publisherKey)!
40
- const oldStoredMillis = (oldLocalEntry.dataEntry.storerTime!.seconds * 1000) + (oldLocalEntry.dataEntry.storerTime!.nanos / 1000000)
41
-
42
- // do nothing if old entry is newer than the one being migrated
24
+ if (this.store.get(key)!.has(creatorNodeId)) {
25
+ const storedMillis = (dataEntry.createdAt!.seconds * 1000) + (dataEntry.createdAt!.nanos / 1000000)
26
+ const oldLocalEntry = this.store.get(key)!.get(creatorNodeId)!
27
+ const oldStoredMillis = (oldLocalEntry.createdAt!.seconds * 1000) + (oldLocalEntry.createdAt!.nanos / 1000000)
28
+ // do nothing if old entry is newer than the one being replicated
43
29
  if (oldStoredMillis >= storedMillis) {
44
30
  return false
45
- } else {
46
- clearTimeout(oldLocalEntry.ttlTimeout)
47
31
  }
48
32
  }
49
- this.store.get(dataKey)!.set(publisherKey, {
50
- dataEntry,
51
- ttlTimeout: setTimeout(() => {
52
- this.deleteEntry(PeerID.fromValue(dataEntry.kademliaId), dataEntry.storer!)
53
- }, createTtlValue(dataEntry.ttl))
54
- })
33
+ this.store.get(key)!.set(creatorNodeId, dataEntry)
55
34
  return true
56
35
  }
57
36
 
58
- public markAsDeleted(id: Uint8Array, storer: PeerID): boolean {
59
- const dataKey = PeerID.fromValue(id).toKey()
60
- if (!this.store.get(dataKey)?.has(storer.toKey())) {
37
+ public markAsDeleted(key: DhtAddress, creator: DhtAddress): boolean {
38
+ const item = this.store.get(key)
39
+ if ((item === undefined) || !item.has(creator)) {
61
40
  return false
62
41
  }
63
- const storedEntry = this.store.get(dataKey)!.get(storer.toKey())
64
- storedEntry!.dataEntry.deleted = true
42
+ const storedEntry = item.get(creator)
43
+ storedEntry!.deleted = true
65
44
  return true
66
45
  }
67
46
 
68
- public getStore(): Map<PeerIDKey, Map<PeerIDKey, LocalDataEntry>> {
69
- return this.store
70
- }
71
-
72
- public getEntry(key: PeerID): Map<PeerIDKey, DataEntry> {
73
- const dataEntries = new Map<PeerIDKey, DataEntry>
74
- this.store.get(key.toKey())?.forEach((value, key) => {
75
- dataEntries.set(key, value.dataEntry)
76
- })
77
- return dataEntries
47
+ public* values(key?: DhtAddress): IterableIterator<DataEntry> {
48
+ if (key !== undefined) {
49
+ const map = this.store.get(key)
50
+ if (map !== undefined) {
51
+ yield* map.values()
52
+ }
53
+ } else {
54
+ for (const v of this.store.values()) {
55
+ yield* v.values()
56
+ }
57
+ }
78
58
  }
79
59
 
80
- public setStale(key: PeerID, storer: PeerDescriptor, stale: boolean): void {
81
- const storerKey = keyFromPeerDescriptor(storer)
82
- const storedEntry = this.store.get(key.toKey())?.get(storerKey)
83
- if (storedEntry) {
84
- storedEntry.dataEntry.stale = stale
85
- }
60
+ public keys(): IterableIterator<DhtAddress> {
61
+ return this.store.keys()
86
62
  }
87
63
 
88
- public setAllEntriesAsStale(key: PeerID): void {
89
- this.store.get(key.toKey())?.forEach((value) => {
90
- value.dataEntry.stale = true
64
+ public setAllEntriesAsStale(key: DhtAddress): void {
65
+ this.store.get(key)?.forEach((value) => {
66
+ value.stale = true
91
67
  })
92
68
  }
93
69
 
94
- public deleteEntry(key: PeerID, storer: PeerDescriptor): void {
95
- const storerKey = keyFromPeerDescriptor(storer)
96
- const storedEntry = this.store.get(key.toKey())?.get(storerKey)
70
+ public deleteEntry(key: DhtAddress, creator: DhtAddress): void {
71
+ const storedEntry = this.store.get(key)?.get(creator)
97
72
  if (storedEntry) {
98
- clearTimeout(storedEntry.ttlTimeout)
99
- this.store.get(key.toKey())?.delete(storerKey)
100
- if (this.store.get(key.toKey())?.size === 0) {
101
- this.store.delete(key.toKey())
73
+ this.store.get(key)?.delete(creator)
74
+ if (this.store.get(key)?.size() === 0) {
75
+ this.store.delete(key)
102
76
  }
103
77
  }
104
78
  }
105
79
 
106
80
  public clear(): void {
107
- this.store.forEach((value) => {
108
- value.forEach((value) => {
109
- clearTimeout(value.ttlTimeout)
110
- })
111
- })
81
+ this.store.forEach((value) => value.clear())
112
82
  this.store.clear()
113
83
  }
114
84
  }