@aztec/aztec-node 0.0.1-commit.21caa21 → 0.0.1-commit.21ecf947b
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 +5 -2
- package/dest/aztec-node/config.d.ts.map +1 -1
- package/dest/aztec-node/config.js +7 -1
- package/dest/aztec-node/node_metrics.d.ts +1 -1
- package/dest/aztec-node/node_metrics.d.ts.map +1 -1
- package/dest/aztec-node/node_metrics.js +9 -16
- package/dest/aztec-node/server.d.ts +52 -122
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +639 -206
- package/dest/sentinel/factory.d.ts +1 -1
- package/dest/sentinel/factory.d.ts.map +1 -1
- package/dest/sentinel/factory.js +1 -1
- package/dest/sentinel/sentinel.d.ts +6 -5
- package/dest/sentinel/sentinel.d.ts.map +1 -1
- package/dest/sentinel/sentinel.js +68 -44
- package/dest/sentinel/store.d.ts +2 -2
- package/dest/sentinel/store.d.ts.map +1 -1
- package/dest/sentinel/store.js +11 -7
- package/package.json +28 -28
- package/src/aztec-node/config.ts +12 -8
- package/src/aztec-node/node_metrics.ts +6 -17
- package/src/aztec-node/server.ts +326 -279
- package/src/sentinel/factory.ts +1 -6
- package/src/sentinel/sentinel.ts +80 -47
- package/src/sentinel/store.ts +12 -12
|
@@ -6,4 +6,4 @@ import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
|
6
6
|
import type { SentinelConfig } from './config.js';
|
|
7
7
|
import { Sentinel } from './sentinel.js';
|
|
8
8
|
export declare function createSentinel(epochCache: EpochCache, archiver: L2BlockSource, p2p: P2PClient, config: SentinelConfig & DataStoreConfig & SlasherConfig, logger?: import("@aztec/foundation/log").Logger): Promise<Sentinel | undefined>;
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlbnRpbmVsL2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFckQsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFOUQsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzVDLE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRXJFLE9BQU8sS0FBSyxFQUFFLGNBQWMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR3pDLHdCQUFzQixjQUFjLENBQ2xDLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFFBQVEsRUFBRSxhQUFhLEVBQ3ZCLEdBQUcsRUFBRSxTQUFTLEVBQ2QsTUFBTSxFQUFFLGNBQWMsR0FBRyxlQUFlLEdBQUcsYUFBYSxFQUN4RCxNQUFNLHlDQUFnQyxHQUNyQyxPQUFPLENBQUMsUUFBUSxHQUFHLFNBQVMsQ0FBQyxDQVkvQiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/sentinel/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,wBAAsB,cAAc,CAClC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,aAAa,EACvB,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,cAAc,GAAG,eAAe,GAAG,aAAa,EACxD,MAAM,yCAAgC,GACrC,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/sentinel/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,wBAAsB,cAAc,CAClC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,aAAa,EACvB,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,cAAc,GAAG,eAAe,GAAG,aAAa,EACxD,MAAM,yCAAgC,GACrC,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAY/B"}
|
package/dest/sentinel/factory.js
CHANGED
|
@@ -6,7 +6,7 @@ export async function createSentinel(epochCache, archiver, p2p, config, logger =
|
|
|
6
6
|
if (!config.sentinelEnabled) {
|
|
7
7
|
return undefined;
|
|
8
8
|
}
|
|
9
|
-
const kvStore = await createStore('sentinel', SentinelStore.SCHEMA_VERSION, config,
|
|
9
|
+
const kvStore = await createStore('sentinel', SentinelStore.SCHEMA_VERSION, config, logger.getBindings());
|
|
10
10
|
const storeHistoryLength = config.sentinelHistoryLengthInEpochs * epochCache.getL1Constants().epochDuration;
|
|
11
11
|
const storeHistoricProvenPerformanceLength = config.sentinelHistoricProvenPerformanceLengthInEpochs;
|
|
12
12
|
const sentinelStore = new SentinelStore(kvStore, {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
2
|
-
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
4
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
5
5
|
import { type L2TipsStore } from '@aztec/kv-store/stores';
|
|
@@ -22,8 +22,8 @@ export declare class Sentinel extends Sentinel_base implements L2BlockStreamEven
|
|
|
22
22
|
protected l2TipsStore: L2TipsStore;
|
|
23
23
|
protected initialSlot: SlotNumber | undefined;
|
|
24
24
|
protected lastProcessedSlot: SlotNumber | undefined;
|
|
25
|
-
protected
|
|
26
|
-
|
|
25
|
+
protected slotNumberToCheckpoint: Map<SlotNumber, {
|
|
26
|
+
checkpointNumber: CheckpointNumber;
|
|
27
27
|
archive: string;
|
|
28
28
|
attestors: EthAddress[];
|
|
29
29
|
}>;
|
|
@@ -34,6 +34,7 @@ export declare class Sentinel extends Sentinel_base implements L2BlockStreamEven
|
|
|
34
34
|
protected init(): Promise<void>;
|
|
35
35
|
stop(): Promise<void>;
|
|
36
36
|
handleBlockStreamEvent(event: L2BlockStreamEvent): Promise<void>;
|
|
37
|
+
protected handleCheckpoint(event: L2BlockStreamEvent): void;
|
|
37
38
|
protected handleChainProven(event: L2BlockStreamEvent): Promise<void>;
|
|
38
39
|
protected computeProvenPerformance(epoch: EpochNumber): Promise<ValidatorsEpochPerformance>;
|
|
39
40
|
/**
|
|
@@ -76,7 +77,7 @@ export declare class Sentinel extends Sentinel_base implements L2BlockStreamEven
|
|
|
76
77
|
/** Computes stats for a single validator. */
|
|
77
78
|
getValidatorStats(validatorAddress: EthAddress, fromSlot?: SlotNumber, toSlot?: SlotNumber): Promise<SingleValidatorStats | undefined>;
|
|
78
79
|
protected computeStatsForValidator(address: `0x${string}`, allHistory: ValidatorStatusHistory, fromSlot?: SlotNumber, toSlot?: SlotNumber): ValidatorStats;
|
|
79
|
-
protected computeMissed(history: ValidatorStatusHistory,
|
|
80
|
+
protected computeMissed(history: ValidatorStatusHistory, computeOverCategory: ValidatorStatusType | undefined, filter: ValidatorStatusInSlot[]): {
|
|
80
81
|
currentStreak: number;
|
|
81
82
|
rate: number | undefined;
|
|
82
83
|
count: number;
|
|
@@ -89,4 +90,4 @@ export declare class Sentinel extends Sentinel_base implements L2BlockStreamEven
|
|
|
89
90
|
} | undefined;
|
|
90
91
|
}
|
|
91
92
|
export {};
|
|
92
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
93
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VudGluZWwuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZW50aW5lbC9zZW50aW5lbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEVBQWUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRXpHLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUUzRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDbkUsT0FBTyxFQUFxQixLQUFLLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdFLE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUM1QyxPQUFPLEVBSUwsS0FBSyxPQUFPLEVBQ1osS0FBSyxjQUFjLEVBQ3BCLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDM0QsT0FBTyxFQUNMLEtBQUssYUFBYSxFQUNsQixhQUFhLEVBQ2IsS0FBSyxrQkFBa0IsRUFDdkIsS0FBSyx5QkFBeUIsRUFFL0IsTUFBTSxxQkFBcUIsQ0FBQztBQUU3QixPQUFPLEtBQUssRUFDVixvQkFBb0IsRUFDcEIsY0FBYyxFQUNkLHNCQUFzQixFQUN0QixxQkFBcUIsRUFDckIsbUJBQW1CLEVBQ25CLDBCQUEwQixFQUMxQixlQUFlLEVBQ2hCLE1BQU0sMEJBQTBCLENBQUM7QUFJbEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFlBQVksQ0FBQzs7QUFhM0MscUJBQWEsUUFBUyxTQUFRLGFBQTJDLFlBQVcseUJBQXlCLEVBQUUsT0FBTztJQWNsSCxTQUFTLENBQUMsVUFBVSxFQUFFLFVBQVU7SUFDaEMsU0FBUyxDQUFDLFFBQVEsRUFBRSxhQUFhO0lB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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sentinel.d.ts","sourceRoot":"","sources":["../../src/sentinel/sentinel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"sentinel.d.ts","sourceRoot":"","sources":["../../src/sentinel/sentinel.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,22 @@
|
|
|
1
|
-
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
|
+
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import { countWhile, filterAsync, fromEntries, getEntries, mapValues } from '@aztec/foundation/collection';
|
|
3
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
5
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
6
6
|
import { L2TipsMemoryStore } from '@aztec/kv-store/stores';
|
|
7
7
|
import { OffenseType, WANT_TO_SLASH_EVENT } from '@aztec/slasher';
|
|
8
|
-
import { L2BlockStream,
|
|
8
|
+
import { L2BlockStream, getAttestationInfoFromPublishedCheckpoint } from '@aztec/stdlib/block';
|
|
9
9
|
import { getEpochAtSlot, getSlotRangeForEpoch, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
10
10
|
import EventEmitter from 'node:events';
|
|
11
|
+
/** Maps a validator status to its category: proposer or attestation. */ function statusToCategory(status) {
|
|
12
|
+
switch(status){
|
|
13
|
+
case 'attestation-sent':
|
|
14
|
+
case 'attestation-missed':
|
|
15
|
+
return 'attestation';
|
|
16
|
+
default:
|
|
17
|
+
return 'proposer';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
11
20
|
export class Sentinel extends EventEmitter {
|
|
12
21
|
epochCache;
|
|
13
22
|
archiver;
|
|
@@ -21,9 +30,9 @@ export class Sentinel extends EventEmitter {
|
|
|
21
30
|
initialSlot;
|
|
22
31
|
lastProcessedSlot;
|
|
23
32
|
// eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
|
|
24
|
-
|
|
33
|
+
slotNumberToCheckpoint;
|
|
25
34
|
constructor(epochCache, archiver, p2p, store, config, logger = createLogger('node:sentinel')){
|
|
26
|
-
super(), this.epochCache = epochCache, this.archiver = archiver, this.p2p = p2p, this.store = store, this.config = config, this.logger = logger, this.
|
|
35
|
+
super(), this.epochCache = epochCache, this.archiver = archiver, this.p2p = p2p, this.store = store, this.config = config, this.logger = logger, this.slotNumberToCheckpoint = new Map();
|
|
27
36
|
this.l2TipsStore = new L2TipsMemoryStore();
|
|
28
37
|
const interval = epochCache.getL1Constants().ethereumSlotDuration * 1000 / 4;
|
|
29
38
|
this.runningPromise = new RunningPromise(this.work.bind(this), logger, interval);
|
|
@@ -40,7 +49,7 @@ export class Sentinel extends EventEmitter {
|
|
|
40
49
|
}
|
|
41
50
|
/** Loads initial slot and initializes blockstream. We will not process anything at or before the initial slot. */ async init() {
|
|
42
51
|
this.initialSlot = this.epochCache.getEpochAndSlotNow().slot;
|
|
43
|
-
const startingBlock = await this.archiver.getBlockNumber();
|
|
52
|
+
const startingBlock = BlockNumber(await this.archiver.getBlockNumber());
|
|
44
53
|
this.logger.info(`Starting validator sentinel with initial slot ${this.initialSlot} and block ${startingBlock}`);
|
|
45
54
|
this.blockStream = new L2BlockStream(this.archiver, this.l2TipsStore, this, this.logger, {
|
|
46
55
|
startingBlock
|
|
@@ -51,33 +60,38 @@ export class Sentinel extends EventEmitter {
|
|
|
51
60
|
}
|
|
52
61
|
async handleBlockStreamEvent(event) {
|
|
53
62
|
await this.l2TipsStore.handleBlockStreamEvent(event);
|
|
54
|
-
if (event.type === '
|
|
55
|
-
|
|
56
|
-
for (const block of event.blocks){
|
|
57
|
-
this.slotNumberToBlock.set(block.block.header.getSlot(), {
|
|
58
|
-
blockNumber: block.block.number,
|
|
59
|
-
archive: block.block.archive.root.toString(),
|
|
60
|
-
attestors: getAttestationInfoFromPublishedL2Block(block).filter((a)=>a.status === 'recovered-from-signature').map((a)=>a.address)
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
// Prune the archive map to only keep at most N entries
|
|
64
|
-
const historyLength = this.store.getHistoryLength();
|
|
65
|
-
if (this.slotNumberToBlock.size > historyLength) {
|
|
66
|
-
const toDelete = Array.from(this.slotNumberToBlock.keys()).sort((a, b)=>Number(a - b)).slice(0, this.slotNumberToBlock.size - historyLength);
|
|
67
|
-
for (const key of toDelete){
|
|
68
|
-
this.slotNumberToBlock.delete(key);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
63
|
+
if (event.type === 'chain-checkpointed') {
|
|
64
|
+
this.handleCheckpoint(event);
|
|
71
65
|
} else if (event.type === 'chain-proven') {
|
|
72
66
|
await this.handleChainProven(event);
|
|
73
67
|
}
|
|
74
68
|
}
|
|
69
|
+
handleCheckpoint(event) {
|
|
70
|
+
if (event.type !== 'chain-checkpointed') {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const checkpoint = event.checkpoint;
|
|
74
|
+
// Store mapping from slot to archive, checkpoint number, and attestors
|
|
75
|
+
this.slotNumberToCheckpoint.set(checkpoint.checkpoint.header.slotNumber, {
|
|
76
|
+
checkpointNumber: checkpoint.checkpoint.number,
|
|
77
|
+
archive: checkpoint.checkpoint.archive.root.toString(),
|
|
78
|
+
attestors: getAttestationInfoFromPublishedCheckpoint(checkpoint).filter((a)=>a.status === 'recovered-from-signature').map((a)=>a.address)
|
|
79
|
+
});
|
|
80
|
+
// Prune the archive map to only keep at most N entries
|
|
81
|
+
const historyLength = this.store.getHistoryLength();
|
|
82
|
+
if (this.slotNumberToCheckpoint.size > historyLength) {
|
|
83
|
+
const toDelete = Array.from(this.slotNumberToCheckpoint.keys()).sort((a, b)=>Number(a - b)).slice(0, this.slotNumberToCheckpoint.size - historyLength);
|
|
84
|
+
for (const key of toDelete){
|
|
85
|
+
this.slotNumberToCheckpoint.delete(key);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
75
89
|
async handleChainProven(event) {
|
|
76
90
|
if (event.type !== 'chain-proven') {
|
|
77
91
|
return;
|
|
78
92
|
}
|
|
79
93
|
const blockNumber = event.block.number;
|
|
80
|
-
const block = await this.archiver.
|
|
94
|
+
const block = await this.archiver.getL2Block(blockNumber);
|
|
81
95
|
if (!block) {
|
|
82
96
|
this.logger.error(`Failed to get block ${blockNumber}`, {
|
|
83
97
|
block
|
|
@@ -221,8 +235,8 @@ export class Sentinel extends EventEmitter {
|
|
|
221
235
|
});
|
|
222
236
|
return false;
|
|
223
237
|
}
|
|
224
|
-
const archiverLastBlockHash = await this.l2TipsStore.getL2Tips().then((tip)=>tip.
|
|
225
|
-
const p2pLastBlockHash = await this.p2p.getL2Tips().then((tips)=>tips.
|
|
238
|
+
const archiverLastBlockHash = await this.l2TipsStore.getL2Tips().then((tip)=>tip.proposed.hash);
|
|
239
|
+
const p2pLastBlockHash = await this.p2p.getL2Tips().then((tips)=>tips.proposed.hash);
|
|
226
240
|
const isP2pSynced = archiverLastBlockHash === p2pLastBlockHash;
|
|
227
241
|
if (!isP2pSynced) {
|
|
228
242
|
this.logger.debug(`Waiting for P2P client to sync with archiver`, {
|
|
@@ -258,17 +272,17 @@ export class Sentinel extends EventEmitter {
|
|
|
258
272
|
committee
|
|
259
273
|
});
|
|
260
274
|
// Check if there is an L2 block in L1 for this L2 slot
|
|
261
|
-
// Here we get all attestations for the
|
|
262
|
-
// or all attestations for all proposals in the slot if no
|
|
275
|
+
// Here we get all checkpoint attestations for the checkpoint at the given slot,
|
|
276
|
+
// or all checkpoint attestations for all proposals in the slot if no checkpoint was mined.
|
|
263
277
|
// We gather from both p2p (contains the ones seen on the p2p layer) and archiver
|
|
264
|
-
// (contains the ones synced from mined
|
|
265
|
-
const
|
|
266
|
-
const p2pAttested = await this.p2p.
|
|
278
|
+
// (contains the ones synced from mined checkpoints, which we may have missed from p2p).
|
|
279
|
+
const checkpoint = this.slotNumberToCheckpoint.get(slot);
|
|
280
|
+
const p2pAttested = await this.p2p.getCheckpointAttestationsForSlot(slot, checkpoint?.archive);
|
|
267
281
|
// Filter out attestations with invalid signatures
|
|
268
282
|
const p2pAttestors = p2pAttested.map((a)=>a.getSender()).filter((s)=>s !== undefined);
|
|
269
283
|
const attestors = new Set([
|
|
270
284
|
...p2pAttestors.map((a)=>a.toString()),
|
|
271
|
-
...
|
|
285
|
+
...checkpoint?.attestors.map((a)=>a.toString()) ?? []
|
|
272
286
|
].filter((addr)=>proposer.toString() !== addr));
|
|
273
287
|
// We assume that there was a block proposal if at least one of the validators (other than the proposer) attested to it.
|
|
274
288
|
// It could be the case that every single validator failed, and we could differentiate it by having
|
|
@@ -276,17 +290,26 @@ export class Sentinel extends EventEmitter {
|
|
|
276
290
|
// But we'll leave that corner case out to reduce pressure on the node.
|
|
277
291
|
// TODO(palla/slash): This breaks if a given node has more than one validator in the current committee,
|
|
278
292
|
// since they will attest to their own proposal it even if it's not re-executable.
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
293
|
+
let status;
|
|
294
|
+
if (checkpoint) {
|
|
295
|
+
status = 'checkpoint-mined';
|
|
296
|
+
} else if (attestors.size > 0) {
|
|
297
|
+
status = 'checkpoint-proposed';
|
|
298
|
+
} else {
|
|
299
|
+
// No checkpoint on L1 and no checkpoint attestations seen. Check if block proposals were sent for this slot.
|
|
300
|
+
const hasBlockProposals = await this.p2p.hasBlockProposalsForSlot(slot);
|
|
301
|
+
status = hasBlockProposals ? 'checkpoint-missed' : 'blocks-missed';
|
|
302
|
+
}
|
|
303
|
+
this.logger.debug(`Checkpoint status for slot ${slot}: ${status}`, {
|
|
304
|
+
...checkpoint,
|
|
282
305
|
slot
|
|
283
306
|
});
|
|
284
|
-
// Get attestors that failed their
|
|
285
|
-
const missedAttestors = new Set(
|
|
307
|
+
// Get attestors that failed their checkpoint attestation duties, but only if there was a checkpoint proposed or mined
|
|
308
|
+
const missedAttestors = new Set(status === 'blocks-missed' || status === 'checkpoint-missed' ? [] : committee.filter((v)=>!attestors.has(v.toString()) && !proposer.equals(v)).map((v)=>v.toString()));
|
|
286
309
|
this.logger.debug(`Retrieved ${attestors.size} attestors out of ${committee.length} for slot ${slot}`, {
|
|
287
|
-
|
|
310
|
+
status,
|
|
288
311
|
proposer: proposer.toString(),
|
|
289
|
-
...
|
|
312
|
+
...checkpoint,
|
|
290
313
|
slot,
|
|
291
314
|
attestors: [
|
|
292
315
|
...attestors
|
|
@@ -299,7 +322,7 @@ export class Sentinel extends EventEmitter {
|
|
|
299
322
|
// Compute the status for each validator in the committee
|
|
300
323
|
const statusFor = (who)=>{
|
|
301
324
|
if (who === proposer.toString()) {
|
|
302
|
-
return
|
|
325
|
+
return status;
|
|
303
326
|
} else if (attestors.has(who)) {
|
|
304
327
|
return 'attestation-sent';
|
|
305
328
|
} else if (missedAttestors.has(who)) {
|
|
@@ -356,15 +379,16 @@ export class Sentinel extends EventEmitter {
|
|
|
356
379
|
computeStatsForValidator(address, allHistory, fromSlot, toSlot) {
|
|
357
380
|
let history = fromSlot ? allHistory.filter((h)=>BigInt(h.slot) >= fromSlot) : allHistory;
|
|
358
381
|
history = toSlot ? history.filter((h)=>BigInt(h.slot) <= toSlot) : history;
|
|
359
|
-
const lastProposal = history.filter((h)=>h.status === '
|
|
382
|
+
const lastProposal = history.filter((h)=>h.status === 'checkpoint-proposed' || h.status === 'checkpoint-mined').at(-1);
|
|
360
383
|
const lastAttestation = history.filter((h)=>h.status === 'attestation-sent').at(-1);
|
|
361
384
|
return {
|
|
362
385
|
address: EthAddress.fromString(address),
|
|
363
386
|
lastProposal: this.computeFromSlot(lastProposal?.slot),
|
|
364
387
|
lastAttestation: this.computeFromSlot(lastAttestation?.slot),
|
|
365
388
|
totalSlots: history.length,
|
|
366
|
-
missedProposals: this.computeMissed(history, '
|
|
367
|
-
'
|
|
389
|
+
missedProposals: this.computeMissed(history, 'proposer', [
|
|
390
|
+
'checkpoint-missed',
|
|
391
|
+
'blocks-missed'
|
|
368
392
|
]),
|
|
369
393
|
missedAttestations: this.computeMissed(history, 'attestation', [
|
|
370
394
|
'attestation-missed'
|
|
@@ -372,8 +396,8 @@ export class Sentinel extends EventEmitter {
|
|
|
372
396
|
history
|
|
373
397
|
};
|
|
374
398
|
}
|
|
375
|
-
computeMissed(history,
|
|
376
|
-
const relevantHistory = history.filter((h)=>!
|
|
399
|
+
computeMissed(history, computeOverCategory, filter) {
|
|
400
|
+
const relevantHistory = history.filter((h)=>!computeOverCategory || statusToCategory(h.status) === computeOverCategory);
|
|
377
401
|
const filteredHistory = relevantHistory.filter((h)=>filter.includes(h.status));
|
|
378
402
|
return {
|
|
379
403
|
currentStreak: countWhile([
|
package/dest/sentinel/store.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { ValidatorStatusHistory, ValidatorStatusInSlot, ValidatorsEpochPerf
|
|
|
5
5
|
export declare class SentinelStore {
|
|
6
6
|
private store;
|
|
7
7
|
private config;
|
|
8
|
-
static readonly SCHEMA_VERSION
|
|
8
|
+
static readonly SCHEMA_VERSION = 3;
|
|
9
9
|
private readonly historyMap;
|
|
10
10
|
private readonly provenMap;
|
|
11
11
|
constructor(store: AztecAsyncKVStore, config: {
|
|
@@ -32,4 +32,4 @@ export declare class SentinelStore {
|
|
|
32
32
|
private statusToNumber;
|
|
33
33
|
private statusFromNumber;
|
|
34
34
|
}
|
|
35
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
35
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZW50aW5lbC9zdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUUzRCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBaUIsTUFBTSxpQkFBaUIsQ0FBQztBQUN4RSxPQUFPLEtBQUssRUFDVixzQkFBc0IsRUFDdEIscUJBQXFCLEVBQ3JCLDBCQUEwQixFQUMzQixNQUFNLDBCQUEwQixDQUFDO0FBRWxDLHFCQUFhLGFBQWE7SUFXdEIsT0FBTyxDQUFDLEtBQUs7SUFDYixPQUFPLENBQUMsTUFBTTtJQVhoQixnQkFBdUIsY0FBYyxLQUFLO0lBRzFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUF1QztJQUlsRSxPQUFPLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBdUM7SUFFakUsWUFDVSxLQUFLLEVBQUUsaUJBQWlCLEVBQ3hCLE1BQU0sRUFBRTtRQUFFLGFBQWEsRUFBRSxNQUFNLENBQUM7UUFBQywrQkFBK0IsRUFBRSxNQUFNLENBQUE7S0FBRSxFQUluRjtJQUVNLGdCQUFnQixXQUV0QjtJQUVNLGtDQUFrQyxXQUV4QztJQUVZLHVCQUF1QixDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLDBCQUEwQixpQkFNL0Y7SUFFWSxvQkFBb0IsQ0FBQyxHQUFHLEVBQUUsVUFBVSxHQUFHLE9BQU8sQ0FBQztRQUFFLE1BQU0sRUFBRSxNQUFNLENBQUM7UUFBQyxLQUFLLEVBQUUsTUFBTSxDQUFDO1FBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQTtLQUFFLEVBQUUsQ0FBQyxDQUduSDtZQUVhLHNDQUFzQztJQTZCdkMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLEtBQUssTUFBTSxFQUFFLEVBQUUscUJBQXFCLEdBQUcsU0FBUyxDQUFDLGlCQVFqSDtZQUVhLDBCQUEwQjtJQVEzQixZQUFZLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLE1BQU0sRUFBRSxFQUFFLHNCQUFzQixDQUFDLENBQUMsQ0FNbEY7SUFFWSxVQUFVLENBQUMsT0FBTyxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsc0JBQXNCLEdBQUcsU0FBUyxDQUFDLENBR3hGO0lBRUQsT0FBTyxDQUFDLG9CQUFvQjtJQU01QixPQUFPLENBQUMsc0JBQXNCO0lBYTlCLE9BQU8sQ0FBQyxnQkFBZ0I7SUFNeEIsT0FBTyxDQUFDLGtCQUFrQjtJQVcxQixPQUFPLENBQUMsY0FBYztJQXFCdEIsT0FBTyxDQUFDLGdCQUFnQjtDQWtCekIifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/sentinel/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EACV,sBAAsB,EACtB,qBAAqB,EACrB,0BAA0B,EAC3B,MAAM,0BAA0B,CAAC;AAElC,qBAAa,aAAa;IAWtB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,MAAM;IAXhB,gBAAuB,cAAc,
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/sentinel/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EACV,sBAAsB,EACtB,qBAAqB,EACrB,0BAA0B,EAC3B,MAAM,0BAA0B,CAAC;AAElC,qBAAa,aAAa;IAWtB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,MAAM;IAXhB,gBAAuB,cAAc,KAAK;IAG1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuC;IAIlE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IAEjE,YACU,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,+BAA+B,EAAE,MAAM,CAAA;KAAE,EAInF;IAEM,gBAAgB,WAEtB;IAEM,kCAAkC,WAExC;IAEY,uBAAuB,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,0BAA0B,iBAM/F;IAEY,oBAAoB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,WAAW,CAAA;KAAE,EAAE,CAAC,CAGnH;YAEa,sCAAsC;IA6BvC,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,MAAM,EAAE,EAAE,qBAAqB,GAAG,SAAS,CAAC,iBAQjH;YAEa,0BAA0B;IAQ3B,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,MAAM,EAAE,EAAE,sBAAsB,CAAC,CAAC,CAMlF;IAEY,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC,CAGxF;IAED,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,sBAAsB;IAa9B,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,cAAc;IAqBtB,OAAO,CAAC,gBAAgB;CAkBzB"}
|
package/dest/sentinel/store.js
CHANGED
|
@@ -4,7 +4,7 @@ import { BufferReader, numToUInt8, numToUInt32BE, serializeToBuffer } from '@azt
|
|
|
4
4
|
export class SentinelStore {
|
|
5
5
|
store;
|
|
6
6
|
config;
|
|
7
|
-
static SCHEMA_VERSION =
|
|
7
|
+
static SCHEMA_VERSION = 3;
|
|
8
8
|
// a map from validator address to their ValidatorStatusHistory
|
|
9
9
|
historyMap;
|
|
10
10
|
// a map from validator address to their historical proven epoch performance
|
|
@@ -134,16 +134,18 @@ export class SentinelStore {
|
|
|
134
134
|
}
|
|
135
135
|
statusToNumber(status) {
|
|
136
136
|
switch(status){
|
|
137
|
-
case '
|
|
137
|
+
case 'checkpoint-mined':
|
|
138
138
|
return 1;
|
|
139
|
-
case '
|
|
139
|
+
case 'checkpoint-proposed':
|
|
140
140
|
return 2;
|
|
141
|
-
case '
|
|
141
|
+
case 'checkpoint-missed':
|
|
142
142
|
return 3;
|
|
143
143
|
case 'attestation-sent':
|
|
144
144
|
return 4;
|
|
145
145
|
case 'attestation-missed':
|
|
146
146
|
return 5;
|
|
147
|
+
case 'blocks-missed':
|
|
148
|
+
return 6;
|
|
147
149
|
default:
|
|
148
150
|
{
|
|
149
151
|
const _exhaustive = status;
|
|
@@ -154,15 +156,17 @@ export class SentinelStore {
|
|
|
154
156
|
statusFromNumber(status) {
|
|
155
157
|
switch(status){
|
|
156
158
|
case 1:
|
|
157
|
-
return '
|
|
159
|
+
return 'checkpoint-mined';
|
|
158
160
|
case 2:
|
|
159
|
-
return '
|
|
161
|
+
return 'checkpoint-proposed';
|
|
160
162
|
case 3:
|
|
161
|
-
return '
|
|
163
|
+
return 'checkpoint-missed';
|
|
162
164
|
case 4:
|
|
163
165
|
return 'attestation-sent';
|
|
164
166
|
case 5:
|
|
165
167
|
return 'attestation-missed';
|
|
168
|
+
case 6:
|
|
169
|
+
return 'blocks-missed';
|
|
166
170
|
default:
|
|
167
171
|
throw new Error(`Unknown status: ${status}`);
|
|
168
172
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/aztec-node",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.21ecf947b",
|
|
4
4
|
"main": "dest/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
"./sentinel": "./dest/aztec-node/sentinel.js",
|
|
10
10
|
"./test": "./dest/test/index.js"
|
|
11
11
|
},
|
|
12
|
-
"bin": "./dest/bin/index.js",
|
|
13
12
|
"typedocOptions": {
|
|
14
13
|
"entryPoints": [
|
|
15
14
|
"./src/index.ts"
|
|
@@ -20,8 +19,8 @@
|
|
|
20
19
|
"scripts": {
|
|
21
20
|
"start": "node --no-warnings ./dest/bin",
|
|
22
21
|
"start:debug": "node --no-warnings --inspect ./dest/bin",
|
|
23
|
-
"build": "yarn clean &&
|
|
24
|
-
"build:dev": "
|
|
22
|
+
"build": "yarn clean && ../scripts/tsc.sh",
|
|
23
|
+
"build:dev": "../scripts/tsc.sh --watch",
|
|
25
24
|
"clean": "rm -rf ./dest .tsbuildinfo",
|
|
26
25
|
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
|
|
27
26
|
},
|
|
@@ -66,29 +65,30 @@
|
|
|
66
65
|
]
|
|
67
66
|
},
|
|
68
67
|
"dependencies": {
|
|
69
|
-
"@aztec/archiver": "0.0.1-commit.
|
|
70
|
-
"@aztec/bb-prover": "0.0.1-commit.
|
|
71
|
-
"@aztec/blob-
|
|
72
|
-
"@aztec/constants": "0.0.1-commit.
|
|
73
|
-
"@aztec/epoch-cache": "0.0.1-commit.
|
|
74
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
75
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
76
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
77
|
-
"@aztec/l1-artifacts": "0.0.1-commit.
|
|
78
|
-
"@aztec/merkle-tree": "0.0.1-commit.
|
|
79
|
-
"@aztec/node-keystore": "0.0.1-commit.
|
|
80
|
-
"@aztec/node-lib": "0.0.1-commit.
|
|
81
|
-
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.
|
|
82
|
-
"@aztec/p2p": "0.0.1-commit.
|
|
83
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
84
|
-
"@aztec/prover-client": "0.0.1-commit.
|
|
85
|
-
"@aztec/sequencer-client": "0.0.1-commit.
|
|
86
|
-
"@aztec/simulator": "0.0.1-commit.
|
|
87
|
-
"@aztec/slasher": "0.0.1-commit.
|
|
88
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
89
|
-
"@aztec/telemetry-client": "0.0.1-commit.
|
|
90
|
-
"@aztec/validator-client": "0.0.1-commit.
|
|
91
|
-
"@aztec/
|
|
68
|
+
"@aztec/archiver": "0.0.1-commit.21ecf947b",
|
|
69
|
+
"@aztec/bb-prover": "0.0.1-commit.21ecf947b",
|
|
70
|
+
"@aztec/blob-client": "0.0.1-commit.21ecf947b",
|
|
71
|
+
"@aztec/constants": "0.0.1-commit.21ecf947b",
|
|
72
|
+
"@aztec/epoch-cache": "0.0.1-commit.21ecf947b",
|
|
73
|
+
"@aztec/ethereum": "0.0.1-commit.21ecf947b",
|
|
74
|
+
"@aztec/foundation": "0.0.1-commit.21ecf947b",
|
|
75
|
+
"@aztec/kv-store": "0.0.1-commit.21ecf947b",
|
|
76
|
+
"@aztec/l1-artifacts": "0.0.1-commit.21ecf947b",
|
|
77
|
+
"@aztec/merkle-tree": "0.0.1-commit.21ecf947b",
|
|
78
|
+
"@aztec/node-keystore": "0.0.1-commit.21ecf947b",
|
|
79
|
+
"@aztec/node-lib": "0.0.1-commit.21ecf947b",
|
|
80
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.21ecf947b",
|
|
81
|
+
"@aztec/p2p": "0.0.1-commit.21ecf947b",
|
|
82
|
+
"@aztec/protocol-contracts": "0.0.1-commit.21ecf947b",
|
|
83
|
+
"@aztec/prover-client": "0.0.1-commit.21ecf947b",
|
|
84
|
+
"@aztec/sequencer-client": "0.0.1-commit.21ecf947b",
|
|
85
|
+
"@aztec/simulator": "0.0.1-commit.21ecf947b",
|
|
86
|
+
"@aztec/slasher": "0.0.1-commit.21ecf947b",
|
|
87
|
+
"@aztec/stdlib": "0.0.1-commit.21ecf947b",
|
|
88
|
+
"@aztec/telemetry-client": "0.0.1-commit.21ecf947b",
|
|
89
|
+
"@aztec/validator-client": "0.0.1-commit.21ecf947b",
|
|
90
|
+
"@aztec/validator-ha-signer": "0.0.1-commit.21ecf947b",
|
|
91
|
+
"@aztec/world-state": "0.0.1-commit.21ecf947b",
|
|
92
92
|
"koa": "^2.16.1",
|
|
93
93
|
"koa-router": "^13.1.1",
|
|
94
94
|
"tslib": "^2.4.0",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"@jest/globals": "^30.0.0",
|
|
99
99
|
"@types/jest": "^30.0.0",
|
|
100
100
|
"@types/node": "^22.15.17",
|
|
101
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
101
|
+
"@typescript/native-preview": "7.0.0-dev.20260113.1",
|
|
102
102
|
"jest": "^30.0.0",
|
|
103
103
|
"jest-mock-extended": "^4.0.0",
|
|
104
104
|
"ts-node": "^10.9.1",
|
package/src/aztec-node/config.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { type ArchiverConfig, archiverConfigMappings } from '@aztec/archiver/config';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
type L1ContractAddresses,
|
|
5
|
-
genesisStateConfigMappings,
|
|
6
|
-
l1ContractAddressesMapping,
|
|
7
|
-
} from '@aztec/ethereum';
|
|
2
|
+
import { type GenesisStateConfig, genesisStateConfigMappings } from '@aztec/ethereum/config';
|
|
3
|
+
import { type L1ContractAddresses, l1ContractAddressesMapping } from '@aztec/ethereum/l1-contract-addresses';
|
|
8
4
|
import { type ConfigMappingsType, booleanConfigHelper, getConfigFromMappings } from '@aztec/foundation/config';
|
|
9
5
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
10
6
|
import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
|
|
@@ -57,6 +53,9 @@ export type AztecNodeConfig = ArchiverConfig &
|
|
|
57
53
|
disableValidator: boolean;
|
|
58
54
|
/** Whether to skip waiting for the archiver to be fully synced before starting other services */
|
|
59
55
|
skipArchiverInitialSync: boolean;
|
|
56
|
+
|
|
57
|
+
/** A flag to force verification of tx Chonk proofs. Only used for testnet */
|
|
58
|
+
debugForceTxProofVerification: boolean;
|
|
60
59
|
};
|
|
61
60
|
|
|
62
61
|
export const aztecNodeConfigMappings: ConfigMappingsType<AztecNodeConfig> = {
|
|
@@ -87,6 +86,11 @@ export const aztecNodeConfigMappings: ConfigMappingsType<AztecNodeConfig> = {
|
|
|
87
86
|
description: 'Whether to skip waiting for the archiver to be fully synced before starting other services.',
|
|
88
87
|
...booleanConfigHelper(false),
|
|
89
88
|
},
|
|
89
|
+
debugForceTxProofVerification: {
|
|
90
|
+
env: 'DEBUG_FORCE_TX_PROOF_VERIFICATION',
|
|
91
|
+
description: 'Whether to skip waiting for the archiver to be fully synced before starting other services.',
|
|
92
|
+
...booleanConfigHelper(false),
|
|
93
|
+
},
|
|
90
94
|
};
|
|
91
95
|
|
|
92
96
|
/**
|
|
@@ -132,7 +136,7 @@ function createKeyStoreFromWeb3Signer(config: ConfigRequiredToBuildKeyStore): Ke
|
|
|
132
136
|
function createKeyStoreFromPrivateKeys(config: ConfigRequiredToBuildKeyStore): KeyStore | undefined {
|
|
133
137
|
const validatorKeyStores: ValidatorKeyStore[] = [];
|
|
134
138
|
const ethPrivateKeys = config.validatorPrivateKeys
|
|
135
|
-
? config.validatorPrivateKeys.getValue().map(x => ethPrivateKeySchema.parse(x))
|
|
139
|
+
? config.validatorPrivateKeys.getValue().map((x: string) => ethPrivateKeySchema.parse(x))
|
|
136
140
|
: [];
|
|
137
141
|
|
|
138
142
|
if (!ethPrivateKeys.length) {
|
|
@@ -142,7 +146,7 @@ function createKeyStoreFromPrivateKeys(config: ConfigRequiredToBuildKeyStore): K
|
|
|
142
146
|
const feeRecipient = config.feeRecipient ?? AztecAddress.ZERO;
|
|
143
147
|
|
|
144
148
|
const publisherKeys = config.publisherPrivateKeys
|
|
145
|
-
? config.publisherPrivateKeys.map(k => ethPrivateKeySchema.parse(k.getValue()))
|
|
149
|
+
? config.publisherPrivateKeys.map((k: { getValue: () => string }) => ethPrivateKeySchema.parse(k.getValue()))
|
|
146
150
|
: [];
|
|
147
151
|
|
|
148
152
|
validatorKeyStores.push({
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
Metrics,
|
|
5
5
|
type TelemetryClient,
|
|
6
6
|
type UpDownCounter,
|
|
7
|
-
|
|
7
|
+
createUpDownCounterWithDefault,
|
|
8
8
|
} from '@aztec/telemetry-client';
|
|
9
9
|
|
|
10
10
|
export class NodeMetrics {
|
|
@@ -16,25 +16,14 @@ export class NodeMetrics {
|
|
|
16
16
|
|
|
17
17
|
constructor(client: TelemetryClient, name = 'AztecNode') {
|
|
18
18
|
const meter = client.getMeter(name);
|
|
19
|
-
this.receiveTxCount = meter
|
|
20
|
-
|
|
21
|
-
description: 'The duration of the receiveTx method',
|
|
22
|
-
unit: 'ms',
|
|
23
|
-
valueType: ValueType.INT,
|
|
19
|
+
this.receiveTxCount = createUpDownCounterWithDefault(meter, Metrics.NODE_RECEIVE_TX_COUNT, {
|
|
20
|
+
[Attributes.OK]: [true, false],
|
|
24
21
|
});
|
|
22
|
+
this.receiveTxDuration = meter.createHistogram(Metrics.NODE_RECEIVE_TX_DURATION);
|
|
25
23
|
|
|
26
|
-
this.snapshotDuration = meter.createHistogram(Metrics.NODE_SNAPSHOT_DURATION
|
|
27
|
-
description: 'How long taking a snapshot takes',
|
|
28
|
-
unit: 'ms',
|
|
29
|
-
valueType: ValueType.INT,
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
this.snapshotErrorCount = meter.createUpDownCounter(Metrics.NODE_SNAPSHOT_ERROR_COUNT, {
|
|
33
|
-
description: 'How many snapshot errors have happened',
|
|
34
|
-
valueType: ValueType.INT,
|
|
35
|
-
});
|
|
24
|
+
this.snapshotDuration = meter.createHistogram(Metrics.NODE_SNAPSHOT_DURATION);
|
|
36
25
|
|
|
37
|
-
this.snapshotErrorCount.
|
|
26
|
+
this.snapshotErrorCount = createUpDownCounterWithDefault(meter, Metrics.NODE_SNAPSHOT_ERROR_COUNT);
|
|
38
27
|
}
|
|
39
28
|
|
|
40
29
|
receivedTx(durationMs: number, isAccepted: boolean) {
|