@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,9 +1,10 @@
1
- import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
2
- import { ProtoRpcClient } from '@streamr/proto-rpc'
3
- import { DhtRpcOptions } from '../../rpc-protocol/DhtRpcOptions'
4
- import { ServiceID } from '../../types/ServiceID'
1
+ import type { ServiceInfo } from '@protobuf-ts/runtime-rpc'
2
+ import { ClassType, ClientTransport, ProtoRpcClient, RpcCommunicator, toProtoRpcClient } from '@streamr/proto-rpc'
5
3
  import { ConnectionType } from '../../connection/IConnection'
6
4
  import { expectedConnectionType } from '../../helpers/Connectivity'
5
+ import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
6
+ import { DhtRpcOptions } from '../../rpc-protocol/DhtRpcOptions'
7
+ import { DhtCallContext } from '../../rpc-protocol/DhtCallContext'
7
8
 
8
9
  // Should connect directly to the server, timeout can be low
9
10
  const WEBSOCKET_CLIENT_TIMEOUT = 5000
@@ -15,7 +16,7 @@ const WEBRTC_TIMEOUT = 15000
15
16
  // default timeout for existing connections
16
17
  export const EXISTING_CONNECTION_TIMEOUT = 5000
17
18
 
18
- const getRpcTimeout = (localPeerDescriptor: PeerDescriptor, remotePeerDescriptor: PeerDescriptor): number => {
19
+ const getTimeout = (localPeerDescriptor: PeerDescriptor, remotePeerDescriptor: PeerDescriptor): number => {
19
20
  const connectionType = expectedConnectionType(localPeerDescriptor, remotePeerDescriptor)
20
21
  if (connectionType === ConnectionType.WEBSOCKET_CLIENT) {
21
22
  return WEBSOCKET_CLIENT_TIMEOUT
@@ -27,25 +28,25 @@ const getRpcTimeout = (localPeerDescriptor: PeerDescriptor, remotePeerDescriptor
27
28
  return WEBRTC_TIMEOUT
28
29
  }
29
30
 
30
- export abstract class Remote<T> {
31
+ export abstract class RpcRemote<T extends ServiceInfo & ClassType> {
31
32
 
32
33
  private readonly localPeerDescriptor: PeerDescriptor
33
34
  private readonly remotePeerDescriptor: PeerDescriptor
34
- private readonly serviceId: ServiceID
35
35
  private readonly client: ProtoRpcClient<T>
36
- private readonly rpcTimeout?: number
36
+ private readonly timeout?: number
37
+
37
38
  constructor(
38
39
  localPeerDescriptor: PeerDescriptor,
39
40
  remotePeerDescriptor: PeerDescriptor,
40
- serviceId: ServiceID,
41
- client: ProtoRpcClient<T>,
42
- rpcTimeout?: number
41
+ rpcCommunicator: RpcCommunicator<DhtCallContext>,
42
+ // eslint-disable-next-line @typescript-eslint/prefer-function-type
43
+ clientClass: { new (clientTransport: ClientTransport): T },
44
+ timeout?: number
43
45
  ) {
44
46
  this.localPeerDescriptor = localPeerDescriptor
45
47
  this.remotePeerDescriptor = remotePeerDescriptor
46
- this.client = client
47
- this.serviceId = serviceId
48
- this.rpcTimeout = rpcTimeout
48
+ this.client = toProtoRpcClient(new clientClass(rpcCommunicator.getRpcClientTransport()))
49
+ this.timeout = timeout
49
50
  }
50
51
 
51
52
  getPeerDescriptor(): PeerDescriptor {
@@ -56,10 +57,6 @@ export abstract class Remote<T> {
56
57
  return this.localPeerDescriptor
57
58
  }
58
59
 
59
- getServiceId(): string {
60
- return this.serviceId
61
- }
62
-
63
60
  getClient(): ProtoRpcClient<T> {
64
61
  return this.client
65
62
  }
@@ -68,7 +65,7 @@ export abstract class Remote<T> {
68
65
  return {
69
66
  sourceDescriptor: this.localPeerDescriptor,
70
67
  targetDescriptor: this.remotePeerDescriptor,
71
- timeout: this.rpcTimeout ?? getRpcTimeout(this.localPeerDescriptor, this.remotePeerDescriptor),
68
+ timeout: this.timeout ?? getTimeout(this.localPeerDescriptor, this.remotePeerDescriptor),
72
69
  ...opts
73
70
  }
74
71
  }
@@ -1,69 +1,86 @@
1
- import KBucket from 'k-bucket'
2
- import { PeerID } from '../../helpers/PeerID'
3
- import { ContactList, ContactState } from './ContactList'
1
+ import { ContactState, Events } from './ContactList'
2
+ import { sortedIndexBy } from 'lodash'
3
+ import EventEmitter from 'eventemitter3'
4
+ import { getDistance } from '../PeerManager'
5
+ import { DhtAddress, getRawFromDhtAddress } from '../../identifiers'
6
+
7
+ export interface SortedContactListConfig {
8
+ referenceId: DhtAddress // all contacts in this list are in sorted by the distance to this ID
9
+ allowToContainReferenceId: boolean
10
+ // TODO could maybe optimize this by removing the flag and then we'd check whether we have
11
+ // any listeners before we emit the event
12
+ emitEvents: boolean
13
+ maxSize?: number
14
+ // if set, the list can't contain any contacts which are futher away than this limit
15
+ nodeIdDistanceLimit?: DhtAddress
16
+ // if set, the list can't contain contacts with these ids
17
+ excludedNodeIds?: Set<DhtAddress>
18
+ }
4
19
 
5
- export class SortedContactList<C extends { getPeerId: () => PeerID }> extends ContactList<C> {
20
+ export class SortedContactList<C extends { getNodeId: () => DhtAddress }> extends EventEmitter<Events<C>> {
6
21
 
7
- private allowLocalPeerId: boolean
8
- private peerIdDistanceLimit?: PeerID
9
- private excludedPeerIDs?: PeerID[]
22
+ private config: SortedContactListConfig
23
+ private contactsById: Map<DhtAddress, ContactState<C>> = new Map()
24
+ private contactIds: DhtAddress[] = []
10
25
 
11
26
  constructor(
12
- ownId: PeerID,
13
- maxSize: number,
14
- defaultContactQueryLimit?: number,
15
- allowLocalPeerId = false,
16
- peerIdDistanceLimit?: PeerID,
17
- excludedPeerIDs?: PeerID[]
27
+ config: SortedContactListConfig
18
28
  ) {
19
- super(ownId, maxSize, defaultContactQueryLimit)
29
+ super()
30
+ this.config = config
20
31
  this.compareIds = this.compareIds.bind(this)
21
- this.allowLocalPeerId = allowLocalPeerId
22
- this.peerIdDistanceLimit = peerIdDistanceLimit
23
- this.excludedPeerIDs = excludedPeerIDs
24
32
  }
25
33
 
26
- public getClosestContactId(): PeerID {
34
+ public getClosestContactId(): DhtAddress {
27
35
  return this.contactIds[0]
28
36
  }
29
37
 
30
- public getContactIds(): PeerID[] {
38
+ public getContactIds(): DhtAddress[] {
31
39
  return this.contactIds
32
40
  }
33
41
 
34
42
  public addContact(contact: C): void {
35
- if (this.excludedPeerIDs
36
- && this.excludedPeerIDs.some((peerId) => contact.getPeerId().equals(peerId))) {
43
+ const contactId = contact.getNodeId()
44
+ if (this.config.excludedNodeIds !== undefined && this.config.excludedNodeIds.has(contactId)) {
37
45
  return
38
46
  }
39
-
40
- if ((!this.allowLocalPeerId && this.ownId.equals(contact.getPeerId())) ||
41
- (this.peerIdDistanceLimit !== undefined && this.compareIds(this.peerIdDistanceLimit, contact.getPeerId()) < 0)) {
47
+ if ((!this.config.allowToContainReferenceId && (this.config.referenceId === contactId)) ||
48
+ (this.config.nodeIdDistanceLimit !== undefined && this.compareIds(this.config.nodeIdDistanceLimit, contactId) < 0)) {
42
49
  return
43
50
  }
44
- if (!this.contactsById.has(contact.getPeerId().toKey())) {
45
- if (this.contactIds.length < this.maxSize) {
46
- this.contactsById.set(contact.getPeerId().toKey(), new ContactState(contact))
47
- this.contactIds.push(contact.getPeerId())
48
- this.contactIds.sort(this.compareIds)
49
- } else if (this.compareIds(this.contactIds[this.maxSize - 1], contact.getPeerId()) > 0) {
51
+ if (!this.contactsById.has(contactId)) {
52
+ if ((this.config.maxSize === undefined) || (this.contactIds.length < this.config.maxSize)) {
53
+ this.contactsById.set(contactId, new ContactState(contact))
54
+ const index = sortedIndexBy(this.contactIds, contactId, (id: DhtAddress) => { return this.distanceToReferenceId(id) })
55
+ this.contactIds.splice(index, 0, contactId)
56
+ if (this.config.emitEvents) {
57
+ this.emit(
58
+ 'contactAdded',
59
+ contact,
60
+ this.getClosestContacts()
61
+ )
62
+ }
63
+ } else if (this.compareIds(this.contactIds[this.config.maxSize - 1], contactId) > 0) {
50
64
  const removedId = this.contactIds.pop()
51
- const removedContact = this.contactsById.get(removedId!.toKey())!.contact
52
- this.contactsById.delete(removedId!.toKey())
53
- this.contactsById.set(contact.getPeerId().toKey(), new ContactState(contact))
54
- this.contactIds.push(contact.getPeerId())
55
- this.contactIds.sort(this.compareIds)
56
- this.emit(
57
- 'contactRemoved',
58
- removedContact,
59
- this.getClosestContacts()
60
- )
65
+ const removedContact = this.contactsById.get(removedId!)!.contact
66
+ this.contactsById.delete(removedId!)
67
+ this.contactsById.set(contactId, new ContactState(contact))
68
+ const index = sortedIndexBy(this.contactIds, contactId, (id: DhtAddress) => { return this.distanceToReferenceId(id) })
69
+ this.contactIds.splice(index, 0, contactId)
70
+ if (this.config.emitEvents) {
71
+ const closestContacts = this.getClosestContacts()
72
+ this.emit(
73
+ 'contactRemoved',
74
+ removedContact,
75
+ closestContacts
76
+ )
77
+ this.emit(
78
+ 'contactAdded',
79
+ contact,
80
+ closestContacts
81
+ )
82
+ }
61
83
  }
62
- this.emit(
63
- 'newContact',
64
- contact,
65
- this.getClosestContacts()
66
- )
67
84
  }
68
85
  }
69
86
 
@@ -71,33 +88,41 @@ export class SortedContactList<C extends { getPeerId: () => PeerID }> extends Co
71
88
  contacts.forEach((contact) => this.addContact(contact))
72
89
  }
73
90
 
74
- public setContacted(contactId: PeerID): void {
75
- if (this.contactsById.has(contactId.toKey())) {
76
- this.contactsById.get(contactId.toKey())!.contacted = true
91
+ public getContact(id: DhtAddress): ContactState<C> | undefined {
92
+ return this.contactsById.get(id)
93
+ }
94
+
95
+ public setContacted(contactId: DhtAddress): void {
96
+ if (this.contactsById.has(contactId)) {
97
+ this.contactsById.get(contactId)!.contacted = true
77
98
  }
78
99
  }
79
100
 
80
- public setActive(contactId: PeerID): void {
81
- if (this.contactsById.has(contactId.toKey())) {
82
- this.contactsById.get(contactId.toKey())!.active = true
101
+ public setActive(contactId: DhtAddress): void {
102
+ if (this.contactsById.has(contactId)) {
103
+ this.contactsById.get(contactId)!.active = true
83
104
  }
84
105
  }
85
106
 
86
- public getClosestContacts(limit = this.defaultContactQueryLimit): C[] {
107
+ public getClosestContacts(limit?: number): C[] {
87
108
  const ret: C[] = []
88
109
  this.contactIds.forEach((contactId) => {
89
- const contact = this.contactsById.get(contactId.toKey())
110
+ const contact = this.contactsById.get(contactId)
90
111
  if (contact) {
91
112
  ret.push(contact.contact)
92
113
  }
93
114
  })
94
- return ret.slice(0, limit)
115
+ if (limit === undefined) {
116
+ return ret
117
+ } else {
118
+ return ret.slice(0, limit)
119
+ }
95
120
  }
96
121
 
97
122
  public getUncontactedContacts(num: number): C[] {
98
123
  const ret: C[] = []
99
124
  for (const contactId of this.contactIds) {
100
- const contact = this.contactsById.get(contactId.toKey())
125
+ const contact = this.contactsById.get(contactId)
101
126
  if (contact && !contact.contacted) {
102
127
  ret.push(contact.contact)
103
128
  if (ret.length >= num) {
@@ -111,7 +136,7 @@ export class SortedContactList<C extends { getPeerId: () => PeerID }> extends Co
111
136
  public getActiveContacts(limit?: number): C[] {
112
137
  const ret: C[] = []
113
138
  this.contactIds.forEach((contactId) => {
114
- const contact = this.contactsById.get(contactId.toKey())
139
+ const contact = this.contactsById.get(contactId)
115
140
  if (contact && contact.active) {
116
141
  ret.push(contact.contact)
117
142
  }
@@ -123,33 +148,56 @@ export class SortedContactList<C extends { getPeerId: () => PeerID }> extends Co
123
148
  }
124
149
  }
125
150
 
126
- public compareIds(id1: PeerID, id2: PeerID): number {
127
- const distance1 = KBucket.distance(this.ownId.value, id1.value)
128
- const distance2 = KBucket.distance(this.ownId.value, id2.value)
151
+ public compareIds(id1: DhtAddress, id2: DhtAddress): number {
152
+ const distance1 = this.distanceToReferenceId(id1)
153
+ const distance2 = this.distanceToReferenceId(id2)
129
154
  return distance1 - distance2
130
155
  }
131
156
 
132
- public removeContact(id: PeerID): boolean {
133
- if (this.contactsById.has(id.toKey())) {
134
- const removed = this.contactsById.get(id.toKey())!.contact
135
- const index = this.contactIds.findIndex((element) => element.equals(id))
157
+ // TODO inline this method?
158
+ private distanceToReferenceId(id: DhtAddress): number {
159
+ // TODO maybe this class should store the referenceId also as DhtAddressRaw so that we don't need to convert it here?
160
+ return getDistance(getRawFromDhtAddress(this.config.referenceId), getRawFromDhtAddress(id))
161
+ }
162
+
163
+ public removeContact(id: DhtAddress): boolean {
164
+ if (this.contactsById.has(id)) {
165
+ const removed = this.contactsById.get(id)!.contact
166
+ // TODO use sortedIndexBy?
167
+ const index = this.contactIds.findIndex((nodeId) => (nodeId === id))
136
168
  this.contactIds.splice(index, 1)
137
- this.contactsById.delete(id.toKey())
138
- this.emit(
139
- 'contactRemoved',
140
- removed,
141
- this.getClosestContacts()
142
- )
169
+ this.contactsById.delete(id)
170
+ if (this.config.emitEvents) {
171
+ this.emit(
172
+ 'contactRemoved',
173
+ removed,
174
+ this.getClosestContacts()
175
+ )
176
+ }
143
177
  return true
144
178
  }
145
179
  return false
146
180
  }
147
181
 
148
- public isActive(id: PeerID): boolean {
149
- return this.contactsById.has(id.toKey()) ? this.contactsById.get(id.toKey())!.active : false
182
+ public isActive(id: DhtAddress): boolean {
183
+ return this.contactsById.has(id) ? this.contactsById.get(id)!.active : false
150
184
  }
151
185
 
152
186
  public getAllContacts(): C[] {
153
- return this.contactIds.map((peerId) => this.contactsById.get(peerId.toKey())!.contact)
187
+ return this.contactIds.map((nodeId) => this.contactsById.get(nodeId)!.contact)
188
+ }
189
+
190
+ public getSize(): number {
191
+ return this.contactIds.length
192
+ }
193
+
194
+ public clear(): void {
195
+ this.contactsById.clear()
196
+ this.contactIds = []
197
+ }
198
+
199
+ public stop(): void {
200
+ this.removeAllListeners()
201
+ this.clear()
154
202
  }
155
203
  }
@@ -0,0 +1,62 @@
1
+ import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
2
+
3
+ // Notice: you cannot convert RingId to RingIdRaw, because
4
+ // RingId is only an approximation of the actual value.
5
+ // That is why RingIdRaw is widely used in the codebase.
6
+
7
+ export type RingIdRaw = Uint8Array & { __ringIdRaw: never }
8
+ export type RingId = number & { __ringId: never }
9
+ export type RingDistance = number & { __ringDistance: never }
10
+
11
+ export const RING_SIZE = 2 ** 120 - 1 // 2^120 - 1
12
+
13
+ const binaryToBigInt = (binary: Uint8Array): bigint => {
14
+ return binary.reduce((acc, val) => (acc << BigInt(8)) | BigInt(val), BigInt(0))
15
+ }
16
+
17
+ export const getRingIdFromRaw = (raw: RingIdRaw): RingId => Number(binaryToBigInt(raw)) as RingId
18
+
19
+ export const getRingIdRawFromPeerDescriptor = (peerDescriptor: PeerDescriptor): RingIdRaw => {
20
+ const regionAsBuffer = Buffer.alloc(4)
21
+ regionAsBuffer.writeUInt32BE(peerDescriptor.region ?? 0, 0)
22
+ const ipAsbuffer = Buffer.alloc(4)
23
+ ipAsbuffer.writeUInt32BE(peerDescriptor.ipAddress ?? 0, 0)
24
+
25
+ const uniquePartAsBuffer = Buffer.from(peerDescriptor.nodeId.subarray(peerDescriptor.nodeId.length - 7, peerDescriptor.nodeId.length))
26
+
27
+ const arr = [
28
+ regionAsBuffer,
29
+ ipAsbuffer,
30
+ uniquePartAsBuffer
31
+ ]
32
+
33
+ const buffer = Buffer.concat(arr)
34
+ return new Uint8Array(buffer) as RingIdRaw
35
+ }
36
+
37
+ export const getRingIdFromPeerDescriptor = (peerDescriptor: PeerDescriptor): RingId => {
38
+ const raw = getRingIdRawFromPeerDescriptor(peerDescriptor)
39
+ return Number(binaryToBigInt(raw)) as RingId
40
+ }
41
+
42
+ export const getLeftDistance = (referenceId: RingId, id: RingId): RingDistance =>{
43
+ const diff = Math.abs(referenceId - id)
44
+ if (referenceId > id) {
45
+ // if id is smaller than referenceId, then the distance is the difference
46
+ return diff as RingDistance
47
+ } else {
48
+ // if id is bigger than referenceId, then the distance is the ringSize - difference
49
+ return RING_SIZE - diff as RingDistance
50
+ }
51
+ }
52
+
53
+ export const getRightDistance = (referenceId: RingId, id: RingId): RingDistance => {
54
+ const diff = Math.abs(referenceId - id)
55
+ if (referenceId > id) {
56
+ // if id is smaller than referenceId, then the distance is the ringSize - difference
57
+ return RING_SIZE - diff as RingDistance
58
+ } else {
59
+ // if id is bigger than referenceId, then the distance is the difference
60
+ return diff as RingDistance
61
+ }
62
+ }
@@ -1,15 +1,10 @@
1
- import { RpcCommunicator, toProtoRpcClient } from '@streamr/proto-rpc'
2
1
  import { Logger, runAndWaitForEvents3 } from '@streamr/utils'
3
2
  import EventEmitter from 'eventemitter3'
4
- import KBucket from 'k-bucket'
5
3
  import { v4 } from 'uuid'
6
- import { PeerID } from '../../helpers/PeerID'
7
4
  import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
8
- import { DhtNodeRpcClient } from '../../proto/packages/dht/protos/DhtRpc.client'
9
- import { SortedContactList } from '../contact/SortedContactList'
5
+ import { PeerManager, getDistance } from '../PeerManager'
10
6
  import { DhtNodeRpcRemote } from '../DhtNodeRpcRemote'
11
- import { areEqualPeerDescriptors, getNodeIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
12
- import { ServiceID } from '../../types/ServiceID'
7
+ import { DhtAddress, getNodeIdFromPeerDescriptor, getRawFromDhtAddress } from '../../identifiers'
13
8
 
14
9
  const logger = new Logger(module)
15
10
 
@@ -18,53 +13,32 @@ interface DiscoverySessionEvents {
18
13
  }
19
14
 
20
15
  interface DiscoverySessionConfig {
21
- bucket: KBucket<DhtNodeRpcRemote>
22
- neighborList: SortedContactList<DhtNodeRpcRemote>
23
- targetId: Uint8Array
24
- localPeerDescriptor: PeerDescriptor
25
- serviceId: ServiceID
26
- rpcCommunicator: RpcCommunicator
16
+ targetId: DhtAddress
27
17
  parallelism: number
28
18
  noProgressLimit: number
29
- newContactListener?: (rpcRemote: DhtNodeRpcRemote) => void
30
- rpcRequestTimeout?: number
19
+ peerManager: PeerManager
20
+ // Note that contacted peers will be mutated by the DiscoverySession or other parallel sessions
21
+ contactedPeers: Set<DhtAddress>
31
22
  }
32
23
 
33
24
  export class DiscoverySession {
34
- public readonly sessionId = v4()
35
25
 
26
+ public readonly id = v4()
36
27
  private stopped = false
37
28
  private emitter = new EventEmitter<DiscoverySessionEvents>()
38
- private outgoingClosestPeersRequestsCounter = 0
39
29
  private noProgressCounter = 0
40
- private ongoingClosestPeersRequests: Set<string> = new Set()
30
+ private ongoingClosestPeersRequests: Set<DhtAddress> = new Set()
41
31
  private readonly config: DiscoverySessionConfig
42
32
 
43
33
  constructor(config: DiscoverySessionConfig) {
44
34
  this.config = config
45
35
  }
46
36
 
47
- private addNewContacts(contacts: PeerDescriptor[]): void {
37
+ private addContacts(contacts: PeerDescriptor[]): void {
48
38
  if (this.stopped) {
49
39
  return
50
40
  }
51
- contacts.forEach((contact) => {
52
- if (!areEqualPeerDescriptors(contact, this.config.localPeerDescriptor)) {
53
- const rpcRemote = new DhtNodeRpcRemote(
54
- this.config.localPeerDescriptor,
55
- contact,
56
- toProtoRpcClient(new DhtNodeRpcClient(this.config.rpcCommunicator.getRpcClientTransport())),
57
- this.config.serviceId,
58
- this.config.rpcRequestTimeout
59
- )
60
- if (this.config.newContactListener) {
61
- this.config.newContactListener(rpcRemote)
62
- }
63
- if (!this.config.neighborList.getContact(rpcRemote.getPeerId())) {
64
- this.config.neighborList.addContact(rpcRemote)
65
- }
66
- }
67
- })
41
+ this.config.peerManager.addContact(contacts)
68
42
  }
69
43
 
70
44
  private async getClosestPeersFromContact(contact: DhtNodeRpcRemote): Promise<PeerDescriptor[]> {
@@ -72,41 +46,45 @@ export class DiscoverySession {
72
46
  return []
73
47
  }
74
48
  logger.trace(`Getting closest peers from contact: ${getNodeIdFromPeerDescriptor(contact.getPeerDescriptor())}`)
75
- this.outgoingClosestPeersRequestsCounter++
76
- this.config.neighborList.setContacted(contact.getPeerId())
49
+ this.config.contactedPeers.add(contact.getNodeId())
77
50
  const returnedContacts = await contact.getClosestPeers(this.config.targetId)
78
- this.config.neighborList.setActive(contact.getPeerId())
51
+ this.config.peerManager.setContactActive(contact.getNodeId())
79
52
  return returnedContacts
80
53
  }
81
54
 
82
- private onClosestPeersRequestSucceeded(peerId: PeerID, contacts: PeerDescriptor[]) {
83
- if (!this.ongoingClosestPeersRequests.has(peerId.toKey())) {
55
+ private onClosestPeersRequestSucceeded(nodeId: DhtAddress, contacts: PeerDescriptor[]) {
56
+ if (!this.ongoingClosestPeersRequests.has(nodeId)) {
84
57
  return
85
58
  }
86
- this.ongoingClosestPeersRequests.delete(peerId.toKey())
87
- const oldClosestContact = this.config.neighborList.getClosestContactId()
88
- this.addNewContacts(contacts)
89
- if (this.config.neighborList.getClosestContactId().equals(oldClosestContact)) {
59
+ this.ongoingClosestPeersRequests.delete(nodeId)
60
+ const targetId = getRawFromDhtAddress(this.config.targetId)
61
+ const oldClosestNeighbor = this.config.peerManager.getClosestNeighborsTo(this.config.targetId, 1)[0]
62
+ const oldClosestDistance = getDistance(targetId, getRawFromDhtAddress(oldClosestNeighbor.getNodeId()))
63
+ this.addContacts(contacts)
64
+ const newClosestNeighbor = this.config.peerManager.getClosestNeighborsTo(this.config.targetId, 1)[0]
65
+ const newClosestDistance = getDistance(targetId, getRawFromDhtAddress(newClosestNeighbor.getNodeId()))
66
+ if (newClosestDistance >= oldClosestDistance) {
90
67
  this.noProgressCounter++
91
- } else {
92
- this.noProgressCounter = 0
93
68
  }
94
69
  }
95
70
 
96
71
  private onClosestPeersRequestFailed(peer: DhtNodeRpcRemote) {
97
- if (!this.ongoingClosestPeersRequests.has(peer.getPeerId().toKey())) {
72
+ if (!this.ongoingClosestPeersRequests.has(peer.getNodeId())) {
98
73
  return
99
74
  }
100
- this.ongoingClosestPeersRequests.delete(peer.getPeerId().toKey())
101
- this.config.bucket.remove(peer.getPeerId().value)
102
- this.config.neighborList.removeContact(peer.getPeerId())
75
+ this.ongoingClosestPeersRequests.delete(peer.getNodeId())
76
+ this.config.peerManager.removeContact(peer.getNodeId())
103
77
  }
104
78
 
105
79
  private findMoreContacts(): void {
106
80
  if (this.stopped) {
107
81
  return
108
82
  }
109
- const uncontacted = this.config.neighborList.getUncontactedContacts(this.config.parallelism)
83
+ const uncontacted = this.config.peerManager.getClosestContactsTo(
84
+ this.config.targetId,
85
+ this.config.parallelism,
86
+ this.config.contactedPeers
87
+ )
110
88
  if (uncontacted.length === 0 || this.noProgressCounter >= this.config.noProgressLimit) {
111
89
  this.emitter.emit('discoveryCompleted')
112
90
  this.stopped = true
@@ -116,30 +94,27 @@ export class DiscoverySession {
116
94
  if (this.ongoingClosestPeersRequests.size >= this.config.parallelism) {
117
95
  break
118
96
  }
119
- this.ongoingClosestPeersRequests.add(nextPeer.getPeerId().toKey())
97
+ this.ongoingClosestPeersRequests.add(nextPeer.getNodeId())
120
98
  // eslint-disable-next-line promise/catch-or-return
121
99
  this.getClosestPeersFromContact(nextPeer)
122
- .then((contacts) => this.onClosestPeersRequestSucceeded(nextPeer.getPeerId(), contacts))
100
+ .then((contacts) => this.onClosestPeersRequestSucceeded(nextPeer.getNodeId(), contacts))
123
101
  .catch(() => this.onClosestPeersRequestFailed(nextPeer))
124
102
  .finally(() => {
125
- this.outgoingClosestPeersRequestsCounter--
126
103
  this.findMoreContacts()
127
104
  })
128
105
  }
129
106
  }
130
107
 
131
- public async findClosestNodes(timeout: number): Promise<SortedContactList<DhtNodeRpcRemote>> {
132
- if (this.config.neighborList.getUncontactedContacts(this.config.parallelism).length === 0) {
133
- logger.trace('getUncontactedContacts length was 0 in beginning of discovery, this.neighborList.size: '
134
- + this.config.neighborList.getSize())
135
- return this.config.neighborList
108
+ public async findClosestNodes(timeout: number): Promise<void> {
109
+ if (this.config.peerManager.getContactCount(this.config.contactedPeers) === 0) {
110
+ return
136
111
  }
112
+ // TODO add abortController and signal it in stop()
137
113
  await runAndWaitForEvents3<DiscoverySessionEvents>(
138
114
  [this.findMoreContacts.bind(this)],
139
115
  [[this.emitter, 'discoveryCompleted']],
140
116
  timeout
141
117
  )
142
- return this.config.neighborList
143
118
  }
144
119
 
145
120
  public stop(): void {