@streamr/trackerless-network 103.3.0 → 103.6.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/dist/exports.cjs +131 -36
- package/dist/exports.cjs.map +1 -1
- package/dist/exports.d.ts +23 -1
- package/dist/exports.js +132 -37
- package/dist/exports.js.map +1 -1
- package/package.json +5 -5
package/dist/exports.d.ts
CHANGED
|
@@ -1084,11 +1084,26 @@ type ContentDeliveryLayerNeighborInfo = MarkRequired<ContentDeliveryLayerNeighbo
|
|
|
1084
1084
|
type StreamPartitionInfo = ChangeFieldType<Required<StreamPartitionInfo$1>, 'contentDeliveryLayerNeighbors', ContentDeliveryLayerNeighborInfo[]>;
|
|
1085
1085
|
type NodeInfo = ChangeFieldType<Required<NodeInfoResponse>, 'streamPartitions', StreamPartitionInfo[]>;
|
|
1086
1086
|
|
|
1087
|
+
declare class PausedNeighbors {
|
|
1088
|
+
private readonly pausedNeighbors;
|
|
1089
|
+
private readonly limit;
|
|
1090
|
+
constructor(limit: number);
|
|
1091
|
+
add(node: DhtAddress, msgChainId: string): boolean;
|
|
1092
|
+
delete(node: DhtAddress, msgChainId: string): void;
|
|
1093
|
+
deleteAll(node: DhtAddress): void;
|
|
1094
|
+
isPaused(node: DhtAddress, msgChainId: string): boolean;
|
|
1095
|
+
forEach(fn: (neighbors: Set<DhtAddress>, msgChainId: string) => void): void;
|
|
1096
|
+
size(msgChainId: string): number;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1087
1099
|
interface Options {
|
|
1088
1100
|
neighbors: NodeList;
|
|
1089
1101
|
localPeerDescriptor: PeerDescriptor$1;
|
|
1090
1102
|
rpcCommunicator: ListeningRpcCommunicator;
|
|
1091
1103
|
maxPausedNeighbors?: number;
|
|
1104
|
+
recoveryTimeout?: number;
|
|
1105
|
+
recoveryCheckInterval?: number;
|
|
1106
|
+
recoveryCooldown?: number;
|
|
1092
1107
|
}
|
|
1093
1108
|
interface Events$3 {
|
|
1094
1109
|
message: (msg: StreamMessage) => void;
|
|
@@ -1101,8 +1116,12 @@ declare class PlumtreeManager extends EventEmitter<Events$3> {
|
|
|
1101
1116
|
private readonly rpcLocal;
|
|
1102
1117
|
private readonly latestMessages;
|
|
1103
1118
|
private readonly rpcCommunicator;
|
|
1104
|
-
private readonly metadataTimestampsAheadOfRealData;
|
|
1105
1119
|
private readonly maxPausedNeighbors;
|
|
1120
|
+
private readonly recoveryState;
|
|
1121
|
+
private readonly recoveryCooldownUntil;
|
|
1122
|
+
private readonly recoveryTimeout;
|
|
1123
|
+
private readonly recoveryCooldown;
|
|
1124
|
+
private readonly abortController;
|
|
1106
1125
|
constructor(options: Options);
|
|
1107
1126
|
pauseNeighbor(node: PeerDescriptor$1, msgChainId: string): Promise<void>;
|
|
1108
1127
|
resumeNeighbor(node: PeerDescriptor$1, msgChainId: string, fromTimestamp: number): Promise<void>;
|
|
@@ -1110,9 +1129,12 @@ declare class PlumtreeManager extends EventEmitter<Events$3> {
|
|
|
1110
1129
|
getLatestMessageTimestamp(msgChainId: string): number;
|
|
1111
1130
|
private sendBuffer;
|
|
1112
1131
|
private onMetadata;
|
|
1132
|
+
private attemptRecovery;
|
|
1113
1133
|
private createRemote;
|
|
1114
1134
|
broadcast(msg: StreamMessage, previousNode: DhtAddress): void;
|
|
1115
1135
|
isNeighborPaused(node: PeerDescriptor$1, msgChainId: string): boolean;
|
|
1136
|
+
getLocalPausedNeighbors(): PausedNeighbors;
|
|
1137
|
+
getRemotePausedNeighbors(): PausedNeighbors;
|
|
1116
1138
|
stop(): void;
|
|
1117
1139
|
}
|
|
1118
1140
|
|
package/dist/exports.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ListeningRpcCommunicator, PeerDescriptor as PeerDescriptor$1, areEqualPeerDescriptors, toNodeId, RpcRemote, toDhtAddress, toDhtAddressRaw, EXISTING_CONNECTION_TIMEOUT, DhtNode } from '@streamr/dht';
|
|
2
2
|
import { toProtoRpcClient } from '@streamr/proto-rpc';
|
|
3
|
-
import { Logger, scheduleAtInterval, wait, setAbortableTimeout, toUserId, addManagedEventListener, waitForEvent, toUserIdRaw, computeSha1, MetricsContext, RateMetric, toStreamPartID, StreamPartIDUtils, until } from '@streamr/utils';
|
|
3
|
+
import { Logger, scheduleAtInterval, wait, setAbortableTimeout, toUserId, addManagedEventListener, waitForEvent, setAbortableInterval, toUserIdRaw, computeSha1, MetricsContext, RateMetric, toStreamPartID, StreamPartIDUtils, until } from '@streamr/utils';
|
|
4
4
|
import pull from 'lodash/pull';
|
|
5
5
|
import { EventEmitter } from 'eventemitter3';
|
|
6
6
|
import sampleSize from 'lodash/sampleSize';
|
|
@@ -27,7 +27,7 @@ class ExternalNetworkRpc {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
var version = "103.
|
|
30
|
+
var version = "103.6.0-rc.0";
|
|
31
31
|
|
|
32
32
|
// @generated message type with reflection information, may provide speed optimized methods
|
|
33
33
|
class Any$Type extends MessageType {
|
|
@@ -1674,6 +1674,18 @@ class PauseNeighborRequest$Type extends MessageType {
|
|
|
1674
1674
|
*/
|
|
1675
1675
|
const PauseNeighborRequest = new PauseNeighborRequest$Type();
|
|
1676
1676
|
// @generated message type with reflection information, may provide speed optimized methods
|
|
1677
|
+
class PauseNeighborResponse$Type extends MessageType {
|
|
1678
|
+
constructor() {
|
|
1679
|
+
super("PauseNeighborResponse", [
|
|
1680
|
+
{ no: 1, name: "accepted", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }
|
|
1681
|
+
]);
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
/**
|
|
1685
|
+
* @generated MessageType for protobuf message PauseNeighborResponse
|
|
1686
|
+
*/
|
|
1687
|
+
const PauseNeighborResponse = new PauseNeighborResponse$Type();
|
|
1688
|
+
// @generated message type with reflection information, may provide speed optimized methods
|
|
1677
1689
|
class ResumeNeighborRequest$Type extends MessageType {
|
|
1678
1690
|
constructor() {
|
|
1679
1691
|
super("ResumeNeighborRequest", [
|
|
@@ -1729,7 +1741,7 @@ const NodeInfoRpc = new ServiceType("NodeInfoRpc", [
|
|
|
1729
1741
|
* @generated ServiceType for protobuf service PlumtreeRpc
|
|
1730
1742
|
*/
|
|
1731
1743
|
const PlumtreeRpc = new ServiceType("PlumtreeRpc", [
|
|
1732
|
-
{ name: "pauseNeighbor", options: {}, I: PauseNeighborRequest, O:
|
|
1744
|
+
{ name: "pauseNeighbor", options: {}, I: PauseNeighborRequest, O: PauseNeighborResponse },
|
|
1733
1745
|
{ name: "resumeNeighbor", options: {}, I: ResumeNeighborRequest, O: Empty },
|
|
1734
1746
|
{ name: "sendMetadata", options: {}, I: MessageID, O: Empty }
|
|
1735
1747
|
]);
|
|
@@ -3331,14 +3343,17 @@ class PlumtreeRpcLocal {
|
|
|
3331
3343
|
async pauseNeighbor(request, context) {
|
|
3332
3344
|
const sender = toNodeId(context.incomingSourceDescriptor);
|
|
3333
3345
|
if (this.neighbors.has(sender)) {
|
|
3334
|
-
this.pausedNodes.add(sender, request.messageChainId);
|
|
3346
|
+
const accepted = this.pausedNodes.add(sender, request.messageChainId);
|
|
3347
|
+
return { accepted };
|
|
3335
3348
|
}
|
|
3336
|
-
return
|
|
3349
|
+
return { accepted: false };
|
|
3337
3350
|
}
|
|
3338
3351
|
async resumeNeighbor(request, context) {
|
|
3339
3352
|
const sender = context.incomingSourceDescriptor;
|
|
3340
|
-
this.
|
|
3341
|
-
|
|
3353
|
+
if (this.neighbors.has(toNodeId(sender))) {
|
|
3354
|
+
this.pausedNodes.delete(toNodeId(sender), request.messageChainId);
|
|
3355
|
+
await this.sendBuffer(request.fromTimestamp, request.messageChainId, sender);
|
|
3356
|
+
}
|
|
3342
3357
|
return Empty;
|
|
3343
3358
|
}
|
|
3344
3359
|
}
|
|
@@ -3351,10 +3366,9 @@ class PlumtreeRpcRemote extends RpcRemote {
|
|
|
3351
3366
|
await this.getClient().sendMetadata(msg, options);
|
|
3352
3367
|
}
|
|
3353
3368
|
async pauseNeighbor(messageChainId) {
|
|
3354
|
-
const options = this.formDhtRpcOptions(
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
await this.getClient().pauseNeighbor({ messageChainId }, options);
|
|
3369
|
+
const options = this.formDhtRpcOptions();
|
|
3370
|
+
const response = await this.getClient().pauseNeighbor({ messageChainId }, options);
|
|
3371
|
+
return response.accepted;
|
|
3358
3372
|
}
|
|
3359
3373
|
async resumeNeighbor(fromTimestamp, messageChainId) {
|
|
3360
3374
|
const options = this.formDhtRpcOptions({
|
|
@@ -3376,9 +3390,10 @@ class PausedNeighbors {
|
|
|
3376
3390
|
this.pausedNeighbors.set(msgChainId, new Set());
|
|
3377
3391
|
}
|
|
3378
3392
|
if (this.pausedNeighbors.get(msgChainId).size >= this.limit) {
|
|
3379
|
-
return;
|
|
3393
|
+
return false;
|
|
3380
3394
|
}
|
|
3381
3395
|
this.pausedNeighbors.get(msgChainId).add(node);
|
|
3396
|
+
return true;
|
|
3382
3397
|
}
|
|
3383
3398
|
delete(node, msgChainId) {
|
|
3384
3399
|
this.pausedNeighbors.get(msgChainId)?.delete(node);
|
|
@@ -3411,19 +3426,24 @@ class PausedNeighbors {
|
|
|
3411
3426
|
}
|
|
3412
3427
|
|
|
3413
3428
|
const MAX_PAUSED_NEIGHBORS_DEFAULT = 3;
|
|
3429
|
+
const DEFAULT_RECOVERY_TIMEOUT = 500;
|
|
3430
|
+
const DEFAULT_RECOVERY_CHECK_INTERVAL = 200;
|
|
3431
|
+
const DEFAULT_RECOVERY_COOLDOWN = 2500;
|
|
3414
3432
|
const logger$4 = new Logger('PlumtreeManager');
|
|
3415
3433
|
class PlumtreeManager extends EventEmitter {
|
|
3416
3434
|
neighbors;
|
|
3417
3435
|
localPeerDescriptor;
|
|
3418
|
-
// We have paused sending real data to these neighbrs and only send metadata
|
|
3419
3436
|
localPausedNeighbors;
|
|
3420
|
-
// We have asked these nodes to pause sending real data to us, used to limit sending of pausing and resuming requests
|
|
3421
3437
|
remotePausedNeighbors;
|
|
3422
3438
|
rpcLocal;
|
|
3423
3439
|
latestMessages = new Map();
|
|
3424
3440
|
rpcCommunicator;
|
|
3425
|
-
metadataTimestampsAheadOfRealData = new Map();
|
|
3426
3441
|
maxPausedNeighbors;
|
|
3442
|
+
recoveryState = new Map();
|
|
3443
|
+
recoveryCooldownUntil = new Map();
|
|
3444
|
+
recoveryTimeout;
|
|
3445
|
+
recoveryCooldown;
|
|
3446
|
+
abortController = new AbortController();
|
|
3427
3447
|
constructor(options) {
|
|
3428
3448
|
super();
|
|
3429
3449
|
this.neighbors = options.neighbors;
|
|
@@ -3431,12 +3451,22 @@ class PlumtreeManager extends EventEmitter {
|
|
|
3431
3451
|
this.localPeerDescriptor = options.localPeerDescriptor;
|
|
3432
3452
|
this.localPausedNeighbors = new PausedNeighbors(options.maxPausedNeighbors ?? MAX_PAUSED_NEIGHBORS_DEFAULT);
|
|
3433
3453
|
this.remotePausedNeighbors = new PausedNeighbors(options.maxPausedNeighbors ?? MAX_PAUSED_NEIGHBORS_DEFAULT);
|
|
3454
|
+
this.recoveryTimeout = options.recoveryTimeout ?? DEFAULT_RECOVERY_TIMEOUT;
|
|
3455
|
+
this.recoveryCooldown = options.recoveryCooldown ?? DEFAULT_RECOVERY_COOLDOWN;
|
|
3434
3456
|
this.rpcLocal = new PlumtreeRpcLocal(this.neighbors, this.localPausedNeighbors, (metadata, previousNode) => this.onMetadata(metadata, previousNode), (fromTimestamp, msgChainId, remotePeerDescriptor) => this.sendBuffer(fromTimestamp, msgChainId, remotePeerDescriptor));
|
|
3435
|
-
this.neighbors.on('nodeRemoved',
|
|
3457
|
+
this.neighbors.on('nodeRemoved', this.onNeighborRemoved);
|
|
3436
3458
|
this.rpcCommunicator = options.rpcCommunicator;
|
|
3437
3459
|
this.rpcCommunicator.registerRpcNotification(MessageID, 'sendMetadata', (msg, context) => this.rpcLocal.sendMetadata(msg, context));
|
|
3438
|
-
this.rpcCommunicator.
|
|
3460
|
+
this.rpcCommunicator.registerRpcMethod(PauseNeighborRequest, PauseNeighborResponse, 'pauseNeighbor', (msg, context) => this.rpcLocal.pauseNeighbor(msg, context));
|
|
3439
3461
|
this.rpcCommunicator.registerRpcNotification(ResumeNeighborRequest, 'resumeNeighbor', (msg, context) => this.rpcLocal.resumeNeighbor(msg, context));
|
|
3462
|
+
setAbortableInterval(() => {
|
|
3463
|
+
const now = performance.now();
|
|
3464
|
+
for (const [chainId, state] of this.recoveryState) {
|
|
3465
|
+
if (now - state.metadataAheadSince >= this.recoveryTimeout && !state.resumeInProgress) {
|
|
3466
|
+
this.attemptRecovery(chainId, state, this.getLatestMessageTimestamp(chainId));
|
|
3467
|
+
}
|
|
3468
|
+
}
|
|
3469
|
+
}, options.recoveryCheckInterval ?? DEFAULT_RECOVERY_CHECK_INTERVAL, this.abortController.signal);
|
|
3440
3470
|
}
|
|
3441
3471
|
async pauseNeighbor(node, msgChainId) {
|
|
3442
3472
|
if (this.neighbors.has(toNodeId(node))
|
|
@@ -3444,8 +3474,16 @@ class PlumtreeManager extends EventEmitter {
|
|
|
3444
3474
|
&& this.remotePausedNeighbors.size(msgChainId) < this.maxPausedNeighbors) {
|
|
3445
3475
|
logger$4.debug(`Pausing neighbor ${toNodeId(node)}`);
|
|
3446
3476
|
this.remotePausedNeighbors.add(toNodeId(node), msgChainId);
|
|
3447
|
-
|
|
3448
|
-
|
|
3477
|
+
try {
|
|
3478
|
+
const remote = this.createRemote(node);
|
|
3479
|
+
const accepted = await remote.pauseNeighbor(msgChainId);
|
|
3480
|
+
if (!accepted) {
|
|
3481
|
+
this.remotePausedNeighbors.delete(toNodeId(node), msgChainId);
|
|
3482
|
+
}
|
|
3483
|
+
}
|
|
3484
|
+
catch (_e) {
|
|
3485
|
+
this.remotePausedNeighbors.delete(toNodeId(node), msgChainId);
|
|
3486
|
+
}
|
|
3449
3487
|
}
|
|
3450
3488
|
}
|
|
3451
3489
|
async resumeNeighbor(node, msgChainId, fromTimestamp) {
|
|
@@ -3456,9 +3494,15 @@ class PlumtreeManager extends EventEmitter {
|
|
|
3456
3494
|
await remote.resumeNeighbor(fromTimestamp, msgChainId);
|
|
3457
3495
|
}
|
|
3458
3496
|
}
|
|
3459
|
-
onNeighborRemoved(nodeId) {
|
|
3497
|
+
onNeighborRemoved = (nodeId) => {
|
|
3460
3498
|
this.localPausedNeighbors.deleteAll(nodeId);
|
|
3461
3499
|
this.remotePausedNeighbors.deleteAll(nodeId);
|
|
3500
|
+
for (const [_chainId, state] of this.recoveryState) {
|
|
3501
|
+
state.candidates = state.candidates.filter((c) => toNodeId(c) !== nodeId);
|
|
3502
|
+
if (state.lastAttemptedNode !== null && toNodeId(state.lastAttemptedNode) === nodeId) {
|
|
3503
|
+
state.lastAttemptedNode = null;
|
|
3504
|
+
}
|
|
3505
|
+
}
|
|
3462
3506
|
if (this.neighbors.size() > 0) {
|
|
3463
3507
|
this.remotePausedNeighbors.forEach((pausedNeighbors, msgChainId) => {
|
|
3464
3508
|
if (pausedNeighbors.size >= this.neighbors.size()) {
|
|
@@ -3468,7 +3512,7 @@ class PlumtreeManager extends EventEmitter {
|
|
|
3468
3512
|
}
|
|
3469
3513
|
});
|
|
3470
3514
|
}
|
|
3471
|
-
}
|
|
3515
|
+
};
|
|
3472
3516
|
getLatestMessageTimestamp(msgChainId) {
|
|
3473
3517
|
if (!this.latestMessages.has(msgChainId) || this.latestMessages.get(msgChainId).length === 0) {
|
|
3474
3518
|
return 0;
|
|
@@ -3478,22 +3522,61 @@ class PlumtreeManager extends EventEmitter {
|
|
|
3478
3522
|
async sendBuffer(fromTimestamp, msgChainId, neighbor) {
|
|
3479
3523
|
const remote = new ContentDeliveryRpcRemote(this.localPeerDescriptor, neighbor, this.rpcCommunicator, ContentDeliveryRpcClient);
|
|
3480
3524
|
const messages = this.latestMessages.get(msgChainId)?.filter((msg) => msg.messageId.timestamp > fromTimestamp) ?? [];
|
|
3481
|
-
|
|
3525
|
+
for (const msg of messages) {
|
|
3526
|
+
await remote.sendStreamMessage(msg);
|
|
3527
|
+
}
|
|
3482
3528
|
}
|
|
3483
3529
|
async onMetadata(msg, previousNode) {
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3530
|
+
const latestTs = this.getLatestMessageTimestamp(msg.messageChainId);
|
|
3531
|
+
if (latestTs >= msg.timestamp) {
|
|
3532
|
+
return;
|
|
3533
|
+
}
|
|
3534
|
+
const chainId = msg.messageChainId;
|
|
3535
|
+
const cooldownUntil = this.recoveryCooldownUntil.get(chainId);
|
|
3536
|
+
if (cooldownUntil !== undefined && performance.now() < cooldownUntil) {
|
|
3537
|
+
return;
|
|
3538
|
+
}
|
|
3539
|
+
let state = this.recoveryState.get(chainId);
|
|
3540
|
+
if (!state) {
|
|
3541
|
+
state = {
|
|
3542
|
+
timestampsAhead: new Set(),
|
|
3543
|
+
metadataAheadSince: performance.now(),
|
|
3544
|
+
candidates: [],
|
|
3545
|
+
lastAttemptedNode: null,
|
|
3546
|
+
resumeInProgress: false
|
|
3547
|
+
};
|
|
3548
|
+
this.recoveryState.set(chainId, state);
|
|
3549
|
+
}
|
|
3550
|
+
state.timestampsAhead.add(msg.timestamp);
|
|
3551
|
+
const nodeId = toNodeId(previousNode);
|
|
3552
|
+
const isLastAttempted = state.lastAttemptedNode !== null && toNodeId(state.lastAttemptedNode) === nodeId;
|
|
3553
|
+
if (!isLastAttempted && !state.candidates.some((c) => toNodeId(c) === nodeId)) {
|
|
3554
|
+
state.candidates.push(previousNode);
|
|
3555
|
+
}
|
|
3556
|
+
if (state.timestampsAhead.size > 1 && !state.resumeInProgress) {
|
|
3557
|
+
await this.attemptRecovery(chainId, state, latestTs);
|
|
3558
|
+
}
|
|
3559
|
+
}
|
|
3560
|
+
async attemptRecovery(chainId, state, latestTs) {
|
|
3561
|
+
const candidate = state.candidates.shift();
|
|
3562
|
+
if (!candidate) {
|
|
3563
|
+
state.metadataAheadSince = performance.now();
|
|
3564
|
+
return;
|
|
3565
|
+
}
|
|
3566
|
+
state.resumeInProgress = true;
|
|
3567
|
+
state.lastAttemptedNode = candidate;
|
|
3568
|
+
state.candidates = [];
|
|
3569
|
+
state.timestampsAhead.clear();
|
|
3570
|
+
state.metadataAheadSince = performance.now();
|
|
3571
|
+
try {
|
|
3572
|
+
const remote = this.createRemote(candidate);
|
|
3573
|
+
await remote.resumeNeighbor(latestTs, chainId);
|
|
3574
|
+
}
|
|
3575
|
+
catch (_e) {
|
|
3576
|
+
logger$4.debug('Recovery resume failed, will retry with next candidate');
|
|
3577
|
+
}
|
|
3578
|
+
finally {
|
|
3579
|
+
state.resumeInProgress = false;
|
|
3497
3580
|
}
|
|
3498
3581
|
}
|
|
3499
3582
|
createRemote(neighbor) {
|
|
@@ -3511,8 +3594,13 @@ class PlumtreeManager extends EventEmitter {
|
|
|
3511
3594
|
this.latestMessages.get(messageChainId).shift();
|
|
3512
3595
|
this.latestMessages.get(messageChainId).push(msg);
|
|
3513
3596
|
}
|
|
3514
|
-
|
|
3515
|
-
|
|
3597
|
+
const state = this.recoveryState.get(messageChainId);
|
|
3598
|
+
if (state) {
|
|
3599
|
+
if (state.lastAttemptedNode) {
|
|
3600
|
+
this.remotePausedNeighbors.delete(toNodeId(state.lastAttemptedNode), messageChainId);
|
|
3601
|
+
}
|
|
3602
|
+
this.recoveryState.delete(messageChainId);
|
|
3603
|
+
this.recoveryCooldownUntil.set(messageChainId, performance.now() + this.recoveryCooldown);
|
|
3516
3604
|
}
|
|
3517
3605
|
this.emit('message', msg);
|
|
3518
3606
|
const neighbors = this.neighbors.getAll().filter((neighbor) => toNodeId(neighbor.getPeerDescriptor()) !== previousNode);
|
|
@@ -3530,7 +3618,14 @@ class PlumtreeManager extends EventEmitter {
|
|
|
3530
3618
|
return this.localPausedNeighbors.isPaused(toNodeId(node), msgChainId)
|
|
3531
3619
|
|| this.remotePausedNeighbors.isPaused(toNodeId(node), msgChainId);
|
|
3532
3620
|
}
|
|
3621
|
+
getLocalPausedNeighbors() {
|
|
3622
|
+
return this.localPausedNeighbors;
|
|
3623
|
+
}
|
|
3624
|
+
getRemotePausedNeighbors() {
|
|
3625
|
+
return this.remotePausedNeighbors;
|
|
3626
|
+
}
|
|
3533
3627
|
stop() {
|
|
3628
|
+
this.abortController.abort();
|
|
3534
3629
|
this.neighbors.off('nodeRemoved', this.onNeighborRemoved);
|
|
3535
3630
|
}
|
|
3536
3631
|
}
|