@streamr/dht 100.0.0-pretestnet.6 → 100.0.0-rc.1

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 +19 -10
  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 +1 -2
  49. package/dist/src/connection/webrtc/WebrtcConnector.js +36 -32
  50. package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
  51. package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.d.ts +4 -2
  52. package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js +28 -22
  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 +17 -14
  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 +24 -12
  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 +25 -27
  254. package/src/connection/webrtc/WebrtcConnector.ts +31 -36
  255. package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +31 -25
  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,4 +1,4 @@
1
- // @generated by protobuf-ts 2.9.1 with parameter server_generic,generate_dependencies,long_type_number
1
+ // @generated by protobuf-ts 2.9.3 with parameter server_generic,generate_dependencies,long_type_number
2
2
  // @generated from protobuf file "packages/proto-rpc/protos/ProtoRpc.proto" (package "protorpc", syntax proto3)
3
3
  // tslint:disable
4
4
  import { MessageType } from "@protobuf-ts/runtime";
@@ -6,9 +6,9 @@ export class DhtCallContext extends ProtoCallContext implements DhtRpcOptions {
6
6
  // used by client
7
7
  targetDescriptor?: PeerDescriptor
8
8
  sourceDescriptor?: PeerDescriptor
9
- notification?: boolean
10
9
  clientId?: number
11
- doNotConnect?: boolean
10
+ connect?: boolean
11
+ sendIfStopped?: boolean
12
12
  //used in incoming calls
13
13
  incomingSourceDescriptor?: PeerDescriptor
14
14
  }
@@ -5,5 +5,6 @@ export interface DhtRpcOptions extends ProtoRpcOptions {
5
5
  targetDescriptor?: PeerDescriptor
6
6
  sourceDescriptor?: PeerDescriptor
7
7
  clientId?: number
8
- doNotConnect?: boolean
8
+ connect?: boolean
9
+ sendIfStopped?: boolean
9
10
  }
@@ -4,7 +4,16 @@ export interface TransportEvents {
4
4
  disconnected: (peerDescriptor: PeerDescriptor, gracefulLeave: boolean) => void
5
5
  message: (message: Message) => void
6
6
  connected: (peerDescriptor: PeerDescriptor) => void
7
+ }
8
+
9
+ export interface SendOptions {
10
+ connect: boolean
11
+ sendIfStopped: boolean
12
+ }
7
13
 
14
+ export const DEFAULT_SEND_OPTIONS = {
15
+ connect: true,
16
+ sendIfStopped: false
8
17
  }
9
18
 
10
19
  export interface ITransport {
@@ -21,8 +30,8 @@ export interface ITransport {
21
30
  off<T extends keyof TransportEvents>(eventName: T, listener: (peerDescriptor: PeerDescriptor) => void): void
22
31
  off<T extends keyof TransportEvents>(eventName: T, listener: (peerDescriptor: PeerDescriptor, gracefulLeave: boolean) => void): void
23
32
 
24
- send(msg: Message, doNotConnect?: boolean): Promise<void>
33
+ send(msg: Message, opts?: SendOptions): Promise<void>
25
34
  getLocalPeerDescriptor(): PeerDescriptor
26
- getAllConnectionPeerDescriptors(): PeerDescriptor[]
35
+ getConnections(): PeerDescriptor[]
27
36
  stop(): void | Promise<void>
28
37
  }
@@ -9,7 +9,7 @@ export class ListeningRpcCommunicator extends RoutingRpcCommunicator {
9
9
  private readonly listener: (msg: Message) => void
10
10
 
11
11
  constructor(ownServiceId: ServiceID, transport: ITransport, config?: RpcCommunicatorConfig) {
12
- super(ownServiceId, transport.send, config)
12
+ super(ownServiceId, (msg, opts) => transport.send(msg, opts), config)
13
13
  this.listener = (msg: Message) => {
14
14
  this.handleMessageFromPeer(msg)
15
15
  }
@@ -1,17 +1,18 @@
1
- import { Message, MessageType, PeerDescriptor } from '../proto/packages/dht/protos/DhtRpc'
1
+ import { Message, PeerDescriptor } from '../proto/packages/dht/protos/DhtRpc'
2
2
  import { v4 } from 'uuid'
3
3
  import { RpcCommunicator, RpcCommunicatorConfig } from '@streamr/proto-rpc'
4
4
  import { DhtCallContext } from '../rpc-protocol/DhtCallContext'
5
5
  import { RpcMessage } from '../proto/packages/proto-rpc/protos/ProtoRpc'
6
6
  import { ServiceID } from '../types/ServiceID'
7
+ import { DEFAULT_SEND_OPTIONS, SendOptions } from './ITransport'
7
8
 
8
- export class RoutingRpcCommunicator extends RpcCommunicator {
9
+ export class RoutingRpcCommunicator extends RpcCommunicator<DhtCallContext> {
9
10
  private ownServiceId: ServiceID
10
- private sendFn: (msg: Message, doNotConnect?: boolean, doNotMindStopped?: boolean) => Promise<void>
11
+ private sendFn: (msg: Message, opts: SendOptions) => Promise<void>
11
12
 
12
13
  constructor(
13
14
  ownServiceId: ServiceID,
14
- sendFn: (msg: Message, doNotConnect?: boolean) => Promise<void>,
15
+ sendFn: (msg: Message, opts: SendOptions) => Promise<void>,
15
16
  config?: RpcCommunicatorConfig
16
17
  ) {
17
18
  super(config)
@@ -34,25 +35,31 @@ export class RoutingRpcCommunicator extends RpcCommunicator {
34
35
  oneofKind: 'rpcMessage',
35
36
  rpcMessage: msg
36
37
  },
37
- messageType: MessageType.RPC,
38
38
  targetDescriptor
39
39
  }
40
40
 
41
- if (msg.header.response || callContext && callContext.doNotConnect && callContext.doNotMindStopped ) {
42
- return this.sendFn(message, true, true)
43
- } else if (msg.header.response || callContext && callContext.doNotConnect) {
44
- return this.sendFn(message, true)
45
- } else {
46
- return this.sendFn(message)
47
- }
48
-
41
+ // TODO maybe sendOptions could be a separate block inside callContext
42
+ const sendOpts = (msg.header.response !== undefined)
43
+ ? {
44
+ // typically we already have a connection, but if it has disconnected for some reason
45
+ // the receiver could have gone offline (or it is no longer a neighbor) and therefore there
46
+ // is no point in trying form a new connection
47
+ connect: false,
48
+ // TODO maybe this options could be removed?
49
+ sendIfStopped: true
50
+ } : {
51
+ connect: callContext?.connect ?? DEFAULT_SEND_OPTIONS.connect,
52
+ sendIfStopped: callContext?.sendIfStopped ?? DEFAULT_SEND_OPTIONS.sendIfStopped
53
+ }
54
+ return this.sendFn(message, sendOpts)
49
55
  })
50
56
  }
51
57
 
52
58
  public handleMessageFromPeer(message: Message): void {
53
- if (message.serviceId == this.ownServiceId && message.body.oneofKind === 'rpcMessage') {
59
+ if (message.serviceId === this.ownServiceId && message.body.oneofKind === 'rpcMessage') {
54
60
  const context = new DhtCallContext()
55
61
  context.incomingSourceDescriptor = message.sourceDescriptor
62
+ // TODO should we have some handling for this floating promise?
56
63
  this.handleIncomingMessage(message.body.rpcMessage, context)
57
64
  }
58
65
  }
@@ -2,13 +2,14 @@
2
2
 
3
3
  import KBucket from 'k-bucket'
4
4
  import { range } from 'lodash'
5
+ import { DhtAddressRaw } from '../src/identifiers'
5
6
 
6
- const compareIds = (id1: Uint8Array, id2: Uint8Array) => {
7
+ const compareIds = (id1: DhtAddressRaw, id2: DhtAddressRaw) => {
7
8
  const sorted = [id1, id2].sort()
8
9
  return KBucket.distance(sorted[0], sorted[1])
9
10
  }
10
11
 
11
- const generateIDs = (count: number): Uint8Array[] => {
12
+ const generateIDs = (count: number): DhtAddressRaw[] => {
12
13
  return range(count).map((i) => new Uint8Array([i, 1, 1]))
13
14
  }
14
15
 
@@ -1,26 +1,21 @@
1
1
  /* eslint-disable no-console */
2
2
  import { LatencyType, Simulator } from '../../src/connection/simulator/Simulator'
3
3
  import { DhtNode } from '../../src/dht/DhtNode'
4
- import { NodeType, PeerDescriptor } from '../../src/proto/packages/dht/protos/DhtRpc'
5
4
  import { createMockConnectionDhtNode } from '../utils/utils'
6
5
  import { execSync } from 'child_process'
7
6
  import fs from 'fs'
8
- import { PeerID } from '../../src/helpers/PeerID'
9
- import { getNodeIdFromPeerDescriptor, peerIdFromPeerDescriptor } from '../../src/helpers/peerIdFromPeerDescriptor'
10
7
  import { Logger, wait } from '@streamr/utils'
11
8
  import { debugVars } from '../../src/helpers/debugHelpers'
9
+ import { getDhtAddressFromRaw, getNodeIdFromPeerDescriptor } from '../../src/identifiers'
12
10
 
13
11
  const logger = new Logger(module)
14
12
 
15
13
  describe('Find correctness', () => {
16
14
  let entryPoint: DhtNode
17
15
  let nodes: DhtNode[]
18
- let entrypointDescriptor: PeerDescriptor
19
16
  const simulator = new Simulator(LatencyType.NONE)
20
17
  const NUM_NODES = 1000
21
18
 
22
- const nodeIndicesById: Record<string, number> = {}
23
-
24
19
  if (!fs.existsSync('test/data/nodeids.json')) {
25
20
  console.log('ground truth data does not exist yet, generating..')
26
21
  execSync('npm run prepare-kademlia-simulation')
@@ -31,20 +26,10 @@ describe('Find correctness', () => {
31
26
  beforeEach(async () => {
32
27
 
33
28
  nodes = []
34
- const entryPointId = '0'
35
- entryPoint = await createMockConnectionDhtNode(entryPointId, simulator, Uint8Array.from(dhtIds[0].data), undefined)
36
- nodes.push(entryPoint)
37
- nodeIndicesById[entryPoint.getNodeId().toKey()] = 0
38
- entrypointDescriptor = {
39
- kademliaId: entryPoint.getNodeId().value,
40
- type: NodeType.NODEJS
41
- }
29
+ entryPoint = await createMockConnectionDhtNode(simulator, getDhtAddressFromRaw(Uint8Array.from(dhtIds[0].data)), undefined)
42
30
 
43
31
  for (let i = 1; i < NUM_NODES; i++) {
44
- const nodeId = `${i}`
45
-
46
- const node = await createMockConnectionDhtNode(nodeId, simulator, Uint8Array.from(dhtIds[i].data), undefined)
47
- nodeIndicesById[node.getNodeId().toKey()] = i
32
+ const node = await createMockConnectionDhtNode(simulator, getDhtAddressFromRaw(Uint8Array.from(dhtIds[i].data)), undefined)
48
33
  nodes.push(node)
49
34
  }
50
35
  })
@@ -57,10 +42,10 @@ describe('Find correctness', () => {
57
42
  })
58
43
 
59
44
  it('Entrypoint can find a node from the network (exact match)', async () => {
60
- await entryPoint.joinDht([entrypointDescriptor])
45
+ await entryPoint.joinDht([entryPoint.getLocalPeerDescriptor()])
61
46
 
62
47
  await Promise.all(
63
- nodes.map((node) => node.joinDht([entrypointDescriptor]))
48
+ nodes.map((node) => node.joinDht([entryPoint.getLocalPeerDescriptor()]))
64
49
  )
65
50
 
66
51
  logger.info('waiting 120s')
@@ -71,17 +56,17 @@ describe('Find correctness', () => {
71
56
  logger.info('waiting over')
72
57
 
73
58
  nodes.forEach((node) => logger.info(getNodeIdFromPeerDescriptor(node.getLocalPeerDescriptor()) + ': connections:' +
74
- node.getNumberOfConnections() + ', kbucket: ' + node.getBucketSize()
75
- + ', localLocked: ' + node.getNumberOfLocalLockedConnections()
76
- + ', remoteLocked: ' + node.getNumberOfRemoteLockedConnections()
77
- + ', weakLocked: ' + node.getNumberOfWeakLockedConnections()))
59
+ node.getConnectionCount() + ', kbucket: ' + node.getNeighborCount()
60
+ + ', localLocked: ' + node.getLocalLockedConnectionCount()
61
+ + ', remoteLocked: ' + node.getRemoteLockedConnectionCount()
62
+ + ', weakLocked: ' + node.getWeakLockedConnectionCount()))
78
63
 
79
64
  logger.info('starting find')
80
- const kademliaIdToFind = Uint8Array.from(dhtIds[9].data)
81
- const results = await nodes[159].startFind(kademliaIdToFind)
65
+ const targetId = Uint8Array.from(dhtIds[9].data)
66
+ const closestNodes = await nodes[159].findClosestNodesFromDht(getDhtAddressFromRaw(targetId))
82
67
  logger.info('find over')
83
- expect(results.closestNodes).toBeGreaterThanOrEqual(5)
84
- expect(PeerID.fromValue(kademliaIdToFind).equals(peerIdFromPeerDescriptor(results.closestNodes[0])))
68
+ expect(closestNodes).toBeGreaterThanOrEqual(5)
69
+ expect(getDhtAddressFromRaw(targetId)).toEqual(getNodeIdFromPeerDescriptor(closestNodes[0]))
85
70
 
86
71
  }, 180000)
87
72
  })
@@ -1,21 +1,21 @@
1
1
  /* eslint-disable no-console */
2
2
  import { Simulator } from '../../src/connection/simulator/Simulator'
3
3
  import { DhtNode } from '../../src/dht/DhtNode'
4
- import { PeerID } from '../../src/helpers/PeerID'
5
- import { getNodeIdFromPeerDescriptor } from '../../src/helpers/peerIdFromPeerDescriptor'
6
- import { NodeType, PeerDescriptor } from '../../src/proto/packages/dht/protos/DhtRpc'
7
4
  import { createMockConnectionDhtNode } from '../utils/utils'
8
5
  import { execSync } from 'child_process'
9
6
  import fs from 'fs'
7
+ import { DhtAddress, getDhtAddressFromRaw, getNodeIdFromPeerDescriptor } from '../../src/identifiers'
8
+ import { Logger } from '@streamr/utils'
9
+
10
+ const logger = new Logger(module)
10
11
 
11
12
  describe('Kademlia correctness', () => {
12
13
  let entryPoint: DhtNode
13
14
  let nodes: DhtNode[]
14
- let entrypointDescriptor: PeerDescriptor
15
15
  const simulator = new Simulator()
16
- const NUM_NODES = 1000
16
+ const NUM_NODES = 200
17
17
 
18
- const nodeIndicesById: Record<string, number> = {}
18
+ const nodeIndicesById: Record<DhtAddress, number> = {}
19
19
 
20
20
  if (!fs.existsSync('test/data/nodeids.json')) {
21
21
  console.log('gound truth data does not exist yet, generating..')
@@ -27,22 +27,14 @@ describe('Kademlia correctness', () => {
27
27
  = JSON.parse(fs.readFileSync('test/data/orderedneighbors.json').toString())
28
28
 
29
29
  beforeEach(async () => {
30
-
31
30
  nodes = []
32
- const entryPointId = '0'
33
- entryPoint = await createMockConnectionDhtNode(entryPointId, simulator, Uint8Array.from(dhtIds[0].data), 8)
31
+ entryPoint = await createMockConnectionDhtNode(simulator, getDhtAddressFromRaw(Uint8Array.from(dhtIds[0].data)), 8)
34
32
  nodes.push(entryPoint)
35
- nodeIndicesById[entryPoint.getNodeId().toKey()] = 0
36
- entrypointDescriptor = {
37
- kademliaId: entryPoint.getNodeId().value,
38
- type: NodeType.NODEJS
39
- }
33
+ nodeIndicesById[entryPoint.getNodeId()] = 0
40
34
 
41
35
  for (let i = 1; i < NUM_NODES; i++) {
42
- const nodeId = `${i}`
43
-
44
- const node = await createMockConnectionDhtNode(nodeId, simulator, Uint8Array.from(dhtIds[i].data))
45
- nodeIndicesById[node.getNodeId().toKey()] = i
36
+ const node = await createMockConnectionDhtNode(simulator, getDhtAddressFromRaw(Uint8Array.from(dhtIds[i].data)))
37
+ nodeIndicesById[node.getNodeId()] = i
46
38
  nodes.push(node)
47
39
  }
48
40
  })
@@ -50,16 +42,20 @@ describe('Kademlia correctness', () => {
50
42
  afterEach(async () => {
51
43
  await Promise.all([
52
44
  entryPoint.stop(),
53
- ...nodes.map(async (node) => await node.stop())
45
+ ...nodes.map((node) => node.stop())
54
46
  ])
55
47
  })
56
48
 
57
49
  it('Can find correct neighbors', async () => {
58
- await entryPoint.joinDht([entrypointDescriptor])
50
+ await entryPoint.joinDht([entryPoint.getLocalPeerDescriptor()])
59
51
 
60
- await Promise.allSettled(
61
- nodes.map((node) => node.joinDht([entrypointDescriptor]))
62
- )
52
+ for (let i = 1; i < NUM_NODES; i++) {
53
+ // time to join the network
54
+ const startTimestamp = Date.now()
55
+ await nodes[i].joinDht([entryPoint.getLocalPeerDescriptor()])
56
+ const endTimestamp = Date.now()
57
+ logger.info('Node ' + i + ' joined in ' + (endTimestamp - startTimestamp) + ' ms')
58
+ }
63
59
 
64
60
  let minimumCorrectNeighbors = Number.MAX_SAFE_INTEGER
65
61
  let sumCorrectNeighbors = 0
@@ -72,17 +68,17 @@ describe('Kademlia correctness', () => {
72
68
  groundTruthString += groundTruth[i + ''][j].name + ','
73
69
  }
74
70
 
75
- const kademliaNeighbors = nodes[i].getClosestContacts().map((p) => PeerID.fromValue(p.kademliaId))
71
+ const kademliaNeighbors = nodes[i].getClosestContacts(8).map((p) => getNodeIdFromPeerDescriptor(p))
76
72
 
77
73
  let kadString = 'kademliaNeighbors: '
78
74
  kademliaNeighbors.forEach((neighbor) => {
79
- kadString += nodeIndicesById[neighbor.toKey()] + ','
75
+ kadString += nodeIndicesById[neighbor] + ','
80
76
  })
81
77
 
82
78
  let correctNeighbors = 0
83
79
  try {
84
80
  for (let j = 0; j < groundTruth[i + ''].length; j++) {
85
- if (groundTruth[i + ''][j].name != (nodeIndicesById[kademliaNeighbors[j].toKey()] + '')) {
81
+ if (groundTruth[i + ''][j].name != (nodeIndicesById[kademliaNeighbors[j]] + '')) {
86
82
  break
87
83
  }
88
84
  correctNeighbors++
@@ -102,7 +98,7 @@ describe('Kademlia correctness', () => {
102
98
  }
103
99
 
104
100
  if (i > 0) {
105
- sumKbucketSize += nodes[i].getBucketSize()
101
+ sumKbucketSize += nodes[i].getNeighborCount()
106
102
  sumCorrectNeighbors += correctNeighbors
107
103
  }
108
104
  }
@@ -114,5 +110,5 @@ describe('Kademlia correctness', () => {
114
110
  console.log('Minimum correct neighbors: ' + minimumCorrectNeighbors)
115
111
  console.log('Average correct neighbors: ' + avgCorrectNeighbors)
116
112
  console.log('Average Kbucket size: ' + avgKbucketSize)
117
- })
113
+ }, 120000)
118
114
  })
@@ -0,0 +1,157 @@
1
+ /* eslint-disable no-console */
2
+ import { Simulator } from '../../src/connection/simulator/Simulator'
3
+ import { DhtNode } from '../../src/dht/DhtNode'
4
+ import { createMockRingNode } from '../utils/utils'
5
+ import { execSync } from 'child_process'
6
+ import fs from 'fs'
7
+ import { DhtAddress, getDhtAddressFromRaw, getNodeIdFromPeerDescriptor } from '../../src/identifiers'
8
+ import { Logger } from '@streamr/utils'
9
+ import { getRingIdRawFromPeerDescriptor } from '../../src/dht/contact/ringIdentifiers'
10
+
11
+ const logger = new Logger(module)
12
+
13
+ describe('Ring correctness', () => {
14
+ let entryPoint: DhtNode
15
+ let nodes: DhtNode[]
16
+ const simulator = new Simulator()
17
+
18
+ const NUM_NODES = 900
19
+ const nodeIndicesById: Record<DhtAddress, number> = {}
20
+
21
+ const regions: Array<number> = []
22
+ for (let i = 0; i < (NUM_NODES + 1); i++) {
23
+ regions.push(i)
24
+ }
25
+
26
+ // Shuffle the regions
27
+ for (let i = regions.length - 1; i > 0; i--) {
28
+ const j = Math.floor(Math.random() * (i + 1))
29
+ const temp = regions[i]
30
+ regions[i] = regions[j]
31
+ regions[j] = temp
32
+ }
33
+
34
+ if (!fs.existsSync('test/data/nodeids.json')) {
35
+ console.log('gound truth data does not exist yet, generating..')
36
+ execSync('npm run prepare-kademlia-simulation')
37
+ }
38
+
39
+ const dhtIds: Array<{ type: string, data: Array<number> }> = JSON.parse(fs.readFileSync('test/data/nodeids.json').toString())
40
+ const groundTruth: Record<string, Array<{ name: string, distance: number, id: { type: string, data: Array<number> } }>>
41
+ = JSON.parse(fs.readFileSync('test/data/orderedneighbors.json').toString())
42
+
43
+ beforeEach(async () => {
44
+ jest.setTimeout(60000)
45
+ nodes = []
46
+ entryPoint = await createMockRingNode(simulator, getDhtAddressFromRaw(Uint8Array.from(dhtIds[0].data)), regions[0])
47
+ nodes.push(entryPoint)
48
+ nodeIndicesById[entryPoint.getNodeId()] = 0
49
+
50
+ for (let i = 1; i < NUM_NODES; i++) {
51
+ const node = await createMockRingNode(simulator, getDhtAddressFromRaw(Uint8Array.from(dhtIds[i].data)), regions[i + 1])
52
+ nodeIndicesById[node.getNodeId()] = i
53
+ nodes.push(node)
54
+ }
55
+ })
56
+
57
+ afterEach(async () => {
58
+ await Promise.all([
59
+ entryPoint.stop(),
60
+ ...nodes.map((node) => node.stop())
61
+ ])
62
+ })
63
+
64
+ it('Can find correct neighbors', async () => {
65
+ await entryPoint.joinDht([entryPoint.getLocalPeerDescriptor()])
66
+
67
+ //await Promise.all(
68
+ // nodes.map((node) => node.joinDht([entryPoint.getLocalPeerDescriptor()]))
69
+ //)
70
+
71
+ for (let i = 1; i < NUM_NODES; i++) {
72
+ // time to join the network
73
+ const startTimestamp = Date.now()
74
+ await nodes[i].joinDht([entryPoint.getLocalPeerDescriptor()])
75
+ const endTimestamp = Date.now()
76
+ logger.info('Node ' + i + ' joined in ' + (endTimestamp - startTimestamp) + ' ms')
77
+ const ringStartTimestamp = Date.now()
78
+ await nodes[i].joinRing()
79
+ const ringEndTimestamp = Date.now()
80
+ logger.info('Node ' + i + ' joined ring in ' + (ringEndTimestamp - ringStartTimestamp) + ' ms')
81
+
82
+ }
83
+
84
+ /*
85
+ for (let i = 1; i < NUM_NODES; i++) {
86
+ // time to join the network
87
+ const ringStartTimestamp = Date.now()
88
+ await nodes[i].joinRing()
89
+ const ringEndTimestamp = Date.now()
90
+ logger.info('Node ' + i + ' joined ring in ' + (ringEndTimestamp - ringStartTimestamp) + ' ms')
91
+ }*/
92
+
93
+ for (let i = 1; i < NUM_NODES; i++) {
94
+ logger.info('Node ' + i + ', own region: ' + nodes[i].getLocalPeerDescriptor().region
95
+ + '. Regions of closest ring peers, left: '
96
+ + nodes[i].getClosestRingContactsTo(
97
+ getRingIdRawFromPeerDescriptor(nodes[i].getLocalPeerDescriptor()), 10).left.map((p) => p.region)
98
+ + ', right: ' + nodes[i].getClosestRingContactsTo(getRingIdRawFromPeerDescriptor(
99
+ nodes[i].getLocalPeerDescriptor()), 10).right.map((p) => p.region)
100
+ )
101
+ }
102
+
103
+ let minimumCorrectNeighbors = Number.MAX_SAFE_INTEGER
104
+ let sumCorrectNeighbors = 0
105
+ let sumKbucketSize = 1
106
+
107
+ for (let i = nodes.length - 1; i >= 0; i--) {
108
+ let groundTruthString = 'groundTruthNeighb: '
109
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
110
+ for (let j = 0; j < groundTruth[i + ''].length; j++) {
111
+ groundTruthString += groundTruth[i + ''][j].name + ','
112
+ }
113
+
114
+ const kademliaNeighbors = nodes[i].getClosestContacts(8).map((p) => getNodeIdFromPeerDescriptor(p))
115
+
116
+ let kadString = 'kademliaNeighbors: '
117
+ kademliaNeighbors.forEach((neighbor) => {
118
+ kadString += nodeIndicesById[neighbor] + ','
119
+ })
120
+
121
+ let correctNeighbors = 0
122
+ try {
123
+ for (let j = 0; j < groundTruth[i + ''].length; j++) {
124
+ if (groundTruth[i + ''][j].name != (nodeIndicesById[kademliaNeighbors[j]] + '')) {
125
+ break
126
+ }
127
+ correctNeighbors++
128
+ }
129
+ } catch (e) {
130
+ console.error('Node ' + getNodeIdFromPeerDescriptor(nodes[i].getLocalPeerDescriptor()) + ' had only '
131
+ + kademliaNeighbors.length + ' kademlia neighbors')
132
+ }
133
+ if (correctNeighbors === 0) {
134
+ console.log('No correct neighbors found for node ' + i)
135
+ console.log(groundTruthString)
136
+ console.log(kadString)
137
+ }
138
+ if (correctNeighbors < minimumCorrectNeighbors) {
139
+ console.log('NEW MIN', i, correctNeighbors)
140
+ minimumCorrectNeighbors = correctNeighbors
141
+ }
142
+
143
+ if (i > 0) {
144
+ sumKbucketSize += nodes[i].getNeighborCount()
145
+ sumCorrectNeighbors += correctNeighbors
146
+ }
147
+ }
148
+
149
+ const avgKbucketSize = sumKbucketSize / (NUM_NODES - 1)
150
+ const avgCorrectNeighbors = sumCorrectNeighbors / (NUM_NODES - 1)
151
+
152
+ console.log('----------- Simulation results ------------------')
153
+ console.log('Minimum correct neighbors: ' + minimumCorrectNeighbors)
154
+ console.log('Average correct neighbors: ' + avgCorrectNeighbors)
155
+ console.log('Average Kbucket size: ' + avgKbucketSize)
156
+ }, 240000)
157
+ })
@@ -0,0 +1,151 @@
1
+ /* eslint-disable no-console */
2
+
3
+ import KBucket from 'k-bucket'
4
+ import { SortedContactList } from '../../src/dht/contact/SortedContactList'
5
+ import { DhtAddress, DhtAddressRaw, createRandomDhtAddress, getRawFromDhtAddress } from '../../src/identifiers'
6
+
7
+ const NUM_ADDS = 1000
8
+
9
+ interface Item {
10
+ id: DhtAddressRaw
11
+ vectorClock: number
12
+ getNodeId: () => DhtAddress
13
+ }
14
+
15
+ const createRandomItem = (index: number): Item => {
16
+ const nodeId = createRandomDhtAddress()
17
+ const nodeIdRaw = getRawFromDhtAddress(nodeId)
18
+ return {
19
+ getNodeId: () => nodeId,
20
+ id: nodeIdRaw,
21
+ vectorClock: index
22
+ }
23
+ }
24
+
25
+ function shuffleArray<T>(array: T[]): T[] {
26
+ for (let i = array.length - 1; i > 0; i--) {
27
+ const j = Math.floor(Math.random() * (i + 1));
28
+ [array[i], array[j]] = [array[j], array[i]]
29
+ }
30
+ return array
31
+ }
32
+
33
+ describe('SortedContactListBenchmark', () => {
34
+
35
+ it('adds ' + NUM_ADDS + ' random nodeIds', async () => {
36
+ const randomIds = []
37
+ for (let i = 0; i < NUM_ADDS; i++) {
38
+ randomIds.push(createRandomItem(i))
39
+ }
40
+ const list = new SortedContactList({
41
+ referenceId: createRandomDhtAddress(),
42
+ allowToContainReferenceId: true,
43
+ emitEvents: true
44
+ })
45
+
46
+ console.time('SortedContactList.addContact() with emitEvents=true')
47
+ for (let i = 0; i < NUM_ADDS; i++) {
48
+ list.addContact(randomIds[i])
49
+ }
50
+ console.timeEnd('SortedContactList.addContact() with emitEvents=true')
51
+
52
+ const list2 = new SortedContactList({
53
+ referenceId: createRandomDhtAddress(),
54
+ allowToContainReferenceId: true,
55
+ emitEvents: false
56
+ })
57
+
58
+ console.time('SortedContactList.addContact() with emitEvents=false')
59
+ for (let i = 0; i < NUM_ADDS; i++) {
60
+ list2.addContact(randomIds[i])
61
+ }
62
+ console.timeEnd('SortedContactList.addContact() with emitEvents=false')
63
+
64
+ const kBucket = new KBucket<Item>({ localNodeId: getRawFromDhtAddress(createRandomDhtAddress()) })
65
+ console.time('KBucket.add()')
66
+ for (let i = 0; i < NUM_ADDS; i++) {
67
+ kBucket.add(randomIds[i])
68
+ }
69
+ console.timeEnd('KBucket.add()')
70
+
71
+ console.time('kBucket toArray()')
72
+
73
+ for (let i = 0; i < NUM_ADDS; i++) {
74
+ kBucket.toArray()
75
+ }
76
+ console.timeEnd('kBucket toArray()')
77
+
78
+ console.time('kBucket closest()')
79
+ for (let i = 0; i < NUM_ADDS; i++) {
80
+ kBucket.closest(getRawFromDhtAddress(createRandomDhtAddress()), 20)
81
+ }
82
+ console.timeEnd('kBucket closest()')
83
+
84
+ console.time('SortedContactList.getClosestContacts() with emitEvents=true')
85
+ for (let i = 0; i < NUM_ADDS; i++) {
86
+ const closest = new SortedContactList<Item>({
87
+ referenceId: createRandomDhtAddress(),
88
+ allowToContainReferenceId: true,
89
+ emitEvents: true
90
+ })
91
+
92
+ const arrayFromBucket = kBucket.toArray()
93
+ arrayFromBucket.forEach((contact) => closest.addContact(contact))
94
+ closest.getClosestContacts(20)
95
+ }
96
+ console.timeEnd('SortedContactList.getClosestContacts() with emitEvents=true')
97
+
98
+ console.time('SortedContactList.getClosestContacts() with emitEvents=false')
99
+ for (let i = 0; i < NUM_ADDS; i++) {
100
+ const closest = new SortedContactList<Item>({
101
+ referenceId: createRandomDhtAddress(),
102
+ allowToContainReferenceId: true,
103
+ emitEvents: false
104
+ })
105
+
106
+ const arrayFromBucket = kBucket.toArray()
107
+ arrayFromBucket.forEach((contact) => closest.addContact(contact))
108
+ closest.getClosestContacts(20)
109
+ }
110
+ console.timeEnd('SortedContactList.getClosestContacts() with emitEvents=false')
111
+
112
+ console.time('SortedContactList.getClosestContacts() with emitEvents=false and lodash')
113
+ for (let i = 0; i < NUM_ADDS; i++) {
114
+ const closest = new SortedContactList<Item>({
115
+ referenceId: createRandomDhtAddress(),
116
+ allowToContainReferenceId: true,
117
+ emitEvents: false
118
+ })
119
+
120
+ const arrayFromBucket = kBucket.toArray()
121
+ arrayFromBucket.forEach((contact) => closest.addContact(contact))
122
+ closest.getClosestContacts(20)
123
+ }
124
+ console.timeEnd('SortedContactList.getClosestContacts() with emitEvents=false and lodash')
125
+
126
+ console.time('SortedContactList.getClosestContacts() with emitEvents=false and addContacts()')
127
+ for (let i = 0; i < NUM_ADDS; i++) {
128
+ const closest = new SortedContactList<Item>({
129
+ referenceId: createRandomDhtAddress(),
130
+ allowToContainReferenceId: true,
131
+ emitEvents: false
132
+ })
133
+
134
+ const arrayFromBucket = kBucket.toArray()
135
+ closest.addContacts(arrayFromBucket)
136
+ closest.getClosestContacts(20)
137
+ }
138
+ console.timeEnd('SortedContactList.getClosestContacts() with emitEvents=false and addContacts()')
139
+
140
+ const shuffled = shuffleArray(kBucket.toArray())
141
+ console.time('kbucket add and closest')
142
+ for (let i = 0; i < NUM_ADDS; i++) {
143
+ const bucket2 = new KBucket<Item>({ localNodeId: getRawFromDhtAddress(createRandomDhtAddress()) })
144
+
145
+ shuffled.forEach((contact) => bucket2.add(contact))
146
+ bucket2.closest(getRawFromDhtAddress(createRandomDhtAddress()), 20)
147
+ }
148
+ console.timeEnd('kbucket add and closest')
149
+
150
+ })
151
+ })