@aztec/aztec-node 0.0.1-commit.29c6b1a3 → 0.0.1-commit.2c0ee1788
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/block_response_helpers.d.ts +21 -0
- package/dest/aztec-node/block_response_helpers.d.ts.map +1 -0
- package/dest/aztec-node/block_response_helpers.js +88 -0
- 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/node_metrics.d.ts +1 -1
- package/dest/aztec-node/node_metrics.d.ts.map +1 -1
- package/dest/aztec-node/node_metrics.js +8 -4
- package/dest/aztec-node/server.d.ts +69 -92
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +870 -400
- package/dest/sentinel/factory.d.ts +4 -3
- package/dest/sentinel/factory.d.ts.map +1 -1
- package/dest/sentinel/factory.js +1 -1
- package/dest/sentinel/sentinel.d.ts +7 -4
- package/dest/sentinel/sentinel.d.ts.map +1 -1
- package/dest/sentinel/sentinel.js +69 -37
- 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 +26 -25
- package/src/aztec-node/block_response_helpers.ts +131 -0
- package/src/aztec-node/config.ts +25 -9
- package/src/aztec-node/node_metrics.ts +12 -5
- package/src/aztec-node/server.ts +1049 -530
- package/src/sentinel/factory.ts +4 -8
- package/src/sentinel/sentinel.ts +82 -37
- package/src/sentinel/store.ts +12 -12
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
2
|
-
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
3
2
|
import type { P2PClient } from '@aztec/p2p';
|
|
4
3
|
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
4
|
+
import type { ChainConfig } from '@aztec/stdlib/config';
|
|
5
5
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
6
|
+
import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
|
|
6
7
|
import type { SentinelConfig } from './config.js';
|
|
7
8
|
import { Sentinel } from './sentinel.js';
|
|
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
|
+
export declare function createSentinel(epochCache: EpochCache, archiver: L2BlockSource, p2p: P2PClient, config: SentinelConfig & DataStoreConfig & SlasherConfig & Pick<ChainConfig, 'l1ChainId' | 'l1Contracts'>, logger?: import("@aztec/foundation/log").Logger): Promise<Sentinel | undefined>;
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlbnRpbmVsL2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFHckQsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzVDLE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3hELE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3JFLE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRTlELE9BQU8sS0FBSyxFQUFFLGNBQWMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR3pDLHdCQUFzQixjQUFjLENBQ2xDLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFFBQVEsRUFBRSxhQUFhLEVBQ3ZCLEdBQUcsRUFBRSxTQUFTLEVBQ2QsTUFBTSxFQUFFLGNBQWMsR0FBRyxlQUFlLEdBQUcsYUFBYSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsV0FBVyxHQUFHLGFBQWEsQ0FBQyxFQUN6RyxNQUFNLHlDQUFnQyxHQUNyQyxPQUFPLENBQUMsUUFBUSxHQUFHLFNBQVMsQ0FBQyxDQVkvQiJ9
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/sentinel/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,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,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,aAAa,CAAC,EACzG,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, {
|
|
@@ -7,15 +7,17 @@ import type { P2PClient } from '@aztec/p2p';
|
|
|
7
7
|
import { type Watcher, type WatcherEmitter } from '@aztec/slasher';
|
|
8
8
|
import type { SlasherConfig } from '@aztec/slasher/config';
|
|
9
9
|
import { type L2BlockSource, L2BlockStream, type L2BlockStreamEvent, type L2BlockStreamEventHandler } from '@aztec/stdlib/block';
|
|
10
|
+
import type { ChainConfig } from '@aztec/stdlib/config';
|
|
10
11
|
import type { SingleValidatorStats, ValidatorStats, ValidatorStatusHistory, ValidatorStatusInSlot, ValidatorStatusType, ValidatorsEpochPerformance, ValidatorsStats } from '@aztec/stdlib/validators';
|
|
11
12
|
import { SentinelStore } from './store.js';
|
|
13
|
+
export type SentinelRuntimeConfig = Pick<SlasherConfig, 'slashInactivityTargetPercentage' | 'slashInactivityPenalty' | 'slashInactivityConsecutiveEpochThreshold'> & Pick<ChainConfig, 'l1ChainId' | 'l1Contracts'>;
|
|
12
14
|
declare const Sentinel_base: new () => WatcherEmitter;
|
|
13
15
|
export declare class Sentinel extends Sentinel_base implements L2BlockStreamEventHandler, Watcher {
|
|
14
16
|
protected epochCache: EpochCache;
|
|
15
17
|
protected archiver: L2BlockSource;
|
|
16
18
|
protected p2p: P2PClient;
|
|
17
19
|
protected store: SentinelStore;
|
|
18
|
-
protected config:
|
|
20
|
+
protected config: SentinelRuntimeConfig;
|
|
19
21
|
protected logger: import("@aztec/foundation/log").Logger;
|
|
20
22
|
protected runningPromise: RunningPromise;
|
|
21
23
|
protected blockStream: L2BlockStream;
|
|
@@ -27,7 +29,8 @@ export declare class Sentinel extends Sentinel_base implements L2BlockStreamEven
|
|
|
27
29
|
archive: string;
|
|
28
30
|
attestors: EthAddress[];
|
|
29
31
|
}>;
|
|
30
|
-
constructor(epochCache: EpochCache, archiver: L2BlockSource, p2p: P2PClient, store: SentinelStore, config:
|
|
32
|
+
constructor(epochCache: EpochCache, archiver: L2BlockSource, p2p: P2PClient, store: SentinelStore, config: SentinelRuntimeConfig, logger?: import("@aztec/foundation/log").Logger);
|
|
33
|
+
private getSignatureContext;
|
|
31
34
|
updateConfig(config: Partial<SlasherConfig>): void;
|
|
32
35
|
start(): Promise<void>;
|
|
33
36
|
/** Loads initial slot and initializes blockstream. We will not process anything at or before the initial slot. */
|
|
@@ -77,7 +80,7 @@ export declare class Sentinel extends Sentinel_base implements L2BlockStreamEven
|
|
|
77
80
|
/** Computes stats for a single validator. */
|
|
78
81
|
getValidatorStats(validatorAddress: EthAddress, fromSlot?: SlotNumber, toSlot?: SlotNumber): Promise<SingleValidatorStats | undefined>;
|
|
79
82
|
protected computeStatsForValidator(address: `0x${string}`, allHistory: ValidatorStatusHistory, fromSlot?: SlotNumber, toSlot?: SlotNumber): ValidatorStats;
|
|
80
|
-
protected computeMissed(history: ValidatorStatusHistory,
|
|
83
|
+
protected computeMissed(history: ValidatorStatusHistory, computeOverCategory: ValidatorStatusType | undefined, filter: ValidatorStatusInSlot[]): {
|
|
81
84
|
currentStreak: number;
|
|
82
85
|
rate: number | undefined;
|
|
83
86
|
count: number;
|
|
@@ -90,4 +93,4 @@ export declare class Sentinel extends Sentinel_base implements L2BlockStreamEven
|
|
|
90
93
|
} | undefined;
|
|
91
94
|
}
|
|
92
95
|
export {};
|
|
93
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
96
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VudGluZWwuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZW50aW5lbC9zZW50aW5lbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEVBQWUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRXpHLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUUzRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDbkUsT0FBTyxFQUFxQixLQUFLLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdFLE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUM1QyxPQUFPLEVBSUwsS0FBSyxPQUFPLEVBQ1osS0FBSyxjQUFjLEVBQ3BCLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDM0QsT0FBTyxFQUNMLEtBQUssYUFBYSxFQUNsQixhQUFhLEVBQ2IsS0FBSyxrQkFBa0IsRUFDdkIsS0FBSyx5QkFBeUIsRUFFL0IsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEtBQUssRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUd4RCxPQUFPLEtBQUssRUFDVixvQkFBb0IsRUFDcEIsY0FBYyxFQUNkLHNCQUFzQixFQUN0QixxQkFBcUIsRUFDckIsbUJBQW1CLEVBQ25CLDBCQUEwQixFQUMxQixlQUFlLEVBQ2hCLE1BQU0sMEJBQTBCLENBQUM7QUFJbEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUUzQyxNQUFNLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxDQUN0QyxhQUFhLEVBQ2IsaUNBQWlDLEdBQUcsd0JBQXdCLEdBQUcsMENBQTBDLENBQzFHLEdBQ0MsSUFBSSxDQUFDLFdBQVcsRUFBRSxXQUFXLEdBQUcsYUFBYSxDQUFDLENBQUM7O0FBYWpELHFCQUFhLFFBQVMsU0FBUSxhQUEyQyxZQUFXLHlCQUF5QixFQUFFLE9BQU87SUFjbEgsU0FBUyxDQUFDLFVBQVUsRUFBRSxVQUFVO0lBQ2hDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsYUFBYTtJQUNqQyxTQUFTLENBQUMsR0FBRyxFQUFFLFNBQVM7SUFDeEIsU0FBUyxDQUFDLEtBQUssRUFBRSxhQUFhO0lBQzlCLFNBQVMsQ0FBQyxNQUFNLEVBQUUscUJBQXFCO0lBQ3ZDLFNBQVMsQ0FBQyxNQUFNO0lBbEJsQixTQUFTLENBQUMsY0FBYyxFQUFFLGNBQWMsQ0FBQztJQUN6QyxTQUFTLENBQUMsV0FBVyxFQUFHLGFBQWEsQ0FBQztJQUN0QyxTQUFTLENBQUMsV0FBVyxFQUFFLFdBQVcsQ0FBQztJQUVuQyxTQUFTLENBQUMsV0FBVyxFQUFFLFVBQVUsR0FBRyxTQUFTLENBQUM7SUFDOUMsU0FBUyxDQUFDLGlCQUFpQixFQUFFLFVBQVUsR0FBRyxTQUFTLENBQUM7SUFFcEQsU0FBUyxDQUFDLHNCQUFzQixFQUFFLEdBQUcsQ0FDbkMsVUFBVSxFQUNWO1FBQUUsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUM7UUFBQyxPQUFPLEVBQUUsTUFBTSxDQUFDO1FBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxDQUFBO0tBQUUsQ0FDakYsQ0FBYTtJQUVkLFlBQ1ksVUFBVSxFQUFFLFVBQVUsRUFDdEIsUUFBUSxFQUFFLGFBQWEsRUFDdkIsR0FBRyxFQUFFLFNBQVMsRUFDZCxLQUFLLEVBQUUsYUFBYSxFQUNwQixNQUFNLEVBQUUscUJBQXFCLEVBQzdCLE1BQU0seUNBQWdDLEVBTWpEO0lBRUQsT0FBTyxDQUFDLG1CQUFtQjtJQU9wQixZQUFZLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxhQUFhLENBQUMsUUFFakQ7SUFFWSxLQUFLLGtCQUdqQjtJQUVELGtIQUFrSDtJQUNsSCxVQUFnQixJQUFJLGtCQUtuQjtJQUVNLElBQUksa0JBRVY7SUFFWSxzQkFBc0IsQ0FBQyxLQUFLLEVBQUUsa0JBQWtCLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQU81RTtJQUVELFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsa0JBQWtCLFFBeUJuRDtJQUVELFVBQWdCLGlCQUFpQixDQUFDLEtBQUssRUFBRSxrQkFBa0IsaUJBb0IxRDtJQUVELFVBQWdCLHdCQUF3QixDQUFDLEtBQUssRUFBRSxXQUFXLEdBQUcsT0FBTyxDQUFDLDBCQUEwQixDQUFDLENBNkJoRztJQUVEOzs7OztPQUtHO0lBQ0gsVUFBZ0IsbUJBQW1CLENBQ2pDLFNBQVMsRUFBRSxVQUFVLEVBQ3JCLFlBQVksRUFBRSxXQUFXLEVBQ3pCLHlCQUF5QixFQUFFLE1BQU0sR0FDaEMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQXVCbEI7SUFFRCxVQUFnQix1QkFBdUIsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSwwQkFBMEIsaUJBa0NsRztJQUVEOzs7O09BSUc7SUFDVSxJQUFJLGtCQWlCaEI7SUFFRDs7OztPQUlHO0lBQ0gsVUFBZ0IsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQyxDQXFDckY7SUFFRDs7O09BR0c7SUFDSCxVQUFnQixXQUFXLENBQUMsSUFBSSxFQUFFLFVBQVUsaUJBa0IzQztJQUVELDBDQUEwQztJQUMxQyxVQUFnQixlQUFlLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRTs7T0FvRWxIO0lBRUQsd0RBQXdEO0lBQ3hELFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxNQUFNLEVBQUUsRUFBRSxxQkFBcUIsR0FBRyxTQUFTLENBQUMsaUJBRTNHO0lBRUQsMERBQTBEO0lBQzdDLFlBQVksQ0FBQyxFQUN4QixRQUFRLEVBQ1IsTUFBTSxFQUNOLFVBQVUsRUFDWCxHQUFFO1FBQUUsUUFBUSxDQUFDLEVBQUUsVUFBVSxDQUFDO1FBQUMsTUFBTSxDQUFDLEVBQUUsVUFBVSxDQUFDO1FBQUMsVUFBVSxDQUFDLEVBQUUsVUFBVSxFQUFFLENBQUE7S0FBTyxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FtQjNHO0lBRUQsNkNBQTZDO0lBQ2hDLGlCQUFpQixDQUM1QixnQkFBZ0IsRUFBRSxVQUFVLEVBQzVCLFFBQVEsQ0FBQyxFQUFFLFVBQVUsRUFDckIsTUFBTSxDQUFDLEVBQUUsVUFBVSxHQUNsQixPQUFPLENBQUMsb0JBQW9CLEdBQUcsU0FBUyxDQUFDLENBa0MzQztJQUVELFNBQVMsQ0FBQyx3QkFBd0IsQ0FDaEMsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFFLEVBQ3RCLFVBQVUsRUFBRSxzQkFBc0IsRUFDbEMsUUFBUSxDQUFDLEVBQUUsVUFBVSxFQUNyQixNQUFNLENBQUMsRUFBRSxVQUFVLEdBQ2xCLGNBQWMsQ0FnQmhCO0lBRUQsU0FBUyxDQUFDLGFBQWEsQ0FDckIsT0FBTyxFQUFFLHNCQUFzQixFQUMvQixtQkFBbUIsRUFBRSxtQkFBbUIsR0FBRyxTQUFTLEVBQ3BELE1BQU0sRUFBRSxxQkFBcUIsRUFBRTs7Ozs7TUFZaEM7SUFFRCxTQUFTLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxVQUFVLEdBQUcsU0FBUzs7OztrQkFNckQ7Q0FDRiJ9
|
|
@@ -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,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAEzG,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAIL,KAAK,OAAO,EACZ,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,KAAK,aAAa,EAClB,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAE/B,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"sentinel.d.ts","sourceRoot":"","sources":["../../src/sentinel/sentinel.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,15 @@ import { OffenseType, WANT_TO_SLASH_EVENT } from '@aztec/slasher';
|
|
|
8
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;
|
|
@@ -28,6 +37,12 @@ export class Sentinel extends EventEmitter {
|
|
|
28
37
|
const interval = epochCache.getL1Constants().ethereumSlotDuration * 1000 / 4;
|
|
29
38
|
this.runningPromise = new RunningPromise(this.work.bind(this), logger, interval);
|
|
30
39
|
}
|
|
40
|
+
getSignatureContext() {
|
|
41
|
+
return {
|
|
42
|
+
chainId: this.config.l1ChainId,
|
|
43
|
+
rollupAddress: this.config.l1Contracts.rollupAddress
|
|
44
|
+
};
|
|
45
|
+
}
|
|
31
46
|
updateConfig(config) {
|
|
32
47
|
this.config = {
|
|
33
48
|
...this.config,
|
|
@@ -39,7 +54,7 @@ export class Sentinel extends EventEmitter {
|
|
|
39
54
|
this.runningPromise.start();
|
|
40
55
|
}
|
|
41
56
|
/** Loads initial slot and initializes blockstream. We will not process anything at or before the initial slot. */ async init() {
|
|
42
|
-
this.initialSlot = this.epochCache.
|
|
57
|
+
this.initialSlot = this.epochCache.getSlotNow();
|
|
43
58
|
const startingBlock = BlockNumber(await this.archiver.getBlockNumber());
|
|
44
59
|
this.logger.info(`Starting validator sentinel with initial slot ${this.initialSlot} and block ${startingBlock}`);
|
|
45
60
|
this.blockStream = new L2BlockStream(this.archiver, this.l2TipsStore, this, this.logger, {
|
|
@@ -66,7 +81,7 @@ export class Sentinel extends EventEmitter {
|
|
|
66
81
|
this.slotNumberToCheckpoint.set(checkpoint.checkpoint.header.slotNumber, {
|
|
67
82
|
checkpointNumber: checkpoint.checkpoint.number,
|
|
68
83
|
archive: checkpoint.checkpoint.archive.root.toString(),
|
|
69
|
-
attestors: getAttestationInfoFromPublishedCheckpoint(checkpoint).filter((a)=>a.status === 'recovered-from-signature').map((a)=>a.address)
|
|
84
|
+
attestors: getAttestationInfoFromPublishedCheckpoint(checkpoint, this.getSignatureContext()).filter((a)=>a.status === 'recovered-from-signature').map((a)=>a.address)
|
|
70
85
|
});
|
|
71
86
|
// Prune the archive map to only keep at most N entries
|
|
72
87
|
const historyLength = this.store.getHistoryLength();
|
|
@@ -82,16 +97,14 @@ export class Sentinel extends EventEmitter {
|
|
|
82
97
|
return;
|
|
83
98
|
}
|
|
84
99
|
const blockNumber = event.block.number;
|
|
85
|
-
const
|
|
86
|
-
if (!
|
|
87
|
-
this.logger.error(`Failed to get block ${blockNumber}
|
|
88
|
-
block
|
|
89
|
-
});
|
|
100
|
+
const header = await this.archiver.getBlockHeader(blockNumber);
|
|
101
|
+
if (!header) {
|
|
102
|
+
this.logger.error(`Failed to get block header ${blockNumber}`);
|
|
90
103
|
return;
|
|
91
104
|
}
|
|
92
105
|
// TODO(palla/slash): We should only be computing proven performance if this is
|
|
93
106
|
// a full proof epoch and not a partial one, otherwise we'll end up with skewed stats.
|
|
94
|
-
const epoch = getEpochAtSlot(
|
|
107
|
+
const epoch = getEpochAtSlot(header.getSlot(), this.epochCache.getL1Constants());
|
|
95
108
|
this.logger.debug(`Computing proven performance for epoch ${epoch}`);
|
|
96
109
|
const performance = await this.computeProvenPerformance(epoch);
|
|
97
110
|
this.logger.info(`Computed proven performance for epoch ${epoch}`, performance);
|
|
@@ -100,7 +113,11 @@ export class Sentinel extends EventEmitter {
|
|
|
100
113
|
}
|
|
101
114
|
async computeProvenPerformance(epoch) {
|
|
102
115
|
const [fromSlot, toSlot] = getSlotRangeForEpoch(epoch, this.epochCache.getL1Constants());
|
|
103
|
-
const { committee } = await this.epochCache.getCommittee(fromSlot);
|
|
116
|
+
const { committee, isEscapeHatchOpen } = await this.epochCache.getCommittee(fromSlot);
|
|
117
|
+
if (isEscapeHatchOpen) {
|
|
118
|
+
this.logger.info(`Skipping proven performance for epoch ${epoch} - escape hatch is open`);
|
|
119
|
+
return {};
|
|
120
|
+
}
|
|
104
121
|
if (!committee) {
|
|
105
122
|
this.logger.trace(`No committee found for slot ${fromSlot}`);
|
|
106
123
|
return {};
|
|
@@ -146,13 +163,13 @@ export class Sentinel extends EventEmitter {
|
|
|
146
163
|
return false;
|
|
147
164
|
}
|
|
148
165
|
// Check that we have at least requiredConsecutiveEpochs and that all of them are above the inactivity threshold
|
|
149
|
-
return pastEpochs.slice(0, requiredConsecutiveEpochs).every((p)=>p.missed / p.total >= this.config.slashInactivityTargetPercentage);
|
|
166
|
+
return pastEpochs.slice(0, requiredConsecutiveEpochs).every((p)=>p.total === 0 ? false : p.missed / p.total >= this.config.slashInactivityTargetPercentage);
|
|
150
167
|
}
|
|
151
168
|
async handleProvenPerformance(epoch, performance) {
|
|
152
169
|
if (this.config.slashInactivityPenalty === 0n) {
|
|
153
170
|
return;
|
|
154
171
|
}
|
|
155
|
-
const inactiveValidators = getEntries(performance).filter(([_, { missed, total }])=>missed / total >= this.config.slashInactivityTargetPercentage).map(([address])=>address);
|
|
172
|
+
const inactiveValidators = getEntries(performance).filter(([_, { missed, total }])=>total > 0 && missed / total >= this.config.slashInactivityTargetPercentage).map(([address])=>address);
|
|
156
173
|
this.logger.debug(`Found ${inactiveValidators.length} inactive validators in epoch ${epoch}`, {
|
|
157
174
|
inactiveValidators,
|
|
158
175
|
epoch,
|
|
@@ -179,7 +196,7 @@ export class Sentinel extends EventEmitter {
|
|
|
179
196
|
* Note that we do not process historical data, since we rely on p2p data for processing,
|
|
180
197
|
* and we don't have that data if we were offline during the period.
|
|
181
198
|
*/ async work() {
|
|
182
|
-
const
|
|
199
|
+
const currentSlot = this.epochCache.getSlotNow();
|
|
183
200
|
try {
|
|
184
201
|
// Manually sync the block stream to ensure we have the latest data.
|
|
185
202
|
// Note we never `start` the blockstream, so it loops at the same pace as we do.
|
|
@@ -218,10 +235,10 @@ export class Sentinel extends EventEmitter {
|
|
|
218
235
|
this.logger.trace(`Refusing to process slot ${targetSlot} given initial slot ${this.initialSlot}`);
|
|
219
236
|
return false;
|
|
220
237
|
}
|
|
221
|
-
const
|
|
222
|
-
if (
|
|
238
|
+
const syncedSlot = await this.archiver.getSyncedL2SlotNumber();
|
|
239
|
+
if (syncedSlot === undefined || syncedSlot < targetSlot) {
|
|
223
240
|
this.logger.debug(`Waiting for archiver to sync with L2 slot ${targetSlot}`, {
|
|
224
|
-
|
|
241
|
+
syncedSlot,
|
|
225
242
|
targetSlot
|
|
226
243
|
});
|
|
227
244
|
return false;
|
|
@@ -242,7 +259,12 @@ export class Sentinel extends EventEmitter {
|
|
|
242
259
|
* Gathers committee and proposer data for a given slot, computes slot stats,
|
|
243
260
|
* and updates overall stats.
|
|
244
261
|
*/ async processSlot(slot) {
|
|
245
|
-
const { epoch, seed, committee } = await this.epochCache.getCommittee(slot);
|
|
262
|
+
const { epoch, seed, committee, isEscapeHatchOpen } = await this.epochCache.getCommittee(slot);
|
|
263
|
+
if (isEscapeHatchOpen) {
|
|
264
|
+
this.logger.info(`Skipping slot ${slot} at epoch ${epoch} - escape hatch is open`);
|
|
265
|
+
this.lastProcessedSlot = slot;
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
246
268
|
if (!committee || committee.length === 0) {
|
|
247
269
|
this.logger.trace(`No committee found for slot ${slot} at epoch ${epoch}`);
|
|
248
270
|
this.lastProcessedSlot = slot;
|
|
@@ -263,17 +285,17 @@ export class Sentinel extends EventEmitter {
|
|
|
263
285
|
committee
|
|
264
286
|
});
|
|
265
287
|
// Check if there is an L2 block in L1 for this L2 slot
|
|
266
|
-
// Here we get all attestations for the
|
|
267
|
-
// or all attestations for all proposals in the slot if no
|
|
288
|
+
// Here we get all checkpoint attestations for the checkpoint at the given slot,
|
|
289
|
+
// or all checkpoint attestations for all proposals in the slot if no checkpoint was mined.
|
|
268
290
|
// We gather from both p2p (contains the ones seen on the p2p layer) and archiver
|
|
269
|
-
// (contains the ones synced from mined
|
|
270
|
-
const
|
|
271
|
-
const p2pAttested = await this.p2p.getCheckpointAttestationsForSlot(slot,
|
|
291
|
+
// (contains the ones synced from mined checkpoints, which we may have missed from p2p).
|
|
292
|
+
const checkpoint = this.slotNumberToCheckpoint.get(slot);
|
|
293
|
+
const p2pAttested = await this.p2p.getCheckpointAttestationsForSlot(slot, checkpoint?.archive);
|
|
272
294
|
// Filter out attestations with invalid signatures
|
|
273
295
|
const p2pAttestors = p2pAttested.map((a)=>a.getSender()).filter((s)=>s !== undefined);
|
|
274
296
|
const attestors = new Set([
|
|
275
297
|
...p2pAttestors.map((a)=>a.toString()),
|
|
276
|
-
...
|
|
298
|
+
...checkpoint?.attestors.map((a)=>a.toString()) ?? []
|
|
277
299
|
].filter((addr)=>proposer.toString() !== addr));
|
|
278
300
|
// We assume that there was a block proposal if at least one of the validators (other than the proposer) attested to it.
|
|
279
301
|
// It could be the case that every single validator failed, and we could differentiate it by having
|
|
@@ -281,17 +303,26 @@ export class Sentinel extends EventEmitter {
|
|
|
281
303
|
// But we'll leave that corner case out to reduce pressure on the node.
|
|
282
304
|
// TODO(palla/slash): This breaks if a given node has more than one validator in the current committee,
|
|
283
305
|
// since they will attest to their own proposal it even if it's not re-executable.
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
306
|
+
let status;
|
|
307
|
+
if (checkpoint) {
|
|
308
|
+
status = 'checkpoint-mined';
|
|
309
|
+
} else if (attestors.size > 0) {
|
|
310
|
+
status = 'checkpoint-proposed';
|
|
311
|
+
} else {
|
|
312
|
+
// No checkpoint on L1 and no checkpoint attestations seen. Check if block proposals were sent for this slot.
|
|
313
|
+
const hasBlockProposals = await this.p2p.hasBlockProposalsForSlot(slot);
|
|
314
|
+
status = hasBlockProposals ? 'checkpoint-missed' : 'blocks-missed';
|
|
315
|
+
}
|
|
316
|
+
this.logger.debug(`Checkpoint status for slot ${slot}: ${status}`, {
|
|
317
|
+
...checkpoint,
|
|
287
318
|
slot
|
|
288
319
|
});
|
|
289
|
-
// Get attestors that failed their
|
|
290
|
-
const missedAttestors = new Set(
|
|
320
|
+
// Get attestors that failed their checkpoint attestation duties, but only if there was a checkpoint proposed or mined
|
|
321
|
+
const missedAttestors = new Set(status === 'blocks-missed' || status === 'checkpoint-missed' ? [] : committee.filter((v)=>!attestors.has(v.toString()) && !proposer.equals(v)).map((v)=>v.toString()));
|
|
291
322
|
this.logger.debug(`Retrieved ${attestors.size} attestors out of ${committee.length} for slot ${slot}`, {
|
|
292
|
-
|
|
323
|
+
status,
|
|
293
324
|
proposer: proposer.toString(),
|
|
294
|
-
...
|
|
325
|
+
...checkpoint,
|
|
295
326
|
slot,
|
|
296
327
|
attestors: [
|
|
297
328
|
...attestors
|
|
@@ -304,7 +335,7 @@ export class Sentinel extends EventEmitter {
|
|
|
304
335
|
// Compute the status for each validator in the committee
|
|
305
336
|
const statusFor = (who)=>{
|
|
306
337
|
if (who === proposer.toString()) {
|
|
307
|
-
return
|
|
338
|
+
return status;
|
|
308
339
|
} else if (attestors.has(who)) {
|
|
309
340
|
return 'attestation-sent';
|
|
310
341
|
} else if (missedAttestors.has(who)) {
|
|
@@ -326,7 +357,7 @@ export class Sentinel extends EventEmitter {
|
|
|
326
357
|
v.toString(),
|
|
327
358
|
await this.store.getHistory(v)
|
|
328
359
|
]))) : await this.store.getHistories();
|
|
329
|
-
const slotNow = this.epochCache.
|
|
360
|
+
const slotNow = this.epochCache.getSlotNow();
|
|
330
361
|
fromSlot ??= SlotNumber(Math.max((this.lastProcessedSlot ?? slotNow) - this.store.getHistoryLength(), 0));
|
|
331
362
|
toSlot ??= this.lastProcessedSlot ?? slotNow;
|
|
332
363
|
const stats = mapValues(histories, (history, address)=>this.computeStatsForValidator(address, history ?? [], fromSlot, toSlot));
|
|
@@ -342,7 +373,7 @@ export class Sentinel extends EventEmitter {
|
|
|
342
373
|
if (!history || history.length === 0) {
|
|
343
374
|
return undefined;
|
|
344
375
|
}
|
|
345
|
-
const slotNow = this.epochCache.
|
|
376
|
+
const slotNow = this.epochCache.getSlotNow();
|
|
346
377
|
const effectiveFromSlot = fromSlot ?? SlotNumber(Math.max((this.lastProcessedSlot ?? slotNow) - this.store.getHistoryLength(), 0));
|
|
347
378
|
const effectiveToSlot = toSlot ?? this.lastProcessedSlot ?? slotNow;
|
|
348
379
|
const historyLength = BigInt(this.store.getHistoryLength());
|
|
@@ -361,15 +392,16 @@ export class Sentinel extends EventEmitter {
|
|
|
361
392
|
computeStatsForValidator(address, allHistory, fromSlot, toSlot) {
|
|
362
393
|
let history = fromSlot ? allHistory.filter((h)=>BigInt(h.slot) >= fromSlot) : allHistory;
|
|
363
394
|
history = toSlot ? history.filter((h)=>BigInt(h.slot) <= toSlot) : history;
|
|
364
|
-
const lastProposal = history.filter((h)=>h.status === '
|
|
395
|
+
const lastProposal = history.filter((h)=>h.status === 'checkpoint-proposed' || h.status === 'checkpoint-mined').at(-1);
|
|
365
396
|
const lastAttestation = history.filter((h)=>h.status === 'attestation-sent').at(-1);
|
|
366
397
|
return {
|
|
367
398
|
address: EthAddress.fromString(address),
|
|
368
399
|
lastProposal: this.computeFromSlot(lastProposal?.slot),
|
|
369
400
|
lastAttestation: this.computeFromSlot(lastAttestation?.slot),
|
|
370
401
|
totalSlots: history.length,
|
|
371
|
-
missedProposals: this.computeMissed(history, '
|
|
372
|
-
'
|
|
402
|
+
missedProposals: this.computeMissed(history, 'proposer', [
|
|
403
|
+
'checkpoint-missed',
|
|
404
|
+
'blocks-missed'
|
|
373
405
|
]),
|
|
374
406
|
missedAttestations: this.computeMissed(history, 'attestation', [
|
|
375
407
|
'attestation-missed'
|
|
@@ -377,8 +409,8 @@ export class Sentinel extends EventEmitter {
|
|
|
377
409
|
history
|
|
378
410
|
};
|
|
379
411
|
}
|
|
380
|
-
computeMissed(history,
|
|
381
|
-
const relevantHistory = history.filter((h)=>!
|
|
412
|
+
computeMissed(history, computeOverCategory, filter) {
|
|
413
|
+
const relevantHistory = history.filter((h)=>!computeOverCategory || statusToCategory(h.status) === computeOverCategory);
|
|
382
414
|
const filteredHistory = relevantHistory.filter((h)=>filter.includes(h.status));
|
|
383
415
|
return {
|
|
384
416
|
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,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;
|
|
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.2c0ee1788",
|
|
4
4
|
"main": "dest/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -65,30 +65,31 @@
|
|
|
65
65
|
]
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@aztec/archiver": "0.0.1-commit.
|
|
69
|
-
"@aztec/bb-prover": "0.0.1-commit.
|
|
70
|
-
"@aztec/blob-client": "0.0.1-commit.
|
|
71
|
-
"@aztec/
|
|
72
|
-
"@aztec/
|
|
73
|
-
"@aztec/
|
|
74
|
-
"@aztec/
|
|
75
|
-
"@aztec/
|
|
76
|
-
"@aztec/
|
|
77
|
-
"@aztec/
|
|
78
|
-
"@aztec/node-keystore": "0.0.1-commit.
|
|
79
|
-
"@aztec/node-lib": "0.0.1-commit.
|
|
80
|
-
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.
|
|
81
|
-
"@aztec/p2p": "0.0.1-commit.
|
|
82
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
83
|
-
"@aztec/prover-client": "0.0.1-commit.
|
|
84
|
-
"@aztec/
|
|
85
|
-
"@aztec/
|
|
86
|
-
"@aztec/
|
|
87
|
-
"@aztec/
|
|
88
|
-
"@aztec/
|
|
89
|
-
"@aztec/
|
|
90
|
-
"@aztec/validator-
|
|
91
|
-
"@aztec/
|
|
68
|
+
"@aztec/archiver": "0.0.1-commit.2c0ee1788",
|
|
69
|
+
"@aztec/bb-prover": "0.0.1-commit.2c0ee1788",
|
|
70
|
+
"@aztec/blob-client": "0.0.1-commit.2c0ee1788",
|
|
71
|
+
"@aztec/blob-lib": "0.0.1-commit.2c0ee1788",
|
|
72
|
+
"@aztec/constants": "0.0.1-commit.2c0ee1788",
|
|
73
|
+
"@aztec/epoch-cache": "0.0.1-commit.2c0ee1788",
|
|
74
|
+
"@aztec/ethereum": "0.0.1-commit.2c0ee1788",
|
|
75
|
+
"@aztec/foundation": "0.0.1-commit.2c0ee1788",
|
|
76
|
+
"@aztec/kv-store": "0.0.1-commit.2c0ee1788",
|
|
77
|
+
"@aztec/l1-artifacts": "0.0.1-commit.2c0ee1788",
|
|
78
|
+
"@aztec/node-keystore": "0.0.1-commit.2c0ee1788",
|
|
79
|
+
"@aztec/node-lib": "0.0.1-commit.2c0ee1788",
|
|
80
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.2c0ee1788",
|
|
81
|
+
"@aztec/p2p": "0.0.1-commit.2c0ee1788",
|
|
82
|
+
"@aztec/protocol-contracts": "0.0.1-commit.2c0ee1788",
|
|
83
|
+
"@aztec/prover-client": "0.0.1-commit.2c0ee1788",
|
|
84
|
+
"@aztec/prover-node": "0.0.1-commit.2c0ee1788",
|
|
85
|
+
"@aztec/sequencer-client": "0.0.1-commit.2c0ee1788",
|
|
86
|
+
"@aztec/simulator": "0.0.1-commit.2c0ee1788",
|
|
87
|
+
"@aztec/slasher": "0.0.1-commit.2c0ee1788",
|
|
88
|
+
"@aztec/stdlib": "0.0.1-commit.2c0ee1788",
|
|
89
|
+
"@aztec/telemetry-client": "0.0.1-commit.2c0ee1788",
|
|
90
|
+
"@aztec/validator-client": "0.0.1-commit.2c0ee1788",
|
|
91
|
+
"@aztec/validator-ha-signer": "0.0.1-commit.2c0ee1788",
|
|
92
|
+
"@aztec/world-state": "0.0.1-commit.2c0ee1788",
|
|
92
93
|
"koa": "^2.16.1",
|
|
93
94
|
"koa-router": "^13.1.1",
|
|
94
95
|
"tslib": "^2.4.0",
|