@aztec/slasher 5.2.0-nightly.20260813 → 5.2.0-nightly.20260815
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.
|
@@ -22,6 +22,11 @@ declare const DataWithholdingWatcher_base: new () => WatcherEmitter;
|
|
|
22
22
|
* The watcher ticks at quarter-eth-slot cadence (matching the Sentinel template). On boot it
|
|
23
23
|
* floors processing at the current slot — restart-time gaps are accepted and not back-filled,
|
|
24
24
|
* matching the Sentinel approach.
|
|
25
|
+
*
|
|
26
|
+
* Since the evidence for an offense is the absence of txs in the local pool, the probe is gated on
|
|
27
|
+
* p2p connectivity: while there are no connected peers, slots are skipped instead of probed, since
|
|
28
|
+
* missing txs then say nothing about the attesters. Nodes running with p2p disabled do not run this
|
|
29
|
+
* watcher at all.
|
|
25
30
|
*/
|
|
26
31
|
export declare class DataWithholdingWatcher extends DataWithholdingWatcher_base implements Watcher {
|
|
27
32
|
private readonly epochCache;
|
|
@@ -35,7 +40,8 @@ export declare class DataWithholdingWatcher extends DataWithholdingWatcher_base
|
|
|
35
40
|
private initialSlot;
|
|
36
41
|
private lastCheckedSlot;
|
|
37
42
|
private config;
|
|
38
|
-
|
|
43
|
+
private gossipDegraded;
|
|
44
|
+
constructor(epochCache: EpochCache, l2BlockSource: Pick<L2BlockSource, 'getCheckpoint' | 'getSyncedL2SlotNumber'>, txProvider: Pick<ITxProvider, 'hasTxs'>, p2p: Pick<P2PApi, 'getCheckpointAttestationsForSlot' | 'getP2PConnectivity'>, reexecutionTracker: Pick<CheckpointReexecutionTracker, 'getTxsCollectedRecord'>, signatureContext: CoordinationSignatureContext, config: DataWithholdingWatcherConfig, log?: Logger);
|
|
39
45
|
start(): Promise<void>;
|
|
40
46
|
stop(): Promise<void>;
|
|
41
47
|
updateConfig(config: Partial<SlasherConfig>): void;
|
|
@@ -60,4 +66,4 @@ export declare class DataWithholdingWatcher extends DataWithholdingWatcher_base
|
|
|
60
66
|
protected extractAttesters(published: PublishedCheckpoint): Promise<EthAddress[]>;
|
|
61
67
|
}
|
|
62
68
|
export {};
|
|
63
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
69
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YV93aXRoaG9sZGluZ193YXRjaGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd2F0Y2hlcnMvZGF0YV93aXRoaG9sZGluZ193YXRjaGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBR3JELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxLQUFLLE1BQU0sRUFBZ0IsTUFBTSx1QkFBdUIsQ0FBQztBQUVsRSxPQUFPLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUV6RCxPQUFPLEtBQUssRUFBRSw0QkFBNEIsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2xHLE9BQU8sS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDMUYsT0FBTyxFQUFvQixLQUFLLDRCQUE0QixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFNeEYsT0FBTyxFQUE2QyxLQUFLLE9BQU8sRUFBRSxLQUFLLGNBQWMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU3RyxRQUFBLE1BQU0sZ0NBQWdDLGdGQUFpRixDQUFDO0FBRXhILEtBQUssNEJBQTRCLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLE9BQU8sZ0NBQWdDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDOztBQUUzRzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBQ0gscUJBQWEsc0JBQXVCLFNBQVEsMkJBQTJDLFlBQVcsT0FBTztJQVFyRyxPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVU7SUFDM0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhO0lBQzlCLE9BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVTtJQUMzQixPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUc7SUFDcEIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxrQkFBa0I7SUFDbkMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0I7SUFFakMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHO0lBZHRCLE9BQU8sQ0FBQyxjQUFjLENBQWlCO0lBQ3ZDLE9BQU8sQ0FBQyxXQUFXLENBQXlCO0lBQzVDLE9BQU8sQ0FBQyxlQUFlLENBQXlCO0lBQ2hELE9BQU8sQ0FBQyxNQUFNLENBQStCO0lBQzdDLE9BQU8sQ0FBQyxjQUFjLENBQVM7SUFFL0IsWUFDbUIsVUFBVSxFQUFFLFVBQVUsRUFDdEIsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsZUFBZSxHQUFHLHVCQUF1QixDQUFDLEVBQzdFLFVBQVUsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxFQUN2QyxHQUFHLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxrQ0FBa0MsR0FBRyxvQkFBb0IsQ0FBQyxFQUM1RSxrQkFBa0IsRUFBRSxJQUFJLENBQUMsNEJBQTRCLEVBQUUsdUJBQXVCLENBQUMsRUFDL0UsZ0JBQWdCLEVBQUUsNEJBQTRCLEVBQy9ELE1BQU0sRUFBRSw0QkFBNEIsRUFDbkIsR0FBRyxHQUFFLE1BQWlELEVBT3hFO0lBRVksS0FBSyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FRbEM7SUFFTSxJQUFJLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUUzQjtJQUVNLFlBQVksQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLGFBQWEsQ0FBQyxHQUFHLElBQUksQ0FHeEQ7SUFFRDs7O09BR0c7SUFDVSxJQUFJLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQXdEakM7WUFHYSxXQUFXO0lBNkV6Qjs7Ozs7Ozs7Ozs7T0FXRztJQUNILFVBQWdCLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxtQkFBbUIsR0FBRyxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FtQnRGO0NBQ0YifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data_withholding_watcher.d.ts","sourceRoot":"","sources":["../../src/watchers/data_withholding_watcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,4BAA4B,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAClG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAC1F,OAAO,EAAoB,KAAK,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAMxF,OAAO,EAA6C,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAE7G,QAAA,MAAM,gCAAgC,gFAAiF,CAAC;AAExH,KAAK,4BAA4B,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,gCAAgC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;;AAE3G
|
|
1
|
+
{"version":3,"file":"data_withholding_watcher.d.ts","sourceRoot":"","sources":["../../src/watchers/data_withholding_watcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,4BAA4B,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAClG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAC1F,OAAO,EAAoB,KAAK,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAMxF,OAAO,EAA6C,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAE7G,QAAA,MAAM,gCAAgC,gFAAiF,CAAC;AAExH,KAAK,4BAA4B,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,gCAAgC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;;AAE3G;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,sBAAuB,SAAQ,2BAA2C,YAAW,OAAO;IAQrG,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAEjC,OAAO,CAAC,QAAQ,CAAC,GAAG;IAdtB,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,eAAe,CAAyB;IAChD,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,cAAc,CAAS;IAE/B,YACmB,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,eAAe,GAAG,uBAAuB,CAAC,EAC7E,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,EACvC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,kCAAkC,GAAG,oBAAoB,CAAC,EAC5E,kBAAkB,EAAE,IAAI,CAAC,4BAA4B,EAAE,uBAAuB,CAAC,EAC/E,gBAAgB,EAAE,4BAA4B,EAC/D,MAAM,EAAE,4BAA4B,EACnB,GAAG,GAAE,MAAiD,EAOxE;IAEY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAQlC;IAEM,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3B;IAEM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAGxD;IAED;;;OAGG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAwDjC;YAGa,WAAW;IA6EzB;;;;;;;;;;;OAWG;IACH,UAAgB,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAmBtF;CACF"}
|
|
@@ -24,6 +24,11 @@ const DataWithholdingWatcherConfigKeys = [
|
|
|
24
24
|
* The watcher ticks at quarter-eth-slot cadence (matching the Sentinel template). On boot it
|
|
25
25
|
* floors processing at the current slot — restart-time gaps are accepted and not back-filled,
|
|
26
26
|
* matching the Sentinel approach.
|
|
27
|
+
*
|
|
28
|
+
* Since the evidence for an offense is the absence of txs in the local pool, the probe is gated on
|
|
29
|
+
* p2p connectivity: while there are no connected peers, slots are skipped instead of probed, since
|
|
30
|
+
* missing txs then say nothing about the attesters. Nodes running with p2p disabled do not run this
|
|
31
|
+
* watcher at all.
|
|
27
32
|
*/ export class DataWithholdingWatcher extends EventEmitter {
|
|
28
33
|
epochCache;
|
|
29
34
|
l2BlockSource;
|
|
@@ -36,8 +41,9 @@ const DataWithholdingWatcherConfigKeys = [
|
|
|
36
41
|
initialSlot;
|
|
37
42
|
lastCheckedSlot;
|
|
38
43
|
config;
|
|
44
|
+
gossipDegraded;
|
|
39
45
|
constructor(epochCache, l2BlockSource, txProvider, p2p, reexecutionTracker, signatureContext, config, log = createLogger('data-withholding-watcher')){
|
|
40
|
-
super(), this.epochCache = epochCache, this.l2BlockSource = l2BlockSource, this.txProvider = txProvider, this.p2p = p2p, this.reexecutionTracker = reexecutionTracker, this.signatureContext = signatureContext, this.log = log;
|
|
46
|
+
super(), this.epochCache = epochCache, this.l2BlockSource = l2BlockSource, this.txProvider = txProvider, this.p2p = p2p, this.reexecutionTracker = reexecutionTracker, this.signatureContext = signatureContext, this.log = log, this.gossipDegraded = false;
|
|
41
47
|
this.config = pick(config, ...DataWithholdingWatcherConfigKeys);
|
|
42
48
|
const interval = epochCache.getL1Constants().ethereumSlotDuration * 1000 / 4;
|
|
43
49
|
this.runningPromise = new RunningPromise(this.work.bind(this), log, interval);
|
|
@@ -80,6 +86,30 @@ const DataWithholdingWatcherConfigKeys = [
|
|
|
80
86
|
if (targetSlot <= this.initialSlot) {
|
|
81
87
|
return;
|
|
82
88
|
}
|
|
89
|
+
// Missing txs are only evidence of withholding if we could have received them. Slots probed
|
|
90
|
+
// while gossip is down are skipped for good rather than deferred: once peers return, txs from
|
|
91
|
+
// those checkpoints may already have been evicted from the pool as mined, so a late probe would
|
|
92
|
+
// still report them missing. An unknown must not turn into an offense. Note this deliberately
|
|
93
|
+
// ignores whether p2p is enabled: a node with no p2p stack sees even less than a peerless one.
|
|
94
|
+
const connectivity = await this.p2p.getP2PConnectivity();
|
|
95
|
+
if (connectivity.connectedPeers === 0) {
|
|
96
|
+
if (!this.gossipDegraded) {
|
|
97
|
+
this.gossipDegraded = true;
|
|
98
|
+
this.log.warn(`Skipping data-withholding checks while no peers are connected`, {
|
|
99
|
+
targetSlot,
|
|
100
|
+
lastCheckedSlot: this.lastCheckedSlot
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
this.lastCheckedSlot = targetSlot;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (this.gossipDegraded) {
|
|
107
|
+
this.gossipDegraded = false;
|
|
108
|
+
this.log.info(`Resuming data-withholding checks now that peers are connected`, {
|
|
109
|
+
targetSlot,
|
|
110
|
+
connectedPeers: connectivity.connectedPeers
|
|
111
|
+
});
|
|
112
|
+
}
|
|
83
113
|
const startSlot = this.lastCheckedSlot === undefined ? this.initialSlot : this.lastCheckedSlot;
|
|
84
114
|
for(let slot = SlotNumber(startSlot + 1); slot <= targetSlot; slot = SlotNumber(slot + 1)){
|
|
85
115
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/slasher",
|
|
3
|
-
"version": "5.2.0-nightly.
|
|
3
|
+
"version": "5.2.0-nightly.20260815",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -56,20 +56,20 @@
|
|
|
56
56
|
]
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@aztec/epoch-cache": "5.2.0-nightly.
|
|
60
|
-
"@aztec/ethereum": "5.2.0-nightly.
|
|
61
|
-
"@aztec/foundation": "5.2.0-nightly.
|
|
62
|
-
"@aztec/kv-store": "5.2.0-nightly.
|
|
63
|
-
"@aztec/l1-artifacts": "5.2.0-nightly.
|
|
64
|
-
"@aztec/stdlib": "5.2.0-nightly.
|
|
65
|
-
"@aztec/telemetry-client": "5.2.0-nightly.
|
|
59
|
+
"@aztec/epoch-cache": "5.2.0-nightly.20260815",
|
|
60
|
+
"@aztec/ethereum": "5.2.0-nightly.20260815",
|
|
61
|
+
"@aztec/foundation": "5.2.0-nightly.20260815",
|
|
62
|
+
"@aztec/kv-store": "5.2.0-nightly.20260815",
|
|
63
|
+
"@aztec/l1-artifacts": "5.2.0-nightly.20260815",
|
|
64
|
+
"@aztec/stdlib": "5.2.0-nightly.20260815",
|
|
65
|
+
"@aztec/telemetry-client": "5.2.0-nightly.20260815",
|
|
66
66
|
"source-map-support": "^0.5.21",
|
|
67
67
|
"tslib": "^2.4.0",
|
|
68
68
|
"viem": "npm:@aztec/viem@2.38.2",
|
|
69
69
|
"zod": "^4"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@aztec/aztec.js": "5.2.0-nightly.
|
|
72
|
+
"@aztec/aztec.js": "5.2.0-nightly.20260815",
|
|
73
73
|
"@jest/globals": "^30.0.0",
|
|
74
74
|
"@types/jest": "^30.0.0",
|
|
75
75
|
"@types/node": "^22.15.17",
|
|
@@ -33,18 +33,24 @@ type DataWithholdingWatcherConfig = Pick<SlasherConfig, (typeof DataWithholdingW
|
|
|
33
33
|
* The watcher ticks at quarter-eth-slot cadence (matching the Sentinel template). On boot it
|
|
34
34
|
* floors processing at the current slot — restart-time gaps are accepted and not back-filled,
|
|
35
35
|
* matching the Sentinel approach.
|
|
36
|
+
*
|
|
37
|
+
* Since the evidence for an offense is the absence of txs in the local pool, the probe is gated on
|
|
38
|
+
* p2p connectivity: while there are no connected peers, slots are skipped instead of probed, since
|
|
39
|
+
* missing txs then say nothing about the attesters. Nodes running with p2p disabled do not run this
|
|
40
|
+
* watcher at all.
|
|
36
41
|
*/
|
|
37
42
|
export class DataWithholdingWatcher extends (EventEmitter as new () => WatcherEmitter) implements Watcher {
|
|
38
43
|
private runningPromise: RunningPromise;
|
|
39
44
|
private initialSlot: SlotNumber | undefined;
|
|
40
45
|
private lastCheckedSlot: SlotNumber | undefined;
|
|
41
46
|
private config: DataWithholdingWatcherConfig;
|
|
47
|
+
private gossipDegraded = false;
|
|
42
48
|
|
|
43
49
|
constructor(
|
|
44
50
|
private readonly epochCache: EpochCache,
|
|
45
51
|
private readonly l2BlockSource: Pick<L2BlockSource, 'getCheckpoint' | 'getSyncedL2SlotNumber'>,
|
|
46
52
|
private readonly txProvider: Pick<ITxProvider, 'hasTxs'>,
|
|
47
|
-
private readonly p2p: Pick<P2PApi, 'getCheckpointAttestationsForSlot'>,
|
|
53
|
+
private readonly p2p: Pick<P2PApi, 'getCheckpointAttestationsForSlot' | 'getP2PConnectivity'>,
|
|
48
54
|
private readonly reexecutionTracker: Pick<CheckpointReexecutionTracker, 'getTxsCollectedRecord'>,
|
|
49
55
|
private readonly signatureContext: CoordinationSignatureContext,
|
|
50
56
|
config: DataWithholdingWatcherConfig,
|
|
@@ -101,6 +107,32 @@ export class DataWithholdingWatcher extends (EventEmitter as new () => WatcherEm
|
|
|
101
107
|
return;
|
|
102
108
|
}
|
|
103
109
|
|
|
110
|
+
// Missing txs are only evidence of withholding if we could have received them. Slots probed
|
|
111
|
+
// while gossip is down are skipped for good rather than deferred: once peers return, txs from
|
|
112
|
+
// those checkpoints may already have been evicted from the pool as mined, so a late probe would
|
|
113
|
+
// still report them missing. An unknown must not turn into an offense. Note this deliberately
|
|
114
|
+
// ignores whether p2p is enabled: a node with no p2p stack sees even less than a peerless one.
|
|
115
|
+
const connectivity = await this.p2p.getP2PConnectivity();
|
|
116
|
+
if (connectivity.connectedPeers === 0) {
|
|
117
|
+
if (!this.gossipDegraded) {
|
|
118
|
+
this.gossipDegraded = true;
|
|
119
|
+
this.log.warn(`Skipping data-withholding checks while no peers are connected`, {
|
|
120
|
+
targetSlot,
|
|
121
|
+
lastCheckedSlot: this.lastCheckedSlot,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
this.lastCheckedSlot = targetSlot;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (this.gossipDegraded) {
|
|
129
|
+
this.gossipDegraded = false;
|
|
130
|
+
this.log.info(`Resuming data-withholding checks now that peers are connected`, {
|
|
131
|
+
targetSlot,
|
|
132
|
+
connectedPeers: connectivity.connectedPeers,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
104
136
|
const startSlot = this.lastCheckedSlot === undefined ? this.initialSlot : this.lastCheckedSlot;
|
|
105
137
|
for (let slot = SlotNumber(startSlot + 1); slot <= targetSlot; slot = SlotNumber(slot + 1)) {
|
|
106
138
|
try {
|