@railgun-community/waku-broadcaster-client-node 9.0.5 → 9.1.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/README.md +1 -2
- package/dist/models/broadcaster-config.d.ts +23 -0
- package/dist/models/broadcaster-config.js +78 -1
- package/dist/models/broadcaster-config.js.map +1 -1
- package/dist/models/constants.d.ts +16 -2
- package/dist/models/constants.js +30 -8
- package/dist/models/constants.js.map +1 -1
- package/dist/models/export-models.d.ts +6 -0
- package/dist/models/export-models.js.map +1 -1
- package/dist/waku/waku-broadcaster-peer-discovery-core-base.d.ts +54 -0
- package/dist/waku/waku-broadcaster-peer-discovery-core-base.js +223 -0
- package/dist/waku/waku-broadcaster-peer-discovery-core-base.js.map +1 -0
- package/dist/waku/waku-broadcaster-waku-core-base.d.ts +37 -6
- package/dist/waku/waku-broadcaster-waku-core-base.js +35 -10
- package/dist/waku/waku-broadcaster-waku-core-base.js.map +1 -1
- package/dist/waku/waku-broadcaster-waku-core.d.ts +14 -3
- package/dist/waku/waku-broadcaster-waku-core.js +42 -42
- package/dist/waku/waku-broadcaster-waku-core.js.map +1 -1
- package/dist/waku/waku-healthcheck.d.ts +62 -0
- package/dist/waku/waku-healthcheck.js +88 -0
- package/dist/waku/waku-healthcheck.js.map +1 -0
- package/dist/waku/waku-observers.d.ts +1 -0
- package/dist/waku/waku-observers.js +10 -4
- package/dist/waku/waku-observers.js.map +1 -1
- package/dist/waku/waku-peer-discovery.d.ts +31 -0
- package/dist/waku/waku-peer-discovery.js +90 -0
- package/dist/waku/waku-peer-discovery.js.map +1 -0
- package/dist/waku-broadcaster-client.d.ts +3 -0
- package/dist/waku-broadcaster-client.js +55 -8
- package/dist/waku-broadcaster-client.js.map +1 -1
- package/package.json +3 -3
|
@@ -4,9 +4,10 @@ import { BroadcasterDebug } from '../utils/broadcaster-debug.js';
|
|
|
4
4
|
import { utf8ToBytes } from '../utils/conversion.js';
|
|
5
5
|
import { isDefined } from '../utils/is-defined.js';
|
|
6
6
|
import { createEncoder, createDecoder, } from '@waku/sdk';
|
|
7
|
-
import {
|
|
7
|
+
import { WAKU_RAILGUN_PUB_SUB_TOPIC, } from '../models/constants.js';
|
|
8
8
|
import { BroadcasterFeeCache } from '../fees/broadcaster-fee-cache.js';
|
|
9
9
|
import { BroadcasterConfig } from '../models/broadcaster-config.js';
|
|
10
|
+
import { getWakuHealthSnapshot } from './waku-healthcheck.js';
|
|
10
11
|
export class WakuBroadcasterWakuCoreBase {
|
|
11
12
|
static hasError = false;
|
|
12
13
|
static restartCallback;
|
|
@@ -14,7 +15,6 @@ export class WakuBroadcasterWakuCoreBase {
|
|
|
14
15
|
static pubSubTopic = WAKU_RAILGUN_PUB_SUB_TOPIC;
|
|
15
16
|
static additionalDirectPeers = [];
|
|
16
17
|
static peerDiscoveryTimeout = 60000;
|
|
17
|
-
static defaultShard = WAKU_RAILGUN_DEFAULT_SHARD;
|
|
18
18
|
static restartCount = 0;
|
|
19
19
|
static async initWaku(chain) {
|
|
20
20
|
try {
|
|
@@ -60,9 +60,12 @@ export class WakuBroadcasterWakuCoreBase {
|
|
|
60
60
|
}
|
|
61
61
|
static setBroadcasterOptions(broadcasterOptions) {
|
|
62
62
|
BroadcasterConfig.trustedFeeSigner = broadcasterOptions.trustedFeeSigner;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
BroadcasterConfig.configureWakuNetwork({
|
|
64
|
+
clusterId: broadcasterOptions.clusterId,
|
|
65
|
+
shardId: broadcasterOptions.shardId,
|
|
66
|
+
pubSubTopic: broadcasterOptions.pubSubTopic,
|
|
67
|
+
});
|
|
68
|
+
this.pubSubTopic = BroadcasterConfig.pubSubTopic;
|
|
66
69
|
if (broadcasterOptions.additionalDirectPeers) {
|
|
67
70
|
this.additionalDirectPeers =
|
|
68
71
|
broadcasterOptions.additionalDirectPeers;
|
|
@@ -103,20 +106,42 @@ export class WakuBroadcasterWakuCoreBase {
|
|
|
103
106
|
return 0;
|
|
104
107
|
return this.waku.libp2p.getConnections().length;
|
|
105
108
|
}
|
|
109
|
+
static async getHealthSnapshot() {
|
|
110
|
+
return getWakuHealthSnapshot({
|
|
111
|
+
hasError: this.hasError,
|
|
112
|
+
peerDiscoveryTimeout: this.peerDiscoveryTimeout,
|
|
113
|
+
restartCount: this.restartCount,
|
|
114
|
+
waku: this.waku,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
static getLightPushAcceptedCount(result) {
|
|
118
|
+
if (Array.isArray(result.successes)) {
|
|
119
|
+
return result.successes.length;
|
|
120
|
+
}
|
|
121
|
+
if (Array.isArray(result.recipients)) {
|
|
122
|
+
return result.recipients.length;
|
|
123
|
+
}
|
|
124
|
+
return 0;
|
|
125
|
+
}
|
|
106
126
|
static async broadcastMessage(data, topic) {
|
|
107
127
|
if (!this.waku) {
|
|
108
128
|
throw new Error('Waku not initialized');
|
|
109
129
|
}
|
|
110
130
|
const encoder = createEncoder({
|
|
111
131
|
contentTopic: topic,
|
|
112
|
-
routingInfo:
|
|
132
|
+
routingInfo: BroadcasterConfig.getWakuRoutingInfo(),
|
|
113
133
|
});
|
|
114
134
|
const payload = utf8ToBytes(JSON.stringify(data));
|
|
115
135
|
const result = await this.waku.lightPush.send(encoder, {
|
|
116
136
|
payload,
|
|
117
137
|
});
|
|
118
|
-
|
|
119
|
-
|
|
138
|
+
const acceptedCount = this.getLightPushAcceptedCount(result);
|
|
139
|
+
const failures = result.failures ?? [];
|
|
140
|
+
if (failures.length > 0) {
|
|
141
|
+
if (acceptedCount > 0) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
throw new Error('Failed to send message');
|
|
120
145
|
}
|
|
121
146
|
}
|
|
122
147
|
static async retrieveHistoricalForTopic(topic) {
|
|
@@ -128,14 +153,14 @@ export class WakuBroadcasterWakuCoreBase {
|
|
|
128
153
|
BroadcasterDebug.log(`No callback found for topic: ${topic}`);
|
|
129
154
|
return;
|
|
130
155
|
}
|
|
131
|
-
const decoder = createDecoder(topic,
|
|
156
|
+
const decoder = createDecoder(topic, BroadcasterConfig.getWakuRoutingInfo());
|
|
132
157
|
try {
|
|
133
158
|
const startTime = new Date();
|
|
134
159
|
startTime.setTime(Date.now() - (BroadcasterConfig.historicalLookBackTime));
|
|
135
160
|
const endTime = new Date(Date.now());
|
|
136
161
|
const options = {
|
|
137
162
|
includeData: true,
|
|
138
|
-
pubsubTopic:
|
|
163
|
+
pubsubTopic: BroadcasterConfig.pubSubTopic,
|
|
139
164
|
contentTopics: [topic],
|
|
140
165
|
paginationForward: true,
|
|
141
166
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"waku-broadcaster-waku-core-base.js","sourceRoot":"","sources":["../../src/waku/waku-broadcaster-waku-core-base.ts"],"names":[],"mappings":"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","sourcesContent":["import { Chain, delay } from '@railgun-community/shared-models';\nimport { WakuObservers } from './waku-observers.js';\nimport { BroadcasterDebug } from '../utils/broadcaster-debug.js';\nimport { utf8ToBytes } from '../utils/conversion.js';\nimport { isDefined } from '../utils/is-defined.js';\nimport {\n createEncoder,\n createDecoder,\n type LightNode,\n type IDecodedMessage,\n type QueryRequestParams,\n} from '@waku/sdk';\nimport { BroadcasterOptions } from '../models/index.js';\nimport {\n WAKU_RAILGUN_DEFAULT_SHARD,\n WAKU_RAILGUN_PUB_SUB_TOPIC,\n} from '../models/constants.js';\nimport { BroadcasterFeeCache } from '../fees/broadcaster-fee-cache.js';\nimport { BroadcasterConfig } from '../models/broadcaster-config.js';\n\nexport abstract class WakuBroadcasterWakuCoreBase {\n static hasError = false;\n static restartCallback: () => void;\n\n static waku: Optional<LightNode>;\n\n protected static pubSubTopic = WAKU_RAILGUN_PUB_SUB_TOPIC;\n protected static additionalDirectPeers: string[] = [];\n protected static peerDiscoveryTimeout = 60000;\n protected static defaultShard = WAKU_RAILGUN_DEFAULT_SHARD;\n public static restartCount = 0;\n\n static async initWaku(chain: Chain): Promise<void> {\n try {\n await this.connect();\n if (!this.waku) {\n BroadcasterDebug.log('No waku instance found');\n return;\n }\n WakuObservers.resetCurrentChain();\n await WakuObservers.setObserversForChain(\n this.waku,\n chain,\n );\n\n this.pollHistoricalTopics()\n\n } catch (err) {\n if (!(err instanceof Error)) {\n throw err;\n }\n BroadcasterDebug.error(err);\n throw err;\n }\n }\n\n static async pollHistoricalTopics() {\n BroadcasterDebug.log(\"Polling historical messages\")\n const topics = WakuObservers.getCurrentContentTopics();\n for (const topic of topics) {\n await this.retrieveHistoricalForTopic(topic);\n }\n await delay(10_000)\n }\n\n static setWakuRestartCallback(callback: () => void) {\n this.restartCallback = callback;\n }\n\n static async reinitWaku(chain: Chain) {\n if (\n isDefined(this.waku) &&\n this.waku.isStarted()\n ) {\n // Reset fees, which will reset status to \"Searching\".\n await this.disconnect();\n }\n BroadcasterFeeCache.resetCache(chain);\n BroadcasterDebug.log(\n `Reinit Waku, ${++this.restartCount}`,\n );\n await this.initWaku(chain);\n if (this.restartCallback) {\n this.restartCallback();\n }\n }\n\n static setBroadcasterOptions(broadcasterOptions: BroadcasterOptions) {\n BroadcasterConfig.trustedFeeSigner = broadcasterOptions.trustedFeeSigner;\n\n if (isDefined(broadcasterOptions.pubSubTopic)) {\n this.pubSubTopic = broadcasterOptions.pubSubTopic;\n }\n if (broadcasterOptions.additionalDirectPeers) {\n this.additionalDirectPeers =\n broadcasterOptions.additionalDirectPeers;\n }\n if (isDefined(broadcasterOptions.peerDiscoveryTimeout)) {\n this.peerDiscoveryTimeout =\n broadcasterOptions.peerDiscoveryTimeout;\n }\n if (isDefined(broadcasterOptions.feeExpirationTimeout)) {\n BroadcasterConfig.feeExpirationTimeout =\n broadcasterOptions.feeExpirationTimeout;\n }\n if (isDefined(broadcasterOptions.historicalLookBackTime)) {\n BroadcasterConfig.historicalLookBackTime = broadcasterOptions.historicalLookBackTime\n }\n }\n\n static async disconnect() {\n await WakuObservers.unsubscribe(this.waku);\n await this.waku?.stop();\n this.waku = undefined;\n }\n\n protected static connect(): Promise<void> {\n throw new Error(\"Method 'connect' must be implemented.\");\n }\n\n static getMeshPeerCount(): number {\n return 0;\n }\n\n static getPubSubPeerCount(): number {\n return 0;\n }\n\n static async getLightPushPeerCount(): Promise<number> {\n if (!this.waku) return 0;\n return this.waku.libp2p.getConnections().length;\n }\n\n static async getFilterPeerCount(): Promise<number> {\n if (!this.waku) return 0;\n return this.waku.libp2p.getConnections().length;\n }\n\n\n\n static async broadcastMessage(data: object, topic: string): Promise<void> {\n if (!this.waku) {\n throw new Error('Waku not initialized');\n }\n const encoder = createEncoder({\n contentTopic: topic,\n routingInfo: WAKU_RAILGUN_DEFAULT_SHARD\n });\n\n const payload = utf8ToBytes(JSON.stringify(data));\n\n const result = await this.waku.lightPush.send(encoder, {\n payload,\n });\n\n if (result.failures && result.failures.length > 0) {\n throw new Error(`Failed to send message: ${result.failures.map(f => f.error).join(', ')}`);\n }\n }\n\n static async retrieveHistoricalForTopic(topic: string): Promise<void> {\n if (!this.waku) {\n return;\n }\n\n const callback = WakuObservers.getCallbackForTopic(topic);\n if (!callback) {\n BroadcasterDebug.log(`No callback found for topic: ${topic}`);\n return;\n }\n\n const decoder = createDecoder(topic, WAKU_RAILGUN_DEFAULT_SHARD);\n\n try {\n const startTime = new Date()\n // TODO: make a variable\n startTime.setTime(Date.now() - (BroadcasterConfig.historicalLookBackTime))\n const endTime = new Date(Date.now())\n const options: QueryRequestParams = {\n includeData: true,\n pubsubTopic: this.pubSubTopic,\n contentTopics: [topic],\n paginationForward: true,\n }\n const lastMessage = WakuObservers.getLastMessage(topic);\n if (lastMessage) {\n const cursor = this.waku.store.createCursor(lastMessage)\n options.paginationCursor = cursor\n } else {\n options.timeStart = startTime\n options.timeEnd = endTime\n }\n const generator = this.waku.store.queryGenerator([decoder], options);\n for await (const messagesPromises of generator) {\n messagesPromises.reverse()\n for (const messagePromise of messagesPromises) {\n if (isDefined(messagePromise)) {\n const message = await messagePromise\n if (isDefined(message)) {\n callback(message);\n }\n }\n }\n }\n } catch (err) {\n if (err instanceof Error) {\n BroadcasterDebug.log(\n `Error retrieving historical messages: ${err.message}`,\n );\n }\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"waku-broadcaster-waku-core-base.js","sourceRoot":"","sources":["../../src/waku/waku-broadcaster-waku-core-base.ts"],"names":[],"mappings":"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","sourcesContent":["import { Chain, delay } from '@railgun-community/shared-models';\nimport { WakuObservers } from './waku-observers.js';\nimport { BroadcasterDebug } from '../utils/broadcaster-debug.js';\nimport { utf8ToBytes } from '../utils/conversion.js';\nimport { isDefined } from '../utils/is-defined.js';\nimport {\n createEncoder,\n createDecoder,\n type LightNode,\n type IDecodedMessage,\n type QueryRequestParams,\n} from '@waku/sdk';\nimport { BroadcasterOptions } from '../models/index.js';\nimport {\n WAKU_RAILGUN_PUB_SUB_TOPIC,\n} from '../models/constants.js';\nimport { BroadcasterFeeCache } from '../fees/broadcaster-fee-cache.js';\nimport { BroadcasterConfig } from '../models/broadcaster-config.js';\nimport { getWakuHealthSnapshot } from './waku-healthcheck.js';\n\nexport abstract class WakuBroadcasterWakuCoreBase {\n static hasError = false;\n static restartCallback: () => void;\n\n static waku: Optional<LightNode>;\n\n protected static pubSubTopic = WAKU_RAILGUN_PUB_SUB_TOPIC;\n protected static additionalDirectPeers: string[] = [];\n protected static peerDiscoveryTimeout = 60000;\n public static restartCount = 0;\n\n static async initWaku(chain: Chain): Promise<void> {\n try {\n await this.connect();\n if (!this.waku) {\n BroadcasterDebug.log('No waku instance found');\n return;\n }\n WakuObservers.resetCurrentChain();\n await WakuObservers.setObserversForChain(\n this.waku,\n chain,\n );\n\n this.pollHistoricalTopics()\n\n } catch (err) {\n if (!(err instanceof Error)) {\n throw err;\n }\n BroadcasterDebug.error(err);\n throw err;\n }\n }\n\n static async pollHistoricalTopics() {\n BroadcasterDebug.log(\"Polling historical messages\")\n const topics = WakuObservers.getCurrentContentTopics();\n for (const topic of topics) {\n await this.retrieveHistoricalForTopic(topic);\n }\n await delay(10_000)\n }\n\n static setWakuRestartCallback(callback: () => void) {\n this.restartCallback = callback;\n }\n\n static async reinitWaku(chain: Chain) {\n if (\n isDefined(this.waku) &&\n this.waku.isStarted()\n ) {\n // Reset fees, which will reset status to \"Searching\".\n await this.disconnect();\n }\n BroadcasterFeeCache.resetCache(chain);\n BroadcasterDebug.log(\n `Reinit Waku, ${++this.restartCount}`,\n );\n await this.initWaku(chain);\n if (this.restartCallback) {\n this.restartCallback();\n }\n }\n\n static setBroadcasterOptions(broadcasterOptions: BroadcasterOptions) {\n BroadcasterConfig.trustedFeeSigner = broadcasterOptions.trustedFeeSigner;\n\n BroadcasterConfig.configureWakuNetwork({\n clusterId: broadcasterOptions.clusterId,\n shardId: broadcasterOptions.shardId,\n pubSubTopic: broadcasterOptions.pubSubTopic,\n });\n\n this.pubSubTopic = BroadcasterConfig.pubSubTopic;\n if (broadcasterOptions.additionalDirectPeers) {\n this.additionalDirectPeers =\n broadcasterOptions.additionalDirectPeers;\n }\n if (isDefined(broadcasterOptions.peerDiscoveryTimeout)) {\n this.peerDiscoveryTimeout =\n broadcasterOptions.peerDiscoveryTimeout;\n }\n if (isDefined(broadcasterOptions.feeExpirationTimeout)) {\n BroadcasterConfig.feeExpirationTimeout =\n broadcasterOptions.feeExpirationTimeout;\n }\n if (isDefined(broadcasterOptions.historicalLookBackTime)) {\n BroadcasterConfig.historicalLookBackTime = broadcasterOptions.historicalLookBackTime\n }\n }\n\n static async disconnect() {\n await WakuObservers.unsubscribe(this.waku);\n await this.waku?.stop();\n this.waku = undefined;\n }\n\n protected static connect(): Promise<void> {\n throw new Error(\"Method 'connect' must be implemented.\");\n }\n\n static getMeshPeerCount(): number {\n return 0;\n }\n\n static getPubSubPeerCount(): number {\n return 0;\n }\n\n static async getLightPushPeerCount(): Promise<number> {\n if (!this.waku) return 0;\n return this.waku.libp2p.getConnections().length;\n }\n\n static async getFilterPeerCount(): Promise<number> {\n if (!this.waku) return 0;\n return this.waku.libp2p.getConnections().length;\n }\n\n static async getHealthSnapshot() {\n return getWakuHealthSnapshot({\n hasError: this.hasError,\n peerDiscoveryTimeout: this.peerDiscoveryTimeout,\n restartCount: this.restartCount,\n waku: this.waku,\n });\n }\n\n private static getLightPushAcceptedCount(result: {\n successes?: unknown[];\n recipients?: unknown[];\n failures?: unknown[];\n }): number {\n if (Array.isArray(result.successes)) {\n return result.successes.length;\n }\n if (Array.isArray(result.recipients)) {\n return result.recipients.length;\n }\n return 0;\n }\n\n static async broadcastMessage(data: object, topic: string): Promise<void> {\n if (!this.waku) {\n throw new Error('Waku not initialized');\n }\n const encoder = createEncoder({\n contentTopic: topic,\n routingInfo: BroadcasterConfig.getWakuRoutingInfo(),\n });\n\n const payload = utf8ToBytes(JSON.stringify(data));\n\n const result = await this.waku.lightPush.send(encoder, {\n payload,\n });\n\n const acceptedCount = this.getLightPushAcceptedCount(result);\n const failures = result.failures ?? [];\n\n if (failures.length > 0) {\n if (acceptedCount > 0) {\n return;\n }\n\n throw new Error('Failed to send message');\n }\n }\n\n static async retrieveHistoricalForTopic(topic: string): Promise<void> {\n if (!this.waku) {\n return;\n }\n\n const callback = WakuObservers.getCallbackForTopic(topic);\n if (!callback) {\n BroadcasterDebug.log(`No callback found for topic: ${topic}`);\n return;\n }\n\n const decoder = createDecoder(topic, BroadcasterConfig.getWakuRoutingInfo());\n\n try {\n const startTime = new Date()\n // TODO: make a variable\n startTime.setTime(Date.now() - (BroadcasterConfig.historicalLookBackTime))\n const endTime = new Date(Date.now())\n const options: QueryRequestParams = {\n includeData: true,\n pubsubTopic: BroadcasterConfig.pubSubTopic,\n contentTopics: [topic],\n paginationForward: true,\n }\n const lastMessage = WakuObservers.getLastMessage(topic);\n if (lastMessage) {\n const cursor = this.waku.store.createCursor(lastMessage)\n options.paginationCursor = cursor\n } else {\n options.timeStart = startTime\n options.timeEnd = endTime\n }\n const generator = this.waku.store.queryGenerator([decoder], options);\n for await (const messagesPromises of generator) {\n messagesPromises.reverse()\n for (const messagePromise of messagesPromises) {\n if (isDefined(messagePromise)) {\n const message = await messagePromise\n if (isDefined(message)) {\n callback(message);\n }\n }\n }\n }\n } catch (err) {\n if (err instanceof Error) {\n BroadcasterDebug.log(\n `Error retrieving historical messages: ${err.message}`,\n );\n }\n }\n }\n}\n"]}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { createLightNode, type CreateLibp2pOptions } from '@waku/sdk';
|
|
2
|
+
import { wakuDnsDiscovery, wakuPeerExchangeDiscovery } from '@waku/discovery';
|
|
3
|
+
import { WakuBroadcasterPeerDiscoveryCoreBase } from './waku-broadcaster-peer-discovery-core-base.js';
|
|
4
|
+
export declare class WakuBroadcasterWakuCore extends WakuBroadcasterPeerDiscoveryCoreBase {
|
|
5
|
+
protected static createWakuNode: typeof createLightNode;
|
|
6
|
+
protected static createDnsPeerDiscovery: typeof wakuDnsDiscovery;
|
|
7
|
+
protected static createPeerExchangeDiscovery: typeof wakuPeerExchangeDiscovery;
|
|
8
|
+
protected static getEnrTrees(): {
|
|
9
|
+
SANDBOX: string;
|
|
10
|
+
TEST: string;
|
|
11
|
+
};
|
|
12
|
+
protected static getDefaultPeers(): string[];
|
|
13
|
+
protected static getBaseLibp2pOptions(): CreateLibp2pOptions;
|
|
14
|
+
protected static applyConnectionLimitGuard(): void;
|
|
4
15
|
}
|
|
@@ -1,49 +1,49 @@
|
|
|
1
1
|
import { tcp } from '@libp2p/tcp';
|
|
2
|
-
import { createLightNode,
|
|
2
|
+
import { createLightNode, } from '@waku/sdk';
|
|
3
3
|
import { BroadcasterDebug } from '../utils/broadcaster-debug.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
static
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
let directPeers = [];
|
|
30
|
-
if (BroadcasterConfig.additionalDirectPeers.length) {
|
|
31
|
-
directPeers = BroadcasterConfig.additionalDirectPeers;
|
|
32
|
-
}
|
|
33
|
-
this.waku = await createLightNode({
|
|
34
|
-
defaultBootstrap: directPeers.length === 0,
|
|
35
|
-
bootstrapPeers: directPeers,
|
|
36
|
-
libp2p: libp2pOptions
|
|
37
|
-
});
|
|
38
|
-
await this.waku.start();
|
|
39
|
-
BroadcasterDebug.log('Waiting for remote peer.');
|
|
40
|
-
await this.waku.waitForPeers([Protocols.Filter, Protocols.LightPush, Protocols.Store], this.peerDiscoveryTimeout);
|
|
41
|
-
BroadcasterDebug.log('Waku initialized and connected to peers');
|
|
4
|
+
import { enrTree, wakuDnsDiscovery, wakuPeerExchangeDiscovery } from '@waku/discovery';
|
|
5
|
+
import { WakuBroadcasterPeerDiscoveryCoreBase } from './waku-broadcaster-peer-discovery-core-base.js';
|
|
6
|
+
import { WAKU_RAILGUN_DEFAULT_PEERS_NODE } from '../models/constants.js';
|
|
7
|
+
export class WakuBroadcasterWakuCore extends WakuBroadcasterPeerDiscoveryCoreBase {
|
|
8
|
+
static createWakuNode = createLightNode;
|
|
9
|
+
static createDnsPeerDiscovery = wakuDnsDiscovery;
|
|
10
|
+
static createPeerExchangeDiscovery = wakuPeerExchangeDiscovery;
|
|
11
|
+
static getEnrTrees() {
|
|
12
|
+
return enrTree;
|
|
13
|
+
}
|
|
14
|
+
static getDefaultPeers() {
|
|
15
|
+
return WAKU_RAILGUN_DEFAULT_PEERS_NODE;
|
|
16
|
+
}
|
|
17
|
+
static getBaseLibp2pOptions() {
|
|
18
|
+
return {
|
|
19
|
+
...super.getBaseLibp2pOptions(),
|
|
20
|
+
transports: [tcp()],
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
static applyConnectionLimitGuard() {
|
|
24
|
+
const connectionManager = this.waku?.connectionManager;
|
|
25
|
+
const dialer = connectionManager?.dialer;
|
|
26
|
+
const libp2p = this.waku?.libp2p;
|
|
27
|
+
if (!dialer || !libp2p || dialer.__wakuConnectionLimitGuardApplied) {
|
|
28
|
+
return;
|
|
42
29
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
30
|
+
const originalShouldSkipPeer = dialer.shouldSkipPeer?.bind(dialer);
|
|
31
|
+
if (typeof originalShouldSkipPeer !== 'function') {
|
|
32
|
+
return;
|
|
46
33
|
}
|
|
34
|
+
dialer.shouldSkipPeer = async (peerId) => {
|
|
35
|
+
const shouldSkip = await originalShouldSkipPeer(peerId);
|
|
36
|
+
if (shouldSkip) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
const connectionCount = libp2p.getConnections().length;
|
|
40
|
+
if (connectionCount >= this.maxConnections) {
|
|
41
|
+
BroadcasterDebug.log(`Skipping peer ${this.formatDiscoveryPeerId(peerId)} - max connections ${this.maxConnections} reached`);
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
};
|
|
46
|
+
dialer.__wakuConnectionLimitGuardApplied = true;
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
//# sourceMappingURL=waku-broadcaster-waku-core.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"waku-broadcaster-waku-core.js","sourceRoot":"","sources":["../../src/waku/waku-broadcaster-waku-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,
|
|
1
|
+
{"version":3,"file":"waku-broadcaster-waku-core.js","sourceRoot":"","sources":["../../src/waku/waku-broadcaster-waku-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EACL,eAAe,GAEhB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACvF,OAAO,EAAE,oCAAoC,EAAE,MAAM,gDAAgD,CAAC;AACtG,OAAO,EAAE,+BAA+B,EAAE,MAAM,wBAAwB,CAAC;AAEzE,MAAM,OAAO,uBAAwB,SAAQ,oCAAoC;IACrE,MAAM,CAAC,cAAc,GAAG,eAAe,CAAC;IACxC,MAAM,CAAC,sBAAsB,GAAG,gBAAgB,CAAC;IACjD,MAAM,CAAC,2BAA2B,GAAG,yBAAyB,CAAC;IAE/D,MAAM,CAAC,WAAW;QAC1B,OAAO,OAAO,CAAC;IACjB,CAAC;IAES,MAAM,CAAC,eAAe;QAC9B,OAAO,+BAA+B,CAAC;IACzC,CAAC;IAES,MAAM,CAAC,oBAAoB;QACnC,OAAO;YACL,GAAG,KAAK,CAAC,oBAAoB,EAAE;YAC/B,UAAU,EAAE,CAAC,GAAG,EAAE,CAAC;SACpB,CAAC;IACJ,CAAC;IAES,MAAM,CAAC,yBAAyB;QACxC,MAAM,iBAAiB,GAAI,IAAI,CAAC,IAAY,EAAE,iBAAiB,CAAC;QAChE,MAAM,MAAM,GAAG,iBAAiB,EAAE,MAAM,CAAC;QACzC,MAAM,MAAM,GAAI,IAAI,CAAC,IAAY,EAAE,MAAM,CAAC;QAC1C,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,iCAAiC,EAAE,CAAC;YACnE,OAAO;QACT,CAAC;QAED,MAAM,sBAAsB,GAAG,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACnE,IAAI,OAAO,sBAAsB,KAAK,UAAU,EAAE,CAAC;YACjD,OAAO;QACT,CAAC;QAED,MAAM,CAAC,cAAc,GAAG,KAAK,EAAE,MAAW,EAAE,EAAE;YAC5C,MAAM,UAAU,GAAG,MAAM,sBAAsB,CAAC,MAAM,CAAC,CAAC;YACxD,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,eAAe,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC;YACvD,IAAI,eAAe,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC3C,gBAAgB,CAAC,GAAG,CAClB,iBAAiB,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,sBAAsB,IAAI,CAAC,cAAc,UAAU,CACvG,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEF,MAAM,CAAC,iCAAiC,GAAG,IAAI,CAAC;IAClD,CAAC","sourcesContent":["import { tcp } from '@libp2p/tcp';\nimport {\n createLightNode,\n type CreateLibp2pOptions,\n} from '@waku/sdk';\nimport { BroadcasterDebug } from '../utils/broadcaster-debug.js';\nimport { enrTree, wakuDnsDiscovery, wakuPeerExchangeDiscovery } from '@waku/discovery';\nimport { WakuBroadcasterPeerDiscoveryCoreBase } from './waku-broadcaster-peer-discovery-core-base.js';\nimport { WAKU_RAILGUN_DEFAULT_PEERS_NODE } from '../models/constants.js';\n\nexport class WakuBroadcasterWakuCore extends WakuBroadcasterPeerDiscoveryCoreBase {\n protected static createWakuNode = createLightNode;\n protected static createDnsPeerDiscovery = wakuDnsDiscovery;\n protected static createPeerExchangeDiscovery = wakuPeerExchangeDiscovery;\n\n protected static getEnrTrees() {\n return enrTree;\n }\n\n protected static getDefaultPeers(): string[] {\n return WAKU_RAILGUN_DEFAULT_PEERS_NODE;\n }\n\n protected static getBaseLibp2pOptions(): CreateLibp2pOptions {\n return {\n ...super.getBaseLibp2pOptions(),\n transports: [tcp()],\n };\n }\n\n protected static applyConnectionLimitGuard() {\n const connectionManager = (this.waku as any)?.connectionManager;\n const dialer = connectionManager?.dialer;\n const libp2p = (this.waku as any)?.libp2p;\n if (!dialer || !libp2p || dialer.__wakuConnectionLimitGuardApplied) {\n return;\n }\n\n const originalShouldSkipPeer = dialer.shouldSkipPeer?.bind(dialer);\n if (typeof originalShouldSkipPeer !== 'function') {\n return;\n }\n\n dialer.shouldSkipPeer = async (peerId: any) => {\n const shouldSkip = await originalShouldSkipPeer(peerId);\n if (shouldSkip) {\n return true;\n }\n\n const connectionCount = libp2p.getConnections().length;\n if (connectionCount >= this.maxConnections) {\n BroadcasterDebug.log(\n `Skipping peer ${this.formatDiscoveryPeerId(peerId)} - max connections ${this.maxConnections} reached`,\n );\n return true;\n }\n\n return false;\n };\n\n dialer.__wakuConnectionLimitGuardApplied = true;\n }\n}\n"]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
type HealthcheckConnection = {
|
|
2
|
+
remotePeer?: {
|
|
3
|
+
toString?: () => string;
|
|
4
|
+
} | string;
|
|
5
|
+
};
|
|
6
|
+
type HealthcheckPeer = {
|
|
7
|
+
id?: {
|
|
8
|
+
toString?: () => string;
|
|
9
|
+
} | string;
|
|
10
|
+
protocols?: string[];
|
|
11
|
+
tags?: Map<string, unknown>;
|
|
12
|
+
};
|
|
13
|
+
export declare const getWakuHealthSnapshot: (options: {
|
|
14
|
+
hasError: boolean;
|
|
15
|
+
peerDiscoveryTimeout: number;
|
|
16
|
+
restartCount: number;
|
|
17
|
+
waku?: {
|
|
18
|
+
isStarted?: () => boolean;
|
|
19
|
+
libp2p?: {
|
|
20
|
+
getConnections?: () => HealthcheckConnection[];
|
|
21
|
+
peerStore?: {
|
|
22
|
+
all?: () => Promise<HealthcheckPeer[]>;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}) => Promise<{
|
|
27
|
+
hasWaku: boolean;
|
|
28
|
+
isStarted: boolean;
|
|
29
|
+
hasError: boolean;
|
|
30
|
+
restartCount: number;
|
|
31
|
+
peerDiscoveryTimeout: number;
|
|
32
|
+
routing: import("../models/constants.js").WakuShardInfo;
|
|
33
|
+
networkConfig: import("../models/constants.js").WakuNetworkConfig;
|
|
34
|
+
configuredPeers: {
|
|
35
|
+
useDNSDiscovery: boolean;
|
|
36
|
+
dnsDiscoveryUrls: string[];
|
|
37
|
+
bootstrapPeers: string[];
|
|
38
|
+
storePeers: string[];
|
|
39
|
+
};
|
|
40
|
+
connections: {
|
|
41
|
+
count: number;
|
|
42
|
+
peers: string[];
|
|
43
|
+
};
|
|
44
|
+
discovery: {
|
|
45
|
+
connectedPeerDetails: {
|
|
46
|
+
peerId: string;
|
|
47
|
+
supportsPeerExchange: boolean;
|
|
48
|
+
protocols: string[];
|
|
49
|
+
tags: string[];
|
|
50
|
+
}[];
|
|
51
|
+
peerStore: {
|
|
52
|
+
count: number;
|
|
53
|
+
bootstrapCount: number;
|
|
54
|
+
peerExchangeCount: number;
|
|
55
|
+
bootstrapPeers: string[];
|
|
56
|
+
peerExchangePeers: string[];
|
|
57
|
+
connectedPeersSupportingPeerExchange: string[];
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
contentTopics: string[];
|
|
61
|
+
}>;
|
|
62
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { BroadcasterConfig } from '../models/broadcaster-config.js';
|
|
2
|
+
import { WakuObservers } from './waku-observers.js';
|
|
3
|
+
import { isDefined } from '../utils/is-defined.js';
|
|
4
|
+
const formatConnectionPeerId = (connection) => {
|
|
5
|
+
const peer = connection.remotePeer;
|
|
6
|
+
if (typeof peer === 'string') {
|
|
7
|
+
return peer;
|
|
8
|
+
}
|
|
9
|
+
if (peer && typeof peer.toString === 'function') {
|
|
10
|
+
return peer.toString();
|
|
11
|
+
}
|
|
12
|
+
return 'unknown-peer';
|
|
13
|
+
};
|
|
14
|
+
const formatPeerId = (peer) => {
|
|
15
|
+
const peerId = peer.id;
|
|
16
|
+
if (typeof peerId === 'string') {
|
|
17
|
+
return peerId;
|
|
18
|
+
}
|
|
19
|
+
if (peerId && typeof peerId.toString === 'function') {
|
|
20
|
+
return peerId.toString();
|
|
21
|
+
}
|
|
22
|
+
return 'unknown-peer';
|
|
23
|
+
};
|
|
24
|
+
const hasPeerExchangeProtocol = (protocols) => (protocols ?? []).includes('/vac/waku/peer-exchange/2.0.0-alpha1');
|
|
25
|
+
export const getWakuHealthSnapshot = async (options) => {
|
|
26
|
+
const connections = options.waku?.libp2p?.getConnections?.() ?? [];
|
|
27
|
+
const connectedPeerIds = new Set(connections.map(connection => formatConnectionPeerId(connection)));
|
|
28
|
+
const peerStore = options.waku?.libp2p?.peerStore;
|
|
29
|
+
const storedPeers = peerStore?.all
|
|
30
|
+
? await peerStore.all().catch(() => [])
|
|
31
|
+
: [];
|
|
32
|
+
const bootstrapPeerIds = [];
|
|
33
|
+
const peerExchangePeerIds = [];
|
|
34
|
+
const connectedPeerDetails = [];
|
|
35
|
+
for (const peer of storedPeers) {
|
|
36
|
+
const peerId = formatPeerId(peer);
|
|
37
|
+
const tags = Array.from(peer.tags?.keys?.() ?? []);
|
|
38
|
+
const protocols = peer.protocols ?? [];
|
|
39
|
+
if (tags.includes('bootstrap')) {
|
|
40
|
+
bootstrapPeerIds.push(peerId);
|
|
41
|
+
}
|
|
42
|
+
if (tags.includes('peer-exchange')) {
|
|
43
|
+
peerExchangePeerIds.push(peerId);
|
|
44
|
+
}
|
|
45
|
+
if (connectedPeerIds.has(peerId)) {
|
|
46
|
+
connectedPeerDetails.push({
|
|
47
|
+
peerId,
|
|
48
|
+
supportsPeerExchange: hasPeerExchangeProtocol(protocols),
|
|
49
|
+
protocols,
|
|
50
|
+
tags,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
hasWaku: isDefined(options.waku),
|
|
56
|
+
isStarted: options.waku?.isStarted?.() ?? false,
|
|
57
|
+
hasError: options.hasError,
|
|
58
|
+
restartCount: options.restartCount,
|
|
59
|
+
peerDiscoveryTimeout: options.peerDiscoveryTimeout,
|
|
60
|
+
routing: BroadcasterConfig.getWakuRoutingInfo(),
|
|
61
|
+
networkConfig: BroadcasterConfig.getWakuNetworkConfig(),
|
|
62
|
+
configuredPeers: {
|
|
63
|
+
useDNSDiscovery: BroadcasterConfig.useDNSDiscovery,
|
|
64
|
+
dnsDiscoveryUrls: BroadcasterConfig.customDNS?.enrTreePeers ?? [],
|
|
65
|
+
bootstrapPeers: BroadcasterConfig.additionalDirectPeers,
|
|
66
|
+
storePeers: BroadcasterConfig.storePeers,
|
|
67
|
+
},
|
|
68
|
+
connections: {
|
|
69
|
+
count: connections.length,
|
|
70
|
+
peers: connections.map(connection => formatConnectionPeerId(connection)),
|
|
71
|
+
},
|
|
72
|
+
discovery: {
|
|
73
|
+
connectedPeerDetails,
|
|
74
|
+
peerStore: {
|
|
75
|
+
count: storedPeers.length,
|
|
76
|
+
bootstrapCount: bootstrapPeerIds.length,
|
|
77
|
+
peerExchangeCount: peerExchangePeerIds.length,
|
|
78
|
+
bootstrapPeers: bootstrapPeerIds,
|
|
79
|
+
peerExchangePeers: peerExchangePeerIds,
|
|
80
|
+
connectedPeersSupportingPeerExchange: connectedPeerDetails
|
|
81
|
+
.filter(peer => peer.supportsPeerExchange)
|
|
82
|
+
.map(peer => peer.peerId),
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
contentTopics: WakuObservers.getCurrentContentTopics(),
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=waku-healthcheck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waku-healthcheck.js","sourceRoot":"","sources":["../../src/waku/waku-healthcheck.ts"],"names":[],"mappings":"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","sourcesContent":["import { BroadcasterConfig } from '../models/broadcaster-config.js';\nimport { WakuObservers } from './waku-observers.js';\nimport { isDefined } from '../utils/is-defined.js';\n\ntype HealthcheckConnection = {\n remotePeer?: {\n toString?: () => string;\n } | string;\n};\n\ntype HealthcheckPeer = {\n id?: {\n toString?: () => string;\n } | string;\n protocols?: string[];\n tags?: Map<string, unknown>;\n};\n\nconst formatConnectionPeerId = (connection: HealthcheckConnection): string => {\n const peer = connection.remotePeer;\n if (typeof peer === 'string') {\n return peer;\n }\n if (peer && typeof peer.toString === 'function') {\n return peer.toString();\n }\n return 'unknown-peer';\n};\n\nconst formatPeerId = (peer: HealthcheckPeer): string => {\n const peerId = peer.id;\n if (typeof peerId === 'string') {\n return peerId;\n }\n if (peerId && typeof peerId.toString === 'function') {\n return peerId.toString();\n }\n return 'unknown-peer';\n};\n\nconst hasPeerExchangeProtocol = (protocols?: string[]): boolean =>\n (protocols ?? []).includes('/vac/waku/peer-exchange/2.0.0-alpha1');\n\nexport const getWakuHealthSnapshot = async (options: {\n hasError: boolean;\n peerDiscoveryTimeout: number;\n restartCount: number;\n waku?: {\n isStarted?: () => boolean;\n libp2p?: {\n getConnections?: () => HealthcheckConnection[];\n peerStore?: {\n all?: () => Promise<HealthcheckPeer[]>;\n };\n };\n };\n}) => {\n const connections = options.waku?.libp2p?.getConnections?.() ?? [];\n const connectedPeerIds = new Set(\n connections.map(connection => formatConnectionPeerId(connection)),\n );\n const peerStore = options.waku?.libp2p?.peerStore;\n const storedPeers: HealthcheckPeer[] = peerStore?.all\n ? await peerStore.all().catch(() => [])\n : [];\n\n const bootstrapPeerIds: string[] = [];\n const peerExchangePeerIds: string[] = [];\n const connectedPeerDetails: {\n peerId: string;\n supportsPeerExchange: boolean;\n protocols: string[];\n tags: string[];\n }[] = [];\n\n for (const peer of storedPeers) {\n const peerId = formatPeerId(peer);\n const tags = Array.from(peer.tags?.keys?.() ?? []);\n const protocols = peer.protocols ?? [];\n\n if (tags.includes('bootstrap')) {\n bootstrapPeerIds.push(peerId);\n }\n if (tags.includes('peer-exchange')) {\n peerExchangePeerIds.push(peerId);\n }\n if (connectedPeerIds.has(peerId)) {\n connectedPeerDetails.push({\n peerId,\n supportsPeerExchange: hasPeerExchangeProtocol(protocols),\n protocols,\n tags,\n });\n }\n }\n\n return {\n hasWaku: isDefined(options.waku),\n isStarted: options.waku?.isStarted?.() ?? false,\n hasError: options.hasError,\n restartCount: options.restartCount,\n peerDiscoveryTimeout: options.peerDiscoveryTimeout,\n routing: BroadcasterConfig.getWakuRoutingInfo(),\n networkConfig: BroadcasterConfig.getWakuNetworkConfig(),\n configuredPeers: {\n useDNSDiscovery: BroadcasterConfig.useDNSDiscovery,\n dnsDiscoveryUrls: BroadcasterConfig.customDNS?.enrTreePeers ?? [],\n bootstrapPeers: BroadcasterConfig.additionalDirectPeers,\n storePeers: BroadcasterConfig.storePeers,\n },\n connections: {\n count: connections.length,\n peers: connections.map(connection => formatConnectionPeerId(connection)),\n },\n discovery: {\n connectedPeerDetails,\n peerStore: {\n count: storedPeers.length,\n bootstrapCount: bootstrapPeerIds.length,\n peerExchangeCount: peerExchangePeerIds.length,\n bootstrapPeers: bootstrapPeerIds,\n peerExchangePeers: peerExchangePeerIds,\n connectedPeersSupportingPeerExchange: connectedPeerDetails\n .filter(peer => peer.supportsPeerExchange)\n .map(peer => peer.peerId),\n },\n },\n contentTopics: WakuObservers.getCurrentContentTopics(),\n };\n};\n"]}
|
|
@@ -7,6 +7,7 @@ export declare class WakuObservers {
|
|
|
7
7
|
private static messageCache;
|
|
8
8
|
private static observedMessages;
|
|
9
9
|
private static MAX_CACHE_SIZE;
|
|
10
|
+
private static resetMessageHistory;
|
|
10
11
|
private static getMessageId;
|
|
11
12
|
private static wrapCallbackWithCache;
|
|
12
13
|
static setObserversForChain: (waku: Optional<LightNode>, chain: Chain) => Promise<void>;
|
|
@@ -5,8 +5,8 @@ import { handleBroadcasterFeesMessage } from '../fees/handle-fees-message.js';
|
|
|
5
5
|
import { BroadcasterTransactResponse } from '../transact/broadcaster-transact-response.js';
|
|
6
6
|
import { BroadcasterDebug } from '../utils/broadcaster-debug.js';
|
|
7
7
|
import { isDefined } from '../utils/is-defined.js';
|
|
8
|
-
import { WAKU_RAILGUN_DEFAULT_SHARD } from '../models/constants.js';
|
|
9
8
|
import { bytesToHex } from '../utils/conversion.js';
|
|
9
|
+
import { BroadcasterConfig } from '../models/broadcaster-config.js';
|
|
10
10
|
export class WakuObservers {
|
|
11
11
|
static currentChain;
|
|
12
12
|
static currentContentTopics = [];
|
|
@@ -14,6 +14,10 @@ export class WakuObservers {
|
|
|
14
14
|
static messageCache = new Set();
|
|
15
15
|
static observedMessages = [];
|
|
16
16
|
static MAX_CACHE_SIZE = 5000;
|
|
17
|
+
static resetMessageHistory() {
|
|
18
|
+
this.messageCache = new Set();
|
|
19
|
+
this.observedMessages = [];
|
|
20
|
+
}
|
|
17
21
|
static getMessageId(message) {
|
|
18
22
|
const timestamp = message.timestamp ? message.timestamp.getTime() : 0;
|
|
19
23
|
const payload = message.payload ? bytesToHex(message.payload) : '';
|
|
@@ -59,6 +63,7 @@ export class WakuObservers {
|
|
|
59
63
|
};
|
|
60
64
|
static resetCurrentChain = () => {
|
|
61
65
|
this.currentChain = undefined;
|
|
66
|
+
this.resetMessageHistory();
|
|
62
67
|
};
|
|
63
68
|
static checkSubscriptionsHealth = async (waku) => {
|
|
64
69
|
BroadcasterDebug.log(`WAKU Health Status: ${waku?.health.getHealthStatus()}`);
|
|
@@ -76,6 +81,7 @@ export class WakuObservers {
|
|
|
76
81
|
}
|
|
77
82
|
this.currentSubscriptions = [];
|
|
78
83
|
this.currentContentTopics = [];
|
|
84
|
+
this.resetMessageHistory();
|
|
79
85
|
}
|
|
80
86
|
static removeAllObservers = async (waku) => {
|
|
81
87
|
await this.unsubscribe(waku);
|
|
@@ -83,8 +89,8 @@ export class WakuObservers {
|
|
|
83
89
|
static getDecodersForChain = (chain) => {
|
|
84
90
|
const contentTopicFees = contentTopics.fees(chain);
|
|
85
91
|
const contentTopicTransactResponse = contentTopics.transactResponse(chain);
|
|
86
|
-
const feesDecoder = createDecoder(contentTopicFees,
|
|
87
|
-
const transactResponseDecoder = createDecoder(contentTopicTransactResponse,
|
|
92
|
+
const feesDecoder = createDecoder(contentTopicFees, BroadcasterConfig.getWakuRoutingInfo());
|
|
93
|
+
const transactResponseDecoder = createDecoder(contentTopicTransactResponse, BroadcasterConfig.getWakuRoutingInfo());
|
|
88
94
|
const feesCallback = this.wrapCallbackWithCache((message) => handleBroadcasterFeesMessage(chain, message, contentTopicFees));
|
|
89
95
|
const transactResponseCallback = this.wrapCallbackWithCache((message) => BroadcasterTransactResponse.handleBroadcasterTransactionResponseMessage(message));
|
|
90
96
|
return [
|
|
@@ -120,7 +126,7 @@ export class WakuObservers {
|
|
|
120
126
|
return;
|
|
121
127
|
}
|
|
122
128
|
const transportTopic = contentTopics.encrypted(topic);
|
|
123
|
-
const decoder = createDecoder(transportTopic,
|
|
129
|
+
const decoder = createDecoder(transportTopic, BroadcasterConfig.getWakuRoutingInfo());
|
|
124
130
|
const wrappedCallback = this.wrapCallbackWithCache(callback);
|
|
125
131
|
const params = {
|
|
126
132
|
topic: transportTopic,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"waku-observers.js","sourceRoot":"","sources":["../../src/waku/waku-observers.ts"],"names":[],"mappings":"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","sourcesContent":["import { Chain, compareChains, delay } from '@railgun-community/shared-models';\nimport {\n createDecoder,\n type IMessage,\n type IDecoder,\n type LightNode,\n type IDecodedMessage,\n} from '@waku/sdk';\nimport { contentTopics } from './waku-topics.js';\nimport { handleBroadcasterFeesMessage } from '../fees/handle-fees-message.js';\nimport { BroadcasterTransactResponse } from '../transact/broadcaster-transact-response.js';\nimport { BroadcasterDebug } from '../utils/broadcaster-debug.js';\nimport { isDefined } from '../utils/is-defined.js';\nimport { WAKU_RAILGUN_DEFAULT_SHARD } from '../models/constants.js';\nimport { bytesToHex } from '../utils/conversion.js';\n\ntype SubscriptionParams = {\n topic: string;\n decoder: IDecoder<any> | IDecoder<any>[];\n callback: (message: any) => void;\n};\n\ntype ActiveSubscription = {\n params: SubscriptionParams;\n};\n\nexport class WakuObservers {\n private static currentChain: Optional<Chain>;\n private static currentContentTopics: string[] = [];\n private static currentSubscriptions: ActiveSubscription[] | undefined = [];\n private static messageCache: Set<string> = new Set();\n private static observedMessages: IDecodedMessage[] = [];\n private static MAX_CACHE_SIZE = 5000;\n\n private static getMessageId(message: IMessage): string {\n const timestamp = message.timestamp ? message.timestamp.getTime() : 0;\n const payload = message.payload ? bytesToHex(message.payload) : '';\n return `${timestamp}-${payload}`;\n }\n\n private static wrapCallbackWithCache(\n callback: (message: IMessage) => void,\n ): (message: IMessage) => void {\n return (message: IMessage) => {\n if (!message.payload) {\n return;\n }\n const messageId = this.getMessageId(message);\n if (this.messageCache.has(messageId)) {\n return;\n }\n this.messageCache.add(messageId);\n if (this.messageCache.size > this.MAX_CACHE_SIZE) {\n const first = this.messageCache.values().next().value;\n if (first) {\n this.messageCache.delete(first);\n }\n }\n this.observedMessages.push(message as IDecodedMessage);\n if (this.observedMessages.length > this.MAX_CACHE_SIZE) {\n this.observedMessages.shift();\n }\n callback(message);\n };\n }\n\n static setObserversForChain = async (\n waku: Optional<LightNode>,\n chain: Chain,\n ) => {\n if (!waku) {\n return;\n }\n if (\n WakuObservers.currentChain &&\n compareChains(WakuObservers.currentChain, chain)\n ) {\n return;\n }\n BroadcasterDebug.log(\n `Add Waku observers for chain: ${chain.type}:${chain.id}`,\n );\n WakuObservers.currentChain = chain;\n await this.removeAllObservers(waku);\n\n BroadcasterDebug.log('Removed all observers');\n await this.addChainObservers(waku, chain);\n BroadcasterDebug.log(\n `Waku listening for events on chain: ${chain.type}:${chain.id}`,\n );\n };\n\n static resetCurrentChain = () => {\n this.currentChain = undefined;\n };\n\n static checkSubscriptionsHealth = async (waku: Optional<LightNode>) => {\n BroadcasterDebug.log(\n // @ts-ignore\n `WAKU Health Status: ${waku?.health.getHealthStatus()}`,\n );\n if (isDefined(this.currentSubscriptions)) {\n if (this.currentSubscriptions.length === 0) {\n BroadcasterDebug.log('No subscriptions to ping');\n // throw new Error('No subscriptions to ping');\n }\n }\n await delay(15 * 1000);\n this.checkSubscriptionsHealth(waku);\n };\n\n static async unsubscribe(waku: Optional<LightNode>) {\n if (isDefined(waku) && isDefined(waku?.filter) && isDefined(this.currentSubscriptions)) {\n waku.filter.unsubscribeAll()\n }\n this.currentSubscriptions = [];\n this.currentContentTopics = [];\n }\n\n private static removeAllObservers = async (waku: Optional<LightNode>) => {\n await this.unsubscribe(waku);\n };\n\n private static getDecodersForChain = (chain: Chain) => {\n const contentTopicFees = contentTopics.fees(chain);\n const contentTopicTransactResponse = contentTopics.transactResponse(chain);\n\n const feesDecoder = createDecoder(\n contentTopicFees,\n WAKU_RAILGUN_DEFAULT_SHARD,\n );\n const transactResponseDecoder = createDecoder(\n contentTopicTransactResponse,\n WAKU_RAILGUN_DEFAULT_SHARD,\n );\n\n const feesCallback = this.wrapCallbackWithCache((message: IMessage) =>\n handleBroadcasterFeesMessage(chain, message, contentTopicFees));\n const transactResponseCallback = this.wrapCallbackWithCache((message: IMessage) =>\n BroadcasterTransactResponse.handleBroadcasterTransactionResponseMessage(\n message,\n ));\n\n return [\n {\n topic: contentTopicFees,\n decoder: feesDecoder,\n callback: feesCallback,\n },\n {\n topic: contentTopicTransactResponse,\n decoder: transactResponseDecoder,\n callback: transactResponseCallback,\n },\n ];\n };\n\n private static addChainObservers = async (waku: LightNode, chain: Chain) => {\n if (!isDefined(waku.filter)) {\n return;\n }\n\n await this.addSubscriptions(chain, waku).catch(\n err => {\n BroadcasterDebug.log(`Error adding Observers. ${err.message}`);\n return undefined;\n },\n );\n // Log current list of observers\n const currentContentTopics = WakuObservers.getCurrentContentTopics();\n BroadcasterDebug.log('Waku content topics:');\n for (const observer of currentContentTopics) {\n BroadcasterDebug.log(observer);\n }\n };\n\n static async addTransportSubscription(\n waku: Optional<LightNode>,\n topic: string,\n callback: (message: any) => void,\n ): Promise<void> {\n if (!isDefined(waku)) {\n BroadcasterDebug.log(\n 'No waku instance found, Transport Subscription not added.',\n );\n return;\n }\n const transportTopic = contentTopics.encrypted(topic);\n const decoder = createDecoder(transportTopic, WAKU_RAILGUN_DEFAULT_SHARD);\n const wrappedCallback = this.wrapCallbackWithCache(callback);\n const params: SubscriptionParams = {\n topic: transportTopic,\n decoder,\n callback: wrappedCallback,\n };\n await waku.filter.subscribe(\n decoder,\n wrappedCallback,\n );\n this.currentSubscriptions?.push({\n params,\n });\n WakuObservers.currentContentTopics.push(transportTopic);\n }\n\n private static async addSubscriptions(\n chain: Optional<Chain>,\n waku: Optional<LightNode>,\n ) {\n if (!isDefined(chain) || !isDefined(waku)) {\n BroadcasterDebug.log('AddSubscription: No Waku or Chain defined.');\n return;\n }\n const subscriptionParams = this.getDecodersForChain(chain);\n const topics = subscriptionParams.map(params => params.topic);\n const newTopics = topics.filter(\n topic => !this.currentContentTopics.includes(topic),\n );\n this.currentContentTopics.push(...newTopics);\n for (const params of subscriptionParams) {\n const { decoder, callback } = params;\n await waku.filter.subscribe(\n decoder,\n callback,\n );\n this.currentSubscriptions?.push({\n params,\n });\n }\n }\n\n static getCurrentContentTopics(): string[] {\n return WakuObservers.currentContentTopics;\n }\n\n static getLastMessage(topic: string): IDecodedMessage | undefined {\n let latestMessage: IDecodedMessage | undefined;\n for (const msg of this.observedMessages) {\n if (msg.contentTopic === topic) {\n if (!latestMessage) {\n latestMessage = msg;\n continue;\n }\n const msgTime = msg.timestamp ? msg.timestamp.getTime() : 0;\n const latestTime = latestMessage.timestamp ? latestMessage.timestamp.getTime() : 0;\n if (msgTime > latestTime) {\n latestMessage = msg;\n }\n }\n }\n return latestMessage;\n }\n\n static getCallbackForTopic(topic: string): Optional<(message: any) => void> {\n const subscription = this.currentSubscriptions?.find(sub => sub.params.topic === topic);\n return subscription?.params.callback;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"waku-observers.js","sourceRoot":"","sources":["../../src/waku/waku-observers.ts"],"names":[],"mappings":"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","sourcesContent":["import { Chain, compareChains, delay } from '@railgun-community/shared-models';\nimport {\n createDecoder,\n type IMessage,\n type IDecoder,\n type LightNode,\n type IDecodedMessage,\n} from '@waku/sdk';\nimport { contentTopics } from './waku-topics.js';\nimport { handleBroadcasterFeesMessage } from '../fees/handle-fees-message.js';\nimport { BroadcasterTransactResponse } from '../transact/broadcaster-transact-response.js';\nimport { BroadcasterDebug } from '../utils/broadcaster-debug.js';\nimport { isDefined } from '../utils/is-defined.js';\nimport { bytesToHex } from '../utils/conversion.js';\nimport { BroadcasterConfig } from '../models/broadcaster-config.js';\n\ntype SubscriptionParams = {\n topic: string;\n decoder: IDecoder<any> | IDecoder<any>[];\n callback: (message: any) => void;\n};\n\ntype ActiveSubscription = {\n params: SubscriptionParams;\n};\n\nexport class WakuObservers {\n private static currentChain: Optional<Chain>;\n private static currentContentTopics: string[] = [];\n private static currentSubscriptions: ActiveSubscription[] | undefined = [];\n private static messageCache: Set<string> = new Set();\n private static observedMessages: IDecodedMessage[] = [];\n private static MAX_CACHE_SIZE = 5000;\n\n private static resetMessageHistory() {\n this.messageCache = new Set();\n this.observedMessages = [];\n }\n\n private static getMessageId(message: IMessage): string {\n const timestamp = message.timestamp ? message.timestamp.getTime() : 0;\n const payload = message.payload ? bytesToHex(message.payload) : '';\n return `${timestamp}-${payload}`;\n }\n\n private static wrapCallbackWithCache(\n callback: (message: IMessage) => void,\n ): (message: IMessage) => void {\n return (message: IMessage) => {\n if (!message.payload) {\n return;\n }\n const messageId = this.getMessageId(message);\n if (this.messageCache.has(messageId)) {\n return;\n }\n this.messageCache.add(messageId);\n if (this.messageCache.size > this.MAX_CACHE_SIZE) {\n const first = this.messageCache.values().next().value;\n if (first) {\n this.messageCache.delete(first);\n }\n }\n this.observedMessages.push(message as IDecodedMessage);\n if (this.observedMessages.length > this.MAX_CACHE_SIZE) {\n this.observedMessages.shift();\n }\n callback(message);\n };\n }\n\n static setObserversForChain = async (\n waku: Optional<LightNode>,\n chain: Chain,\n ) => {\n if (!waku) {\n return;\n }\n if (\n WakuObservers.currentChain &&\n compareChains(WakuObservers.currentChain, chain)\n ) {\n return;\n }\n BroadcasterDebug.log(\n `Add Waku observers for chain: ${chain.type}:${chain.id}`,\n );\n WakuObservers.currentChain = chain;\n await this.removeAllObservers(waku);\n\n BroadcasterDebug.log('Removed all observers');\n await this.addChainObservers(waku, chain);\n BroadcasterDebug.log(\n `Waku listening for events on chain: ${chain.type}:${chain.id}`,\n );\n };\n\n static resetCurrentChain = () => {\n this.currentChain = undefined;\n this.resetMessageHistory();\n };\n\n static checkSubscriptionsHealth = async (waku: Optional<LightNode>) => {\n BroadcasterDebug.log(\n // @ts-ignore\n `WAKU Health Status: ${waku?.health.getHealthStatus()}`,\n );\n if (isDefined(this.currentSubscriptions)) {\n if (this.currentSubscriptions.length === 0) {\n BroadcasterDebug.log('No subscriptions to ping');\n // throw new Error('No subscriptions to ping');\n }\n }\n await delay(15 * 1000);\n this.checkSubscriptionsHealth(waku);\n };\n\n static async unsubscribe(waku: Optional<LightNode>) {\n if (isDefined(waku) && isDefined(waku?.filter) && isDefined(this.currentSubscriptions)) {\n waku.filter.unsubscribeAll()\n }\n this.currentSubscriptions = [];\n this.currentContentTopics = [];\n this.resetMessageHistory();\n }\n\n private static removeAllObservers = async (waku: Optional<LightNode>) => {\n await this.unsubscribe(waku);\n };\n\n private static getDecodersForChain = (chain: Chain) => {\n const contentTopicFees = contentTopics.fees(chain);\n const contentTopicTransactResponse = contentTopics.transactResponse(chain);\n\n const feesDecoder = createDecoder(\n contentTopicFees,\n BroadcasterConfig.getWakuRoutingInfo(),\n );\n const transactResponseDecoder = createDecoder(\n contentTopicTransactResponse,\n BroadcasterConfig.getWakuRoutingInfo(),\n );\n\n const feesCallback = this.wrapCallbackWithCache((message: IMessage) =>\n handleBroadcasterFeesMessage(chain, message, contentTopicFees));\n const transactResponseCallback = this.wrapCallbackWithCache((message: IMessage) =>\n BroadcasterTransactResponse.handleBroadcasterTransactionResponseMessage(\n message,\n ));\n\n return [\n {\n topic: contentTopicFees,\n decoder: feesDecoder,\n callback: feesCallback,\n },\n {\n topic: contentTopicTransactResponse,\n decoder: transactResponseDecoder,\n callback: transactResponseCallback,\n },\n ];\n };\n\n private static addChainObservers = async (waku: LightNode, chain: Chain) => {\n if (!isDefined(waku.filter)) {\n return;\n }\n\n await this.addSubscriptions(chain, waku).catch(\n err => {\n BroadcasterDebug.log(`Error adding Observers. ${err.message}`);\n return undefined;\n },\n );\n // Log current list of observers\n const currentContentTopics = WakuObservers.getCurrentContentTopics();\n BroadcasterDebug.log('Waku content topics:');\n for (const observer of currentContentTopics) {\n BroadcasterDebug.log(observer);\n }\n };\n\n static async addTransportSubscription(\n waku: Optional<LightNode>,\n topic: string,\n callback: (message: any) => void,\n ): Promise<void> {\n if (!isDefined(waku)) {\n BroadcasterDebug.log(\n 'No waku instance found, Transport Subscription not added.',\n );\n return;\n }\n const transportTopic = contentTopics.encrypted(topic);\n const decoder = createDecoder(\n transportTopic,\n BroadcasterConfig.getWakuRoutingInfo(),\n );\n const wrappedCallback = this.wrapCallbackWithCache(callback);\n const params: SubscriptionParams = {\n topic: transportTopic,\n decoder,\n callback: wrappedCallback,\n };\n await waku.filter.subscribe(\n decoder,\n wrappedCallback,\n );\n this.currentSubscriptions?.push({\n params,\n });\n WakuObservers.currentContentTopics.push(transportTopic);\n }\n\n private static async addSubscriptions(\n chain: Optional<Chain>,\n waku: Optional<LightNode>,\n ) {\n if (!isDefined(chain) || !isDefined(waku)) {\n BroadcasterDebug.log('AddSubscription: No Waku or Chain defined.');\n return;\n }\n const subscriptionParams = this.getDecodersForChain(chain);\n const topics = subscriptionParams.map(params => params.topic);\n const newTopics = topics.filter(\n topic => !this.currentContentTopics.includes(topic),\n );\n this.currentContentTopics.push(...newTopics);\n for (const params of subscriptionParams) {\n const { decoder, callback } = params;\n await waku.filter.subscribe(\n decoder,\n callback,\n );\n this.currentSubscriptions?.push({\n params,\n });\n }\n }\n\n static getCurrentContentTopics(): string[] {\n return WakuObservers.currentContentTopics;\n }\n\n static getLastMessage(topic: string): IDecodedMessage | undefined {\n let latestMessage: IDecodedMessage | undefined;\n for (const msg of this.observedMessages) {\n if (msg.contentTopic === topic) {\n if (!latestMessage) {\n latestMessage = msg;\n continue;\n }\n const msgTime = msg.timestamp ? msg.timestamp.getTime() : 0;\n const latestTime = latestMessage.timestamp ? latestMessage.timestamp.getTime() : 0;\n if (msgTime > latestTime) {\n latestMessage = msg;\n }\n }\n }\n return latestMessage;\n }\n\n static getCallbackForTopic(topic: string): Optional<(message: any) => void> {\n const subscription = this.currentSubscriptions?.find(sub => sub.params.topic === topic);\n return subscription?.params.callback;\n }\n}\n"]}
|