@aztec/aztec-node 0.0.1-commit.0c875d939 → 0.0.1-commit.0dc957cde
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/dest/aztec-node/config.d.ts +8 -5
- package/dest/aztec-node/config.d.ts.map +1 -1
- package/dest/aztec-node/config.js +11 -3
- package/dest/aztec-node/server.d.ts +48 -36
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +574 -281
- package/dest/sentinel/factory.d.ts +2 -2
- package/dest/sentinel/factory.d.ts.map +1 -1
- package/dest/sentinel/sentinel.d.ts +1 -1
- package/dest/sentinel/sentinel.d.ts.map +1 -1
- package/dest/sentinel/sentinel.js +24 -17
- package/package.json +26 -25
- package/src/aztec-node/config.ts +25 -9
- package/src/aztec-node/server.ts +710 -354
- package/src/sentinel/factory.ts +1 -1
- package/src/sentinel/sentinel.ts +24 -15
package/src/sentinel/factory.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
2
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
-
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
4
3
|
import { createStore } from '@aztec/kv-store/lmdb-v2';
|
|
5
4
|
import type { P2PClient } from '@aztec/p2p';
|
|
6
5
|
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
7
6
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
7
|
+
import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
|
|
8
8
|
|
|
9
9
|
import type { SentinelConfig } from './config.js';
|
|
10
10
|
import { Sentinel } from './sentinel.js';
|
package/src/sentinel/sentinel.ts
CHANGED
|
@@ -88,7 +88,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
88
88
|
|
|
89
89
|
/** Loads initial slot and initializes blockstream. We will not process anything at or before the initial slot. */
|
|
90
90
|
protected async init() {
|
|
91
|
-
this.initialSlot = this.epochCache.
|
|
91
|
+
this.initialSlot = this.epochCache.getSlotNow();
|
|
92
92
|
const startingBlock = BlockNumber(await this.archiver.getBlockNumber());
|
|
93
93
|
this.logger.info(`Starting validator sentinel with initial slot ${this.initialSlot} and block ${startingBlock}`);
|
|
94
94
|
this.blockStream = new L2BlockStream(this.archiver, this.l2TipsStore, this, this.logger, { startingBlock });
|
|
@@ -139,15 +139,15 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
139
139
|
return;
|
|
140
140
|
}
|
|
141
141
|
const blockNumber = event.block.number;
|
|
142
|
-
const
|
|
143
|
-
if (!
|
|
144
|
-
this.logger.error(`Failed to get block ${blockNumber}
|
|
142
|
+
const header = await this.archiver.getBlockHeader(blockNumber);
|
|
143
|
+
if (!header) {
|
|
144
|
+
this.logger.error(`Failed to get block header ${blockNumber}`);
|
|
145
145
|
return;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
// TODO(palla/slash): We should only be computing proven performance if this is
|
|
149
149
|
// a full proof epoch and not a partial one, otherwise we'll end up with skewed stats.
|
|
150
|
-
const epoch = getEpochAtSlot(
|
|
150
|
+
const epoch = getEpochAtSlot(header.getSlot(), this.epochCache.getL1Constants());
|
|
151
151
|
this.logger.debug(`Computing proven performance for epoch ${epoch}`);
|
|
152
152
|
const performance = await this.computeProvenPerformance(epoch);
|
|
153
153
|
this.logger.info(`Computed proven performance for epoch ${epoch}`, performance);
|
|
@@ -158,7 +158,11 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
158
158
|
|
|
159
159
|
protected async computeProvenPerformance(epoch: EpochNumber): Promise<ValidatorsEpochPerformance> {
|
|
160
160
|
const [fromSlot, toSlot] = getSlotRangeForEpoch(epoch, this.epochCache.getL1Constants());
|
|
161
|
-
const { committee } = await this.epochCache.getCommittee(fromSlot);
|
|
161
|
+
const { committee, isEscapeHatchOpen } = await this.epochCache.getCommittee(fromSlot);
|
|
162
|
+
if (isEscapeHatchOpen) {
|
|
163
|
+
this.logger.info(`Skipping proven performance for epoch ${epoch} - escape hatch is open`);
|
|
164
|
+
return {};
|
|
165
|
+
}
|
|
162
166
|
if (!committee) {
|
|
163
167
|
this.logger.trace(`No committee found for slot ${fromSlot}`);
|
|
164
168
|
return {};
|
|
@@ -215,7 +219,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
215
219
|
// Check that we have at least requiredConsecutiveEpochs and that all of them are above the inactivity threshold
|
|
216
220
|
return pastEpochs
|
|
217
221
|
.slice(0, requiredConsecutiveEpochs)
|
|
218
|
-
.every(p => p.missed / p.total >= this.config.slashInactivityTargetPercentage);
|
|
222
|
+
.every(p => (p.total === 0 ? false : p.missed / p.total >= this.config.slashInactivityTargetPercentage));
|
|
219
223
|
}
|
|
220
224
|
|
|
221
225
|
protected async handleProvenPerformance(epoch: EpochNumber, performance: ValidatorsEpochPerformance) {
|
|
@@ -224,7 +228,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
224
228
|
}
|
|
225
229
|
|
|
226
230
|
const inactiveValidators = getEntries(performance)
|
|
227
|
-
.filter(([_, { missed, total }]) => missed / total >= this.config.slashInactivityTargetPercentage)
|
|
231
|
+
.filter(([_, { missed, total }]) => total > 0 && missed / total >= this.config.slashInactivityTargetPercentage)
|
|
228
232
|
.map(([address]) => address);
|
|
229
233
|
|
|
230
234
|
this.logger.debug(`Found ${inactiveValidators.length} inactive validators in epoch ${epoch}`, {
|
|
@@ -260,7 +264,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
260
264
|
* and we don't have that data if we were offline during the period.
|
|
261
265
|
*/
|
|
262
266
|
public async work() {
|
|
263
|
-
const
|
|
267
|
+
const currentSlot = this.epochCache.getSlotNow();
|
|
264
268
|
try {
|
|
265
269
|
// Manually sync the block stream to ensure we have the latest data.
|
|
266
270
|
// Note we never `start` the blockstream, so it loops at the same pace as we do.
|
|
@@ -305,9 +309,9 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
305
309
|
return false;
|
|
306
310
|
}
|
|
307
311
|
|
|
308
|
-
const
|
|
309
|
-
if (
|
|
310
|
-
this.logger.debug(`Waiting for archiver to sync with L2 slot ${targetSlot}`, {
|
|
312
|
+
const syncedSlot = await this.archiver.getSyncedL2SlotNumber();
|
|
313
|
+
if (syncedSlot === undefined || syncedSlot < targetSlot) {
|
|
314
|
+
this.logger.debug(`Waiting for archiver to sync with L2 slot ${targetSlot}`, { syncedSlot, targetSlot });
|
|
311
315
|
return false;
|
|
312
316
|
}
|
|
313
317
|
|
|
@@ -327,7 +331,12 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
327
331
|
* and updates overall stats.
|
|
328
332
|
*/
|
|
329
333
|
protected async processSlot(slot: SlotNumber) {
|
|
330
|
-
const { epoch, seed, committee } = await this.epochCache.getCommittee(slot);
|
|
334
|
+
const { epoch, seed, committee, isEscapeHatchOpen } = await this.epochCache.getCommittee(slot);
|
|
335
|
+
if (isEscapeHatchOpen) {
|
|
336
|
+
this.logger.info(`Skipping slot ${slot} at epoch ${epoch} - escape hatch is open`);
|
|
337
|
+
this.lastProcessedSlot = slot;
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
331
340
|
if (!committee || committee.length === 0) {
|
|
332
341
|
this.logger.trace(`No committee found for slot ${slot} at epoch ${epoch}`);
|
|
333
342
|
this.lastProcessedSlot = slot;
|
|
@@ -427,7 +436,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
427
436
|
? fromEntries(await Promise.all(validators.map(async v => [v.toString(), await this.store.getHistory(v)])))
|
|
428
437
|
: await this.store.getHistories();
|
|
429
438
|
|
|
430
|
-
const slotNow = this.epochCache.
|
|
439
|
+
const slotNow = this.epochCache.getSlotNow();
|
|
431
440
|
fromSlot ??= SlotNumber(Math.max((this.lastProcessedSlot ?? slotNow) - this.store.getHistoryLength(), 0));
|
|
432
441
|
toSlot ??= this.lastProcessedSlot ?? slotNow;
|
|
433
442
|
|
|
@@ -455,7 +464,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
455
464
|
return undefined;
|
|
456
465
|
}
|
|
457
466
|
|
|
458
|
-
const slotNow = this.epochCache.
|
|
467
|
+
const slotNow = this.epochCache.getSlotNow();
|
|
459
468
|
const effectiveFromSlot =
|
|
460
469
|
fromSlot ?? SlotNumber(Math.max((this.lastProcessedSlot ?? slotNow) - this.store.getHistoryLength(), 0));
|
|
461
470
|
const effectiveToSlot = toSlot ?? this.lastProcessedSlot ?? slotNow;
|