@streamr/trackerless-network 100.0.0-testnet-one.4 → 100.0.0-testnet-two.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 +7 -7
- package/dist/src/NetworkStack.d.ts +1 -5
- package/dist/src/NetworkStack.js +1 -3
- package/dist/src/NetworkStack.js.map +1 -1
- package/dist/src/logic/DeliveryRpcLocal.d.ts +1 -1
- package/dist/src/logic/DeliveryRpcLocal.js +3 -3
- package/dist/src/logic/DeliveryRpcLocal.js.map +1 -1
- package/dist/src/logic/DeliveryRpcRemote.d.ts +3 -3
- package/dist/src/logic/DeliveryRpcRemote.js +3 -2
- package/dist/src/logic/DeliveryRpcRemote.js.map +1 -1
- package/dist/src/logic/EntryPointDiscovery.d.ts +3 -0
- package/dist/src/logic/EntryPointDiscovery.js +11 -5
- package/dist/src/logic/EntryPointDiscovery.js.map +1 -1
- package/dist/src/logic/RandomGraphNode.d.ts +10 -8
- package/dist/src/logic/RandomGraphNode.js +23 -17
- package/dist/src/logic/RandomGraphNode.js.map +1 -1
- package/dist/src/logic/StreamrNode.js +13 -4
- package/dist/src/logic/StreamrNode.js.map +1 -1
- package/dist/src/logic/formStreamPartDeliveryServiceId.d.ts +2 -1
- package/dist/src/logic/formStreamPartDeliveryServiceId.js.map +1 -1
- package/dist/src/logic/inspect/Inspector.d.ts +5 -11
- package/dist/src/logic/inspect/Inspector.js +2 -3
- package/dist/src/logic/inspect/Inspector.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.d.ts +3 -3
- package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.js +39 -13
- package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.d.ts +5 -3
- package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.js +18 -8
- package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/Handshaker.d.ts +1 -6
- package/dist/src/logic/neighbor-discovery/Handshaker.js +6 -6
- package/dist/src/logic/neighbor-discovery/Handshaker.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborFinder.d.ts +1 -6
- package/dist/src/logic/neighbor-discovery/NeighborFinder.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.d.ts +3 -8
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js +1 -3
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.d.ts +2 -2
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.js +1 -2
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcRemote.d.ts +2 -2
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcRemote.js.map +1 -1
- package/dist/src/logic/proxy/ProxyClient.d.ts +4 -1
- package/dist/src/logic/proxy/ProxyClient.js +7 -6
- package/dist/src/logic/proxy/ProxyClient.js.map +1 -1
- package/dist/src/logic/proxy/ProxyConnectionRpcLocal.js +2 -3
- package/dist/src/logic/proxy/ProxyConnectionRpcLocal.js.map +1 -1
- package/dist/src/logic/proxy/ProxyConnectionRpcRemote.d.ts +2 -2
- package/dist/src/logic/proxy/ProxyConnectionRpcRemote.js.map +1 -1
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.js +2 -2
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.js.map +1 -1
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcRemote.d.ts +2 -2
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcRemote.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +21 -22
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +18 -18
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +49 -65
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +43 -58
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +11 -12
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.d.ts +6 -5
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.js +2 -2
- 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 +26 -10
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js +21 -9
- 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 +4 -3
- package/dist/test/benchmark/first-message.js +4 -6
- package/dist/test/benchmark/first-message.js.map +1 -1
- package/dist/test/utils/utils.d.ts +1 -1
- package/dist/test/utils/utils.js +8 -7
- package/dist/test/utils/utils.js.map +1 -1
- package/package.json +7 -7
- package/protos/NetworkRpc.proto +8 -4
- package/src/NetworkStack.ts +1 -7
- package/src/logic/DeliveryRpcLocal.ts +4 -4
- package/src/logic/DeliveryRpcRemote.ts +5 -4
- package/src/logic/EntryPointDiscovery.ts +10 -6
- package/src/logic/RandomGraphNode.ts +38 -25
- package/src/logic/StreamrNode.ts +22 -5
- package/src/logic/formStreamPartDeliveryServiceId.ts +2 -1
- package/src/logic/inspect/Inspector.ts +15 -16
- package/src/logic/neighbor-discovery/HandshakeRpcLocal.ts +46 -15
- package/src/logic/neighbor-discovery/HandshakeRpcRemote.ts +21 -10
- package/src/logic/neighbor-discovery/Handshaker.ts +15 -24
- package/src/logic/neighbor-discovery/NeighborFinder.ts +1 -7
- package/src/logic/neighbor-discovery/NeighborUpdateManager.ts +10 -12
- package/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.ts +4 -4
- package/src/logic/neighbor-discovery/NeighborUpdateRpcRemote.ts +2 -2
- package/src/logic/proxy/ProxyClient.ts +19 -7
- package/src/logic/proxy/ProxyConnectionRpcLocal.ts +3 -3
- package/src/logic/proxy/ProxyConnectionRpcRemote.ts +3 -3
- package/src/logic/temporary-connection/TemporaryConnectionRpcLocal.ts +3 -2
- package/src/logic/temporary-connection/TemporaryConnectionRpcRemote.ts +2 -2
- package/src/proto/packages/dht/protos/DhtRpc.client.ts +31 -32
- package/src/proto/packages/dht/protos/DhtRpc.server.ts +11 -12
- package/src/proto/packages/dht/protos/DhtRpc.ts +67 -90
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.client.ts +7 -6
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.server.ts +4 -3
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.ts +36 -15
- package/test/benchmark/first-message.ts +8 -6
- package/test/end-to-end/random-graph-with-real-connections.test.ts +10 -5
- package/test/end-to-end/webrtc-full-node-network.test.ts +1 -1
- package/test/end-to-end/websocket-full-node-network.test.ts +2 -2
- package/test/integration/DeliveryRpcRemote.test.ts +3 -3
- package/test/integration/HandshakeRpcRemote.test.ts +2 -4
- package/test/integration/Handshakes.test.ts +8 -7
- package/test/integration/Inspect.test.ts +0 -2
- package/test/integration/NeighborUpdateRpcRemote.test.ts +2 -2
- package/test/integration/NetworkNode.test.ts +0 -2
- package/test/integration/NetworkRpc.test.ts +0 -3
- package/test/integration/RandomGraphNode-Layer1Node-Latencies.test.ts +4 -4
- package/test/integration/RandomGraphNode-Layer1Node.test.ts +4 -5
- package/test/integration/stream-without-default-entrypoints.test.ts +4 -7
- package/test/integration/streamEntryPointReplacing.test.ts +94 -0
- package/test/unit/DeliveryRpcLocal.test.ts +2 -1
- package/test/unit/EntrypointDiscovery.test.ts +5 -2
- package/test/unit/HandshakeRpcLocal.test.ts +47 -9
- package/test/unit/NodeList.test.ts +10 -12
- package/test/unit/ProxyConnectionRpcRemote.test.ts +18 -10
- package/test/unit/RandomGraphNode.test.ts +6 -4
- package/test/utils/mock/MockHandshaker.ts +3 -2
- package/test/utils/mock/MockNeighborFinder.ts +3 -2
- package/test/utils/mock/MockNeighborUpdateManager.ts +3 -2
- package/test/utils/utils.ts +16 -8
|
@@ -51,7 +51,7 @@ const exponentialRunOff = async (
|
|
|
51
51
|
|
|
52
52
|
const logger = new Logger(module)
|
|
53
53
|
|
|
54
|
-
const ENTRYPOINT_STORE_LIMIT = 8
|
|
54
|
+
export const ENTRYPOINT_STORE_LIMIT = 8
|
|
55
55
|
export const NETWORK_SPLIT_AVOIDANCE_LIMIT = 4
|
|
56
56
|
|
|
57
57
|
interface EntryPointDiscoveryConfig {
|
|
@@ -69,16 +69,14 @@ export class EntryPointDiscovery {
|
|
|
69
69
|
private readonly config: EntryPointDiscoveryConfig
|
|
70
70
|
private readonly storeInterval: number
|
|
71
71
|
private readonly networkSplitAvoidedNodes: Set<NodeID> = new Set()
|
|
72
|
-
|
|
72
|
+
private isLocalNodeStoredAsEntryPoint = false
|
|
73
73
|
constructor(config: EntryPointDiscoveryConfig) {
|
|
74
74
|
this.config = config
|
|
75
75
|
this.abortController = new AbortController()
|
|
76
76
|
this.storeInterval = this.config.storeInterval ?? 60000
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
async discoverEntryPointsFromDht(
|
|
80
|
-
knownEntryPointCount: number
|
|
81
|
-
): Promise<FindEntryPointsResult> {
|
|
79
|
+
async discoverEntryPointsFromDht(knownEntryPointCount: number): Promise<FindEntryPointsResult> {
|
|
82
80
|
if (knownEntryPointCount > 0) {
|
|
83
81
|
return {
|
|
84
82
|
entryPointsFromDht: false,
|
|
@@ -124,6 +122,7 @@ export class EntryPointDiscovery {
|
|
|
124
122
|
}
|
|
125
123
|
const possibleNetworkSplitDetected = this.config.layer1Node.getNumberOfNeighbors() < NETWORK_SPLIT_AVOIDANCE_LIMIT
|
|
126
124
|
if ((currentEntrypointCount < ENTRYPOINT_STORE_LIMIT) || possibleNetworkSplitDetected) {
|
|
125
|
+
this.isLocalNodeStoredAsEntryPoint = true
|
|
127
126
|
await this.storeSelfAsEntryPoint()
|
|
128
127
|
await this.keepSelfAsEntryPoint()
|
|
129
128
|
}
|
|
@@ -165,7 +164,8 @@ export class EntryPointDiscovery {
|
|
|
165
164
|
if (this.config.layer1Node.getNumberOfNeighbors() < NETWORK_SPLIT_AVOIDANCE_LIMIT) {
|
|
166
165
|
// Filter out nodes that are not neighbors as those nodes are assumed to be offline
|
|
167
166
|
const nodesToAvoid = rediscoveredEntrypoints
|
|
168
|
-
.filter((peer) => !this.config.layer1Node.getAllNeighborPeerDescriptors()
|
|
167
|
+
.filter((peer) => !this.config.layer1Node.getAllNeighborPeerDescriptors()
|
|
168
|
+
.some((neighbor) => areEqualPeerDescriptors(neighbor, peer)))
|
|
169
169
|
.map((peer) => getNodeIdFromPeerDescriptor(peer))
|
|
170
170
|
nodesToAvoid.forEach((node) => this.networkSplitAvoidedNodes.add(node))
|
|
171
171
|
throw new Error(`Network split is still possible`)
|
|
@@ -175,6 +175,10 @@ export class EntryPointDiscovery {
|
|
|
175
175
|
logger.trace(`Network split avoided`)
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
public isLocalNodeEntryPoint(): boolean {
|
|
179
|
+
return this.isLocalNodeStoredAsEntryPoint
|
|
180
|
+
}
|
|
181
|
+
|
|
178
182
|
async destroy(): Promise<void> {
|
|
179
183
|
this.abortController.abort()
|
|
180
184
|
await this.config.deleteEntryPointData(streamPartIdToDataKey(this.config.streamPartId))
|
|
@@ -19,23 +19,24 @@ import { DeliveryRpcRemote } from './DeliveryRpcRemote'
|
|
|
19
19
|
import { IDeliveryRpc } from '../proto/packages/trackerless-network/protos/NetworkRpc.server'
|
|
20
20
|
import { DuplicateMessageDetector } from './DuplicateMessageDetector'
|
|
21
21
|
import { Logger, addManagedEventListener } from '@streamr/utils'
|
|
22
|
-
import {
|
|
23
|
-
import { IHandshaker } from './neighbor-discovery/Handshaker'
|
|
22
|
+
import { Handshaker } from './neighbor-discovery/Handshaker'
|
|
24
23
|
import { Propagation } from './propagation/Propagation'
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
24
|
+
import { NeighborFinder } from './neighbor-discovery/NeighborFinder'
|
|
25
|
+
import { NeighborUpdateManager } from './neighbor-discovery/NeighborUpdateManager'
|
|
27
26
|
import { DeliveryRpcLocal } from './DeliveryRpcLocal'
|
|
28
27
|
import { ProxyConnectionRpcLocal } from './proxy/ProxyConnectionRpcLocal'
|
|
29
|
-
import {
|
|
28
|
+
import { Inspector } from './inspect/Inspector'
|
|
30
29
|
import { TemporaryConnectionRpcLocal } from './temporary-connection/TemporaryConnectionRpcLocal'
|
|
31
30
|
import { markAndCheckDuplicate } from './utils'
|
|
32
31
|
import { NodeID, getNodeIdFromPeerDescriptor } from '../identifiers'
|
|
33
32
|
import { Layer1Node } from './Layer1Node'
|
|
34
33
|
import { StreamPartID } from '@streamr/protocol'
|
|
34
|
+
import { uniqBy } from 'lodash'
|
|
35
35
|
|
|
36
36
|
export interface Events {
|
|
37
37
|
message: (message: StreamMessage) => void
|
|
38
38
|
targetNeighborConnected: (nodeId: NodeID) => void
|
|
39
|
+
entryPointLeaveDetected: () => void
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
export interface StrictRandomGraphNodeConfig {
|
|
@@ -48,14 +49,16 @@ export interface StrictRandomGraphNodeConfig {
|
|
|
48
49
|
nearbyNodeView: NodeList
|
|
49
50
|
randomNodeView: NodeList
|
|
50
51
|
targetNeighbors: NodeList
|
|
51
|
-
handshaker:
|
|
52
|
-
neighborFinder:
|
|
53
|
-
neighborUpdateManager:
|
|
52
|
+
handshaker: Handshaker
|
|
53
|
+
neighborFinder: NeighborFinder
|
|
54
|
+
neighborUpdateManager: NeighborUpdateManager
|
|
54
55
|
propagation: Propagation
|
|
55
56
|
rpcCommunicator: ListeningRpcCommunicator
|
|
56
57
|
numOfTargetNeighbors: number
|
|
57
|
-
inspector:
|
|
58
|
+
inspector: Inspector
|
|
58
59
|
temporaryConnectionRpcLocal: TemporaryConnectionRpcLocal
|
|
60
|
+
isLocalNodeEntryPoint: () => boolean
|
|
61
|
+
|
|
59
62
|
proxyConnectionRpcLocal?: ProxyConnectionRpcLocal
|
|
60
63
|
rpcRequestTimeout?: number
|
|
61
64
|
}
|
|
@@ -80,19 +83,25 @@ export class RandomGraphNode extends EventEmitter<Events> {
|
|
|
80
83
|
rpcCommunicator: this.config.rpcCommunicator,
|
|
81
84
|
markAndCheckDuplicate: (msg: MessageID, prev?: MessageRef) => markAndCheckDuplicate(this.duplicateDetectors, msg, prev),
|
|
82
85
|
broadcast: (message: StreamMessage, previousNode?: NodeID) => this.broadcast(message, previousNode),
|
|
83
|
-
onLeaveNotice: (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
onLeaveNotice: (sourceId: NodeID, sourceIsStreamEntryPoint: boolean) => {
|
|
87
|
+
if (this.abortController.signal.aborted) {
|
|
88
|
+
return
|
|
89
|
+
}
|
|
90
|
+
const contact = this.config.nearbyNodeView.get(sourceId)
|
|
91
|
+
|| this.config.randomNodeView.get(sourceId)
|
|
92
|
+
|| this.config.targetNeighbors.get(sourceId)
|
|
93
|
+
|| this.config.proxyConnectionRpcLocal?.getConnection(sourceId )?.remote
|
|
88
94
|
// TODO: check integrity of notifier?
|
|
89
95
|
if (contact) {
|
|
90
96
|
this.config.layer1Node.removeContact(contact.getPeerDescriptor())
|
|
91
97
|
this.config.targetNeighbors.remove(contact.getPeerDescriptor())
|
|
92
98
|
this.config.nearbyNodeView.remove(contact.getPeerDescriptor())
|
|
93
99
|
this.config.connectionLocker.unlockConnection(contact.getPeerDescriptor(), this.config.streamPartId)
|
|
94
|
-
this.config.neighborFinder.start([
|
|
95
|
-
this.config.proxyConnectionRpcLocal?.removeConnection(
|
|
100
|
+
this.config.neighborFinder.start([sourceId])
|
|
101
|
+
this.config.proxyConnectionRpcLocal?.removeConnection(sourceId)
|
|
102
|
+
}
|
|
103
|
+
if (sourceIsStreamEntryPoint) {
|
|
104
|
+
this.emit('entryPointLeaveDetected')
|
|
96
105
|
}
|
|
97
106
|
},
|
|
98
107
|
markForInspection: (senderId: NodeID, messageId: MessageID) => this.config.inspector.markMessage(senderId, messageId)
|
|
@@ -191,7 +200,8 @@ export class RandomGraphNode extends EventEmitter<Events> {
|
|
|
191
200
|
this.config.localPeerDescriptor,
|
|
192
201
|
descriptor,
|
|
193
202
|
this.config.streamPartId,
|
|
194
|
-
|
|
203
|
+
this.config.rpcCommunicator,
|
|
204
|
+
DeliveryRpcClient,
|
|
195
205
|
this.config.rpcRequestTimeout
|
|
196
206
|
)
|
|
197
207
|
))
|
|
@@ -204,7 +214,8 @@ export class RandomGraphNode extends EventEmitter<Events> {
|
|
|
204
214
|
this.config.localPeerDescriptor,
|
|
205
215
|
descriptor,
|
|
206
216
|
this.config.streamPartId,
|
|
207
|
-
|
|
217
|
+
this.config.rpcCommunicator,
|
|
218
|
+
DeliveryRpcClient,
|
|
208
219
|
this.config.rpcRequestTimeout
|
|
209
220
|
|
|
210
221
|
)
|
|
@@ -221,7 +232,8 @@ export class RandomGraphNode extends EventEmitter<Events> {
|
|
|
221
232
|
this.config.localPeerDescriptor,
|
|
222
233
|
descriptor,
|
|
223
234
|
this.config.streamPartId,
|
|
224
|
-
|
|
235
|
+
this.config.rpcCommunicator,
|
|
236
|
+
DeliveryRpcClient,
|
|
225
237
|
this.config.rpcRequestTimeout
|
|
226
238
|
)
|
|
227
239
|
))
|
|
@@ -240,7 +252,8 @@ export class RandomGraphNode extends EventEmitter<Events> {
|
|
|
240
252
|
this.config.localPeerDescriptor,
|
|
241
253
|
descriptor,
|
|
242
254
|
this.config.streamPartId,
|
|
243
|
-
|
|
255
|
+
this.config.rpcCommunicator,
|
|
256
|
+
DeliveryRpcClient,
|
|
244
257
|
this.config.rpcRequestTimeout
|
|
245
258
|
)
|
|
246
259
|
))
|
|
@@ -256,14 +269,14 @@ export class RandomGraphNode extends EventEmitter<Events> {
|
|
|
256
269
|
}
|
|
257
270
|
|
|
258
271
|
private getNeighborCandidatesFromLayer1(): PeerDescriptor[] {
|
|
259
|
-
const
|
|
272
|
+
const nodes: PeerDescriptor[] = []
|
|
260
273
|
this.config.layer1Node.getClosestContacts(this.config.nodeViewSize).forEach((peer: PeerDescriptor) => {
|
|
261
|
-
|
|
274
|
+
nodes.push(peer)
|
|
262
275
|
})
|
|
263
276
|
this.config.layer1Node.getAllNeighborPeerDescriptors().forEach((peer: PeerDescriptor) => {
|
|
264
|
-
|
|
277
|
+
nodes.push(peer)
|
|
265
278
|
})
|
|
266
|
-
return
|
|
279
|
+
return uniqBy(nodes, (p) => getNodeIdFromPeerDescriptor(p))
|
|
267
280
|
}
|
|
268
281
|
|
|
269
282
|
hasProxyConnection(nodeId: NodeID): boolean {
|
|
@@ -279,7 +292,7 @@ export class RandomGraphNode extends EventEmitter<Events> {
|
|
|
279
292
|
}
|
|
280
293
|
this.abortController.abort()
|
|
281
294
|
this.config.proxyConnectionRpcLocal?.stop()
|
|
282
|
-
this.config.targetNeighbors.getAll().map((remote) => remote.leaveStreamPartNotice())
|
|
295
|
+
this.config.targetNeighbors.getAll().map((remote) => remote.leaveStreamPartNotice(this.config.isLocalNodeEntryPoint()))
|
|
283
296
|
this.config.rpcCommunicator.destroy()
|
|
284
297
|
this.removeAllListeners()
|
|
285
298
|
this.config.nearbyNodeView.stop()
|
package/src/logic/StreamrNode.ts
CHANGED
|
@@ -130,7 +130,6 @@ export class StreamrNode extends EventEmitter<Events> {
|
|
|
130
130
|
return
|
|
131
131
|
}
|
|
132
132
|
const layer1Node = this.createLayer1Node(streamPartId, this.knownStreamPartEntryPoints.get(streamPartId) ?? [])
|
|
133
|
-
const node = this.createRandomGraphNode(streamPartId, layer1Node)
|
|
134
133
|
const entryPointDiscovery = new EntryPointDiscovery({
|
|
135
134
|
streamPartId,
|
|
136
135
|
localPeerDescriptor: this.getPeerDescriptor(),
|
|
@@ -139,6 +138,11 @@ export class StreamrNode extends EventEmitter<Events> {
|
|
|
139
138
|
storeEntryPointData: (key, data) => this.layer0Node!.storeDataToDht(key, data),
|
|
140
139
|
deleteEntryPointData: async (key: Uint8Array) => this.layer0Node!.deleteDataFromDht(key, false)
|
|
141
140
|
})
|
|
141
|
+
const node = this.createRandomGraphNode(
|
|
142
|
+
streamPartId,
|
|
143
|
+
layer1Node,
|
|
144
|
+
() => entryPointDiscovery.isLocalNodeEntryPoint()
|
|
145
|
+
)
|
|
142
146
|
streamPart = {
|
|
143
147
|
proxied: false,
|
|
144
148
|
layer1Node,
|
|
@@ -155,6 +159,14 @@ export class StreamrNode extends EventEmitter<Events> {
|
|
|
155
159
|
node.on('message', (message: StreamMessage) => {
|
|
156
160
|
this.emit('newMessage', message)
|
|
157
161
|
})
|
|
162
|
+
const handleEntryPointLeave = async () => {
|
|
163
|
+
if (this.destroyed || entryPointDiscovery.isLocalNodeEntryPoint() || this.knownStreamPartEntryPoints.has(streamPartId)) {
|
|
164
|
+
return
|
|
165
|
+
}
|
|
166
|
+
const entryPoints = await entryPointDiscovery.discoverEntryPointsFromDht(0)
|
|
167
|
+
await entryPointDiscovery.storeSelfAsEntryPointIfNecessary(entryPoints.discoveredEntryPoints.length)
|
|
168
|
+
}
|
|
169
|
+
node.on('entryPointLeaveDetected', () => handleEntryPointLeave())
|
|
158
170
|
setImmediate(async () => {
|
|
159
171
|
try {
|
|
160
172
|
await this.startLayersAndJoinDht(streamPartId, entryPointDiscovery)
|
|
@@ -190,13 +202,17 @@ export class StreamrNode extends EventEmitter<Events> {
|
|
|
190
202
|
serviceId: 'layer1::' + streamPartId,
|
|
191
203
|
peerDescriptor: this.layer0Node!.getLocalPeerDescriptor(),
|
|
192
204
|
entryPoints,
|
|
193
|
-
numberOfNodesPerKBucket: 4,
|
|
205
|
+
numberOfNodesPerKBucket: 4, // TODO use config option or named constant?
|
|
194
206
|
rpcRequestTimeout: EXISTING_CONNECTION_TIMEOUT,
|
|
195
|
-
dhtJoinTimeout: 20000
|
|
207
|
+
dhtJoinTimeout: 20000 // TODO use config option or named constant?
|
|
196
208
|
})
|
|
197
209
|
}
|
|
198
210
|
|
|
199
|
-
private createRandomGraphNode(
|
|
211
|
+
private createRandomGraphNode(
|
|
212
|
+
streamPartId: StreamPartID,
|
|
213
|
+
layer1Node: Layer1Node,
|
|
214
|
+
isLocalNodeEntryPoint: () => boolean
|
|
215
|
+
) {
|
|
200
216
|
return createRandomGraphNode({
|
|
201
217
|
streamPartId,
|
|
202
218
|
transport: this.transport!,
|
|
@@ -206,7 +222,8 @@ export class StreamrNode extends EventEmitter<Events> {
|
|
|
206
222
|
minPropagationTargets: this.config.streamPartitionMinPropagationTargets,
|
|
207
223
|
numOfTargetNeighbors: this.config.streamPartitionNumOfNeighbors,
|
|
208
224
|
acceptProxyConnections: this.config.acceptProxyConnections,
|
|
209
|
-
rpcRequestTimeout: this.config.rpcRequestTimeout
|
|
225
|
+
rpcRequestTimeout: this.config.rpcRequestTimeout,
|
|
226
|
+
isLocalNodeEntryPoint
|
|
210
227
|
})
|
|
211
228
|
}
|
|
212
229
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { ServiceID } from '@streamr/dht'
|
|
1
2
|
import { StreamPartID } from '@streamr/protocol'
|
|
2
3
|
|
|
3
|
-
export const formStreamPartDeliveryServiceId = (streamPartId: StreamPartID):
|
|
4
|
+
export const formStreamPartDeliveryServiceId = (streamPartId: StreamPartID): ServiceID => {
|
|
4
5
|
return `stream-part-delivery-${streamPartId}`
|
|
5
6
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { PeerDescriptor, ConnectionLocker } from '@streamr/dht'
|
|
1
|
+
import { PeerDescriptor, ConnectionLocker, LockID } from '@streamr/dht'
|
|
2
2
|
import { MessageID } from '../../proto/packages/trackerless-network/protos/NetworkRpc'
|
|
3
3
|
import { InspectSession, Events as InspectSessionEvents } from './InspectSession'
|
|
4
4
|
import { TemporaryConnectionRpcClient } from '../../proto/packages/trackerless-network/protos/NetworkRpc.client'
|
|
5
|
-
import {
|
|
5
|
+
import { RpcCommunicator } from '@streamr/proto-rpc'
|
|
6
6
|
import { Logger, waitForEvent3 } from '@streamr/utils'
|
|
7
7
|
import { TemporaryConnectionRpcRemote } from '../temporary-connection/TemporaryConnectionRpcRemote'
|
|
8
8
|
import { NodeID, getNodeIdFromPeerDescriptor } from '../../identifiers'
|
|
@@ -14,40 +14,39 @@ interface InspectorConfig {
|
|
|
14
14
|
rpcCommunicator: RpcCommunicator
|
|
15
15
|
connectionLocker: ConnectionLocker
|
|
16
16
|
inspectionTimeout?: number
|
|
17
|
-
openInspectConnection?: (peerDescriptor: PeerDescriptor, lockId:
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface IInspector {
|
|
21
|
-
inspect(peerDescriptor: PeerDescriptor): Promise<boolean>
|
|
22
|
-
markMessage(sender: NodeID, messageId: MessageID): void
|
|
23
|
-
isInspected(nodeId: NodeID): boolean
|
|
24
|
-
stop(): void
|
|
17
|
+
openInspectConnection?: (peerDescriptor: PeerDescriptor, lockId: LockID) => Promise<void>
|
|
25
18
|
}
|
|
26
19
|
|
|
27
20
|
const logger = new Logger(module)
|
|
28
21
|
const DEFAULT_TIMEOUT = 60 * 1000
|
|
29
22
|
|
|
30
|
-
export class Inspector
|
|
23
|
+
export class Inspector {
|
|
31
24
|
|
|
32
25
|
private readonly sessions: Map<NodeID, InspectSession> = new Map()
|
|
33
26
|
private readonly streamPartId: StreamPartID
|
|
34
|
-
private readonly client: ProtoRpcClient<TemporaryConnectionRpcClient>
|
|
35
27
|
private readonly localPeerDescriptor: PeerDescriptor
|
|
28
|
+
private readonly rpcCommunicator: RpcCommunicator
|
|
36
29
|
private readonly connectionLocker: ConnectionLocker
|
|
37
30
|
private readonly inspectionTimeout: number
|
|
38
|
-
private readonly openInspectConnection: (peerDescriptor: PeerDescriptor, lockId:
|
|
31
|
+
private readonly openInspectConnection: (peerDescriptor: PeerDescriptor, lockId: LockID) => Promise<void>
|
|
39
32
|
|
|
40
33
|
constructor(config: InspectorConfig) {
|
|
41
34
|
this.streamPartId = config.streamPartId
|
|
42
35
|
this.localPeerDescriptor = config.localPeerDescriptor
|
|
43
|
-
this.
|
|
36
|
+
this.rpcCommunicator = config.rpcCommunicator
|
|
44
37
|
this.connectionLocker = config.connectionLocker
|
|
45
38
|
this.inspectionTimeout = config.inspectionTimeout ?? DEFAULT_TIMEOUT
|
|
46
39
|
this.openInspectConnection = config.openInspectConnection ?? this.defaultOpenInspectConnection
|
|
47
40
|
}
|
|
48
41
|
|
|
49
|
-
async defaultOpenInspectConnection(peerDescriptor: PeerDescriptor, lockId:
|
|
50
|
-
const rpcRemote = new TemporaryConnectionRpcRemote(
|
|
42
|
+
async defaultOpenInspectConnection(peerDescriptor: PeerDescriptor, lockId: LockID): Promise<void> {
|
|
43
|
+
const rpcRemote = new TemporaryConnectionRpcRemote(
|
|
44
|
+
this.localPeerDescriptor,
|
|
45
|
+
peerDescriptor,
|
|
46
|
+
this.streamPartId,
|
|
47
|
+
this.rpcCommunicator,
|
|
48
|
+
TemporaryConnectionRpcClient
|
|
49
|
+
)
|
|
51
50
|
await rpcRemote.openConnection()
|
|
52
51
|
this.connectionLocker.lockConnection(peerDescriptor, lockId)
|
|
53
52
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
InterleaveRequest,
|
|
3
|
+
InterleaveResponse,
|
|
4
|
+
StreamPartHandshakeRequest,
|
|
5
|
+
StreamPartHandshakeResponse
|
|
6
|
+
} from '../../proto/packages/trackerless-network/protos/NetworkRpc'
|
|
3
7
|
import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
|
|
4
8
|
import { NodeList } from '../NodeList'
|
|
5
9
|
import { ConnectionLocker, DhtCallContext, PeerDescriptor } from '@streamr/dht'
|
|
@@ -7,7 +11,7 @@ import { IHandshakeRpc } from '../../proto/packages/trackerless-network/protos/N
|
|
|
7
11
|
import { HandshakeRpcRemote } from './HandshakeRpcRemote'
|
|
8
12
|
import { DeliveryRpcRemote } from '../DeliveryRpcRemote'
|
|
9
13
|
import { NodeID, getNodeIdFromPeerDescriptor } from '../../identifiers'
|
|
10
|
-
import { binaryToHex } from '@streamr/utils'
|
|
14
|
+
import { Logger, binaryToHex } from '@streamr/utils'
|
|
11
15
|
import { StreamPartID } from '@streamr/protocol'
|
|
12
16
|
|
|
13
17
|
interface HandshakeRpcLocalConfig {
|
|
@@ -15,12 +19,15 @@ interface HandshakeRpcLocalConfig {
|
|
|
15
19
|
targetNeighbors: NodeList
|
|
16
20
|
connectionLocker: ConnectionLocker
|
|
17
21
|
ongoingHandshakes: Set<NodeID>
|
|
22
|
+
ongoingInterleaves: Set<NodeID>
|
|
18
23
|
maxNeighborCount: number
|
|
19
24
|
createRpcRemote: (target: PeerDescriptor) => HandshakeRpcRemote
|
|
20
25
|
createDeliveryRpcRemote: (peerDescriptor: PeerDescriptor) => DeliveryRpcRemote
|
|
21
26
|
handshakeWithInterleaving: (target: PeerDescriptor, senderId: NodeID) => Promise<boolean>
|
|
22
27
|
}
|
|
23
28
|
|
|
29
|
+
const logger = new Logger(module)
|
|
30
|
+
|
|
24
31
|
export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
25
32
|
|
|
26
33
|
private readonly config: HandshakeRpcLocalConfig
|
|
@@ -36,13 +43,17 @@ export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
|
36
43
|
private handleRequest(request: StreamPartHandshakeRequest, context: ServerCallContext): StreamPartHandshakeResponse {
|
|
37
44
|
const senderDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
|
|
38
45
|
const getInterleaveSourceIds = () => (request.interleaveSourceId !== undefined) ? [binaryToHex(request.interleaveSourceId) as NodeID] : []
|
|
39
|
-
if (this.config.
|
|
46
|
+
if (this.config.ongoingInterleaves.has(getNodeIdFromPeerDescriptor(senderDescriptor))) {
|
|
47
|
+
return this.rejectHandshake(request)
|
|
48
|
+
} else if (this.config.targetNeighbors.hasNode(senderDescriptor)
|
|
40
49
|
|| this.config.ongoingHandshakes.has(getNodeIdFromPeerDescriptor(senderDescriptor))
|
|
41
50
|
) {
|
|
42
51
|
return this.acceptHandshake(request, senderDescriptor)
|
|
43
52
|
} else if (this.config.targetNeighbors.size() + this.config.ongoingHandshakes.size < this.config.maxNeighborCount) {
|
|
44
53
|
return this.acceptHandshake(request, senderDescriptor)
|
|
45
|
-
} else if (this.config.targetNeighbors.size(getInterleaveSourceIds()) >= 2) {
|
|
54
|
+
} else if (this.config.targetNeighbors.size(getInterleaveSourceIds()) - this.config.ongoingInterleaves.size >= 2) {
|
|
55
|
+
// Do not accept the handshakes requests if the target neighbor count can potentially drop below 2
|
|
56
|
+
// due to interleaving. This ensures that a stable number of connections is kept during high churn.
|
|
46
57
|
return this.acceptHandshakeWithInterleaving(request, senderDescriptor)
|
|
47
58
|
} else {
|
|
48
59
|
return this.rejectHandshake(request)
|
|
@@ -69,7 +80,9 @@ export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
|
69
80
|
}
|
|
70
81
|
|
|
71
82
|
private acceptHandshakeWithInterleaving(request: StreamPartHandshakeRequest, requester: PeerDescriptor): StreamPartHandshakeResponse {
|
|
72
|
-
const exclude
|
|
83
|
+
const exclude: NodeID[] = []
|
|
84
|
+
request.neighborIds.forEach((id: Uint8Array) => exclude.push(binaryToHex(id) as NodeID))
|
|
85
|
+
this.config.ongoingInterleaves.forEach((id) => exclude.push(id))
|
|
73
86
|
exclude.push(getNodeIdFromPeerDescriptor(requester))
|
|
74
87
|
if (request.interleaveSourceId !== undefined) {
|
|
75
88
|
exclude.push(binaryToHex(request.interleaveSourceId) as NodeID)
|
|
@@ -77,10 +90,25 @@ export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
|
77
90
|
const furthest = this.config.targetNeighbors.getFurthest(exclude)
|
|
78
91
|
const furthestPeerDescriptor = furthest ? furthest.getPeerDescriptor() : undefined
|
|
79
92
|
if (furthest) {
|
|
93
|
+
const nodeId = getNodeIdFromPeerDescriptor(furthest.getPeerDescriptor())
|
|
80
94
|
const remote = this.config.createRpcRemote(furthest.getPeerDescriptor())
|
|
81
|
-
|
|
82
|
-
this
|
|
83
|
-
|
|
95
|
+
this.config.ongoingInterleaves.add(nodeId)
|
|
96
|
+
// Run this with then catch instead of setImmediate to avoid changes in state
|
|
97
|
+
// eslint-disable-next-line promise/catch-or-return
|
|
98
|
+
remote.interleaveRequest(requester).then((response) => {
|
|
99
|
+
// If response is accepted, remove the furthest node from the target neighbors
|
|
100
|
+
// and unlock the connection
|
|
101
|
+
// If response is not accepted, keep the furthest node as a neighbor
|
|
102
|
+
if (response.accepted) {
|
|
103
|
+
this.config.targetNeighbors.remove(furthest.getPeerDescriptor())
|
|
104
|
+
this.config.connectionLocker.unlockConnection(furthestPeerDescriptor!, this.config.streamPartId)
|
|
105
|
+
}
|
|
106
|
+
return
|
|
107
|
+
}).catch(() => {
|
|
108
|
+
// no-op: InterleaveRequest cannot reject
|
|
109
|
+
}).finally(() => {
|
|
110
|
+
this.config.ongoingInterleaves.delete(nodeId)
|
|
111
|
+
})
|
|
84
112
|
}
|
|
85
113
|
this.config.targetNeighbors.add(this.config.createDeliveryRpcRemote(requester))
|
|
86
114
|
this.config.connectionLocker.lockConnection(requester, this.config.streamPartId)
|
|
@@ -91,16 +119,19 @@ export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
|
91
119
|
}
|
|
92
120
|
}
|
|
93
121
|
|
|
94
|
-
async
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
122
|
+
async interleaveRequest(message: InterleaveRequest, context: ServerCallContext): Promise<InterleaveResponse> {
|
|
123
|
+
const senderPeerDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
|
|
124
|
+
const senderId = getNodeIdFromPeerDescriptor(senderPeerDescriptor)
|
|
125
|
+
try {
|
|
126
|
+
await this.config.handshakeWithInterleaving(message.interleaveTargetDescriptor!, senderId)
|
|
98
127
|
if (this.config.targetNeighbors.hasNodeById(senderId)) {
|
|
99
128
|
this.config.connectionLocker.unlockConnection(senderPeerDescriptor, this.config.streamPartId)
|
|
100
129
|
this.config.targetNeighbors.remove(senderPeerDescriptor)
|
|
101
130
|
}
|
|
102
|
-
|
|
131
|
+
return { accepted: true }
|
|
132
|
+
} catch (err) {
|
|
133
|
+
logger.debug(`interleaveRequest to ${getNodeIdFromPeerDescriptor(message.interleaveTargetDescriptor!)} failed: ${err}`)
|
|
134
|
+
return { accepted: false }
|
|
103
135
|
}
|
|
104
|
-
return Empty
|
|
105
136
|
}
|
|
106
137
|
}
|
|
@@ -2,8 +2,8 @@ import { PeerDescriptor, RpcRemote } from '@streamr/dht'
|
|
|
2
2
|
import { Logger, hexToBinary } from '@streamr/utils'
|
|
3
3
|
import { v4 } from 'uuid'
|
|
4
4
|
import { NodeID, getNodeIdFromPeerDescriptor } from '../../identifiers'
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { InterleaveRequest, InterleaveResponse, StreamPartHandshakeRequest } from '../../proto/packages/trackerless-network/protos/NetworkRpc'
|
|
6
|
+
import { HandshakeRpcClient } from '../../proto/packages/trackerless-network/protos/NetworkRpc.client'
|
|
7
7
|
|
|
8
8
|
const logger = new Logger(module)
|
|
9
9
|
|
|
@@ -12,7 +12,9 @@ interface HandshakeResponse {
|
|
|
12
12
|
interleaveTargetDescriptor?: PeerDescriptor
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export
|
|
15
|
+
export const INTERLEAVE_REQUEST_TIMEOUT = 15000
|
|
16
|
+
|
|
17
|
+
export class HandshakeRpcRemote extends RpcRemote<HandshakeRpcClient> {
|
|
16
18
|
|
|
17
19
|
async handshake(
|
|
18
20
|
neighborIds: NodeID[],
|
|
@@ -40,16 +42,25 @@ export class HandshakeRpcRemote extends RpcRemote<IHandshakeRpcClient> {
|
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
streamPartId: this.getServiceId(),
|
|
45
|
+
async interleaveRequest(originatorDescriptor: PeerDescriptor): Promise<InterleaveResponse> {
|
|
46
|
+
const request: InterleaveRequest = {
|
|
46
47
|
interleaveTargetDescriptor: originatorDescriptor
|
|
47
48
|
}
|
|
48
49
|
const options = this.formDhtRpcOptions({
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
this.getClient().interleaveNotice(notification, options).catch(() => {
|
|
52
|
-
logger.debug('Failed to send interleaveNotice')
|
|
50
|
+
connect: false,
|
|
51
|
+
timeout: INTERLEAVE_REQUEST_TIMEOUT
|
|
53
52
|
})
|
|
53
|
+
try {
|
|
54
|
+
const res = await this.getClient().interleaveRequest(request, options)
|
|
55
|
+
return {
|
|
56
|
+
accepted: res.accepted
|
|
57
|
+
}
|
|
58
|
+
} catch (err) {
|
|
59
|
+
logger.debug(`interleaveRequest to ${getNodeIdFromPeerDescriptor(this.getPeerDescriptor())} failed: ${err}`)
|
|
60
|
+
return {
|
|
61
|
+
accepted: false
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
54
65
|
}
|
|
55
66
|
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { ConnectionLocker, PeerDescriptor } from '@streamr/dht'
|
|
2
2
|
import { NodeList } from '../NodeList'
|
|
3
3
|
import { DeliveryRpcRemote } from '../DeliveryRpcRemote'
|
|
4
|
-
import {
|
|
4
|
+
import { RpcCommunicator } from '@streamr/proto-rpc'
|
|
5
5
|
import {
|
|
6
|
-
HandshakeRpcClient
|
|
7
|
-
IHandshakeRpcClient, DeliveryRpcClient
|
|
6
|
+
DeliveryRpcClient, HandshakeRpcClient
|
|
8
7
|
} from '../../proto/packages/trackerless-network/protos/NetworkRpc.client'
|
|
9
8
|
import {
|
|
10
|
-
|
|
9
|
+
InterleaveRequest,
|
|
10
|
+
InterleaveResponse,
|
|
11
11
|
StreamPartHandshakeRequest,
|
|
12
12
|
StreamPartHandshakeResponse
|
|
13
13
|
} from '../../proto/packages/trackerless-network/protos/NetworkRpc'
|
|
14
14
|
import { Logger } from '@streamr/utils'
|
|
15
15
|
import { IHandshakeRpc } from '../../proto/packages/trackerless-network/protos/NetworkRpc.server'
|
|
16
|
-
import { HandshakeRpcRemote } from './HandshakeRpcRemote'
|
|
16
|
+
import { HandshakeRpcRemote, INTERLEAVE_REQUEST_TIMEOUT } from './HandshakeRpcRemote'
|
|
17
17
|
import { HandshakeRpcLocal } from './HandshakeRpcLocal'
|
|
18
18
|
import { NodeID, getNodeIdFromPeerDescriptor } from '../../identifiers'
|
|
19
19
|
import { StreamPartID } from '@streamr/protocol'
|
|
@@ -34,38 +34,33 @@ const logger = new Logger(module)
|
|
|
34
34
|
|
|
35
35
|
const PARALLEL_HANDSHAKE_COUNT = 2
|
|
36
36
|
|
|
37
|
-
export
|
|
38
|
-
attemptHandshakesOnContacts(excludedIds: NodeID[]): Promise<NodeID[]>
|
|
39
|
-
getOngoingHandshakes(): Set<NodeID>
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export class Handshaker implements IHandshaker {
|
|
37
|
+
export class Handshaker {
|
|
43
38
|
|
|
44
39
|
private readonly ongoingHandshakes: Set<NodeID> = new Set()
|
|
45
40
|
private config: HandshakerConfig
|
|
46
|
-
private readonly client: ProtoRpcClient<IHandshakeRpcClient>
|
|
47
41
|
private readonly rpcLocal: IHandshakeRpc
|
|
48
42
|
|
|
49
43
|
constructor(config: HandshakerConfig) {
|
|
50
44
|
this.config = config
|
|
51
|
-
this.client = toProtoRpcClient(new HandshakeRpcClient(this.config.rpcCommunicator.getRpcClientTransport()))
|
|
52
45
|
this.rpcLocal = new HandshakeRpcLocal({
|
|
53
46
|
streamPartId: this.config.streamPartId,
|
|
54
47
|
targetNeighbors: this.config.targetNeighbors,
|
|
55
48
|
connectionLocker: this.config.connectionLocker,
|
|
56
49
|
ongoingHandshakes: this.ongoingHandshakes,
|
|
50
|
+
ongoingInterleaves: new Set(),
|
|
57
51
|
maxNeighborCount: this.config.maxNeighborCount,
|
|
58
52
|
handshakeWithInterleaving: (target: PeerDescriptor, senderId: NodeID) => this.handshakeWithInterleaving(target, senderId),
|
|
59
53
|
createRpcRemote: (target: PeerDescriptor) => this.createRpcRemote(target),
|
|
60
54
|
createDeliveryRpcRemote: (target: PeerDescriptor) => this.createDeliveryRpcRemote(target)
|
|
61
55
|
})
|
|
62
|
-
this.config.rpcCommunicator.
|
|
63
|
-
(req:
|
|
56
|
+
this.config.rpcCommunicator.registerRpcMethod(InterleaveRequest, InterleaveResponse, 'interleaveRequest',
|
|
57
|
+
(req: InterleaveRequest, context) => this.rpcLocal.interleaveRequest(req, context), { timeout: INTERLEAVE_REQUEST_TIMEOUT })
|
|
64
58
|
this.config.rpcCommunicator.registerRpcMethod(StreamPartHandshakeRequest, StreamPartHandshakeResponse, 'handshake',
|
|
65
59
|
(req: StreamPartHandshakeRequest, context) => this.rpcLocal.handshake(req, context))
|
|
66
60
|
}
|
|
67
61
|
|
|
68
62
|
async attemptHandshakesOnContacts(excludedIds: NodeID[]): Promise<NodeID[]> {
|
|
63
|
+
// TODO use config option or named constant? or why the value 2?
|
|
69
64
|
if (this.config.targetNeighbors.size() + this.ongoingHandshakes.size < this.config.maxNeighborCount - 2) {
|
|
70
65
|
logger.trace(`Attempting parallel handshakes with ${PARALLEL_HANDSHAKE_COUNT} targets`)
|
|
71
66
|
return this.selectParallelTargetsAndHandshake(excludedIds)
|
|
@@ -142,13 +137,7 @@ export class Handshaker implements IHandshaker {
|
|
|
142
137
|
}
|
|
143
138
|
|
|
144
139
|
private async handshakeWithInterleaving(target: PeerDescriptor, interleaveSourceId: NodeID): Promise<boolean> {
|
|
145
|
-
const targetNeighbor =
|
|
146
|
-
this.config.localPeerDescriptor,
|
|
147
|
-
target,
|
|
148
|
-
this.config.streamPartId,
|
|
149
|
-
this.client,
|
|
150
|
-
this.config.rpcRequestTimeout
|
|
151
|
-
)
|
|
140
|
+
const targetNeighbor = this.createRpcRemote(target)
|
|
152
141
|
const targetNodeId = getNodeIdFromPeerDescriptor(targetNeighbor.getPeerDescriptor())
|
|
153
142
|
this.ongoingHandshakes.add(targetNodeId)
|
|
154
143
|
const result = await targetNeighbor.handshake(
|
|
@@ -169,7 +158,8 @@ export class Handshaker implements IHandshaker {
|
|
|
169
158
|
this.config.localPeerDescriptor,
|
|
170
159
|
targetPeerDescriptor,
|
|
171
160
|
this.config.streamPartId,
|
|
172
|
-
this.
|
|
161
|
+
this.config.rpcCommunicator,
|
|
162
|
+
HandshakeRpcClient,
|
|
173
163
|
this.config.rpcRequestTimeout
|
|
174
164
|
)
|
|
175
165
|
}
|
|
@@ -179,7 +169,8 @@ export class Handshaker implements IHandshaker {
|
|
|
179
169
|
this.config.localPeerDescriptor,
|
|
180
170
|
targetPeerDescriptor,
|
|
181
171
|
this.config.streamPartId,
|
|
182
|
-
|
|
172
|
+
this.config.rpcCommunicator,
|
|
173
|
+
DeliveryRpcClient,
|
|
183
174
|
this.config.rpcRequestTimeout
|
|
184
175
|
)
|
|
185
176
|
}
|
|
@@ -12,13 +12,7 @@ interface FindNeighborsSessionConfig {
|
|
|
12
12
|
const INITIAL_WAIT = 100
|
|
13
13
|
const INTERVAL = 250
|
|
14
14
|
|
|
15
|
-
export
|
|
16
|
-
start(excluded?: NodeID[]): void
|
|
17
|
-
stop(): void
|
|
18
|
-
isRunning(): boolean
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export class NeighborFinder implements INeighborFinder {
|
|
15
|
+
export class NeighborFinder {
|
|
22
16
|
private readonly abortController: AbortController
|
|
23
17
|
private readonly config: FindNeighborsSessionConfig
|
|
24
18
|
private running = false
|