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

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 (186) hide show
  1. package/dist/package.json +10 -8
  2. package/dist/src/NetworkNode.js +2 -2
  3. package/dist/src/NetworkNode.js.map +1 -1
  4. package/dist/src/NetworkStack.d.ts +5 -6
  5. package/dist/src/NetworkStack.js +27 -56
  6. package/dist/src/NetworkStack.js.map +1 -1
  7. package/dist/src/identifiers.js +2 -2
  8. package/dist/src/identifiers.js.map +1 -1
  9. package/dist/src/logic/{StreamNodeServer.d.ts → DeliveryRpcLocal.d.ts} +6 -5
  10. package/dist/src/logic/{StreamNodeServer.js → DeliveryRpcLocal.js} +5 -5
  11. package/dist/src/logic/{StreamNodeServer.js.map → DeliveryRpcLocal.js.map} +1 -1
  12. package/dist/src/logic/{RemoteRandomGraphNode.d.ts → DeliveryRpcRemote.d.ts} +2 -2
  13. package/dist/src/logic/{RemoteRandomGraphNode.js → DeliveryRpcRemote.js} +5 -5
  14. package/dist/src/logic/DeliveryRpcRemote.js.map +1 -0
  15. package/dist/src/logic/{StreamPartEntryPointDiscovery.d.ts → EntryPointDiscovery.d.ts} +10 -12
  16. package/dist/src/logic/{StreamPartEntryPointDiscovery.js → EntryPointDiscovery.js} +18 -40
  17. package/dist/src/logic/EntryPointDiscovery.js.map +1 -0
  18. package/dist/src/logic/Layer0Node.d.ts +14 -0
  19. package/dist/src/logic/{ILayer1.js → Layer0Node.js} +1 -1
  20. package/dist/src/logic/Layer0Node.js.map +1 -0
  21. package/dist/src/logic/{ILayer1.d.ts → Layer1Node.d.ts} +5 -5
  22. package/dist/src/logic/{ILayer0.js → Layer1Node.js} +1 -1
  23. package/dist/src/logic/Layer1Node.js.map +1 -0
  24. package/dist/src/logic/NodeList.d.ts +10 -10
  25. package/dist/src/logic/NodeList.js.map +1 -1
  26. package/dist/src/logic/RandomGraphNode.d.ts +11 -15
  27. package/dist/src/logic/RandomGraphNode.js +46 -45
  28. package/dist/src/logic/RandomGraphNode.js.map +1 -1
  29. package/dist/src/logic/StreamrNode.d.ts +15 -18
  30. package/dist/src/logic/StreamrNode.js +78 -87
  31. package/dist/src/logic/StreamrNode.js.map +1 -1
  32. package/dist/src/logic/createRandomGraphNode.d.ts +6 -1
  33. package/dist/src/logic/createRandomGraphNode.js +17 -23
  34. package/dist/src/logic/createRandomGraphNode.js.map +1 -1
  35. package/dist/src/logic/formStreamPartDeliveryServiceId.d.ts +2 -0
  36. package/dist/src/logic/formStreamPartDeliveryServiceId.js +8 -0
  37. package/dist/src/logic/formStreamPartDeliveryServiceId.js.map +1 -0
  38. package/dist/src/logic/inspect/Inspector.d.ts +3 -2
  39. package/dist/src/logic/inspect/Inspector.js +5 -5
  40. package/dist/src/logic/inspect/Inspector.js.map +1 -1
  41. package/dist/src/logic/neighbor-discovery/{HandshakerServer.d.ts → HandshakeRpcLocal.d.ts} +10 -10
  42. package/dist/src/logic/neighbor-discovery/{HandshakerServer.js → HandshakeRpcLocal.js} +13 -13
  43. package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.js.map +1 -0
  44. package/dist/src/logic/neighbor-discovery/{RemoteHandshaker.d.ts → HandshakeRpcRemote.d.ts} +1 -1
  45. package/dist/src/logic/neighbor-discovery/{RemoteHandshaker.js → HandshakeRpcRemote.js} +8 -7
  46. package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.js.map +1 -0
  47. package/dist/src/logic/neighbor-discovery/Handshaker.d.ts +8 -7
  48. package/dist/src/logic/neighbor-discovery/Handshaker.js +23 -24
  49. package/dist/src/logic/neighbor-discovery/Handshaker.js.map +1 -1
  50. package/dist/src/logic/neighbor-discovery/NeighborFinder.d.ts +1 -1
  51. package/dist/src/logic/neighbor-discovery/NeighborFinder.js +1 -1
  52. package/dist/src/logic/neighbor-discovery/NeighborFinder.js.map +1 -1
  53. package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.d.ts +3 -2
  54. package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js +5 -5
  55. package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js.map +1 -1
  56. package/dist/src/logic/neighbor-discovery/{NeighborUpdateManagerServer.d.ts → NeighborUpdateRpcLocal.d.ts} +6 -6
  57. package/dist/src/logic/neighbor-discovery/{NeighborUpdateManagerServer.js → NeighborUpdateRpcLocal.js} +9 -9
  58. package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.js.map +1 -0
  59. package/dist/src/logic/neighbor-discovery/{RemoteNeighborUpdateManager.d.ts → NeighborUpdateRpcRemote.d.ts} +1 -1
  60. package/dist/src/logic/neighbor-discovery/{RemoteNeighborUpdateManager.js → NeighborUpdateRpcRemote.js} +5 -5
  61. package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcRemote.js.map +1 -0
  62. package/dist/src/logic/propagation/Propagation.js +2 -2
  63. package/dist/src/logic/propagation/Propagation.js.map +1 -1
  64. package/dist/src/logic/proxy/{ProxyStreamConnectionClient.d.ts → ProxyClient.d.ts} +7 -10
  65. package/dist/src/logic/proxy/{ProxyStreamConnectionClient.js → ProxyClient.js} +24 -22
  66. package/dist/src/logic/proxy/ProxyClient.js.map +1 -0
  67. package/dist/src/logic/proxy/{ProxyStreamConnectionServer.d.ts → ProxyConnectionRpcLocal.d.ts} +5 -5
  68. package/dist/src/logic/proxy/{ProxyStreamConnectionServer.js → ProxyConnectionRpcLocal.js} +6 -6
  69. package/dist/src/logic/proxy/ProxyConnectionRpcLocal.js.map +1 -0
  70. package/dist/src/logic/proxy/{RemoteProxyServer.d.ts → ProxyConnectionRpcRemote.d.ts} +1 -1
  71. package/dist/src/logic/proxy/{RemoteProxyServer.js → ProxyConnectionRpcRemote.js} +4 -4
  72. package/dist/src/logic/proxy/ProxyConnectionRpcRemote.js.map +1 -0
  73. package/dist/src/logic/temporary-connection/{TemporaryConnectionRpcServer.d.ts → TemporaryConnectionRpcLocal.d.ts} +5 -4
  74. package/dist/src/logic/temporary-connection/{TemporaryConnectionRpcServer.js → TemporaryConnectionRpcLocal.js} +6 -6
  75. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.js.map +1 -0
  76. package/dist/src/logic/temporary-connection/{RemoteTemporaryConnectionRpcServer.d.ts → TemporaryConnectionRpcRemote.d.ts} +1 -1
  77. package/dist/src/logic/temporary-connection/{RemoteTemporaryConnectionRpcServer.js → TemporaryConnectionRpcRemote.js} +4 -4
  78. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcRemote.js.map +1 -0
  79. package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +10 -0
  80. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +7 -0
  81. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
  82. package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +54 -118
  83. package/dist/src/proto/packages/dht/protos/DhtRpc.js +50 -49
  84. package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
  85. package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +6 -0
  86. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.d.ts +4 -4
  87. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.js +7 -7
  88. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.js.map +1 -1
  89. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.d.ts +10 -10
  90. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js +7 -7
  91. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js.map +1 -1
  92. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.server.d.ts +2 -2
  93. package/dist/test/benchmark/first-message.js +16 -17
  94. package/dist/test/benchmark/first-message.js.map +1 -1
  95. package/dist/test/utils/utils.d.ts +7 -6
  96. package/dist/test/utils/utils.js +18 -17
  97. package/dist/test/utils/utils.js.map +1 -1
  98. package/package.json +10 -8
  99. package/protos/NetworkRpc.proto +5 -5
  100. package/src/NetworkNode.ts +2 -2
  101. package/src/NetworkStack.ts +31 -72
  102. package/src/identifiers.ts +3 -3
  103. package/src/logic/{StreamNodeServer.ts → DeliveryRpcLocal.ts} +8 -7
  104. package/src/logic/{RemoteRandomGraphNode.ts → DeliveryRpcRemote.ts} +3 -3
  105. package/src/logic/{StreamPartEntryPointDiscovery.ts → EntryPointDiscovery.ts} +24 -48
  106. package/src/logic/Layer0Node.ts +15 -0
  107. package/src/logic/{ILayer1.ts → Layer1Node.ts} +5 -5
  108. package/src/logic/NodeList.ts +12 -12
  109. package/src/logic/RandomGraphNode.ts +73 -74
  110. package/src/logic/StreamrNode.ts +90 -103
  111. package/src/logic/createRandomGraphNode.ts +28 -26
  112. package/src/logic/formStreamPartDeliveryServiceId.ts +5 -0
  113. package/src/logic/inspect/Inspector.ts +8 -7
  114. package/src/logic/neighbor-discovery/{HandshakerServer.ts → HandshakeRpcLocal.ts} +20 -20
  115. package/src/logic/neighbor-discovery/{RemoteHandshaker.ts → HandshakeRpcRemote.ts} +6 -5
  116. package/src/logic/neighbor-discovery/Handshaker.ts +38 -38
  117. package/src/logic/neighbor-discovery/NeighborFinder.ts +2 -2
  118. package/src/logic/neighbor-discovery/NeighborUpdateManager.ts +13 -10
  119. package/src/logic/neighbor-discovery/{NeighborUpdateManagerServer.ts → NeighborUpdateRpcLocal.ts} +15 -15
  120. package/src/logic/neighbor-discovery/{RemoteNeighborUpdateManager.ts → NeighborUpdateRpcRemote.ts} +2 -2
  121. package/src/logic/propagation/Propagation.ts +2 -2
  122. package/src/logic/proxy/{ProxyStreamConnectionClient.ts → ProxyClient.ts} +29 -29
  123. package/src/logic/proxy/{ProxyStreamConnectionServer.ts → ProxyConnectionRpcLocal.ts} +10 -11
  124. package/src/logic/proxy/{RemoteProxyServer.ts → ProxyConnectionRpcRemote.ts} +1 -1
  125. package/src/logic/temporary-connection/{TemporaryConnectionRpcServer.ts → TemporaryConnectionRpcLocal.ts} +11 -10
  126. package/src/logic/temporary-connection/{RemoteTemporaryConnectionRpcServer.ts → TemporaryConnectionRpcRemote.ts} +1 -1
  127. package/src/proto/packages/dht/protos/DhtRpc.client.ts +13 -0
  128. package/src/proto/packages/dht/protos/DhtRpc.server.ts +6 -0
  129. package/src/proto/packages/dht/protos/DhtRpc.ts +88 -166
  130. package/src/proto/packages/trackerless-network/protos/NetworkRpc.client.ts +8 -8
  131. package/src/proto/packages/trackerless-network/protos/NetworkRpc.server.ts +2 -2
  132. package/src/proto/packages/trackerless-network/protos/NetworkRpc.ts +14 -14
  133. package/test/benchmark/first-message.ts +19 -20
  134. package/test/end-to-end/inspect.test.ts +12 -12
  135. package/test/end-to-end/proxy-and-full-node.test.ts +17 -18
  136. package/test/end-to-end/proxy-connections.test.ts +9 -11
  137. package/test/end-to-end/proxy-key-exchange.test.ts +12 -13
  138. package/test/end-to-end/random-graph-with-real-connections.test.ts +27 -22
  139. package/test/end-to-end/webrtc-full-node-network.test.ts +8 -8
  140. package/test/end-to-end/websocket-full-node-network.test.ts +8 -10
  141. package/test/integration/{RemoteRandomGraphNode.test.ts → DeliveryRpcRemote.test.ts} +17 -14
  142. package/test/integration/{RemoteHandshaker.test.ts → HandshakeRpcRemote.test.ts} +10 -9
  143. package/test/integration/Handshakes.test.ts +23 -20
  144. package/test/integration/Inspect.test.ts +4 -3
  145. package/test/integration/{RemoteNeighborUpdateManager.test.ts → NeighborUpdateRpcRemote.test.ts} +12 -10
  146. package/test/integration/NetworkNode.test.ts +9 -8
  147. package/test/integration/NetworkRpc.test.ts +5 -7
  148. package/test/integration/NetworkStack.test.ts +13 -15
  149. package/test/integration/Propagation.test.ts +14 -13
  150. package/test/integration/RandomGraphNode-Layer1Node-Latencies.test.ts +23 -20
  151. package/test/integration/RandomGraphNode-Layer1Node.test.ts +30 -29
  152. package/test/integration/StreamrNode.test.ts +16 -13
  153. package/test/integration/joining-streams-on-offline-peers.test.ts +16 -18
  154. package/test/integration/stream-without-default-entrypoints.test.ts +12 -14
  155. package/test/unit/{StreamNodeServer.test.ts → DeliveryRpcLocal.test.ts} +8 -8
  156. package/test/unit/{StreamPartEntrypointDiscovery.test.ts → EntrypointDiscovery.test.ts} +27 -44
  157. package/test/unit/{HandshakerServer.test.ts → HandshakeRpcLocal.test.ts} +26 -24
  158. package/test/unit/Handshaker.test.ts +10 -8
  159. package/test/unit/Inspector.test.ts +4 -3
  160. package/test/unit/NeighborFinder.test.ts +5 -5
  161. package/test/unit/NodeList.test.ts +22 -13
  162. package/test/unit/{RemoteProxyServer.test.ts → ProxyConnectionRpcRemote.test.ts} +4 -4
  163. package/test/unit/RandomGraphNode.test.ts +15 -13
  164. package/test/unit/StreamMessageTranslator.test.ts +10 -9
  165. package/test/unit/StreamrNode.test.ts +10 -10
  166. package/test/utils/mock/{MockLayer0.ts → MockLayer0Node.ts} +23 -26
  167. package/test/utils/mock/{MockLayer1.ts → MockLayer1Node.ts} +5 -10
  168. package/test/utils/mock/MockNeighborFinder.ts +1 -2
  169. package/test/utils/mock/MockNeighborUpdateManager.ts +1 -2
  170. package/test/utils/mock/Transport.ts +2 -2
  171. package/test/utils/utils.ts +18 -16
  172. package/dist/src/logic/ILayer0.d.ts +0 -13
  173. package/dist/src/logic/ILayer0.js.map +0 -1
  174. package/dist/src/logic/ILayer1.js.map +0 -1
  175. package/dist/src/logic/RemoteRandomGraphNode.js.map +0 -1
  176. package/dist/src/logic/StreamPartEntryPointDiscovery.js.map +0 -1
  177. package/dist/src/logic/neighbor-discovery/HandshakerServer.js.map +0 -1
  178. package/dist/src/logic/neighbor-discovery/NeighborUpdateManagerServer.js.map +0 -1
  179. package/dist/src/logic/neighbor-discovery/RemoteHandshaker.js.map +0 -1
  180. package/dist/src/logic/neighbor-discovery/RemoteNeighborUpdateManager.js.map +0 -1
  181. package/dist/src/logic/proxy/ProxyStreamConnectionClient.js.map +0 -1
  182. package/dist/src/logic/proxy/ProxyStreamConnectionServer.js.map +0 -1
  183. package/dist/src/logic/proxy/RemoteProxyServer.js.map +0 -1
  184. package/dist/src/logic/temporary-connection/RemoteTemporaryConnectionRpcServer.js.map +0 -1
  185. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcServer.js.map +0 -1
  186. package/src/logic/ILayer0.ts +0 -14
@@ -1,39 +1,10 @@
1
- import { ConnectionManager, DhtNode, DhtNodeOptions, isSamePeerDescriptor } from '@streamr/dht'
1
+ import { ConnectionManager, DhtNode, DhtNodeOptions, areEqualPeerDescriptors } from '@streamr/dht'
2
2
  import { StreamrNode, StreamrNodeConfig } from './logic/StreamrNode'
3
- import { MetricsContext, waitForCondition, waitForEvent3 } from '@streamr/utils'
3
+ import { MetricsContext, waitForCondition } from '@streamr/utils'
4
4
  import { EventEmitter } from 'eventemitter3'
5
5
  import { StreamID, StreamPartID, toStreamPartID } from '@streamr/protocol'
6
6
  import { ProxyDirection, StreamMessage, StreamMessageType } from './proto/packages/trackerless-network/protos/NetworkRpc'
7
-
8
- interface ReadinessEvents {
9
- done: () => void
10
- }
11
-
12
- class ReadinessListener {
13
-
14
- private readonly emitter = new EventEmitter<ReadinessEvents>()
15
- private readonly networkStack: NetworkStack
16
- private readonly dhtNode: DhtNode
17
-
18
- constructor(networkStack: NetworkStack, dhtNode: DhtNode) {
19
- this.networkStack = networkStack
20
- this.dhtNode = dhtNode
21
- this.networkStack.on('stopped', this.onDone)
22
- this.dhtNode.on('connected', this.onDone)
23
- }
24
-
25
- private onDone = () => {
26
- this.networkStack.off('stopped', this.onDone)
27
- this.dhtNode.off('connected', this.onDone)
28
- this.emitter.emit('done')
29
- }
30
-
31
- public async waitUntilReady(timeout: number): Promise<void> {
32
- if (this.dhtNode.getNumberOfConnections() === 0) {
33
- await waitForEvent3<ReadinessEvents>(this.emitter, 'done', timeout)
34
- }
35
- }
36
- }
7
+ import { Layer0Node } from './logic/Layer0Node'
37
8
 
38
9
  export interface NetworkOptions {
39
10
  layer0?: DhtNodeOptions
@@ -45,11 +16,9 @@ export interface NetworkStackEvents {
45
16
  stopped: () => void
46
17
  }
47
18
 
48
- const DEFAULT_FIRST_CONNECTION_TIMEOUT = 5000
49
-
50
19
  export class NetworkStack extends EventEmitter<NetworkStackEvents> {
51
20
 
52
- private layer0DhtNode?: DhtNode
21
+ private layer0Node?: Layer0Node
53
22
  private streamrNode?: StreamrNode
54
23
  private readonly metricsContext: MetricsContext
55
24
  private readonly options: NetworkOptions
@@ -58,13 +27,12 @@ export class NetworkStack extends EventEmitter<NetworkStackEvents> {
58
27
  super()
59
28
  this.options = options
60
29
  this.metricsContext = options.metricsContext ?? new MetricsContext()
61
- this.layer0DhtNode = new DhtNode({
30
+ this.layer0Node = new DhtNode({
62
31
  ...options.layer0,
63
32
  metricsContext: this.metricsContext
64
33
  })
65
34
  this.streamrNode = new StreamrNode({
66
35
  ...options.networkNode,
67
- nodeName: options.networkNode?.nodeName ?? options.layer0?.nodeName,
68
36
  metricsContext: this.metricsContext
69
37
  })
70
38
  }
@@ -73,7 +41,7 @@ export class NetworkStack extends EventEmitter<NetworkStackEvents> {
73
41
  if (this.getStreamrNode().isProxiedStreamPart(streamPartId)) {
74
42
  throw new Error(`Cannot join to ${streamPartId} as proxy connections have been set`)
75
43
  }
76
- await this.joinLayer0IfRequired(streamPartId)
44
+ await this.ensureConnectedToControlLayer()
77
45
  this.getStreamrNode().joinStreamPart(streamPartId)
78
46
  if (neighborRequirement !== undefined) {
79
47
  await waitForCondition(() => {
@@ -87,59 +55,50 @@ export class NetworkStack extends EventEmitter<NetworkStackEvents> {
87
55
  if (this.getStreamrNode().isProxiedStreamPart(streamPartId, ProxyDirection.SUBSCRIBE) && (msg.messageType === StreamMessageType.MESSAGE)) {
88
56
  throw new Error(`Cannot broadcast to ${streamPartId} as proxy subscribe connections have been set`)
89
57
  }
90
- await this.joinLayer0IfRequired(streamPartId)
58
+ // TODO could combine these two calls to isProxiedStreamPart?
59
+ if (!this.streamrNode!.isProxiedStreamPart(streamPartId)) {
60
+ await this.ensureConnectedToControlLayer()
61
+ }
91
62
  this.getStreamrNode().broadcast(msg)
92
63
  }
93
64
 
94
65
  async start(doJoin = true): Promise<void> {
95
- await this.layer0DhtNode!.start()
96
- const connectionManager = this.layer0DhtNode!.getTransport() as ConnectionManager
66
+ await this.layer0Node!.start()
67
+ const connectionManager = this.layer0Node!.getTransport() as ConnectionManager
97
68
  if ((this.options.layer0?.entryPoints !== undefined) && (this.options.layer0.entryPoints.some((entryPoint) =>
98
- isSamePeerDescriptor(entryPoint, this.layer0DhtNode!.getPeerDescriptor())
69
+ areEqualPeerDescriptors(entryPoint, this.layer0Node!.getPeerDescriptor())
99
70
  ))) {
100
- await this.layer0DhtNode?.joinDht(this.options.layer0.entryPoints)
71
+ await this.layer0Node?.joinDht(this.options.layer0.entryPoints)
101
72
  } else {
102
73
  if (doJoin) {
103
- await this.joinDht()
74
+ // in practice there aren't be existing connections and therefore this always connects
75
+ await this.ensureConnectedToControlLayer()
104
76
  }
105
77
  }
106
- await this.streamrNode?.start(this.layer0DhtNode!, connectionManager, connectionManager)
107
- }
108
-
109
- private async joinDht(): Promise<void> {
110
- setImmediate(async () => {
111
- if (this.options.layer0?.entryPoints !== undefined) {
112
- // TODO should catch possible rejection?
113
- await this.layer0DhtNode?.joinDht(this.options.layer0.entryPoints)
114
- }
115
- })
116
- await this.waitForFirstConnection()
78
+ await this.streamrNode?.start(this.layer0Node!, connectionManager, connectionManager)
117
79
  }
118
80
 
119
- private async waitForFirstConnection(): Promise<void> {
120
- const readinessListener = new ReadinessListener(this, this.layer0DhtNode!)
121
- const timeout = this.options.networkNode?.firstConnectionTimeout ?? DEFAULT_FIRST_CONNECTION_TIMEOUT
122
- await readinessListener.waitUntilReady(timeout)
123
- }
124
-
125
- private async joinLayer0IfRequired(streamPartId: StreamPartID): Promise<void> {
126
- if (this.streamrNode!.isProxiedStreamPart(streamPartId)) {
127
- return
128
- }
81
+ private async ensureConnectedToControlLayer(): Promise<void> {
129
82
  // TODO we could wrap joinDht with pOnce and call it here (no else-if needed in that case)
130
- if (!this.layer0DhtNode!.hasJoined()) {
131
- await this.joinDht()
132
- } else if (this.layer0DhtNode!.getNumberOfConnections() < 1) {
133
- await this.waitForFirstConnection()
83
+ if (!this.layer0Node!.hasJoined()) {
84
+ setImmediate(async () => {
85
+ if (this.options.layer0?.entryPoints !== undefined) {
86
+ // TODO should catch possible rejection?
87
+ // the question mark is there to avoid problems when stop() is called before start()
88
+ // -> TODO change to exlamation mark if we don't support that (and remove NetworkStackStoppedDuringStart.test)
89
+ await this.layer0Node?.joinDht(this.options.layer0.entryPoints)
90
+ }
91
+ })
134
92
  }
93
+ await this.layer0Node!.waitForNetworkConnectivity()
135
94
  }
136
95
 
137
96
  getStreamrNode(): StreamrNode {
138
97
  return this.streamrNode!
139
98
  }
140
99
 
141
- getLayer0DhtNode(): DhtNode {
142
- return this.layer0DhtNode!
100
+ getLayer0Node(): Layer0Node {
101
+ return this.layer0Node!
143
102
  }
144
103
 
145
104
  getMetricsContext(): MetricsContext {
@@ -149,7 +108,7 @@ export class NetworkStack extends EventEmitter<NetworkStackEvents> {
149
108
  async stop(): Promise<void> {
150
109
  await this.streamrNode!.destroy()
151
110
  this.streamrNode = undefined
152
- this.layer0DhtNode = undefined
111
+ this.layer0Node = undefined
153
112
  this.emit('stopped')
154
113
  }
155
114
 
@@ -1,8 +1,8 @@
1
- import { PeerDescriptor, keyFromPeerDescriptor } from '@streamr/dht'
2
- import { BrandedString } from '@streamr/utils'
1
+ import { PeerDescriptor } from '@streamr/dht'
2
+ import { BrandedString, binaryToHex } from '@streamr/utils'
3
3
 
4
4
  export type NodeID = BrandedString<'NodeID'>
5
5
 
6
6
  export const getNodeIdFromPeerDescriptor = (peerDescriptor: PeerDescriptor): NodeID => {
7
- return keyFromPeerDescriptor(peerDescriptor) as unknown as NodeID
7
+ return binaryToHex(peerDescriptor.kademliaId) as unknown as NodeID
8
8
  }
@@ -6,13 +6,14 @@ import {
6
6
  MessageRef,
7
7
  StreamMessage
8
8
  } from '../proto/packages/trackerless-network/protos/NetworkRpc'
9
- import { INetworkRpc } from '../proto/packages/trackerless-network/protos/NetworkRpc.server'
9
+ import { IDeliveryRpc } from '../proto/packages/trackerless-network/protos/NetworkRpc.server'
10
10
  import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
11
11
  import { NodeID, getNodeIdFromPeerDescriptor } from '../identifiers'
12
+ import { StreamPartID } from '@streamr/protocol'
12
13
 
13
- export interface StreamNodeServerConfig {
14
+ export interface DeliveryRpcLocalConfig {
14
15
  ownPeerDescriptor: PeerDescriptor
15
- randomGraphId: string
16
+ streamPartId: StreamPartID
16
17
  markAndCheckDuplicate: (messageId: MessageID, previousMessageRef?: MessageRef) => boolean
17
18
  broadcast: (message: StreamMessage, previousNode?: NodeID) => void
18
19
  onLeaveNotice(senderId: NodeID): void
@@ -20,11 +21,11 @@ export interface StreamNodeServerConfig {
20
21
  rpcCommunicator: ListeningRpcCommunicator
21
22
  }
22
23
 
23
- export class StreamNodeServer implements INetworkRpc {
24
+ export class DeliveryRpcLocal implements IDeliveryRpc {
24
25
 
25
- private readonly config: StreamNodeServerConfig
26
+ private readonly config: DeliveryRpcLocalConfig
26
27
 
27
- constructor(config: StreamNodeServerConfig) {
28
+ constructor(config: DeliveryRpcLocalConfig) {
28
29
  this.config = config
29
30
  }
30
31
 
@@ -38,7 +39,7 @@ export class StreamNodeServer implements INetworkRpc {
38
39
  }
39
40
 
40
41
  async leaveStreamPartNotice(message: LeaveStreamPartNotice, context: ServerCallContext): Promise<Empty> {
41
- if (message.randomGraphId === this.config.randomGraphId) {
42
+ if (message.streamPartId === this.config.streamPartId) {
42
43
  const senderPeerDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
43
44
  const senderId = getNodeIdFromPeerDescriptor(senderPeerDescriptor)
44
45
  this.config.onLeaveNotice(senderId)
@@ -4,11 +4,11 @@ import {
4
4
  LeaveStreamPartNotice,
5
5
  StreamMessage
6
6
  } from '../proto/packages/trackerless-network/protos/NetworkRpc'
7
- import { INetworkRpcClient } from '../proto/packages/trackerless-network/protos/NetworkRpc.client'
7
+ import { IDeliveryRpcClient } from '../proto/packages/trackerless-network/protos/NetworkRpc.client'
8
8
 
9
9
  const logger = new Logger(module)
10
10
 
11
- export class RemoteRandomGraphNode extends Remote<INetworkRpcClient> {
11
+ export class DeliveryRpcRemote extends Remote<IDeliveryRpcClient> {
12
12
 
13
13
  async sendStreamMessage(msg: StreamMessage): Promise<void> {
14
14
  const options = this.formDhtRpcOptions({
@@ -21,7 +21,7 @@ export class RemoteRandomGraphNode extends Remote<INetworkRpcClient> {
21
21
 
22
22
  leaveStreamPartNotice(): void {
23
23
  const notification: LeaveStreamPartNotice = {
24
- randomGraphId: this.getServiceId()
24
+ streamPartId: this.getServiceId()
25
25
  }
26
26
  const options = this.formDhtRpcOptions({
27
27
  notification: true
@@ -1,15 +1,14 @@
1
1
  import {
2
2
  DataEntry,
3
3
  PeerDescriptor,
4
- RecursiveFindResult,
5
- isSamePeerDescriptor
4
+ areEqualPeerDescriptors
6
5
  } from '@streamr/dht'
7
6
  import { StreamPartID } from '@streamr/protocol'
8
7
  import { Logger, scheduleAtInterval, wait } from '@streamr/utils'
9
8
  import { createHash } from 'crypto'
10
9
  import { NodeID, getNodeIdFromPeerDescriptor } from '../identifiers'
11
10
  import { Any } from '../proto/google/protobuf/any'
12
- import { ILayer1 } from './ILayer1'
11
+ import { Layer1Node } from './Layer1Node'
13
12
 
14
13
  export const streamPartIdToDataKey = (streamPartId: StreamPartID): Uint8Array => {
15
14
  return new Uint8Array(createHash('md5').update(streamPartId).digest())
@@ -55,32 +54,30 @@ const logger = new Logger(module)
55
54
  const ENTRYPOINT_STORE_LIMIT = 8
56
55
  export const NETWORK_SPLIT_AVOIDANCE_LIMIT = 4
57
56
 
58
- interface StreamPartEntryPointDiscoveryConfig {
57
+ interface EntryPointDiscoveryConfig {
59
58
  streamPartId: StreamPartID
60
59
  ownPeerDescriptor: PeerDescriptor
61
- layer1: ILayer1
62
- getEntryPointData: (key: Uint8Array) => Promise<RecursiveFindResult>
63
- getEntryPointDataViaNode: (key: Uint8Array, node: PeerDescriptor) => Promise<DataEntry[]>
60
+ layer1Node: Layer1Node
61
+ getEntryPointData: (key: Uint8Array) => Promise<DataEntry[]>
64
62
  storeEntryPointData: (key: Uint8Array, data: Any) => Promise<PeerDescriptor[]>
65
63
  deleteEntryPointData: (key: Uint8Array) => Promise<void>
66
- cacheInterval?: number
64
+ storeInterval?: number
67
65
  }
68
66
 
69
- export class StreamPartEntryPointDiscovery {
67
+ export class EntryPointDiscovery {
70
68
  private readonly abortController: AbortController
71
- private readonly config: StreamPartEntryPointDiscoveryConfig
72
- private readonly cacheInterval: number
69
+ private readonly config: EntryPointDiscoveryConfig
70
+ private readonly storeInterval: number
73
71
  private readonly networkSplitAvoidedNodes: Set<NodeID> = new Set()
74
72
 
75
- constructor(config: StreamPartEntryPointDiscoveryConfig) {
73
+ constructor(config: EntryPointDiscoveryConfig) {
76
74
  this.config = config
77
75
  this.abortController = new AbortController()
78
- this.cacheInterval = this.config.cacheInterval ?? 60000
76
+ this.storeInterval = this.config.storeInterval ?? 60000
79
77
  }
80
78
 
81
79
  async discoverEntryPointsFromDht(
82
- knownEntryPointCount: number,
83
- forwardingNode?: PeerDescriptor
80
+ knownEntryPointCount: number
84
81
  ): Promise<FindEntryPointsResult> {
85
82
  if (knownEntryPointCount > 0) {
86
83
  return {
@@ -88,7 +85,7 @@ export class StreamPartEntryPointDiscovery {
88
85
  discoveredEntryPoints: []
89
86
  }
90
87
  }
91
- const discoveredEntryPoints = await this.discoverEntryPoints(forwardingNode)
88
+ const discoveredEntryPoints = await this.discoverEntryPoints()
92
89
  if (discoveredEntryPoints.length === 0) {
93
90
  discoveredEntryPoints.push(this.config.ownPeerDescriptor)
94
91
  }
@@ -98,11 +95,9 @@ export class StreamPartEntryPointDiscovery {
98
95
  }
99
96
  }
100
97
 
101
- private async discoverEntryPoints(forwardingNode?: PeerDescriptor): Promise<PeerDescriptor[]> {
98
+ private async discoverEntryPoints(): Promise<PeerDescriptor[]> {
102
99
  const dataKey = streamPartIdToDataKey(this.config.streamPartId)
103
- const discoveredEntryPoints = forwardingNode ?
104
- await this.queryEntryPointsViaNode(dataKey, forwardingNode) : await this.queryEntrypoints(dataKey)
105
-
100
+ const discoveredEntryPoints = await this.queryEntrypoints(dataKey)
106
101
  const filtered = discoveredEntryPoints.filter((node) =>
107
102
  !this.networkSplitAvoidedNodes.has(getNodeIdFromPeerDescriptor(node)))
108
103
  // If all discovered entry points have previously been detected as offline, try again
@@ -114,29 +109,10 @@ export class StreamPartEntryPointDiscovery {
114
109
  }
115
110
 
116
111
  private async queryEntrypoints(key: Uint8Array): Promise<PeerDescriptor[]> {
117
- logger.trace(`Finding data from dht node ${this.config.ownPeerDescriptor.nodeName}`)
112
+ logger.trace(`Finding data from dht node ${getNodeIdFromPeerDescriptor(this.config.ownPeerDescriptor)}`)
118
113
  try {
119
- const results = await this.config.getEntryPointData(key)
120
- if (results.dataEntries) {
121
- return parseEntryPointData(results.dataEntries)
122
- } else {
123
- return []
124
- }
125
- } catch (err) {
126
- return []
127
- }
128
- }
129
-
130
- // TODO remove this method in NET-1122
131
- private async queryEntryPointsViaNode(key: Uint8Array, node: PeerDescriptor): Promise<PeerDescriptor[]> {
132
- logger.trace(`Finding data via node ${this.config.ownPeerDescriptor.nodeName}`)
133
- try {
134
- const results = await this.config.getEntryPointDataViaNode(key, node)
135
- if (results) {
136
- return parseEntryPointData(results)
137
- } else {
138
- return []
139
- }
114
+ const result = await this.config.getEntryPointData(key)
115
+ return parseEntryPointData(result)
140
116
  } catch (err) {
141
117
  return []
142
118
  }
@@ -146,7 +122,7 @@ export class StreamPartEntryPointDiscovery {
146
122
  if (this.abortController.signal.aborted) {
147
123
  return
148
124
  }
149
- const possibleNetworkSplitDetected = this.config.layer1.getBucketSize() < NETWORK_SPLIT_AVOIDANCE_LIMIT
125
+ const possibleNetworkSplitDetected = this.config.layer1Node.getBucketSize() < NETWORK_SPLIT_AVOIDANCE_LIMIT
150
126
  if ((currentEntrypointCount < ENTRYPOINT_STORE_LIMIT) || possibleNetworkSplitDetected) {
151
127
  await this.storeSelfAsEntryPoint()
152
128
  await this.keepSelfAsEntryPoint()
@@ -172,23 +148,23 @@ export class StreamPartEntryPointDiscovery {
172
148
  try {
173
149
  const discovered = await this.discoverEntryPoints()
174
150
  if (discovered.length < ENTRYPOINT_STORE_LIMIT
175
- || discovered.some((peerDescriptor) => isSamePeerDescriptor(peerDescriptor, this.config.ownPeerDescriptor))) {
151
+ || discovered.some((peerDescriptor) => areEqualPeerDescriptors(peerDescriptor, this.config.ownPeerDescriptor))) {
176
152
  await this.storeSelfAsEntryPoint()
177
153
  }
178
154
  } catch (err) {
179
155
  logger.debug(`Failed to keep self as entrypoint for ${this.config.streamPartId}`)
180
156
  }
181
- }, this.cacheInterval, false, this.abortController.signal)
157
+ }, this.storeInterval, false, this.abortController.signal)
182
158
  }
183
159
 
184
160
  private async avoidNetworkSplit(): Promise<void> {
185
161
  await exponentialRunOff(async () => {
186
162
  const rediscoveredEntrypoints = await this.discoverEntryPoints()
187
- await this.config.layer1.joinDht(rediscoveredEntrypoints, false, false)
188
- if (this.config.layer1!.getBucketSize() < NETWORK_SPLIT_AVOIDANCE_LIMIT) {
163
+ await this.config.layer1Node.joinDht(rediscoveredEntrypoints, false, false)
164
+ if (this.config.layer1Node!.getBucketSize() < NETWORK_SPLIT_AVOIDANCE_LIMIT) {
189
165
  // Filter out nodes that are not in the k-bucket, assumed to be offline
190
166
  const nodesToAvoid = rediscoveredEntrypoints
191
- .filter((peer) => !this.config.layer1!.getKBucketPeers().includes(peer))
167
+ .filter((peer) => !this.config.layer1Node!.getKBucketPeers().includes(peer))
192
168
  .map((peer) => getNodeIdFromPeerDescriptor(peer))
193
169
  nodesToAvoid.forEach((node) => this.networkSplitAvoidedNodes.add(node))
194
170
  throw new Error(`Network split is still possible`)
@@ -0,0 +1,15 @@
1
+ import { DataEntry, ITransport, PeerDescriptor } from '@streamr/dht'
2
+ import { Any } from '../proto/google/protobuf/any'
3
+
4
+ export interface Layer0Node extends ITransport {
5
+ joinDht(entryPointDescriptors: PeerDescriptor[]): Promise<void>
6
+ hasJoined(): boolean
7
+ getPeerDescriptor(): PeerDescriptor
8
+ getDataFromDht(key: Uint8Array): Promise<DataEntry[]>
9
+ storeDataToDht(key: Uint8Array, data: Any): Promise<PeerDescriptor[]>
10
+ deleteDataFromDht(key: Uint8Array): Promise<void>
11
+ waitForNetworkConnectivity(): Promise<void>
12
+ getTransport(): ITransport
13
+ start(): Promise<void>
14
+ stop(): Promise<void>
15
+ }
@@ -1,16 +1,16 @@
1
1
  import { PeerDescriptor } from '@streamr/dht'
2
2
 
3
- export interface ILayer1Events {
3
+ export interface Layer1NodeEvents {
4
4
  newContact: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
5
5
  contactRemoved: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
6
6
  newRandomContact: (peerDescriptor: PeerDescriptor, randomPeers: PeerDescriptor[]) => void
7
7
  randomContactRemoved: (peerDescriptor: PeerDescriptor, randomPeers: PeerDescriptor[]) => void
8
8
  }
9
9
 
10
- export interface ILayer1 {
11
- on<T extends keyof ILayer1Events>(eventName: T, listener: (peerDescriptor: PeerDescriptor, peers: PeerDescriptor[]) => void): void
12
- once<T extends keyof ILayer1Events>(eventName: T, listener: (peerDescriptor: PeerDescriptor, peers: PeerDescriptor[]) => void): void
13
- off<T extends keyof ILayer1Events>(eventName: T, listener: (peerDescriptor: PeerDescriptor, peers: PeerDescriptor[]) => void): void
10
+ export interface Layer1Node {
11
+ on<T extends keyof Layer1NodeEvents>(eventName: T, listener: (peerDescriptor: PeerDescriptor, peers: PeerDescriptor[]) => void): void
12
+ once<T extends keyof Layer1NodeEvents>(eventName: T, listener: (peerDescriptor: PeerDescriptor, peers: PeerDescriptor[]) => void): void
13
+ off<T extends keyof Layer1NodeEvents>(eventName: T, listener: (peerDescriptor: PeerDescriptor, peers: PeerDescriptor[]) => void): void
14
14
  removeContact: (peerDescriptor: PeerDescriptor, removeFromOpenInternetPeers?: boolean) => void
15
15
  getClosestContacts: (maxCount?: number) => PeerDescriptor[]
16
16
  getKBucketPeers: () => PeerDescriptor[]
@@ -1,21 +1,21 @@
1
1
  import { PeerDescriptor } from '@streamr/dht'
2
2
  import { sample } from 'lodash'
3
- import { RemoteRandomGraphNode } from './RemoteRandomGraphNode'
3
+ import { DeliveryRpcRemote } from './DeliveryRpcRemote'
4
4
  import { EventEmitter } from 'eventemitter3'
5
5
  import { getNodeIdFromPeerDescriptor, NodeID } from '../identifiers'
6
6
 
7
7
  export interface Events {
8
- nodeAdded: (id: NodeID, remote: RemoteRandomGraphNode) => any
8
+ nodeAdded: (id: NodeID, remote: DeliveryRpcRemote) => any
9
9
  }
10
10
 
11
- const getValuesOfIncludedKeys = (nodes: Map<NodeID, RemoteRandomGraphNode>, exclude: NodeID[]): RemoteRandomGraphNode[] => {
11
+ const getValuesOfIncludedKeys = (nodes: Map<NodeID, DeliveryRpcRemote>, exclude: NodeID[]): DeliveryRpcRemote[] => {
12
12
  return Array.from(nodes.entries())
13
13
  .filter(([id, _node]) => !exclude.includes(id))
14
14
  .map(([_id, node]) => node)
15
15
  }
16
16
 
17
17
  export class NodeList extends EventEmitter<Events> {
18
- private readonly nodes: Map<NodeID, RemoteRandomGraphNode>
18
+ private readonly nodes: Map<NodeID, DeliveryRpcRemote>
19
19
  private readonly limit: number
20
20
  private ownId: NodeID
21
21
 
@@ -26,7 +26,7 @@ export class NodeList extends EventEmitter<Events> {
26
26
  this.ownId = ownId
27
27
  }
28
28
 
29
- add(remote: RemoteRandomGraphNode): void {
29
+ add(remote: DeliveryRpcRemote): void {
30
30
  const nodeId = getNodeIdFromPeerDescriptor(remote.getPeerDescriptor())
31
31
  if ((this.ownId !== nodeId) && (this.nodes.size < this.limit)) {
32
32
  const isExistingNode = this.nodes.has(nodeId)
@@ -54,7 +54,7 @@ export class NodeList extends EventEmitter<Events> {
54
54
  return this.nodes.has(nodeId)
55
55
  }
56
56
 
57
- replaceAll(neighbors: RemoteRandomGraphNode[]): void {
57
+ replaceAll(neighbors: DeliveryRpcRemote[]): void {
58
58
  this.nodes.clear()
59
59
  const limited = neighbors.splice(0, this.limit)
60
60
  limited.forEach((remote) => {
@@ -66,7 +66,7 @@ export class NodeList extends EventEmitter<Events> {
66
66
  return Array.from(this.nodes.keys())
67
67
  }
68
68
 
69
- get(id: NodeID): RemoteRandomGraphNode | undefined {
69
+ get(id: NodeID): DeliveryRpcRemote | undefined {
70
70
  return this.nodes.get(id)
71
71
  }
72
72
 
@@ -74,16 +74,16 @@ export class NodeList extends EventEmitter<Events> {
74
74
  return Array.from(this.nodes.keys()).filter((node) => !exclude.includes(node)).length
75
75
  }
76
76
 
77
- getRandom(exclude: NodeID[]): RemoteRandomGraphNode | undefined {
77
+ getRandom(exclude: NodeID[]): DeliveryRpcRemote | undefined {
78
78
  return sample(getValuesOfIncludedKeys(this.nodes, exclude))
79
79
  }
80
80
 
81
- getClosest(exclude: NodeID[]): RemoteRandomGraphNode | undefined {
81
+ getClosest(exclude: NodeID[]): DeliveryRpcRemote | undefined {
82
82
  const included = getValuesOfIncludedKeys(this.nodes, exclude)
83
83
  return included[0]
84
84
  }
85
85
 
86
- getClosestAndFurthest(exclude: NodeID[]): RemoteRandomGraphNode[] {
86
+ getClosestAndFurthest(exclude: NodeID[]): DeliveryRpcRemote[] {
87
87
  const included = getValuesOfIncludedKeys(this.nodes, exclude)
88
88
  if (included.length === 0) {
89
89
  return []
@@ -91,12 +91,12 @@ export class NodeList extends EventEmitter<Events> {
91
91
  return included.length > 1 ? [this.getClosest(exclude)!, this.getFurthest(exclude)!] : [this.getClosest(exclude)!]
92
92
  }
93
93
 
94
- getFurthest(exclude: NodeID[]): RemoteRandomGraphNode | undefined {
94
+ getFurthest(exclude: NodeID[]): DeliveryRpcRemote | undefined {
95
95
  const included = getValuesOfIncludedKeys(this.nodes, exclude)
96
96
  return included[included.length - 1]
97
97
  }
98
98
 
99
- getAll(): RemoteRandomGraphNode[] {
99
+ getAll(): DeliveryRpcRemote[] {
100
100
  return Array.from(this.nodes.values())
101
101
  }
102
102