@waku/core 0.0.33-aeb05cd.0 → 0.0.33-b93134a.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/bundle/{base_protocol-0xHh0_Hq.js → base_protocol-1U9jKpZH.js} +83 -77
- package/bundle/index.js +6 -9
- package/bundle/lib/base_protocol.js +1 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/lib/base_protocol.d.ts +3 -2
- package/dist/lib/base_protocol.js +7 -6
- package/dist/lib/base_protocol.js.map +1 -1
- package/dist/lib/filter/index.d.ts +1 -2
- package/dist/lib/filter/index.js +3 -6
- package/dist/lib/filter/index.js.map +1 -1
- package/dist/lib/metadata/index.js +1 -1
- package/dist/lib/metadata/index.js.map +1 -1
- package/dist/lib/stream_manager/stream_manager.d.ts +10 -9
- package/dist/lib/stream_manager/stream_manager.js +72 -55
- package/dist/lib/stream_manager/stream_manager.js.map +1 -1
- package/dist/lib/stream_manager/utils.d.ts +1 -1
- package/dist/lib/stream_manager/utils.js +5 -17
- package/dist/lib/stream_manager/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/lib/base_protocol.ts +11 -11
- package/src/lib/filter/index.ts +2 -13
- package/src/lib/metadata/index.ts +1 -1
- package/src/lib/stream_manager/stream_manager.ts +105 -66
- package/src/lib/stream_manager/utils.ts +5 -17
@@ -156,110 +156,115 @@ function filterPeersByDiscovery(peers, numPeers, maxBootstrapPeers) {
|
|
156
156
|
return selectedPeers;
|
157
157
|
}
|
158
158
|
|
159
|
-
function
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
let latestConnection;
|
165
|
-
connections.forEach((connection) => {
|
166
|
-
if (connection.status === "open") {
|
167
|
-
if (!latestConnection) {
|
168
|
-
latestConnection = connection;
|
169
|
-
}
|
170
|
-
else if (connection.timeline.open > latestConnection.timeline.open) {
|
171
|
-
latestConnection = connection;
|
172
|
-
}
|
173
|
-
}
|
174
|
-
});
|
175
|
-
return latestConnection;
|
159
|
+
function selectOpenConnection(connections) {
|
160
|
+
return connections
|
161
|
+
.filter((c) => c.status === "open")
|
162
|
+
.sort((left, right) => right.timeline.open - left.timeline.open)
|
163
|
+
.at(0);
|
176
164
|
}
|
177
165
|
|
178
|
-
const CONNECTION_TIMEOUT = 5_000;
|
179
|
-
const RETRY_BACKOFF_BASE = 1_000;
|
180
|
-
const MAX_RETRIES = 3;
|
181
166
|
class StreamManager {
|
182
167
|
multicodec;
|
183
168
|
getConnections;
|
184
169
|
addEventListener;
|
185
|
-
streamPool;
|
186
170
|
log;
|
171
|
+
ongoingCreation = new Set();
|
172
|
+
streamPool = new Map();
|
187
173
|
constructor(multicodec, getConnections, addEventListener) {
|
188
174
|
this.multicodec = multicodec;
|
189
175
|
this.getConnections = getConnections;
|
190
176
|
this.addEventListener = addEventListener;
|
191
177
|
this.log = new Logger(`stream-manager:${multicodec}`);
|
192
|
-
this.streamPool = new Map();
|
193
178
|
this.addEventListener("peer:update", this.handlePeerUpdateStreamPool);
|
194
179
|
}
|
195
180
|
async getStream(peer) {
|
196
|
-
const
|
197
|
-
const
|
198
|
-
if (
|
199
|
-
|
200
|
-
|
201
|
-
this.streamPool.delete(peerIdStr);
|
202
|
-
this.prepareStream(peer);
|
203
|
-
try {
|
204
|
-
const stream = await streamPromise;
|
205
|
-
if (stream && stream.status !== "closed") {
|
206
|
-
return stream;
|
207
|
-
}
|
181
|
+
const peerId = peer.id.toString();
|
182
|
+
const scheduledStream = this.streamPool.get(peerId);
|
183
|
+
if (scheduledStream) {
|
184
|
+
this.streamPool.delete(peerId);
|
185
|
+
await scheduledStream;
|
208
186
|
}
|
209
|
-
|
210
|
-
|
211
|
-
this.log.
|
187
|
+
const stream = this.getOpenStreamForCodec(peer.id);
|
188
|
+
if (stream) {
|
189
|
+
this.log.info(`Found existing stream peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
|
190
|
+
return stream;
|
212
191
|
}
|
213
192
|
return this.createStream(peer);
|
214
193
|
}
|
215
194
|
async createStream(peer, retries = 0) {
|
216
195
|
const connections = this.getConnections(peer.id);
|
217
|
-
const connection =
|
196
|
+
const connection = selectOpenConnection(connections);
|
218
197
|
if (!connection) {
|
219
|
-
throw new Error(
|
198
|
+
throw new Error(`Failed to get a connection to the peer peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
|
199
|
+
}
|
200
|
+
let lastError;
|
201
|
+
let stream;
|
202
|
+
for (let i = 0; i < retries + 1; i++) {
|
203
|
+
try {
|
204
|
+
this.log.info(`Attempting to create a stream for peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
|
205
|
+
stream = await connection.newStream(this.multicodec);
|
206
|
+
this.log.info(`Created stream for peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
|
207
|
+
break;
|
208
|
+
}
|
209
|
+
catch (error) {
|
210
|
+
lastError = error;
|
211
|
+
}
|
212
|
+
}
|
213
|
+
if (!stream) {
|
214
|
+
throw new Error(`Failed to create a new stream for ${peer.id.toString()} -- ` +
|
215
|
+
lastError);
|
216
|
+
}
|
217
|
+
return stream;
|
218
|
+
}
|
219
|
+
async createStreamWithLock(peer) {
|
220
|
+
const peerId = peer.id.toString();
|
221
|
+
if (this.ongoingCreation.has(peerId)) {
|
222
|
+
this.log.info(`Skipping creation of a stream due to lock for peerId=${peerId} multicodec=${this.multicodec}`);
|
223
|
+
return;
|
220
224
|
}
|
221
225
|
try {
|
222
|
-
|
226
|
+
this.ongoingCreation.add(peerId);
|
227
|
+
await this.createStream(peer);
|
223
228
|
}
|
224
229
|
catch (error) {
|
225
|
-
|
226
|
-
const backoff = RETRY_BACKOFF_BASE * Math.pow(2, retries);
|
227
|
-
await new Promise((resolve) => setTimeout(resolve, backoff));
|
228
|
-
return this.createStream(peer, retries + 1);
|
229
|
-
}
|
230
|
-
throw new Error(`Failed to create a new stream for ${peer.id.toString()} -- ` + error);
|
230
|
+
this.log.error(`Failed to createStreamWithLock:`, error);
|
231
231
|
}
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
this.createStream(peer),
|
237
|
-
timeoutPromise.then(() => {
|
238
|
-
throw new Error("Connection timeout");
|
239
|
-
})
|
240
|
-
]).catch((error) => {
|
241
|
-
this.log.error(`Failed to prepare a new stream for ${peer.id.toString()} -- `, error);
|
242
|
-
});
|
243
|
-
this.streamPool.set(peer.id.toString(), streamPromise);
|
232
|
+
finally {
|
233
|
+
this.ongoingCreation.delete(peerId);
|
234
|
+
}
|
235
|
+
return;
|
244
236
|
}
|
245
237
|
handlePeerUpdateStreamPool = (evt) => {
|
246
238
|
const { peer } = evt.detail;
|
247
|
-
if (peer.protocols.includes(this.multicodec)) {
|
248
|
-
|
249
|
-
if (isConnected) {
|
250
|
-
this.log.info(`Preemptively opening a stream to ${peer.id.toString()}`);
|
251
|
-
this.prepareStream(peer);
|
252
|
-
}
|
253
|
-
else {
|
254
|
-
const peerIdStr = peer.id.toString();
|
255
|
-
this.streamPool.delete(peerIdStr);
|
256
|
-
this.log.info(`Removed pending stream for disconnected peer ${peerIdStr}`);
|
257
|
-
}
|
239
|
+
if (!peer.protocols.includes(this.multicodec)) {
|
240
|
+
return;
|
258
241
|
}
|
242
|
+
const stream = this.getOpenStreamForCodec(peer.id);
|
243
|
+
if (stream) {
|
244
|
+
return;
|
245
|
+
}
|
246
|
+
this.scheduleNewStream(peer);
|
259
247
|
};
|
260
|
-
|
248
|
+
scheduleNewStream(peer) {
|
249
|
+
this.log.info(`Scheduling creation of a stream for peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
|
250
|
+
// abandon previous attempt
|
251
|
+
if (this.streamPool.has(peer.id.toString())) {
|
252
|
+
this.streamPool.delete(peer.id.toString());
|
253
|
+
}
|
254
|
+
this.streamPool.set(peer.id.toString(), this.createStreamWithLock(peer));
|
255
|
+
}
|
256
|
+
getOpenStreamForCodec(peerId) {
|
261
257
|
const connections = this.getConnections(peerId);
|
262
|
-
|
258
|
+
const connection = selectOpenConnection(connections);
|
259
|
+
if (!connection) {
|
260
|
+
return;
|
261
|
+
}
|
262
|
+
const stream = connection.streams.find((s) => s.protocol === this.multicodec);
|
263
|
+
const isStreamUnusable = ["done", "closed", "closing"].includes(stream?.writeStatus || "");
|
264
|
+
if (isStreamUnusable) {
|
265
|
+
return;
|
266
|
+
}
|
267
|
+
return stream;
|
263
268
|
}
|
264
269
|
}
|
265
270
|
|
@@ -287,20 +292,21 @@ class BaseProtocol {
|
|
287
292
|
async getStream(peer) {
|
288
293
|
return this.streamManager.getStream(peer);
|
289
294
|
}
|
290
|
-
|
295
|
+
get peerStore() {
|
296
|
+
return this.components.peerStore;
|
297
|
+
}
|
291
298
|
/**
|
292
299
|
* Returns known peers from the address book (`libp2p.peerStore`) that support
|
293
300
|
* the class protocol. Waku may or may not be currently connected to these
|
294
301
|
* peers.
|
295
302
|
*/
|
296
303
|
async allPeers() {
|
297
|
-
return getPeersForProtocol(this.
|
304
|
+
return getPeersForProtocol(this.peerStore, [this.multicodec]);
|
298
305
|
}
|
299
306
|
async connectedPeers() {
|
300
307
|
const peers = await this.allPeers();
|
301
308
|
return peers.filter((peer) => {
|
302
|
-
|
303
|
-
return connections.some((c) => c.streams.some((s) => s.protocol === this.multicodec));
|
309
|
+
return (this.components.connectionManager.getConnections(peer.id).length > 0);
|
304
310
|
});
|
305
311
|
}
|
306
312
|
/**
|
@@ -316,11 +322,11 @@ class BaseProtocol {
|
|
316
322
|
numPeers: 0
|
317
323
|
}) {
|
318
324
|
// Retrieve all connected peers that support the protocol & shard (if configured)
|
319
|
-
const connectedPeersForProtocolAndShard = await getConnectedPeersForProtocolAndShard(this.components.connectionManager.getConnections(), this.
|
325
|
+
const connectedPeersForProtocolAndShard = await getConnectedPeersForProtocolAndShard(this.components.connectionManager.getConnections(), this.peerStore, [this.multicodec], pubsubTopicsToShardInfo(this.pubsubTopics));
|
320
326
|
// Filter the peers based on discovery & number of peers requested
|
321
327
|
const filteredPeers = filterPeersByDiscovery(connectedPeersForProtocolAndShard, numPeers, maxBootstrapPeers);
|
322
328
|
// Sort the peers by latency
|
323
|
-
const sortedFilteredPeers = await sortPeersByLatency(this.
|
329
|
+
const sortedFilteredPeers = await sortPeersByLatency(this.peerStore, filteredPeers);
|
324
330
|
if (sortedFilteredPeers.length === 0) {
|
325
331
|
this.log.warn("No peers found. Ensure you have a connection to the network.");
|
326
332
|
}
|
package/bundle/index.js
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
import { v as version_0, e as encodingLength, a as encode$1, d as decode$1, M as MessagePush, F as FilterSubscribeRequest, b as FilterSubscribeResponse$1, P as PushRpc$1, c as PushResponse, S as StoreQueryRequest$1, f as StoreQueryResponse$1, g as createEncoder, W as WakuMetadataRequest, h as WakuMetadataResponse } from './version_0-BrbNEwD-.js';
|
2
2
|
export { i as createDecoder } from './version_0-BrbNEwD-.js';
|
3
3
|
import { a as allocUnsafe, b as alloc, L as Logger, P as ProtocolError, c as Protocols, u as utf8ToBytes, p as pubsubTopicToSingleShardInfo, T as Tags, E as EPeersByDiscoveryEvents, s as shardInfoToPubsubTopics, d as EConnectionStateEvents, H as HealthStatus, e as pubsubTopicsToShardInfo } from './index-tdQNdKHx.js';
|
4
|
-
import { B as BaseProtocol, d as decodeRelayShard, e as encodeRelayShard } from './base_protocol-
|
5
|
-
export { S as StreamManager } from './base_protocol-
|
4
|
+
import { B as BaseProtocol, d as decodeRelayShard, e as encodeRelayShard } from './base_protocol-1U9jKpZH.js';
|
5
|
+
export { S as StreamManager } from './base_protocol-1U9jKpZH.js';
|
6
6
|
|
7
7
|
const MB = 1024 ** 2;
|
8
8
|
const SIZE_CAP_IN_MB = 1;
|
@@ -1564,12 +1564,10 @@ const FilterCodecs = {
|
|
1564
1564
|
};
|
1565
1565
|
class FilterCore extends BaseProtocol {
|
1566
1566
|
handleIncomingMessage;
|
1567
|
-
handleError;
|
1568
1567
|
pubsubTopics;
|
1569
|
-
constructor(handleIncomingMessage,
|
1568
|
+
constructor(handleIncomingMessage, pubsubTopics, libp2p) {
|
1570
1569
|
super(FilterCodecs.SUBSCRIBE, libp2p.components, log$6, pubsubTopics);
|
1571
1570
|
this.handleIncomingMessage = handleIncomingMessage;
|
1572
|
-
this.handleError = handleError;
|
1573
1571
|
this.pubsubTopics = pubsubTopics;
|
1574
1572
|
libp2p
|
1575
1573
|
.handle(FilterCodecs.PUSH, this.onRequest.bind(this), {
|
@@ -1751,9 +1749,8 @@ class FilterCore extends BaseProtocol {
|
|
1751
1749
|
}
|
1752
1750
|
}).then(() => {
|
1753
1751
|
log$6.info("Receiving pipe closed.");
|
1754
|
-
},
|
1755
|
-
log$6.error("Error with receiving pipe", e
|
1756
|
-
await this.handleError(e);
|
1752
|
+
}, (e) => {
|
1753
|
+
log$6.error("Error with receiving pipe", e);
|
1757
1754
|
});
|
1758
1755
|
}
|
1759
1756
|
catch (e) {
|
@@ -3208,7 +3205,7 @@ class Metadata extends BaseProtocol {
|
|
3208
3205
|
*/
|
3209
3206
|
async query(peerId) {
|
3210
3207
|
const request = WakuMetadataRequest.encode(pubsubTopicsToShardInfo(this.pubsubTopics));
|
3211
|
-
const peer = await this.
|
3208
|
+
const peer = await this.peerStore.get(peerId);
|
3212
3209
|
if (!peer) {
|
3213
3210
|
return {
|
3214
3211
|
shardInfo: null,
|
@@ -1,2 +1,2 @@
|
|
1
1
|
import '../index-tdQNdKHx.js';
|
2
|
-
export { B as BaseProtocol } from '../base_protocol-
|
2
|
+
export { B as BaseProtocol } from '../base_protocol-1U9jKpZH.js';
|