@streamr/trackerless-network 100.2.5-beta.1 → 101.0.0-beta.1
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 +6 -6
- package/dist/src/NetworkNode.js +1 -1
- package/dist/src/NetworkNode.js.map +1 -1
- package/dist/src/NetworkStack.d.ts +5 -5
- package/dist/src/NetworkStack.js +21 -21
- package/dist/src/NetworkStack.js.map +1 -1
- package/dist/src/exports.d.ts +2 -2
- package/dist/src/exports.js +2 -2
- package/dist/src/exports.js.map +1 -1
- package/dist/src/logic/ContentDeliveryLayerNode.d.ts +5 -5
- package/dist/src/logic/ContentDeliveryLayerNode.js +85 -85
- package/dist/src/logic/ContentDeliveryLayerNode.js.map +1 -1
- package/dist/src/logic/ContentDeliveryManager.d.ts +11 -12
- package/dist/src/logic/ContentDeliveryManager.js +65 -61
- package/dist/src/logic/ContentDeliveryManager.js.map +1 -1
- package/dist/src/logic/ContentDeliveryRpcLocal.d.ts +5 -5
- package/dist/src/logic/ContentDeliveryRpcLocal.js +9 -9
- package/dist/src/logic/ContentDeliveryRpcLocal.js.map +1 -1
- package/dist/src/logic/{Layer0Node.d.ts → ControlLayerNode.d.ts} +1 -1
- package/dist/src/logic/{Layer0Node.js → ControlLayerNode.js} +1 -1
- package/dist/src/logic/ControlLayerNode.js.map +1 -0
- package/dist/src/logic/{Layer1Node.d.ts → DiscoveryLayerNode.d.ts} +8 -8
- package/dist/src/logic/{Layer1Node.js → DiscoveryLayerNode.js} +1 -1
- package/dist/src/logic/DiscoveryLayerNode.js.map +1 -0
- package/dist/src/logic/PeerDescriptorStoreManager.d.ts +28 -0
- package/dist/src/logic/PeerDescriptorStoreManager.js +79 -0
- package/dist/src/logic/PeerDescriptorStoreManager.js.map +1 -0
- package/dist/src/logic/StreamPartNetworkSplitAvoidance.d.ts +5 -5
- package/dist/src/logic/StreamPartNetworkSplitAvoidance.js +8 -8
- package/dist/src/logic/StreamPartNetworkSplitAvoidance.js.map +1 -1
- package/dist/src/logic/StreamPartReconnect.d.ts +5 -5
- package/dist/src/logic/StreamPartReconnect.js +10 -10
- package/dist/src/logic/StreamPartReconnect.js.map +1 -1
- package/dist/src/logic/createContentDeliveryLayerNode.d.ts +3 -3
- package/dist/src/logic/createContentDeliveryLayerNode.js +34 -34
- package/dist/src/logic/createContentDeliveryLayerNode.js.map +1 -1
- package/dist/src/logic/inspect/InspectSession.d.ts +3 -3
- package/dist/src/logic/inspect/InspectSession.js +5 -5
- package/dist/src/logic/inspect/InspectSession.js.map +1 -1
- package/dist/src/logic/inspect/Inspector.d.ts +2 -2
- package/dist/src/logic/inspect/Inspector.js +8 -8
- package/dist/src/logic/inspect/Inspector.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.d.ts +4 -4
- package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.js +24 -24
- package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.d.ts +1 -1
- package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.js +4 -4
- package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/Handshaker.d.ts +3 -3
- package/dist/src/logic/neighbor-discovery/Handshaker.js +37 -37
- package/dist/src/logic/neighbor-discovery/Handshaker.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborFinder.d.ts +3 -3
- package/dist/src/logic/neighbor-discovery/NeighborFinder.js +9 -9
- package/dist/src/logic/neighbor-discovery/NeighborFinder.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.d.ts +3 -3
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js +12 -12
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.d.ts +3 -3
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.js +14 -14
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.js.map +1 -1
- package/dist/src/logic/proxy/ProxyClient.d.ts +3 -3
- package/dist/src/logic/proxy/ProxyClient.js +25 -25
- package/dist/src/logic/proxy/ProxyClient.js.map +1 -1
- package/dist/src/logic/proxy/ProxyConnectionRpcLocal.d.ts +3 -3
- package/dist/src/logic/proxy/ProxyConnectionRpcLocal.js +10 -10
- package/dist/src/logic/proxy/ProxyConnectionRpcLocal.js.map +1 -1
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.d.ts +3 -3
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.js +11 -11
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +4 -4
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +8 -8
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +11 -3
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +7 -5
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +2 -2
- package/dist/src/proto/packages/proto-rpc/protos/ProtoRpc.js +1 -1
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.js +1 -1
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.d.ts +6 -23
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js +5 -23
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js.map +1 -1
- package/dist/test/benchmark/first-message.js +7 -7
- package/dist/test/benchmark/first-message.js.map +1 -1
- package/dist/test/utils/utils.d.ts +2 -2
- package/dist/test/utils/utils.js +3 -3
- package/dist/test/utils/utils.js.map +1 -1
- package/package.json +6 -6
- package/protos/NetworkRpc.proto +3 -9
- package/src/NetworkNode.ts +1 -1
- package/src/NetworkStack.ts +24 -24
- package/src/exports.ts +2 -2
- package/src/logic/ContentDeliveryLayerNode.ts +112 -112
- package/src/logic/ContentDeliveryManager.ts +71 -67
- package/src/logic/ContentDeliveryRpcLocal.ts +12 -12
- package/src/logic/{Layer0Node.ts → ControlLayerNode.ts} +1 -1
- package/src/logic/{Layer1Node.ts → DiscoveryLayerNode.ts} +8 -8
- package/src/logic/PeerDescriptorStoreManager.ts +97 -0
- package/src/logic/StreamPartNetworkSplitAvoidance.ts +11 -11
- package/src/logic/StreamPartReconnect.ts +12 -12
- package/src/logic/createContentDeliveryLayerNode.ts +38 -38
- package/src/logic/inspect/InspectSession.ts +6 -6
- package/src/logic/inspect/Inspector.ts +9 -9
- package/src/logic/neighbor-discovery/HandshakeRpcLocal.ts +26 -26
- package/src/logic/neighbor-discovery/HandshakeRpcRemote.ts +6 -6
- package/src/logic/neighbor-discovery/Handshaker.ts +45 -45
- package/src/logic/neighbor-discovery/NeighborFinder.ts +10 -10
- package/src/logic/neighbor-discovery/NeighborUpdateManager.ts +14 -14
- package/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.ts +17 -17
- package/src/logic/proxy/ProxyClient.ts +26 -26
- package/src/logic/proxy/ProxyConnectionRpcLocal.ts +12 -12
- package/src/logic/temporary-connection/TemporaryConnectionRpcLocal.ts +13 -13
- package/src/proto/google/protobuf/any.ts +1 -1
- package/src/proto/google/protobuf/empty.ts +1 -1
- package/src/proto/google/protobuf/timestamp.ts +1 -1
- package/src/proto/packages/dht/protos/DhtRpc.client.ts +9 -9
- package/src/proto/packages/dht/protos/DhtRpc.server.ts +3 -3
- package/src/proto/packages/dht/protos/DhtRpc.ts +15 -5
- package/src/proto/packages/proto-rpc/protos/ProtoRpc.ts +1 -1
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.client.ts +1 -1
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.server.ts +1 -1
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.ts +10 -27
- package/test/benchmark/StreamPartIdDataKeyDistribution.test.ts +1 -1
- package/test/benchmark/first-message.ts +9 -9
- package/test/end-to-end/content-delivery-layer-node-with-real-connections.test.ts +12 -12
- package/test/end-to-end/proxy-and-full-node.test.ts +4 -4
- package/test/integration/ContentDeliveryLayerNode-Layer1Node-Latencies.test.ts +19 -19
- package/test/integration/ContentDeliveryLayerNode-Layer1Node.test.ts +19 -19
- package/test/integration/ContentDeliveryManager.test.ts +11 -11
- package/test/integration/Inspect.test.ts +1 -1
- package/test/integration/Propagation.test.ts +6 -6
- package/test/integration/joining-streams-on-offline-peers.test.ts +3 -3
- package/test/integration/stream-without-default-entrypoints.test.ts +2 -2
- package/test/integration/streamEntryPointReplacing.test.ts +2 -2
- package/test/unit/ContentDeliveryLayerNode.test.ts +11 -11
- package/test/unit/ContentDeliveryManager.test.ts +2 -2
- package/test/unit/{EntrypointDiscovery.test.ts → PeerDescriptorStoreManager.test.ts} +28 -29
- package/test/unit/StreamPartIDDataKey.test.ts +1 -1
- package/test/unit/StreamPartNetworkSplitAvoidance.test.ts +8 -8
- package/test/unit/StreamPartReconnect.test.ts +9 -9
- package/test/utils/fake/FakePeerDescriptorStoreManager.ts +29 -0
- package/test/utils/mock/{MockLayer0Node.ts → MockControlLayerNode.ts} +2 -2
- package/test/utils/mock/{MockLayer1Node.ts → MockDiscoveryLayerNode.ts} +2 -2
- package/test/utils/utils.ts +5 -5
- package/dist/src/logic/EntryPointDiscovery.d.ts +0 -27
- package/dist/src/logic/EntryPointDiscovery.js +0 -80
- package/dist/src/logic/EntryPointDiscovery.js.map +0 -1
- package/dist/src/logic/Layer0Node.js.map +0 -1
- package/dist/src/logic/Layer1Node.js.map +0 -1
- package/src/logic/EntryPointDiscovery.ts +0 -100
- package/test/utils/fake/FakeEntryPointDiscovery.ts +0 -29
|
@@ -2,7 +2,7 @@ import { DhtAddress, ListeningRpcCommunicator, getNodeIdFromPeerDescriptor } fro
|
|
|
2
2
|
import { Handshaker } from './neighbor-discovery/Handshaker'
|
|
3
3
|
import { NeighborFinder } from './neighbor-discovery/NeighborFinder'
|
|
4
4
|
import { NeighborUpdateManager } from './neighbor-discovery/NeighborUpdateManager'
|
|
5
|
-
import {
|
|
5
|
+
import { StrictContentDeliveryLayerNodeOptions, ContentDeliveryLayerNode } from './ContentDeliveryLayerNode'
|
|
6
6
|
import { NodeList } from './NodeList'
|
|
7
7
|
import { Propagation } from './propagation/Propagation'
|
|
8
8
|
import { StreamMessage } from '../proto/packages/trackerless-network/protos/NetworkRpc'
|
|
@@ -12,7 +12,7 @@ import { Inspector } from './inspect/Inspector'
|
|
|
12
12
|
import { TemporaryConnectionRpcLocal } from './temporary-connection/TemporaryConnectionRpcLocal'
|
|
13
13
|
import { formStreamPartContentDeliveryServiceId } from './formStreamPartDeliveryServiceId'
|
|
14
14
|
|
|
15
|
-
type
|
|
15
|
+
type ContentDeliveryLayerNodeOptions = MarkOptional<StrictContentDeliveryLayerNodeOptions,
|
|
16
16
|
'nearbyNodeView' | 'randomNodeView' | 'neighbors' | 'leftNodeView' | 'rightNodeView' | 'propagation'
|
|
17
17
|
| 'handshaker' | 'neighborFinder' | 'neighborUpdateManager' | 'neighborTargetCount'
|
|
18
18
|
| 'rpcCommunicator' | 'nodeViewSize'
|
|
@@ -23,36 +23,36 @@ type ContentDeliveryLayerNodeConfig = MarkOptional<StrictContentDeliveryLayerNod
|
|
|
23
23
|
neighborUpdateInterval?: number
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
const createConfigWithDefaults = (
|
|
27
|
-
const ownNodeId = getNodeIdFromPeerDescriptor(
|
|
28
|
-
const rpcCommunicator =
|
|
29
|
-
formStreamPartContentDeliveryServiceId(
|
|
30
|
-
|
|
26
|
+
const createConfigWithDefaults = (options: ContentDeliveryLayerNodeOptions): StrictContentDeliveryLayerNodeOptions => {
|
|
27
|
+
const ownNodeId = getNodeIdFromPeerDescriptor(options.localPeerDescriptor)
|
|
28
|
+
const rpcCommunicator = options.rpcCommunicator ?? new ListeningRpcCommunicator(
|
|
29
|
+
formStreamPartContentDeliveryServiceId(options.streamPartId),
|
|
30
|
+
options.transport
|
|
31
31
|
)
|
|
32
|
-
const neighborTargetCount =
|
|
33
|
-
const maxContactCount =
|
|
34
|
-
const minPropagationTargets =
|
|
35
|
-
const acceptProxyConnections =
|
|
36
|
-
const neighborUpdateInterval =
|
|
37
|
-
const neighbors =
|
|
38
|
-
const leftNodeView =
|
|
39
|
-
const rightNodeView =
|
|
40
|
-
const nearbyNodeView =
|
|
41
|
-
const randomNodeView =
|
|
32
|
+
const neighborTargetCount = options.neighborTargetCount ?? 4
|
|
33
|
+
const maxContactCount = options.maxContactCount ?? 20
|
|
34
|
+
const minPropagationTargets = options.minPropagationTargets ?? 2
|
|
35
|
+
const acceptProxyConnections = options.acceptProxyConnections ?? false
|
|
36
|
+
const neighborUpdateInterval = options.neighborUpdateInterval ?? 10000
|
|
37
|
+
const neighbors = options.neighbors ?? new NodeList(ownNodeId, maxContactCount)
|
|
38
|
+
const leftNodeView = options.leftNodeView ?? new NodeList(ownNodeId, maxContactCount)
|
|
39
|
+
const rightNodeView = options.rightNodeView ?? new NodeList(ownNodeId, maxContactCount)
|
|
40
|
+
const nearbyNodeView = options.nearbyNodeView ?? new NodeList(ownNodeId, maxContactCount)
|
|
41
|
+
const randomNodeView = options.randomNodeView ?? new NodeList(ownNodeId, maxContactCount)
|
|
42
42
|
const ongoingHandshakes = new Set<DhtAddress>()
|
|
43
43
|
|
|
44
44
|
const temporaryConnectionRpcLocal = new TemporaryConnectionRpcLocal({
|
|
45
45
|
rpcCommunicator,
|
|
46
|
-
localPeerDescriptor:
|
|
47
|
-
streamPartId:
|
|
48
|
-
connectionLocker:
|
|
46
|
+
localPeerDescriptor: options.localPeerDescriptor,
|
|
47
|
+
streamPartId: options.streamPartId,
|
|
48
|
+
connectionLocker: options.connectionLocker
|
|
49
49
|
})
|
|
50
50
|
const proxyConnectionRpcLocal = acceptProxyConnections ? new ProxyConnectionRpcLocal({
|
|
51
|
-
localPeerDescriptor:
|
|
52
|
-
streamPartId:
|
|
51
|
+
localPeerDescriptor: options.localPeerDescriptor,
|
|
52
|
+
streamPartId: options.streamPartId,
|
|
53
53
|
rpcCommunicator
|
|
54
54
|
}) : undefined
|
|
55
|
-
const propagation =
|
|
55
|
+
const propagation = options.propagation ?? new Propagation({
|
|
56
56
|
minPropagationTargets,
|
|
57
57
|
sendToNeighbor: async (neighborId: DhtAddress, msg: StreamMessage): Promise<void> => {
|
|
58
58
|
const remote = neighbors.get(neighborId) ?? temporaryConnectionRpcLocal.getNodes().get(neighborId)
|
|
@@ -66,9 +66,9 @@ const createConfigWithDefaults = (config: ContentDeliveryLayerNodeConfig): Stric
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
})
|
|
69
|
-
const handshaker =
|
|
70
|
-
localPeerDescriptor:
|
|
71
|
-
streamPartId:
|
|
69
|
+
const handshaker = options.handshaker ?? new Handshaker({
|
|
70
|
+
localPeerDescriptor: options.localPeerDescriptor,
|
|
71
|
+
streamPartId: options.streamPartId,
|
|
72
72
|
rpcCommunicator,
|
|
73
73
|
neighbors,
|
|
74
74
|
leftNodeView,
|
|
@@ -76,10 +76,10 @@ const createConfigWithDefaults = (config: ContentDeliveryLayerNodeConfig): Stric
|
|
|
76
76
|
nearbyNodeView,
|
|
77
77
|
randomNodeView,
|
|
78
78
|
maxNeighborCount: neighborTargetCount,
|
|
79
|
-
rpcRequestTimeout:
|
|
79
|
+
rpcRequestTimeout: options.rpcRequestTimeout,
|
|
80
80
|
ongoingHandshakes
|
|
81
81
|
})
|
|
82
|
-
const neighborFinder =
|
|
82
|
+
const neighborFinder = options.neighborFinder ?? new NeighborFinder({
|
|
83
83
|
neighbors,
|
|
84
84
|
leftNodeView,
|
|
85
85
|
rightNodeView,
|
|
@@ -88,25 +88,25 @@ const createConfigWithDefaults = (config: ContentDeliveryLayerNodeConfig): Stric
|
|
|
88
88
|
doFindNeighbors: (excludedIds) => handshaker.attemptHandshakesOnContacts(excludedIds),
|
|
89
89
|
minCount: neighborTargetCount
|
|
90
90
|
})
|
|
91
|
-
const neighborUpdateManager =
|
|
91
|
+
const neighborUpdateManager = options.neighborUpdateManager ?? new NeighborUpdateManager({
|
|
92
92
|
neighbors,
|
|
93
93
|
nearbyNodeView,
|
|
94
|
-
localPeerDescriptor:
|
|
94
|
+
localPeerDescriptor: options.localPeerDescriptor,
|
|
95
95
|
neighborFinder,
|
|
96
|
-
streamPartId:
|
|
96
|
+
streamPartId: options.streamPartId,
|
|
97
97
|
rpcCommunicator,
|
|
98
98
|
neighborUpdateInterval,
|
|
99
99
|
neighborTargetCount,
|
|
100
100
|
ongoingHandshakes
|
|
101
101
|
})
|
|
102
|
-
const inspector =
|
|
103
|
-
localPeerDescriptor:
|
|
102
|
+
const inspector = options.inspector ?? new Inspector({
|
|
103
|
+
localPeerDescriptor: options.localPeerDescriptor,
|
|
104
104
|
rpcCommunicator,
|
|
105
|
-
streamPartId:
|
|
106
|
-
connectionLocker:
|
|
105
|
+
streamPartId: options.streamPartId,
|
|
106
|
+
connectionLocker: options.connectionLocker
|
|
107
107
|
})
|
|
108
108
|
return {
|
|
109
|
-
...
|
|
109
|
+
...options,
|
|
110
110
|
neighbors,
|
|
111
111
|
leftNodeView,
|
|
112
112
|
rightNodeView,
|
|
@@ -125,6 +125,6 @@ const createConfigWithDefaults = (config: ContentDeliveryLayerNodeConfig): Stric
|
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
export const createContentDeliveryLayerNode = (
|
|
129
|
-
return new ContentDeliveryLayerNode(createConfigWithDefaults(
|
|
128
|
+
export const createContentDeliveryLayerNode = (options: ContentDeliveryLayerNodeOptions): ContentDeliveryLayerNode => {
|
|
129
|
+
return new ContentDeliveryLayerNode(createConfigWithDefaults(options))
|
|
130
130
|
}
|
|
@@ -7,7 +7,7 @@ export interface Events {
|
|
|
7
7
|
done: () => void
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
interface
|
|
10
|
+
interface InspectSessionOptions {
|
|
11
11
|
inspectedNode: DhtAddress
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -20,18 +20,18 @@ export class InspectSession extends EventEmitter<Events> {
|
|
|
20
20
|
private readonly inspectionMessages: Map<string, boolean> = new Map()
|
|
21
21
|
private readonly inspectedNode: DhtAddress
|
|
22
22
|
|
|
23
|
-
constructor(
|
|
23
|
+
constructor(options: InspectSessionOptions) {
|
|
24
24
|
super()
|
|
25
|
-
this.inspectedNode =
|
|
25
|
+
this.inspectedNode = options.inspectedNode
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
markMessage(
|
|
28
|
+
markMessage(remoteNodeId: DhtAddress, messageId: MessageID): void {
|
|
29
29
|
const messageKey = createMessageKey(messageId)
|
|
30
30
|
if (!this.inspectionMessages.has(messageKey)) {
|
|
31
|
-
this.inspectionMessages.set(messageKey,
|
|
31
|
+
this.inspectionMessages.set(messageKey, remoteNodeId === this.inspectedNode)
|
|
32
32
|
} else if (this.inspectionMessages.has(messageKey)
|
|
33
33
|
&& this.inspectionMessages.get(messageKey) === false
|
|
34
|
-
&&
|
|
34
|
+
&& remoteNodeId === this.inspectedNode
|
|
35
35
|
) {
|
|
36
36
|
this.emit('done')
|
|
37
37
|
} else if (this.inspectionMessages.has(messageKey)
|
|
@@ -6,7 +6,7 @@ import { Logger, waitForEvent3 } from '@streamr/utils'
|
|
|
6
6
|
import { TemporaryConnectionRpcRemote } from '../temporary-connection/TemporaryConnectionRpcRemote'
|
|
7
7
|
import { StreamPartID } from '@streamr/protocol'
|
|
8
8
|
|
|
9
|
-
interface
|
|
9
|
+
interface InspectorOptions {
|
|
10
10
|
localPeerDescriptor: PeerDescriptor
|
|
11
11
|
streamPartId: StreamPartID
|
|
12
12
|
rpcCommunicator: ListeningRpcCommunicator
|
|
@@ -30,14 +30,14 @@ export class Inspector {
|
|
|
30
30
|
private readonly openInspectConnection: (peerDescriptor: PeerDescriptor, lockId: LockID) => Promise<void>
|
|
31
31
|
private readonly closeInspectConnection: (peerDescriptor: PeerDescriptor, lockId: LockID) => Promise<void>
|
|
32
32
|
|
|
33
|
-
constructor(
|
|
34
|
-
this.streamPartId =
|
|
35
|
-
this.localPeerDescriptor =
|
|
36
|
-
this.rpcCommunicator =
|
|
37
|
-
this.connectionLocker =
|
|
38
|
-
this.inspectionTimeout =
|
|
39
|
-
this.openInspectConnection =
|
|
40
|
-
this.closeInspectConnection =
|
|
33
|
+
constructor(options: InspectorOptions) {
|
|
34
|
+
this.streamPartId = options.streamPartId
|
|
35
|
+
this.localPeerDescriptor = options.localPeerDescriptor
|
|
36
|
+
this.rpcCommunicator = options.rpcCommunicator
|
|
37
|
+
this.connectionLocker = options.connectionLocker
|
|
38
|
+
this.inspectionTimeout = options.inspectionTimeout ?? DEFAULT_TIMEOUT
|
|
39
|
+
this.openInspectConnection = options.openInspectConnection ?? this.defaultOpenInspectConnection
|
|
40
|
+
this.closeInspectConnection = options.closeInspectConnection ?? this.defaultCloseInspectConnection
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
async defaultOpenInspectConnection(peerDescriptor: PeerDescriptor, lockId: LockID): Promise<void> {
|
|
@@ -20,7 +20,7 @@ import { ContentDeliveryRpcRemote } from '../ContentDeliveryRpcRemote'
|
|
|
20
20
|
import { Logger } from '@streamr/utils'
|
|
21
21
|
import { StreamPartID } from '@streamr/protocol'
|
|
22
22
|
|
|
23
|
-
interface
|
|
23
|
+
interface HandshakeRpcLocalOptions {
|
|
24
24
|
streamPartId: StreamPartID
|
|
25
25
|
neighbors: NodeList
|
|
26
26
|
ongoingHandshakes: Set<DhtAddress>
|
|
@@ -28,17 +28,17 @@ interface HandshakeRpcLocalConfig {
|
|
|
28
28
|
maxNeighborCount: number
|
|
29
29
|
createRpcRemote: (target: PeerDescriptor) => HandshakeRpcRemote
|
|
30
30
|
createContentDeliveryRpcRemote: (peerDescriptor: PeerDescriptor) => ContentDeliveryRpcRemote
|
|
31
|
-
handshakeWithInterleaving: (target: PeerDescriptor,
|
|
31
|
+
handshakeWithInterleaving: (target: PeerDescriptor, remoteNodeId: DhtAddress) => Promise<boolean>
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
const logger = new Logger(module)
|
|
35
35
|
|
|
36
36
|
export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
37
37
|
|
|
38
|
-
private readonly
|
|
38
|
+
private readonly options: HandshakeRpcLocalOptions
|
|
39
39
|
|
|
40
|
-
constructor(
|
|
41
|
-
this.
|
|
40
|
+
constructor(options: HandshakeRpcLocalOptions) {
|
|
41
|
+
this.options = options
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
async handshake(request: StreamPartHandshakeRequest, context: ServerCallContext): Promise<StreamPartHandshakeResponse> {
|
|
@@ -47,19 +47,19 @@ export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
|
47
47
|
|
|
48
48
|
private handleRequest(request: StreamPartHandshakeRequest, context: ServerCallContext): StreamPartHandshakeResponse {
|
|
49
49
|
const senderDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
|
|
50
|
-
const
|
|
50
|
+
const getInterleaveNodeIds = () => (request.interleaveNodeId !== undefined) ? [getDhtAddressFromRaw(request.interleaveNodeId)] : []
|
|
51
51
|
const senderNodeId = getNodeIdFromPeerDescriptor(senderDescriptor)
|
|
52
|
-
if (this.
|
|
52
|
+
if (this.options.ongoingInterleaves.has(senderNodeId)) {
|
|
53
53
|
return this.rejectHandshake(request)
|
|
54
|
-
} else if (this.
|
|
55
|
-
|| this.
|
|
54
|
+
} else if (this.options.neighbors.has(senderNodeId)
|
|
55
|
+
|| this.options.ongoingHandshakes.has(senderNodeId)
|
|
56
56
|
) {
|
|
57
57
|
return this.acceptHandshake(request, senderDescriptor)
|
|
58
|
-
} else if (this.
|
|
58
|
+
} else if (this.options.neighbors.size() + this.options.ongoingHandshakes.size < this.options.maxNeighborCount) {
|
|
59
59
|
return this.acceptHandshake(request, senderDescriptor)
|
|
60
60
|
} else if (
|
|
61
|
-
this.
|
|
62
|
-
&& this.
|
|
61
|
+
this.options.neighbors.size(getInterleaveNodeIds()) - this.options.ongoingInterleaves.size >= 2
|
|
62
|
+
&& this.options.neighbors.size() <= this.options.maxNeighborCount
|
|
63
63
|
) {
|
|
64
64
|
// Do not accept the handshakes requests if the target neighbor count can potentially drop below 2
|
|
65
65
|
// due to interleaving. This ensures that a stable number of connections is kept during high churn.
|
|
@@ -74,7 +74,7 @@ export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
|
74
74
|
requestId: request.requestId,
|
|
75
75
|
accepted: true
|
|
76
76
|
}
|
|
77
|
-
this.
|
|
77
|
+
this.options.neighbors.add(this.options.createContentDeliveryRpcRemote(requester))
|
|
78
78
|
return res
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -89,18 +89,18 @@ export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
|
89
89
|
|
|
90
90
|
private acceptHandshakeWithInterleaving(request: StreamPartHandshakeRequest, requester: PeerDescriptor): StreamPartHandshakeResponse {
|
|
91
91
|
const exclude: DhtAddress[] = []
|
|
92
|
-
request.
|
|
93
|
-
this.
|
|
92
|
+
request.neighborNodeIds.forEach((id: DhtAddressRaw) => exclude.push(getDhtAddressFromRaw(id)))
|
|
93
|
+
this.options.ongoingInterleaves.forEach((id) => exclude.push(id))
|
|
94
94
|
exclude.push(getNodeIdFromPeerDescriptor(requester))
|
|
95
|
-
if (request.
|
|
96
|
-
exclude.push(getDhtAddressFromRaw(request.
|
|
95
|
+
if (request.interleaveNodeId !== undefined) {
|
|
96
|
+
exclude.push(getDhtAddressFromRaw(request.interleaveNodeId))
|
|
97
97
|
}
|
|
98
|
-
const last = this.
|
|
98
|
+
const last = this.options.neighbors.getLast(exclude)
|
|
99
99
|
const lastPeerDescriptor = last ? last.getPeerDescriptor() : undefined
|
|
100
100
|
if (last) {
|
|
101
101
|
const nodeId = getNodeIdFromPeerDescriptor(last.getPeerDescriptor())
|
|
102
|
-
const remote = this.
|
|
103
|
-
this.
|
|
102
|
+
const remote = this.options.createRpcRemote(last.getPeerDescriptor())
|
|
103
|
+
this.options.ongoingInterleaves.add(nodeId)
|
|
104
104
|
// Run this with then catch instead of setImmediate to avoid changes in state
|
|
105
105
|
// eslint-disable-next-line promise/catch-or-return
|
|
106
106
|
remote.interleaveRequest(requester).then((response) => {
|
|
@@ -108,15 +108,15 @@ export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
|
108
108
|
// and unlock the connection
|
|
109
109
|
// If response is not accepted, keep the last node as a neighbor
|
|
110
110
|
if (response.accepted) {
|
|
111
|
-
this.
|
|
111
|
+
this.options.neighbors.remove(getNodeIdFromPeerDescriptor(lastPeerDescriptor!))
|
|
112
112
|
}
|
|
113
113
|
}).catch(() => {
|
|
114
114
|
// no-op: InterleaveRequest cannot reject
|
|
115
115
|
}).finally(() => {
|
|
116
|
-
this.
|
|
116
|
+
this.options.ongoingInterleaves.delete(nodeId)
|
|
117
117
|
})
|
|
118
118
|
}
|
|
119
|
-
this.
|
|
119
|
+
this.options.neighbors.add(this.options.createContentDeliveryRpcRemote(requester))
|
|
120
120
|
return {
|
|
121
121
|
requestId: request.requestId,
|
|
122
122
|
accepted: true,
|
|
@@ -126,10 +126,10 @@ export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
|
126
126
|
|
|
127
127
|
async interleaveRequest(message: InterleaveRequest, context: ServerCallContext): Promise<InterleaveResponse> {
|
|
128
128
|
const senderPeerDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
|
|
129
|
-
const
|
|
129
|
+
const remoteNodeId = getNodeIdFromPeerDescriptor(senderPeerDescriptor)
|
|
130
130
|
try {
|
|
131
|
-
await this.
|
|
132
|
-
this.
|
|
131
|
+
await this.options.handshakeWithInterleaving(message.interleaveTargetDescriptor!, remoteNodeId)
|
|
132
|
+
this.options.neighbors.remove(remoteNodeId)
|
|
133
133
|
return { accepted: true }
|
|
134
134
|
} catch (err) {
|
|
135
135
|
logger.debug(`interleaveRequest to ${getNodeIdFromPeerDescriptor(message.interleaveTargetDescriptor!)} failed`, { err })
|
|
@@ -18,16 +18,16 @@ export class HandshakeRpcRemote extends RpcRemote<HandshakeRpcClient> {
|
|
|
18
18
|
|
|
19
19
|
async handshake(
|
|
20
20
|
streamPartId: StreamPartID,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
neighborNodeIds: DhtAddress[],
|
|
22
|
+
concurrentHandshakeNodeId?: DhtAddress,
|
|
23
|
+
interleaveNodeId?: DhtAddress
|
|
24
24
|
): Promise<HandshakeResponse> {
|
|
25
25
|
const request: StreamPartHandshakeRequest = {
|
|
26
26
|
streamPartId,
|
|
27
27
|
requestId: v4(),
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
neighborNodeIds: neighborNodeIds.map((id) => getRawFromDhtAddress(id)),
|
|
29
|
+
concurrentHandshakeNodeId: (concurrentHandshakeNodeId !== undefined) ? getRawFromDhtAddress(concurrentHandshakeNodeId) : undefined,
|
|
30
|
+
interleaveNodeId: (interleaveNodeId !== undefined) ? getRawFromDhtAddress(interleaveNodeId) : undefined
|
|
31
31
|
}
|
|
32
32
|
try {
|
|
33
33
|
const response = await this.getClient().handshake(request, this.formDhtRpcOptions())
|
|
@@ -15,7 +15,7 @@ import { HandshakeRpcRemote, INTERLEAVE_REQUEST_TIMEOUT } from './HandshakeRpcRe
|
|
|
15
15
|
import { HandshakeRpcLocal } from './HandshakeRpcLocal'
|
|
16
16
|
import { StreamPartID } from '@streamr/protocol'
|
|
17
17
|
|
|
18
|
-
interface
|
|
18
|
+
interface HandshakerOptions {
|
|
19
19
|
localPeerDescriptor: PeerDescriptor
|
|
20
20
|
streamPartId: StreamPartID
|
|
21
21
|
neighbors: NodeList
|
|
@@ -35,33 +35,33 @@ const PARALLEL_HANDSHAKE_COUNT = 2
|
|
|
35
35
|
|
|
36
36
|
export class Handshaker {
|
|
37
37
|
|
|
38
|
-
private
|
|
38
|
+
private options: HandshakerOptions
|
|
39
39
|
private readonly rpcLocal: HandshakeRpcLocal
|
|
40
40
|
|
|
41
|
-
constructor(
|
|
42
|
-
this.
|
|
41
|
+
constructor(options: HandshakerOptions) {
|
|
42
|
+
this.options = options
|
|
43
43
|
this.rpcLocal = new HandshakeRpcLocal({
|
|
44
|
-
streamPartId: this.
|
|
45
|
-
neighbors: this.
|
|
46
|
-
ongoingHandshakes: this.
|
|
44
|
+
streamPartId: this.options.streamPartId,
|
|
45
|
+
neighbors: this.options.neighbors,
|
|
46
|
+
ongoingHandshakes: this.options.ongoingHandshakes,
|
|
47
47
|
ongoingInterleaves: new Set(),
|
|
48
|
-
maxNeighborCount: this.
|
|
49
|
-
handshakeWithInterleaving: (target: PeerDescriptor,
|
|
48
|
+
maxNeighborCount: this.options.maxNeighborCount,
|
|
49
|
+
handshakeWithInterleaving: (target: PeerDescriptor, remoteNodeId: DhtAddress) => this.handshakeWithInterleaving(target, remoteNodeId),
|
|
50
50
|
createRpcRemote: (target: PeerDescriptor) => this.createRpcRemote(target),
|
|
51
51
|
createContentDeliveryRpcRemote: (target: PeerDescriptor) => this.createContentDeliveryRpcRemote(target)
|
|
52
52
|
})
|
|
53
|
-
this.
|
|
53
|
+
this.options.rpcCommunicator.registerRpcMethod(InterleaveRequest, InterleaveResponse, 'interleaveRequest',
|
|
54
54
|
(req: InterleaveRequest, context) => this.rpcLocal.interleaveRequest(req, context), { timeout: INTERLEAVE_REQUEST_TIMEOUT })
|
|
55
|
-
this.
|
|
55
|
+
this.options.rpcCommunicator.registerRpcMethod(StreamPartHandshakeRequest, StreamPartHandshakeResponse, 'handshake',
|
|
56
56
|
(req: StreamPartHandshakeRequest, context) => this.rpcLocal.handshake(req, context))
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
async attemptHandshakesOnContacts(excludedIds: DhtAddress[]): Promise<DhtAddress[]> {
|
|
60
|
-
// TODO use
|
|
61
|
-
if (this.
|
|
60
|
+
// TODO use options option or named constant? or why the value 2?
|
|
61
|
+
if (this.options.neighbors.size() + this.options.ongoingHandshakes.size < this.options.maxNeighborCount - 2) {
|
|
62
62
|
logger.trace(`Attempting parallel handshakes with ${PARALLEL_HANDSHAKE_COUNT} targets`)
|
|
63
63
|
return this.selectParallelTargetsAndHandshake(excludedIds)
|
|
64
|
-
} else if (this.
|
|
64
|
+
} else if (this.options.neighbors.size() + this.options.ongoingHandshakes.size < this.options.maxNeighborCount) {
|
|
65
65
|
logger.trace(`Attempting handshake with new target`)
|
|
66
66
|
return this.selectNewTargetAndHandshake(excludedIds)
|
|
67
67
|
}
|
|
@@ -69,17 +69,17 @@ export class Handshaker {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
private async selectParallelTargetsAndHandshake(excludedIds: DhtAddress[]): Promise<DhtAddress[]> {
|
|
72
|
-
const exclude = excludedIds.concat(this.
|
|
72
|
+
const exclude = excludedIds.concat(this.options.neighbors.getIds())
|
|
73
73
|
const neighbors = this.selectParallelTargets(exclude)
|
|
74
|
-
neighbors.forEach((contact) => this.
|
|
74
|
+
neighbors.forEach((contact) => this.options.ongoingHandshakes.add(getNodeIdFromPeerDescriptor(contact.getPeerDescriptor())))
|
|
75
75
|
return this.doParallelHandshakes(neighbors, exclude)
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
private selectParallelTargets(excludedIds: DhtAddress[]): HandshakeRpcRemote[] {
|
|
79
79
|
const neighbors: Map<DhtAddress, ContentDeliveryRpcRemote> = new Map()
|
|
80
80
|
// First add the closest left and then right contacts from the ring if possible.
|
|
81
|
-
const left = this.
|
|
82
|
-
const right = this.
|
|
81
|
+
const left = this.options.leftNodeView.getFirst([...excludedIds, ...Array.from(neighbors.keys())] as DhtAddress[])
|
|
82
|
+
const right = this.options.rightNodeView.getFirst([...excludedIds, ...Array.from(neighbors.keys())] as DhtAddress[])
|
|
83
83
|
if (left) {
|
|
84
84
|
neighbors.set(getNodeIdFromPeerDescriptor(left.getPeerDescriptor()), left)
|
|
85
85
|
}
|
|
@@ -88,7 +88,7 @@ export class Handshaker {
|
|
|
88
88
|
}
|
|
89
89
|
// If there is still room add the closest contact based on the kademlia metric
|
|
90
90
|
if (neighbors.size < PARALLEL_HANDSHAKE_COUNT) {
|
|
91
|
-
const first = this.
|
|
91
|
+
const first = this.options.nearbyNodeView.getFirst([...excludedIds, ...Array.from(neighbors.keys())] as DhtAddress[])
|
|
92
92
|
if (first) {
|
|
93
93
|
neighbors.set(getNodeIdFromPeerDescriptor(first.getPeerDescriptor()), first)
|
|
94
94
|
}
|
|
@@ -100,9 +100,9 @@ export class Handshaker {
|
|
|
100
100
|
// If there is still room add a random contact until PARALLEL_HANDSHAKE_COUNT is reached
|
|
101
101
|
while (
|
|
102
102
|
neighbors.size < PARALLEL_HANDSHAKE_COUNT
|
|
103
|
-
&& this.
|
|
103
|
+
&& this.options.randomNodeView.size(getExcludedFromRandomView()) > 0
|
|
104
104
|
) {
|
|
105
|
-
const random = this.
|
|
105
|
+
const random = this.options.randomNodeView.getRandom([...excludedIds, ...Array.from(neighbors.keys())] as DhtAddress[])
|
|
106
106
|
if (random) {
|
|
107
107
|
neighbors.set(getNodeIdFromPeerDescriptor(random.getPeerDescriptor()), random)
|
|
108
108
|
}
|
|
@@ -128,11 +128,11 @@ export class Handshaker {
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
private async selectNewTargetAndHandshake(excludedIds: DhtAddress[]): Promise<DhtAddress[]> {
|
|
131
|
-
const exclude = excludedIds.concat(this.
|
|
132
|
-
const neighbor = this.
|
|
133
|
-
?? this.
|
|
134
|
-
?? this.
|
|
135
|
-
?? this.
|
|
131
|
+
const exclude = excludedIds.concat(this.options.neighbors.getIds())
|
|
132
|
+
const neighbor = this.options.leftNodeView.getFirst(exclude)
|
|
133
|
+
?? this.options.rightNodeView.getFirst(exclude)
|
|
134
|
+
?? this.options.nearbyNodeView.getFirst(exclude)
|
|
135
|
+
?? this.options.randomNodeView.getRandom(exclude)
|
|
136
136
|
if (neighbor) {
|
|
137
137
|
const accepted = await this.handshakeWithTarget(this.createRpcRemote(neighbor.getPeerDescriptor()))
|
|
138
138
|
if (!accepted) {
|
|
@@ -144,61 +144,61 @@ export class Handshaker {
|
|
|
144
144
|
|
|
145
145
|
private async handshakeWithTarget(neighbor: HandshakeRpcRemote, concurrentNodeId?: DhtAddress): Promise<boolean> {
|
|
146
146
|
const targetNodeId = getNodeIdFromPeerDescriptor(neighbor.getPeerDescriptor())
|
|
147
|
-
this.
|
|
147
|
+
this.options.ongoingHandshakes.add(targetNodeId)
|
|
148
148
|
const result = await neighbor.handshake(
|
|
149
|
-
this.
|
|
150
|
-
this.
|
|
149
|
+
this.options.streamPartId,
|
|
150
|
+
this.options.neighbors.getIds(),
|
|
151
151
|
concurrentNodeId
|
|
152
152
|
)
|
|
153
153
|
if (result.accepted) {
|
|
154
|
-
this.
|
|
154
|
+
this.options.neighbors.add(this.createContentDeliveryRpcRemote(neighbor.getPeerDescriptor()))
|
|
155
155
|
}
|
|
156
156
|
if (result.interleaveTargetDescriptor) {
|
|
157
157
|
await this.handshakeWithInterleaving(result.interleaveTargetDescriptor, targetNodeId)
|
|
158
158
|
}
|
|
159
|
-
this.
|
|
159
|
+
this.options.ongoingHandshakes.delete(targetNodeId)
|
|
160
160
|
return result.accepted
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
private async handshakeWithInterleaving(target: PeerDescriptor,
|
|
163
|
+
private async handshakeWithInterleaving(target: PeerDescriptor, remoteNodeId: DhtAddress): Promise<boolean> {
|
|
164
164
|
const neighbor = this.createRpcRemote(target)
|
|
165
165
|
const targetNodeId = getNodeIdFromPeerDescriptor(neighbor.getPeerDescriptor())
|
|
166
|
-
this.
|
|
166
|
+
this.options.ongoingHandshakes.add(targetNodeId)
|
|
167
167
|
const result = await neighbor.handshake(
|
|
168
|
-
this.
|
|
169
|
-
this.
|
|
168
|
+
this.options.streamPartId,
|
|
169
|
+
this.options.neighbors.getIds(),
|
|
170
170
|
undefined,
|
|
171
|
-
|
|
171
|
+
remoteNodeId
|
|
172
172
|
)
|
|
173
173
|
if (result.accepted) {
|
|
174
|
-
this.
|
|
174
|
+
this.options.neighbors.add(this.createContentDeliveryRpcRemote(neighbor.getPeerDescriptor()))
|
|
175
175
|
}
|
|
176
|
-
this.
|
|
176
|
+
this.options.ongoingHandshakes.delete(targetNodeId)
|
|
177
177
|
return result.accepted
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
private createRpcRemote(targetPeerDescriptor: PeerDescriptor): HandshakeRpcRemote {
|
|
181
181
|
return new HandshakeRpcRemote(
|
|
182
|
-
this.
|
|
182
|
+
this.options.localPeerDescriptor,
|
|
183
183
|
targetPeerDescriptor,
|
|
184
|
-
this.
|
|
184
|
+
this.options.rpcCommunicator,
|
|
185
185
|
HandshakeRpcClient,
|
|
186
|
-
this.
|
|
186
|
+
this.options.rpcRequestTimeout
|
|
187
187
|
)
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
private createContentDeliveryRpcRemote(targetPeerDescriptor: PeerDescriptor): ContentDeliveryRpcRemote {
|
|
191
191
|
return new ContentDeliveryRpcRemote(
|
|
192
|
-
this.
|
|
192
|
+
this.options.localPeerDescriptor,
|
|
193
193
|
targetPeerDescriptor,
|
|
194
|
-
this.
|
|
194
|
+
this.options.rpcCommunicator,
|
|
195
195
|
ContentDeliveryRpcClient,
|
|
196
|
-
this.
|
|
196
|
+
this.options.rpcRequestTimeout
|
|
197
197
|
)
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
getOngoingHandshakes(): Set<DhtAddress> {
|
|
201
|
-
return this.
|
|
201
|
+
return this.options.ongoingHandshakes
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
}
|
|
@@ -2,7 +2,7 @@ import { setAbortableTimeout } from '@streamr/utils'
|
|
|
2
2
|
import { NodeList } from '../NodeList'
|
|
3
3
|
import { DhtAddress } from '@streamr/dht'
|
|
4
4
|
|
|
5
|
-
interface
|
|
5
|
+
interface FindNeighborsSessionOptions {
|
|
6
6
|
neighbors: NodeList
|
|
7
7
|
nearbyNodeView: NodeList
|
|
8
8
|
leftNodeView: NodeList
|
|
@@ -17,11 +17,11 @@ const INTERVAL = 250
|
|
|
17
17
|
|
|
18
18
|
export class NeighborFinder {
|
|
19
19
|
private readonly abortController: AbortController
|
|
20
|
-
private readonly
|
|
20
|
+
private readonly options: FindNeighborsSessionOptions
|
|
21
21
|
private running = false
|
|
22
22
|
|
|
23
|
-
constructor(
|
|
24
|
-
this.
|
|
23
|
+
constructor(options: FindNeighborsSessionOptions) {
|
|
24
|
+
this.options = options
|
|
25
25
|
this.abortController = new AbortController()
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -29,14 +29,14 @@ export class NeighborFinder {
|
|
|
29
29
|
if (!this.running) {
|
|
30
30
|
return
|
|
31
31
|
}
|
|
32
|
-
const newExcludes = await this.
|
|
32
|
+
const newExcludes = await this.options.doFindNeighbors(excluded)
|
|
33
33
|
const uniqueContactCount = new Set([
|
|
34
|
-
...this.
|
|
35
|
-
...this.
|
|
36
|
-
...this.
|
|
37
|
-
...this.
|
|
34
|
+
...this.options.nearbyNodeView.getIds(),
|
|
35
|
+
...this.options.leftNodeView.getIds(),
|
|
36
|
+
...this.options.rightNodeView.getIds(),
|
|
37
|
+
...this.options.randomNodeView.getIds()
|
|
38
38
|
]).size
|
|
39
|
-
if (this.
|
|
39
|
+
if (this.options.neighbors.size() < this.options.minCount && newExcludes.length < uniqueContactCount) {
|
|
40
40
|
// TODO should we catch possible promise rejection?
|
|
41
41
|
setAbortableTimeout(() => this.findNeighbors(newExcludes), INTERVAL, this.abortController.signal)
|
|
42
42
|
} else {
|