@streamr/trackerless-network 100.0.0-pretestnet.6 → 100.0.0-rc.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/README.md +57 -0
- package/dist/package.json +12 -12
- package/dist/src/NetworkNode.d.ts +6 -5
- package/dist/src/NetworkNode.js +9 -2
- package/dist/src/NetworkNode.js.map +1 -1
- package/dist/src/NetworkStack.d.ts +13 -9
- package/dist/src/NetworkStack.js +80 -12
- package/dist/src/NetworkStack.js.map +1 -1
- package/dist/src/exports.d.ts +4 -3
- package/dist/src/exports.js +12 -1
- package/dist/src/exports.js.map +1 -1
- package/dist/src/logic/DeliveryRpcLocal.d.ts +4 -5
- package/dist/src/logic/DeliveryRpcLocal.js +6 -5
- package/dist/src/logic/DeliveryRpcLocal.js.map +1 -1
- package/dist/src/logic/DeliveryRpcRemote.d.ts +5 -4
- package/dist/src/logic/DeliveryRpcRemote.js +4 -3
- package/dist/src/logic/DeliveryRpcRemote.js.map +1 -1
- package/dist/src/logic/DuplicateMessageDetector.d.ts +3 -3
- package/dist/src/logic/DuplicateMessageDetector.js +10 -6
- package/dist/src/logic/DuplicateMessageDetector.js.map +1 -1
- package/dist/src/logic/EntryPointDiscovery.d.ts +8 -5
- package/dist/src/logic/EntryPointDiscovery.js +24 -15
- package/dist/src/logic/EntryPointDiscovery.js.map +1 -1
- package/dist/src/logic/Layer0Node.d.ts +6 -4
- package/dist/src/logic/Layer1Node.d.ts +12 -6
- package/dist/src/logic/NodeList.d.ts +13 -15
- package/dist/src/logic/NodeList.js +19 -16
- package/dist/src/logic/NodeList.js.map +1 -1
- package/dist/src/logic/RandomGraphNode.d.ts +26 -22
- package/dist/src/logic/RandomGraphNode.js +85 -52
- package/dist/src/logic/RandomGraphNode.js.map +1 -1
- package/dist/src/logic/StreamrNode.d.ts +6 -6
- package/dist/src/logic/StreamrNode.js +53 -37
- package/dist/src/logic/StreamrNode.js.map +1 -1
- package/dist/src/logic/createRandomGraphNode.d.ts +2 -2
- package/dist/src/logic/createRandomGraphNode.js +33 -21
- package/dist/src/logic/createRandomGraphNode.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/InspectSession.d.ts +4 -3
- package/dist/src/logic/inspect/InspectSession.js +6 -2
- package/dist/src/logic/inspect/InspectSession.js.map +1 -1
- package/dist/src/logic/inspect/Inspector.d.ts +11 -16
- package/dist/src/logic/inspect/Inspector.js +21 -9
- package/dist/src/logic/inspect/Inspector.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.d.ts +7 -9
- package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.js +55 -32
- package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.d.ts +8 -6
- package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.js +25 -16
- package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/Handshaker.d.ts +9 -15
- package/dist/src/logic/neighbor-discovery/Handshaker.js +68 -44
- package/dist/src/logic/neighbor-discovery/Handshaker.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborFinder.d.ts +8 -10
- package/dist/src/logic/neighbor-discovery/NeighborFinder.js +12 -2
- package/dist/src/logic/neighbor-discovery/NeighborFinder.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.d.ts +7 -10
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js +11 -9
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.d.ts +8 -4
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.js +33 -24
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcRemote.d.ts +5 -4
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcRemote.js +4 -5
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcRemote.js.map +1 -1
- package/dist/src/logic/node-info/NodeInfoClient.d.ts +9 -0
- package/dist/src/logic/node-info/NodeInfoClient.js +21 -0
- package/dist/src/logic/node-info/NodeInfoClient.js.map +1 -0
- package/dist/src/logic/node-info/NodeInfoRpcLocal.d.ts +12 -0
- package/dist/src/logic/node-info/NodeInfoRpcLocal.js +22 -0
- package/dist/src/logic/node-info/NodeInfoRpcLocal.js.map +1 -0
- package/dist/src/logic/node-info/NodeInfoRpcRemote.d.ts +6 -0
- package/dist/src/logic/node-info/NodeInfoRpcRemote.js +11 -0
- package/dist/src/logic/node-info/NodeInfoRpcRemote.js.map +1 -0
- package/dist/src/logic/propagation/FifoMapWithTTL.js +7 -3
- package/dist/src/logic/propagation/FifoMapWithTTL.js.map +1 -1
- package/dist/src/logic/propagation/Propagation.d.ts +4 -4
- package/dist/src/logic/propagation/Propagation.js +4 -0
- package/dist/src/logic/propagation/Propagation.js.map +1 -1
- package/dist/src/logic/propagation/PropagationTaskStore.d.ts +2 -2
- package/dist/src/logic/propagation/PropagationTaskStore.js +1 -0
- package/dist/src/logic/propagation/PropagationTaskStore.js.map +1 -1
- package/dist/src/logic/protocol-integration/stream-message/GroupKeyRequestTranslator.js +1 -1
- package/dist/src/logic/protocol-integration/stream-message/GroupKeyRequestTranslator.js.map +1 -1
- package/dist/src/logic/protocol-integration/stream-message/GroupKeyResponseTranslator.js +1 -1
- package/dist/src/logic/protocol-integration/stream-message/GroupKeyResponseTranslator.js.map +1 -1
- package/dist/src/logic/protocol-integration/stream-message/StreamMessageTranslator.js +87 -53
- package/dist/src/logic/protocol-integration/stream-message/StreamMessageTranslator.js.map +1 -1
- package/dist/src/logic/protocol-integration/stream-message/oldStreamMessageBinaryUtils.d.ts +7 -0
- package/dist/src/logic/protocol-integration/stream-message/oldStreamMessageBinaryUtils.js +32 -0
- package/dist/src/logic/protocol-integration/stream-message/oldStreamMessageBinaryUtils.js.map +1 -0
- package/dist/src/logic/proxy/ProxyClient.d.ts +8 -6
- package/dist/src/logic/proxy/ProxyClient.js +40 -28
- package/dist/src/logic/proxy/ProxyClient.js.map +1 -1
- package/dist/src/logic/proxy/ProxyConnectionRpcLocal.d.ts +6 -7
- package/dist/src/logic/proxy/ProxyConnectionRpcLocal.js +8 -8
- package/dist/src/logic/proxy/ProxyConnectionRpcLocal.js.map +1 -1
- package/dist/src/logic/proxy/ProxyConnectionRpcRemote.d.ts +3 -3
- package/dist/src/logic/proxy/ProxyConnectionRpcRemote.js +1 -1
- package/dist/src/logic/proxy/ProxyConnectionRpcRemote.js.map +1 -1
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.d.ts +9 -4
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.js +21 -6
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.js.map +1 -1
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcRemote.d.ts +4 -3
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcRemote.js +13 -3
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcRemote.js.map +1 -1
- package/dist/src/logic/utils.js.map +1 -1
- package/dist/src/proto/google/protobuf/any.js +8 -8
- package/dist/src/proto/google/protobuf/any.js.map +1 -1
- package/dist/src/proto/google/protobuf/empty.js +2 -4
- package/dist/src/proto/google/protobuf/empty.js.map +1 -1
- package/dist/src/proto/google/protobuf/timestamp.js +10 -10
- package/dist/src/proto/google/protobuf/timestamp.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +36 -49
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +54 -52
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +184 -234
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +118 -168
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +20 -29
- package/dist/src/proto/packages/proto-rpc/protos/ProtoRpc.js +1 -1
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.d.ts +42 -5
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.js +52 -19
- 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 +193 -28
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js +129 -20
- 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 +20 -3
- package/dist/test/benchmark/first-message.js +14 -15
- package/dist/test/benchmark/first-message.js.map +1 -1
- package/dist/test/utils/utils.d.ts +2 -4
- package/dist/test/utils/utils.js +20 -19
- package/dist/test/utils/utils.js.map +1 -1
- package/jest.config.js +3 -38
- package/package.json +12 -12
- package/protos/NetworkRpc.proto +57 -12
- package/src/NetworkNode.ts +13 -6
- package/src/NetworkStack.ts +94 -16
- package/src/exports.ts +11 -3
- package/src/logic/DeliveryRpcLocal.ts +7 -8
- package/src/logic/DeliveryRpcRemote.ts +7 -5
- package/src/logic/DuplicateMessageDetector.ts +7 -7
- package/src/logic/EntryPointDiscovery.ts +26 -19
- package/src/logic/Layer0Node.ts +6 -4
- package/src/logic/Layer1Node.ts +21 -6
- package/src/logic/NodeList.ts +26 -27
- package/src/logic/RandomGraphNode.ts +158 -78
- package/src/logic/StreamrNode.ts +58 -41
- package/src/logic/createRandomGraphNode.ts +37 -25
- package/src/logic/formStreamPartDeliveryServiceId.ts +2 -1
- package/src/logic/inspect/InspectSession.ts +8 -4
- package/src/logic/inspect/Inspector.ts +34 -24
- package/src/logic/neighbor-discovery/HandshakeRpcLocal.ts +72 -38
- package/src/logic/neighbor-discovery/HandshakeRpcRemote.ts +32 -20
- package/src/logic/neighbor-discovery/Handshaker.ts +90 -75
- package/src/logic/neighbor-discovery/NeighborFinder.ts +18 -13
- package/src/logic/neighbor-discovery/NeighborUpdateManager.ts +19 -20
- package/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.ts +43 -33
- package/src/logic/neighbor-discovery/NeighborUpdateRpcRemote.ts +6 -6
- package/src/logic/node-info/NodeInfoClient.ts +23 -0
- package/src/logic/node-info/NodeInfoRpcLocal.ts +28 -0
- package/src/logic/node-info/NodeInfoRpcRemote.ts +11 -0
- package/src/logic/propagation/Propagation.ts +7 -6
- package/src/logic/propagation/PropagationTaskStore.ts +2 -2
- package/src/logic/protocol-integration/stream-message/GroupKeyRequestTranslator.ts +1 -1
- package/src/logic/protocol-integration/stream-message/GroupKeyResponseTranslator.ts +1 -2
- package/src/logic/protocol-integration/stream-message/StreamMessageTranslator.ts +95 -69
- package/src/logic/protocol-integration/stream-message/oldStreamMessageBinaryUtils.ts +37 -0
- package/src/logic/proxy/ProxyClient.ts +60 -40
- package/src/logic/proxy/ProxyConnectionRpcLocal.ts +15 -19
- package/src/logic/proxy/ProxyConnectionRpcRemote.ts +3 -3
- package/src/logic/temporary-connection/TemporaryConnectionRpcLocal.ts +30 -10
- package/src/logic/temporary-connection/TemporaryConnectionRpcRemote.ts +14 -4
- package/src/proto/google/protobuf/any.ts +4 -4
- package/src/proto/google/protobuf/empty.ts +2 -4
- package/src/proto/google/protobuf/timestamp.ts +4 -4
- package/src/proto/packages/dht/protos/DhtRpc.client.ts +50 -66
- package/src/proto/packages/dht/protos/DhtRpc.server.ts +21 -30
- package/src/proto/packages/dht/protos/DhtRpc.ts +242 -316
- package/src/proto/packages/proto-rpc/protos/ProtoRpc.ts +1 -1
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.client.ts +49 -7
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.server.ts +21 -4
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.ts +251 -44
- package/test/benchmark/StreamPartIdDataKeyDistribution.test.ts +60 -0
- package/test/benchmark/first-message.ts +38 -17
- package/test/end-to-end/inspect.test.ts +16 -4
- package/test/end-to-end/proxy-and-full-node.test.ts +26 -13
- package/test/end-to-end/proxy-connections.test.ts +23 -11
- package/test/end-to-end/proxy-key-exchange.test.ts +25 -15
- package/test/end-to-end/random-graph-with-real-connections.test.ts +35 -32
- package/test/end-to-end/webrtc-full-node-network.test.ts +11 -12
- package/test/end-to-end/websocket-full-node-network.test.ts +12 -12
- package/test/integration/DeliveryRpcRemote.test.ts +6 -9
- package/test/integration/HandshakeRpcRemote.test.ts +6 -8
- package/test/integration/Handshakes.test.ts +29 -27
- package/test/integration/Inspect.test.ts +0 -2
- package/test/integration/NeighborUpdateRpcRemote.test.ts +6 -7
- package/test/integration/NetworkNode.test.ts +27 -12
- package/test/integration/NetworkRpc.test.ts +3 -5
- package/test/integration/NetworkStack.test.ts +2 -2
- package/test/integration/NodeInfoRpc.test.ts +104 -0
- package/test/integration/Propagation.test.ts +3 -3
- package/test/integration/RandomGraphNode-Layer1Node-Latencies.test.ts +24 -25
- package/test/integration/RandomGraphNode-Layer1Node.test.ts +26 -24
- package/test/integration/StreamrNode.test.ts +4 -16
- package/test/integration/joining-streams-on-offline-peers.test.ts +7 -31
- package/test/integration/stream-without-default-entrypoints.test.ts +22 -23
- package/test/integration/streamEntryPointReplacing.test.ts +94 -0
- package/test/unit/DeliveryRpcLocal.test.ts +2 -1
- package/test/unit/EntrypointDiscovery.test.ts +11 -8
- package/test/unit/GroupKeyResponseTranslator.test.ts +1 -1
- package/test/unit/HandshakeRpcLocal.test.ts +80 -28
- package/test/unit/Handshaker.test.ts +14 -9
- package/test/unit/InspectSession.test.ts +5 -6
- package/test/unit/Inspector.test.ts +3 -4
- package/test/unit/NeighborFinder.test.ts +12 -9
- package/test/unit/NeighborUpdateRpcLocal.test.ts +139 -0
- package/test/unit/NodeList.test.ts +77 -80
- package/test/unit/Propagation.test.ts +21 -16
- package/test/unit/ProxyConnectionRpcRemote.test.ts +18 -12
- package/test/unit/RandomGraphNode.test.ts +23 -20
- package/test/unit/StreamMessageTranslator.test.ts +10 -8
- package/test/unit/StreamPartIDDataKey.test.ts +12 -0
- package/test/unit/StreamrNode.test.ts +2 -0
- package/test/unit/TemporaryConnectionRpcLocal.test.ts +38 -0
- package/test/unit/oldStreamMessageBinaryUtils.test.ts +39 -0
- package/test/utils/mock/MockHandshaker.ts +6 -5
- package/test/utils/mock/MockLayer0Node.ts +7 -2
- package/test/utils/mock/MockLayer1Node.ts +5 -2
- package/test/utils/mock/MockNeighborFinder.ts +3 -2
- package/test/utils/mock/MockNeighborUpdateManager.ts +3 -2
- package/test/utils/mock/Transport.ts +1 -1
- package/test/utils/utils.ts +40 -25
- package/tsconfig.jest.json +5 -4
- package/tsconfig.node.json +2 -2
- package/dist/src/identifiers.d.ts +0 -4
- package/dist/src/identifiers.js +0 -9
- package/dist/src/identifiers.js.map +0 -1
- package/src/identifiers.ts +0 -8
- package/test/unit/GroupKeyRequestTranslator.test.ts +0 -36
|
@@ -1,26 +1,38 @@
|
|
|
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
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
DhtAddress,
|
|
11
|
+
DhtAddressRaw,
|
|
12
|
+
DhtCallContext,
|
|
13
|
+
PeerDescriptor,
|
|
14
|
+
getDhtAddressFromRaw,
|
|
15
|
+
getNodeIdFromPeerDescriptor
|
|
16
|
+
} from '@streamr/dht'
|
|
6
17
|
import { IHandshakeRpc } from '../../proto/packages/trackerless-network/protos/NetworkRpc.server'
|
|
7
18
|
import { HandshakeRpcRemote } from './HandshakeRpcRemote'
|
|
8
19
|
import { DeliveryRpcRemote } from '../DeliveryRpcRemote'
|
|
9
|
-
import {
|
|
10
|
-
import { binaryToHex } from '@streamr/utils'
|
|
20
|
+
import { Logger } from '@streamr/utils'
|
|
11
21
|
import { StreamPartID } from '@streamr/protocol'
|
|
12
22
|
|
|
13
23
|
interface HandshakeRpcLocalConfig {
|
|
14
24
|
streamPartId: StreamPartID
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
neighbors: NodeList
|
|
26
|
+
ongoingHandshakes: Set<DhtAddress>
|
|
27
|
+
ongoingInterleaves: Set<DhtAddress>
|
|
18
28
|
maxNeighborCount: number
|
|
19
29
|
createRpcRemote: (target: PeerDescriptor) => HandshakeRpcRemote
|
|
20
30
|
createDeliveryRpcRemote: (peerDescriptor: PeerDescriptor) => DeliveryRpcRemote
|
|
21
|
-
handshakeWithInterleaving: (target: PeerDescriptor, senderId:
|
|
31
|
+
handshakeWithInterleaving: (target: PeerDescriptor, senderId: DhtAddress) => Promise<boolean>
|
|
22
32
|
}
|
|
23
33
|
|
|
34
|
+
const logger = new Logger(module)
|
|
35
|
+
|
|
24
36
|
export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
25
37
|
|
|
26
38
|
private readonly config: HandshakeRpcLocalConfig
|
|
@@ -35,14 +47,22 @@ export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
|
35
47
|
|
|
36
48
|
private handleRequest(request: StreamPartHandshakeRequest, context: ServerCallContext): StreamPartHandshakeResponse {
|
|
37
49
|
const senderDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
|
|
38
|
-
const getInterleaveSourceIds = () => (request.interleaveSourceId !== undefined) ? [
|
|
39
|
-
|
|
40
|
-
|
|
50
|
+
const getInterleaveSourceIds = () => (request.interleaveSourceId !== undefined) ? [getDhtAddressFromRaw(request.interleaveSourceId)] : []
|
|
51
|
+
const senderNodeId = getNodeIdFromPeerDescriptor(senderDescriptor)
|
|
52
|
+
if (this.config.ongoingInterleaves.has(senderNodeId)) {
|
|
53
|
+
return this.rejectHandshake(request)
|
|
54
|
+
} else if (this.config.neighbors.has(senderNodeId)
|
|
55
|
+
|| this.config.ongoingHandshakes.has(senderNodeId)
|
|
41
56
|
) {
|
|
42
57
|
return this.acceptHandshake(request, senderDescriptor)
|
|
43
|
-
} else if (this.config.
|
|
58
|
+
} else if (this.config.neighbors.size() + this.config.ongoingHandshakes.size < this.config.maxNeighborCount) {
|
|
44
59
|
return this.acceptHandshake(request, senderDescriptor)
|
|
45
|
-
} else if (
|
|
60
|
+
} else if (
|
|
61
|
+
this.config.neighbors.size(getInterleaveSourceIds()) - this.config.ongoingInterleaves.size >= 2
|
|
62
|
+
&& this.config.neighbors.size() <= this.config.maxNeighborCount
|
|
63
|
+
) {
|
|
64
|
+
// Do not accept the handshakes requests if the target neighbor count can potentially drop below 2
|
|
65
|
+
// due to interleaving. This ensures that a stable number of connections is kept during high churn.
|
|
46
66
|
return this.acceptHandshakeWithInterleaving(request, senderDescriptor)
|
|
47
67
|
} else {
|
|
48
68
|
return this.rejectHandshake(request)
|
|
@@ -54,8 +74,7 @@ export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
|
54
74
|
requestId: request.requestId,
|
|
55
75
|
accepted: true
|
|
56
76
|
}
|
|
57
|
-
this.config.
|
|
58
|
-
this.config.connectionLocker.lockConnection(requester, this.config.streamPartId)
|
|
77
|
+
this.config.neighbors.add(this.config.createDeliveryRpcRemote(requester))
|
|
59
78
|
return res
|
|
60
79
|
}
|
|
61
80
|
|
|
@@ -69,38 +88,53 @@ export class HandshakeRpcLocal implements IHandshakeRpc {
|
|
|
69
88
|
}
|
|
70
89
|
|
|
71
90
|
private acceptHandshakeWithInterleaving(request: StreamPartHandshakeRequest, requester: PeerDescriptor): StreamPartHandshakeResponse {
|
|
72
|
-
const exclude
|
|
91
|
+
const exclude: DhtAddress[] = []
|
|
92
|
+
request.neighborIds.forEach((id: DhtAddressRaw) => exclude.push(getDhtAddressFromRaw(id)))
|
|
93
|
+
this.config.ongoingInterleaves.forEach((id) => exclude.push(id))
|
|
73
94
|
exclude.push(getNodeIdFromPeerDescriptor(requester))
|
|
74
95
|
if (request.interleaveSourceId !== undefined) {
|
|
75
|
-
exclude.push(
|
|
96
|
+
exclude.push(getDhtAddressFromRaw(request.interleaveSourceId))
|
|
76
97
|
}
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
if (
|
|
80
|
-
const
|
|
81
|
-
remote.
|
|
82
|
-
this.config.
|
|
83
|
-
this
|
|
98
|
+
const last = this.config.neighbors.getLast(exclude)
|
|
99
|
+
const lastPeerDescriptor = last ? last.getPeerDescriptor() : undefined
|
|
100
|
+
if (last) {
|
|
101
|
+
const nodeId = getNodeIdFromPeerDescriptor(last.getPeerDescriptor())
|
|
102
|
+
const remote = this.config.createRpcRemote(last.getPeerDescriptor())
|
|
103
|
+
this.config.ongoingInterleaves.add(nodeId)
|
|
104
|
+
// Run this with then catch instead of setImmediate to avoid changes in state
|
|
105
|
+
// eslint-disable-next-line promise/catch-or-return
|
|
106
|
+
remote.interleaveRequest(requester).then((response) => {
|
|
107
|
+
// If response is accepted, remove the last node from the target neighbors
|
|
108
|
+
// and unlock the connection
|
|
109
|
+
// If response is not accepted, keep the last node as a neighbor
|
|
110
|
+
if (response.accepted) {
|
|
111
|
+
this.config.neighbors.remove(getNodeIdFromPeerDescriptor(lastPeerDescriptor!))
|
|
112
|
+
}
|
|
113
|
+
return
|
|
114
|
+
}).catch(() => {
|
|
115
|
+
// no-op: InterleaveRequest cannot reject
|
|
116
|
+
}).finally(() => {
|
|
117
|
+
this.config.ongoingInterleaves.delete(nodeId)
|
|
118
|
+
})
|
|
84
119
|
}
|
|
85
|
-
this.config.
|
|
86
|
-
this.config.connectionLocker.lockConnection(requester, this.config.streamPartId)
|
|
120
|
+
this.config.neighbors.add(this.config.createDeliveryRpcRemote(requester))
|
|
87
121
|
return {
|
|
88
122
|
requestId: request.requestId,
|
|
89
123
|
accepted: true,
|
|
90
|
-
interleaveTargetDescriptor:
|
|
124
|
+
interleaveTargetDescriptor: lastPeerDescriptor
|
|
91
125
|
}
|
|
92
126
|
}
|
|
93
127
|
|
|
94
|
-
async
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
128
|
+
async interleaveRequest(message: InterleaveRequest, context: ServerCallContext): Promise<InterleaveResponse> {
|
|
129
|
+
const senderPeerDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
|
|
130
|
+
const senderId = getNodeIdFromPeerDescriptor(senderPeerDescriptor)
|
|
131
|
+
try {
|
|
132
|
+
await this.config.handshakeWithInterleaving(message.interleaveTargetDescriptor!, senderId)
|
|
133
|
+
this.config.neighbors.remove(senderId)
|
|
134
|
+
return { accepted: true }
|
|
135
|
+
} catch (err) {
|
|
136
|
+
logger.debug(`interleaveRequest to ${getNodeIdFromPeerDescriptor(message.interleaveTargetDescriptor!)} failed: ${err}`)
|
|
137
|
+
return { accepted: false }
|
|
103
138
|
}
|
|
104
|
-
return Empty
|
|
105
139
|
}
|
|
106
140
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { PeerDescriptor,
|
|
2
|
-
import { Logger
|
|
1
|
+
import { DhtAddress, PeerDescriptor, RpcRemote, getNodeIdFromPeerDescriptor, getRawFromDhtAddress } from '@streamr/dht'
|
|
2
|
+
import { Logger } from '@streamr/utils'
|
|
3
3
|
import { v4 } from 'uuid'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { InterleaveRequest, InterleaveResponse, StreamPartHandshakeRequest } from '../../proto/packages/trackerless-network/protos/NetworkRpc'
|
|
5
|
+
import { HandshakeRpcClient } from '../../proto/packages/trackerless-network/protos/NetworkRpc.client'
|
|
6
|
+
import { StreamPartID } from '@streamr/protocol'
|
|
7
7
|
|
|
8
8
|
const logger = new Logger(module)
|
|
9
9
|
|
|
@@ -12,19 +12,22 @@ 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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
streamPartId: StreamPartID,
|
|
21
|
+
neighborIds: DhtAddress[],
|
|
22
|
+
concurrentHandshakeTargetId?: DhtAddress,
|
|
23
|
+
interleaveSourceId?: DhtAddress
|
|
21
24
|
): Promise<HandshakeResponse> {
|
|
22
25
|
const request: StreamPartHandshakeRequest = {
|
|
23
|
-
streamPartId
|
|
26
|
+
streamPartId,
|
|
24
27
|
requestId: v4(),
|
|
25
|
-
neighborIds: neighborIds.map((id) =>
|
|
26
|
-
concurrentHandshakeTargetId: (concurrentHandshakeTargetId !== undefined) ?
|
|
27
|
-
interleaveSourceId: (interleaveSourceId !== undefined) ?
|
|
28
|
+
neighborIds: neighborIds.map((id) => getRawFromDhtAddress(id)),
|
|
29
|
+
concurrentHandshakeTargetId: (concurrentHandshakeTargetId !== undefined) ? getRawFromDhtAddress(concurrentHandshakeTargetId) : undefined,
|
|
30
|
+
interleaveSourceId: (interleaveSourceId !== undefined) ? getRawFromDhtAddress(interleaveSourceId) : undefined
|
|
28
31
|
}
|
|
29
32
|
try {
|
|
30
33
|
const response = await this.getClient().handshake(request, this.formDhtRpcOptions())
|
|
@@ -40,16 +43,25 @@ export class HandshakeRpcRemote extends Remote<IHandshakeRpcClient> {
|
|
|
40
43
|
}
|
|
41
44
|
}
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
streamPartId: this.getServiceId(),
|
|
46
|
+
async interleaveRequest(originatorDescriptor: PeerDescriptor): Promise<InterleaveResponse> {
|
|
47
|
+
const request: InterleaveRequest = {
|
|
46
48
|
interleaveTargetDescriptor: originatorDescriptor
|
|
47
49
|
}
|
|
48
50
|
const options = this.formDhtRpcOptions({
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
this.getClient().interleaveNotice(notification, options).catch(() => {
|
|
52
|
-
logger.debug('Failed to send interleaveNotice')
|
|
51
|
+
connect: false,
|
|
52
|
+
timeout: INTERLEAVE_REQUEST_TIMEOUT
|
|
53
53
|
})
|
|
54
|
+
try {
|
|
55
|
+
const res = await this.getClient().interleaveRequest(request, options)
|
|
56
|
+
return {
|
|
57
|
+
accepted: res.accepted
|
|
58
|
+
}
|
|
59
|
+
} catch (err) {
|
|
60
|
+
logger.debug(`interleaveRequest to ${getNodeIdFromPeerDescriptor(this.getPeerDescriptor())} failed: ${err}`)
|
|
61
|
+
return {
|
|
62
|
+
accepted: false
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
54
66
|
}
|
|
55
67
|
}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DhtAddress, PeerDescriptor, ListeningRpcCommunicator, getNodeIdFromPeerDescriptor } from '@streamr/dht'
|
|
2
2
|
import { NodeList } from '../NodeList'
|
|
3
3
|
import { DeliveryRpcRemote } from '../DeliveryRpcRemote'
|
|
4
|
-
import { ProtoRpcClient, RpcCommunicator, toProtoRpcClient } from '@streamr/proto-rpc'
|
|
5
4
|
import {
|
|
6
|
-
HandshakeRpcClient
|
|
7
|
-
IHandshakeRpcClient, DeliveryRpcClient
|
|
5
|
+
DeliveryRpcClient, HandshakeRpcClient
|
|
8
6
|
} from '../../proto/packages/trackerless-network/protos/NetworkRpc.client'
|
|
9
7
|
import {
|
|
10
|
-
|
|
8
|
+
InterleaveRequest,
|
|
9
|
+
InterleaveResponse,
|
|
11
10
|
StreamPartHandshakeRequest,
|
|
12
11
|
StreamPartHandshakeResponse
|
|
13
12
|
} from '../../proto/packages/trackerless-network/protos/NetworkRpc'
|
|
14
13
|
import { Logger } from '@streamr/utils'
|
|
15
14
|
import { IHandshakeRpc } from '../../proto/packages/trackerless-network/protos/NetworkRpc.server'
|
|
16
|
-
import { HandshakeRpcRemote } from './HandshakeRpcRemote'
|
|
15
|
+
import { HandshakeRpcRemote, INTERLEAVE_REQUEST_TIMEOUT } from './HandshakeRpcRemote'
|
|
17
16
|
import { HandshakeRpcLocal } from './HandshakeRpcLocal'
|
|
18
|
-
import { NodeID, getNodeIdFromPeerDescriptor } from '../../identifiers'
|
|
19
17
|
import { StreamPartID } from '@streamr/protocol'
|
|
20
18
|
|
|
21
19
|
interface HandshakerConfig {
|
|
22
20
|
localPeerDescriptor: PeerDescriptor
|
|
23
21
|
streamPartId: StreamPartID
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
neighbors: NodeList
|
|
23
|
+
leftNodeView: NodeList
|
|
24
|
+
rightNodeView: NodeList
|
|
26
25
|
nearbyNodeView: NodeList
|
|
27
26
|
randomNodeView: NodeList
|
|
28
|
-
rpcCommunicator:
|
|
27
|
+
rpcCommunicator: ListeningRpcCommunicator
|
|
29
28
|
maxNeighborCount: number
|
|
29
|
+
ongoingHandshakes: Set<DhtAddress>
|
|
30
30
|
rpcRequestTimeout?: number
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -34,75 +34,93 @@ 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
|
-
private readonly ongoingHandshakes: Set<NodeID> = new Set()
|
|
45
39
|
private config: HandshakerConfig
|
|
46
|
-
private readonly client: ProtoRpcClient<IHandshakeRpcClient>
|
|
47
40
|
private readonly rpcLocal: IHandshakeRpc
|
|
48
41
|
|
|
49
42
|
constructor(config: HandshakerConfig) {
|
|
50
43
|
this.config = config
|
|
51
|
-
this.client = toProtoRpcClient(new HandshakeRpcClient(this.config.rpcCommunicator.getRpcClientTransport()))
|
|
52
44
|
this.rpcLocal = new HandshakeRpcLocal({
|
|
53
45
|
streamPartId: this.config.streamPartId,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
neighbors: this.config.neighbors,
|
|
47
|
+
ongoingHandshakes: this.config.ongoingHandshakes,
|
|
48
|
+
ongoingInterleaves: new Set(),
|
|
57
49
|
maxNeighborCount: this.config.maxNeighborCount,
|
|
58
|
-
handshakeWithInterleaving: (target: PeerDescriptor, senderId:
|
|
50
|
+
handshakeWithInterleaving: (target: PeerDescriptor, senderId: DhtAddress) => this.handshakeWithInterleaving(target, senderId),
|
|
59
51
|
createRpcRemote: (target: PeerDescriptor) => this.createRpcRemote(target),
|
|
60
52
|
createDeliveryRpcRemote: (target: PeerDescriptor) => this.createDeliveryRpcRemote(target)
|
|
61
53
|
})
|
|
62
|
-
this.config.rpcCommunicator.
|
|
63
|
-
(req:
|
|
54
|
+
this.config.rpcCommunicator.registerRpcMethod(InterleaveRequest, InterleaveResponse, 'interleaveRequest',
|
|
55
|
+
(req: InterleaveRequest, context) => this.rpcLocal.interleaveRequest(req, context), { timeout: INTERLEAVE_REQUEST_TIMEOUT })
|
|
64
56
|
this.config.rpcCommunicator.registerRpcMethod(StreamPartHandshakeRequest, StreamPartHandshakeResponse, 'handshake',
|
|
65
57
|
(req: StreamPartHandshakeRequest, context) => this.rpcLocal.handshake(req, context))
|
|
66
58
|
}
|
|
67
59
|
|
|
68
|
-
async attemptHandshakesOnContacts(excludedIds:
|
|
69
|
-
|
|
60
|
+
async attemptHandshakesOnContacts(excludedIds: DhtAddress[]): Promise<DhtAddress[]> {
|
|
61
|
+
// TODO use config option or named constant? or why the value 2?
|
|
62
|
+
if (this.config.neighbors.size() + this.config.ongoingHandshakes.size < this.config.maxNeighborCount - 2) {
|
|
70
63
|
logger.trace(`Attempting parallel handshakes with ${PARALLEL_HANDSHAKE_COUNT} targets`)
|
|
71
64
|
return this.selectParallelTargetsAndHandshake(excludedIds)
|
|
72
|
-
} else if (this.config.
|
|
65
|
+
} else if (this.config.neighbors.size() + this.config.ongoingHandshakes.size < this.config.maxNeighborCount) {
|
|
73
66
|
logger.trace(`Attempting handshake with new target`)
|
|
74
67
|
return this.selectNewTargetAndHandshake(excludedIds)
|
|
75
68
|
}
|
|
76
69
|
return excludedIds
|
|
77
70
|
}
|
|
78
71
|
|
|
79
|
-
private async selectParallelTargetsAndHandshake(excludedIds:
|
|
80
|
-
const exclude = excludedIds.concat(this.config.
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
return this.doParallelHandshakes(
|
|
72
|
+
private async selectParallelTargetsAndHandshake(excludedIds: DhtAddress[]): Promise<DhtAddress[]> {
|
|
73
|
+
const exclude = excludedIds.concat(this.config.neighbors.getIds())
|
|
74
|
+
const neighbors = this.selectParallelTargets(exclude)
|
|
75
|
+
neighbors.forEach((contact) => this.config.ongoingHandshakes.add(getNodeIdFromPeerDescriptor(contact.getPeerDescriptor())))
|
|
76
|
+
return this.doParallelHandshakes(neighbors, exclude)
|
|
84
77
|
}
|
|
85
78
|
|
|
86
|
-
private selectParallelTargets(excludedIds:
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
79
|
+
private selectParallelTargets(excludedIds: DhtAddress[]): HandshakeRpcRemote[] {
|
|
80
|
+
const neighbors: Map<DhtAddress, DeliveryRpcRemote> = new Map()
|
|
81
|
+
// First add the closest left and then right contacts from the ring if possible.
|
|
82
|
+
const left = this.config.leftNodeView.getFirst([...excludedIds, ...Array.from(neighbors.keys())] as DhtAddress[])
|
|
83
|
+
const right = this.config.rightNodeView.getFirst([...excludedIds, ...Array.from(neighbors.keys())] as DhtAddress[])
|
|
84
|
+
if (left) {
|
|
85
|
+
neighbors.set(getNodeIdFromPeerDescriptor(left.getPeerDescriptor()), left)
|
|
86
|
+
}
|
|
87
|
+
if (right) {
|
|
88
|
+
neighbors.set(getNodeIdFromPeerDescriptor(right.getPeerDescriptor()), right)
|
|
89
|
+
}
|
|
90
|
+
// If there is still room add the closest contact based on the kademlia metric
|
|
91
|
+
if (neighbors.size < PARALLEL_HANDSHAKE_COUNT) {
|
|
92
|
+
const first = this.config.nearbyNodeView.getFirst([...excludedIds, ...Array.from(neighbors.keys())] as DhtAddress[])
|
|
93
|
+
if (first) {
|
|
94
|
+
neighbors.set(getNodeIdFromPeerDescriptor(first.getPeerDescriptor()), first)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const getExcludedFromRandomView = () => [
|
|
98
|
+
...excludedIds,
|
|
99
|
+
...Array.from(neighbors.values()).map((neighbor) => getNodeIdFromPeerDescriptor(neighbor.getPeerDescriptor()))
|
|
100
|
+
]
|
|
101
|
+
// If there is still room add a random contact until PARALLEL_HANDSHAKE_COUNT is reached
|
|
102
|
+
while (
|
|
103
|
+
neighbors.size < PARALLEL_HANDSHAKE_COUNT
|
|
104
|
+
&& this.config.randomNodeView.size(getExcludedFromRandomView()) > 0
|
|
105
|
+
) {
|
|
106
|
+
const random = this.config.randomNodeView.getRandom([...excludedIds, ...Array.from(neighbors.keys())] as DhtAddress[])
|
|
90
107
|
if (random) {
|
|
91
|
-
|
|
108
|
+
neighbors.set(getNodeIdFromPeerDescriptor(random.getPeerDescriptor()), random)
|
|
92
109
|
}
|
|
93
110
|
}
|
|
94
|
-
return
|
|
111
|
+
return Array.from(neighbors.values()).map((neighbor) => this.createRpcRemote(neighbor.getPeerDescriptor()))
|
|
95
112
|
}
|
|
96
113
|
|
|
97
|
-
private async doParallelHandshakes(targets: HandshakeRpcRemote[], excludedIds:
|
|
114
|
+
private async doParallelHandshakes(targets: HandshakeRpcRemote[], excludedIds: DhtAddress[]): Promise<DhtAddress[]> {
|
|
98
115
|
const results = await Promise.allSettled(
|
|
99
116
|
Array.from(targets.values()).map(async (target: HandshakeRpcRemote, i) => {
|
|
100
117
|
const otherNode = i === 0 ? targets[1] : targets[0]
|
|
118
|
+
// TODO better check (currently this condition is always true)
|
|
101
119
|
const otherNodeId = otherNode ? getNodeIdFromPeerDescriptor(otherNode.getPeerDescriptor()) : undefined
|
|
102
120
|
return this.handshakeWithTarget(target, otherNodeId)
|
|
103
121
|
})
|
|
104
122
|
)
|
|
105
|
-
results.
|
|
123
|
+
results.forEach((res, i) => {
|
|
106
124
|
if (res.status !== 'fulfilled' || !res.value) {
|
|
107
125
|
excludedIds.push(getNodeIdFromPeerDescriptor(targets[i].getPeerDescriptor()))
|
|
108
126
|
}
|
|
@@ -110,56 +128,53 @@ export class Handshaker implements IHandshaker {
|
|
|
110
128
|
return excludedIds
|
|
111
129
|
}
|
|
112
130
|
|
|
113
|
-
private async selectNewTargetAndHandshake(excludedIds:
|
|
114
|
-
const exclude = excludedIds.concat(this.config.
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
131
|
+
private async selectNewTargetAndHandshake(excludedIds: DhtAddress[]): Promise<DhtAddress[]> {
|
|
132
|
+
const exclude = excludedIds.concat(this.config.neighbors.getIds())
|
|
133
|
+
const neighbor = this.config.leftNodeView.getFirst(exclude)
|
|
134
|
+
?? this.config.rightNodeView.getFirst(exclude)
|
|
135
|
+
?? this.config.nearbyNodeView.getFirst(exclude)
|
|
136
|
+
?? this.config.randomNodeView.getRandom(exclude)
|
|
137
|
+
if (neighbor) {
|
|
138
|
+
const accepted = await this.handshakeWithTarget(this.createRpcRemote(neighbor.getPeerDescriptor()))
|
|
118
139
|
if (!accepted) {
|
|
119
|
-
excludedIds.push(getNodeIdFromPeerDescriptor(
|
|
140
|
+
excludedIds.push(getNodeIdFromPeerDescriptor(neighbor.getPeerDescriptor()))
|
|
120
141
|
}
|
|
121
142
|
}
|
|
122
143
|
return excludedIds
|
|
123
144
|
}
|
|
124
145
|
|
|
125
|
-
private async handshakeWithTarget(
|
|
126
|
-
const targetNodeId = getNodeIdFromPeerDescriptor(
|
|
127
|
-
this.ongoingHandshakes.add(targetNodeId)
|
|
128
|
-
const result = await
|
|
129
|
-
this.config.
|
|
146
|
+
private async handshakeWithTarget(neighbor: HandshakeRpcRemote, concurrentNodeId?: DhtAddress): Promise<boolean> {
|
|
147
|
+
const targetNodeId = getNodeIdFromPeerDescriptor(neighbor.getPeerDescriptor())
|
|
148
|
+
this.config.ongoingHandshakes.add(targetNodeId)
|
|
149
|
+
const result = await neighbor.handshake(
|
|
150
|
+
this.config.streamPartId,
|
|
151
|
+
this.config.neighbors.getIds(),
|
|
130
152
|
concurrentNodeId
|
|
131
153
|
)
|
|
132
154
|
if (result.accepted) {
|
|
133
|
-
this.config.
|
|
134
|
-
this.config.connectionLocker.lockConnection(targetNeighbor.getPeerDescriptor(), this.config.streamPartId)
|
|
155
|
+
this.config.neighbors.add(this.createDeliveryRpcRemote(neighbor.getPeerDescriptor()))
|
|
135
156
|
}
|
|
136
157
|
if (result.interleaveTargetDescriptor) {
|
|
137
158
|
await this.handshakeWithInterleaving(result.interleaveTargetDescriptor, targetNodeId)
|
|
138
159
|
}
|
|
139
|
-
this.ongoingHandshakes.delete(targetNodeId)
|
|
160
|
+
this.config.ongoingHandshakes.delete(targetNodeId)
|
|
140
161
|
return result.accepted
|
|
141
162
|
}
|
|
142
163
|
|
|
143
|
-
private async handshakeWithInterleaving(target: PeerDescriptor, interleaveSourceId:
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
164
|
+
private async handshakeWithInterleaving(target: PeerDescriptor, interleaveSourceId: DhtAddress): Promise<boolean> {
|
|
165
|
+
const neighbor = this.createRpcRemote(target)
|
|
166
|
+
const targetNodeId = getNodeIdFromPeerDescriptor(neighbor.getPeerDescriptor())
|
|
167
|
+
this.config.ongoingHandshakes.add(targetNodeId)
|
|
168
|
+
const result = await neighbor.handshake(
|
|
147
169
|
this.config.streamPartId,
|
|
148
|
-
this.
|
|
149
|
-
this.config.rpcRequestTimeout
|
|
150
|
-
)
|
|
151
|
-
const targetNodeId = getNodeIdFromPeerDescriptor(targetNeighbor.getPeerDescriptor())
|
|
152
|
-
this.ongoingHandshakes.add(targetNodeId)
|
|
153
|
-
const result = await targetNeighbor.handshake(
|
|
154
|
-
this.config.targetNeighbors.getIds(),
|
|
170
|
+
this.config.neighbors.getIds(),
|
|
155
171
|
undefined,
|
|
156
172
|
interleaveSourceId
|
|
157
173
|
)
|
|
158
174
|
if (result.accepted) {
|
|
159
|
-
this.config.
|
|
160
|
-
this.config.connectionLocker.lockConnection(targetNeighbor.getPeerDescriptor(), this.config.streamPartId)
|
|
175
|
+
this.config.neighbors.add(this.createDeliveryRpcRemote(neighbor.getPeerDescriptor()))
|
|
161
176
|
}
|
|
162
|
-
this.ongoingHandshakes.delete(targetNodeId)
|
|
177
|
+
this.config.ongoingHandshakes.delete(targetNodeId)
|
|
163
178
|
return result.accepted
|
|
164
179
|
}
|
|
165
180
|
|
|
@@ -167,8 +182,8 @@ export class Handshaker implements IHandshaker {
|
|
|
167
182
|
return new HandshakeRpcRemote(
|
|
168
183
|
this.config.localPeerDescriptor,
|
|
169
184
|
targetPeerDescriptor,
|
|
170
|
-
this.config.
|
|
171
|
-
|
|
185
|
+
this.config.rpcCommunicator,
|
|
186
|
+
HandshakeRpcClient,
|
|
172
187
|
this.config.rpcRequestTimeout
|
|
173
188
|
)
|
|
174
189
|
}
|
|
@@ -177,14 +192,14 @@ export class Handshaker implements IHandshaker {
|
|
|
177
192
|
return new DeliveryRpcRemote(
|
|
178
193
|
this.config.localPeerDescriptor,
|
|
179
194
|
targetPeerDescriptor,
|
|
180
|
-
this.config.
|
|
181
|
-
|
|
195
|
+
this.config.rpcCommunicator,
|
|
196
|
+
DeliveryRpcClient,
|
|
182
197
|
this.config.rpcRequestTimeout
|
|
183
198
|
)
|
|
184
199
|
}
|
|
185
200
|
|
|
186
|
-
getOngoingHandshakes(): Set<
|
|
187
|
-
return this.ongoingHandshakes
|
|
201
|
+
getOngoingHandshakes(): Set<DhtAddress> {
|
|
202
|
+
return this.config.ongoingHandshakes
|
|
188
203
|
}
|
|
189
204
|
|
|
190
205
|
}
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
import { setAbortableTimeout } from '@streamr/utils'
|
|
2
2
|
import { NodeList } from '../NodeList'
|
|
3
|
-
import {
|
|
3
|
+
import { DhtAddress } from '@streamr/dht'
|
|
4
4
|
|
|
5
5
|
interface FindNeighborsSessionConfig {
|
|
6
|
-
|
|
6
|
+
neighbors: NodeList
|
|
7
7
|
nearbyNodeView: NodeList
|
|
8
|
-
|
|
8
|
+
leftNodeView: NodeList
|
|
9
|
+
rightNodeView: NodeList
|
|
10
|
+
randomNodeView: NodeList
|
|
11
|
+
doFindNeighbors: (excludedNodes: DhtAddress[]) => Promise<DhtAddress[]>
|
|
9
12
|
minCount: number
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
const INITIAL_WAIT = 100
|
|
13
16
|
const INTERVAL = 250
|
|
14
17
|
|
|
15
|
-
export
|
|
16
|
-
start(excluded?: NodeID[]): void
|
|
17
|
-
stop(): void
|
|
18
|
-
isRunning(): boolean
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export class NeighborFinder implements INeighborFinder {
|
|
18
|
+
export class NeighborFinder {
|
|
22
19
|
private readonly abortController: AbortController
|
|
23
20
|
private readonly config: FindNeighborsSessionConfig
|
|
24
21
|
private running = false
|
|
@@ -28,12 +25,19 @@ export class NeighborFinder implements INeighborFinder {
|
|
|
28
25
|
this.abortController = new AbortController()
|
|
29
26
|
}
|
|
30
27
|
|
|
31
|
-
private async findNeighbors(excluded:
|
|
28
|
+
private async findNeighbors(excluded: DhtAddress[]): Promise<void> {
|
|
32
29
|
if (!this.running) {
|
|
33
30
|
return
|
|
34
31
|
}
|
|
35
32
|
const newExcludes = await this.config.doFindNeighbors(excluded)
|
|
36
|
-
|
|
33
|
+
const uniqueContactCount = new Set([
|
|
34
|
+
...this.config.nearbyNodeView.getIds(),
|
|
35
|
+
...this.config.leftNodeView.getIds(),
|
|
36
|
+
...this.config.rightNodeView.getIds(),
|
|
37
|
+
...this.config.randomNodeView.getIds()
|
|
38
|
+
]).size
|
|
39
|
+
if (this.config.neighbors.size() < this.config.minCount && newExcludes.length < uniqueContactCount) {
|
|
40
|
+
// TODO should we catch possible promise rejection?
|
|
37
41
|
setAbortableTimeout(() => this.findNeighbors(newExcludes), INTERVAL, this.abortController.signal)
|
|
38
42
|
} else {
|
|
39
43
|
this.running = false
|
|
@@ -44,11 +48,12 @@ export class NeighborFinder implements INeighborFinder {
|
|
|
44
48
|
return this.running
|
|
45
49
|
}
|
|
46
50
|
|
|
47
|
-
start(excluded:
|
|
51
|
+
start(excluded: DhtAddress[] = []): void {
|
|
48
52
|
if (this.running) {
|
|
49
53
|
return
|
|
50
54
|
}
|
|
51
55
|
this.running = true
|
|
56
|
+
// TODO should we catch possible promise rejection?
|
|
52
57
|
setAbortableTimeout(() => this.findNeighbors(excluded), INITIAL_WAIT, this.abortController.signal)
|
|
53
58
|
}
|
|
54
59
|
|