@streamr/dht 100.0.0-pretestnet.6 → 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
@@ -0,0 +1,339 @@
1
+ import {
2
+ Logger
3
+ } from '@streamr/utils'
4
+ import KBucket from 'k-bucket'
5
+ import {
6
+ PeerDescriptor
7
+ } from '../proto/packages/dht/protos/DhtRpc'
8
+ import { DhtNodeRpcRemote } from './DhtNodeRpcRemote'
9
+ import { RandomContactList } from './contact/RandomContactList'
10
+ import { SortedContactList } from './contact/SortedContactList'
11
+ import { ConnectionManager } from '../connection/ConnectionManager'
12
+ import EventEmitter from 'eventemitter3'
13
+ import { DhtAddress, DhtAddressRaw, getNodeIdFromPeerDescriptor, getRawFromDhtAddress } from '../identifiers'
14
+ import { RingContactList, RingContacts } from './contact/RingContactList'
15
+ import { RingIdRaw, getRingIdRawFromPeerDescriptor } from './contact/ringIdentifiers'
16
+ import { LockID } from '../connection/ConnectionLockHandler'
17
+
18
+ const logger = new Logger(module)
19
+
20
+ interface PeerManagerConfig {
21
+ numberOfNodesPerKBucket: number
22
+ maxContactListSize: number
23
+ peerDiscoveryQueryBatchSize: number
24
+ localNodeId: DhtAddress
25
+ localPeerDescriptor: PeerDescriptor
26
+ connectionManager: ConnectionManager
27
+ isLayer0: boolean
28
+ lockId: LockID
29
+ createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => DhtNodeRpcRemote
30
+ }
31
+
32
+ export interface PeerManagerEvents {
33
+ contactAdded: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
34
+ contactRemoved: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
35
+ randomContactAdded: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
36
+ randomContactRemoved: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
37
+ ringContactAdded: (peerDescriptor: PeerDescriptor, closestPeers: RingContacts) => void
38
+ ringContactRemoved: (peerDescriptor: PeerDescriptor, closestPeers: RingContacts) => void
39
+ kBucketEmpty: () => void
40
+ }
41
+
42
+ export const getDistance = (nodeIdOrDataKeyRaw1: DhtAddressRaw, nodeIdOrDataKeyRaw2: DhtAddressRaw): number => {
43
+ return KBucket.distance(nodeIdOrDataKeyRaw1, nodeIdOrDataKeyRaw2)
44
+ }
45
+
46
+ export class PeerManager extends EventEmitter<PeerManagerEvents> {
47
+
48
+ // Glossary:
49
+ // * 'neighbors' are the nodes that are our neighbors according to
50
+ // the protocol of the layer we are in
51
+ // * 'connections' are the nodes that are connected to this node on Layer0
52
+ // * 'contacts' are all non-unresponsive nodes that we know about
53
+
54
+ // The kademlia k-bucket
55
+ private bucket: KBucket<DhtNodeRpcRemote>
56
+ // Nodes that are connected to this node on Layer0
57
+ public readonly connections: Map<DhtAddress, DhtNodeRpcRemote> = new Map()
58
+ // All nodes that we know about
59
+ private contacts: SortedContactList<DhtNodeRpcRemote>
60
+ private randomPeers: RandomContactList<DhtNodeRpcRemote>
61
+ private ringContacts: RingContactList<DhtNodeRpcRemote>
62
+ private stopped: boolean = false
63
+ private readonly config: PeerManagerConfig
64
+
65
+ constructor(config: PeerManagerConfig) {
66
+ super()
67
+ this.config = config
68
+ this.bucket = new KBucket<DhtNodeRpcRemote>({
69
+ localNodeId: getRawFromDhtAddress(this.config.localNodeId),
70
+ numberOfNodesPerKBucket: this.config.numberOfNodesPerKBucket,
71
+ numberOfNodesToPing: this.config.numberOfNodesPerKBucket
72
+ })
73
+ this.ringContacts = new RingContactList<DhtNodeRpcRemote>(getRingIdRawFromPeerDescriptor(this.config.localPeerDescriptor), true)
74
+ this.ringContacts.on('ringContactAdded', (peerDescriptor: PeerDescriptor, closestPeers: RingContacts) => {
75
+ this.emit('ringContactAdded', peerDescriptor, closestPeers)
76
+ })
77
+ this.ringContacts.on('ringContactRemoved', (peerDescriptor: PeerDescriptor, closestPeers: RingContacts) => {
78
+ this.emit('ringContactRemoved', peerDescriptor, closestPeers)
79
+ })
80
+ this.bucket.on('ping', (oldContacts: DhtNodeRpcRemote[], newContact: DhtNodeRpcRemote) => this.onKBucketPing(oldContacts, newContact))
81
+ this.bucket.on('removed', (contact: DhtNodeRpcRemote) => this.onKBucketRemoved(getNodeIdFromPeerDescriptor(contact.getPeerDescriptor())))
82
+ this.bucket.on('added', (contact: DhtNodeRpcRemote) => this.onKBucketAdded(contact))
83
+ this.bucket.on('updated', () => {
84
+ // TODO: Update contact info to the connection manager and reconnect
85
+ })
86
+ this.contacts = new SortedContactList({
87
+ referenceId: this.config.localNodeId,
88
+ maxSize: this.config.maxContactListSize,
89
+ allowToContainReferenceId: false,
90
+ emitEvents: true
91
+ })
92
+ this.contacts.on('contactRemoved', (removedContact: DhtNodeRpcRemote, activeContacts: DhtNodeRpcRemote[]) => {
93
+ if (this.stopped) {
94
+ return
95
+ }
96
+ this.emit('contactRemoved', removedContact.getPeerDescriptor(), activeContacts.map((c) => c.getPeerDescriptor()))
97
+ this.randomPeers.addContact(this.config.createDhtNodeRpcRemote(removedContact.getPeerDescriptor()))
98
+ })
99
+ this.contacts.on('contactAdded', (contactAdded: DhtNodeRpcRemote, activeContacts: DhtNodeRpcRemote[]) =>
100
+ this.emit('contactAdded', contactAdded.getPeerDescriptor(), activeContacts.map((c) => c.getPeerDescriptor()))
101
+ )
102
+ this.randomPeers = new RandomContactList(this.config.localNodeId, this.config.maxContactListSize)
103
+ this.randomPeers.on('contactRemoved', (removedContact: DhtNodeRpcRemote, activeContacts: DhtNodeRpcRemote[]) =>
104
+ this.emit('randomContactRemoved', removedContact.getPeerDescriptor(), activeContacts.map((c) => c.getPeerDescriptor()))
105
+ )
106
+ this.randomPeers.on('contactAdded', (contactAdded: DhtNodeRpcRemote, activeContacts: DhtNodeRpcRemote[]) =>
107
+ this.emit('randomContactAdded', contactAdded.getPeerDescriptor(), activeContacts.map((c) => c.getPeerDescriptor()))
108
+ )
109
+ }
110
+
111
+ private onKBucketPing(oldContacts: DhtNodeRpcRemote[], newContact: DhtNodeRpcRemote): void {
112
+ if (this.stopped) {
113
+ return
114
+ }
115
+ const sortingList: SortedContactList<DhtNodeRpcRemote> = new SortedContactList({
116
+ referenceId: this.config.localNodeId,
117
+ maxSize: 100, // TODO use config option or named constant?
118
+ allowToContainReferenceId: false,
119
+ emitEvents: false
120
+ })
121
+ sortingList.addContacts(oldContacts)
122
+ const sortedContacts = sortingList.getAllContacts()
123
+ const removableNodeId = sortedContacts[sortedContacts.length - 1].getNodeId()
124
+ this.config.connectionManager?.weakUnlockConnection(removableNodeId, this.config.lockId)
125
+ this.bucket.remove(getRawFromDhtAddress(removableNodeId))
126
+ this.bucket.add(newContact)
127
+ }
128
+
129
+ private onKBucketRemoved(nodeId: DhtAddress): void {
130
+ if (this.stopped) {
131
+ return
132
+ }
133
+ this.config.connectionManager?.weakUnlockConnection(nodeId, this.config.lockId)
134
+ logger.trace(`Removed contact ${nodeId}`)
135
+ if (this.bucket.count() === 0) {
136
+ this.emit('kBucketEmpty')
137
+ }
138
+ }
139
+
140
+ private onKBucketAdded(contact: DhtNodeRpcRemote): void {
141
+ if (this.stopped) {
142
+ return
143
+ }
144
+ if (contact.getNodeId() !== this.config.localNodeId) {
145
+ const peerDescriptor = contact.getPeerDescriptor()
146
+ const nodeId = getNodeIdFromPeerDescriptor(peerDescriptor)
147
+ // Important to lock here, before the ping result is known
148
+ this.config.connectionManager?.weakLockConnection(nodeId, this.config.lockId)
149
+ if (this.connections.has(contact.getNodeId())) {
150
+ logger.trace(`Added new contact ${nodeId}`)
151
+ } else { // open connection by pinging
152
+ logger.trace('starting ping ' + nodeId)
153
+ contact.ping().then((result) => {
154
+ if (result) {
155
+ logger.trace(`Added new contact ${nodeId}`)
156
+ } else {
157
+ logger.trace('ping failed ' + nodeId)
158
+ this.config.connectionManager?.weakUnlockConnection(nodeId, this.config.lockId)
159
+ this.removeContact(nodeId)
160
+ this.addClosestContactToBucket()
161
+ }
162
+ return
163
+ }).catch((_e) => {
164
+ this.config.connectionManager?.weakUnlockConnection(nodeId, this.config.lockId)
165
+ this.removeContact(nodeId)
166
+ this.addClosestContactToBucket()
167
+ })
168
+ }
169
+ }
170
+ }
171
+
172
+ private addClosestContactToBucket(): void {
173
+ if (this.stopped) {
174
+ return
175
+ }
176
+ const closest = this.getClosestActiveContactNotInBucket()
177
+ if (closest) {
178
+ this.addContact([closest.getPeerDescriptor()])
179
+ }
180
+ }
181
+
182
+ private getClosestActiveContactNotInBucket(): DhtNodeRpcRemote | undefined {
183
+ for (const contactId of this.contacts.getContactIds()) {
184
+ if (!this.bucket.get(getRawFromDhtAddress(contactId)) && this.contacts.isActive(contactId)) {
185
+ return this.contacts.getContact(contactId)!.contact
186
+ }
187
+ }
188
+ return undefined
189
+ }
190
+
191
+ onContactConnected(peerDescriptor: PeerDescriptor): void {
192
+ const nodeId = getNodeIdFromPeerDescriptor(peerDescriptor)
193
+ if (nodeId === this.config.localNodeId) {
194
+ logger.error('handleConnected() to self')
195
+ }
196
+ const rpcRemote = this.config.createDhtNodeRpcRemote(peerDescriptor)
197
+ if (!this.connections.has(nodeId)) {
198
+ this.connections.set(nodeId, rpcRemote)
199
+ logger.trace('connectionschange add ' + this.connections.size)
200
+ } else {
201
+ logger.trace('new connection not set to connections, there is already a connection with the peer ID')
202
+ }
203
+ logger.trace('connected: ' + nodeId + ' ' + this.connections.size)
204
+ }
205
+
206
+ onContactDisconnected(nodeId: DhtAddress, gracefulLeave: boolean): void {
207
+ logger.trace('disconnected: ' + nodeId)
208
+ this.connections.delete(nodeId)
209
+ if (this.config.isLayer0) {
210
+ this.bucket.remove(getRawFromDhtAddress(nodeId))
211
+ if (gracefulLeave === true) {
212
+ logger.trace(nodeId + ' ' + 'onTransportDisconnected with gracefulLeave ' + gracefulLeave)
213
+ this.removeContact(nodeId)
214
+ } else {
215
+ logger.trace(nodeId + ' ' + 'onTransportDisconnected with gracefulLeave ' + gracefulLeave)
216
+ }
217
+ }
218
+ }
219
+
220
+ removeContact(nodeId: DhtAddress): void {
221
+ if (this.stopped) {
222
+ return
223
+ }
224
+ logger.trace(`Removing contact ${nodeId}`)
225
+ this.ringContacts.removeContact(this.contacts.getContact(nodeId)?.contact)
226
+ this.bucket.remove(getRawFromDhtAddress(nodeId))
227
+ this.contacts.removeContact(nodeId)
228
+ this.randomPeers.removeContact(nodeId)
229
+ }
230
+
231
+ stop(): void {
232
+ this.stopped = true
233
+ this.bucket.toArray().forEach((rpcRemote: DhtNodeRpcRemote) => {
234
+ rpcRemote.leaveNotice()
235
+ this.bucket.remove(rpcRemote.id)
236
+ })
237
+ this.bucket.removeAllListeners()
238
+ this.ringContacts.getAllContacts().forEach((rpcRemote) => {
239
+ rpcRemote.leaveNotice()
240
+ this.ringContacts.removeContact(rpcRemote)
241
+ })
242
+ this.contacts.stop()
243
+ this.randomPeers.stop()
244
+ this.connections.clear()
245
+ }
246
+
247
+ getClosestNeighborsTo(referenceId: DhtAddress, limit?: number, excludedNodeIds?: Set<DhtAddress>): DhtNodeRpcRemote[] {
248
+ const closest = new SortedContactList<DhtNodeRpcRemote>({
249
+ referenceId,
250
+ allowToContainReferenceId: true,
251
+ emitEvents: false,
252
+ excludedNodeIds
253
+ })
254
+ this.bucket.toArray().forEach((contact) => closest.addContact(contact))
255
+ return closest.getClosestContacts(limit)
256
+ }
257
+
258
+ // TODO reduce copy-paste?
259
+ getClosestContactsTo(referenceId: DhtAddress, limit?: number, excludedNodeIds?: Set<DhtAddress>): DhtNodeRpcRemote[] {
260
+ const closest = new SortedContactList<DhtNodeRpcRemote>({
261
+ referenceId,
262
+ allowToContainReferenceId: true,
263
+ emitEvents: false,
264
+ excludedNodeIds
265
+ })
266
+ this.contacts.getAllContacts().map((contact) => closest.addContact(contact))
267
+ // TODO should set the excludeSet and limit to SortedContactList constructor and remove these line
268
+ return closest.getClosestContacts(limit)
269
+ }
270
+
271
+ getClosestRingContactsTo(
272
+ ringIdRaw: RingIdRaw,
273
+ limit?: number,
274
+ excludedIds?: Set<DhtAddress>
275
+ ): { left: DhtNodeRpcRemote[], right: DhtNodeRpcRemote[] } {
276
+ const closest = new RingContactList<DhtNodeRpcRemote>(ringIdRaw, false, excludedIds)
277
+ this.contacts.getAllContacts().map((contact) => closest.addContact(contact))
278
+ this.ringContacts.getAllContacts().map((contact) => closest.addContact(contact))
279
+ return closest.getClosestContacts(limit ?? 8)
280
+ }
281
+
282
+ getContactCount(excludedNodeIds?: Set<DhtAddress>): number {
283
+ return this.contacts.getAllContacts().filter((contact) => {
284
+ if (!excludedNodeIds) {
285
+ return true
286
+ } else {
287
+ return !excludedNodeIds.has(contact.getNodeId())
288
+ }
289
+ }).length
290
+ }
291
+
292
+ getConnectionCount(): number {
293
+ return this.connections.size
294
+ }
295
+
296
+ getNeighborCount(): number {
297
+ return this.bucket.count()
298
+ }
299
+
300
+ getNeighbors(): PeerDescriptor[] {
301
+ return this.bucket.toArray().map((rpcRemote: DhtNodeRpcRemote) => rpcRemote.getPeerDescriptor())
302
+ }
303
+
304
+ setContactActive(nodeId: DhtAddress): void {
305
+ this.contacts.setActive(nodeId)
306
+ }
307
+
308
+ addContact(peerDescriptors: PeerDescriptor[], setActive?: boolean): void {
309
+ if (this.stopped) {
310
+ return
311
+ }
312
+ peerDescriptors.forEach((contact) => {
313
+ const nodeId = getNodeIdFromPeerDescriptor(contact)
314
+ if (nodeId !== this.config.localNodeId) {
315
+ logger.trace(`Adding new contact ${nodeId}`)
316
+ const remote = this.config.createDhtNodeRpcRemote(contact)
317
+ const isInBucket = (this.bucket.get(contact.nodeId) !== null)
318
+ const isInContacts = (this.contacts.getContact(nodeId) !== undefined)
319
+ const isInRingContacts = this.ringContacts.getContact(contact) !== undefined
320
+
321
+ if (isInBucket || isInContacts) {
322
+ this.randomPeers.addContact(remote)
323
+ }
324
+ if (!isInBucket) {
325
+ this.bucket.add(remote)
326
+ }
327
+ if (!isInContacts) {
328
+ this.contacts.addContact(remote)
329
+ }
330
+ if (setActive) {
331
+ this.contacts.setActive(nodeId)
332
+ }
333
+ if (!isInRingContacts) {
334
+ this.ringContacts.addContact(remote)
335
+ }
336
+ }
337
+ })
338
+ }
339
+ }
@@ -1,8 +1,8 @@
1
- import { PeerID } from '../../helpers/PeerID'
2
1
  import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
3
- import { peerIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
2
+ import { DhtAddress, getNodeIdFromPeerDescriptor } from '../../identifiers'
4
3
 
5
4
  export class Contact {
5
+
6
6
  private peerDescriptor: PeerDescriptor
7
7
 
8
8
  constructor(peerDescriptor: PeerDescriptor) {
@@ -13,7 +13,7 @@ export class Contact {
13
13
  return this.peerDescriptor
14
14
  }
15
15
 
16
- public getPeerId(): PeerID {
17
- return peerIdFromPeerDescriptor(this.peerDescriptor)
16
+ public getNodeId(): DhtAddress {
17
+ return getNodeIdFromPeerDescriptor(this.peerDescriptor)
18
18
  }
19
19
  }
@@ -1,5 +1,5 @@
1
- import { PeerID, PeerIDKey } from '../../helpers/PeerID'
2
1
  import EventEmitter from 'eventemitter3'
2
+ import { DhtAddress } from '../../identifiers'
3
3
 
4
4
  export class ContactState<C> {
5
5
  public contacted = false
@@ -13,30 +13,31 @@ export class ContactState<C> {
13
13
 
14
14
  export interface Events<C> {
15
15
  contactRemoved: (removedContact: C, closestContacts: C[]) => void
16
- newContact: (newContact: C, closestContacts: C[]) => void
16
+ contactAdded: (contactAdded: C, closestContacts: C[]) => void
17
17
  }
18
18
 
19
- export class ContactList<C extends { getPeerId: () => PeerID }> extends EventEmitter<Events<C>> {
19
+ export class ContactList<C extends { getNodeId: () => DhtAddress }> extends EventEmitter<Events<C>> {
20
20
 
21
- protected contactsById: Map<PeerIDKey, ContactState<C>> = new Map()
22
- protected contactIds: PeerID[] = []
23
- protected ownId: PeerID
21
+ protected contactsById: Map<DhtAddress, ContactState<C>> = new Map()
22
+ // TODO move this to SortedContactList
23
+ protected contactIds: DhtAddress[] = []
24
+ protected localNodeId: DhtAddress
24
25
  protected maxSize: number
25
26
  protected defaultContactQueryLimit
26
27
 
27
28
  constructor(
28
- ownId: PeerID,
29
+ localNodeId: DhtAddress,
29
30
  maxSize: number,
30
31
  defaultContactQueryLimit = 20
31
32
  ) {
32
33
  super()
33
- this.ownId = ownId
34
+ this.localNodeId = localNodeId
34
35
  this.maxSize = maxSize
35
36
  this.defaultContactQueryLimit = defaultContactQueryLimit
36
37
  }
37
38
 
38
- public getContact(id: PeerID): ContactState<C> {
39
- return this.contactsById.get(id.toKey())!
39
+ public getContact(id: DhtAddress): ContactState<C> | undefined {
40
+ return this.contactsById.get(id)
40
41
  }
41
42
 
42
43
  public getSize(): number {
@@ -1,35 +1,35 @@
1
- import { PeerID } from '../../helpers/PeerID'
1
+ import { DhtAddress } from '../../identifiers'
2
2
  import { ContactList, ContactState } from './ContactList'
3
3
 
4
- export class RandomContactList<C extends { getPeerId: () => PeerID }> extends ContactList<C> {
4
+ export class RandomContactList<C extends { getNodeId: () => DhtAddress }> extends ContactList<C> {
5
5
 
6
6
  private randomness: number
7
7
 
8
8
  constructor(
9
- ownId: PeerID,
9
+ localNodeId: DhtAddress,
10
10
  maxSize: number,
11
11
  randomness = 0.20,
12
12
  defaultContactQueryLimit?: number
13
13
  ) {
14
- super(ownId, maxSize, defaultContactQueryLimit)
14
+ super(localNodeId, maxSize, defaultContactQueryLimit)
15
15
  this.randomness = randomness
16
16
  }
17
17
 
18
18
  addContact(contact: C): void {
19
- if (this.ownId.equals(contact.getPeerId())) {
19
+ if (this.localNodeId === contact.getNodeId()) {
20
20
  return
21
21
  }
22
- if (!this.contactsById.has(contact.getPeerId().toKey())) {
22
+ if (!this.contactsById.has(contact.getNodeId())) {
23
23
  const roll = Math.random()
24
24
  if (roll < this.randomness) {
25
25
  if (this.getSize() === this.maxSize && this.getSize() > 0) {
26
26
  const toRemove = this.contactIds[0]
27
27
  this.removeContact(toRemove)
28
28
  }
29
- this.contactIds.push(contact.getPeerId())
30
- this.contactsById.set(contact.getPeerId().toKey(), new ContactState(contact))
29
+ this.contactIds.push(contact.getNodeId())
30
+ this.contactsById.set(contact.getNodeId(), new ContactState(contact))
31
31
  this.emit(
32
- 'newContact',
32
+ 'contactAdded',
33
33
  contact,
34
34
  this.getContacts()
35
35
  )
@@ -37,12 +37,12 @@ export class RandomContactList<C extends { getPeerId: () => PeerID }> extends Co
37
37
  }
38
38
  }
39
39
 
40
- removeContact(id: PeerID): boolean {
41
- if (this.contactsById.has(id.toKey())) {
42
- const removed = this.contactsById.get(id.toKey())!.contact
43
- const index = this.contactIds.findIndex((element) => element.equals(id))
40
+ removeContact(id: DhtAddress): boolean {
41
+ if (this.contactsById.has(id)) {
42
+ const removed = this.contactsById.get(id)!.contact
43
+ const index = this.contactIds.findIndex((nodeId) => (nodeId === id))
44
44
  this.contactIds.splice(index, 1)
45
- this.contactsById.delete(id.toKey())
45
+ this.contactsById.delete(id)
46
46
  this.emit('contactRemoved', removed, this.getContacts())
47
47
  return true
48
48
  }
@@ -52,7 +52,7 @@ export class RandomContactList<C extends { getPeerId: () => PeerID }> extends Co
52
52
  public getContacts(limit = this.defaultContactQueryLimit): C[] {
53
53
  const ret: C[] = []
54
54
  this.contactIds.forEach((contactId) => {
55
- const contact = this.contactsById.get(contactId.toKey())
55
+ const contact = this.contactsById.get(contactId)
56
56
  if (contact) {
57
57
  ret.push(contact.contact)
58
58
  }
@@ -0,0 +1,151 @@
1
+ import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
2
+ import { OrderedMap } from '@js-sdsl/ordered-map'
3
+ import { RingDistance, RingId, RingIdRaw, getLeftDistance, getRightDistance, getRingIdFromPeerDescriptor, getRingIdFromRaw } from './ringIdentifiers'
4
+ import { DhtAddress, getNodeIdFromPeerDescriptor } from '../../identifiers'
5
+ import EventEmitter from 'eventemitter3'
6
+
7
+ export interface RingContacts {
8
+ left: PeerDescriptor[]
9
+ right: PeerDescriptor[]
10
+ }
11
+ export interface RingContactListEvents {
12
+ ringContactAdded: (peerDescriptor: PeerDescriptor, closestPeers: RingContacts) => void
13
+ ringContactRemoved: (peerDescriptor: PeerDescriptor, closestPeers: RingContacts) => void
14
+ }
15
+ export class RingContactList<C extends { getPeerDescriptor(): PeerDescriptor }> extends EventEmitter<RingContactListEvents> {
16
+
17
+ private readonly numNeighborsPerSide = 5
18
+ private readonly referenceId: RingId
19
+ private readonly excludedIds: Set<DhtAddress>
20
+ private readonly leftNeighbors: OrderedMap<RingDistance, C>
21
+ private readonly rightNeighbors: OrderedMap<RingDistance, C>
22
+ private readonly emitEvents: boolean
23
+
24
+ constructor(rawReferenceId: RingIdRaw, emitEvents: boolean, excludedIds?: Set<DhtAddress>) {
25
+ super()
26
+ this.referenceId = getRingIdFromRaw(rawReferenceId)
27
+ this.emitEvents = emitEvents
28
+ this.excludedIds = excludedIds ?? new Set()
29
+ this.leftNeighbors = new OrderedMap<RingDistance, C>()
30
+ this.rightNeighbors = new OrderedMap<RingDistance, C>()
31
+ }
32
+
33
+ addContact(contact: C): void {
34
+ const id = getRingIdFromPeerDescriptor(contact.getPeerDescriptor())
35
+ if (id === this.referenceId || this.excludedIds.has(getNodeIdFromPeerDescriptor(contact.getPeerDescriptor()))) {
36
+ return
37
+ }
38
+ let elementAdded = false
39
+ let elementRemoved = false
40
+
41
+ const leftDistance = getLeftDistance(this.referenceId, id)
42
+ const lastLeftNeighbor = this.leftNeighbors.back()
43
+ if (lastLeftNeighbor === undefined || leftDistance < lastLeftNeighbor[0]) {
44
+ this.leftNeighbors.setElement(leftDistance, contact)
45
+ elementAdded = true
46
+ if (this.leftNeighbors.size() > this.numNeighborsPerSide) {
47
+ this.leftNeighbors.eraseElementByIterator(this.leftNeighbors.rBegin())
48
+ elementRemoved = true
49
+ }
50
+ }
51
+
52
+ const rightDistance = getRightDistance(this.referenceId, id)
53
+ const lastRightNeighbor = this.rightNeighbors.back()
54
+ if (lastRightNeighbor === undefined || rightDistance < lastRightNeighbor[0]) {
55
+ this.rightNeighbors.setElement(rightDistance, contact)
56
+ elementAdded = true
57
+ if (this.rightNeighbors.size() > this.numNeighborsPerSide) {
58
+ this.rightNeighbors.eraseElementByIterator(this.rightNeighbors.rBegin())
59
+ elementRemoved = true
60
+ }
61
+ }
62
+
63
+ if (this.emitEvents && (elementAdded || elementRemoved)) {
64
+ const closestContacts = this.getClosestContacts()
65
+ const closestDescriptors = {
66
+ left: closestContacts.left.map((c) => c.getPeerDescriptor()),
67
+ right: closestContacts.right.map((c) => c.getPeerDescriptor())
68
+ }
69
+ if (elementAdded) {
70
+ this.emit('ringContactAdded', contact.getPeerDescriptor(), closestDescriptors)
71
+ }
72
+ if (elementRemoved) {
73
+ this.emit('ringContactRemoved', contact.getPeerDescriptor(), closestDescriptors)
74
+ }
75
+ }
76
+ }
77
+
78
+ removeContact(contact?: C): void {
79
+ if (contact === undefined) {
80
+ return
81
+ }
82
+
83
+ const id = getRingIdFromPeerDescriptor(contact.getPeerDescriptor())
84
+ const leftDistance = getLeftDistance(this.referenceId, id)
85
+ const rightDistance = getRightDistance(this.referenceId, id)
86
+
87
+ let elementRemoved = false
88
+ if (this.leftNeighbors.eraseElementByKey(leftDistance)) {
89
+ elementRemoved = true
90
+ }
91
+ if (this.rightNeighbors.eraseElementByKey(rightDistance)) {
92
+ elementRemoved = true
93
+ }
94
+
95
+ if (this.emitEvents && elementRemoved) {
96
+ const closestContacts = this.getClosestContacts()
97
+ const closestDescriptors = { left: closestContacts.left.map((c) => c.getPeerDescriptor()),
98
+ right: closestContacts.right.map((c) => c.getPeerDescriptor()) }
99
+ this.emit('ringContactRemoved', contact.getPeerDescriptor(), closestDescriptors)
100
+ }
101
+ }
102
+
103
+ getContact(peerDescriptor: PeerDescriptor): C | undefined {
104
+ const id = getRingIdFromPeerDescriptor(peerDescriptor)
105
+ const leftDistance = getLeftDistance(this.referenceId, id)
106
+ const rightDistance = getRightDistance(this.referenceId, id)
107
+ if (this.leftNeighbors.getElementByKey(leftDistance)) {
108
+ return this.leftNeighbors.getElementByKey(leftDistance)
109
+ }
110
+ if (this.rightNeighbors.getElementByKey(rightDistance)) {
111
+ return this.rightNeighbors.getElementByKey(rightDistance)
112
+ }
113
+ return undefined
114
+ }
115
+
116
+ getClosestContacts(limitPerSide?: number): { left: C[], right: C[] } {
117
+ const leftContacts: C[] = []
118
+ const rightContacts: C[] = []
119
+
120
+ let leftCount = 0
121
+ for (const item of this.leftNeighbors) {
122
+ if (limitPerSide != undefined && leftCount >= limitPerSide) {
123
+ break
124
+ }
125
+ leftContacts.push(item[1])
126
+ leftCount++
127
+ }
128
+
129
+ let rightCount = 0
130
+ for (const item of this.rightNeighbors) {
131
+ if (limitPerSide != undefined && rightCount >= limitPerSide) {
132
+ break
133
+ }
134
+ rightContacts.push(item[1])
135
+ rightCount++
136
+ }
137
+
138
+ return { left: leftContacts, right: rightContacts }
139
+ }
140
+
141
+ getAllContacts(): C[] {
142
+ const ret: C[] = []
143
+ for (const item of this.leftNeighbors) {
144
+ ret.push(item[1])
145
+ }
146
+ for (const item of this.rightNeighbors) {
147
+ ret.push(item[1])
148
+ }
149
+ return ret
150
+ }
151
+ }