@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamr/trackerless-network",
|
|
3
|
-
"version": "100.0.0-
|
|
3
|
+
"version": "100.0.0-rc.1",
|
|
4
4
|
"description": "Minimal and extendable implementation of the Streamr Network node.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@protobuf-ts/runtime": "^2.8.2",
|
|
32
32
|
"@protobuf-ts/runtime-rpc": "^2.8.2",
|
|
33
|
-
"@streamr/dht": "100.0.0-
|
|
34
|
-
"@streamr/proto-rpc": "100.0.0-
|
|
35
|
-
"@streamr/protocol": "100.0.0-
|
|
36
|
-
"@streamr/test-utils": "100.0.0-
|
|
37
|
-
"@streamr/utils": "100.0.0-
|
|
33
|
+
"@streamr/dht": "100.0.0-rc.1",
|
|
34
|
+
"@streamr/proto-rpc": "100.0.0-rc.1",
|
|
35
|
+
"@streamr/protocol": "100.0.0-rc.1",
|
|
36
|
+
"@streamr/test-utils": "100.0.0-rc.1",
|
|
37
|
+
"@streamr/utils": "100.0.0-rc.1",
|
|
38
38
|
"eventemitter3": "^5.0.0",
|
|
39
39
|
"lodash": "^4.17.21",
|
|
40
40
|
"uuid": "^9.0.1",
|
|
@@ -42,14 +42,14 @@
|
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@streamr/browser-test-runner": "^0.0.1",
|
|
45
|
-
"@types/lodash": "^4.14.
|
|
46
|
-
"@types/uuid": "^9.0.
|
|
45
|
+
"@types/lodash": "^4.14.202",
|
|
46
|
+
"@types/uuid": "^9.0.8",
|
|
47
47
|
"@types/yallist": "^4.0.1",
|
|
48
|
-
"commander": "^
|
|
48
|
+
"commander": "^12.0.0",
|
|
49
49
|
"expect": "^29.6.2",
|
|
50
|
-
"express": "^4.
|
|
50
|
+
"express": "^4.18.3",
|
|
51
51
|
"ts-essentials": "^9.4.1",
|
|
52
|
-
"ts-loader": "^9.5.
|
|
53
|
-
"ts-node": "^10.9.
|
|
52
|
+
"ts-loader": "^9.5.1",
|
|
53
|
+
"ts-node": "^10.9.2"
|
|
54
54
|
}
|
|
55
55
|
}
|
package/protos/NetworkRpc.proto
CHANGED
|
@@ -17,7 +17,7 @@ service ProxyConnectionRpc {
|
|
|
17
17
|
|
|
18
18
|
service HandshakeRpc {
|
|
19
19
|
rpc handshake (StreamPartHandshakeRequest) returns (StreamPartHandshakeResponse);
|
|
20
|
-
rpc
|
|
20
|
+
rpc interleaveRequest (InterleaveRequest) returns (InterleaveResponse);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
service NeighborUpdateRpc {
|
|
@@ -26,6 +26,11 @@ service NeighborUpdateRpc {
|
|
|
26
26
|
|
|
27
27
|
service TemporaryConnectionRpc {
|
|
28
28
|
rpc openConnection (TemporaryConnectionRequest) returns (TemporaryConnectionResponse);
|
|
29
|
+
rpc closeConnection (CloseTemporaryConnection) returns (google.protobuf.Empty);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
service NodeInfoRpc {
|
|
33
|
+
rpc getInfo (NodeInfoRequest) returns (NodeInfoResponse);
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
message MessageID {
|
|
@@ -58,17 +63,30 @@ enum EncryptionType {
|
|
|
58
63
|
AES = 1;
|
|
59
64
|
}
|
|
60
65
|
|
|
66
|
+
enum SignatureType {
|
|
67
|
+
LEGACY_SECP256K1 = 0;
|
|
68
|
+
SECP256K1 = 1;
|
|
69
|
+
}
|
|
70
|
+
|
|
61
71
|
message StreamMessage {
|
|
62
|
-
|
|
72
|
+
// this is a required field but in generated NetworkRpc.ts it is incorrectly annotated as optional (NET-1082)
|
|
73
|
+
MessageID messageId = 1;
|
|
74
|
+
optional MessageRef previousMessageRef = 2;
|
|
75
|
+
bytes signature = 3;
|
|
76
|
+
SignatureType signatureType = 4;
|
|
77
|
+
oneof body {
|
|
78
|
+
ContentMessage contentMessage = 5;
|
|
79
|
+
GroupKeyRequest groupKeyRequest = 6;
|
|
80
|
+
GroupKeyResponse groupKeyResponse = 7;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
message ContentMessage {
|
|
85
|
+
bytes content = 1;
|
|
63
86
|
ContentType contentType = 2;
|
|
64
87
|
EncryptionType encryptionType = 3;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// this is a required field but in generated NetworkRpc.ts it is incorrectly annotated as optional (NET-1082)
|
|
68
|
-
MessageID messageId = 6;
|
|
69
|
-
optional MessageRef previousMessageRef = 7;
|
|
70
|
-
optional string groupKeyId = 8;
|
|
71
|
-
optional GroupKey newGroupKey = 9;
|
|
88
|
+
optional string groupKeyId = 4;
|
|
89
|
+
optional GroupKey newGroupKey = 5;
|
|
72
90
|
}
|
|
73
91
|
|
|
74
92
|
message GroupKeyRequest {
|
|
@@ -103,14 +121,18 @@ message StreamPartHandshakeResponse {
|
|
|
103
121
|
optional dht.PeerDescriptor interleaveTargetDescriptor = 3;
|
|
104
122
|
}
|
|
105
123
|
|
|
106
|
-
message
|
|
107
|
-
string streamPartId = 1;
|
|
124
|
+
message InterleaveRequest {
|
|
108
125
|
// this is a required field but in generated NetworkRpc.ts it is incorrectly annotated as optional (NET-1082)
|
|
109
|
-
dht.PeerDescriptor interleaveTargetDescriptor =
|
|
126
|
+
dht.PeerDescriptor interleaveTargetDescriptor = 1;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
message InterleaveResponse {
|
|
130
|
+
bool accepted = 1;
|
|
110
131
|
}
|
|
111
132
|
|
|
112
133
|
message LeaveStreamPartNotice {
|
|
113
134
|
string streamPartId = 1;
|
|
135
|
+
bool isEntryPoint = 2;
|
|
114
136
|
}
|
|
115
137
|
|
|
116
138
|
message NeighborUpdate {
|
|
@@ -135,7 +157,30 @@ message TemporaryConnectionResponse {
|
|
|
135
157
|
bool accepted = 1;
|
|
136
158
|
}
|
|
137
159
|
|
|
160
|
+
message CloseTemporaryConnection {
|
|
161
|
+
}
|
|
162
|
+
|
|
138
163
|
enum ProxyDirection {
|
|
139
164
|
PUBLISH = 0;
|
|
140
165
|
SUBSCRIBE = 1;
|
|
141
166
|
}
|
|
167
|
+
|
|
168
|
+
message StreamPartitionInfo {
|
|
169
|
+
string id = 1;
|
|
170
|
+
repeated dht.PeerDescriptor controlLayerNeighbors = 2;
|
|
171
|
+
repeated dht.PeerDescriptor deliveryLayerNeighbors = 3;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
message ControlLayerInfo {
|
|
175
|
+
repeated dht.PeerDescriptor neighbors = 1;
|
|
176
|
+
repeated dht.PeerDescriptor connections = 2;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
message NodeInfoRequest {}
|
|
180
|
+
|
|
181
|
+
message NodeInfoResponse {
|
|
182
|
+
dht.PeerDescriptor peerDescriptor = 1;
|
|
183
|
+
repeated StreamPartitionInfo streamPartitions = 2;
|
|
184
|
+
optional ControlLayerInfo controlLayer = 3;
|
|
185
|
+
string version = 4;
|
|
186
|
+
}
|
package/src/NetworkNode.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { StreamMessage, StreamPartID } from '@streamr/protocol'
|
|
2
|
-
import { PeerDescriptor } from '@streamr/dht'
|
|
2
|
+
import { DhtAddress, PeerDescriptor } from '@streamr/dht'
|
|
3
3
|
import { StreamMessageTranslator } from './logic/protocol-integration/stream-message/StreamMessageTranslator'
|
|
4
|
-
import { NetworkOptions, NetworkStack } from './NetworkStack'
|
|
4
|
+
import { NetworkOptions, NetworkStack, NodeInfo } from './NetworkStack'
|
|
5
5
|
import { EthereumAddress, Logger, MetricsContext } from '@streamr/utils'
|
|
6
6
|
import { ProxyDirection } from './proto/packages/trackerless-network/protos/NetworkRpc'
|
|
7
|
-
import { NodeID } from './identifiers'
|
|
8
7
|
import { pull } from 'lodash'
|
|
9
8
|
|
|
10
9
|
export const createNetworkNode = (opts: NetworkOptions): NetworkNode => {
|
|
@@ -74,7 +73,7 @@ export class NetworkNode {
|
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
setStreamPartEntryPoints(streamPartId: StreamPartID, contactPeerDescriptors: PeerDescriptor[]): void {
|
|
77
|
-
this.stack.getStreamrNode()
|
|
76
|
+
this.stack.getStreamrNode().setStreamPartEntryPoints(streamPartId, contactPeerDescriptors)
|
|
78
77
|
}
|
|
79
78
|
|
|
80
79
|
removeMessageListener(cb: (msg: StreamMessage) => void): void {
|
|
@@ -88,7 +87,7 @@ export class NetworkNode {
|
|
|
88
87
|
await this.stack.getStreamrNode().leaveStreamPart(streamPartId)
|
|
89
88
|
}
|
|
90
89
|
|
|
91
|
-
getNeighbors(streamPartId: StreamPartID): ReadonlyArray<
|
|
90
|
+
getNeighbors(streamPartId: StreamPartID): ReadonlyArray<DhtAddress> {
|
|
92
91
|
return this.stack.getStreamrNode().getNeighbors(streamPartId)
|
|
93
92
|
}
|
|
94
93
|
|
|
@@ -109,14 +108,22 @@ export class NetworkNode {
|
|
|
109
108
|
return this.stack.getMetricsContext()
|
|
110
109
|
}
|
|
111
110
|
|
|
112
|
-
getNodeId():
|
|
111
|
+
getNodeId(): DhtAddress {
|
|
113
112
|
return this.stack.getStreamrNode().getNodeId()
|
|
114
113
|
}
|
|
115
114
|
|
|
115
|
+
getOptions(): NetworkOptions {
|
|
116
|
+
return this.stack.getOptions()
|
|
117
|
+
}
|
|
118
|
+
|
|
116
119
|
getStreamParts(): StreamPartID[] {
|
|
117
120
|
return this.stack.getStreamrNode().getStreamParts()
|
|
118
121
|
}
|
|
119
122
|
|
|
123
|
+
async fetchNodeInfo(node: PeerDescriptor): Promise<NodeInfo> {
|
|
124
|
+
return this.stack.fetchNodeInfo(node)
|
|
125
|
+
}
|
|
126
|
+
|
|
120
127
|
// eslint-disable-next-line class-methods-use-this
|
|
121
128
|
getDiagnosticInfo(): Record<string, unknown> {
|
|
122
129
|
return {}
|
package/src/NetworkStack.ts
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import {
|
|
2
|
+
ConnectionManager,
|
|
3
|
+
DhtNode,
|
|
4
|
+
DhtNodeOptions,
|
|
5
|
+
ListeningRpcCommunicator,
|
|
6
|
+
PeerDescriptor,
|
|
7
|
+
areEqualPeerDescriptors
|
|
8
|
+
} from '@streamr/dht'
|
|
5
9
|
import { StreamID, StreamPartID, toStreamPartID } from '@streamr/protocol'
|
|
6
|
-
import {
|
|
10
|
+
import { Logger, MetricsContext, waitForCondition } from '@streamr/utils'
|
|
11
|
+
import { pull } from 'lodash'
|
|
12
|
+
import { version as applicationVersion } from '../package.json'
|
|
7
13
|
import { Layer0Node } from './logic/Layer0Node'
|
|
14
|
+
import { StreamrNode, StreamrNodeConfig } from './logic/StreamrNode'
|
|
15
|
+
import { NodeInfoClient } from './logic/node-info/NodeInfoClient'
|
|
16
|
+
import { NODE_INFO_RPC_SERVICE_ID, NodeInfoRpcLocal } from './logic/node-info/NodeInfoRpcLocal'
|
|
17
|
+
import { NodeInfoResponse, ProxyDirection, StreamMessage } from './proto/packages/trackerless-network/protos/NetworkRpc'
|
|
8
18
|
|
|
9
19
|
export interface NetworkOptions {
|
|
10
20
|
layer0?: DhtNodeOptions
|
|
@@ -12,19 +22,46 @@ export interface NetworkOptions {
|
|
|
12
22
|
metricsContext?: MetricsContext
|
|
13
23
|
}
|
|
14
24
|
|
|
15
|
-
|
|
16
|
-
|
|
25
|
+
const logger = new Logger(module)
|
|
26
|
+
|
|
27
|
+
const instances: NetworkStack[] = []
|
|
28
|
+
const stopInstances = async () => {
|
|
29
|
+
// make a clone so that it is ok for each instance.stop() to remove itself from the list (at line 139)
|
|
30
|
+
// while the map function is iterating the list
|
|
31
|
+
const clonedInstances = [...instances]
|
|
32
|
+
await Promise.all(clonedInstances.map((instance) => instance.stop()))
|
|
33
|
+
}
|
|
34
|
+
const EXIT_EVENTS = [`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `unhandledRejection`, `SIGTERM`]
|
|
35
|
+
EXIT_EVENTS.forEach((event) => {
|
|
36
|
+
process.on(event, async (eventArg) => {
|
|
37
|
+
const isError = (event === 'uncaughtException') || (event === 'unhandledRejection')
|
|
38
|
+
if (isError) {
|
|
39
|
+
logger.error(`exit event: ${event}`, eventArg)
|
|
40
|
+
}
|
|
41
|
+
await stopInstances()
|
|
42
|
+
process.exit(isError ? 1 : 0)
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
declare let window: any
|
|
46
|
+
if (typeof window === 'object') {
|
|
47
|
+
window.addEventListener('unload', async () => {
|
|
48
|
+
await stopInstances()
|
|
49
|
+
})
|
|
17
50
|
}
|
|
18
51
|
|
|
19
|
-
export
|
|
52
|
+
export type NodeInfo = Required<NodeInfoResponse>
|
|
53
|
+
|
|
54
|
+
export class NetworkStack {
|
|
20
55
|
|
|
21
56
|
private layer0Node?: Layer0Node
|
|
22
57
|
private streamrNode?: StreamrNode
|
|
58
|
+
private stopped = false
|
|
23
59
|
private readonly metricsContext: MetricsContext
|
|
24
60
|
private readonly options: NetworkOptions
|
|
61
|
+
private nodeInfoRpcLocal?: NodeInfoRpcLocal
|
|
62
|
+
private nodeInfoClient?: NodeInfoClient
|
|
25
63
|
|
|
26
64
|
constructor(options: NetworkOptions) {
|
|
27
|
-
super()
|
|
28
65
|
this.options = options
|
|
29
66
|
this.metricsContext = options.metricsContext ?? new MetricsContext()
|
|
30
67
|
this.layer0Node = new DhtNode({
|
|
@@ -35,6 +72,7 @@ export class NetworkStack extends EventEmitter<NetworkStackEvents> {
|
|
|
35
72
|
...options.networkNode,
|
|
36
73
|
metricsContext: this.metricsContext
|
|
37
74
|
})
|
|
75
|
+
instances.push(this)
|
|
38
76
|
}
|
|
39
77
|
|
|
40
78
|
async joinStreamPart(streamPartId: StreamPartID, neighborRequirement?: { minCount: number, timeout: number }): Promise<void> {
|
|
@@ -52,7 +90,7 @@ export class NetworkStack extends EventEmitter<NetworkStackEvents> {
|
|
|
52
90
|
|
|
53
91
|
async broadcast(msg: StreamMessage): Promise<void> {
|
|
54
92
|
const streamPartId = toStreamPartID(msg.messageId!.streamId as StreamID, msg.messageId!.streamPartition)
|
|
55
|
-
if (this.getStreamrNode().isProxiedStreamPart(streamPartId, ProxyDirection.SUBSCRIBE) && (msg.
|
|
93
|
+
if (this.getStreamrNode().isProxiedStreamPart(streamPartId, ProxyDirection.SUBSCRIBE) && (msg.body.oneofKind === 'contentMessage')) {
|
|
56
94
|
throw new Error(`Cannot broadcast to ${streamPartId} as proxy subscribe connections have been set`)
|
|
57
95
|
}
|
|
58
96
|
// TODO could combine these two calls to isProxiedStreamPart?
|
|
@@ -75,7 +113,16 @@ export class NetworkStack extends EventEmitter<NetworkStackEvents> {
|
|
|
75
113
|
await this.ensureConnectedToControlLayer()
|
|
76
114
|
}
|
|
77
115
|
}
|
|
116
|
+
// TODO: remove undefined checks here. Assume that start is approproately awaited before stop is called.
|
|
78
117
|
await this.streamrNode?.start(this.layer0Node!, connectionManager, connectionManager)
|
|
118
|
+
if (this.streamrNode) {
|
|
119
|
+
const infoRpcCommunicator = new ListeningRpcCommunicator(NODE_INFO_RPC_SERVICE_ID, this.getConnectionManager())
|
|
120
|
+
this.nodeInfoRpcLocal = new NodeInfoRpcLocal(this, infoRpcCommunicator)
|
|
121
|
+
this.nodeInfoClient = new NodeInfoClient(
|
|
122
|
+
this.layer0Node!.getLocalPeerDescriptor(),
|
|
123
|
+
infoRpcCommunicator
|
|
124
|
+
)
|
|
125
|
+
}
|
|
79
126
|
}
|
|
80
127
|
|
|
81
128
|
private async ensureConnectedToControlLayer(): Promise<void> {
|
|
@@ -89,8 +136,8 @@ export class NetworkStack extends EventEmitter<NetworkStackEvents> {
|
|
|
89
136
|
await this.layer0Node?.joinDht(this.options.layer0.entryPoints)
|
|
90
137
|
}
|
|
91
138
|
})
|
|
139
|
+
await this.layer0Node!.waitForNetworkConnectivity()
|
|
92
140
|
}
|
|
93
|
-
await this.layer0Node!.waitForNetworkConnectivity()
|
|
94
141
|
}
|
|
95
142
|
|
|
96
143
|
getStreamrNode(): StreamrNode {
|
|
@@ -105,12 +152,43 @@ export class NetworkStack extends EventEmitter<NetworkStackEvents> {
|
|
|
105
152
|
return this.metricsContext
|
|
106
153
|
}
|
|
107
154
|
|
|
155
|
+
async fetchNodeInfo(node: PeerDescriptor): Promise<NodeInfo> {
|
|
156
|
+
if (!areEqualPeerDescriptors(node, this.getLayer0Node().getLocalPeerDescriptor())) {
|
|
157
|
+
return this.nodeInfoClient!.getInfo(node)
|
|
158
|
+
} else {
|
|
159
|
+
return this.createNodeInfo()
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
createNodeInfo(): NodeInfo {
|
|
164
|
+
return {
|
|
165
|
+
peerDescriptor: this.getLayer0Node().getLocalPeerDescriptor(),
|
|
166
|
+
controlLayer: {
|
|
167
|
+
connections: this.getLayer0Node().getConnections(),
|
|
168
|
+
neighbors: this.getLayer0Node().getNeighbors()
|
|
169
|
+
},
|
|
170
|
+
streamPartitions: this.getStreamrNode().getNodeInfo(),
|
|
171
|
+
version: applicationVersion
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
getOptions(): NetworkOptions {
|
|
176
|
+
return this.options
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private getConnectionManager(): ConnectionManager {
|
|
180
|
+
return this.layer0Node!.getTransport() as ConnectionManager
|
|
181
|
+
}
|
|
182
|
+
|
|
108
183
|
async stop(): Promise<void> {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
184
|
+
if (!this.stopped) {
|
|
185
|
+
this.stopped = true
|
|
186
|
+
pull(instances, this)
|
|
187
|
+
await this.streamrNode!.destroy()
|
|
188
|
+
await this.layer0Node!.stop()
|
|
189
|
+
this.streamrNode = undefined
|
|
190
|
+
this.layer0Node = undefined
|
|
191
|
+
}
|
|
114
192
|
}
|
|
115
193
|
|
|
116
194
|
}
|
package/src/exports.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
export { NetworkStack, NetworkOptions } from './NetworkStack'
|
|
1
|
+
export { NetworkStack, NetworkOptions, NodeInfo } from './NetworkStack'
|
|
2
2
|
export { NetworkNode, createNetworkNode } from './NetworkNode'
|
|
3
3
|
export { StreamrNodeConfig } from './logic/StreamrNode'
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
4
|
+
export { ProxyDirection, GroupKeyRequest, GroupKeyResponse } from './proto/packages/trackerless-network/protos/NetworkRpc'
|
|
5
|
+
export { streamPartIdToDataKey } from './logic/EntryPointDiscovery'
|
|
6
|
+
export {
|
|
7
|
+
convertStreamMessageToBytes,
|
|
8
|
+
convertBytesToStreamMessage,
|
|
9
|
+
convertGroupKeyRequestToBytes,
|
|
10
|
+
convertBytesToGroupKeyRequest,
|
|
11
|
+
convertGroupKeyResponseToBytes,
|
|
12
|
+
convertBytesToGroupKeyResponse
|
|
13
|
+
} from './logic/protocol-integration/stream-message/oldStreamMessageBinaryUtils'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ListeningRpcCommunicator, PeerDescriptor, DhtCallContext } from '@streamr/dht'
|
|
1
|
+
import { ListeningRpcCommunicator, PeerDescriptor, DhtCallContext, DhtAddress, getNodeIdFromPeerDescriptor } from '@streamr/dht'
|
|
2
2
|
import { Empty } from '../proto/google/protobuf/empty'
|
|
3
3
|
import {
|
|
4
4
|
LeaveStreamPartNotice,
|
|
@@ -8,16 +8,15 @@ import {
|
|
|
8
8
|
} from '../proto/packages/trackerless-network/protos/NetworkRpc'
|
|
9
9
|
import { IDeliveryRpc } from '../proto/packages/trackerless-network/protos/NetworkRpc.server'
|
|
10
10
|
import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
|
|
11
|
-
import { NodeID, getNodeIdFromPeerDescriptor } from '../identifiers'
|
|
12
11
|
import { StreamPartID } from '@streamr/protocol'
|
|
13
12
|
|
|
14
13
|
export interface DeliveryRpcLocalConfig {
|
|
15
14
|
localPeerDescriptor: PeerDescriptor
|
|
16
15
|
streamPartId: StreamPartID
|
|
17
16
|
markAndCheckDuplicate: (messageId: MessageID, previousMessageRef?: MessageRef) => boolean
|
|
18
|
-
broadcast: (message: StreamMessage, previousNode?:
|
|
19
|
-
onLeaveNotice(senderId:
|
|
20
|
-
markForInspection(senderId:
|
|
17
|
+
broadcast: (message: StreamMessage, previousNode?: DhtAddress) => void
|
|
18
|
+
onLeaveNotice(senderId: DhtAddress, isLocalNodeEntryPoint: boolean): void
|
|
19
|
+
markForInspection(senderId: DhtAddress, messageId: MessageID): void
|
|
21
20
|
rpcCommunicator: ListeningRpcCommunicator
|
|
22
21
|
}
|
|
23
22
|
|
|
@@ -40,9 +39,9 @@ export class DeliveryRpcLocal implements IDeliveryRpc {
|
|
|
40
39
|
|
|
41
40
|
async leaveStreamPartNotice(message: LeaveStreamPartNotice, context: ServerCallContext): Promise<Empty> {
|
|
42
41
|
if (message.streamPartId === this.config.streamPartId) {
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
this.config.onLeaveNotice(
|
|
42
|
+
const sourcePeerDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
|
|
43
|
+
const sourceId = getNodeIdFromPeerDescriptor(sourcePeerDescriptor)
|
|
44
|
+
this.config.onLeaveNotice(sourceId, message.isEntryPoint)
|
|
46
45
|
}
|
|
47
46
|
return Empty
|
|
48
47
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RpcRemote } from '@streamr/dht'
|
|
2
2
|
import { Logger } from '@streamr/utils'
|
|
3
3
|
import {
|
|
4
4
|
LeaveStreamPartNotice,
|
|
5
5
|
StreamMessage
|
|
6
6
|
} from '../proto/packages/trackerless-network/protos/NetworkRpc'
|
|
7
|
-
import {
|
|
7
|
+
import { DeliveryRpcClient } from '../proto/packages/trackerless-network/protos/NetworkRpc.client'
|
|
8
|
+
import { StreamPartID } from '@streamr/protocol'
|
|
8
9
|
|
|
9
10
|
const logger = new Logger(module)
|
|
10
11
|
|
|
11
|
-
export class DeliveryRpcRemote extends
|
|
12
|
+
export class DeliveryRpcRemote extends RpcRemote<DeliveryRpcClient> {
|
|
12
13
|
|
|
13
14
|
async sendStreamMessage(msg: StreamMessage): Promise<void> {
|
|
14
15
|
const options = this.formDhtRpcOptions({
|
|
@@ -19,9 +20,10 @@ export class DeliveryRpcRemote extends Remote<IDeliveryRpcClient> {
|
|
|
19
20
|
})
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
leaveStreamPartNotice(): void {
|
|
23
|
+
leaveStreamPartNotice(streamPartId: StreamPartID, isLocalNodeEntryPoint: boolean): void {
|
|
23
24
|
const notification: LeaveStreamPartNotice = {
|
|
24
|
-
streamPartId
|
|
25
|
+
streamPartId,
|
|
26
|
+
isEntryPoint: isLocalNodeEntryPoint
|
|
25
27
|
}
|
|
26
28
|
const options = this.formDhtRpcOptions({
|
|
27
29
|
notification: true
|
|
@@ -82,11 +82,11 @@ export class GapMisMatchError extends Error {
|
|
|
82
82
|
*
|
|
83
83
|
*/
|
|
84
84
|
export class DuplicateMessageDetector {
|
|
85
|
-
private readonly
|
|
85
|
+
private readonly maxGapCount: number
|
|
86
86
|
private readonly gaps: Array<[NumberPair, NumberPair]>
|
|
87
87
|
|
|
88
|
-
constructor(
|
|
89
|
-
this.
|
|
88
|
+
constructor(maxGapCount = 10000) {
|
|
89
|
+
this.maxGapCount = maxGapCount
|
|
90
90
|
this.gaps = [] // ascending order of half-closed intervals (x,y] representing gaps that contain unseen message(s)
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -144,7 +144,7 @@ export class DuplicateMessageDetector {
|
|
|
144
144
|
// - last gap is [n, Infinity]
|
|
145
145
|
// - anything not covered by a gap is considered seen
|
|
146
146
|
|
|
147
|
-
this.
|
|
147
|
+
this.dropLowestGapIfOverMaxGapCount()
|
|
148
148
|
return true
|
|
149
149
|
}
|
|
150
150
|
if (number.greaterThan(lowerBound)) {
|
|
@@ -154,9 +154,9 @@ export class DuplicateMessageDetector {
|
|
|
154
154
|
return false
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
private
|
|
158
|
-
// invariant: this.gaps.length <= this.
|
|
159
|
-
if (this.gaps.length > this.
|
|
157
|
+
private dropLowestGapIfOverMaxGapCount(): void {
|
|
158
|
+
// invariant: this.gaps.length <= this.maxGapCount + 1
|
|
159
|
+
if (this.gaps.length > this.maxGapCount) {
|
|
160
160
|
this.gaps.shift()
|
|
161
161
|
}
|
|
162
162
|
}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DataEntry,
|
|
3
|
+
DhtAddress,
|
|
3
4
|
PeerDescriptor,
|
|
4
|
-
areEqualPeerDescriptors
|
|
5
|
+
areEqualPeerDescriptors,
|
|
6
|
+
getDhtAddressFromRaw,
|
|
7
|
+
getNodeIdFromPeerDescriptor
|
|
5
8
|
} from '@streamr/dht'
|
|
6
9
|
import { StreamPartID } from '@streamr/protocol'
|
|
7
10
|
import { Logger, scheduleAtInterval, wait } from '@streamr/utils'
|
|
8
11
|
import { createHash } from 'crypto'
|
|
9
|
-
import { NodeID, getNodeIdFromPeerDescriptor } from '../identifiers'
|
|
10
12
|
import { Any } from '../proto/google/protobuf/any'
|
|
11
13
|
import { Layer1Node } from './Layer1Node'
|
|
12
14
|
|
|
13
|
-
export const streamPartIdToDataKey = (streamPartId: StreamPartID):
|
|
14
|
-
return new Uint8Array(createHash('
|
|
15
|
+
export const streamPartIdToDataKey = (streamPartId: StreamPartID): DhtAddress => {
|
|
16
|
+
return getDhtAddressFromRaw(new Uint8Array((createHash('sha1').update(streamPartId).digest())))
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
const parseEntryPointData = (dataEntries: DataEntry[]): PeerDescriptor[] => {
|
|
@@ -51,16 +53,16 @@ const exponentialRunOff = async (
|
|
|
51
53
|
|
|
52
54
|
const logger = new Logger(module)
|
|
53
55
|
|
|
54
|
-
const ENTRYPOINT_STORE_LIMIT =
|
|
56
|
+
export const ENTRYPOINT_STORE_LIMIT = 8
|
|
55
57
|
export const NETWORK_SPLIT_AVOIDANCE_LIMIT = 4
|
|
56
58
|
|
|
57
59
|
interface EntryPointDiscoveryConfig {
|
|
58
60
|
streamPartId: StreamPartID
|
|
59
61
|
localPeerDescriptor: PeerDescriptor
|
|
60
62
|
layer1Node: Layer1Node
|
|
61
|
-
|
|
62
|
-
storeEntryPointData: (key:
|
|
63
|
-
deleteEntryPointData: (key:
|
|
63
|
+
fetchEntryPointData: (key: DhtAddress) => Promise<DataEntry[]>
|
|
64
|
+
storeEntryPointData: (key: DhtAddress, data: Any) => Promise<PeerDescriptor[]>
|
|
65
|
+
deleteEntryPointData: (key: DhtAddress) => Promise<void>
|
|
64
66
|
storeInterval?: number
|
|
65
67
|
}
|
|
66
68
|
|
|
@@ -68,17 +70,15 @@ export class EntryPointDiscovery {
|
|
|
68
70
|
private readonly abortController: AbortController
|
|
69
71
|
private readonly config: EntryPointDiscoveryConfig
|
|
70
72
|
private readonly storeInterval: number
|
|
71
|
-
private readonly networkSplitAvoidedNodes: Set<
|
|
72
|
-
|
|
73
|
+
private readonly networkSplitAvoidedNodes: Set<DhtAddress> = new Set()
|
|
74
|
+
private isLocalNodeStoredAsEntryPoint = false
|
|
73
75
|
constructor(config: EntryPointDiscoveryConfig) {
|
|
74
76
|
this.config = config
|
|
75
77
|
this.abortController = new AbortController()
|
|
76
78
|
this.storeInterval = this.config.storeInterval ?? 60000
|
|
77
79
|
}
|
|
78
80
|
|
|
79
|
-
async discoverEntryPointsFromDht(
|
|
80
|
-
knownEntryPointCount: number
|
|
81
|
-
): Promise<FindEntryPointsResult> {
|
|
81
|
+
async discoverEntryPointsFromDht(knownEntryPointCount: number): Promise<FindEntryPointsResult> {
|
|
82
82
|
if (knownEntryPointCount > 0) {
|
|
83
83
|
return {
|
|
84
84
|
entryPointsFromDht: false,
|
|
@@ -108,10 +108,10 @@ export class EntryPointDiscovery {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
private async queryEntrypoints(key:
|
|
111
|
+
private async queryEntrypoints(key: DhtAddress): Promise<PeerDescriptor[]> {
|
|
112
112
|
logger.trace(`Finding data from dht node ${getNodeIdFromPeerDescriptor(this.config.localPeerDescriptor)}`)
|
|
113
113
|
try {
|
|
114
|
-
const result = await this.config.
|
|
114
|
+
const result = await this.config.fetchEntryPointData(key)
|
|
115
115
|
return parseEntryPointData(result)
|
|
116
116
|
} catch (err) {
|
|
117
117
|
return []
|
|
@@ -122,12 +122,14 @@ export class EntryPointDiscovery {
|
|
|
122
122
|
if (this.abortController.signal.aborted) {
|
|
123
123
|
return
|
|
124
124
|
}
|
|
125
|
-
const possibleNetworkSplitDetected = this.config.layer1Node.
|
|
125
|
+
const possibleNetworkSplitDetected = this.config.layer1Node.getNeighborCount() < NETWORK_SPLIT_AVOIDANCE_LIMIT
|
|
126
126
|
if ((currentEntrypointCount < ENTRYPOINT_STORE_LIMIT) || possibleNetworkSplitDetected) {
|
|
127
|
+
this.isLocalNodeStoredAsEntryPoint = true
|
|
127
128
|
await this.storeSelfAsEntryPoint()
|
|
128
129
|
await this.keepSelfAsEntryPoint()
|
|
129
130
|
}
|
|
130
131
|
if (possibleNetworkSplitDetected) {
|
|
132
|
+
// TODO should we catch possible promise rejection?
|
|
131
133
|
setImmediate(() => this.avoidNetworkSplit())
|
|
132
134
|
}
|
|
133
135
|
}
|
|
@@ -161,10 +163,11 @@ export class EntryPointDiscovery {
|
|
|
161
163
|
await exponentialRunOff(async () => {
|
|
162
164
|
const rediscoveredEntrypoints = await this.discoverEntryPoints()
|
|
163
165
|
await this.config.layer1Node.joinDht(rediscoveredEntrypoints, false, false)
|
|
164
|
-
if (this.config.layer1Node
|
|
165
|
-
// Filter out nodes that are not
|
|
166
|
+
if (this.config.layer1Node.getNeighborCount() < NETWORK_SPLIT_AVOIDANCE_LIMIT) {
|
|
167
|
+
// Filter out nodes that are not neighbors as those nodes are assumed to be offline
|
|
166
168
|
const nodesToAvoid = rediscoveredEntrypoints
|
|
167
|
-
.filter((peer) => !this.config.layer1Node
|
|
169
|
+
.filter((peer) => !this.config.layer1Node.getNeighbors()
|
|
170
|
+
.some((neighbor) => areEqualPeerDescriptors(neighbor, peer)))
|
|
168
171
|
.map((peer) => getNodeIdFromPeerDescriptor(peer))
|
|
169
172
|
nodesToAvoid.forEach((node) => this.networkSplitAvoidedNodes.add(node))
|
|
170
173
|
throw new Error(`Network split is still possible`)
|
|
@@ -174,6 +177,10 @@ export class EntryPointDiscovery {
|
|
|
174
177
|
logger.trace(`Network split avoided`)
|
|
175
178
|
}
|
|
176
179
|
|
|
180
|
+
public isLocalNodeEntryPoint(): boolean {
|
|
181
|
+
return this.isLocalNodeStoredAsEntryPoint
|
|
182
|
+
}
|
|
183
|
+
|
|
177
184
|
async destroy(): Promise<void> {
|
|
178
185
|
this.abortController.abort()
|
|
179
186
|
await this.config.deleteEntryPointData(streamPartIdToDataKey(this.config.streamPartId))
|
package/src/logic/Layer0Node.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { DataEntry, ITransport, PeerDescriptor } from '@streamr/dht'
|
|
1
|
+
import { DataEntry, DhtAddress, ITransport, PeerDescriptor } from '@streamr/dht'
|
|
2
2
|
import { Any } from '../proto/google/protobuf/any'
|
|
3
3
|
|
|
4
4
|
export interface Layer0Node extends ITransport {
|
|
5
5
|
joinDht(entryPointDescriptors: PeerDescriptor[]): Promise<void>
|
|
6
6
|
hasJoined(): boolean
|
|
7
7
|
getLocalPeerDescriptor(): PeerDescriptor
|
|
8
|
-
|
|
9
|
-
storeDataToDht(key:
|
|
10
|
-
deleteDataFromDht(key:
|
|
8
|
+
fetchDataFromDht(key: DhtAddress): Promise<DataEntry[]>
|
|
9
|
+
storeDataToDht(key: DhtAddress, data: Any): Promise<PeerDescriptor[]>
|
|
10
|
+
deleteDataFromDht(key: DhtAddress, waitForCompletion: boolean): Promise<void>
|
|
11
11
|
waitForNetworkConnectivity(): Promise<void>
|
|
12
12
|
getTransport(): ITransport
|
|
13
|
+
getNeighbors(): PeerDescriptor[]
|
|
14
|
+
getConnections(): PeerDescriptor[]
|
|
13
15
|
start(): Promise<void>
|
|
14
16
|
stop(): Promise<void>
|
|
15
17
|
}
|