@streamr/dht 102.0.0-beta.0 → 102.0.0-beta.2

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 (264) hide show
  1. package/dist/generated/packages/dht/protos/DhtRpc.d.ts +16 -8
  2. package/dist/generated/packages/dht/protos/DhtRpc.js +7 -5
  3. package/dist/generated/packages/dht/protos/DhtRpc.js.map +1 -1
  4. package/dist/package.json +15 -16
  5. package/dist/src/connection/ConnectionManager.js +18 -8
  6. package/dist/src/connection/ConnectionManager.js.map +1 -1
  7. package/dist/src/connection/Handshaker.d.ts +1 -1
  8. package/dist/src/connection/Handshaker.js +9 -5
  9. package/dist/src/connection/Handshaker.js.map +1 -1
  10. package/dist/src/connection/ManagedConnection.js +17 -7
  11. package/dist/src/connection/ManagedConnection.js.map +1 -1
  12. package/dist/src/connection/connectivityChecker.js +20 -10
  13. package/dist/src/connection/connectivityChecker.js.map +1 -1
  14. package/dist/src/connection/connectivityRequestHandler.js +3 -3
  15. package/dist/src/connection/connectivityRequestHandler.js.map +1 -1
  16. package/dist/src/connection/simulator/Simulator.js +3 -2
  17. package/dist/src/connection/simulator/Simulator.js.map +1 -1
  18. package/dist/src/connection/simulator/pings.d.ts +1 -1
  19. package/dist/src/connection/simulator/pings.js +3 -3
  20. package/dist/src/connection/simulator/pings.js.map +1 -1
  21. package/dist/src/connection/webrtc/NodeWebrtcConnection.js +0 -2
  22. package/dist/src/connection/webrtc/NodeWebrtcConnection.js.map +1 -1
  23. package/dist/src/connection/webrtc/WebrtcConnector.js +19 -9
  24. package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
  25. package/dist/src/connection/webrtc/iceServerAsString.js +1 -2
  26. package/dist/src/connection/webrtc/iceServerAsString.js.map +1 -1
  27. package/dist/src/connection/websocket/AbstractWebsocketClientConnection.d.ts +0 -2
  28. package/dist/src/connection/websocket/WebsocketClientConnectorRpcLocal.d.ts +0 -1
  29. package/dist/src/connection/websocket/WebsocketServerConnection.d.ts +0 -1
  30. package/dist/src/connection/websocket/WebsocketServerConnector.js +28 -18
  31. package/dist/src/connection/websocket/WebsocketServerConnector.js.map +1 -1
  32. package/dist/src/dht/DhtNode.d.ts +1 -0
  33. package/dist/src/dht/DhtNode.js +3 -2
  34. package/dist/src/dht/DhtNode.js.map +1 -1
  35. package/dist/src/dht/DhtNodeRpcLocal.d.ts +1 -1
  36. package/dist/src/dht/PeerManager.d.ts +2 -1
  37. package/dist/src/dht/PeerManager.js +2 -1
  38. package/dist/src/dht/PeerManager.js.map +1 -1
  39. package/dist/src/dht/contact/SortedContactList.js +1 -1
  40. package/dist/src/dht/contact/SortedContactList.js.map +1 -1
  41. package/dist/src/dht/discovery/DiscoverySession.d.ts +0 -1
  42. package/dist/src/dht/discovery/PeerDiscovery.d.ts +0 -1
  43. package/dist/src/dht/discovery/RingDiscoverySession.d.ts +0 -1
  44. package/dist/src/dht/recursive-operation/RecursiveOperationManager.d.ts +2 -2
  45. package/dist/src/dht/routing/DuplicateDetector.js.map +1 -1
  46. package/dist/src/dht/routing/RoutingSession.js +2 -2
  47. package/dist/src/dht/routing/RoutingSession.js.map +1 -1
  48. package/dist/src/dht/routing/RoutingTablesCache.d.ts +1 -1
  49. package/dist/src/dht/store/LocalDataStore.js +1 -1
  50. package/dist/src/dht/store/LocalDataStore.js.map +1 -1
  51. package/dist/src/dht/store/StoreManager.d.ts +1 -1
  52. package/dist/src/dht/store/StoreRpcLocal.d.ts +1 -1
  53. package/dist/src/helpers/AddressTools.js +2 -3
  54. package/dist/src/helpers/AddressTools.js.map +1 -1
  55. package/dist/src/helpers/debugHelpers.js +2 -2
  56. package/dist/src/helpers/debugHelpers.js.map +1 -1
  57. package/dist/src/helpers/protoClasses.d.ts +1 -1
  58. package/dist/src/helpers/protoClasses.js.map +1 -1
  59. package/dist/src/helpers/protoToString.js +1 -2
  60. package/dist/src/helpers/protoToString.js.map +1 -1
  61. package/dist/src/helpers/version.d.ts +1 -1
  62. package/dist/src/helpers/version.js +4 -4
  63. package/dist/src/helpers/version.js.map +1 -1
  64. package/eslint.config.mjs +12 -0
  65. package/jest.config.ts +12 -0
  66. package/package.json +15 -16
  67. package/protos/DhtRpc.proto +6 -4
  68. package/.eslintignore +0 -5
  69. package/.eslintrc +0 -3
  70. package/generated/google/protobuf/any.ts +0 -326
  71. package/generated/google/protobuf/empty.ts +0 -81
  72. package/generated/google/protobuf/timestamp.ts +0 -287
  73. package/generated/packages/dht/protos/DhtRpc.client.ts +0 -419
  74. package/generated/packages/dht/protos/DhtRpc.server.ts +0 -165
  75. package/generated/packages/dht/protos/DhtRpc.ts +0 -1266
  76. package/generated/packages/proto-rpc/protos/ProtoRpc.ts +0 -108
  77. package/jest.config.js +0 -5
  78. package/src/connection/Connection.ts +0 -28
  79. package/src/connection/ConnectionLockRpcLocal.ts +0 -78
  80. package/src/connection/ConnectionLockRpcRemote.ts +0 -64
  81. package/src/connection/ConnectionLockStates.ts +0 -131
  82. package/src/connection/ConnectionManager.ts +0 -661
  83. package/src/connection/ConnectionsView.ts +0 -8
  84. package/src/connection/ConnectorFacade.ts +0 -217
  85. package/src/connection/Handshaker.ts +0 -205
  86. package/src/connection/IConnection.ts +0 -40
  87. package/src/connection/ManagedConnection.ts +0 -113
  88. package/src/connection/OutputBuffer.ts +0 -28
  89. package/src/connection/PendingConnection.ts +0 -68
  90. package/src/connection/connectivityChecker.ts +0 -108
  91. package/src/connection/connectivityRequestHandler.ts +0 -116
  92. package/src/connection/simulator/Simulator.ts +0 -368
  93. package/src/connection/simulator/SimulatorConnection.ts +0 -137
  94. package/src/connection/simulator/SimulatorConnector.ts +0 -98
  95. package/src/connection/simulator/SimulatorTransport.ts +0 -15
  96. package/src/connection/simulator/pings.ts +0 -42
  97. package/src/connection/webrtc/BrowserWebrtcConnection.ts +0 -242
  98. package/src/connection/webrtc/IWebrtcConnection.ts +0 -24
  99. package/src/connection/webrtc/NodeWebrtcConnection.ts +0 -247
  100. package/src/connection/webrtc/WebrtcConnector.ts +0 -234
  101. package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +0 -108
  102. package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +0 -60
  103. package/src/connection/webrtc/iceServerAsString.ts +0 -15
  104. package/src/connection/websocket/AbstractWebsocketClientConnection.ts +0 -122
  105. package/src/connection/websocket/AutoCertifierClientFacade.ts +0 -89
  106. package/src/connection/websocket/BrowserWebsocketClientConnection.ts +0 -44
  107. package/src/connection/websocket/NodeWebsocketClientConnection.ts +0 -39
  108. package/src/connection/websocket/WebsocketClientConnector.ts +0 -119
  109. package/src/connection/websocket/WebsocketClientConnectorRpcLocal.ts +0 -38
  110. package/src/connection/websocket/WebsocketClientConnectorRpcRemote.ts +0 -19
  111. package/src/connection/websocket/WebsocketServer.ts +0 -164
  112. package/src/connection/websocket/WebsocketServerConnection.ts +0 -109
  113. package/src/connection/websocket/WebsocketServerConnector.ts +0 -286
  114. package/src/dht/DhtNode.ts +0 -678
  115. package/src/dht/DhtNodeRpcLocal.ts +0 -84
  116. package/src/dht/DhtNodeRpcRemote.ts +0 -107
  117. package/src/dht/ExternalApiRpcLocal.ts +0 -58
  118. package/src/dht/ExternalApiRpcRemote.ts +0 -41
  119. package/src/dht/PeerManager.ts +0 -303
  120. package/src/dht/contact/Contact.ts +0 -19
  121. package/src/dht/contact/ContactList.ts +0 -43
  122. package/src/dht/contact/RandomContactList.ts +0 -56
  123. package/src/dht/contact/RingContactList.ts +0 -143
  124. package/src/dht/contact/RpcRemote.ts +0 -72
  125. package/src/dht/contact/SortedContactList.ts +0 -173
  126. package/src/dht/contact/getClosestNodes.ts +0 -24
  127. package/src/dht/contact/ringIdentifiers.ts +0 -62
  128. package/src/dht/discovery/DiscoverySession.ts +0 -129
  129. package/src/dht/discovery/PeerDiscovery.ts +0 -244
  130. package/src/dht/discovery/RingDiscoverySession.ts +0 -148
  131. package/src/dht/recursive-operation/RecursiveOperationManager.ts +0 -251
  132. package/src/dht/recursive-operation/RecursiveOperationRpcLocal.ts +0 -34
  133. package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +0 -43
  134. package/src/dht/recursive-operation/RecursiveOperationSession.ts +0 -231
  135. package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +0 -35
  136. package/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.ts +0 -30
  137. package/src/dht/routing/DuplicateDetector.ts +0 -34
  138. package/src/dht/routing/Router.ts +0 -246
  139. package/src/dht/routing/RouterRpcLocal.ts +0 -78
  140. package/src/dht/routing/RouterRpcRemote.ts +0 -80
  141. package/src/dht/routing/RoutingSession.ts +0 -243
  142. package/src/dht/routing/RoutingTablesCache.ts +0 -60
  143. package/src/dht/routing/getPreviousPeer.ts +0 -6
  144. package/src/dht/store/LocalDataStore.ts +0 -84
  145. package/src/dht/store/StoreManager.ts +0 -170
  146. package/src/dht/store/StoreRpcLocal.ts +0 -89
  147. package/src/dht/store/StoreRpcRemote.ts +0 -32
  148. package/src/exports.ts +0 -33
  149. package/src/helpers/AddressTools.ts +0 -28
  150. package/src/helpers/Connectivity.ts +0 -19
  151. package/src/helpers/browser/isBrowserEnvironment.ts +0 -1
  152. package/src/helpers/browser/isBrowserEnvironment_override.ts +0 -3
  153. package/src/helpers/createPeerDescriptor.ts +0 -57
  154. package/src/helpers/createPeerDescriptorSignaturePayload.ts +0 -28
  155. package/src/helpers/debugHelpers.ts +0 -9
  156. package/src/helpers/errors.ts +0 -49
  157. package/src/helpers/offering.ts +0 -15
  158. package/src/helpers/protoClasses.ts +0 -57
  159. package/src/helpers/protoToString.ts +0 -21
  160. package/src/helpers/version.ts +0 -32
  161. package/src/identifiers.ts +0 -29
  162. package/src/rpc-protocol/DhtCallContext.ts +0 -14
  163. package/src/rpc-protocol/DhtRpcOptions.ts +0 -10
  164. package/src/transport/ITransport.ts +0 -37
  165. package/src/transport/ListeningRpcCommunicator.ts +0 -32
  166. package/src/transport/RoutingRpcCommunicator.ts +0 -66
  167. package/src/types/ServiceID.ts +0 -1
  168. package/src/types/textencoding.d.ts +0 -6
  169. package/test/benchmark/Find.test.ts +0 -72
  170. package/test/benchmark/KademliaCorrectness.test.ts +0 -114
  171. package/test/benchmark/RingCorrectness.test.ts +0 -157
  172. package/test/benchmark/SortedContactListBenchmark.test.ts +0 -108
  173. package/test/benchmark/WebsocketServerMemoryLeak.test.ts +0 -41
  174. package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +0 -71
  175. package/test/end-to-end/GeoIpLayer0.test.ts +0 -55
  176. package/test/end-to-end/Layer0-Layer1.test.ts +0 -93
  177. package/test/end-to-end/Layer0.test.ts +0 -76
  178. package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +0 -110
  179. package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +0 -137
  180. package/test/end-to-end/Layer0Webrtc.test.ts +0 -85
  181. package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +0 -82
  182. package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +0 -76
  183. package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +0 -52
  184. package/test/end-to-end/WebsocketConnectionRequest.test.ts +0 -69
  185. package/test/end-to-end/memory-leak.test.ts +0 -80
  186. package/test/integration/ConnectionLocking.test.ts +0 -182
  187. package/test/integration/ConnectionManager.test.ts +0 -528
  188. package/test/integration/ConnectivityChecking.test.ts +0 -53
  189. package/test/integration/DhtJoinPeerDiscovery.test.ts +0 -49
  190. package/test/integration/DhtNode.test.ts +0 -66
  191. package/test/integration/DhtNodeExternalAPI.test.ts +0 -48
  192. package/test/integration/DhtNodeRpcRemote.test.ts +0 -66
  193. package/test/integration/DhtRpc.test.ts +0 -121
  194. package/test/integration/Find.test.ts +0 -45
  195. package/test/integration/GeoIpConnectivityChecking.test.ts +0 -72
  196. package/test/integration/Layer1-scale.test.ts +0 -189
  197. package/test/integration/Mock-Layer1-Layer0.test.ts +0 -85
  198. package/test/integration/MultipleEntryPointJoining.test.ts +0 -105
  199. package/test/integration/ReplicateData.test.ts +0 -104
  200. package/test/integration/RouteMessage.test.ts +0 -230
  201. package/test/integration/RouterRpcRemote.test.ts +0 -77
  202. package/test/integration/SimultaneousConnections.test.ts +0 -316
  203. package/test/integration/Store.test.ts +0 -85
  204. package/test/integration/StoreAndDelete.test.ts +0 -77
  205. package/test/integration/StoreOnDhtWithThreeNodes.test.ts +0 -59
  206. package/test/integration/StoreOnDhtWithTwoNodes.test.ts +0 -51
  207. package/test/integration/StoreRpcRemote.test.ts +0 -54
  208. package/test/integration/WebrtcConnectionManagement.test.ts +0 -219
  209. package/test/integration/WebrtcConnectorRpc.test.ts +0 -125
  210. package/test/integration/Websocket.test.ts +0 -65
  211. package/test/integration/WebsocketClientConnectorRpc.test.ts +0 -69
  212. package/test/integration/WebsocketConnectionManagement.test.ts +0 -191
  213. package/test/integration/rpc-connections-over-webrtc.test.ts +0 -158
  214. package/test/kademlia-simulation/data/nodeids.json +0 -13002
  215. package/test/kademlia-simulation/data/orderedneighbors.json +0 -1001
  216. package/test/types/global.d.ts +0 -1
  217. package/test/unit/AddressTools.test.ts +0 -44
  218. package/test/unit/AutoCertifierClientFacade.test.ts +0 -58
  219. package/test/unit/ConnectionManager.test.ts +0 -65
  220. package/test/unit/ConnectivityHelpers.test.ts +0 -61
  221. package/test/unit/DiscoverySession.test.ts +0 -87
  222. package/test/unit/DuplicateDetector.test.ts +0 -31
  223. package/test/unit/Handshaker.test.ts +0 -169
  224. package/test/unit/ListeningRpcCommunicator.test.ts +0 -52
  225. package/test/unit/LocalDataStore.test.ts +0 -108
  226. package/test/unit/ManagedConnection.test.ts +0 -58
  227. package/test/unit/PeerManager.test.ts +0 -93
  228. package/test/unit/PendingConnection.test.ts +0 -57
  229. package/test/unit/ProtobufMessage.test.ts +0 -21
  230. package/test/unit/RandomContactList.test.ts +0 -58
  231. package/test/unit/RecursiveOperationManager.test.ts +0 -161
  232. package/test/unit/RecursiveOperationSession.test.ts +0 -68
  233. package/test/unit/Router.test.ts +0 -137
  234. package/test/unit/RoutingSession.test.ts +0 -79
  235. package/test/unit/SortedContactList.test.ts +0 -115
  236. package/test/unit/StoreManager.test.ts +0 -146
  237. package/test/unit/StoreRpcLocal.test.ts +0 -167
  238. package/test/unit/WebrtcConnection.test.ts +0 -29
  239. package/test/unit/WebrtcConnector.test.ts +0 -56
  240. package/test/unit/WebsocketClientConnector.test.ts +0 -101
  241. package/test/unit/WebsocketServer.test.ts +0 -66
  242. package/test/unit/WebsocketServerConnector.test.ts +0 -102
  243. package/test/unit/connectivityRequestHandler.test.ts +0 -104
  244. package/test/unit/createPeerDescriptor.test.ts +0 -69
  245. package/test/unit/customMatchers.test.ts +0 -16
  246. package/test/unit/getClosestNodes.test.ts +0 -30
  247. package/test/unit/version.test.ts +0 -18
  248. package/test/unit/webrtcReplaceInternalIpWithExternalIp.test.ts +0 -18
  249. package/test/utils/FakeConnectorFacade.ts +0 -41
  250. package/test/utils/FakeRpcCommunicator.ts +0 -23
  251. package/test/utils/FakeTransport.ts +0 -79
  252. package/test/utils/customMatchers.ts +0 -71
  253. package/test/utils/mock/MockConnection.ts +0 -26
  254. package/test/utils/mock/MockConnectionsView.ts +0 -18
  255. package/test/utils/mock/MockRouter.ts +0 -62
  256. package/test/utils/mock/MockRpcCommunicator.ts +0 -7
  257. package/test/utils/mock/MockTransport.ts +0 -26
  258. package/test/utils/mock/mockDataEntry.ts +0 -38
  259. package/test/utils/topology.ts +0 -80
  260. package/test/utils/utils.ts +0 -268
  261. package/tsconfig.browser.json +0 -17
  262. package/tsconfig.jest.json +0 -25
  263. package/tsconfig.json +0 -3
  264. package/tsconfig.node.json +0 -24
@@ -1,56 +0,0 @@
1
- import { DhtAddress } from '../../identifiers'
2
- import { ContactList } from './ContactList'
3
-
4
- export class RandomContactList<C extends { getNodeId: () => DhtAddress }> extends ContactList<C> {
5
-
6
- private randomness: number
7
-
8
- constructor(
9
- localNodeId: DhtAddress,
10
- maxSize: number,
11
- randomness = 0.20
12
- ) {
13
- super(localNodeId, maxSize)
14
- this.randomness = randomness
15
- }
16
-
17
- addContact(contact: C): void {
18
- if (this.localNodeId === contact.getNodeId()) {
19
- return
20
- }
21
- if (!this.contactsById.has(contact.getNodeId())) {
22
- const roll = Math.random()
23
- if (roll < this.randomness) {
24
- if (this.getSize() === this.maxSize && this.getSize() > 0) {
25
- const toRemove = this.contactIds[0]
26
- this.removeContact(toRemove)
27
- }
28
- this.contactIds.push(contact.getNodeId())
29
- this.contactsById.set(contact.getNodeId(), contact)
30
- this.emit(
31
- 'contactAdded',
32
- contact
33
- )
34
- }
35
- }
36
- }
37
-
38
- removeContact(id: DhtAddress): boolean {
39
- if (this.contactsById.has(id)) {
40
- const removed = this.contactsById.get(id)!
41
- const index = this.contactIds.findIndex((nodeId) => (nodeId === id))
42
- this.contactIds.splice(index, 1)
43
- this.contactsById.delete(id)
44
- this.emit('contactRemoved', removed)
45
- return true
46
- }
47
- return false
48
- }
49
-
50
- public getContacts(limit?: number): C[] {
51
- const items = (limit === undefined)
52
- ? this.contactIds
53
- : this.contactIds.slice(0, Math.max(limit, 0))
54
- return items.map((contactId) => this.contactsById.get(contactId)!)
55
- }
56
- }
@@ -1,143 +0,0 @@
1
- import { PeerDescriptor } from '../../../generated/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, toNodeId } from '../../identifiers'
5
- import EventEmitter from 'eventemitter3'
6
- import { Events } from './ContactList'
7
-
8
- export interface RingContacts {
9
- left: PeerDescriptor[]
10
- right: PeerDescriptor[]
11
- }
12
-
13
- export class RingContactList<C extends { getPeerDescriptor(): PeerDescriptor }> extends EventEmitter<Events<C>> {
14
-
15
- private readonly numNeighborsPerSide = 5
16
- private readonly referenceId: RingId
17
- private readonly excludedIds: Set<DhtAddress>
18
- private readonly leftNeighbors: OrderedMap<RingDistance, C>
19
- private readonly rightNeighbors: OrderedMap<RingDistance, C>
20
-
21
- constructor(rawReferenceId: RingIdRaw, excludedIds?: Set<DhtAddress>) {
22
- super()
23
- this.referenceId = getRingIdFromRaw(rawReferenceId)
24
- this.excludedIds = excludedIds ?? new Set()
25
- this.leftNeighbors = new OrderedMap<RingDistance, C>()
26
- this.rightNeighbors = new OrderedMap<RingDistance, C>()
27
- }
28
-
29
- addContact(contact: C): void {
30
- const id = getRingIdFromPeerDescriptor(contact.getPeerDescriptor())
31
- if (id === this.referenceId || this.excludedIds.has(toNodeId(contact.getPeerDescriptor()))) {
32
- return
33
- }
34
- let elementAdded = false
35
- let elementRemoved = false
36
-
37
- const leftDistance = getLeftDistance(this.referenceId, id)
38
- const lastLeftNeighbor = this.leftNeighbors.back()
39
- if (lastLeftNeighbor === undefined || leftDistance < lastLeftNeighbor[0]) {
40
- this.leftNeighbors.setElement(leftDistance, contact)
41
- elementAdded = true
42
- if (this.leftNeighbors.size() > this.numNeighborsPerSide) {
43
- this.leftNeighbors.eraseElementByIterator(this.leftNeighbors.rBegin())
44
- elementRemoved = true
45
- }
46
- }
47
-
48
- const rightDistance = getRightDistance(this.referenceId, id)
49
- const lastRightNeighbor = this.rightNeighbors.back()
50
- if (lastRightNeighbor === undefined || rightDistance < lastRightNeighbor[0]) {
51
- this.rightNeighbors.setElement(rightDistance, contact)
52
- elementAdded = true
53
- if (this.rightNeighbors.size() > this.numNeighborsPerSide) {
54
- this.rightNeighbors.eraseElementByIterator(this.rightNeighbors.rBegin())
55
- elementRemoved = true
56
- }
57
- }
58
-
59
- if (this.hasEventListeners() && (elementAdded || elementRemoved)) {
60
- if (elementAdded) {
61
- this.emit('contactAdded', contact)
62
- }
63
- if (elementRemoved) {
64
- this.emit('contactRemoved', contact)
65
- }
66
- }
67
- }
68
-
69
- removeContact(contact?: C): void {
70
- if (contact === undefined) {
71
- return
72
- }
73
-
74
- const id = getRingIdFromPeerDescriptor(contact.getPeerDescriptor())
75
- const leftDistance = getLeftDistance(this.referenceId, id)
76
- const rightDistance = getRightDistance(this.referenceId, id)
77
-
78
- let elementRemoved = false
79
- if (this.leftNeighbors.eraseElementByKey(leftDistance)) {
80
- elementRemoved = true
81
- }
82
- if (this.rightNeighbors.eraseElementByKey(rightDistance)) {
83
- elementRemoved = true
84
- }
85
-
86
- if (this.hasEventListeners() && elementRemoved) {
87
- this.emit('contactRemoved', contact)
88
- }
89
- }
90
-
91
- getContact(peerDescriptor: PeerDescriptor): C | undefined {
92
- const id = getRingIdFromPeerDescriptor(peerDescriptor)
93
- const leftDistance = getLeftDistance(this.referenceId, id)
94
- const rightDistance = getRightDistance(this.referenceId, id)
95
- if (this.leftNeighbors.getElementByKey(leftDistance)) {
96
- return this.leftNeighbors.getElementByKey(leftDistance)
97
- }
98
- if (this.rightNeighbors.getElementByKey(rightDistance)) {
99
- return this.rightNeighbors.getElementByKey(rightDistance)
100
- }
101
- return undefined
102
- }
103
-
104
- getClosestContacts(limitPerSide?: number): { left: C[], right: C[] } {
105
- const leftContacts: C[] = []
106
- const rightContacts: C[] = []
107
-
108
- let leftCount = 0
109
- for (const item of this.leftNeighbors) {
110
- if (limitPerSide != undefined && leftCount >= limitPerSide) {
111
- break
112
- }
113
- leftContacts.push(item[1])
114
- leftCount++
115
- }
116
-
117
- let rightCount = 0
118
- for (const item of this.rightNeighbors) {
119
- if (limitPerSide != undefined && rightCount >= limitPerSide) {
120
- break
121
- }
122
- rightContacts.push(item[1])
123
- rightCount++
124
- }
125
-
126
- return { left: leftContacts, right: rightContacts }
127
- }
128
-
129
- getAllContacts(): C[] {
130
- const ret: C[] = []
131
- for (const item of this.leftNeighbors) {
132
- ret.push(item[1])
133
- }
134
- for (const item of this.rightNeighbors) {
135
- ret.push(item[1])
136
- }
137
- return ret
138
- }
139
-
140
- private hasEventListeners(): boolean {
141
- return this.eventNames().length > 0
142
- }
143
- }
@@ -1,72 +0,0 @@
1
- import type { ServiceInfo } from '@protobuf-ts/runtime-rpc'
2
- import { ClassType, ClientTransport, ProtoRpcClient, RpcCommunicator, toProtoRpcClient } from '@streamr/proto-rpc'
3
- import { ConnectionType } from '../../connection/IConnection'
4
- import { expectedConnectionType } from '../../helpers/Connectivity'
5
- import { PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc'
6
- import { DhtRpcOptions } from '../../rpc-protocol/DhtRpcOptions'
7
- import { DhtCallContext } from '../../rpc-protocol/DhtCallContext'
8
-
9
- // Should connect directly to the server, timeout can be low
10
- const WEBSOCKET_CLIENT_TIMEOUT = 5000
11
- // Requires a WebsocketConnectionRequest to be routed to the client before the connection can be opened
12
- // takes a little bit longer than WEBSOCKET_CLIENT
13
- const WEBSOCKET_SERVER_TIMEOUT = 7500
14
- // WebRTC connections require lots of signalling to open and might take a longer time.
15
- const WEBRTC_TIMEOUT = 10000
16
- // default timeout for existing connections
17
- export const EXISTING_CONNECTION_TIMEOUT = 5000
18
-
19
- const getTimeout = (localPeerDescriptor: PeerDescriptor, remotePeerDescriptor: PeerDescriptor): number => {
20
- const connectionType = expectedConnectionType(localPeerDescriptor, remotePeerDescriptor)
21
- if (connectionType === ConnectionType.WEBSOCKET_CLIENT) {
22
- return WEBSOCKET_CLIENT_TIMEOUT
23
- } else if (connectionType === ConnectionType.WEBSOCKET_SERVER) {
24
- return WEBSOCKET_SERVER_TIMEOUT
25
- } else if (connectionType === ConnectionType.WEBRTC) {
26
- return WEBRTC_TIMEOUT
27
- }
28
- return WEBRTC_TIMEOUT
29
- }
30
-
31
- export abstract class RpcRemote<T extends ServiceInfo & ClassType> {
32
-
33
- private readonly localPeerDescriptor: PeerDescriptor
34
- private readonly remotePeerDescriptor: PeerDescriptor
35
- private readonly client: ProtoRpcClient<T>
36
- private readonly timeout?: number
37
-
38
- constructor(
39
- localPeerDescriptor: PeerDescriptor,
40
- remotePeerDescriptor: PeerDescriptor,
41
- rpcCommunicator: RpcCommunicator<DhtCallContext>,
42
- // eslint-disable-next-line @typescript-eslint/prefer-function-type
43
- clientClass: { new (clientTransport: ClientTransport): T },
44
- timeout?: number
45
- ) {
46
- this.localPeerDescriptor = localPeerDescriptor
47
- this.remotePeerDescriptor = remotePeerDescriptor
48
- this.client = toProtoRpcClient(new clientClass(rpcCommunicator.getRpcClientTransport()))
49
- this.timeout = timeout
50
- }
51
-
52
- getPeerDescriptor(): PeerDescriptor {
53
- return this.remotePeerDescriptor
54
- }
55
-
56
- getLocalPeerDescriptor(): PeerDescriptor {
57
- return this.localPeerDescriptor
58
- }
59
-
60
- getClient(): ProtoRpcClient<T> {
61
- return this.client
62
- }
63
-
64
- formDhtRpcOptions(opts?: Omit<DhtRpcOptions, 'sourceDescriptor' | 'targetDescriptor'>): DhtRpcOptions {
65
- return {
66
- sourceDescriptor: this.localPeerDescriptor,
67
- targetDescriptor: this.remotePeerDescriptor,
68
- timeout: this.timeout ?? getTimeout(this.localPeerDescriptor, this.remotePeerDescriptor),
69
- ...opts
70
- }
71
- }
72
- }
@@ -1,173 +0,0 @@
1
- import { Events } from './ContactList'
2
- import { sortedIndexBy } from 'lodash'
3
- import EventEmitter from 'eventemitter3'
4
- import { getDistance } from '../PeerManager'
5
- import { DhtAddress, toDhtAddressRaw } from '../../identifiers'
6
-
7
- // add other getters in the future if needed
8
- export type ReadonlySortedContactList<C extends { getNodeId: () => DhtAddress }> =
9
- Pick<SortedContactList<C>, 'getClosestContacts' | 'getAllContactsInUndefinedOrder'>
10
-
11
- export interface SortedContactListOptions {
12
- referenceId: DhtAddress // all contacts in this list are in sorted by the distance to this ID
13
- allowToContainReferenceId: boolean
14
- maxSize?: number
15
- // if set, the list can't contain any contacts which are futher away than this limit
16
- nodeIdDistanceLimit?: DhtAddress
17
- // if set, the list can't contain contacts with these ids
18
- excludedNodeIds?: Set<DhtAddress>
19
- }
20
-
21
- export class SortedContactList<C extends { getNodeId: () => DhtAddress }> extends EventEmitter<Events<C>> {
22
-
23
- private options: SortedContactListOptions
24
- private contactsById: Map<DhtAddress, C> = new Map()
25
- private contactIds: DhtAddress[] = []
26
-
27
- constructor(
28
- options: SortedContactListOptions
29
- ) {
30
- super()
31
- this.options = options
32
- this.compareIds = this.compareIds.bind(this)
33
- }
34
-
35
- public getClosestContactId(): DhtAddress {
36
- return this.contactIds[0]
37
- }
38
-
39
- public getContactIds(): DhtAddress[] {
40
- return this.contactIds
41
- }
42
-
43
- public addContact(contact: C): void {
44
- const contactId = contact.getNodeId()
45
- if (this.options.excludedNodeIds !== undefined && this.options.excludedNodeIds.has(contactId)) {
46
- return
47
- }
48
- if ((!this.options.allowToContainReferenceId && (this.options.referenceId === contactId)) ||
49
- (this.options.nodeIdDistanceLimit !== undefined && this.compareIds(this.options.nodeIdDistanceLimit, contactId) < 0)) {
50
- return
51
- }
52
- if (!this.contactsById.has(contactId)) {
53
- if ((this.options.maxSize === undefined) || (this.contactIds.length < this.options.maxSize)) {
54
- this.contactsById.set(contactId, contact)
55
- const index = sortedIndexBy(this.contactIds, contactId, (id: DhtAddress) => { return this.distanceToReferenceId(id) })
56
- this.contactIds.splice(index, 0, contactId)
57
- if (this.hasEventListeners()) {
58
- this.emit(
59
- 'contactAdded',
60
- contact
61
- )
62
- }
63
- } else if (this.compareIds(this.contactIds[this.options.maxSize - 1], contactId) > 0) {
64
- const removedId = this.contactIds.pop()
65
- const removedContact = this.contactsById.get(removedId!)!
66
- this.contactsById.delete(removedId!)
67
- this.contactsById.set(contactId, contact)
68
- const index = sortedIndexBy(this.contactIds, contactId, (id: DhtAddress) => { return this.distanceToReferenceId(id) })
69
- this.contactIds.splice(index, 0, contactId)
70
- if (this.hasEventListeners()) {
71
- this.emit(
72
- 'contactRemoved',
73
- removedContact
74
- )
75
- this.emit(
76
- 'contactAdded',
77
- contact
78
- )
79
- }
80
- }
81
- }
82
- }
83
-
84
- public addContacts(contacts: C[]): void {
85
- contacts.forEach((contact) => this.addContact(contact))
86
- }
87
-
88
- public getContact(id: DhtAddress): C | undefined {
89
- return this.contactsById.get(id)
90
- }
91
-
92
- has(id: DhtAddress): boolean {
93
- return this.contactsById.has(id)
94
- }
95
-
96
- /*
97
- * Closest first then others in ascending distance order
98
- */
99
- public getClosestContacts(limit?: number): C[] {
100
- const limitedContactIds = (limit === undefined) ? this.contactIds : this.contactIds.slice(0, Math.max(limit, 0))
101
- return limitedContactIds.map((nodeId) => this.contactsById.get(nodeId)!)
102
- }
103
-
104
- /*
105
- * Furthest first then others in descending distance order
106
- */
107
- getFurthestContacts(limit?: number): C[] {
108
- const ret = [...this.getClosestContacts()].reverse()
109
- return (limit === undefined)
110
- ? ret
111
- : ret.slice(0, Math.max(limit, 0))
112
- }
113
-
114
- public compareIds(id1: DhtAddress, id2: DhtAddress): number {
115
- const distance1 = this.distanceToReferenceId(id1)
116
- const distance2 = this.distanceToReferenceId(id2)
117
- return distance1 - distance2
118
- }
119
-
120
- // TODO inline this method?
121
- private distanceToReferenceId(id: DhtAddress): number {
122
- // TODO maybe this class should store the referenceId also as DhtAddressRaw so that we don't need to convert it here?
123
- return getDistance(toDhtAddressRaw(this.options.referenceId), toDhtAddressRaw(id))
124
- }
125
-
126
- public removeContact(id: DhtAddress): boolean {
127
- if (this.contactsById.has(id)) {
128
- const removed = this.contactsById.get(id)!
129
- // TODO use sortedIndexBy?
130
- const index = this.contactIds.findIndex((nodeId) => (nodeId === id))
131
- this.contactIds.splice(index, 1)
132
- this.contactsById.delete(id)
133
- if (this.hasEventListeners()) {
134
- this.emit(
135
- 'contactRemoved',
136
- removed
137
- )
138
- }
139
- return true
140
- }
141
- return false
142
- }
143
-
144
- public getAllContactsInUndefinedOrder(): Iterable<C> {
145
- return this.contactsById.values()
146
- }
147
-
148
- public getSize(excludedNodeIds?: Set<DhtAddress>): number {
149
- let excludedCount = 0
150
- if (excludedNodeIds !== undefined) {
151
- for (const nodeId of excludedNodeIds) {
152
- if (this.has(nodeId)) {
153
- excludedCount++
154
- }
155
- }
156
- }
157
- return this.contactIds.length - excludedCount
158
- }
159
-
160
- public clear(): void {
161
- this.contactsById.clear()
162
- this.contactIds = []
163
- }
164
-
165
- public stop(): void {
166
- this.removeAllListeners()
167
- this.clear()
168
- }
169
-
170
- private hasEventListeners(): boolean {
171
- return this.eventNames().length > 0
172
- }
173
- }
@@ -1,24 +0,0 @@
1
- import { PeerDescriptor } from '../../exports'
2
- import { DhtAddress } from '../../identifiers'
3
- import { Contact } from './Contact'
4
- import { SortedContactList } from './SortedContactList'
5
-
6
- export const getClosestNodes = (
7
- referenceId: DhtAddress,
8
- contacts: Iterable<PeerDescriptor>,
9
- opts?: {
10
- maxCount?: number
11
- excludedNodeIds?: Set<DhtAddress>
12
- }
13
- ): PeerDescriptor[] => {
14
- const list = new SortedContactList<Contact>({
15
- referenceId,
16
- allowToContainReferenceId: true,
17
- excludedNodeIds: opts?.excludedNodeIds,
18
- maxSize: opts?.maxCount
19
- })
20
- for (const contact of contacts) {
21
- list.addContact(new Contact(contact))
22
- }
23
- return list.getClosestContacts().map((n) => n.getPeerDescriptor())
24
- }
@@ -1,62 +0,0 @@
1
- import { PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc'
2
-
3
- // Notice: you cannot convert RingId to RingIdRaw, because
4
- // RingId is only an approximation of the actual value.
5
- // That is why RingIdRaw is widely used in the codebase.
6
-
7
- export type RingIdRaw = Uint8Array & { __ringIdRaw: never }
8
- export type RingId = number & { __ringId: never }
9
- export type RingDistance = number & { __ringDistance: never }
10
-
11
- export const RING_SIZE = 2 ** 120 - 1 // 2^120 - 1
12
-
13
- const binaryToBigInt = (binary: Uint8Array): bigint => {
14
- return binary.reduce((acc, val) => (acc << BigInt(8)) | BigInt(val), BigInt(0))
15
- }
16
-
17
- export const getRingIdFromRaw = (raw: RingIdRaw): RingId => Number(binaryToBigInt(raw)) as RingId
18
-
19
- export const getRingIdRawFromPeerDescriptor = (peerDescriptor: PeerDescriptor): RingIdRaw => {
20
- const regionAsBuffer = Buffer.alloc(4)
21
- regionAsBuffer.writeUInt32BE(peerDescriptor.region ?? 0, 0)
22
- const ipAsbuffer = Buffer.alloc(4)
23
- ipAsbuffer.writeUInt32BE(peerDescriptor.ipAddress ?? 0, 0)
24
-
25
- const uniquePartAsBuffer = Buffer.from(peerDescriptor.nodeId.subarray(peerDescriptor.nodeId.length - 7, peerDescriptor.nodeId.length))
26
-
27
- const arr = [
28
- regionAsBuffer,
29
- ipAsbuffer,
30
- uniquePartAsBuffer
31
- ]
32
-
33
- const buffer = Buffer.concat(arr)
34
- return new Uint8Array(buffer) as RingIdRaw
35
- }
36
-
37
- export const getRingIdFromPeerDescriptor = (peerDescriptor: PeerDescriptor): RingId => {
38
- const raw = getRingIdRawFromPeerDescriptor(peerDescriptor)
39
- return Number(binaryToBigInt(raw)) as RingId
40
- }
41
-
42
- export const getLeftDistance = (referenceId: RingId, id: RingId): RingDistance =>{
43
- const diff = Math.abs(referenceId - id)
44
- if (referenceId > id) {
45
- // if id is smaller than referenceId, then the distance is the difference
46
- return diff as RingDistance
47
- } else {
48
- // if id is bigger than referenceId, then the distance is the ringSize - difference
49
- return RING_SIZE - diff as RingDistance
50
- }
51
- }
52
-
53
- export const getRightDistance = (referenceId: RingId, id: RingId): RingDistance => {
54
- const diff = Math.abs(referenceId - id)
55
- if (referenceId > id) {
56
- // if id is smaller than referenceId, then the distance is the ringSize - difference
57
- return RING_SIZE - diff as RingDistance
58
- } else {
59
- // if id is bigger than referenceId, then the distance is the difference
60
- return diff as RingDistance
61
- }
62
- }
@@ -1,129 +0,0 @@
1
- import { Gate, Logger, withTimeout } from '@streamr/utils'
2
- import { v4 } from 'uuid'
3
- import { DhtAddress, toNodeId, toDhtAddressRaw } from '../../identifiers'
4
- import { PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc'
5
- import { DhtNodeRpcRemote } from '../DhtNodeRpcRemote'
6
- import { PeerManager, getDistance } from '../PeerManager'
7
- import { getClosestNodes } from '../contact/getClosestNodes'
8
-
9
- const logger = new Logger(module)
10
-
11
- interface DiscoverySessionOptions {
12
- targetId: DhtAddress
13
- parallelism: number
14
- noProgressLimit: number
15
- peerManager: PeerManager
16
- // Note that contacted peers will be mutated by the DiscoverySession or other parallel sessions
17
- contactedPeers: Set<DhtAddress>
18
- abortSignal: AbortSignal
19
- createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => DhtNodeRpcRemote
20
- }
21
-
22
- export class DiscoverySession {
23
-
24
- public readonly id = v4()
25
- private noProgressCounter = 0
26
- private ongoingRequests: Set<DhtAddress> = new Set()
27
- private doneGate = new Gate(false)
28
- private readonly options: DiscoverySessionOptions
29
-
30
- constructor(options: DiscoverySessionOptions) {
31
- this.options = options
32
- }
33
-
34
- private addContacts(contacts: PeerDescriptor[]): void {
35
- if (this.options.abortSignal.aborted || this.doneGate.isOpen()) {
36
- return
37
- }
38
- for (const contact of contacts) {
39
- this.options.peerManager.addContact(contact)
40
- }
41
- }
42
-
43
- private async fetchClosestNeighborsFromRemote(peerDescriptor: PeerDescriptor): Promise<PeerDescriptor[]> {
44
- if (this.options.abortSignal.aborted || this.doneGate.isOpen()) {
45
- return []
46
- }
47
- const nodeId = toNodeId(peerDescriptor)
48
- logger.trace(`Getting closest neighbors from remote: ${nodeId}`)
49
- this.options.contactedPeers.add(nodeId)
50
- const remote = this.options.createDhtNodeRpcRemote(peerDescriptor)
51
- const returnedContacts = await remote.getClosestPeers(this.options.targetId)
52
- this.options.peerManager.setContactActive(nodeId)
53
- return returnedContacts
54
- }
55
-
56
- private onRequestSucceeded(nodeId: DhtAddress, contacts: PeerDescriptor[]) {
57
- if (!this.ongoingRequests.has(nodeId)) {
58
- return
59
- }
60
- this.ongoingRequests.delete(nodeId)
61
- const targetId = toDhtAddressRaw(this.options.targetId)
62
- const oldClosestNeighbor = this.getClosestNeighbor()
63
- const oldClosestDistance = getDistance(targetId, oldClosestNeighbor.nodeId)
64
- this.addContacts(contacts)
65
- const newClosestNeighbor = this.getClosestNeighbor()
66
- const newClosestDistance = getDistance(targetId, newClosestNeighbor.nodeId)
67
- if (newClosestDistance >= oldClosestDistance) {
68
- this.noProgressCounter++
69
- }
70
- }
71
-
72
- private getClosestNeighbor(): PeerDescriptor {
73
- return getClosestNodes(
74
- this.options.targetId,
75
- this.options.peerManager.getNeighbors().map((n) => n.getPeerDescriptor()),
76
- { maxCount: 1 }
77
- )[0]
78
- }
79
-
80
- private onRequestFailed(nodeId: DhtAddress) {
81
- if (!this.ongoingRequests.has(nodeId)) {
82
- return
83
- }
84
- this.ongoingRequests.delete(nodeId)
85
- this.options.peerManager.removeContact(nodeId)
86
- }
87
-
88
- private findMoreContacts(): void {
89
- if (this.options.abortSignal.aborted || this.doneGate.isOpen()) {
90
- return
91
- }
92
- const uncontacted = getClosestNodes(
93
- this.options.targetId,
94
- Array.from(this.options.peerManager.getNearbyContacts().getAllContactsInUndefinedOrder(), (c) => c.getPeerDescriptor()),
95
- {
96
- maxCount: this.options.parallelism,
97
- excludedNodeIds: this.options.contactedPeers
98
- }
99
- )
100
- if ((uncontacted.length === 0 && this.ongoingRequests.size === 0) || (this.noProgressCounter >= this.options.noProgressLimit)) {
101
- this.doneGate.open()
102
- return
103
- }
104
- for (const node of uncontacted) {
105
- if (this.ongoingRequests.size >= this.options.parallelism) {
106
- break
107
- }
108
- const nodeId = toNodeId(node)
109
- this.ongoingRequests.add(nodeId)
110
- // eslint-disable-next-line promise/catch-or-return
111
- this.fetchClosestNeighborsFromRemote(node)
112
- .then((contacts) => this.onRequestSucceeded(nodeId, contacts))
113
- .catch(() => this.onRequestFailed(nodeId))
114
- .finally(() => {
115
- this.findMoreContacts()
116
- })
117
- }
118
- }
119
-
120
- public async findClosestNodes(timeout: number): Promise<void> {
121
- if (this.options.peerManager.getNearbyContactCount(this.options.contactedPeers) === 0) {
122
- return
123
- }
124
- setImmediate(() => {
125
- this.findMoreContacts()
126
- })
127
- await withTimeout(this.doneGate.waitUntilOpen(), timeout, 'discovery session timed out', this.options.abortSignal)
128
- }
129
- }