@streamr/trackerless-network 0.0.1-tatum.5 → 0.0.1-tatum.6

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 (50) hide show
  1. package/dist/package.json +6 -6
  2. package/dist/src/NetworkStack.d.ts +1 -1
  3. package/dist/src/NetworkStack.js.map +1 -1
  4. package/dist/src/logic/ILayer1.d.ts +2 -2
  5. package/dist/src/logic/NodeList.d.ts +2 -2
  6. package/dist/src/logic/NodeList.js +2 -2
  7. package/dist/src/logic/NodeList.js.map +1 -1
  8. package/dist/src/logic/RandomGraphNode.js +6 -6
  9. package/dist/src/logic/RandomGraphNode.js.map +1 -1
  10. package/dist/src/logic/StreamPartEntryPointDiscovery.d.ts +7 -9
  11. package/dist/src/logic/StreamPartEntryPointDiscovery.js +46 -73
  12. package/dist/src/logic/StreamPartEntryPointDiscovery.js.map +1 -1
  13. package/dist/src/logic/StreamrNode.d.ts +2 -1
  14. package/dist/src/logic/StreamrNode.js +22 -15
  15. package/dist/src/logic/StreamrNode.js.map +1 -1
  16. package/dist/src/logic/createRandomGraphNode.js +1 -1
  17. package/dist/src/logic/createRandomGraphNode.js.map +1 -1
  18. package/dist/src/logic/neighbor-discovery/NeighborFinder.js +4 -4
  19. package/dist/src/logic/neighbor-discovery/NeighborFinder.js.map +1 -1
  20. package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js +2 -2
  21. package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js.map +1 -1
  22. package/dist/src/logic/neighbor-discovery/NeighborUpdateManagerServer.js +2 -2
  23. package/dist/src/logic/neighbor-discovery/NeighborUpdateManagerServer.js.map +1 -1
  24. package/dist/src/logic/proxy/ProxyStreamConnectionClient.d.ts +2 -3
  25. package/dist/src/logic/proxy/ProxyStreamConnectionClient.js +5 -8
  26. package/dist/src/logic/proxy/ProxyStreamConnectionClient.js.map +1 -1
  27. package/dist/src/logic/proxy/ProxyStreamConnectionServer.d.ts +0 -2
  28. package/dist/src/logic/proxy/ProxyStreamConnectionServer.js +0 -6
  29. package/dist/src/logic/proxy/ProxyStreamConnectionServer.js.map +1 -1
  30. package/dist/test/utils/utils.js +0 -1
  31. package/dist/test/utils/utils.js.map +1 -1
  32. package/package.json +6 -6
  33. package/src/NetworkStack.ts +1 -1
  34. package/src/logic/ILayer1.ts +2 -5
  35. package/src/logic/NodeList.ts +2 -2
  36. package/src/logic/RandomGraphNode.ts +6 -7
  37. package/src/logic/StreamPartEntryPointDiscovery.ts +51 -86
  38. package/src/logic/StreamrNode.ts +23 -21
  39. package/src/logic/createRandomGraphNode.ts +1 -1
  40. package/src/logic/neighbor-discovery/NeighborFinder.ts +4 -4
  41. package/src/logic/neighbor-discovery/NeighborUpdateManager.ts +2 -2
  42. package/src/logic/neighbor-discovery/NeighborUpdateManagerServer.ts +2 -2
  43. package/src/logic/proxy/ProxyStreamConnectionClient.ts +6 -10
  44. package/src/logic/proxy/ProxyStreamConnectionServer.ts +0 -8
  45. package/test/end-to-end/proxy-connections.test.ts +1 -1
  46. package/test/end-to-end/websocket-full-node-network.test.ts +1 -1
  47. package/test/unit/RandomGraphNode.test.ts +6 -6
  48. package/test/unit/StreamPartEntrypointDiscovery.test.ts +15 -30
  49. package/test/utils/mock/MockLayer1.ts +5 -7
  50. package/test/utils/utils.ts +0 -1
@@ -1,15 +1,14 @@
1
- import { createHash } from 'crypto'
2
1
  import {
3
- isSamePeerDescriptor,
2
+ DataEntry,
4
3
  PeerDescriptor,
5
4
  RecursiveFindResult,
6
- DataEntry
5
+ isSamePeerDescriptor
7
6
  } from '@streamr/dht'
8
- import { Any } from '../proto/google/protobuf/any'
9
- import { Logger, setAbortableTimeout, wait } from '@streamr/utils'
10
- import { StreamPartDelivery } from './StreamrNode'
11
7
  import { StreamPartID } from '@streamr/protocol'
8
+ import { Logger, scheduleAtInterval, wait } from '@streamr/utils'
9
+ import { createHash } from 'crypto'
12
10
  import { NodeID, getNodeIdFromPeerDescriptor } from '../identifiers'
11
+ import { Any } from '../proto/google/protobuf/any'
13
12
  import { ILayer1 } from './ILayer1'
14
13
 
15
14
  export const streamPartIdToDataKey = (streamPartId: StreamPartID): Uint8Array => {
@@ -57,8 +56,9 @@ const ENTRYPOINT_STORE_LIMIT = 8
57
56
  export const NETWORK_SPLIT_AVOIDANCE_LIMIT = 4
58
57
 
59
58
  interface StreamPartEntryPointDiscoveryConfig {
60
- streamParts: Map<string, StreamPartDelivery>
59
+ streamPartId: StreamPartID
61
60
  ownPeerDescriptor: PeerDescriptor
61
+ layer1: ILayer1
62
62
  getEntryPointData: (key: Uint8Array) => Promise<RecursiveFindResult>
63
63
  getEntryPointDataViaNode: (key: Uint8Array, node: PeerDescriptor) => Promise<DataEntry[]>
64
64
  storeEntryPointData: (key: Uint8Array, data: Any) => Promise<PeerDescriptor[]>
@@ -69,19 +69,16 @@ interface StreamPartEntryPointDiscoveryConfig {
69
69
  export class StreamPartEntryPointDiscovery {
70
70
  private readonly abortController: AbortController
71
71
  private readonly config: StreamPartEntryPointDiscoveryConfig
72
- private readonly servicedStreamParts: Map<StreamPartID, NodeJS.Timeout>
73
72
  private readonly cacheInterval: number
74
- private readonly networkSplitAvoidedNodes: Map<StreamPartID, Set<NodeID>> = new Map()
73
+ private readonly networkSplitAvoidedNodes: Set<NodeID> = new Set()
75
74
 
76
75
  constructor(config: StreamPartEntryPointDiscoveryConfig) {
77
76
  this.config = config
78
77
  this.abortController = new AbortController()
79
78
  this.cacheInterval = this.config.cacheInterval ?? 60000
80
- this.servicedStreamParts = new Map()
81
79
  }
82
80
 
83
81
  async discoverEntryPointsFromDht(
84
- streamPartId: StreamPartID,
85
82
  knownEntryPointCount: number,
86
83
  forwardingNode?: PeerDescriptor
87
84
  ): Promise<FindEntryPointsResult> {
@@ -91,7 +88,7 @@ export class StreamPartEntryPointDiscovery {
91
88
  discoveredEntryPoints: []
92
89
  }
93
90
  }
94
- const discoveredEntryPoints = await this.discoverEntryPoints(streamPartId, forwardingNode)
91
+ const discoveredEntryPoints = await this.discoverEntryPoints(forwardingNode)
95
92
  if (discoveredEntryPoints.length === 0) {
96
93
  discoveredEntryPoints.push(this.config.ownPeerDescriptor)
97
94
  }
@@ -101,20 +98,19 @@ export class StreamPartEntryPointDiscovery {
101
98
  }
102
99
  }
103
100
 
104
- private async discoverEntryPoints(streamPartId: StreamPartID, forwardingNode?: PeerDescriptor): Promise<PeerDescriptor[]> {
105
- const dataKey = streamPartIdToDataKey(streamPartId)
106
- let discoveredEntryPoints = forwardingNode ?
101
+ private async discoverEntryPoints(forwardingNode?: PeerDescriptor): Promise<PeerDescriptor[]> {
102
+ const dataKey = streamPartIdToDataKey(this.config.streamPartId)
103
+ const discoveredEntryPoints = forwardingNode ?
107
104
  await this.queryEntryPointsViaNode(dataKey, forwardingNode) : await this.queryEntrypoints(dataKey)
108
105
 
109
- if (this.networkSplitAvoidedNodes.has(streamPartId)) {
110
- const filtered = discoveredEntryPoints.filter((node) =>
111
- !this.networkSplitAvoidedNodes.get(streamPartId)!.has(getNodeIdFromPeerDescriptor(node)))
112
- // If all discovered entry points have previously beed detected as offline, try again
113
- if (filtered.length > 0) {
114
- discoveredEntryPoints = filtered
115
- }
106
+ const filtered = discoveredEntryPoints.filter((node) =>
107
+ !this.networkSplitAvoidedNodes.has(getNodeIdFromPeerDescriptor(node)))
108
+ // If all discovered entry points have previously been detected as offline, try again
109
+ if (filtered.length > 0) {
110
+ return filtered
111
+ } else {
112
+ return discoveredEntryPoints
116
113
  }
117
- return discoveredEntryPoints
118
114
  }
119
115
 
120
116
  private async queryEntrypoints(key: Uint8Array): Promise<PeerDescriptor[]> {
@@ -131,6 +127,7 @@ export class StreamPartEntryPointDiscovery {
131
127
  }
132
128
  }
133
129
 
130
+ // TODO remove this method in NET-1122
134
131
  private async queryEntryPointsViaNode(key: Uint8Array, node: PeerDescriptor): Promise<PeerDescriptor[]> {
135
132
  logger.trace(`Finding data via node ${this.config.ownPeerDescriptor.nodeName}`)
136
133
  try {
@@ -145,96 +142,64 @@ export class StreamPartEntryPointDiscovery {
145
142
  }
146
143
  }
147
144
 
148
- async storeSelfAsEntryPointIfNecessary(
149
- streamPartId: StreamPartID,
150
- entryPointsFromDht: boolean,
151
- currentEntrypointCount: number
152
- ): Promise<void> {
153
- if (!this.config.streamParts.has(streamPartId) || !entryPointsFromDht) {
145
+ async storeSelfAsEntryPointIfNecessary(currentEntrypointCount: number): Promise<void> {
146
+ if (this.abortController.signal.aborted) {
154
147
  return
155
148
  }
156
- if ((this.config.streamParts.get(streamPartId)! as { layer1: ILayer1 }).layer1!.getBucketSize() < NETWORK_SPLIT_AVOIDANCE_LIMIT) {
157
- await this.storeSelfAsEntryPoint(streamPartId)
158
- setImmediate(() => this.avoidNetworkSplit(streamPartId))
159
- } else if (currentEntrypointCount < ENTRYPOINT_STORE_LIMIT) {
160
- await this.storeSelfAsEntryPoint(streamPartId)
149
+ const possibleNetworkSplitDetected = this.config.layer1.getBucketSize() < NETWORK_SPLIT_AVOIDANCE_LIMIT
150
+ if ((currentEntrypointCount < ENTRYPOINT_STORE_LIMIT) || possibleNetworkSplitDetected) {
151
+ await this.storeSelfAsEntryPoint()
152
+ await this.keepSelfAsEntryPoint()
153
+ }
154
+ if (possibleNetworkSplitDetected) {
155
+ setImmediate(() => this.avoidNetworkSplit())
161
156
  }
162
157
  }
163
158
 
164
- private async storeSelfAsEntryPoint(streamPartId: StreamPartID): Promise<void> {
159
+ private async storeSelfAsEntryPoint(): Promise<void> {
165
160
  const ownPeerDescriptor = this.config.ownPeerDescriptor
166
161
  const dataToStore = Any.pack(ownPeerDescriptor, PeerDescriptor)
167
162
  try {
168
- await this.config.storeEntryPointData(streamPartIdToDataKey(streamPartId), dataToStore)
169
- this.keepSelfAsEntryPoint(streamPartId)
163
+ await this.config.storeEntryPointData(streamPartIdToDataKey(this.config.streamPartId), dataToStore)
170
164
  } catch (err) {
171
- logger.warn(`Failed to store self as entrypoint for ${streamPartId}`)
165
+ logger.warn(`Failed to store self as entrypoint for ${this.config.streamPartId}`)
172
166
  }
173
167
  }
174
168
 
175
- private keepSelfAsEntryPoint(streamPartId: StreamPartID): void {
176
- if (!this.config.streamParts.has(streamPartId) || this.servicedStreamParts.has(streamPartId)) {
177
- return
178
- }
179
- this.servicedStreamParts.set(streamPartId, setTimeout(async () => {
180
- if (!this.config.streamParts.has(streamPartId)) {
181
- this.servicedStreamParts.delete(streamPartId)
182
- return
183
- }
184
- logger.trace(`Attempting to keep self as entrypoint for ${streamPartId}`)
169
+ private async keepSelfAsEntryPoint(): Promise<void> {
170
+ await scheduleAtInterval(async () => {
171
+ logger.trace(`Attempting to keep self as entrypoint for ${this.config.streamPartId}`)
185
172
  try {
186
- const discovered = await this.discoverEntryPoints(streamPartId)
173
+ const discovered = await this.discoverEntryPoints()
187
174
  if (discovered.length < ENTRYPOINT_STORE_LIMIT
188
175
  || discovered.some((peerDescriptor) => isSamePeerDescriptor(peerDescriptor, this.config.ownPeerDescriptor))) {
189
- await this.storeSelfAsEntryPoint(streamPartId)
190
- this.servicedStreamParts.delete(streamPartId)
191
- this.keepSelfAsEntryPoint(streamPartId)
192
- } else {
193
- this.servicedStreamParts.delete(streamPartId)
176
+ await this.storeSelfAsEntryPoint()
194
177
  }
195
178
  } catch (err) {
196
- logger.debug(`Failed to keep self as entrypoint for ${streamPartId}`)
179
+ logger.debug(`Failed to keep self as entrypoint for ${this.config.streamPartId}`)
197
180
  }
198
- }, this.cacheInterval))
181
+ }, this.cacheInterval, false, this.abortController.signal)
199
182
  }
200
183
 
201
- private async avoidNetworkSplit(streamPartId: StreamPartID): Promise<void> {
184
+ private async avoidNetworkSplit(): Promise<void> {
202
185
  await exponentialRunOff(async () => {
203
- if (this.config.streamParts.has(streamPartId)) {
204
- const stream = this.config.streamParts.get(streamPartId)! as { layer1: ILayer1 }
205
- const rediscoveredEntrypoints = await this.discoverEntryPoints(streamPartId)
206
- await stream.layer1!.joinDht(rediscoveredEntrypoints, false, false)
207
- if (stream.layer1!.getBucketSize() < NETWORK_SPLIT_AVOIDANCE_LIMIT) {
208
- // Filter out nodes that are not in the k-bucket, assumed to be offline
209
- const nodesToAvoid = rediscoveredEntrypoints.filter((peer) => !stream.layer1!.getKBucketPeers().includes(peer))
210
- this.addAvoidedNodes(streamPartId, nodesToAvoid)
211
- throw new Error(`Network split is still possible`)
212
- }
186
+ const rediscoveredEntrypoints = await this.discoverEntryPoints()
187
+ await this.config.layer1.joinDht(rediscoveredEntrypoints, false, false)
188
+ if (this.config.layer1!.getBucketSize() < NETWORK_SPLIT_AVOIDANCE_LIMIT) {
189
+ // Filter out nodes that are not in the k-bucket, assumed to be offline
190
+ const nodesToAvoid = rediscoveredEntrypoints
191
+ .filter((peer) => !this.config.layer1!.getKBucketPeers().includes(peer))
192
+ .map((peer) => getNodeIdFromPeerDescriptor(peer))
193
+ nodesToAvoid.forEach((node) => this.networkSplitAvoidedNodes.add(node))
194
+ throw new Error(`Network split is still possible`)
213
195
  }
214
196
  }, 'avoid network split', this.abortController.signal)
215
- this.networkSplitAvoidedNodes.delete(streamPartId)
197
+ this.networkSplitAvoidedNodes.clear()
216
198
  logger.trace(`Network split avoided`)
217
199
  }
218
200
 
219
- private addAvoidedNodes(streamPartId: StreamPartID, nodesToAvoid: PeerDescriptor[]): void {
220
- if (!this.networkSplitAvoidedNodes.has(streamPartId)) {
221
- this.networkSplitAvoidedNodes.set(streamPartId, new Set())
222
- }
223
- nodesToAvoid.forEach((node) => this.networkSplitAvoidedNodes.get(streamPartId)!.add(getNodeIdFromPeerDescriptor(node)))
224
- }
225
-
226
- removeSelfAsEntryPoint(streamPartId: StreamPartID): void {
227
- if (this.servicedStreamParts.has(streamPartId)) {
228
- setAbortableTimeout(() => this.config.deleteEntryPointData(streamPartIdToDataKey(streamPartId)), 0, this.abortController.signal)
229
- clearTimeout(this.servicedStreamParts.get(streamPartId))
230
- this.servicedStreamParts.delete(streamPartId)
231
- }
232
- }
233
-
234
201
  async destroy(): Promise<void> {
235
- this.servicedStreamParts.forEach((_, streamPartId) => this.removeSelfAsEntryPoint(streamPartId))
236
- this.servicedStreamParts.clear()
237
202
  this.abortController.abort()
203
+ await this.config.deleteEntryPointData(streamPartIdToDataKey(this.config.streamPartId))
238
204
  }
239
-
240
205
  }
@@ -31,6 +31,7 @@ export type StreamPartDelivery = {
31
31
  proxied: false
32
32
  layer1: ILayer1
33
33
  node: RandomGraphNode
34
+ entryPointDiscovery: StreamPartEntryPointDiscovery
34
35
  } | {
35
36
  proxied: true
36
37
  client: ProxyStreamConnectionClient
@@ -63,7 +64,6 @@ export class StreamrNode extends EventEmitter<Events> {
63
64
  private P2PTransport?: ITransport
64
65
  private connectionLocker?: ConnectionLocker
65
66
  private layer0?: ILayer0
66
- private streamPartEntryPointDiscovery?: StreamPartEntryPointDiscovery
67
67
  private readonly metricsContext: MetricsContext
68
68
  private readonly metrics: Metrics
69
69
  public config: StreamrNodeConfig
@@ -93,14 +93,6 @@ export class StreamrNode extends EventEmitter<Events> {
93
93
  this.layer0 = startedAndJoinedLayer0
94
94
  this.P2PTransport = transport
95
95
  this.connectionLocker = connectionLocker
96
- this.streamPartEntryPointDiscovery = new StreamPartEntryPointDiscovery({
97
- ownPeerDescriptor: this.getPeerDescriptor(),
98
- streamParts: this.streamParts,
99
- getEntryPointData: (key) => this.layer0!.getDataFromDht(key),
100
- getEntryPointDataViaNode: (key, node) => this.layer0!.findDataViaPeer(key, node),
101
- storeEntryPointData: (key, data) => this.layer0!.storeDataToDht(key, data),
102
- deleteEntryPointData: (key) => this.layer0!.deleteDataFromDht(key)
103
- })
104
96
  cleanUp = () => this.destroy()
105
97
  }
106
98
 
@@ -111,14 +103,12 @@ export class StreamrNode extends EventEmitter<Events> {
111
103
  logger.trace('Destroying StreamrNode...')
112
104
  this.destroyed = true
113
105
  this.streamParts.forEach((stream) => stream.stop())
114
- await this.streamPartEntryPointDiscovery!.destroy()
115
106
  this.streamParts.clear()
116
107
  this.removeAllListeners()
117
108
  await this.layer0!.stop()
118
109
  await this.P2PTransport!.stop()
119
110
  this.layer0 = undefined
120
111
  this.P2PTransport = undefined
121
- this.streamPartEntryPointDiscovery = undefined
122
112
  this.connectionLocker = undefined
123
113
  }
124
114
 
@@ -136,7 +126,6 @@ export class StreamrNode extends EventEmitter<Events> {
136
126
  stream.stop()
137
127
  this.streamParts.delete(streamPartId)
138
128
  }
139
- this.streamPartEntryPointDiscovery!.removeSelfAsEntryPoint(streamPartId)
140
129
  }
141
130
 
142
131
  joinStreamPart(streamPartId: StreamPartID): void {
@@ -147,12 +136,28 @@ export class StreamrNode extends EventEmitter<Events> {
147
136
  }
148
137
  const layer1 = this.createLayer1Node(streamPartId, this.knownStreamPartEntryPoints.get(streamPartId) ?? [])
149
138
  const node = this.createRandomGraphNode(streamPartId, layer1)
139
+ const entryPointDiscovery = new StreamPartEntryPointDiscovery({
140
+ streamPartId,
141
+ ownPeerDescriptor: this.getPeerDescriptor(),
142
+ layer1,
143
+ getEntryPointData: (key) => this.layer0!.getDataFromDht(key),
144
+ getEntryPointDataViaNode: (key, node) => this.layer0!.findDataViaPeer(key, node),
145
+ storeEntryPointData: (key, data) => this.layer0!.storeDataToDht(key, data),
146
+ deleteEntryPointData: async (key) => {
147
+ if (this.destroyed) {
148
+ return
149
+ }
150
+ return this.layer0!.deleteDataFromDht(key)
151
+ }
152
+ })
150
153
  stream = {
151
154
  proxied: false,
152
155
  layer1,
153
156
  node,
157
+ entryPointDiscovery,
154
158
  broadcast: (msg: StreamMessage) => node.broadcast(msg),
155
159
  stop: () => {
160
+ entryPointDiscovery.destroy()
156
161
  node.stop()
157
162
  layer1.stop()
158
163
  }
@@ -163,14 +168,14 @@ export class StreamrNode extends EventEmitter<Events> {
163
168
  })
164
169
  setImmediate(async () => {
165
170
  try {
166
- await this.startLayersAndJoinDht(streamPartId)
171
+ await this.startLayersAndJoinDht(streamPartId, entryPointDiscovery)
167
172
  } catch (err) {
168
173
  logger.warn(`Failed to join to stream ${streamPartId} with error: ${err}`)
169
174
  }
170
175
  })
171
176
  }
172
177
 
173
- private async startLayersAndJoinDht(streamPartId: StreamPartID): Promise<void> {
178
+ private async startLayersAndJoinDht(streamPartId: StreamPartID, entryPointDiscovery: StreamPartEntryPointDiscovery): Promise<void> {
174
179
  logger.debug(`Start layers and join DHT for stream part ${streamPartId}`)
175
180
  const stream = this.streamParts.get(streamPartId)
176
181
  if ((stream === undefined) || stream.proxied) {
@@ -181,18 +186,15 @@ export class StreamrNode extends EventEmitter<Events> {
181
186
  await stream.node.start()
182
187
  let entryPoints = this.knownStreamPartEntryPoints.get(streamPartId) ?? []
183
188
  const forwardingNode = this.layer0!.isJoinOngoing() ? this.layer0!.getKnownEntryPoints()[0] : undefined
184
- const discoveryResult = await this.streamPartEntryPointDiscovery!.discoverEntryPointsFromDht(
185
- streamPartId,
189
+ const discoveryResult = await entryPointDiscovery.discoverEntryPointsFromDht(
186
190
  entryPoints.length,
187
191
  forwardingNode
188
192
  )
189
193
  entryPoints = entryPoints.concat(discoveryResult.discoveredEntryPoints)
190
194
  await stream.layer1.joinDht(sampleSize(entryPoints, NETWORK_SPLIT_AVOIDANCE_LIMIT))
191
- await this.streamPartEntryPointDiscovery!.storeSelfAsEntryPointIfNecessary(
192
- streamPartId,
193
- discoveryResult.entryPointsFromDht,
194
- entryPoints.length
195
- )
195
+ if (discoveryResult.entryPointsFromDht) {
196
+ await entryPointDiscovery.storeSelfAsEntryPointIfNecessary(entryPoints.length)
197
+ }
196
198
  }
197
199
 
198
200
  private createLayer1Node = (streamPartId: StreamPartID, entryPoints: PeerDescriptor[]): ILayer1 => {
@@ -45,7 +45,7 @@ const createConfigWithDefaults = (config: RandomGraphNodeConfig): StrictRandomGr
45
45
  const propagation = config.propagation ?? new Propagation({
46
46
  minPropagationTargets,
47
47
  sendToNeighbor: async (neighborId: NodeID, msg: StreamMessage): Promise<void> => {
48
- const remote = targetNeighbors.getNeighborById(neighborId) ?? temporaryConnectionServer.getNodes().getNeighborById(neighborId)
48
+ const remote = targetNeighbors.get(neighborId) ?? temporaryConnectionServer.getNodes().get(neighborId)
49
49
  const proxyConnection = proxyConnectionServer?.getConnection(neighborId)
50
50
  if (remote) {
51
51
  await remote.sendStreamMessage(msg)
@@ -9,8 +9,8 @@ interface FindNeighborsSessionConfig {
9
9
  N: number
10
10
  }
11
11
 
12
- const INITIAL_TIMEOUT = 100
13
- const INTERVAL_TIMEOUT = 250
12
+ const INITIAL_WAIT = 100
13
+ const INTERVAL = 250
14
14
 
15
15
  export interface INeighborFinder {
16
16
  start(excluded?: NodeID[]): void
@@ -34,7 +34,7 @@ export class NeighborFinder implements INeighborFinder {
34
34
  }
35
35
  const newExcludes = await this.config.doFindNeighbors(excluded)
36
36
  if (this.config.targetNeighbors.size() < this.config.N && newExcludes.length < this.config.nearbyNodeView.size()) {
37
- setAbortableTimeout(() => this.findNeighbors(newExcludes), INTERVAL_TIMEOUT, this.abortController.signal)
37
+ setAbortableTimeout(() => this.findNeighbors(newExcludes), INTERVAL, this.abortController.signal)
38
38
  } else {
39
39
  this.running = false
40
40
  }
@@ -49,7 +49,7 @@ export class NeighborFinder implements INeighborFinder {
49
49
  return
50
50
  }
51
51
  this.running = true
52
- setAbortableTimeout(() => this.findNeighbors(excluded), INITIAL_TIMEOUT, this.abortController.signal)
52
+ setAbortableTimeout(() => this.findNeighbors(excluded), INITIAL_WAIT, this.abortController.signal)
53
53
  }
54
54
 
55
55
  stop(): void {
@@ -50,8 +50,8 @@ export class NeighborUpdateManager implements INeighborUpdateManager {
50
50
 
51
51
  private async updateNeighborInfo(): Promise<void> {
52
52
  logger.trace(`Updating neighbor info to nodes`)
53
- const neighborDescriptors = this.config.targetNeighbors.getNodes().map((neighbor) => neighbor.getPeerDescriptor())
54
- await Promise.allSettled(this.config.targetNeighbors.getNodes().map(async (neighbor) => {
53
+ const neighborDescriptors = this.config.targetNeighbors.getAll().map((neighbor) => neighbor.getPeerDescriptor())
54
+ await Promise.allSettled(this.config.targetNeighbors.getAll().map(async (neighbor) => {
55
55
  const res = await this.createRemote(neighbor.getPeerDescriptor()).updateNeighbors(neighborDescriptors)
56
56
  if (res.removeMe) {
57
57
  this.config.targetNeighbors.remove(neighbor.getPeerDescriptor())
@@ -49,14 +49,14 @@ export class NeighborUpdateManagerServer implements INeighborUpdateRpc {
49
49
  this.config.neighborFinder.start()
50
50
  const response: NeighborUpdate = {
51
51
  randomGraphId: this.config.randomGraphId,
52
- neighborDescriptors: this.config.targetNeighbors.getNodes().map((neighbor) => neighbor.getPeerDescriptor()),
52
+ neighborDescriptors: this.config.targetNeighbors.getAll().map((neighbor) => neighbor.getPeerDescriptor()),
53
53
  removeMe: false
54
54
  }
55
55
  return response
56
56
  } else {
57
57
  const response: NeighborUpdate = {
58
58
  randomGraphId: this.config.randomGraphId,
59
- neighborDescriptors: this.config.targetNeighbors.getNodes().map((neighbor) => neighbor.getPeerDescriptor()),
59
+ neighborDescriptors: this.config.targetNeighbors.getAll().map((neighbor) => neighbor.getPeerDescriptor()),
60
60
  removeMe: true
61
61
  }
62
62
  return response
@@ -83,7 +83,7 @@ export class ProxyStreamConnectionClient extends EventEmitter {
83
83
  markAndCheckDuplicate: (msg: MessageID, prev?: MessageRef) => markAndCheckDuplicate(this.duplicateDetectors, msg, prev),
84
84
  broadcast: (message: StreamMessage, previousNode?: NodeID) => this.broadcast(message, previousNode),
85
85
  onLeaveNotice: (senderId: NodeID) => {
86
- const contact = this.targetNeighbors.getNeighborById(senderId)
86
+ const contact = this.targetNeighbors.get(senderId)
87
87
  if (contact) {
88
88
  setImmediate(() => this.onNodeDisconnected(contact.getPeerDescriptor()))
89
89
  }
@@ -94,7 +94,7 @@ export class ProxyStreamConnectionClient extends EventEmitter {
94
94
  this.propagation = new Propagation({
95
95
  minPropagationTargets: config.minPropagationTargets ?? 2,
96
96
  sendToNeighbor: async (neighborId: NodeID, msg: StreamMessage): Promise<void> => {
97
- const remote = this.targetNeighbors.getNeighborById(neighborId)
97
+ const remote = this.targetNeighbors.get(neighborId)
98
98
  if (remote) {
99
99
  await remote.sendStreamMessage(msg)
100
100
  } else {
@@ -202,7 +202,7 @@ export class ProxyStreamConnectionClient extends EventEmitter {
202
202
  logger.info('Close proxy connection', {
203
203
  nodeId
204
204
  })
205
- const server = this.targetNeighbors.getNeighborById(nodeId)
205
+ const server = this.targetNeighbors.get(nodeId)
206
206
  server?.leaveStreamPartNotice()
207
207
  this.removeConnection(nodeId)
208
208
  }
@@ -221,11 +221,7 @@ export class ProxyStreamConnectionClient extends EventEmitter {
221
221
  this.propagation.feedUnseenMessage(msg, this.targetNeighbors.getIds(), previousNode ?? null)
222
222
  }
223
223
 
224
- getTargetNeighborIds(): NodeID[] {
225
- return this.targetNeighbors.getIds()
226
- }
227
-
228
- hasProxyConnection(nodeId: NodeID, direction: ProxyDirection): boolean {
224
+ hasConnection(nodeId: NodeID, direction: ProxyDirection): boolean {
229
225
  return this.connections.has(nodeId) && this.connections.get(nodeId) === direction
230
226
  }
231
227
 
@@ -233,7 +229,7 @@ export class ProxyStreamConnectionClient extends EventEmitter {
233
229
  return this.definition!.direction
234
230
  }
235
231
 
236
- async onNodeDisconnected(peerDescriptor: PeerDescriptor): Promise<void> {
232
+ private async onNodeDisconnected(peerDescriptor: PeerDescriptor): Promise<void> {
237
233
  const nodeId = getNodeIdFromPeerDescriptor(peerDescriptor)
238
234
  if (this.connections.has(nodeId)) {
239
235
  this.config.connectionLocker.unlockConnection(peerDescriptor, 'proxy-stream-connection-client')
@@ -253,7 +249,7 @@ export class ProxyStreamConnectionClient extends EventEmitter {
253
249
  }
254
250
 
255
251
  stop(): void {
256
- this.targetNeighbors.getNodes().map((remote) => {
252
+ this.targetNeighbors.getAll().map((remote) => {
257
253
  this.config.connectionLocker.unlockConnection(remote.getPeerDescriptor(), 'proxy-stream-connection-client')
258
254
  remote.leaveStreamPartNotice()
259
255
  })
@@ -66,14 +66,6 @@ export class ProxyStreamConnectionServer extends EventEmitter<Events> implements
66
66
  this.removeAllListeners()
67
67
  }
68
68
 
69
- getConnectedNodeIds(): NodeID[] {
70
- return Array.from(this.connections.keys())
71
- }
72
-
73
- getConnections(): ProxyConnection[] {
74
- return Array.from(this.connections.values())
75
- }
76
-
77
69
  getPropagationTargets(msg: StreamMessage): NodeID[] {
78
70
  if (msg.messageType === StreamMessageType.GROUP_KEY_REQUEST) {
79
71
  try {
@@ -42,7 +42,7 @@ describe('Proxy connections', () => {
42
42
 
43
43
  const hasConnectionToProxy = (proxyNodeId: NodeID, direction: ProxyDirection): boolean => {
44
44
  const client = (proxiedNode.stack.getStreamrNode()!.getStream(STREAM_PART_ID) as { client: ProxyStreamConnectionClient }).client
45
- return client.hasProxyConnection(proxyNodeId, direction)
45
+ return client.hasConnection(proxyNodeId, direction)
46
46
  }
47
47
 
48
48
  beforeEach(async () => {
@@ -60,7 +60,7 @@ describe('Full node network with WebSocket connections only', () => {
60
60
  it('happy path', async () => {
61
61
  await Promise.all(nodes.map((node) =>
62
62
  waitForCondition(() => {
63
- return node.getStreamrNode()!.getNeighbors(randomGraphId).length >= 3
63
+ return node.getStreamrNode()!.getNeighbors(randomGraphId).length >= 4
64
64
  }
65
65
  , 120000)
66
66
  ))
@@ -68,8 +68,8 @@ describe('RandomGraphNode', () => {
68
68
  const peerDescriptor2 = createMockPeerDescriptor()
69
69
  layer1.emit('newContact', peerDescriptor1, [peerDescriptor1, peerDescriptor2])
70
70
  await waitForCondition(() => nearbyNodeView.size() === 2)
71
- expect(nearbyNodeView.getNeighborById(getNodeIdFromPeerDescriptor(peerDescriptor1))).toBeTruthy()
72
- expect(nearbyNodeView.getNeighborById(getNodeIdFromPeerDescriptor(peerDescriptor2))).toBeTruthy()
71
+ expect(nearbyNodeView.get(getNodeIdFromPeerDescriptor(peerDescriptor1))).toBeTruthy()
72
+ expect(nearbyNodeView.get(getNodeIdFromPeerDescriptor(peerDescriptor2))).toBeTruthy()
73
73
  })
74
74
 
75
75
  it('Adds Random Nodes from layer1 newRandomContact event to randomNodeView', async () => {
@@ -77,8 +77,8 @@ describe('RandomGraphNode', () => {
77
77
  const peerDescriptor2 = createMockPeerDescriptor()
78
78
  layer1.emit('newRandomContact', peerDescriptor1, [peerDescriptor1, peerDescriptor2])
79
79
  await waitForCondition(() => randomNodeView.size() === 2)
80
- expect(randomNodeView.getNeighborById(getNodeIdFromPeerDescriptor(peerDescriptor1))).toBeTruthy()
81
- expect(randomNodeView.getNeighborById(getNodeIdFromPeerDescriptor(peerDescriptor2))).toBeTruthy()
80
+ expect(randomNodeView.get(getNodeIdFromPeerDescriptor(peerDescriptor1))).toBeTruthy()
81
+ expect(randomNodeView.get(getNodeIdFromPeerDescriptor(peerDescriptor2))).toBeTruthy()
82
82
  })
83
83
 
84
84
  it('Adds Nodes from layer1 KBucket to nearbyNodeView if its size is below nodeViewSize', async () => {
@@ -87,8 +87,8 @@ describe('RandomGraphNode', () => {
87
87
  layer1.addNewRandomPeerToKBucket()
88
88
  layer1.emit('newContact', peerDescriptor1, [peerDescriptor1, peerDescriptor2])
89
89
  await waitForCondition(() => nearbyNodeView.size() === 3)
90
- expect(nearbyNodeView.getNeighborById(getNodeIdFromPeerDescriptor(peerDescriptor1))).toBeTruthy()
91
- expect(nearbyNodeView.getNeighborById(getNodeIdFromPeerDescriptor(peerDescriptor2))).toBeTruthy()
90
+ expect(nearbyNodeView.get(getNodeIdFromPeerDescriptor(peerDescriptor1))).toBeTruthy()
91
+ expect(nearbyNodeView.get(getNodeIdFromPeerDescriptor(peerDescriptor2))).toBeTruthy()
92
92
  })
93
93
 
94
94
  })