@streamr/node 100.0.0-rc.0
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/LICENSE +78 -0
- package/README.md +54 -0
- package/bin/broker.ts +36 -0
- package/bin/config-wizard.js +4 -0
- package/bin/config-wizard.ts +17 -0
- package/bin/delete-expired-data.ts +41 -0
- package/bin/entry-point.ts +27 -0
- package/configs/development-1.env.json +68 -0
- package/configs/development-2.env.json +53 -0
- package/configs/development-3.env.json +53 -0
- package/configs/development-prod-resend.env.json +21 -0
- package/configs/docker-1.env.json +72 -0
- package/configs/docker-2.env.json +58 -0
- package/configs/docker-3.env.json +58 -0
- package/configuration.md +38 -0
- package/dist/bin/broker.d.ts +2 -0
- package/dist/bin/broker.js +42 -0
- package/dist/bin/broker.js.map +1 -0
- package/dist/bin/config-wizard.d.ts +2 -0
- package/dist/bin/config-wizard.js +22 -0
- package/dist/bin/config-wizard.js.map +1 -0
- package/dist/bin/delete-expired-data.d.ts +2 -0
- package/dist/bin/delete-expired-data.js +44 -0
- package/dist/bin/delete-expired-data.js.map +1 -0
- package/dist/bin/entry-point.d.ts +2 -0
- package/dist/bin/entry-point.js +28 -0
- package/dist/bin/entry-point.js.map +1 -0
- package/dist/package.json +78 -0
- package/dist/src/Plugin.d.ts +33 -0
- package/dist/src/Plugin.js +43 -0
- package/dist/src/Plugin.js.map +1 -0
- package/dist/src/apiAuthentication.d.ts +4 -0
- package/dist/src/apiAuthentication.js +16 -0
- package/dist/src/apiAuthentication.js.map +1 -0
- package/dist/src/broker.d.ts +8 -0
- package/dist/src/broker.js +69 -0
- package/dist/src/broker.js.map +1 -0
- package/dist/src/config/ConfigWizard.d.ts +5 -0
- package/dist/src/config/ConfigWizard.js +466 -0
- package/dist/src/config/ConfigWizard.js.map +1 -0
- package/dist/src/config/config.d.ts +26 -0
- package/dist/src/config/config.js +92 -0
- package/dist/src/config/config.js.map +1 -0
- package/dist/src/config/config.schema.json +86 -0
- package/dist/src/config/definitions.schema.json +35 -0
- package/dist/src/config/migration.d.ts +6 -0
- package/dist/src/config/migration.js +210 -0
- package/dist/src/config/migration.js.map +1 -0
- package/dist/src/config/validateConfig.d.ts +4 -0
- package/dist/src/config/validateConfig.js +40 -0
- package/dist/src/config/validateConfig.js.map +1 -0
- package/dist/src/exports.d.ts +3 -0
- package/dist/src/exports.js +6 -0
- package/dist/src/exports.js.map +1 -0
- package/dist/src/helpers/PayloadFormat.d.ts +19 -0
- package/dist/src/helpers/PayloadFormat.js +85 -0
- package/dist/src/helpers/PayloadFormat.js.map +1 -0
- package/dist/src/helpers/applyPluginClientConfigs.d.ts +3 -0
- package/dist/src/helpers/applyPluginClientConfigs.js +29 -0
- package/dist/src/helpers/applyPluginClientConfigs.js.map +1 -0
- package/dist/src/helpers/fetchOrThrow.d.ts +2 -0
- package/dist/src/helpers/fetchOrThrow.js +20 -0
- package/dist/src/helpers/fetchOrThrow.js.map +1 -0
- package/dist/src/helpers/generateMnemonicFromAddress.d.ts +5 -0
- package/dist/src/helpers/generateMnemonicFromAddress.js +16 -0
- package/dist/src/helpers/generateMnemonicFromAddress.js.map +1 -0
- package/dist/src/helpers/multiply.d.ts +1 -0
- package/dist/src/helpers/multiply.js +10 -0
- package/dist/src/helpers/multiply.js.map +1 -0
- package/dist/src/helpers/parser.d.ts +9 -0
- package/dist/src/helpers/parser.js +62 -0
- package/dist/src/helpers/parser.js.map +1 -0
- package/dist/src/helpers/partitions.d.ts +8 -0
- package/dist/src/helpers/partitions.js +32 -0
- package/dist/src/helpers/partitions.js.map +1 -0
- package/dist/src/helpers/weightedSample.d.ts +16 -0
- package/dist/src/helpers/weightedSample.js +35 -0
- package/dist/src/helpers/weightedSample.js.map +1 -0
- package/dist/src/httpServer.d.ts +16 -0
- package/dist/src/httpServer.js +71 -0
- package/dist/src/httpServer.js.map +1 -0
- package/dist/src/pluginRegistry.d.ts +3 -0
- package/dist/src/pluginRegistry.js +35 -0
- package/dist/src/pluginRegistry.js.map +1 -0
- package/dist/src/plugins/consoleMetrics/ConsoleMetricsPlugin.d.ts +12 -0
- package/dist/src/plugins/consoleMetrics/ConsoleMetricsPlugin.js +36 -0
- package/dist/src/plugins/consoleMetrics/ConsoleMetricsPlugin.js.map +1 -0
- package/dist/src/plugins/consoleMetrics/config.schema.json +18 -0
- package/dist/src/plugins/http/HttpPlugin.d.ts +8 -0
- package/dist/src/plugins/http/HttpPlugin.js +23 -0
- package/dist/src/plugins/http/HttpPlugin.js.map +1 -0
- package/dist/src/plugins/http/config.schema.json +12 -0
- package/dist/src/plugins/http/publishEndpoint.d.ts +3 -0
- package/dist/src/plugins/http/publishEndpoint.js +72 -0
- package/dist/src/plugins/http/publishEndpoint.js.map +1 -0
- package/dist/src/plugins/info/InfoPlugin.d.ts +9 -0
- package/dist/src/plugins/info/InfoPlugin.js +31 -0
- package/dist/src/plugins/info/InfoPlugin.js.map +1 -0
- package/dist/src/plugins/info/config.schema.json +12 -0
- package/dist/src/plugins/mqtt/Bridge.d.ts +40 -0
- package/dist/src/plugins/mqtt/Bridge.js +136 -0
- package/dist/src/plugins/mqtt/Bridge.js.map +1 -0
- package/dist/src/plugins/mqtt/MqttPlugin.d.ts +14 -0
- package/dist/src/plugins/mqtt/MqttPlugin.js +30 -0
- package/dist/src/plugins/mqtt/MqttPlugin.js.map +1 -0
- package/dist/src/plugins/mqtt/MqttServer.d.ts +22 -0
- package/dist/src/plugins/mqtt/MqttServer.js +109 -0
- package/dist/src/plugins/mqtt/MqttServer.js.map +1 -0
- package/dist/src/plugins/mqtt/config.schema.json +26 -0
- package/dist/src/plugins/operator/ConsistentHashRing.d.ts +20 -0
- package/dist/src/plugins/operator/ConsistentHashRing.js +64 -0
- package/dist/src/plugins/operator/ConsistentHashRing.js.map +1 -0
- package/dist/src/plugins/operator/ContractFacade.d.ts +80 -0
- package/dist/src/plugins/operator/ContractFacade.js +364 -0
- package/dist/src/plugins/operator/ContractFacade.js.map +1 -0
- package/dist/src/plugins/operator/MaintainTopologyHelper.d.ts +23 -0
- package/dist/src/plugins/operator/MaintainTopologyHelper.js +75 -0
- package/dist/src/plugins/operator/MaintainTopologyHelper.js.map +1 -0
- package/dist/src/plugins/operator/MaintainTopologyService.d.ts +11 -0
- package/dist/src/plugins/operator/MaintainTopologyService.js +57 -0
- package/dist/src/plugins/operator/MaintainTopologyService.js.map +1 -0
- package/dist/src/plugins/operator/OperatorFleetState.d.ts +33 -0
- package/dist/src/plugins/operator/OperatorFleetState.js +112 -0
- package/dist/src/plugins/operator/OperatorFleetState.js.map +1 -0
- package/dist/src/plugins/operator/OperatorPlugin.d.ts +50 -0
- package/dist/src/plugins/operator/OperatorPlugin.js +159 -0
- package/dist/src/plugins/operator/OperatorPlugin.js.map +1 -0
- package/dist/src/plugins/operator/StreamPartAssignments.d.ts +28 -0
- package/dist/src/plugins/operator/StreamPartAssignments.js +104 -0
- package/dist/src/plugins/operator/StreamPartAssignments.js.map +1 -0
- package/dist/src/plugins/operator/announceNodeToContract.d.ts +3 -0
- package/dist/src/plugins/operator/announceNodeToContract.js +39 -0
- package/dist/src/plugins/operator/announceNodeToContract.js.map +1 -0
- package/dist/src/plugins/operator/announceNodeToStream.d.ts +3 -0
- package/dist/src/plugins/operator/announceNodeToStream.js +25 -0
- package/dist/src/plugins/operator/announceNodeToStream.js.map +1 -0
- package/dist/src/plugins/operator/checkOperatorValueBreach.d.ts +2 -0
- package/dist/src/plugins/operator/checkOperatorValueBreach.js +21 -0
- package/dist/src/plugins/operator/checkOperatorValueBreach.js.map +1 -0
- package/dist/src/plugins/operator/closeExpiredFlags.d.ts +3 -0
- package/dist/src/plugins/operator/closeExpiredFlags.js +24 -0
- package/dist/src/plugins/operator/closeExpiredFlags.js.map +1 -0
- package/dist/src/plugins/operator/config.schema.json +152 -0
- package/dist/src/plugins/operator/createIsLeaderFn.d.ts +4 -0
- package/dist/src/plugins/operator/createIsLeaderFn.js +14 -0
- package/dist/src/plugins/operator/createIsLeaderFn.js.map +1 -0
- package/dist/src/plugins/operator/fetchRedundancyFactor.d.ts +2 -0
- package/dist/src/plugins/operator/fetchRedundancyFactor.js +43 -0
- package/dist/src/plugins/operator/fetchRedundancyFactor.js.map +1 -0
- package/dist/src/plugins/operator/formCoordinationStreamId.d.ts +3 -0
- package/dist/src/plugins/operator/formCoordinationStreamId.js +9 -0
- package/dist/src/plugins/operator/formCoordinationStreamId.js.map +1 -0
- package/dist/src/plugins/operator/heartbeatUtils.d.ts +67 -0
- package/dist/src/plugins/operator/heartbeatUtils.js +26 -0
- package/dist/src/plugins/operator/heartbeatUtils.js.map +1 -0
- package/dist/src/plugins/operator/inspectOverTime.d.ts +22 -0
- package/dist/src/plugins/operator/inspectOverTime.js +146 -0
- package/dist/src/plugins/operator/inspectOverTime.js.map +1 -0
- package/dist/src/plugins/operator/inspectRandomNode.d.ts +8 -0
- package/dist/src/plugins/operator/inspectRandomNode.js +44 -0
- package/dist/src/plugins/operator/inspectRandomNode.js.map +1 -0
- package/dist/src/plugins/operator/inspectionUtils.d.ts +23 -0
- package/dist/src/plugins/operator/inspectionUtils.js +120 -0
- package/dist/src/plugins/operator/inspectionUtils.js.map +1 -0
- package/dist/src/plugins/operator/maintainOperatorValue.d.ts +2 -0
- package/dist/src/plugins/operator/maintainOperatorValue.js +21 -0
- package/dist/src/plugins/operator/maintainOperatorValue.js.map +1 -0
- package/dist/src/plugins/operator/reviewSuspectNode.d.ts +24 -0
- package/dist/src/plugins/operator/reviewSuspectNode.js +56 -0
- package/dist/src/plugins/operator/reviewSuspectNode.js.map +1 -0
- package/dist/src/plugins/storage/Batch.d.ts +51 -0
- package/dist/src/plugins/storage/Batch.js +121 -0
- package/dist/src/plugins/storage/Batch.js.map +1 -0
- package/dist/src/plugins/storage/BatchManager.d.ts +27 -0
- package/dist/src/plugins/storage/BatchManager.js +117 -0
- package/dist/src/plugins/storage/BatchManager.js.map +1 -0
- package/dist/src/plugins/storage/Bucket.d.ts +23 -0
- package/dist/src/plugins/storage/Bucket.js +90 -0
- package/dist/src/plugins/storage/Bucket.js.map +1 -0
- package/dist/src/plugins/storage/BucketManager.d.ts +56 -0
- package/dist/src/plugins/storage/BucketManager.js +306 -0
- package/dist/src/plugins/storage/BucketManager.js.map +1 -0
- package/dist/src/plugins/storage/DataQueryFormat.d.ts +10 -0
- package/dist/src/plugins/storage/DataQueryFormat.js +51 -0
- package/dist/src/plugins/storage/DataQueryFormat.js.map +1 -0
- package/dist/src/plugins/storage/DeleteExpiredCmd.d.ts +28 -0
- package/dist/src/plugins/storage/DeleteExpiredCmd.js +155 -0
- package/dist/src/plugins/storage/DeleteExpiredCmd.js.map +1 -0
- package/dist/src/plugins/storage/SetMembershipSynchronizer.d.ts +33 -0
- package/dist/src/plugins/storage/SetMembershipSynchronizer.js +102 -0
- package/dist/src/plugins/storage/SetMembershipSynchronizer.js.map +1 -0
- package/dist/src/plugins/storage/Storage.d.ts +47 -0
- package/dist/src/plugins/storage/Storage.js +459 -0
- package/dist/src/plugins/storage/Storage.js.map +1 -0
- package/dist/src/plugins/storage/StorageConfig.d.ts +43 -0
- package/dist/src/plugins/storage/StorageConfig.js +83 -0
- package/dist/src/plugins/storage/StorageConfig.js.map +1 -0
- package/dist/src/plugins/storage/StorageEventListener.d.ts +17 -0
- package/dist/src/plugins/storage/StorageEventListener.js +46 -0
- package/dist/src/plugins/storage/StorageEventListener.js.map +1 -0
- package/dist/src/plugins/storage/StoragePlugin.d.ts +32 -0
- package/dist/src/plugins/storage/StoragePlugin.js +103 -0
- package/dist/src/plugins/storage/StoragePlugin.js.map +1 -0
- package/dist/src/plugins/storage/StoragePoller.d.ts +15 -0
- package/dist/src/plugins/storage/StoragePoller.js +47 -0
- package/dist/src/plugins/storage/StoragePoller.js.map +1 -0
- package/dist/src/plugins/storage/config.schema.json +88 -0
- package/dist/src/plugins/storage/dataMetadataEndpoint.d.ts +3 -0
- package/dist/src/plugins/storage/dataMetadataEndpoint.js +35 -0
- package/dist/src/plugins/storage/dataMetadataEndpoint.js.map +1 -0
- package/dist/src/plugins/storage/dataQueryEndpoint.d.ts +6 -0
- package/dist/src/plugins/storage/dataQueryEndpoint.js +181 -0
- package/dist/src/plugins/storage/dataQueryEndpoint.js.map +1 -0
- package/dist/src/plugins/storage/storageConfigEndpoint.d.ts +3 -0
- package/dist/src/plugins/storage/storageConfigEndpoint.js +31 -0
- package/dist/src/plugins/storage/storageConfigEndpoint.js.map +1 -0
- package/dist/src/plugins/subscriber/SubscriberPlugin.d.ts +16 -0
- package/dist/src/plugins/subscriber/SubscriberPlugin.js +22 -0
- package/dist/src/plugins/subscriber/SubscriberPlugin.js.map +1 -0
- package/dist/src/plugins/subscriber/config.schema.json +31 -0
- package/dist/src/plugins/websocket/Connection.d.ts +9 -0
- package/dist/src/plugins/websocket/Connection.js +45 -0
- package/dist/src/plugins/websocket/Connection.js.map +1 -0
- package/dist/src/plugins/websocket/PublishConnection.d.ts +12 -0
- package/dist/src/plugins/websocket/PublishConnection.js +46 -0
- package/dist/src/plugins/websocket/PublishConnection.js.map +1 -0
- package/dist/src/plugins/websocket/SubscribeConnection.d.ts +13 -0
- package/dist/src/plugins/websocket/SubscribeConnection.js +50 -0
- package/dist/src/plugins/websocket/SubscribeConnection.js.map +1 -0
- package/dist/src/plugins/websocket/WebsocketPlugin.d.ts +19 -0
- package/dist/src/plugins/websocket/WebsocketPlugin.js +26 -0
- package/dist/src/plugins/websocket/WebsocketPlugin.js.map +1 -0
- package/dist/src/plugins/websocket/WebsocketServer.d.ts +16 -0
- package/dist/src/plugins/websocket/WebsocketServer.js +132 -0
- package/dist/src/plugins/websocket/WebsocketServer.js.map +1 -0
- package/dist/src/plugins/websocket/config.schema.json +51 -0
- package/package.json +78 -0
- package/plugins.md +318 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ContractFacade = exports.parsePartitionFromReviewRequestMetadata = exports.ParseError = exports.VOTE_NO_KICK = exports.VOTE_KICK = void 0;
|
|
7
|
+
const network_contracts_1 = require("@streamr/network-contracts");
|
|
8
|
+
const protocol_1 = require("@streamr/protocol");
|
|
9
|
+
const utils_1 = require("@streamr/utils");
|
|
10
|
+
const ethers_1 = require("ethers");
|
|
11
|
+
const sample_1 = __importDefault(require("lodash/sample"));
|
|
12
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
13
|
+
exports.VOTE_KICK = '0x0000000000000000000000000000000000000000000000000000000000000001';
|
|
14
|
+
exports.VOTE_NO_KICK = '0x0000000000000000000000000000000000000000000000000000000000000000';
|
|
15
|
+
class ParseError extends Error {
|
|
16
|
+
reasonText;
|
|
17
|
+
constructor(reasonText) {
|
|
18
|
+
super(`Failed to parse metadata: ${reasonText}`);
|
|
19
|
+
this.reasonText = reasonText;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.ParseError = ParseError;
|
|
23
|
+
function parsePartitionFromReviewRequestMetadata(metadataAsString) {
|
|
24
|
+
if (metadataAsString === undefined) {
|
|
25
|
+
throw new ParseError('no metadata');
|
|
26
|
+
}
|
|
27
|
+
let metadata;
|
|
28
|
+
try {
|
|
29
|
+
metadata = JSON.parse(metadataAsString);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
throw new ParseError('malformed metadata');
|
|
33
|
+
}
|
|
34
|
+
const partition = Number(metadata.partition);
|
|
35
|
+
if (isNaN(partition)) {
|
|
36
|
+
throw new ParseError('invalid or missing "partition" field');
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
(0, protocol_1.ensureValidStreamPartitionIndex)(partition);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
throw new ParseError('invalid partition numbering');
|
|
43
|
+
}
|
|
44
|
+
return partition;
|
|
45
|
+
}
|
|
46
|
+
exports.parsePartitionFromReviewRequestMetadata = parsePartitionFromReviewRequestMetadata;
|
|
47
|
+
const logger = new utils_1.Logger(module);
|
|
48
|
+
class ContractFacade {
|
|
49
|
+
operatorContract;
|
|
50
|
+
theGraphClient;
|
|
51
|
+
config;
|
|
52
|
+
// for tests
|
|
53
|
+
constructor(operatorContract, theGraphClient, config) {
|
|
54
|
+
this.operatorContract = operatorContract;
|
|
55
|
+
this.theGraphClient = theGraphClient;
|
|
56
|
+
this.config = config;
|
|
57
|
+
}
|
|
58
|
+
static createInstance(config) {
|
|
59
|
+
return new ContractFacade(new ethers_1.Contract(config.operatorContractAddress, network_contracts_1.operatorABI, config.signer), new utils_1.TheGraphClient({
|
|
60
|
+
serverUrl: config.theGraphUrl,
|
|
61
|
+
fetch: node_fetch_1.default,
|
|
62
|
+
logger
|
|
63
|
+
}), config);
|
|
64
|
+
}
|
|
65
|
+
async writeHeartbeat(nodeDescriptor) {
|
|
66
|
+
const metadata = JSON.stringify(nodeDescriptor);
|
|
67
|
+
await (await this.operatorContract.heartbeat(metadata, this.getEthersOverrides())).wait();
|
|
68
|
+
}
|
|
69
|
+
async getTimestampOfLastHeartbeat() {
|
|
70
|
+
const result = await this.theGraphClient.queryEntity({
|
|
71
|
+
query: `{
|
|
72
|
+
operator(id: "${this.getOperatorContractAddress()}") {
|
|
73
|
+
latestHeartbeatTimestamp
|
|
74
|
+
}
|
|
75
|
+
}`
|
|
76
|
+
});
|
|
77
|
+
if (result.operator === null || result.operator.latestHeartbeatTimestamp === null) {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const timestampInSecs = parseInt(result.operator.latestHeartbeatTimestamp);
|
|
82
|
+
if (isNaN(timestampInSecs)) {
|
|
83
|
+
throw new Error('Assertion failed: unexpected non-integer latestHeartbeatTimestamp'); // should never happen
|
|
84
|
+
}
|
|
85
|
+
return timestampInSecs * 1000;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
getOperatorContractAddress() {
|
|
89
|
+
return (0, utils_1.toEthereumAddress)(this.operatorContract.address);
|
|
90
|
+
}
|
|
91
|
+
async getSponsorshipsOfOperator(operatorAddress) {
|
|
92
|
+
const createQuery = (lastId, pageSize) => {
|
|
93
|
+
return {
|
|
94
|
+
query: `
|
|
95
|
+
{
|
|
96
|
+
operator(id: "${operatorAddress}") {
|
|
97
|
+
stakes(where: {id_gt: "${lastId}"}, first: ${pageSize}) {
|
|
98
|
+
id
|
|
99
|
+
sponsorship {
|
|
100
|
+
id
|
|
101
|
+
operatorCount
|
|
102
|
+
stream {
|
|
103
|
+
id
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
`
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
const parseItems = (response) => {
|
|
113
|
+
return response.operator?.stakes ?? [];
|
|
114
|
+
};
|
|
115
|
+
const queryResult = this.theGraphClient.queryEntities(createQuery, parseItems);
|
|
116
|
+
const results = [];
|
|
117
|
+
for await (const stake of queryResult) {
|
|
118
|
+
results.push({
|
|
119
|
+
sponsorshipAddress: (0, utils_1.toEthereumAddress)(stake.sponsorship.id),
|
|
120
|
+
streamId: (0, protocol_1.toStreamID)(stake.sponsorship.stream.id),
|
|
121
|
+
operatorCount: stake.sponsorship.operatorCount
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return results;
|
|
125
|
+
}
|
|
126
|
+
async getExpiredFlags(sponsorships, maxAgeInMs) {
|
|
127
|
+
const maxFlagStartTime = Math.floor((Date.now() - maxAgeInMs) / 1000);
|
|
128
|
+
const createQuery = (lastId, pageSize) => {
|
|
129
|
+
return {
|
|
130
|
+
query: `
|
|
131
|
+
{
|
|
132
|
+
flags (where : {
|
|
133
|
+
id_gt: "${lastId}",
|
|
134
|
+
flaggingTimestamp_lt: ${maxFlagStartTime},
|
|
135
|
+
result_in: ["waiting", "voting"],
|
|
136
|
+
sponsorship_in: ${JSON.stringify(sponsorships)}
|
|
137
|
+
}, first: ${pageSize}) {
|
|
138
|
+
id
|
|
139
|
+
flaggingTimestamp
|
|
140
|
+
target {
|
|
141
|
+
id
|
|
142
|
+
}
|
|
143
|
+
sponsorship {
|
|
144
|
+
id
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}`
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
const flagEntities = this.theGraphClient.queryEntities(createQuery);
|
|
151
|
+
const flags = [];
|
|
152
|
+
for await (const flag of flagEntities) {
|
|
153
|
+
flags.push(flag);
|
|
154
|
+
}
|
|
155
|
+
return flags;
|
|
156
|
+
}
|
|
157
|
+
async getOperatorsInSponsorship(sponsorshipAddress) {
|
|
158
|
+
const createQuery = (lastId, pageSize) => {
|
|
159
|
+
return {
|
|
160
|
+
query: `
|
|
161
|
+
{
|
|
162
|
+
sponsorship(id: "${sponsorshipAddress}") {
|
|
163
|
+
stakes(where: {id_gt: "${lastId}"}, first: ${pageSize}) {
|
|
164
|
+
id
|
|
165
|
+
operator {
|
|
166
|
+
id
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
`
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
const parseItems = (response) => {
|
|
175
|
+
return response.sponsorship?.stakes ?? [];
|
|
176
|
+
};
|
|
177
|
+
const queryResult = this.theGraphClient.queryEntities(createQuery, parseItems);
|
|
178
|
+
const operatorIds = [];
|
|
179
|
+
for await (const stake of queryResult) {
|
|
180
|
+
operatorIds.push((0, utils_1.toEthereumAddress)(stake.operator.id));
|
|
181
|
+
}
|
|
182
|
+
return operatorIds;
|
|
183
|
+
}
|
|
184
|
+
async flag(sponsorship, operator, partition) {
|
|
185
|
+
const metadata = JSON.stringify({ partition });
|
|
186
|
+
await (await this.operatorContract.flag(sponsorship, operator, metadata, this.getEthersOverrides())).wait();
|
|
187
|
+
}
|
|
188
|
+
async getRandomOperator() {
|
|
189
|
+
const latestBlock = await this.operatorContract.provider.getBlockNumber();
|
|
190
|
+
const operators = await this.getOperatorAddresses(latestBlock);
|
|
191
|
+
const excluded = this.getOperatorContractAddress();
|
|
192
|
+
const operatorAddresses = operators.filter((id) => id !== excluded);
|
|
193
|
+
logger.debug(`Found ${operatorAddresses.length} operators`);
|
|
194
|
+
return (0, sample_1.default)(operatorAddresses);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Find the sum of earnings in Sponsorships (that the Operator must withdraw before the sum reaches a limit),
|
|
198
|
+
* SUBJECT TO the constraints, set in the OperatorServiceConfig:
|
|
199
|
+
* - only take at most maxSponsorshipsInWithdraw addresses (those with most earnings), or all if undefined
|
|
200
|
+
* - only take sponsorships that have more than minSponsorshipEarningsInWithdraw, or all if undefined
|
|
201
|
+
*/
|
|
202
|
+
async getEarningsOf(operatorContractAddress, minSponsorshipEarningsInWithdraw, maxSponsorshipsInWithdraw) {
|
|
203
|
+
const operator = new ethers_1.Contract(operatorContractAddress, network_contracts_1.operatorABI, this.config.signer);
|
|
204
|
+
const minSponsorshipEarningsInWithdrawWei = BigInt(minSponsorshipEarningsInWithdraw ?? 0);
|
|
205
|
+
const { addresses: allSponsorshipAddresses, earnings, maxAllowedEarnings, } = await operator.getSponsorshipsAndEarnings();
|
|
206
|
+
const sponsorships = allSponsorshipAddresses
|
|
207
|
+
.map((address, i) => ({ address, earnings: earnings[i].toBigInt() }))
|
|
208
|
+
.filter((sponsorship) => sponsorship.earnings >= minSponsorshipEarningsInWithdrawWei)
|
|
209
|
+
.sort((a, b) => Number(b.earnings - a.earnings)) // TODO: after Node 20, use .toSorted() instead
|
|
210
|
+
.slice(0, maxSponsorshipsInWithdraw); // take all if maxSponsorshipsInWithdraw is undefined
|
|
211
|
+
return {
|
|
212
|
+
sponsorshipAddresses: sponsorships.map((sponsorship) => (0, utils_1.toEthereumAddress)(sponsorship.address)),
|
|
213
|
+
sumDataWei: sponsorships.reduce((sum, sponsorship) => sum += sponsorship.earnings, 0n),
|
|
214
|
+
maxAllowedEarningsDataWei: maxAllowedEarnings.toBigInt()
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
async getMyEarnings(minSponsorshipEarningsInWithdraw, maxSponsorshipsInWithdraw) {
|
|
218
|
+
return this.getEarningsOf(this.getOperatorContractAddress(), minSponsorshipEarningsInWithdraw, maxSponsorshipsInWithdraw);
|
|
219
|
+
}
|
|
220
|
+
async withdrawMyEarningsFromSponsorships(sponsorshipAddresses) {
|
|
221
|
+
await (await this.operatorContract.withdrawEarningsFromSponsorships(sponsorshipAddresses, this.getEthersOverrides())).wait();
|
|
222
|
+
}
|
|
223
|
+
async triggerWithdraw(targetOperatorAddress, sponsorshipAddresses) {
|
|
224
|
+
await (await this.operatorContract.triggerAnotherOperatorWithdraw(targetOperatorAddress, sponsorshipAddresses, this.getEthersOverrides())).wait();
|
|
225
|
+
}
|
|
226
|
+
async getOperatorAddresses(requiredBlockNumber) {
|
|
227
|
+
// TODO: use pagination or find a clever efficient way of selecting a random operator (NET-1113)
|
|
228
|
+
const createQuery = () => {
|
|
229
|
+
return {
|
|
230
|
+
query: `
|
|
231
|
+
{
|
|
232
|
+
operators(first: 1000) {
|
|
233
|
+
id
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
`
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
this.theGraphClient.updateRequiredBlockNumber(requiredBlockNumber);
|
|
240
|
+
const queryResult = this.theGraphClient.queryEntities(createQuery);
|
|
241
|
+
const operatorAddresses = [];
|
|
242
|
+
for await (const operator of queryResult) {
|
|
243
|
+
operatorAddresses.push((0, utils_1.toEthereumAddress)(operator.id));
|
|
244
|
+
}
|
|
245
|
+
return operatorAddresses;
|
|
246
|
+
}
|
|
247
|
+
pullStakedStreams(requiredBlockNumber) {
|
|
248
|
+
const createQuery = (lastId, pageSize) => {
|
|
249
|
+
return {
|
|
250
|
+
query: `
|
|
251
|
+
{
|
|
252
|
+
operator(id: "${this.getOperatorContractAddress()}") {
|
|
253
|
+
stakes(where: {id_gt: "${lastId}"}, first: ${pageSize}) {
|
|
254
|
+
sponsorship {
|
|
255
|
+
id
|
|
256
|
+
stream {
|
|
257
|
+
id
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
_meta {
|
|
263
|
+
block {
|
|
264
|
+
number
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
`
|
|
269
|
+
};
|
|
270
|
+
};
|
|
271
|
+
const parseItems = (response) => {
|
|
272
|
+
if (!response.operator) {
|
|
273
|
+
logger.error('Unable to find operator in The Graph', { operatorContractAddress: this.operatorContract.address });
|
|
274
|
+
return [];
|
|
275
|
+
}
|
|
276
|
+
return response.operator.stakes;
|
|
277
|
+
};
|
|
278
|
+
this.theGraphClient.updateRequiredBlockNumber(requiredBlockNumber);
|
|
279
|
+
return this.theGraphClient.queryEntities(createQuery, parseItems);
|
|
280
|
+
}
|
|
281
|
+
async hasOpenFlag(operatorAddress, sponsorshipAddress) {
|
|
282
|
+
const createQuery = () => {
|
|
283
|
+
return {
|
|
284
|
+
query: `
|
|
285
|
+
{
|
|
286
|
+
flags(where: {
|
|
287
|
+
sponsorship: "${sponsorshipAddress}",
|
|
288
|
+
target: "${operatorAddress}",
|
|
289
|
+
result_in: ["waiting", "voting"]
|
|
290
|
+
}) {
|
|
291
|
+
id
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
`
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
const queryResult = this.theGraphClient.queryEntities(createQuery);
|
|
298
|
+
const flags = await (0, utils_1.collect)(queryResult, 1);
|
|
299
|
+
if (flags.length > 0) {
|
|
300
|
+
logger.debug('Found open flag', { flag: flags[0] });
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
addReviewRequestListener(listener, abortSignal) {
|
|
308
|
+
(0, utils_1.addManagedEventListener)(this.operatorContract, 'ReviewRequest', (sponsorship, targetOperator, voteStartTimestampInSecs, voteEndTimestampInSecs, metadataAsString) => {
|
|
309
|
+
let partition;
|
|
310
|
+
try {
|
|
311
|
+
partition = parsePartitionFromReviewRequestMetadata(metadataAsString);
|
|
312
|
+
}
|
|
313
|
+
catch (err) {
|
|
314
|
+
if (err instanceof ParseError) {
|
|
315
|
+
logger.warn(`Skip review request (${err.reasonText})`, {
|
|
316
|
+
address: this.operatorContract.address,
|
|
317
|
+
sponsorship,
|
|
318
|
+
targetOperator,
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
logger.warn('Encountered unexpected error', { err });
|
|
323
|
+
}
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
logger.debug('Receive review request', {
|
|
327
|
+
address: this.operatorContract.address,
|
|
328
|
+
sponsorship,
|
|
329
|
+
targetOperator,
|
|
330
|
+
partition
|
|
331
|
+
});
|
|
332
|
+
listener((0, utils_1.toEthereumAddress)(sponsorship), (0, utils_1.toEthereumAddress)(targetOperator), partition, voteStartTimestampInSecs * 1000, voteEndTimestampInSecs * 1000);
|
|
333
|
+
}, abortSignal);
|
|
334
|
+
}
|
|
335
|
+
async getStreamId(sponsorshipAddress) {
|
|
336
|
+
const sponsorship = new ethers_1.Contract(sponsorshipAddress, network_contracts_1.sponsorshipABI, this.config.signer);
|
|
337
|
+
return (0, protocol_1.toStreamID)(await sponsorship.streamId());
|
|
338
|
+
}
|
|
339
|
+
async voteOnFlag(sponsorship, targetOperator, kick) {
|
|
340
|
+
const voteData = kick ? exports.VOTE_KICK : exports.VOTE_NO_KICK;
|
|
341
|
+
// typical gas cost 99336, but this has shown insufficient sometimes
|
|
342
|
+
// TODO should we set gasLimit only here, or also for other transactions made by ContractFacade?
|
|
343
|
+
await (await this.operatorContract.voteOnFlag(sponsorship, targetOperator, voteData, { ...this.getEthersOverrides(), gasLimit: '1000000' })).wait();
|
|
344
|
+
}
|
|
345
|
+
async closeFlag(sponsorship, targetOperator) {
|
|
346
|
+
// voteOnFlag is not used to vote here but to close the expired flag. The vote data gets ignored.
|
|
347
|
+
// Anyone can call this function at this point.
|
|
348
|
+
await this.voteOnFlag(sponsorship, targetOperator, false);
|
|
349
|
+
}
|
|
350
|
+
addOperatorContractStakeEventListener(eventName, listener) {
|
|
351
|
+
this.operatorContract.on(eventName, listener);
|
|
352
|
+
}
|
|
353
|
+
removeOperatorContractStakeEventListener(eventName, listener) {
|
|
354
|
+
this.operatorContract.off(eventName, listener);
|
|
355
|
+
}
|
|
356
|
+
getProvider() {
|
|
357
|
+
return this.config.signer.provider;
|
|
358
|
+
}
|
|
359
|
+
getEthersOverrides() {
|
|
360
|
+
return this.config.getEthersOverrides();
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
exports.ContractFacade = ContractFacade;
|
|
364
|
+
//# sourceMappingURL=ContractFacade.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContractFacade.js","sourceRoot":"","sources":["../../../../src/plugins/operator/ContractFacade.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { StreamID } from '@streamr/protocol';
|
|
2
|
+
import { EventEmitter } from 'eventemitter3';
|
|
3
|
+
import { ContractFacade } from './ContractFacade';
|
|
4
|
+
export interface MaintainTopologyHelperEvents {
|
|
5
|
+
/**
|
|
6
|
+
* Emitted when staking into a Sponsorship on a stream that we haven't staked on before (in another Sponsorship)
|
|
7
|
+
*/
|
|
8
|
+
addStakedStreams: (streamIds: StreamID[]) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Emitted when un-staked from all Sponsorships for the given stream
|
|
11
|
+
*/
|
|
12
|
+
removeStakedStream: (streamId: StreamID) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare class MaintainTopologyHelper extends EventEmitter<MaintainTopologyHelperEvents> {
|
|
15
|
+
private readonly streamIdOfSponsorship;
|
|
16
|
+
private readonly sponsorshipCountOfStream;
|
|
17
|
+
private onStakedListener?;
|
|
18
|
+
private onUnstakedListener?;
|
|
19
|
+
private readonly contractFacade;
|
|
20
|
+
constructor(contractFacade: ContractFacade);
|
|
21
|
+
start(): Promise<void>;
|
|
22
|
+
stop(): void;
|
|
23
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MaintainTopologyHelper = void 0;
|
|
4
|
+
const protocol_1 = require("@streamr/protocol");
|
|
5
|
+
const utils_1 = require("@streamr/utils");
|
|
6
|
+
const eventemitter3_1 = require("eventemitter3");
|
|
7
|
+
const logger = new utils_1.Logger(module);
|
|
8
|
+
class MaintainTopologyHelper extends eventemitter3_1.EventEmitter {
|
|
9
|
+
streamIdOfSponsorship = new Map();
|
|
10
|
+
sponsorshipCountOfStream = new Map();
|
|
11
|
+
onStakedListener;
|
|
12
|
+
onUnstakedListener;
|
|
13
|
+
contractFacade;
|
|
14
|
+
constructor(contractFacade) {
|
|
15
|
+
super();
|
|
16
|
+
this.contractFacade = contractFacade;
|
|
17
|
+
}
|
|
18
|
+
async start() {
|
|
19
|
+
const latestBlock = await this.contractFacade.getProvider().getBlockNumber();
|
|
20
|
+
this.onStakedListener = async (sponsorship) => {
|
|
21
|
+
logger.info('Receive "Staked" event', { sponsorship });
|
|
22
|
+
const sponsorshipAddress = (0, utils_1.toEthereumAddress)(sponsorship);
|
|
23
|
+
const streamId = await this.contractFacade.getStreamId(sponsorshipAddress); // TODO: add catching here
|
|
24
|
+
if (this.streamIdOfSponsorship.has(sponsorshipAddress)) {
|
|
25
|
+
logger.debug('Ignore already staked into sponsorship', { sponsorship });
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
this.streamIdOfSponsorship.set(sponsorshipAddress, streamId);
|
|
29
|
+
const sponsorshipCount = (this.sponsorshipCountOfStream.get(streamId) ?? 0) + 1;
|
|
30
|
+
this.sponsorshipCountOfStream.set(streamId, sponsorshipCount);
|
|
31
|
+
if (sponsorshipCount === 1) {
|
|
32
|
+
this.emit('addStakedStreams', [streamId]);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
this.contractFacade.addOperatorContractStakeEventListener('Staked', this.onStakedListener);
|
|
36
|
+
this.onUnstakedListener = (sponsorship) => {
|
|
37
|
+
logger.info('Receive "Unstaked" event', { sponsorship });
|
|
38
|
+
const sponsorshipAddress = (0, utils_1.toEthereumAddress)(sponsorship);
|
|
39
|
+
const streamId = this.streamIdOfSponsorship.get(sponsorshipAddress);
|
|
40
|
+
if (streamId === undefined) {
|
|
41
|
+
logger.debug('Unable to find streamId for sponsorship', { sponsorshipAddress });
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.streamIdOfSponsorship.delete(sponsorshipAddress);
|
|
45
|
+
const sponsorshipCount = this.sponsorshipCountOfStream.get(streamId) - 1;
|
|
46
|
+
this.sponsorshipCountOfStream.set(streamId, sponsorshipCount);
|
|
47
|
+
if (sponsorshipCount === 0) {
|
|
48
|
+
this.sponsorshipCountOfStream.delete(streamId);
|
|
49
|
+
this.emit('removeStakedStream', streamId);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
this.contractFacade.addOperatorContractStakeEventListener('Unstaked', this.onUnstakedListener);
|
|
53
|
+
const queryResult = this.contractFacade.pullStakedStreams(latestBlock);
|
|
54
|
+
for await (const stake of queryResult) {
|
|
55
|
+
const sponsorshipId = (0, utils_1.toEthereumAddress)(stake.sponsorship.id);
|
|
56
|
+
const streamId = (0, protocol_1.toStreamID)(stake.sponsorship.stream.id);
|
|
57
|
+
if (this.streamIdOfSponsorship.get(sponsorshipId) !== streamId) {
|
|
58
|
+
this.streamIdOfSponsorship.set(sponsorshipId, streamId);
|
|
59
|
+
const sponsorshipCount = (this.sponsorshipCountOfStream.get(streamId) || 0) + 1;
|
|
60
|
+
this.sponsorshipCountOfStream.set(streamId, sponsorshipCount);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (this.sponsorshipCountOfStream.size > 0) {
|
|
64
|
+
const initialStreams = Array.from(this.sponsorshipCountOfStream.keys());
|
|
65
|
+
this.emit('addStakedStreams', initialStreams);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
stop() {
|
|
69
|
+
this.contractFacade.removeOperatorContractStakeEventListener('Staked', this.onStakedListener);
|
|
70
|
+
this.contractFacade.removeOperatorContractStakeEventListener('Unstaked', this.onUnstakedListener);
|
|
71
|
+
this.removeAllListeners();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.MaintainTopologyHelper = MaintainTopologyHelper;
|
|
75
|
+
//# sourceMappingURL=MaintainTopologyHelper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MaintainTopologyHelper.js","sourceRoot":"","sources":["../../../../src/plugins/operator/MaintainTopologyHelper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { StreamrClient } from '@streamr/sdk';
|
|
2
|
+
import { StreamPartAssignments } from './StreamPartAssignments';
|
|
3
|
+
export declare class MaintainTopologyService {
|
|
4
|
+
private readonly streamrClient;
|
|
5
|
+
private readonly subscriptions;
|
|
6
|
+
private readonly concurrencyLimit;
|
|
7
|
+
constructor(streamrClient: StreamrClient, assignments: StreamPartAssignments);
|
|
8
|
+
private onAddStakedStreamPart;
|
|
9
|
+
private onRemoveStakedStreamPart;
|
|
10
|
+
private concurrencyLimiter;
|
|
11
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MaintainTopologyService = void 0;
|
|
7
|
+
const utils_1 = require("@streamr/utils");
|
|
8
|
+
const protocol_1 = require("@streamr/protocol");
|
|
9
|
+
const p_limit_1 = __importDefault(require("p-limit"));
|
|
10
|
+
const logger = new utils_1.Logger(module);
|
|
11
|
+
class MaintainTopologyService {
|
|
12
|
+
streamrClient;
|
|
13
|
+
subscriptions = new Map();
|
|
14
|
+
concurrencyLimit = (0, p_limit_1.default)(1);
|
|
15
|
+
constructor(streamrClient, assignments) {
|
|
16
|
+
this.streamrClient = streamrClient;
|
|
17
|
+
assignments.on('assigned', this.onAddStakedStreamPart);
|
|
18
|
+
assignments.on('unassigned', this.onRemoveStakedStreamPart);
|
|
19
|
+
}
|
|
20
|
+
onAddStakedStreamPart = this.concurrencyLimiter(async (streamPartId) => {
|
|
21
|
+
const [id, partition] = protocol_1.StreamPartIDUtils.getStreamIDAndPartition(streamPartId);
|
|
22
|
+
let subscription;
|
|
23
|
+
try {
|
|
24
|
+
logger.info('Join stream partition', { streamPartId });
|
|
25
|
+
subscription = await this.streamrClient.subscribe({
|
|
26
|
+
id,
|
|
27
|
+
partition,
|
|
28
|
+
raw: true
|
|
29
|
+
}, () => { });
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
logger.warn('Failed to join stream partition', { streamPartId, reason: err?.reason });
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this.subscriptions.set(streamPartId, subscription);
|
|
36
|
+
});
|
|
37
|
+
onRemoveStakedStreamPart = this.concurrencyLimiter(async (streamPartId) => {
|
|
38
|
+
const subscription = this.subscriptions.get(streamPartId);
|
|
39
|
+
this.subscriptions.delete(streamPartId);
|
|
40
|
+
try {
|
|
41
|
+
logger.info('Leave stream partition', { streamPartId });
|
|
42
|
+
await subscription?.unsubscribe();
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
logger.warn('Failed to leave stream partition', { streamPartId, reason: err?.reason });
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
concurrencyLimiter(fn) {
|
|
49
|
+
return (streamPartId) => {
|
|
50
|
+
this.concurrencyLimit(() => fn(streamPartId)).catch((err) => {
|
|
51
|
+
logger.warn('Encountered error while processing event', { err });
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.MaintainTopologyService = MaintainTopologyService;
|
|
57
|
+
//# sourceMappingURL=MaintainTopologyService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MaintainTopologyService.js","sourceRoot":"","sources":["../../../../src/plugins/operator/MaintainTopologyService.ts"],"names":[],"mappings":";;;;;;AAAA,0CAAuC;AAEvC,gDAAmE;AACnE,sDAA4B;AAG5B,MAAM,MAAM,GAAG,IAAI,cAAM,CAAC,MAAM,CAAC,CAAA;AAEjC,MAAa,uBAAuB;IACf,aAAa,CAAe;IAC5B,aAAa,GAAG,IAAI,GAAG,EAA8B,CAAA;IACrD,gBAAgB,GAAG,IAAA,iBAAM,EAAC,CAAC,CAAC,CAAA;IAE7C,YAAY,aAA4B,EAAE,WAAkC;QACxE,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;QAClC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAA;QACtD,WAAW,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,wBAAwB,CAAC,CAAA;IAC/D,CAAC;IAEO,qBAAqB,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,YAA0B,EAAiB,EAAE;QACxG,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC,GAAG,4BAAiB,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAA;QAC/E,IAAI,YAA0B,CAAA;QAC9B,IAAI,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,YAAY,EAAE,CAAC,CAAA;YACtD,YAAY,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC;gBAC9C,EAAE;gBACF,SAAS;gBACT,GAAG,EAAE,IAAI;aACZ,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,iCAAiC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAA;YACrF,OAAM;QACV,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEM,wBAAwB,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,YAA0B,EAAiB,EAAE;QAC3G,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QACzD,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;QACvC,IAAI,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,YAAY,EAAE,CAAC,CAAA;YACvD,MAAM,YAAY,EAAE,WAAW,EAAE,CAAA;QACrC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAA;QAC1F,CAAC;IACL,CAAC,CAAC,CAAA;IAEM,kBAAkB,CACtB,EAAiD;QAEjD,OAAO,CAAC,YAAY,EAAE,EAAE;YACpB,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACxD,MAAM,CAAC,IAAI,CAAC,0CAA0C,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;YACpE,CAAC,CAAC,CAAA;QACN,CAAC,CAAA;IACL,CAAC;CACJ;AAhDD,0DAgDC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { DhtAddress } from '@streamr/dht';
|
|
2
|
+
import { StreamID } from '@streamr/protocol';
|
|
3
|
+
import { EventEmitter } from 'eventemitter3';
|
|
4
|
+
import { NetworkPeerDescriptor, StreamrClient } from '@streamr/sdk';
|
|
5
|
+
export interface OperatorFleetStateEvents {
|
|
6
|
+
added: (nodeId: DhtAddress) => void;
|
|
7
|
+
removed: (nodeId: DhtAddress) => void;
|
|
8
|
+
}
|
|
9
|
+
export type CreateOperatorFleetStateFn = (coordinationStreamId: StreamID) => OperatorFleetState;
|
|
10
|
+
export declare class OperatorFleetState extends EventEmitter<OperatorFleetStateEvents> {
|
|
11
|
+
private readonly streamrClient;
|
|
12
|
+
private readonly coordinationStreamId;
|
|
13
|
+
private readonly timeProvider;
|
|
14
|
+
private readonly pruneAgeInMs;
|
|
15
|
+
private readonly pruneIntervalInMs;
|
|
16
|
+
private readonly heartbeatIntervalInMs;
|
|
17
|
+
private readonly latencyExtraInMs;
|
|
18
|
+
private readonly warmupPeriodInMs;
|
|
19
|
+
private readonly latestHeartbeats;
|
|
20
|
+
private readonly abortController;
|
|
21
|
+
private readonly ready;
|
|
22
|
+
private subscription?;
|
|
23
|
+
static createOperatorFleetStateBuilder(streamrClient: StreamrClient, heartbeatIntervalInMs: number, pruneAgeInMs: number, pruneIntervalInMs: number, latencyExtraInMs: number, warmupPeriodInMs: number, timeProvider?: () => number): CreateOperatorFleetStateFn;
|
|
24
|
+
private constructor();
|
|
25
|
+
start(): Promise<void>;
|
|
26
|
+
waitUntilReady(): Promise<void>;
|
|
27
|
+
destroy(): Promise<void>;
|
|
28
|
+
getLeaderNodeId(): DhtAddress | undefined;
|
|
29
|
+
getNodeIds(): DhtAddress[];
|
|
30
|
+
getPeerDescriptor(nodeId: DhtAddress): NetworkPeerDescriptor | undefined;
|
|
31
|
+
private launchOpenReadyGateTimer;
|
|
32
|
+
private pruneOfflineNodes;
|
|
33
|
+
}
|