@streamr/dht 102.0.0-beta.1 → 102.0.0-beta.3

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 (211) hide show
  1. package/dist/generated/google/protobuf/any.d.ts +180 -0
  2. package/dist/generated/google/protobuf/any.js +155 -0
  3. package/dist/generated/google/protobuf/any.js.map +1 -0
  4. package/dist/generated/google/protobuf/empty.d.ts +31 -0
  5. package/dist/generated/google/protobuf/empty.js +32 -0
  6. package/dist/generated/google/protobuf/empty.js.map +1 -0
  7. package/dist/generated/google/protobuf/timestamp.d.ts +155 -0
  8. package/dist/generated/google/protobuf/timestamp.js +136 -0
  9. package/dist/generated/google/protobuf/timestamp.js.map +1 -0
  10. package/dist/generated/packages/dht/protos/DhtRpc.client.d.ts +361 -0
  11. package/dist/generated/packages/dht/protos/DhtRpc.client.js +285 -0
  12. package/dist/generated/packages/dht/protos/DhtRpc.client.js.map +1 -0
  13. package/dist/generated/packages/dht/protos/DhtRpc.d.ts +999 -0
  14. package/dist/generated/packages/dht/protos/DhtRpc.js +677 -0
  15. package/dist/generated/packages/dht/protos/DhtRpc.js.map +1 -0
  16. package/dist/generated/packages/dht/protos/DhtRpc.server.d.ts +162 -0
  17. package/dist/generated/packages/dht/protos/DhtRpc.server.js +3 -0
  18. package/dist/generated/packages/dht/protos/DhtRpc.server.js.map +1 -0
  19. package/dist/generated/packages/proto-rpc/protos/ProtoRpc.d.ts +87 -0
  20. package/dist/generated/packages/proto-rpc/protos/ProtoRpc.js +66 -0
  21. package/dist/generated/packages/proto-rpc/protos/ProtoRpc.js.map +1 -0
  22. package/dist/package.json +7 -7
  23. package/package.json +7 -7
  24. package/eslint.config.mjs +0 -12
  25. package/src/connection/Connection.ts +0 -28
  26. package/src/connection/ConnectionLockRpcLocal.ts +0 -78
  27. package/src/connection/ConnectionLockRpcRemote.ts +0 -64
  28. package/src/connection/ConnectionLockStates.ts +0 -131
  29. package/src/connection/ConnectionManager.ts +0 -661
  30. package/src/connection/ConnectionsView.ts +0 -8
  31. package/src/connection/ConnectorFacade.ts +0 -217
  32. package/src/connection/Handshaker.ts +0 -209
  33. package/src/connection/IConnection.ts +0 -40
  34. package/src/connection/ManagedConnection.ts +0 -113
  35. package/src/connection/OutputBuffer.ts +0 -28
  36. package/src/connection/PendingConnection.ts +0 -68
  37. package/src/connection/connectivityChecker.ts +0 -108
  38. package/src/connection/connectivityRequestHandler.ts +0 -116
  39. package/src/connection/simulator/Simulator.ts +0 -369
  40. package/src/connection/simulator/SimulatorConnection.ts +0 -137
  41. package/src/connection/simulator/SimulatorConnector.ts +0 -98
  42. package/src/connection/simulator/SimulatorTransport.ts +0 -15
  43. package/src/connection/simulator/pings.ts +0 -42
  44. package/src/connection/webrtc/BrowserWebrtcConnection.ts +0 -242
  45. package/src/connection/webrtc/IWebrtcConnection.ts +0 -24
  46. package/src/connection/webrtc/NodeWebrtcConnection.ts +0 -245
  47. package/src/connection/webrtc/WebrtcConnector.ts +0 -234
  48. package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +0 -108
  49. package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +0 -60
  50. package/src/connection/webrtc/iceServerAsString.ts +0 -15
  51. package/src/connection/websocket/AbstractWebsocketClientConnection.ts +0 -122
  52. package/src/connection/websocket/AutoCertifierClientFacade.ts +0 -89
  53. package/src/connection/websocket/BrowserWebsocketClientConnection.ts +0 -44
  54. package/src/connection/websocket/NodeWebsocketClientConnection.ts +0 -39
  55. package/src/connection/websocket/WebsocketClientConnector.ts +0 -119
  56. package/src/connection/websocket/WebsocketClientConnectorRpcLocal.ts +0 -38
  57. package/src/connection/websocket/WebsocketClientConnectorRpcRemote.ts +0 -19
  58. package/src/connection/websocket/WebsocketServer.ts +0 -164
  59. package/src/connection/websocket/WebsocketServerConnection.ts +0 -109
  60. package/src/connection/websocket/WebsocketServerConnector.ts +0 -290
  61. package/src/dht/DhtNode.ts +0 -683
  62. package/src/dht/DhtNodeRpcLocal.ts +0 -84
  63. package/src/dht/DhtNodeRpcRemote.ts +0 -107
  64. package/src/dht/ExternalApiRpcLocal.ts +0 -58
  65. package/src/dht/ExternalApiRpcRemote.ts +0 -41
  66. package/src/dht/PeerManager.ts +0 -305
  67. package/src/dht/contact/Contact.ts +0 -19
  68. package/src/dht/contact/ContactList.ts +0 -43
  69. package/src/dht/contact/RandomContactList.ts +0 -56
  70. package/src/dht/contact/RingContactList.ts +0 -143
  71. package/src/dht/contact/RpcRemote.ts +0 -72
  72. package/src/dht/contact/SortedContactList.ts +0 -173
  73. package/src/dht/contact/getClosestNodes.ts +0 -24
  74. package/src/dht/contact/ringIdentifiers.ts +0 -62
  75. package/src/dht/discovery/DiscoverySession.ts +0 -129
  76. package/src/dht/discovery/PeerDiscovery.ts +0 -244
  77. package/src/dht/discovery/RingDiscoverySession.ts +0 -148
  78. package/src/dht/recursive-operation/RecursiveOperationManager.ts +0 -251
  79. package/src/dht/recursive-operation/RecursiveOperationRpcLocal.ts +0 -34
  80. package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +0 -43
  81. package/src/dht/recursive-operation/RecursiveOperationSession.ts +0 -231
  82. package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +0 -35
  83. package/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.ts +0 -30
  84. package/src/dht/routing/DuplicateDetector.ts +0 -34
  85. package/src/dht/routing/Router.ts +0 -246
  86. package/src/dht/routing/RouterRpcLocal.ts +0 -78
  87. package/src/dht/routing/RouterRpcRemote.ts +0 -80
  88. package/src/dht/routing/RoutingSession.ts +0 -243
  89. package/src/dht/routing/RoutingTablesCache.ts +0 -60
  90. package/src/dht/routing/getPreviousPeer.ts +0 -6
  91. package/src/dht/store/LocalDataStore.ts +0 -84
  92. package/src/dht/store/StoreManager.ts +0 -170
  93. package/src/dht/store/StoreRpcLocal.ts +0 -89
  94. package/src/dht/store/StoreRpcRemote.ts +0 -32
  95. package/src/exports.ts +0 -33
  96. package/src/helpers/AddressTools.ts +0 -28
  97. package/src/helpers/Connectivity.ts +0 -19
  98. package/src/helpers/browser/isBrowserEnvironment.ts +0 -1
  99. package/src/helpers/browser/isBrowserEnvironment_override.ts +0 -3
  100. package/src/helpers/createPeerDescriptor.ts +0 -57
  101. package/src/helpers/createPeerDescriptorSignaturePayload.ts +0 -28
  102. package/src/helpers/debugHelpers.ts +0 -9
  103. package/src/helpers/errors.ts +0 -49
  104. package/src/helpers/offering.ts +0 -15
  105. package/src/helpers/protoClasses.ts +0 -57
  106. package/src/helpers/protoToString.ts +0 -21
  107. package/src/helpers/version.ts +0 -32
  108. package/src/identifiers.ts +0 -29
  109. package/src/rpc-protocol/DhtCallContext.ts +0 -14
  110. package/src/rpc-protocol/DhtRpcOptions.ts +0 -10
  111. package/src/transport/ITransport.ts +0 -37
  112. package/src/transport/ListeningRpcCommunicator.ts +0 -32
  113. package/src/transport/RoutingRpcCommunicator.ts +0 -66
  114. package/src/types/ServiceID.ts +0 -1
  115. package/src/types/textencoding.d.ts +0 -6
  116. package/test/benchmark/Find.test.ts +0 -72
  117. package/test/benchmark/KademliaCorrectness.test.ts +0 -114
  118. package/test/benchmark/RingCorrectness.test.ts +0 -157
  119. package/test/benchmark/SortedContactListBenchmark.test.ts +0 -108
  120. package/test/benchmark/WebsocketServerMemoryLeak.test.ts +0 -41
  121. package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +0 -71
  122. package/test/end-to-end/GeoIpLayer0.test.ts +0 -55
  123. package/test/end-to-end/Layer0-Layer1.test.ts +0 -93
  124. package/test/end-to-end/Layer0.test.ts +0 -76
  125. package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +0 -110
  126. package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +0 -137
  127. package/test/end-to-end/Layer0Webrtc.test.ts +0 -85
  128. package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +0 -82
  129. package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +0 -76
  130. package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +0 -52
  131. package/test/end-to-end/WebsocketConnectionRequest.test.ts +0 -69
  132. package/test/end-to-end/memory-leak.test.ts +0 -80
  133. package/test/integration/ConnectionLocking.test.ts +0 -192
  134. package/test/integration/ConnectionManager.test.ts +0 -528
  135. package/test/integration/ConnectivityChecking.test.ts +0 -53
  136. package/test/integration/DhtJoinPeerDiscovery.test.ts +0 -49
  137. package/test/integration/DhtNode.test.ts +0 -66
  138. package/test/integration/DhtNodeExternalAPI.test.ts +0 -48
  139. package/test/integration/DhtNodeRpcRemote.test.ts +0 -66
  140. package/test/integration/DhtRpc.test.ts +0 -121
  141. package/test/integration/Find.test.ts +0 -45
  142. package/test/integration/GeoIpConnectivityChecking.test.ts +0 -72
  143. package/test/integration/Layer1-scale.test.ts +0 -189
  144. package/test/integration/Mock-Layer1-Layer0.test.ts +0 -85
  145. package/test/integration/MultipleEntryPointJoining.test.ts +0 -105
  146. package/test/integration/ReplicateData.test.ts +0 -104
  147. package/test/integration/RouteMessage.test.ts +0 -230
  148. package/test/integration/RouterRpcRemote.test.ts +0 -77
  149. package/test/integration/SimultaneousConnections.test.ts +0 -316
  150. package/test/integration/Store.test.ts +0 -85
  151. package/test/integration/StoreAndDelete.test.ts +0 -77
  152. package/test/integration/StoreOnDhtWithThreeNodes.test.ts +0 -59
  153. package/test/integration/StoreOnDhtWithTwoNodes.test.ts +0 -51
  154. package/test/integration/StoreRpcRemote.test.ts +0 -54
  155. package/test/integration/WebrtcConnectionManagement.test.ts +0 -191
  156. package/test/integration/WebrtcConnectorRpc.test.ts +0 -125
  157. package/test/integration/Websocket.test.ts +0 -65
  158. package/test/integration/WebsocketClientConnectorRpc.test.ts +0 -69
  159. package/test/integration/WebsocketConnectionManagement.test.ts +0 -191
  160. package/test/integration/rpc-connections-over-webrtc.test.ts +0 -123
  161. package/test/kademlia-simulation/data/nodeids.json +0 -13002
  162. package/test/kademlia-simulation/data/orderedneighbors.json +0 -1001
  163. package/test/types/global.d.ts +0 -1
  164. package/test/unit/AddressTools.test.ts +0 -44
  165. package/test/unit/AutoCertifierClientFacade.test.ts +0 -58
  166. package/test/unit/ConnectionManager.test.ts +0 -65
  167. package/test/unit/ConnectivityHelpers.test.ts +0 -61
  168. package/test/unit/DiscoverySession.test.ts +0 -87
  169. package/test/unit/DuplicateDetector.test.ts +0 -31
  170. package/test/unit/Handshaker.test.ts +0 -169
  171. package/test/unit/ListeningRpcCommunicator.test.ts +0 -52
  172. package/test/unit/LocalDataStore.test.ts +0 -108
  173. package/test/unit/ManagedConnection.test.ts +0 -58
  174. package/test/unit/PeerManager.test.ts +0 -93
  175. package/test/unit/PendingConnection.test.ts +0 -57
  176. package/test/unit/ProtobufMessage.test.ts +0 -21
  177. package/test/unit/RandomContactList.test.ts +0 -58
  178. package/test/unit/RecursiveOperationManager.test.ts +0 -161
  179. package/test/unit/RecursiveOperationSession.test.ts +0 -68
  180. package/test/unit/Router.test.ts +0 -137
  181. package/test/unit/RoutingSession.test.ts +0 -86
  182. package/test/unit/SortedContactList.test.ts +0 -115
  183. package/test/unit/StoreManager.test.ts +0 -146
  184. package/test/unit/StoreRpcLocal.test.ts +0 -167
  185. package/test/unit/WebrtcConnection.test.ts +0 -29
  186. package/test/unit/WebrtcConnector.test.ts +0 -56
  187. package/test/unit/WebsocketClientConnector.test.ts +0 -101
  188. package/test/unit/WebsocketServer.test.ts +0 -66
  189. package/test/unit/WebsocketServerConnector.test.ts +0 -102
  190. package/test/unit/connectivityRequestHandler.test.ts +0 -104
  191. package/test/unit/createPeerDescriptor.test.ts +0 -69
  192. package/test/unit/customMatchers.test.ts +0 -34
  193. package/test/unit/getClosestNodes.test.ts +0 -30
  194. package/test/unit/version.test.ts +0 -18
  195. package/test/unit/webrtcReplaceInternalIpWithExternalIp.test.ts +0 -18
  196. package/test/utils/FakeConnectorFacade.ts +0 -41
  197. package/test/utils/FakeRpcCommunicator.ts +0 -23
  198. package/test/utils/FakeTransport.ts +0 -79
  199. package/test/utils/customMatchers.ts +0 -71
  200. package/test/utils/mock/MockConnection.ts +0 -26
  201. package/test/utils/mock/MockConnectionsView.ts +0 -18
  202. package/test/utils/mock/MockRouter.ts +0 -62
  203. package/test/utils/mock/MockRpcCommunicator.ts +0 -7
  204. package/test/utils/mock/MockTransport.ts +0 -26
  205. package/test/utils/mock/mockDataEntry.ts +0 -38
  206. package/test/utils/topology.ts +0 -79
  207. package/test/utils/utils.ts +0 -268
  208. package/tsconfig.browser.json +0 -17
  209. package/tsconfig.jest.json +0 -25
  210. package/tsconfig.json +0 -3
  211. 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?.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
- }