@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.
- package/dist/package.json +10 -8
- package/dist/src/NetworkNode.js +2 -2
- package/dist/src/NetworkNode.js.map +1 -1
- package/dist/src/NetworkStack.d.ts +5 -6
- package/dist/src/NetworkStack.js +27 -56
- package/dist/src/NetworkStack.js.map +1 -1
- package/dist/src/identifiers.js +2 -2
- package/dist/src/identifiers.js.map +1 -1
- package/dist/src/logic/{StreamNodeServer.d.ts → DeliveryRpcLocal.d.ts} +6 -5
- package/dist/src/logic/{StreamNodeServer.js → DeliveryRpcLocal.js} +5 -5
- package/dist/src/logic/{StreamNodeServer.js.map → DeliveryRpcLocal.js.map} +1 -1
- package/dist/src/logic/{RemoteRandomGraphNode.d.ts → DeliveryRpcRemote.d.ts} +2 -2
- package/dist/src/logic/{RemoteRandomGraphNode.js → DeliveryRpcRemote.js} +5 -5
- package/dist/src/logic/DeliveryRpcRemote.js.map +1 -0
- package/dist/src/logic/{StreamPartEntryPointDiscovery.d.ts → EntryPointDiscovery.d.ts} +10 -12
- package/dist/src/logic/{StreamPartEntryPointDiscovery.js → EntryPointDiscovery.js} +18 -40
- package/dist/src/logic/EntryPointDiscovery.js.map +1 -0
- package/dist/src/logic/Layer0Node.d.ts +14 -0
- package/dist/src/logic/{ILayer1.js → Layer0Node.js} +1 -1
- package/dist/src/logic/Layer0Node.js.map +1 -0
- package/dist/src/logic/{ILayer1.d.ts → Layer1Node.d.ts} +5 -5
- package/dist/src/logic/{ILayer0.js → Layer1Node.js} +1 -1
- package/dist/src/logic/Layer1Node.js.map +1 -0
- package/dist/src/logic/NodeList.d.ts +10 -10
- package/dist/src/logic/NodeList.js.map +1 -1
- package/dist/src/logic/RandomGraphNode.d.ts +11 -15
- package/dist/src/logic/RandomGraphNode.js +46 -45
- package/dist/src/logic/RandomGraphNode.js.map +1 -1
- package/dist/src/logic/StreamrNode.d.ts +15 -18
- package/dist/src/logic/StreamrNode.js +78 -87
- package/dist/src/logic/StreamrNode.js.map +1 -1
- package/dist/src/logic/createRandomGraphNode.d.ts +6 -1
- package/dist/src/logic/createRandomGraphNode.js +17 -23
- package/dist/src/logic/createRandomGraphNode.js.map +1 -1
- package/dist/src/logic/formStreamPartDeliveryServiceId.d.ts +2 -0
- package/dist/src/logic/formStreamPartDeliveryServiceId.js +8 -0
- package/dist/src/logic/formStreamPartDeliveryServiceId.js.map +1 -0
- package/dist/src/logic/inspect/Inspector.d.ts +3 -2
- package/dist/src/logic/inspect/Inspector.js +5 -5
- package/dist/src/logic/inspect/Inspector.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/{HandshakerServer.d.ts → HandshakeRpcLocal.d.ts} +10 -10
- package/dist/src/logic/neighbor-discovery/{HandshakerServer.js → HandshakeRpcLocal.js} +13 -13
- package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.js.map +1 -0
- package/dist/src/logic/neighbor-discovery/{RemoteHandshaker.d.ts → HandshakeRpcRemote.d.ts} +1 -1
- package/dist/src/logic/neighbor-discovery/{RemoteHandshaker.js → HandshakeRpcRemote.js} +8 -7
- package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.js.map +1 -0
- package/dist/src/logic/neighbor-discovery/Handshaker.d.ts +8 -7
- package/dist/src/logic/neighbor-discovery/Handshaker.js +23 -24
- package/dist/src/logic/neighbor-discovery/Handshaker.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborFinder.d.ts +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborFinder.js +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborFinder.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.d.ts +3 -2
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js +5 -5
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/{NeighborUpdateManagerServer.d.ts → NeighborUpdateRpcLocal.d.ts} +6 -6
- package/dist/src/logic/neighbor-discovery/{NeighborUpdateManagerServer.js → NeighborUpdateRpcLocal.js} +9 -9
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.js.map +1 -0
- package/dist/src/logic/neighbor-discovery/{RemoteNeighborUpdateManager.d.ts → NeighborUpdateRpcRemote.d.ts} +1 -1
- package/dist/src/logic/neighbor-discovery/{RemoteNeighborUpdateManager.js → NeighborUpdateRpcRemote.js} +5 -5
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcRemote.js.map +1 -0
- package/dist/src/logic/propagation/Propagation.js +2 -2
- package/dist/src/logic/propagation/Propagation.js.map +1 -1
- package/dist/src/logic/proxy/{ProxyStreamConnectionClient.d.ts → ProxyClient.d.ts} +7 -10
- package/dist/src/logic/proxy/{ProxyStreamConnectionClient.js → ProxyClient.js} +24 -22
- package/dist/src/logic/proxy/ProxyClient.js.map +1 -0
- package/dist/src/logic/proxy/{ProxyStreamConnectionServer.d.ts → ProxyConnectionRpcLocal.d.ts} +5 -5
- package/dist/src/logic/proxy/{ProxyStreamConnectionServer.js → ProxyConnectionRpcLocal.js} +6 -6
- package/dist/src/logic/proxy/ProxyConnectionRpcLocal.js.map +1 -0
- package/dist/src/logic/proxy/{RemoteProxyServer.d.ts → ProxyConnectionRpcRemote.d.ts} +1 -1
- package/dist/src/logic/proxy/{RemoteProxyServer.js → ProxyConnectionRpcRemote.js} +4 -4
- package/dist/src/logic/proxy/ProxyConnectionRpcRemote.js.map +1 -0
- package/dist/src/logic/temporary-connection/{TemporaryConnectionRpcServer.d.ts → TemporaryConnectionRpcLocal.d.ts} +5 -4
- package/dist/src/logic/temporary-connection/{TemporaryConnectionRpcServer.js → TemporaryConnectionRpcLocal.js} +6 -6
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.js.map +1 -0
- package/dist/src/logic/temporary-connection/{RemoteTemporaryConnectionRpcServer.d.ts → TemporaryConnectionRpcRemote.d.ts} +1 -1
- package/dist/src/logic/temporary-connection/{RemoteTemporaryConnectionRpcServer.js → TemporaryConnectionRpcRemote.js} +4 -4
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcRemote.js.map +1 -0
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +10 -0
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +7 -0
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +54 -118
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +50 -49
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +6 -0
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.d.ts +4 -4
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.js +7 -7
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.js.map +1 -1
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.d.ts +10 -10
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js +7 -7
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js.map +1 -1
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.server.d.ts +2 -2
- package/dist/test/benchmark/first-message.js +16 -17
- package/dist/test/benchmark/first-message.js.map +1 -1
- package/dist/test/utils/utils.d.ts +7 -6
- package/dist/test/utils/utils.js +18 -17
- package/dist/test/utils/utils.js.map +1 -1
- package/package.json +10 -8
- package/protos/NetworkRpc.proto +5 -5
- package/src/NetworkNode.ts +2 -2
- package/src/NetworkStack.ts +31 -72
- package/src/identifiers.ts +3 -3
- package/src/logic/{StreamNodeServer.ts → DeliveryRpcLocal.ts} +8 -7
- package/src/logic/{RemoteRandomGraphNode.ts → DeliveryRpcRemote.ts} +3 -3
- package/src/logic/{StreamPartEntryPointDiscovery.ts → EntryPointDiscovery.ts} +24 -48
- package/src/logic/Layer0Node.ts +15 -0
- package/src/logic/{ILayer1.ts → Layer1Node.ts} +5 -5
- package/src/logic/NodeList.ts +12 -12
- package/src/logic/RandomGraphNode.ts +73 -74
- package/src/logic/StreamrNode.ts +90 -103
- package/src/logic/createRandomGraphNode.ts +28 -26
- package/src/logic/formStreamPartDeliveryServiceId.ts +5 -0
- package/src/logic/inspect/Inspector.ts +8 -7
- package/src/logic/neighbor-discovery/{HandshakerServer.ts → HandshakeRpcLocal.ts} +20 -20
- package/src/logic/neighbor-discovery/{RemoteHandshaker.ts → HandshakeRpcRemote.ts} +6 -5
- package/src/logic/neighbor-discovery/Handshaker.ts +38 -38
- package/src/logic/neighbor-discovery/NeighborFinder.ts +2 -2
- package/src/logic/neighbor-discovery/NeighborUpdateManager.ts +13 -10
- package/src/logic/neighbor-discovery/{NeighborUpdateManagerServer.ts → NeighborUpdateRpcLocal.ts} +15 -15
- package/src/logic/neighbor-discovery/{RemoteNeighborUpdateManager.ts → NeighborUpdateRpcRemote.ts} +2 -2
- package/src/logic/propagation/Propagation.ts +2 -2
- package/src/logic/proxy/{ProxyStreamConnectionClient.ts → ProxyClient.ts} +29 -29
- package/src/logic/proxy/{ProxyStreamConnectionServer.ts → ProxyConnectionRpcLocal.ts} +10 -11
- package/src/logic/proxy/{RemoteProxyServer.ts → ProxyConnectionRpcRemote.ts} +1 -1
- package/src/logic/temporary-connection/{TemporaryConnectionRpcServer.ts → TemporaryConnectionRpcLocal.ts} +11 -10
- package/src/logic/temporary-connection/{RemoteTemporaryConnectionRpcServer.ts → TemporaryConnectionRpcRemote.ts} +1 -1
- package/src/proto/packages/dht/protos/DhtRpc.client.ts +13 -0
- package/src/proto/packages/dht/protos/DhtRpc.server.ts +6 -0
- package/src/proto/packages/dht/protos/DhtRpc.ts +88 -166
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.client.ts +8 -8
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.server.ts +2 -2
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.ts +14 -14
- package/test/benchmark/first-message.ts +19 -20
- package/test/end-to-end/inspect.test.ts +12 -12
- package/test/end-to-end/proxy-and-full-node.test.ts +17 -18
- package/test/end-to-end/proxy-connections.test.ts +9 -11
- package/test/end-to-end/proxy-key-exchange.test.ts +12 -13
- package/test/end-to-end/random-graph-with-real-connections.test.ts +27 -22
- package/test/end-to-end/webrtc-full-node-network.test.ts +8 -8
- package/test/end-to-end/websocket-full-node-network.test.ts +8 -10
- package/test/integration/{RemoteRandomGraphNode.test.ts → DeliveryRpcRemote.test.ts} +17 -14
- package/test/integration/{RemoteHandshaker.test.ts → HandshakeRpcRemote.test.ts} +10 -9
- package/test/integration/Handshakes.test.ts +23 -20
- package/test/integration/Inspect.test.ts +4 -3
- package/test/integration/{RemoteNeighborUpdateManager.test.ts → NeighborUpdateRpcRemote.test.ts} +12 -10
- package/test/integration/NetworkNode.test.ts +9 -8
- package/test/integration/NetworkRpc.test.ts +5 -7
- package/test/integration/NetworkStack.test.ts +13 -15
- package/test/integration/Propagation.test.ts +14 -13
- package/test/integration/RandomGraphNode-Layer1Node-Latencies.test.ts +23 -20
- package/test/integration/RandomGraphNode-Layer1Node.test.ts +30 -29
- package/test/integration/StreamrNode.test.ts +16 -13
- package/test/integration/joining-streams-on-offline-peers.test.ts +16 -18
- package/test/integration/stream-without-default-entrypoints.test.ts +12 -14
- package/test/unit/{StreamNodeServer.test.ts → DeliveryRpcLocal.test.ts} +8 -8
- package/test/unit/{StreamPartEntrypointDiscovery.test.ts → EntrypointDiscovery.test.ts} +27 -44
- package/test/unit/{HandshakerServer.test.ts → HandshakeRpcLocal.test.ts} +26 -24
- package/test/unit/Handshaker.test.ts +10 -8
- package/test/unit/Inspector.test.ts +4 -3
- package/test/unit/NeighborFinder.test.ts +5 -5
- package/test/unit/NodeList.test.ts +22 -13
- package/test/unit/{RemoteProxyServer.test.ts → ProxyConnectionRpcRemote.test.ts} +4 -4
- package/test/unit/RandomGraphNode.test.ts +15 -13
- package/test/unit/StreamMessageTranslator.test.ts +10 -9
- package/test/unit/StreamrNode.test.ts +10 -10
- package/test/utils/mock/{MockLayer0.ts → MockLayer0Node.ts} +23 -26
- package/test/utils/mock/{MockLayer1.ts → MockLayer1Node.ts} +5 -10
- package/test/utils/mock/MockNeighborFinder.ts +1 -2
- package/test/utils/mock/MockNeighborUpdateManager.ts +1 -2
- package/test/utils/mock/Transport.ts +2 -2
- package/test/utils/utils.ts +18 -16
- package/dist/src/logic/ILayer0.d.ts +0 -13
- package/dist/src/logic/ILayer0.js.map +0 -1
- package/dist/src/logic/ILayer1.js.map +0 -1
- package/dist/src/logic/RemoteRandomGraphNode.js.map +0 -1
- package/dist/src/logic/StreamPartEntryPointDiscovery.js.map +0 -1
- package/dist/src/logic/neighbor-discovery/HandshakerServer.js.map +0 -1
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManagerServer.js.map +0 -1
- package/dist/src/logic/neighbor-discovery/RemoteHandshaker.js.map +0 -1
- package/dist/src/logic/neighbor-discovery/RemoteNeighborUpdateManager.js.map +0 -1
- package/dist/src/logic/proxy/ProxyStreamConnectionClient.js.map +0 -1
- package/dist/src/logic/proxy/ProxyStreamConnectionServer.js.map +0 -1
- package/dist/src/logic/proxy/RemoteProxyServer.js.map +0 -1
- package/dist/src/logic/temporary-connection/RemoteTemporaryConnectionRpcServer.js.map +0 -1
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcServer.js.map +0 -1
- package/src/logic/ILayer0.ts +0 -14
package/src/NetworkStack.ts
CHANGED
|
@@ -1,39 +1,10 @@
|
|
|
1
|
-
import { ConnectionManager, DhtNode, DhtNodeOptions,
|
|
1
|
+
import { ConnectionManager, DhtNode, DhtNodeOptions, areEqualPeerDescriptors } from '@streamr/dht'
|
|
2
2
|
import { StreamrNode, StreamrNodeConfig } from './logic/StreamrNode'
|
|
3
|
-
import { MetricsContext, waitForCondition
|
|
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
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
96
|
-
const connectionManager = this.
|
|
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
|
-
|
|
69
|
+
areEqualPeerDescriptors(entryPoint, this.layer0Node!.getPeerDescriptor())
|
|
99
70
|
))) {
|
|
100
|
-
await this.
|
|
71
|
+
await this.layer0Node?.joinDht(this.options.layer0.entryPoints)
|
|
101
72
|
} else {
|
|
102
73
|
if (doJoin) {
|
|
103
|
-
|
|
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.
|
|
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
|
|
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.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
-
|
|
142
|
-
return this.
|
|
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.
|
|
111
|
+
this.layer0Node = undefined
|
|
153
112
|
this.emit('stopped')
|
|
154
113
|
}
|
|
155
114
|
|
package/src/identifiers.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { PeerDescriptor
|
|
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
|
|
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 {
|
|
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
|
|
14
|
+
export interface DeliveryRpcLocalConfig {
|
|
14
15
|
ownPeerDescriptor: PeerDescriptor
|
|
15
|
-
|
|
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
|
|
24
|
+
export class DeliveryRpcLocal implements IDeliveryRpc {
|
|
24
25
|
|
|
25
|
-
private readonly config:
|
|
26
|
+
private readonly config: DeliveryRpcLocalConfig
|
|
26
27
|
|
|
27
|
-
constructor(config:
|
|
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.
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
|
57
|
+
interface EntryPointDiscoveryConfig {
|
|
59
58
|
streamPartId: StreamPartID
|
|
60
59
|
ownPeerDescriptor: PeerDescriptor
|
|
61
|
-
|
|
62
|
-
getEntryPointData: (key: Uint8Array) => Promise<
|
|
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
|
-
|
|
64
|
+
storeInterval?: number
|
|
67
65
|
}
|
|
68
66
|
|
|
69
|
-
export class
|
|
67
|
+
export class EntryPointDiscovery {
|
|
70
68
|
private readonly abortController: AbortController
|
|
71
|
-
private readonly config:
|
|
72
|
-
private readonly
|
|
69
|
+
private readonly config: EntryPointDiscoveryConfig
|
|
70
|
+
private readonly storeInterval: number
|
|
73
71
|
private readonly networkSplitAvoidedNodes: Set<NodeID> = new Set()
|
|
74
72
|
|
|
75
|
-
constructor(config:
|
|
73
|
+
constructor(config: EntryPointDiscoveryConfig) {
|
|
76
74
|
this.config = config
|
|
77
75
|
this.abortController = new AbortController()
|
|
78
|
-
this.
|
|
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(
|
|
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(
|
|
98
|
+
private async discoverEntryPoints(): Promise<PeerDescriptor[]> {
|
|
102
99
|
const dataKey = streamPartIdToDataKey(this.config.streamPartId)
|
|
103
|
-
const discoveredEntryPoints =
|
|
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
|
|
112
|
+
logger.trace(`Finding data from dht node ${getNodeIdFromPeerDescriptor(this.config.ownPeerDescriptor)}`)
|
|
118
113
|
try {
|
|
119
|
-
const
|
|
120
|
-
|
|
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.
|
|
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) =>
|
|
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.
|
|
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.
|
|
188
|
-
if (this.config.
|
|
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.
|
|
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
|
|
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
|
|
11
|
-
on<T extends keyof
|
|
12
|
-
once<T extends keyof
|
|
13
|
-
off<T extends keyof
|
|
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[]
|
package/src/logic/NodeList.ts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { PeerDescriptor } from '@streamr/dht'
|
|
2
2
|
import { sample } from 'lodash'
|
|
3
|
-
import {
|
|
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:
|
|
8
|
+
nodeAdded: (id: NodeID, remote: DeliveryRpcRemote) => any
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
const getValuesOfIncludedKeys = (nodes: Map<NodeID,
|
|
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,
|
|
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:
|
|
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:
|
|
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):
|
|
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[]):
|
|
77
|
+
getRandom(exclude: NodeID[]): DeliveryRpcRemote | undefined {
|
|
78
78
|
return sample(getValuesOfIncludedKeys(this.nodes, exclude))
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
getClosest(exclude: NodeID[]):
|
|
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[]):
|
|
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[]):
|
|
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():
|
|
99
|
+
getAll(): DeliveryRpcRemote[] {
|
|
100
100
|
return Array.from(this.nodes.values())
|
|
101
101
|
}
|
|
102
102
|
|