@streamr/trackerless-network 0.0.1-tatum.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 (262) hide show
  1. package/.eslintignore +7 -0
  2. package/.eslintrc +3 -0
  3. package/README.md +6 -0
  4. package/bin/bootstrap-node.ts +73 -0
  5. package/bin/full-node-webrtc.ts +102 -0
  6. package/bin/full-node-websocket.ts +102 -0
  7. package/bin/network.ts +43 -0
  8. package/dist/package.json +53 -0
  9. package/dist/src/NameDirectory.d.ts +5 -0
  10. package/dist/src/NameDirectory.js +44 -0
  11. package/dist/src/NameDirectory.js.map +1 -0
  12. package/dist/src/NetworkNode.d.ts +35 -0
  13. package/dist/src/NetworkNode.js +130 -0
  14. package/dist/src/NetworkNode.js.map +1 -0
  15. package/dist/src/NetworkStack.d.ts +32 -0
  16. package/dist/src/NetworkStack.js +108 -0
  17. package/dist/src/NetworkStack.js.map +1 -0
  18. package/dist/src/exports.d.ts +6 -0
  19. package/dist/src/exports.js +12 -0
  20. package/dist/src/exports.js.map +1 -0
  21. package/dist/src/identifiers.d.ts +1 -0
  22. package/dist/src/identifiers.js +3 -0
  23. package/dist/src/identifiers.js.map +1 -0
  24. package/dist/src/logic/DuplicateMessageDetector.d.ts +55 -0
  25. package/dist/src/logic/DuplicateMessageDetector.js +155 -0
  26. package/dist/src/logic/DuplicateMessageDetector.js.map +1 -0
  27. package/dist/src/logic/ILayer0.d.ts +13 -0
  28. package/dist/src/logic/ILayer0.js +3 -0
  29. package/dist/src/logic/ILayer0.js.map +1 -0
  30. package/dist/src/logic/IStreamNode.d.ts +12 -0
  31. package/dist/src/logic/IStreamNode.js +3 -0
  32. package/dist/src/logic/IStreamNode.js.map +1 -0
  33. package/dist/src/logic/PeerList.d.ts +27 -0
  34. package/dist/src/logic/PeerList.js +84 -0
  35. package/dist/src/logic/PeerList.js.map +1 -0
  36. package/dist/src/logic/RandomGraphNode.d.ts +68 -0
  37. package/dist/src/logic/RandomGraphNode.js +201 -0
  38. package/dist/src/logic/RandomGraphNode.js.map +1 -0
  39. package/dist/src/logic/Remote.d.ts +9 -0
  40. package/dist/src/logic/Remote.js +15 -0
  41. package/dist/src/logic/Remote.js.map +1 -0
  42. package/dist/src/logic/RemoteRandomGraphNode.d.ts +8 -0
  43. package/dist/src/logic/RemoteRandomGraphNode.js +35 -0
  44. package/dist/src/logic/RemoteRandomGraphNode.js.map +1 -0
  45. package/dist/src/logic/StreamEntryPointDiscovery.d.ts +36 -0
  46. package/dist/src/logic/StreamEntryPointDiscovery.js +179 -0
  47. package/dist/src/logic/StreamEntryPointDiscovery.js.map +1 -0
  48. package/dist/src/logic/StreamNodeServer.d.ts +20 -0
  49. package/dist/src/logic/StreamNodeServer.js +26 -0
  50. package/dist/src/logic/StreamNodeServer.js.map +1 -0
  51. package/dist/src/logic/StreamrNode.d.ts +76 -0
  52. package/dist/src/logic/StreamrNode.js +303 -0
  53. package/dist/src/logic/StreamrNode.js.map +1 -0
  54. package/dist/src/logic/createRandomGraphNode.d.ts +5 -0
  55. package/dist/src/logic/createRandomGraphNode.js +110 -0
  56. package/dist/src/logic/createRandomGraphNode.js.map +1 -0
  57. package/dist/src/logic/inspect/InspectSession.d.ts +18 -0
  58. package/dist/src/logic/inspect/InspectSession.js +38 -0
  59. package/dist/src/logic/inspect/InspectSession.js.map +1 -0
  60. package/dist/src/logic/inspect/Inspector.d.ts +33 -0
  61. package/dist/src/logic/inspect/Inspector.js +63 -0
  62. package/dist/src/logic/inspect/Inspector.js.map +1 -0
  63. package/dist/src/logic/neighbor-discovery/Handshaker.d.ts +35 -0
  64. package/dist/src/logic/neighbor-discovery/Handshaker.js +121 -0
  65. package/dist/src/logic/neighbor-discovery/Handshaker.js.map +1 -0
  66. package/dist/src/logic/neighbor-discovery/HandshakerServer.d.ts +30 -0
  67. package/dist/src/logic/neighbor-discovery/HandshakerServer.js +78 -0
  68. package/dist/src/logic/neighbor-discovery/HandshakerServer.js.map +1 -0
  69. package/dist/src/logic/neighbor-discovery/NeighborFinder.d.ts +23 -0
  70. package/dist/src/logic/neighbor-discovery/NeighborFinder.js +44 -0
  71. package/dist/src/logic/neighbor-discovery/NeighborFinder.js.map +1 -0
  72. package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.d.ts +30 -0
  73. package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js +42 -0
  74. package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js.map +1 -0
  75. package/dist/src/logic/neighbor-discovery/NeighborUpdateManagerServer.d.ts +20 -0
  76. package/dist/src/logic/neighbor-discovery/NeighborUpdateManagerServer.js +42 -0
  77. package/dist/src/logic/neighbor-discovery/NeighborUpdateManagerServer.js.map +1 -0
  78. package/dist/src/logic/neighbor-discovery/RemoteHandshaker.d.ts +12 -0
  79. package/dist/src/logic/neighbor-discovery/RemoteHandshaker.js +54 -0
  80. package/dist/src/logic/neighbor-discovery/RemoteHandshaker.js.map +1 -0
  81. package/dist/src/logic/neighbor-discovery/RemoteNeighborUpdateManager.d.ts +11 -0
  82. package/dist/src/logic/neighbor-discovery/RemoteNeighborUpdateManager.js +37 -0
  83. package/dist/src/logic/neighbor-discovery/RemoteNeighborUpdateManager.js.map +1 -0
  84. package/dist/src/logic/propagation/FifoMapWithTTL.d.ts +36 -0
  85. package/dist/src/logic/propagation/FifoMapWithTTL.js +81 -0
  86. package/dist/src/logic/propagation/FifoMapWithTTL.js.map +1 -0
  87. package/dist/src/logic/propagation/Propagation.d.ts +31 -0
  88. package/dist/src/logic/propagation/Propagation.js +64 -0
  89. package/dist/src/logic/propagation/Propagation.js.map +1 -0
  90. package/dist/src/logic/propagation/PropagationTaskStore.d.ts +21 -0
  91. package/dist/src/logic/propagation/PropagationTaskStore.js +32 -0
  92. package/dist/src/logic/propagation/PropagationTaskStore.js.map +1 -0
  93. package/dist/src/logic/protocol-integration/stream-message/ContentMessageTranslator.d.ts +5 -0
  94. package/dist/src/logic/protocol-integration/stream-message/ContentMessageTranslator.js +17 -0
  95. package/dist/src/logic/protocol-integration/stream-message/ContentMessageTranslator.js.map +1 -0
  96. package/dist/src/logic/protocol-integration/stream-message/GroupKeyRequestTranslator.d.ts +6 -0
  97. package/dist/src/logic/protocol-integration/stream-message/GroupKeyRequestTranslator.js +27 -0
  98. package/dist/src/logic/protocol-integration/stream-message/GroupKeyRequestTranslator.js.map +1 -0
  99. package/dist/src/logic/protocol-integration/stream-message/GroupKeyResponseTranslator.d.ts +6 -0
  100. package/dist/src/logic/protocol-integration/stream-message/GroupKeyResponseTranslator.js +33 -0
  101. package/dist/src/logic/protocol-integration/stream-message/GroupKeyResponseTranslator.js.map +1 -0
  102. package/dist/src/logic/protocol-integration/stream-message/StreamMessageTranslator.d.ts +6 -0
  103. package/dist/src/logic/protocol-integration/stream-message/StreamMessageTranslator.js +109 -0
  104. package/dist/src/logic/protocol-integration/stream-message/StreamMessageTranslator.js.map +1 -0
  105. package/dist/src/logic/proxy/ProxyStreamConnectionClient.d.ts +44 -0
  106. package/dist/src/logic/proxy/ProxyStreamConnectionClient.js +189 -0
  107. package/dist/src/logic/proxy/ProxyStreamConnectionClient.js.map +1 -0
  108. package/dist/src/logic/proxy/ProxyStreamConnectionServer.d.ts +34 -0
  109. package/dist/src/logic/proxy/ProxyStreamConnectionServer.js +64 -0
  110. package/dist/src/logic/proxy/ProxyStreamConnectionServer.js.map +1 -0
  111. package/dist/src/logic/proxy/RemoteProxyServer.d.ts +7 -0
  112. package/dist/src/logic/proxy/RemoteProxyServer.js +36 -0
  113. package/dist/src/logic/proxy/RemoteProxyServer.js.map +1 -0
  114. package/dist/src/logic/temporary-connection/RemoteTemporaryConnectionRpcServer.d.ts +6 -0
  115. package/dist/src/logic/temporary-connection/RemoteTemporaryConnectionRpcServer.js +28 -0
  116. package/dist/src/logic/temporary-connection/RemoteTemporaryConnectionRpcServer.js.map +1 -0
  117. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcServer.d.ts +20 -0
  118. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcServer.js +29 -0
  119. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcServer.js.map +1 -0
  120. package/dist/src/logic/utils.d.ts +3 -0
  121. package/dist/src/logic/utils.js +16 -0
  122. package/dist/src/logic/utils.js.map +1 -0
  123. package/dist/src/proto/google/protobuf/any.d.ts +173 -0
  124. package/dist/src/proto/google/protobuf/any.js +155 -0
  125. package/dist/src/proto/google/protobuf/any.js.map +1 -0
  126. package/dist/src/proto/google/protobuf/empty.d.ts +32 -0
  127. package/dist/src/proto/google/protobuf/empty.js +34 -0
  128. package/dist/src/proto/google/protobuf/empty.js.map +1 -0
  129. package/dist/src/proto/google/protobuf/timestamp.d.ts +149 -0
  130. package/dist/src/proto/google/protobuf/timestamp.js +136 -0
  131. package/dist/src/proto/google/protobuf/timestamp.js.map +1 -0
  132. package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +320 -0
  133. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +245 -0
  134. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -0
  135. package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +1089 -0
  136. package/dist/src/proto/packages/dht/protos/DhtRpc.js +710 -0
  137. package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -0
  138. package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +145 -0
  139. package/dist/src/proto/packages/dht/protos/DhtRpc.server.js +3 -0
  140. package/dist/src/proto/packages/dht/protos/DhtRpc.server.js.map +1 -0
  141. package/dist/src/proto/packages/proto-rpc/protos/ProtoRpc.d.ts +87 -0
  142. package/dist/src/proto/packages/proto-rpc/protos/ProtoRpc.js +66 -0
  143. package/dist/src/proto/packages/proto-rpc/protos/ProtoRpc.js.map +1 -0
  144. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.d.ts +156 -0
  145. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.js +122 -0
  146. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.js.map +1 -0
  147. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.d.ts +524 -0
  148. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js +350 -0
  149. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js.map +1 -0
  150. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.server.d.ts +65 -0
  151. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.server.js +3 -0
  152. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.server.js.map +1 -0
  153. package/dist/test/benchmark/first-message.d.ts +1 -0
  154. package/dist/test/benchmark/first-message.js +137 -0
  155. package/dist/test/benchmark/first-message.js.map +1 -0
  156. package/dist/test/utils/utils.d.ts +12 -0
  157. package/dist/test/utils/utils.js +86 -0
  158. package/dist/test/utils/utils.js.map +1 -0
  159. package/jest.config.js +36 -0
  160. package/karma.config.js +20 -0
  161. package/log.txt +501 -0
  162. package/package.json +53 -0
  163. package/proto.sh +2 -0
  164. package/protos/NetworkRpc.proto +161 -0
  165. package/src/NameDirectory.ts +44 -0
  166. package/src/NetworkNode.ts +169 -0
  167. package/src/NetworkStack.ts +144 -0
  168. package/src/exports.ts +6 -0
  169. package/src/identifiers.ts +1 -0
  170. package/src/logic/DuplicateMessageDetector.ts +167 -0
  171. package/src/logic/ILayer0.ts +14 -0
  172. package/src/logic/IStreamNode.ts +17 -0
  173. package/src/logic/PeerList.ts +106 -0
  174. package/src/logic/RandomGraphNode.ts +310 -0
  175. package/src/logic/Remote.ts +19 -0
  176. package/src/logic/RemoteRandomGraphNode.ts +39 -0
  177. package/src/logic/StreamEntryPointDiscovery.ts +221 -0
  178. package/src/logic/StreamNodeServer.ts +44 -0
  179. package/src/logic/StreamrNode.ts +416 -0
  180. package/src/logic/createRandomGraphNode.ts +114 -0
  181. package/src/logic/inspect/InspectSession.ts +49 -0
  182. package/src/logic/inspect/Inspector.ts +89 -0
  183. package/src/logic/neighbor-discovery/Handshaker.ts +180 -0
  184. package/src/logic/neighbor-discovery/HandshakerServer.ts +99 -0
  185. package/src/logic/neighbor-discovery/NeighborFinder.ts +61 -0
  186. package/src/logic/neighbor-discovery/NeighborUpdateManager.ts +67 -0
  187. package/src/logic/neighbor-discovery/NeighborUpdateManagerServer.ts +61 -0
  188. package/src/logic/neighbor-discovery/RemoteHandshaker.ts +64 -0
  189. package/src/logic/neighbor-discovery/RemoteNeighborUpdateManager.ts +41 -0
  190. package/src/logic/propagation/FifoMapWithTTL.ts +108 -0
  191. package/src/logic/propagation/Propagation.ts +83 -0
  192. package/src/logic/propagation/PropagationTaskStore.ts +40 -0
  193. package/src/logic/protocol-integration/stream-message/ContentMessageTranslator.ts +16 -0
  194. package/src/logic/protocol-integration/stream-message/GroupKeyRequestTranslator.ts +28 -0
  195. package/src/logic/protocol-integration/stream-message/GroupKeyResponseTranslator.ts +38 -0
  196. package/src/logic/protocol-integration/stream-message/StreamMessageTranslator.ts +142 -0
  197. package/src/logic/proxy/ProxyStreamConnectionClient.ts +255 -0
  198. package/src/logic/proxy/ProxyStreamConnectionServer.ts +97 -0
  199. package/src/logic/proxy/RemoteProxyServer.ts +36 -0
  200. package/src/logic/temporary-connection/RemoteTemporaryConnectionRpcServer.ts +27 -0
  201. package/src/logic/temporary-connection/TemporaryConnectionRpcServer.ts +50 -0
  202. package/src/logic/utils.ts +17 -0
  203. package/src/proto/google/protobuf/any.ts +319 -0
  204. package/src/proto/google/protobuf/empty.ts +84 -0
  205. package/src/proto/google/protobuf/timestamp.ts +281 -0
  206. package/src/proto/packages/dht/protos/DhtRpc.client.ts +373 -0
  207. package/src/proto/packages/dht/protos/DhtRpc.server.ts +148 -0
  208. package/src/proto/packages/dht/protos/DhtRpc.ts +1399 -0
  209. package/src/proto/packages/proto-rpc/protos/ProtoRpc.ts +108 -0
  210. package/src/proto/packages/trackerless-network/protos/NetworkRpc.client.ts +176 -0
  211. package/src/proto/packages/trackerless-network/protos/NetworkRpc.server.ts +68 -0
  212. package/src/proto/packages/trackerless-network/protos/NetworkRpc.ts +667 -0
  213. package/test/benchmark/first-message.ts +155 -0
  214. package/test/end-to-end/inspect.test.ts +119 -0
  215. package/test/end-to-end/proxy-and-full-node.test.ts +140 -0
  216. package/test/end-to-end/proxy-connections.test.ts +228 -0
  217. package/test/end-to-end/proxy-key-exchange.test.ts +142 -0
  218. package/test/end-to-end/random-graph-with-real-connections.test.ts +154 -0
  219. package/test/end-to-end/webrtc-full-node-network.test.ts +97 -0
  220. package/test/end-to-end/websocket-full-node-network.test.ts +93 -0
  221. package/test/integration/Handshakes.test.ts +167 -0
  222. package/test/integration/Inspect.test.ts +102 -0
  223. package/test/integration/NetworkNode.test.ts +99 -0
  224. package/test/integration/NetworkRpc.test.ts +61 -0
  225. package/test/integration/NetworkStack.test.ts +74 -0
  226. package/test/integration/NetworkStackStoppedDuringStart.test.ts +45 -0
  227. package/test/integration/Propagation.test.ts +79 -0
  228. package/test/integration/RandomGraphNode-Layer1Node-Latencies.test.ts +141 -0
  229. package/test/integration/RandomGraphNode-Layer1Node.test.ts +226 -0
  230. package/test/integration/RemoteHandshaker.test.ts +78 -0
  231. package/test/integration/RemoteNeighborUpdateManager.test.ts +82 -0
  232. package/test/integration/RemoteRandomGraphNode.test.ts +102 -0
  233. package/test/integration/StreamrNode.test.ts +145 -0
  234. package/test/integration/stream-without-default-entrypoints.test.ts +132 -0
  235. package/test/unit/ContentMessageTranslator.test.ts +20 -0
  236. package/test/unit/DuplicateMessageDetector.test.ts +192 -0
  237. package/test/unit/FifoMapWithTtl.test.ts +229 -0
  238. package/test/unit/GroupKeyRequestTranslator.test.ts +36 -0
  239. package/test/unit/GroupKeyResponseTranslator.test.ts +39 -0
  240. package/test/unit/Handshaker.test.ts +63 -0
  241. package/test/unit/HandshakerServer.test.ts +123 -0
  242. package/test/unit/InspectSession.test.ts +78 -0
  243. package/test/unit/Inspector.test.ts +57 -0
  244. package/test/unit/NeighborFinder.test.ts +48 -0
  245. package/test/unit/NumberPair.test.ts +22 -0
  246. package/test/unit/PeerList.test.ts +150 -0
  247. package/test/unit/Propagation.test.ts +134 -0
  248. package/test/unit/RandomGraphNode.test.ts +73 -0
  249. package/test/unit/StreamEntrypointDiscovery.test.ts +152 -0
  250. package/test/unit/StreamMessageTranslator.test.ts +67 -0
  251. package/test/unit/StreamNodeServer.test.ts +63 -0
  252. package/test/unit/StreamrNode.test.ts +74 -0
  253. package/test/utils/mock/MockHandshaker.ts +15 -0
  254. package/test/utils/mock/MockLayer0.ts +71 -0
  255. package/test/utils/mock/MockLayer1.ts +6 -0
  256. package/test/utils/mock/MockNeighborFinder.ts +19 -0
  257. package/test/utils/mock/MockNeighborUpdateManager.ts +21 -0
  258. package/test/utils/mock/Transport.ts +25 -0
  259. package/test/utils/utils.ts +104 -0
  260. package/tsconfig.browser.json +12 -0
  261. package/tsconfig.jest.json +15 -0
  262. package/tsconfig.node.json +18 -0
@@ -0,0 +1,155 @@
1
+ /* eslint-disable no-console */
2
+
3
+ import { PeerID, LatencyType, Simulator, getRandomRegion } from '@streamr/dht'
4
+ import fs from 'fs'
5
+ import { createNetworkNodeWithSimulator } from '../utils/utils'
6
+ import { NetworkNode } from '../../src/NetworkNode'
7
+ import { PeerDescriptor } from '../../../dht/src/exports'
8
+ import { StreamMessage, toStreamID, MessageID, StreamPartIDUtils, StreamMessageType, toStreamPartID, StreamPartID } from '@streamr/protocol'
9
+ import { waitForEvent3 } from '@streamr/utils'
10
+ import { streamPartIdToDataKey } from '../../src/logic/StreamEntryPointDiscovery'
11
+
12
+ const numNodes = 10000
13
+
14
+ let nodes: NetworkNode[]
15
+ let simulator: Simulator
16
+ let layer0Ep: PeerDescriptor
17
+ const publishIntervals: NodeJS.Timeout[] = []
18
+ const streams: Map<StreamPartID, NetworkNode> = new Map()
19
+ let currentNode: NetworkNode
20
+ let publishInterval: NodeJS.Timeout | undefined
21
+ let i = 0
22
+
23
+ const prepareLayer0 = async () => {
24
+ console.log('Preparing network')
25
+ nodes = []
26
+ simulator = new Simulator(LatencyType.REAL)
27
+ const entryPointId = PeerID.generateRandom()
28
+ const peerDescriptor = {
29
+ kademliaId: entryPointId.value,
30
+ region: getRandomRegion(),
31
+ type: 0,
32
+ nodeName: 'entrypoint'
33
+ }
34
+ layer0Ep = peerDescriptor
35
+ const entryPoint = createNetworkNodeWithSimulator(peerDescriptor, simulator, [peerDescriptor])
36
+ await entryPoint.start()
37
+ nodes.push(entryPoint)
38
+
39
+ console.log('Entrypoint ready')
40
+ }
41
+
42
+ const prepareStream = async (streamId: string) => {
43
+ console.log('Preparing stream ')
44
+ const publisherId = PeerID.generateRandom()
45
+ const peerDescriptor = {
46
+ kademliaId: publisherId.value,
47
+ region: getRandomRegion(),
48
+ type: 0,
49
+ nodeName: streamId
50
+ }
51
+ const streamPartId = toStreamPartID(toStreamID(streamId), 0)
52
+ const streamPublisher = createNetworkNodeWithSimulator(peerDescriptor, simulator, [layer0Ep])
53
+ await streamPublisher.start()
54
+ streamPublisher.subscribe(streamPartId)
55
+ nodes.push(streamPublisher)
56
+ streams.set(streamPartId, streamPublisher)
57
+ }
58
+
59
+ const shutdownNetwork = async () => {
60
+ publishIntervals.map((interval) => clearInterval(interval))
61
+ await Promise.all([
62
+ ...nodes.map((node) => node.stop())
63
+ ])
64
+ simulator.stop()
65
+ }
66
+
67
+ const measureJoiningTime = async (count: number) => {
68
+ const nodeId = PeerID.generateRandom()
69
+ const peerDescriptor = {
70
+ kademliaId: nodeId.value,
71
+ type: 0,
72
+ region: getRandomRegion(),
73
+ nodeName: `${count}`
74
+ }
75
+ console.log('starting node with id ', nodeId.toKey())
76
+
77
+ // start publishing ons stream
78
+ const stream = Array.from(streams.keys())[Math.floor(Math.random() * streams.size)]
79
+ console.log(stream)
80
+ publishInterval = setInterval(() => {
81
+ i += 1
82
+ const streamMessage = new StreamMessage({
83
+ messageId: new MessageID(
84
+ StreamPartIDUtils.getStreamID(stream),
85
+ 0,
86
+ i,
87
+ Math.floor(Math.random() * 20000),
88
+ 'peer' as any,
89
+ 'msgChainId'
90
+ ),
91
+ prevMsgRef: null,
92
+ content: {
93
+ hello: 'world'
94
+ },
95
+ messageType: StreamMessageType.MESSAGE,
96
+ signature: 'signature',
97
+ })
98
+ streams.get(stream)!.publish(streamMessage)
99
+ }, 1000)
100
+ // get random node from network to use as entrypoint
101
+ const randomNode = nodes[Math.floor(Math.random() * nodes.length)]
102
+ const streamSubscriber = createNetworkNodeWithSimulator(peerDescriptor, simulator, [randomNode.stack.getLayer0DhtNode().getPeerDescriptor()])
103
+ currentNode = streamSubscriber
104
+ const start = performance.now()
105
+ await streamSubscriber.start()
106
+
107
+ await Promise.all([
108
+ waitForEvent3(streamSubscriber.stack.getStreamrNode() as any, 'newMessage', 60000),
109
+ streamSubscriber.subscribe(stream)
110
+ ])
111
+
112
+ const end = performance.now()
113
+
114
+ nodes.push(streamSubscriber)
115
+ clearInterval(publishInterval)
116
+ publishInterval = undefined
117
+ return end - start
118
+ }
119
+
120
+ const run = async () => {
121
+ Simulator.useFakeTimers()
122
+ await prepareLayer0()
123
+ for (let i = 0; i < 20; i++) {
124
+ await prepareStream(`stream-${i}`)
125
+ }
126
+ const logFile = fs.openSync('FirstMessageTime.log', 'w')
127
+
128
+ fs.writeSync(logFile, 'Network size' + '\t' + 'Time to receive first message time (ms)' + '\n')
129
+ for (let i = 0; i < numNodes; i++) {
130
+ const time = await measureJoiningTime(i)
131
+ console.log(`Time to receive first message for ${i + 1} nodes network: ${time}ms`)
132
+ fs.writeSync(logFile, `${i + 1}` + '\t' + `${Math.round(time)}\n`)
133
+ }
134
+ fs.closeSync(logFile)
135
+ await shutdownNetwork()
136
+ Simulator.useFakeTimers(false)
137
+ }
138
+
139
+ // eslint-disable-next-line promise/catch-or-return
140
+ run().then(() => {
141
+ console.log('done')
142
+ }).catch((err) => {
143
+ console.error(err)
144
+ const streamParts = currentNode.stack.getStreamrNode()!.getStreamParts()
145
+ const foundData = nodes[0].stack.getLayer0DhtNode().getDataFromDht(streamPartIdToDataKey(streamParts[0]))
146
+ console.log(foundData)
147
+ console.log(currentNode.stack.getLayer0DhtNode().getKBucketPeers().length)
148
+ console.log(currentNode.stack.getLayer0DhtNode().getNumberOfConnections())
149
+ console.log(currentNode.stack.getStreamrNode().getStream(streamParts[0])!.layer1!.getKBucketPeers())
150
+ console.log(currentNode.stack.getStreamrNode().getStream(streamParts[0])!.layer2.getTargetNeighborStringIds())
151
+ console.log(nodes[nodes.length - 1])
152
+ if (publishInterval) {
153
+ clearInterval(publishInterval)
154
+ }
155
+ })
@@ -0,0 +1,119 @@
1
+ import { PeerDescriptor, NodeType, PeerID } from '@streamr/dht'
2
+ import { NetworkNode } from '../../src/NetworkNode'
3
+ import { MessageID, MessageRef, StreamMessage, StreamMessageType, toStreamID, toStreamPartID } from '@streamr/protocol'
4
+ import { EthereumAddress } from 'streamr-client'
5
+ import { waitForCondition } from '@streamr/utils'
6
+
7
+ describe('inspect', () => {
8
+
9
+ const publisherDescriptor: PeerDescriptor = {
10
+ kademliaId: PeerID.fromString('publisher').value,
11
+ type: NodeType.NODEJS,
12
+ websocket: {
13
+ ip: 'localhost',
14
+ port: 15478
15
+ }
16
+ }
17
+
18
+ const inspectedDescriptor: PeerDescriptor = {
19
+ kademliaId: PeerID.fromString('inspected').value,
20
+ type: NodeType.NODEJS,
21
+ websocket: {
22
+ ip: 'localhost',
23
+ port: 15479
24
+ }
25
+ }
26
+
27
+ const inspectorDescriptor: PeerDescriptor = {
28
+ kademliaId: PeerID.fromString('inspector').value,
29
+ type: NodeType.NODEJS,
30
+ websocket: {
31
+ ip: 'localhost',
32
+ port: 15480
33
+ }
34
+ }
35
+
36
+ const streamPartId = toStreamPartID(toStreamID('stream'), 0)
37
+
38
+ let publisherNode: NetworkNode
39
+
40
+ let inspectedNode: NetworkNode
41
+
42
+ let inspectorNode: NetworkNode
43
+
44
+ const message = new StreamMessage({
45
+ messageId: new MessageID(
46
+ toStreamID('stream'),
47
+ 0,
48
+ 666,
49
+ 0,
50
+ 'peer' as EthereumAddress,
51
+ 'msgChainId'
52
+ ),
53
+ prevMsgRef: new MessageRef(665, 0),
54
+ content: {
55
+ hello: 'world'
56
+ },
57
+ messageType: StreamMessageType.MESSAGE,
58
+ signature: 'signature',
59
+ })
60
+
61
+ beforeEach(async () => {
62
+ publisherNode = new NetworkNode({
63
+ layer0: {
64
+ entryPoints: [publisherDescriptor],
65
+ peerDescriptor: publisherDescriptor
66
+ },
67
+ networkNode: {}
68
+ })
69
+
70
+ inspectedNode = new NetworkNode({
71
+ layer0: {
72
+ entryPoints: [publisherDescriptor],
73
+ peerDescriptor: inspectedDescriptor
74
+ },
75
+ networkNode: {}
76
+ })
77
+
78
+ inspectorNode = new NetworkNode({
79
+ layer0: {
80
+ entryPoints: [publisherDescriptor],
81
+ peerDescriptor: inspectorDescriptor
82
+ },
83
+ networkNode: {}
84
+ })
85
+
86
+ await publisherNode.start()
87
+ await inspectedNode.start()
88
+ await inspectorNode.start()
89
+
90
+ await Promise.all([
91
+ publisherNode.stack.getStreamrNode()!.joinStream(streamPartId),
92
+ inspectedNode.stack.getStreamrNode()!.joinStream(streamPartId),
93
+ inspectorNode.stack.getStreamrNode()!.joinStream(streamPartId)
94
+ ])
95
+
96
+ await waitForCondition(() =>
97
+ publisherNode.getNeighbors().length === 2
98
+ && inspectedNode.getNeighbors().length === 2
99
+ && inspectorNode.getNeighbors().length === 2
100
+ )
101
+ }, 30000)
102
+
103
+ afterEach(async () => {
104
+ await Promise.all([
105
+ publisherNode.stop(),
106
+ inspectedNode.stop(),
107
+ inspectorNode.stop()
108
+ ])
109
+ })
110
+
111
+ it('should inspect succesfully', async () => {
112
+ setTimeout(async () => {
113
+ await publisherNode.publish(message)
114
+ }, 250)
115
+ const success = await inspectorNode.inspect(inspectedDescriptor, streamPartId)
116
+ expect(success).toBe(true)
117
+ })
118
+
119
+ })
@@ -0,0 +1,140 @@
1
+ import { NodeType, PeerDescriptor, PeerID } from '@streamr/dht'
2
+ import { NetworkNode } from '../../src/NetworkNode'
3
+ import { MessageID, MessageRef, StreamID, StreamMessage, StreamMessageType, toStreamID, toStreamPartID } from '@streamr/protocol'
4
+ import { EthereumAddress, waitForEvent3 } from '@streamr/utils'
5
+ import { ProxyDirection, StreamMessage as InternalStreamMessage } from '../../src/proto/packages/trackerless-network/protos/NetworkRpc'
6
+ import { StreamNodeType } from '../../src/logic/StreamrNode'
7
+
8
+ const createMessage = (streamId: StreamID): StreamMessage => {
9
+ return new StreamMessage({
10
+ messageId: new MessageID(
11
+ streamId,
12
+ 0,
13
+ 666,
14
+ 0,
15
+ 'peer' as EthereumAddress,
16
+ 'msgChainId'
17
+ ),
18
+ prevMsgRef: new MessageRef(665, 0),
19
+ content: {
20
+ hello: 'world'
21
+ },
22
+ messageType: StreamMessageType.MESSAGE,
23
+ signature: 'signature',
24
+ })
25
+ }
26
+
27
+ describe('proxy and full node', () => {
28
+
29
+ const proxyNodeDescriptor: PeerDescriptor = {
30
+ kademliaId: PeerID.fromString(`proxyNode`).value,
31
+ type: NodeType.NODEJS,
32
+ nodeName: 'proxyNode',
33
+ websocket: { ip: 'localhost', port: 23135 }
34
+ }
35
+ const proxiedNodeDescriptor: PeerDescriptor = {
36
+ kademliaId: PeerID.fromString(`proxiedNode`).value,
37
+ type: NodeType.NODEJS,
38
+ }
39
+
40
+ const proxyStreamId = toStreamPartID(toStreamID('proxy-stream'), 0)
41
+ const regularStreamId1 = toStreamPartID(toStreamID('regular-stream1'), 0)
42
+ const regularStreamId2 = toStreamPartID(toStreamID('regular-stream2'), 0)
43
+ const regularStreamId3 = toStreamPartID(toStreamID('regular-stream3'), 0)
44
+ const regularStreamId4 = toStreamPartID(toStreamID('regular-stream4'), 0)
45
+
46
+ const proxiedMessage = createMessage(toStreamID('proxy-stream'))
47
+ const regularMessage1 = createMessage(toStreamID('regular-stream1'))
48
+ const regularMessage2 = createMessage(toStreamID('regular-stream2'))
49
+ const regularMessage3 = createMessage(toStreamID('regular-stream3'))
50
+ const regularMessage4 = createMessage(toStreamID('regular-stream4'))
51
+
52
+ let proxyNode: NetworkNode
53
+ let proxiedNode: NetworkNode
54
+
55
+ beforeEach(async () => {
56
+ proxyNode = new NetworkNode({
57
+ layer0: {
58
+ entryPoints: [proxyNodeDescriptor],
59
+ peerDescriptor: proxyNodeDescriptor,
60
+ },
61
+ networkNode: {
62
+ acceptProxyConnections: true
63
+ }
64
+ })
65
+ await proxyNode.start()
66
+ await proxyNode.stack.getStreamrNode()!.joinStream(proxyStreamId)
67
+ await proxyNode.stack.getStreamrNode()!.joinStream(regularStreamId1)
68
+ await proxyNode.stack.getStreamrNode()!.joinStream(regularStreamId2)
69
+ await proxyNode.stack.getStreamrNode()!.joinStream(regularStreamId3)
70
+ await proxyNode.stack.getStreamrNode()!.joinStream(regularStreamId4)
71
+
72
+ proxiedNode = new NetworkNode({
73
+ layer0: {
74
+ entryPoints: [proxyNodeDescriptor],
75
+ peerDescriptor: proxiedNodeDescriptor,
76
+ },
77
+ networkNode: {}
78
+ })
79
+ await proxiedNode.start(false)
80
+ })
81
+
82
+ afterEach(async () => {
83
+ await proxyNode.stop()
84
+ await proxiedNode.stop()
85
+ })
86
+
87
+ it('proxied node can act as full node on another stream', async () => {
88
+ await proxiedNode.setProxies(proxyStreamId, [proxyNodeDescriptor], ProxyDirection.PUBLISH, async () => 'proxiedNode', 1)
89
+ expect(proxiedNode.stack.getLayer0DhtNode().hasJoined()).toBe(false)
90
+
91
+ await Promise.all([
92
+ waitForEvent3(proxyNode.stack.getStreamrNode()! as any, 'newMessage'),
93
+ proxiedNode.publish(regularMessage1)
94
+ ])
95
+
96
+ expect(proxiedNode.stack.getLayer0DhtNode().hasJoined()).toBe(true)
97
+
98
+ await Promise.all([
99
+ waitForEvent3(proxyNode.stack.getStreamrNode()! as any, 'newMessage'),
100
+ proxiedNode.publish(proxiedMessage)
101
+ ])
102
+
103
+ expect(proxiedNode.stack.getStreamrNode().getStream(proxyStreamId)!.type).toBe(StreamNodeType.PROXY)
104
+ expect(proxiedNode.stack.getStreamrNode().getStream(regularStreamId1)!.type).toBe(StreamNodeType.RANDOM_GRAPH)
105
+ })
106
+
107
+ it('proxied node can act as full node on multiple streams', async () => {
108
+ await proxiedNode.setProxies(proxyStreamId, [proxyNodeDescriptor], ProxyDirection.PUBLISH, async () => 'proxiedNode', 1)
109
+ expect(proxiedNode.stack.getLayer0DhtNode().hasJoined()).toBe(false)
110
+
111
+ await Promise.all([
112
+ waitForEvent3(proxyNode.stack.getStreamrNode()! as any, 'newMessage', 5000,
113
+ (streamMessage: InternalStreamMessage) => streamMessage.messageRef!.streamId === 'regular-stream1'),
114
+ waitForEvent3(proxyNode.stack.getStreamrNode()! as any, 'newMessage', 5000,
115
+ (streamMessage: InternalStreamMessage) => streamMessage.messageRef!.streamId === 'regular-stream2'),
116
+ waitForEvent3(proxyNode.stack.getStreamrNode()! as any, 'newMessage', 5000,
117
+ (streamMessage: InternalStreamMessage) => streamMessage.messageRef!.streamId === 'regular-stream3'),
118
+ waitForEvent3(proxyNode.stack.getStreamrNode()! as any, 'newMessage', 5000,
119
+ (streamMessage: InternalStreamMessage) => streamMessage.messageRef!.streamId === 'regular-stream4'),
120
+ proxiedNode.publish(regularMessage1),
121
+ proxiedNode.publish(regularMessage2),
122
+ proxiedNode.publish(regularMessage3),
123
+ proxiedNode.publish(regularMessage4)
124
+ ])
125
+
126
+ expect(proxiedNode.stack.getLayer0DhtNode().hasJoined()).toBe(true)
127
+
128
+ await Promise.all([
129
+ waitForEvent3(proxyNode.stack.getStreamrNode()! as any, 'newMessage'),
130
+ proxiedNode.publish(proxiedMessage)
131
+ ])
132
+
133
+ expect(proxiedNode.stack.getStreamrNode().getStream(proxyStreamId)!.type).toBe(StreamNodeType.PROXY)
134
+ expect(proxiedNode.stack.getStreamrNode().getStream(regularStreamId1)!.type).toBe(StreamNodeType.RANDOM_GRAPH)
135
+ expect(proxiedNode.stack.getStreamrNode().getStream(regularStreamId2)!.type).toBe(StreamNodeType.RANDOM_GRAPH)
136
+ expect(proxiedNode.stack.getStreamrNode().getStream(regularStreamId3)!.type).toBe(StreamNodeType.RANDOM_GRAPH)
137
+ expect(proxiedNode.stack.getStreamrNode().getStream(regularStreamId4)!.type).toBe(StreamNodeType.RANDOM_GRAPH)
138
+ })
139
+
140
+ })
@@ -0,0 +1,228 @@
1
+ import { NodeType, PeerDescriptor, PeerID, keyFromPeerDescriptor, peerIdFromPeerDescriptor } from '@streamr/dht'
2
+ import { ProxyDirection } from '../../src/proto/packages/trackerless-network/protos/NetworkRpc'
3
+ import { EthereumAddress, waitForCondition, waitForEvent3 } from '@streamr/utils'
4
+ import { NetworkNode } from '../../src/NetworkNode'
5
+ import { MessageID, MessageRef, StreamMessage, StreamMessageType, toStreamID, toStreamPartID } from '@streamr/protocol'
6
+
7
+ describe('Proxy connections', () => {
8
+
9
+ const proxyNodeDescriptor1: PeerDescriptor = {
10
+ kademliaId: PeerID.fromString(`proxyNode1`).value,
11
+ type: NodeType.NODEJS,
12
+ nodeName: 'proxyNode',
13
+ websocket: { ip: 'localhost', port: 23132 }
14
+ }
15
+ const proxyNodeDescriptor2: PeerDescriptor = {
16
+ kademliaId: PeerID.fromString(`proxyNode2`).value,
17
+ type: NodeType.NODEJS,
18
+ nodeName: 'proxyNode',
19
+ websocket: { ip: 'localhost', port: 23133 }
20
+ }
21
+ const proxiedNodeDescriptor: PeerDescriptor = {
22
+ kademliaId: PeerID.fromString(`proxiedNode`).value,
23
+ type: NodeType.NODEJS,
24
+ }
25
+ const proxiedPeerId = peerIdFromPeerDescriptor(proxiedNodeDescriptor)
26
+
27
+ const streamPartId = toStreamPartID(toStreamID('proxy-test'), 0)
28
+
29
+ const message = new StreamMessage({
30
+ messageId: new MessageID(
31
+ toStreamID('proxy-test'),
32
+ 0,
33
+ 666,
34
+ 0,
35
+ 'peer' as EthereumAddress,
36
+ 'msgChainId'
37
+ ),
38
+ prevMsgRef: new MessageRef(665, 0),
39
+ content: {
40
+ hello: 'world'
41
+ },
42
+ messageType: StreamMessageType.MESSAGE,
43
+ signature: 'signature',
44
+ })
45
+
46
+ let proxyNode1: NetworkNode
47
+ let proxyNode2: NetworkNode
48
+ let proxiedNode: NetworkNode
49
+
50
+ beforeEach(async () => {
51
+ proxyNode1 = new NetworkNode({
52
+ layer0: {
53
+ entryPoints: [proxyNodeDescriptor1],
54
+ peerDescriptor: proxyNodeDescriptor1,
55
+ },
56
+ networkNode: {
57
+ acceptProxyConnections: true
58
+ }
59
+ })
60
+ await proxyNode1.start()
61
+ await proxyNode1.setStreamPartEntryPoints(streamPartId, [proxyNodeDescriptor1])
62
+ await proxyNode1.stack.getStreamrNode()!.joinStream(streamPartId)
63
+
64
+ proxyNode2 = new NetworkNode({
65
+ layer0: {
66
+ entryPoints: [proxyNodeDescriptor1],
67
+ peerDescriptor: proxyNodeDescriptor2,
68
+ },
69
+ networkNode: {
70
+ acceptProxyConnections: true
71
+ }
72
+ })
73
+ await proxyNode2.start()
74
+ proxyNode2.setStreamPartEntryPoints(streamPartId, [proxyNodeDescriptor1])
75
+ await proxyNode2.stack.getStreamrNode()!.joinStream(streamPartId)
76
+
77
+ proxiedNode = new NetworkNode({
78
+ layer0: {
79
+ entryPoints: [proxyNodeDescriptor1],
80
+ peerDescriptor: proxiedNodeDescriptor,
81
+ },
82
+ networkNode: {}
83
+ })
84
+ await proxiedNode.start(false)
85
+ }, 30000)
86
+
87
+ afterEach(async () => {
88
+ await proxyNode1.stop()
89
+ await proxyNode2.stop()
90
+ await proxiedNode.stop()
91
+ })
92
+
93
+ it('happy path publishing', async () => {
94
+ await proxiedNode.setProxies(streamPartId, [proxyNodeDescriptor1], ProxyDirection.PUBLISH, async () => 'proxiedNode', 1)
95
+
96
+ await Promise.all([
97
+ waitForEvent3(proxyNode1.stack.getStreamrNode()! as any, 'newMessage'),
98
+ proxiedNode.publish(message)
99
+ ])
100
+ })
101
+
102
+ it('happy path subscribing', async () => {
103
+ await proxiedNode.setProxies(streamPartId, [proxyNodeDescriptor1], ProxyDirection.SUBSCRIBE, async () => 'proxiedNode', 1)
104
+ proxiedNode.subscribe(streamPartId)
105
+ await Promise.all([
106
+ waitForEvent3(proxiedNode.stack.getStreamrNode()! as any, 'newMessage'),
107
+ proxyNode1.publish(message)
108
+ ])
109
+ })
110
+
111
+ it('can leave proxy publish connection', async () => {
112
+ await proxiedNode.setProxies(streamPartId, [proxyNodeDescriptor1], ProxyDirection.PUBLISH, async () => 'proxiedNode', 1)
113
+ expect(proxiedNode.hasStreamPart(streamPartId)).toBe(true)
114
+ expect(proxyNode1.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.PUBLISH)).toBe(true)
115
+
116
+ await proxiedNode.setProxies(streamPartId, [], ProxyDirection.PUBLISH, async () => 'proxiedNode', 0)
117
+ expect(proxiedNode.hasStreamPart(streamPartId)).toBe(false)
118
+ await waitForCondition(() =>
119
+ proxyNode1.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.PUBLISH) === false)
120
+ })
121
+
122
+ it('can leave proxy subscribe connection', async () => {
123
+ await proxiedNode.setProxies(streamPartId, [proxyNodeDescriptor1], ProxyDirection.SUBSCRIBE, async () => 'proxiedNode', 1)
124
+ expect(proxiedNode.hasStreamPart(streamPartId)).toBe(true)
125
+ expect(proxyNode1.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.SUBSCRIBE)).toBe(true)
126
+
127
+ await proxiedNode.setProxies(streamPartId, [], ProxyDirection.SUBSCRIBE, async () => 'proxiedNode', 0)
128
+ expect(proxiedNode.hasStreamPart(streamPartId)).toBe(false)
129
+ await waitForCondition(() =>
130
+ proxyNode1.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.SUBSCRIBE) === false)
131
+
132
+ })
133
+
134
+ it('can open multiple proxy connections', async () => {
135
+ await proxiedNode.setProxies(
136
+ streamPartId,
137
+ [proxyNodeDescriptor1, proxyNodeDescriptor2],
138
+ ProxyDirection.SUBSCRIBE,
139
+ async () => 'proxiedNode'
140
+ )
141
+ expect(proxiedNode.hasStreamPart(streamPartId)).toBe(true)
142
+ expect(proxiedNode.stack.getStreamrNode().getStream(streamPartId)!.layer2.getTargetNeighborStringIds().length).toBe(2)
143
+ expect(proxyNode1.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.SUBSCRIBE)).toBe(true)
144
+ expect(proxyNode2.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.SUBSCRIBE)).toBe(true)
145
+ })
146
+
147
+ it('can open multiple proxy connections and close one', async () => {
148
+ await proxiedNode.setProxies(
149
+ streamPartId,
150
+ [proxyNodeDescriptor1, proxyNodeDescriptor2],
151
+ ProxyDirection.SUBSCRIBE,
152
+ async () => 'proxiedNode'
153
+ )
154
+ expect(proxiedNode.hasStreamPart(streamPartId)).toBe(true)
155
+ expect(proxiedNode.stack.getStreamrNode().getStream(streamPartId)!.layer2.getTargetNeighborStringIds().length).toBe(2)
156
+ expect(proxyNode1.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.SUBSCRIBE)).toBe(true)
157
+ expect(proxyNode2.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.SUBSCRIBE)).toBe(true)
158
+
159
+ await proxiedNode.setProxies(streamPartId, [proxyNodeDescriptor1], ProxyDirection.SUBSCRIBE, async () => 'proxiedNode')
160
+ expect(proxiedNode.hasStreamPart(streamPartId)).toBe(true)
161
+ expect(proxiedNode.stack.getStreamrNode().getStream(streamPartId)!.layer2.getTargetNeighborStringIds().length).toBe(1)
162
+ await waitForCondition(() =>
163
+ proxyNode2.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.SUBSCRIBE) === false)
164
+ expect(proxyNode1.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.SUBSCRIBE)).toBe(true)
165
+ })
166
+
167
+ it('can open and close all connections', async () => {
168
+ await proxiedNode.setProxies(
169
+ streamPartId,
170
+ [proxyNodeDescriptor1, proxyNodeDescriptor2],
171
+ ProxyDirection.SUBSCRIBE,
172
+ async () => 'proxiedNode'
173
+ )
174
+ expect(proxiedNode.hasStreamPart(streamPartId)).toBe(true)
175
+ expect(proxiedNode.stack.getStreamrNode().getStream(streamPartId)!.layer2.getTargetNeighborStringIds().length).toBe(2)
176
+ expect(proxyNode1.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.SUBSCRIBE)).toBe(true)
177
+ expect(proxyNode2.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.SUBSCRIBE)).toBe(true)
178
+
179
+ await proxiedNode.setProxies(streamPartId, [], ProxyDirection.SUBSCRIBE, async () => 'proxiedNode')
180
+ expect(proxiedNode.hasStreamPart(streamPartId)).toBe(false)
181
+ await waitForCondition(() =>
182
+ proxyNode1.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.SUBSCRIBE) === false)
183
+ await waitForCondition(() =>
184
+ proxyNode2.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.SUBSCRIBE) === false)
185
+ })
186
+
187
+ it('will reconnect if proxy node goes offline and comes back online', async () => {
188
+ await proxiedNode.setProxies(
189
+ streamPartId,
190
+ [proxyNodeDescriptor1],
191
+ ProxyDirection.SUBSCRIBE,
192
+ async () => 'proxiedNode'
193
+ )
194
+ expect(proxiedNode.hasStreamPart(streamPartId)).toBe(true)
195
+ proxyNode1.unsubscribe(streamPartId)
196
+ await waitForCondition(() =>
197
+ proxiedNode.hasProxyConnection(streamPartId, keyFromPeerDescriptor(proxyNodeDescriptor1), ProxyDirection.SUBSCRIBE))
198
+ expect(proxyNode1.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.SUBSCRIBE)).toBe(false)
199
+
200
+ await proxyNode1.stack.getStreamrNode()!.joinStream(streamPartId)
201
+ await waitForCondition(() =>
202
+ proxiedNode.hasProxyConnection(streamPartId, keyFromPeerDescriptor(proxyNodeDescriptor1), ProxyDirection.SUBSCRIBE)
203
+ , 25000)
204
+ expect(proxyNode1.hasProxyConnection(streamPartId, proxiedPeerId.toKey(), ProxyDirection.SUBSCRIBE)).toBe(false)
205
+
206
+ }, 30000)
207
+
208
+ it('cannot subscribe on proxy publish streams', async () => {
209
+ await proxiedNode.setProxies(
210
+ streamPartId,
211
+ [proxyNodeDescriptor1],
212
+ ProxyDirection.PUBLISH,
213
+ async () => 'proxiedNode'
214
+ )
215
+ await expect(proxiedNode.subscribe(streamPartId)).rejects.toThrow('Cannot subscribe')
216
+ })
217
+
218
+ it('connect publish on proxy subscribe streams', async () => {
219
+ await proxiedNode.setProxies(
220
+ streamPartId,
221
+ [proxyNodeDescriptor1],
222
+ ProxyDirection.SUBSCRIBE,
223
+ async () => 'proxiedNode'
224
+ )
225
+ await expect(proxiedNode.publish(message)).rejects.toThrow('Cannot publish')
226
+ })
227
+
228
+ })