@streamr/dht 100.0.0 → 100.1.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 (119) hide show
  1. package/dist/package.json +6 -6
  2. package/dist/src/connection/ConnectionLockRpcLocal.d.ts +1 -1
  3. package/dist/src/connection/ConnectionLockRpcRemote.d.ts +1 -1
  4. package/dist/src/connection/ConnectionLockRpcRemote.js +1 -1
  5. package/dist/src/connection/ConnectionLockRpcRemote.js.map +1 -1
  6. package/dist/src/connection/{ConnectionLockHandler.d.ts → ConnectionLockStates.d.ts} +1 -1
  7. package/dist/src/connection/{ConnectionLockHandler.js → ConnectionLockStates.js} +4 -4
  8. package/dist/src/connection/ConnectionLockStates.js.map +1 -0
  9. package/dist/src/connection/ConnectionManager.d.ts +5 -3
  10. package/dist/src/connection/ConnectionManager.js +8 -11
  11. package/dist/src/connection/ConnectionManager.js.map +1 -1
  12. package/dist/src/connection/ConnectorFacade.js +1 -1
  13. package/dist/src/connection/ConnectorFacade.js.map +1 -1
  14. package/dist/src/connection/ManagedConnection.d.ts +2 -2
  15. package/dist/src/connection/ManagedConnection.js +8 -8
  16. package/dist/src/connection/ManagedConnection.js.map +1 -1
  17. package/dist/src/connection/connectivityChecker.js +3 -3
  18. package/dist/src/connection/connectivityChecker.js.map +1 -1
  19. package/dist/src/connection/connectivityRequestHandler.js +4 -4
  20. package/dist/src/connection/connectivityRequestHandler.js.map +1 -1
  21. package/dist/src/connection/websocket/AbstractWebsocketClientConnection.d.ts +28 -0
  22. package/dist/src/connection/websocket/{ClientWebsocket.js → AbstractWebsocketClientConnection.js} +42 -68
  23. package/dist/src/connection/websocket/AbstractWebsocketClientConnection.js.map +1 -0
  24. package/dist/src/connection/websocket/NodeWebsocketClientConnection.d.ts +7 -0
  25. package/dist/src/connection/websocket/NodeWebsocketClientConnection.js +39 -0
  26. package/dist/src/connection/websocket/NodeWebsocketClientConnection.js.map +1 -0
  27. package/dist/src/connection/websocket/WebsocketConnector.js +3 -3
  28. package/dist/src/connection/websocket/WebsocketConnector.js.map +1 -1
  29. package/dist/src/connection/websocket/WebsocketServerConnection.js +3 -3
  30. package/dist/src/connection/websocket/WebsocketServerConnection.js.map +1 -1
  31. package/dist/src/dht/DhtNode.d.ts +2 -2
  32. package/dist/src/dht/DhtNode.js +12 -16
  33. package/dist/src/dht/DhtNode.js.map +1 -1
  34. package/dist/src/dht/DhtNodeRpcRemote.js +1 -1
  35. package/dist/src/dht/DhtNodeRpcRemote.js.map +1 -1
  36. package/dist/src/dht/PeerManager.d.ts +4 -4
  37. package/dist/src/dht/PeerManager.js +33 -44
  38. package/dist/src/dht/PeerManager.js.map +1 -1
  39. package/dist/src/dht/contact/SortedContactList.d.ts +2 -1
  40. package/dist/src/dht/contact/SortedContactList.js +19 -17
  41. package/dist/src/dht/contact/SortedContactList.js.map +1 -1
  42. package/dist/src/dht/discovery/DiscoverySession.js +3 -1
  43. package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
  44. package/dist/src/dht/discovery/PeerDiscovery.d.ts +2 -2
  45. package/dist/src/dht/discovery/PeerDiscovery.js +6 -4
  46. package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
  47. package/dist/src/dht/discovery/RingDiscoverySession.js +3 -1
  48. package/dist/src/dht/discovery/RingDiscoverySession.js.map +1 -1
  49. package/dist/src/dht/recursive-operation/RecursiveOperationManager.js +1 -1
  50. package/dist/src/dht/recursive-operation/RecursiveOperationManager.js.map +1 -1
  51. package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.js +1 -1
  52. package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.js.map +1 -1
  53. package/dist/src/dht/routing/Router.d.ts +0 -1
  54. package/dist/src/dht/routing/Router.js +0 -1
  55. package/dist/src/dht/routing/Router.js.map +1 -1
  56. package/dist/src/dht/routing/RouterRpcLocal.d.ts +0 -1
  57. package/dist/src/dht/routing/RouterRpcLocal.js.map +1 -1
  58. package/dist/src/dht/routing/RouterRpcRemote.js +2 -2
  59. package/dist/src/dht/routing/RouterRpcRemote.js.map +1 -1
  60. package/dist/src/dht/routing/RoutingSession.js +2 -2
  61. package/dist/src/dht/routing/RoutingSession.js.map +1 -1
  62. package/dist/src/dht/store/LocalDataStore.js +2 -2
  63. package/dist/src/dht/store/LocalDataStore.js.map +1 -1
  64. package/dist/src/dht/store/StoreManager.js +1 -1
  65. package/dist/src/dht/store/StoreManager.js.map +1 -1
  66. package/dist/src/exports.d.ts +2 -2
  67. package/dist/src/exports.js +3 -3
  68. package/dist/src/exports.js.map +1 -1
  69. package/karma.config.js +4 -1
  70. package/package.json +6 -6
  71. package/src/connection/ConnectionLockRpcLocal.ts +1 -1
  72. package/src/connection/ConnectionLockRpcRemote.ts +2 -2
  73. package/src/connection/{ConnectionLockHandler.ts → ConnectionLockStates.ts} +1 -1
  74. package/src/connection/ConnectionManager.ts +11 -12
  75. package/src/connection/ConnectorFacade.ts +1 -1
  76. package/src/connection/ManagedConnection.ts +8 -8
  77. package/src/connection/connectivityChecker.ts +3 -3
  78. package/src/connection/connectivityRequestHandler.ts +4 -4
  79. package/src/connection/webrtc/BrowserWebrtcConnection.ts +18 -0
  80. package/src/connection/websocket/{ClientWebsocket.ts → AbstractWebsocketClientConnection.ts} +57 -70
  81. package/src/connection/websocket/BrowserWebsocketClientConnection.ts +44 -0
  82. package/src/connection/websocket/NodeWebsocketClientConnection.ts +39 -0
  83. package/src/connection/websocket/WebsocketConnector.ts +3 -3
  84. package/src/connection/websocket/WebsocketServerConnection.ts +1 -1
  85. package/src/dht/DhtNode.ts +13 -16
  86. package/src/dht/DhtNodeRpcRemote.ts +1 -1
  87. package/src/dht/PeerManager.ts +36 -46
  88. package/src/dht/contact/SortedContactList.ts +22 -18
  89. package/src/dht/discovery/DiscoverySession.ts +3 -1
  90. package/src/dht/discovery/PeerDiscovery.ts +8 -6
  91. package/src/dht/discovery/RingDiscoverySession.ts +3 -1
  92. package/src/dht/recursive-operation/RecursiveOperationManager.ts +1 -1
  93. package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +1 -1
  94. package/src/dht/routing/Router.ts +0 -2
  95. package/src/dht/routing/RouterRpcLocal.ts +0 -1
  96. package/src/dht/routing/RouterRpcRemote.ts +2 -2
  97. package/src/dht/routing/RoutingSession.ts +2 -2
  98. package/src/dht/store/LocalDataStore.ts +1 -1
  99. package/src/dht/store/StoreManager.ts +1 -1
  100. package/src/exports.ts +2 -2
  101. package/test/benchmark/WebsocketServerMemoryLeak.test.ts +2 -2
  102. package/test/integration/Find.test.ts +2 -2
  103. package/test/integration/ReplicateData.test.ts +3 -3
  104. package/test/integration/Store.test.ts +2 -2
  105. package/test/integration/StoreAndDelete.test.ts +2 -2
  106. package/test/integration/Websocket.test.ts +2 -2
  107. package/test/unit/PeerManager.test.ts +42 -11
  108. package/test/unit/Router.test.ts +0 -1
  109. package/test/utils/utils.ts +17 -37
  110. package/tsconfig.browser.json +2 -1
  111. package/tsconfig.jest.json +2 -1
  112. package/tsconfig.node.json +2 -1
  113. package/dist/src/connection/ConnectionLockHandler.js.map +0 -1
  114. package/dist/src/connection/websocket/ClientWebsocket.d.ts +0 -17
  115. package/dist/src/connection/websocket/ClientWebsocket.js.map +0 -1
  116. package/dist/src/helpers/MapWithTtl.d.ts +0 -14
  117. package/dist/src/helpers/MapWithTtl.js +0 -60
  118. package/dist/src/helpers/MapWithTtl.js.map +0 -1
  119. package/src/helpers/MapWithTtl.ts +0 -71
@@ -38,7 +38,9 @@ export class DiscoverySession {
38
38
  if (this.stopped) {
39
39
  return
40
40
  }
41
- this.config.peerManager.addContact(contacts)
41
+ for (const contact of contacts) {
42
+ this.config.peerManager.addContact(contact)
43
+ }
42
44
  }
43
45
 
44
46
  private async getClosestPeersFromContact(contact: DhtNodeRpcRemote): Promise<PeerDescriptor[]> {
@@ -2,7 +2,7 @@ import { DiscoverySession } from './DiscoverySession'
2
2
  import { DhtNodeRpcRemote } from '../DhtNodeRpcRemote'
3
3
  import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
4
4
  import { Logger, scheduleAtInterval, setAbortableTimeout } from '@streamr/utils'
5
- import { ConnectionManager } from '../../connection/ConnectionManager'
5
+ import { ConnectionLocker } from '../../connection/ConnectionManager'
6
6
  import { PeerManager } from '../PeerManager'
7
7
  import { DhtAddress, areEqualPeerDescriptors, getDhtAddressFromRaw, getNodeIdFromPeerDescriptor, getRawFromDhtAddress } from '../../identifiers'
8
8
  import { ServiceID } from '../../types/ServiceID'
@@ -16,7 +16,7 @@ interface PeerDiscoveryConfig {
16
16
  serviceId: ServiceID
17
17
  parallelism: number
18
18
  joinTimeout: number
19
- connectionManager?: ConnectionManager
19
+ connectionLocker?: ConnectionLocker
20
20
  peerManager: PeerManager
21
21
  }
22
22
 
@@ -78,15 +78,15 @@ export class PeerDiscovery {
78
78
  if (areEqualPeerDescriptors(entryPointDescriptor, this.config.localPeerDescriptor)) {
79
79
  return
80
80
  }
81
- this.config.connectionManager?.lockConnection(entryPointDescriptor, `${this.config.serviceId}::joinDht`)
82
- this.config.peerManager.addContact([entryPointDescriptor])
81
+ this.config.connectionLocker?.lockConnection(entryPointDescriptor, `${this.config.serviceId}::joinDht`)
82
+ this.config.peerManager.addContact(entryPointDescriptor)
83
83
  const targetId = getNodeIdFromPeerDescriptor(this.config.localPeerDescriptor)
84
84
  const sessions = [this.createSession(targetId, contactedPeers)]
85
85
  if (additionalDistantJoin.enabled) {
86
86
  sessions.push(this.createSession(createDistantDhtAddress(targetId), additionalDistantJoin.contactedPeers))
87
87
  }
88
88
  await this.runSessions(sessions, entryPointDescriptor, retry)
89
- this.config.connectionManager?.unlockConnection(entryPointDescriptor, `${this.config.serviceId}::joinDht`)
89
+ this.config.connectionLocker?.unlockConnection(entryPointDescriptor, `${this.config.serviceId}::joinDht`)
90
90
 
91
91
  }
92
92
 
@@ -196,7 +196,9 @@ export class PeerDiscovery {
196
196
  await Promise.allSettled(
197
197
  nodes.map(async (peer: DhtNodeRpcRemote) => {
198
198
  const contacts = await peer.getClosestPeers(localNodeId)
199
- this.config.peerManager.addContact(contacts)
199
+ for (const contact of contacts) {
200
+ this.config.peerManager.addContact(contact)
201
+ }
200
202
  })
201
203
  )
202
204
  }
@@ -43,7 +43,9 @@ export class RingDiscoverySession {
43
43
  if (this.stopped) {
44
44
  return
45
45
  }
46
- this.config.peerManager.addContact(contacts)
46
+ for (const contact of contacts) {
47
+ this.config.peerManager.addContact(contact)
48
+ }
47
49
  }
48
50
 
49
51
  private async getClosestPeersFromContact(contact: DhtNodeRpcRemote): Promise<RingContacts> {
@@ -115,7 +115,7 @@ export class RecursiveOperationManager {
115
115
  15000
116
116
  )
117
117
  } catch (err) {
118
- logger.debug(`start failed with error ${err}`)
118
+ logger.debug('start failed', { err })
119
119
  }
120
120
  } else {
121
121
  session.start(this.config.serviceId)
@@ -35,7 +35,7 @@ export class RecursiveOperationRpcRemote extends RpcRemote<RecursiveOperationRpc
35
35
  ? getNodeIdFromPeerDescriptor(previousPeer)
36
36
  : getNodeIdFromPeerDescriptor(params.sourcePeer!)
37
37
  const toNode = getNodeIdFromPeerDescriptor(this.getPeerDescriptor())
38
- logger.debug(`Failed to send routeRequest message from ${fromNode} to ${toNode} with: ${err}`)
38
+ logger.debug(`Failed to send routeRequest message from ${fromNode} to ${toNode}`, { err })
39
39
  return false
40
40
  }
41
41
  return true
@@ -13,7 +13,6 @@ export interface RouterConfig {
13
13
  rpcCommunicator: RoutingRpcCommunicator
14
14
  localPeerDescriptor: PeerDescriptor
15
15
  connections: Map<DhtAddress, DhtNodeRpcRemote>
16
- addContact: (contact: PeerDescriptor, setActive?: boolean) => void
17
16
  handleMessage: (message: Message) => void
18
17
  }
19
18
 
@@ -42,7 +41,6 @@ export class Router {
42
41
  private registerLocalRpcMethods() {
43
42
  const rpcLocal = new RouterRpcLocal({
44
43
  doRouteMessage: (routedMessage: RouteMessageWrapper, mode?: RoutingMode) => this.doRouteMessage(routedMessage, mode),
45
- addContact: (contact: PeerDescriptor, setActive: boolean) => this.config.addContact(contact, setActive),
46
44
  setForwardingEntries: (routedMessage: RouteMessageWrapper) => this.setForwardingEntries(routedMessage),
47
45
  duplicateRequestDetector: this.duplicateRequestDetector,
48
46
  localPeerDescriptor: this.config.localPeerDescriptor,
@@ -8,7 +8,6 @@ import { v4 } from 'uuid'
8
8
 
9
9
  interface RouterRpcLocalConfig {
10
10
  doRouteMessage: (routedMessage: RouteMessageWrapper, mode?: RoutingMode) => RouteMessageAck
11
- addContact: (contact: PeerDescriptor, setActive: boolean) => void
12
11
  setForwardingEntries: (routedMessage: RouteMessageWrapper) => void
13
12
  handleMessage: (message: Message) => void
14
13
  duplicateRequestDetector: DuplicateDetector
@@ -39,7 +39,7 @@ export class RouterRpcRemote extends RpcRemote<RouterRpcClient> {
39
39
  ? getNodeIdFromPeerDescriptor(previousPeer)
40
40
  : getNodeIdFromPeerDescriptor(params.sourcePeer!)
41
41
  const toNode = getNodeIdFromPeerDescriptor(this.getPeerDescriptor())
42
- logger.trace(`Failed to send routeMessage from ${fromNode} to ${toNode} with: ${err}`)
42
+ logger.trace(`Failed to send routeMessage from ${fromNode} to ${toNode}`, { err })
43
43
  return false
44
44
  }
45
45
  return true
@@ -69,7 +69,7 @@ export class RouterRpcRemote extends RpcRemote<RouterRpcClient> {
69
69
  ? getNodeIdFromPeerDescriptor(previousPeer)
70
70
  : getNodeIdFromPeerDescriptor(params.sourcePeer!)
71
71
  const toNode = getNodeIdFromPeerDescriptor(this.getPeerDescriptor())
72
- logger.trace(`Failed to send forwardMessage from ${fromNode} to ${toNode} with: ${err}`)
72
+ logger.trace(`Failed to send forwardMessage from ${fromNode} to ${toNode}`, { err })
73
73
  return false
74
74
  }
75
75
  return true
@@ -212,8 +212,8 @@ export class RoutingSession extends EventEmitter<RoutingSessionEvents> {
212
212
  } else {
213
213
  this.onRequestFailed(nextPeer!.getNodeId())
214
214
  }
215
- } catch (e) {
216
- logger.debug('Unable to route message ', { error: e })
215
+ } catch (err) {
216
+ logger.debug('Unable to route message ', { err })
217
217
  } finally {
218
218
  logger.trace('sendRouteMessageRequest returned')
219
219
  }
@@ -1,6 +1,6 @@
1
1
  import { DataEntry } from '../../proto/packages/dht/protos/DhtRpc'
2
- import { MapWithTtl } from '../../helpers/MapWithTtl'
3
2
  import { DhtAddress, getDhtAddressFromRaw } from '../../identifiers'
3
+ import { MapWithTtl } from '@streamr/utils'
4
4
 
5
5
  export class LocalDataStore {
6
6
 
@@ -158,7 +158,7 @@ export class StoreManager {
158
158
  try {
159
159
  await rpcRemote.replicateData({ entry: dataEntry })
160
160
  } catch (err) {
161
- logger.trace('Failed to replicate data in replicateDataToClosestNodes', { error: err })
161
+ logger.trace('Failed to replicate data in replicateDataToClosestNodes', { err })
162
162
  }
163
163
  }))
164
164
  }))
package/src/exports.ts CHANGED
@@ -7,13 +7,13 @@ export { getRandomRegion, getRegionDelayMatrix } from './connection/simulator/pi
7
7
  export { PeerDescriptor, Message, NodeType, DataEntry } from './proto/packages/dht/protos/DhtRpc'
8
8
  export { ITransport } from './transport/ITransport'
9
9
  export { ConnectionManager, ConnectionLocker, PortRange, TlsCertificate } from './connection/ConnectionManager'
10
- export { LockID } from './connection/ConnectionLockHandler'
10
+ export { LockID } from './connection/ConnectionLockStates'
11
11
  export { DefaultConnectorFacade } from './connection/ConnectorFacade'
12
12
  export { DhtRpcOptions } from './rpc-protocol/DhtRpcOptions'
13
13
  export { RpcRemote, EXISTING_CONNECTION_TIMEOUT } from './dht/contact/RpcRemote'
14
14
  export { IceServer } from './connection/webrtc/WebrtcConnector'
15
15
  export { DhtCallContext } from './rpc-protocol/DhtCallContext'
16
- export { ClientWebsocket } from './connection/websocket/ClientWebsocket'
16
+ export { WebsocketClientConnection } from './connection/websocket/NodeWebsocketClientConnection'
17
17
  export { ManagedConnection } from './connection/ManagedConnection'
18
18
  export { ConnectionType } from './connection/IConnection'
19
19
  export { ServiceID } from './types/ServiceID'
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { wait } from '@streamr/utils'
4
4
  import { WebsocketServer } from '../../src/connection/websocket/WebsocketServer'
5
- import { ClientWebsocket } from '../../src/connection/websocket/ClientWebsocket'
5
+ import { WebsocketClientConnection } from '../../src/connection/websocket/NodeWebsocketClientConnection'
6
6
 
7
7
  // This 'test' is meant to be run manually using the following command:
8
8
  // node --inspect ../../../../node_modules/.bin/jest WebsocketServerMemoryLeak.test.ts
@@ -26,7 +26,7 @@ describe('WebsocketServermemoryLeak', () => {
26
26
  expect(port).toEqual(19792)
27
27
 
28
28
  for (let i = 0; i < 10000; i++) {
29
- const clientWebsocket: ClientWebsocket = new ClientWebsocket()
29
+ const clientWebsocket: WebsocketClientConnection = new WebsocketClientConnection()
30
30
  clientWebsocket.on('connected', () => {
31
31
  console.log('clientWebsocket connected ' + i)
32
32
  })
@@ -1,7 +1,7 @@
1
1
  import { LatencyType, Simulator } from '../../src/connection/simulator/Simulator'
2
2
  import { DhtNode } from '../../src/dht/DhtNode'
3
3
  import { PeerDescriptor } from '../../src/proto/packages/dht/protos/DhtRpc'
4
- import { createMockConnectionDhtNode, waitConnectionManagersReadyForTesting } from '../utils/utils'
4
+ import { createMockConnectionDhtNode, waitForStableTopology } from '../utils/utils'
5
5
  import { getDhtAddressFromRaw, getNodeIdFromPeerDescriptor, getRawFromDhtAddress } from '../../src/identifiers'
6
6
 
7
7
  const NUM_NODES = 100
@@ -25,7 +25,7 @@ describe('Find correctness', () => {
25
25
  }
26
26
  await entryPoint.joinDht([entrypointDescriptor])
27
27
  await Promise.all(nodes.map((node) => node.joinDht([entrypointDescriptor])))
28
- await waitConnectionManagersReadyForTesting(nodes.map((node) => node.connectionManager!), 20)
28
+ await waitForStableTopology(nodes, 20)
29
29
  }, 90000)
30
30
 
31
31
  afterEach(async () => {
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable no-console */
2
2
  import { LatencyType, Simulator } from '../../src/connection/simulator/Simulator'
3
3
  import { DhtNode } from '../../src/dht/DhtNode'
4
- import { createMockConnectionDhtNode, waitNodesReadyForTesting } from '../utils/utils'
4
+ import { createMockConnectionDhtNode, waitForStableTopology } from '../utils/utils'
5
5
  import { SortedContactList } from '../../src/dht/contact/SortedContactList'
6
6
  import { createMockDataEntry, expectEqualData } from '../utils/mock/mockDataEntry'
7
7
  import { DhtAddress, createRandomDhtAddress, getDhtAddressFromRaw, getNodeIdFromPeerDescriptor } from '../../src/identifiers'
@@ -72,7 +72,7 @@ describe('Replicate data from node to node in DHT', () => {
72
72
  }
73
73
  })
74
74
  )
75
- await waitNodesReadyForTesting(nodes)
75
+ await waitForStableTopology(nodes)
76
76
 
77
77
  const data = getDataEntries(closest[0])
78
78
  expect(data).toHaveLength(1)
@@ -87,7 +87,7 @@ describe('Replicate data from node to node in DHT', () => {
87
87
  }
88
88
  })
89
89
  )
90
- await waitNodesReadyForTesting(nodes)
90
+ await waitForStableTopology(nodes)
91
91
 
92
92
  const randomIndex = Math.floor(Math.random() * nodes.length)
93
93
  const storerDescriptors = await nodes[randomIndex].storeDataToDht(getDhtAddressFromRaw(DATA.key), DATA.data!)
@@ -3,7 +3,7 @@ import { DhtNode } from '../../src/dht/DhtNode'
3
3
  import { getDhtAddressFromRaw, getNodeIdFromPeerDescriptor } from '../../src/identifiers'
4
4
  import { PeerDescriptor } from '../../src/proto/packages/dht/protos/DhtRpc'
5
5
  import { createMockDataEntry, expectEqualData } from '../utils/mock/mockDataEntry'
6
- import { createMockConnectionDhtNode, createMockPeerDescriptor, waitConnectionManagersReadyForTesting } from '../utils/utils'
6
+ import { createMockConnectionDhtNode, createMockPeerDescriptor, waitForStableTopology } from '../utils/utils'
7
7
 
8
8
  const NUM_NODES = 100
9
9
  const MAX_CONNECTIONS = 20
@@ -33,7 +33,7 @@ describe('Storing data in DHT', () => {
33
33
  nodes.push(node)
34
34
  }
35
35
  await Promise.all(nodes.map((node) => node.joinDht([entrypointDescriptor])))
36
- await waitConnectionManagersReadyForTesting(nodes.map((node) => node.connectionManager!), MAX_CONNECTIONS)
36
+ await waitForStableTopology(nodes, MAX_CONNECTIONS)
37
37
  }, 90000)
38
38
 
39
39
  afterEach(async () => {
@@ -1,6 +1,6 @@
1
1
  import { LatencyType, Simulator } from '../../src/connection/simulator/Simulator'
2
2
  import { DhtNode } from '../../src/dht/DhtNode'
3
- import { createMockConnectionDhtNode, waitConnectionManagersReadyForTesting } from '../utils/utils'
3
+ import { createMockConnectionDhtNode, waitForStableTopology } from '../utils/utils'
4
4
  import { createMockDataEntry, expectEqualData } from '../utils/mock/mockDataEntry'
5
5
  import { createRandomDhtAddress } from '../../src/identifiers'
6
6
  import { getDhtAddressFromRaw } from '../../src/identifiers'
@@ -30,7 +30,7 @@ describe('Storing data in DHT', () => {
30
30
  nodes.push(node)
31
31
  }
32
32
  await Promise.all(nodes.map((node) => node.joinDht([entryPoint.getLocalPeerDescriptor()])))
33
- await waitConnectionManagersReadyForTesting(nodes.map((node) => node.connectionManager!), MAX_CONNECTIONS)
33
+ await waitForStableTopology(nodes, MAX_CONNECTIONS)
34
34
  }, 90000)
35
35
 
36
36
  afterEach(async () => {
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { WebsocketServer } from '../../src/connection/websocket/WebsocketServer'
4
4
  import { IConnection } from '../../src/connection/IConnection'
5
- import { ClientWebsocket } from '../../src/connection/websocket/ClientWebsocket'
5
+ import { WebsocketClientConnection } from '../../src/connection/websocket/NodeWebsocketClientConnection'
6
6
  import { Logger } from '@streamr/utils'
7
7
 
8
8
  const logger = new Logger(module)
@@ -13,7 +13,7 @@ describe('Websocket', () => {
13
13
  portRange: { min: 9977, max: 9977 },
14
14
  enableTls: false
15
15
  })
16
- const clientWebsocket = new ClientWebsocket()
16
+ const clientWebsocket = new WebsocketClientConnection()
17
17
 
18
18
  beforeAll(async () => {
19
19
  await websocketServer.start()
@@ -1,27 +1,35 @@
1
1
  import { PeerManager, getDistance } from '../../src/dht/PeerManager'
2
2
  import { DhtAddress, createRandomDhtAddress, getNodeIdFromPeerDescriptor, getRawFromDhtAddress } from '../../src/identifiers'
3
3
  import { NodeType, PeerDescriptor } from '../../src/proto/packages/dht/protos/DhtRpc'
4
- import { range, sampleSize, sortBy, without } from 'lodash'
4
+ import { range, sample, sampleSize, sortBy, without } from 'lodash'
5
5
  import { DhtNodeRpcRemote } from '../../src/dht/DhtNodeRpcRemote'
6
6
  import { MockRpcCommunicator } from '../utils/mock/MockRpcCommunicator'
7
7
  import { createMockPeerDescriptor } from '../utils/utils'
8
8
 
9
+ const createPeerManager = (nodeIds: DhtAddress[]) => {
10
+ const peerDescriptor = createMockPeerDescriptor()
11
+ const manager = new PeerManager({
12
+ localNodeId: getNodeIdFromPeerDescriptor(peerDescriptor),
13
+ localPeerDescriptor: peerDescriptor,
14
+ createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => {
15
+ return new DhtNodeRpcRemote(undefined as any, peerDescriptor, undefined as any, new MockRpcCommunicator())
16
+ }
17
+ } as any)
18
+ const contacts = nodeIds.map((n) => ({ nodeId: getRawFromDhtAddress(n), type: NodeType.NODEJS }))
19
+ for (const contact of contacts) {
20
+ manager.addContact(contact)
21
+ }
22
+ return manager
23
+ }
24
+
9
25
  describe('PeerManager', () => {
10
26
 
11
27
  it('getClosestContactsTo', () => {
12
28
  const nodeIds = range(10).map(() => createRandomDhtAddress())
13
- const peerDescriptor = createMockPeerDescriptor()
14
- const manager = new PeerManager({
15
- localNodeId: getNodeIdFromPeerDescriptor(peerDescriptor),
16
- localPeerDescriptor: peerDescriptor,
17
- createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => {
18
- return new DhtNodeRpcRemote(undefined as any, peerDescriptor, undefined as any, new MockRpcCommunicator())
19
- }
20
- } as any)
21
- manager.addContact(nodeIds.map((n) => ({ nodeId: getRawFromDhtAddress(n), type: NodeType.NODEJS })))
22
-
29
+ const manager = createPeerManager(nodeIds)
23
30
  const referenceId = createRandomDhtAddress()
24
31
  const excluded = new Set<DhtAddress>(sampleSize(nodeIds, 2))
32
+
25
33
  const actual = manager.getClosestContactsTo(referenceId, 5, excluded)
26
34
 
27
35
  const expected = sortBy(
@@ -30,4 +38,27 @@ describe('PeerManager', () => {
30
38
  ).slice(0, 5)
31
39
  expect(actual.map((n) => n.getNodeId())).toEqual(expected)
32
40
  })
41
+
42
+ it('getClosestNeighborsTo', () => {
43
+ const nodeIds = range(10).map(() => createRandomDhtAddress())
44
+ const manager = createPeerManager(nodeIds)
45
+ const referenceId = createRandomDhtAddress()
46
+ const excluded = new Set<DhtAddress>(sampleSize(nodeIds, 2))
47
+
48
+ const actual = manager.getClosestNeighborsTo(referenceId, 5, excluded)
49
+
50
+ const expected = sortBy(
51
+ without(manager.getNeighbors().map((n) => getNodeIdFromPeerDescriptor(n)), ...Array.from(excluded.values())),
52
+ (n: DhtAddress) => getDistance(getRawFromDhtAddress(n), getRawFromDhtAddress(referenceId))
53
+ ).slice(0, 5)
54
+ expect(actual.map((n) => n.getNodeId())).toEqual(expected)
55
+ })
56
+
57
+ it('getContactCount', () => {
58
+ const nodeIds = range(10).map(() => createRandomDhtAddress())
59
+ const manager = createPeerManager(nodeIds)
60
+ expect(manager.getContactCount()).toBe(10)
61
+ expect(manager.getContactCount(new Set(sampleSize(nodeIds, 2)))).toBe(8)
62
+ expect(manager.getContactCount(new Set([sample(nodeIds)!, createRandomDhtAddress()]))).toBe(9)
63
+ })
33
64
  })
@@ -50,7 +50,6 @@ describe('Router', () => {
50
50
  router = new Router({
51
51
  localPeerDescriptor: peerDescriptor1,
52
52
  rpcCommunicator: rpcCommunicator as any,
53
- addContact: (_contact) => {},
54
53
  connections,
55
54
  handleMessage: () => {}
56
55
  })
@@ -242,42 +242,22 @@ export const createMockPeers = (): PeerDescriptor[] => {
242
242
  ]
243
243
  }
244
244
 
245
- export const waitConnectionManagersReadyForTesting = async (connectionManagers: ConnectionManager[], limit: number): Promise<void> => {
246
- connectionManagers.forEach((connectionManager) => garbageCollectConnections(connectionManager, limit))
247
- try {
248
- await Promise.all(connectionManagers.map((connectionManager) => waitReadyForTesting(connectionManager, limit)))
249
- } catch (_err) {
250
- // did not successfully meet condition but network should be in a stable non-star state
251
- }
252
- }
253
-
254
- export const waitNodesReadyForTesting = async (nodes: DhtNode[], limit: number = 10000): Promise<void> => {
255
- return waitConnectionManagersReadyForTesting(
256
- nodes.map((node) => {
257
- return (node.getTransport() as ConnectionManager)
258
- }), limit)
259
- }
260
-
261
- function garbageCollectConnections(connectionManager: ConnectionManager, limit: number): void {
262
- const LAST_USED_LIMIT = 100
263
- connectionManager.garbageCollectConnections(limit, LAST_USED_LIMIT)
264
- }
265
-
266
- async function waitReadyForTesting(connectionManager: ConnectionManager, limit: number): Promise<void> {
267
- const LAST_USED_LIMIT = 100
268
- connectionManager.garbageCollectConnections(limit, LAST_USED_LIMIT)
269
- try {
270
- await waitForCondition(() => {
271
- return (connectionManager.getLocalLockedConnectionCount() === 0 &&
272
- connectionManager.getRemoteLockedConnectionCount() === 0 &&
273
- connectionManager.getConnections().length <= limit)
274
- }, 20000)
275
- } catch (err) {
276
- if (connectionManager.getLocalLockedConnectionCount() > 0
277
- && connectionManager.getRemoteLockedConnectionCount() > 0) {
278
- throw new Error('Connections are still locked')
279
- } else if (connectionManager.getConnections().length > limit) {
280
- throw new Error(`ConnectionManager has more than ${limit}`)
245
+ /*
246
+ * When we start multiple nodes, most of the nodes have unlocked connections. This promise will resolve when some of those
247
+ * unlocked connections have been garbage collected, i.e. we typically have connections only to the nodes which
248
+ * are neighbors.
249
+ */
250
+ export const waitForStableTopology = async (nodes: DhtNode[], maxConnectionCount: number = 10000): Promise<void> => {
251
+ const MAX_IDLE_TIME = 100
252
+ const connectionManagers = nodes.map((n) => n.getTransport() as ConnectionManager)
253
+ await Promise.all(connectionManagers.map(async (connectionManager) => {
254
+ connectionManager.garbageCollectConnections(maxConnectionCount, MAX_IDLE_TIME)
255
+ try {
256
+ await waitForCondition(() => connectionManager.getConnections().length <= maxConnectionCount, 20000)
257
+ } catch (err) {
258
+ // the topology is very likely stable, but we can't be sure (maybe the node has more than maxConnectionCount
259
+ // locked connections and therefore it is ok to that garbage collector was not able to remove any of those
260
+ // connections
281
261
  }
282
- }
262
+ }))
283
263
  }
@@ -11,6 +11,7 @@
11
11
  "package.json"
12
12
  ],
13
13
  "exclude": [
14
- "src/connection/webrtc/NodeWebrtcConnection.ts"
14
+ "src/connection/webrtc/NodeWebrtcConnection.ts",
15
+ "src/connection/websocket/NodeWebsocketClientConnection.ts"
15
16
  ]
16
17
  }
@@ -10,7 +10,8 @@
10
10
  "package.json"
11
11
  ],
12
12
  "exclude": [
13
- "src/connection/webrtc/BrowserWebrtcConnection.ts"
13
+ "src/connection/webrtc/BrowserWebrtcConnection.ts",
14
+ "src/connection/websocket/BrowserWebsocketClientConnection.ts"
14
15
  ],
15
16
  "references": [
16
17
  { "path": "../utils/tsconfig.node.json" },
@@ -9,7 +9,8 @@
9
9
  "package.json"
10
10
  ],
11
11
  "exclude": [
12
- "src/connection/webrtc/BrowserWebrtcConnection.ts"
12
+ "src/connection/webrtc/BrowserWebrtcConnection.ts",
13
+ "src/connection/websocket/BrowserWebsocketClientConnection.ts"
13
14
  ],
14
15
  "references": [
15
16
  { "path": "../utils/tsconfig.node.json" },
@@ -1 +0,0 @@
1
- {"version":3,"file":"ConnectionLockHandler.js","sourceRoot":"","sources":["../../../src/connection/ConnectionLockHandler.ts"],"names":[],"mappings":"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"}
@@ -1,17 +0,0 @@
1
- import EventEmitter from 'eventemitter3';
2
- import { ConnectionEvents, ConnectionID, ConnectionType, IConnection } from '../IConnection';
3
- export declare const GOING_AWAY = 1001;
4
- export declare const CUSTOM_GOING_AWAY = 3001;
5
- export declare class ClientWebsocket extends EventEmitter<ConnectionEvents> implements IConnection {
6
- readonly connectionId: ConnectionID;
7
- private socket?;
8
- connectionType: ConnectionType;
9
- private destroyed;
10
- constructor();
11
- connect(address: string, selfSigned?: boolean): void;
12
- private doDisconnect;
13
- send(data: Uint8Array): void;
14
- close(gracefulLeave: boolean): Promise<void>;
15
- private stopListening;
16
- destroy(): void;
17
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"ClientWebsocket.js","sourceRoot":"","sources":["../../../../src/connection/websocket/ClientWebsocket.ts"],"names":[],"mappings":"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"}
@@ -1,14 +0,0 @@
1
- export declare class MapWithTtl<K, V> {
2
- private readonly delegate;
3
- private readonly getTtl;
4
- constructor(getTtl: (value: V) => number);
5
- set(key: K, value: V): void;
6
- get(key: K): V | undefined;
7
- has(key: K): boolean;
8
- delete(key: K): void;
9
- clear(): void;
10
- size(): number;
11
- values(): IterableIterator<V>;
12
- forEach(cb: (value: V, key: K) => void): void;
13
- private createTimeout;
14
- }
@@ -1,60 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MapWithTtl = void 0;
4
- class MapWithTtl {
5
- delegate = new Map();
6
- getTtl;
7
- constructor(getTtl) {
8
- this.getTtl = getTtl;
9
- }
10
- set(key, value) {
11
- const existing = this.delegate.get(key);
12
- if (existing !== undefined) {
13
- clearTimeout(existing.timeout);
14
- }
15
- this.delegate.set(key, {
16
- value,
17
- timeout: this.createTimeout(key, value)
18
- });
19
- }
20
- get(key) {
21
- const wrapper = this.delegate.get(key);
22
- return wrapper?.value;
23
- }
24
- has(key) {
25
- return this.delegate.has(key);
26
- }
27
- delete(key) {
28
- const existing = this.delegate.get(key);
29
- if (existing !== undefined) {
30
- clearTimeout(existing.timeout);
31
- this.delegate.delete(key);
32
- }
33
- }
34
- clear() {
35
- this.delegate.forEach((value) => {
36
- clearTimeout(value.timeout);
37
- });
38
- this.delegate.clear();
39
- }
40
- size() {
41
- return this.delegate.size;
42
- }
43
- *values() {
44
- for (const v of this.delegate.values()) {
45
- yield v.value;
46
- }
47
- }
48
- forEach(cb) {
49
- this.delegate.forEach((valueWrapper, key) => {
50
- cb(valueWrapper.value, key);
51
- });
52
- }
53
- createTimeout(key, value) {
54
- return setTimeout(() => {
55
- this.delete(key);
56
- }, this.getTtl(value));
57
- }
58
- }
59
- exports.MapWithTtl = MapWithTtl;
60
- //# sourceMappingURL=MapWithTtl.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MapWithTtl.js","sourceRoot":"","sources":["../../../src/helpers/MapWithTtl.ts"],"names":[],"mappings":";;;AAKA,MAAa,UAAU;IAEF,QAAQ,GAA4B,IAAI,GAAG,EAAE,CAAA;IAC7C,MAAM,CAAsB;IAE7C,YAAY,MAA4B;QACpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACxB,CAAC;IAED,GAAG,CAAC,GAAM,EAAE,KAAQ;QAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACzB,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAClC,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE;YACnB,KAAK;YACL,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC;SAC1C,CAAC,CAAA;IACN,CAAC;IAED,GAAG,CAAC,GAAM;QACN,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACtC,OAAO,OAAO,EAAE,KAAK,CAAA;IACzB,CAAC;IAED,GAAG,CAAC,GAAM;QACN,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACjC,CAAC;IAED,MAAM,CAAC,GAAM;QACT,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACzB,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;YAC9B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC7B,CAAC;IACL,CAAC;IAED,KAAK;QACD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC5B,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC/B,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAA;IACzB,CAAC;IAED,IAAI;QACA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAA;IAC7B,CAAC;IAED,CAAC,MAAM;QACH,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YACrC,MAAM,CAAC,CAAC,KAAK,CAAA;QACjB,CAAC;IACL,CAAC;IAED,OAAO,CAAC,EAA8B;QAClC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,YAA6B,EAAE,GAAM,EAAE,EAAE;YAC5D,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAC/B,CAAC,CAAC,CAAA;IACN,CAAC;IAEO,aAAa,CAAC,GAAM,EAAE,KAAQ;QAClC,OAAO,UAAU,CAAC,GAAG,EAAE;YACnB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACpB,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;IAC1B,CAAC;CACJ;AAjED,gCAiEC"}