@aztec/aztec-node 0.0.1-commit.24de95ac → 0.0.1-commit.2606882
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 +25 -0
- package/dest/aztec-node/block_response_helpers.d.ts.map +1 -0
- package/dest/aztec-node/block_response_helpers.js +112 -0
- package/dest/aztec-node/config.d.ts +17 -8
- package/dest/aztec-node/config.d.ts.map +1 -1
- package/dest/aztec-node/config.js +22 -8
- 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/public_data_overrides.d.ts +13 -0
- package/dest/aztec-node/public_data_overrides.d.ts.map +1 -0
- package/dest/aztec-node/public_data_overrides.js +21 -0
- package/dest/aztec-node/server.d.ts +109 -199
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +1602 -506
- package/dest/bin/index.d.ts +1 -1
- package/dest/index.d.ts +1 -1
- package/dest/sentinel/config.d.ts +3 -2
- package/dest/sentinel/config.d.ts.map +1 -1
- package/dest/sentinel/config.js +15 -5
- package/dest/sentinel/factory.d.ts +5 -3
- package/dest/sentinel/factory.d.ts.map +1 -1
- package/dest/sentinel/factory.js +5 -5
- package/dest/sentinel/index.d.ts +1 -1
- package/dest/sentinel/sentinel.d.ts +151 -25
- package/dest/sentinel/sentinel.d.ts.map +1 -1
- package/dest/sentinel/sentinel.js +290 -110
- package/dest/sentinel/store.d.ts +11 -10
- package/dest/sentinel/store.d.ts.map +1 -1
- package/dest/sentinel/store.js +36 -23
- package/dest/test/index.d.ts +3 -3
- package/dest/test/index.d.ts.map +1 -1
- package/package.json +31 -28
- package/src/aztec-node/block_response_helpers.ts +161 -0
- package/src/aztec-node/config.ts +45 -21
- package/src/aztec-node/node_metrics.ts +6 -17
- package/src/aztec-node/public_data_overrides.ts +35 -0
- package/src/aztec-node/server.ts +1385 -640
- package/src/sentinel/README.md +103 -0
- package/src/sentinel/config.ts +18 -6
- package/src/sentinel/factory.ts +9 -11
- package/src/sentinel/sentinel.ts +375 -136
- package/src/sentinel/store.ts +43 -34
- package/src/test/index.ts +2 -2
package/src/sentinel/store.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
2
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
3
|
import { BufferReader, numToUInt8, numToUInt32BE, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
3
4
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
@@ -8,45 +9,45 @@ import type {
|
|
|
8
9
|
} from '@aztec/stdlib/validators';
|
|
9
10
|
|
|
10
11
|
export class SentinelStore {
|
|
11
|
-
public static readonly SCHEMA_VERSION =
|
|
12
|
+
public static readonly SCHEMA_VERSION = 4;
|
|
12
13
|
|
|
13
14
|
// a map from validator address to their ValidatorStatusHistory
|
|
14
15
|
private readonly historyMap: AztecAsyncMap<`0x${string}`, Buffer>;
|
|
15
16
|
|
|
16
|
-
// a map from validator address to their historical
|
|
17
|
+
// a map from validator address to their historical epoch performance, evaluated at end-of-epoch.
|
|
17
18
|
// e.g. { validator: [{ epoch: 1, missed: 1, total: 10 }, { epoch: 2, missed: 3, total: 7 }, ...] }
|
|
18
|
-
private readonly
|
|
19
|
+
private readonly epochMap: AztecAsyncMap<`0x${string}`, Buffer>;
|
|
19
20
|
|
|
20
21
|
constructor(
|
|
21
22
|
private store: AztecAsyncKVStore,
|
|
22
|
-
private config: { historyLength: number;
|
|
23
|
+
private config: { historyLength: number; historicEpochPerformanceLength: number },
|
|
23
24
|
) {
|
|
24
25
|
this.historyMap = store.openMap('sentinel-validator-status');
|
|
25
|
-
this.
|
|
26
|
+
this.epochMap = store.openMap('sentinel-validator-epoch');
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
public getHistoryLength() {
|
|
29
30
|
return this.config.historyLength;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
public
|
|
33
|
-
return this.config.
|
|
33
|
+
public getHistoricEpochPerformanceLength() {
|
|
34
|
+
return this.config.historicEpochPerformanceLength;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
public async
|
|
37
|
+
public async updateEpochPerformance(epoch: EpochNumber, performance: ValidatorsEpochPerformance) {
|
|
37
38
|
await this.store.transactionAsync(async () => {
|
|
38
39
|
for (const [who, { missed, total }] of Object.entries(performance)) {
|
|
39
|
-
await this.
|
|
40
|
+
await this.pushValidatorEpochPerformance({ who: EthAddress.fromString(who), missed, total, epoch });
|
|
40
41
|
}
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
public async
|
|
45
|
-
const currentPerformanceBuffer = await this.
|
|
45
|
+
public async getEpochPerformance(who: EthAddress): Promise<{ missed: number; total: number; epoch: EpochNumber }[]> {
|
|
46
|
+
const currentPerformanceBuffer = await this.epochMap.getAsync(who.toString());
|
|
46
47
|
return currentPerformanceBuffer ? this.deserializePerformance(currentPerformanceBuffer) : [];
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
private async
|
|
50
|
+
private async pushValidatorEpochPerformance({
|
|
50
51
|
who,
|
|
51
52
|
missed,
|
|
52
53
|
total,
|
|
@@ -55,9 +56,9 @@ export class SentinelStore {
|
|
|
55
56
|
who: EthAddress;
|
|
56
57
|
missed: number;
|
|
57
58
|
total: number;
|
|
58
|
-
epoch:
|
|
59
|
+
epoch: EpochNumber;
|
|
59
60
|
}) {
|
|
60
|
-
const currentPerformance = await this.
|
|
61
|
+
const currentPerformance = await this.getEpochPerformance(who);
|
|
61
62
|
const existingIndex = currentPerformance.findIndex(p => p.epoch === epoch);
|
|
62
63
|
if (existingIndex !== -1) {
|
|
63
64
|
currentPerformance[existingIndex] = { missed, total, epoch };
|
|
@@ -69,13 +70,13 @@ export class SentinelStore {
|
|
|
69
70
|
// Since we keep the size small, this is not a big deal.
|
|
70
71
|
currentPerformance.sort((a, b) => Number(a.epoch - b.epoch));
|
|
71
72
|
|
|
72
|
-
// keep the most recent `
|
|
73
|
-
const performanceToKeep = currentPerformance.slice(-this.config.
|
|
73
|
+
// keep the most recent `historicEpochPerformanceLength` entries.
|
|
74
|
+
const performanceToKeep = currentPerformance.slice(-this.config.historicEpochPerformanceLength);
|
|
74
75
|
|
|
75
|
-
await this.
|
|
76
|
+
await this.epochMap.set(who.toString(), this.serializePerformance(performanceToKeep));
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
public async updateValidators(slot:
|
|
79
|
+
public async updateValidators(slot: SlotNumber, statuses: Record<`0x${string}`, ValidatorStatusInSlot | undefined>) {
|
|
79
80
|
await this.store.transactionAsync(async () => {
|
|
80
81
|
for (const [who, status] of Object.entries(statuses)) {
|
|
81
82
|
if (status) {
|
|
@@ -85,11 +86,7 @@ export class SentinelStore {
|
|
|
85
86
|
});
|
|
86
87
|
}
|
|
87
88
|
|
|
88
|
-
private async pushValidatorStatusForSlot(
|
|
89
|
-
who: EthAddress,
|
|
90
|
-
slot: bigint,
|
|
91
|
-
status: 'block-mined' | 'block-proposed' | 'block-missed' | 'attestation-sent' | 'attestation-missed',
|
|
92
|
-
) {
|
|
89
|
+
private async pushValidatorStatusForSlot(who: EthAddress, slot: SlotNumber, status: ValidatorStatusInSlot) {
|
|
93
90
|
await this.store.transactionAsync(async () => {
|
|
94
91
|
const currentHistory = (await this.getHistory(who)) ?? [];
|
|
95
92
|
const newHistory = [...currentHistory, { slot, status }].slice(-this.config.historyLength);
|
|
@@ -110,18 +107,18 @@ export class SentinelStore {
|
|
|
110
107
|
return data && this.deserializeHistory(data);
|
|
111
108
|
}
|
|
112
109
|
|
|
113
|
-
private serializePerformance(performance: { missed: number; total: number; epoch:
|
|
110
|
+
private serializePerformance(performance: { missed: number; total: number; epoch: EpochNumber }[]): Buffer {
|
|
114
111
|
return serializeToBuffer(
|
|
115
112
|
performance.map(p => [numToUInt32BE(Number(p.epoch)), numToUInt32BE(p.missed), numToUInt32BE(p.total)]),
|
|
116
113
|
);
|
|
117
114
|
}
|
|
118
115
|
|
|
119
|
-
private deserializePerformance(buffer: Buffer): { missed: number; total: number; epoch:
|
|
116
|
+
private deserializePerformance(buffer: Buffer): { missed: number; total: number; epoch: EpochNumber }[] {
|
|
120
117
|
const reader = new BufferReader(buffer);
|
|
121
|
-
const performance: { missed: number; total: number; epoch:
|
|
118
|
+
const performance: { missed: number; total: number; epoch: EpochNumber }[] = [];
|
|
122
119
|
while (!reader.isEmpty()) {
|
|
123
120
|
performance.push({
|
|
124
|
-
epoch:
|
|
121
|
+
epoch: EpochNumber(reader.readNumber()),
|
|
125
122
|
missed: reader.readNumber(),
|
|
126
123
|
total: reader.readNumber(),
|
|
127
124
|
});
|
|
@@ -139,7 +136,7 @@ export class SentinelStore {
|
|
|
139
136
|
const reader = new BufferReader(buffer);
|
|
140
137
|
const history: ValidatorStatusHistory = [];
|
|
141
138
|
while (!reader.isEmpty()) {
|
|
142
|
-
const slot =
|
|
139
|
+
const slot = SlotNumber(reader.readNumber());
|
|
143
140
|
const status = this.statusFromNumber(reader.readUInt8());
|
|
144
141
|
history.push({ slot, status });
|
|
145
142
|
}
|
|
@@ -148,16 +145,22 @@ export class SentinelStore {
|
|
|
148
145
|
|
|
149
146
|
private statusToNumber(status: ValidatorStatusInSlot): number {
|
|
150
147
|
switch (status) {
|
|
151
|
-
case '
|
|
148
|
+
case 'checkpoint-mined':
|
|
152
149
|
return 1;
|
|
153
|
-
case '
|
|
150
|
+
case 'checkpoint-valid':
|
|
154
151
|
return 2;
|
|
155
|
-
case '
|
|
152
|
+
case 'checkpoint-missed':
|
|
156
153
|
return 3;
|
|
157
154
|
case 'attestation-sent':
|
|
158
155
|
return 4;
|
|
159
156
|
case 'attestation-missed':
|
|
160
157
|
return 5;
|
|
158
|
+
case 'blocks-missed':
|
|
159
|
+
return 6;
|
|
160
|
+
case 'checkpoint-invalid':
|
|
161
|
+
return 7;
|
|
162
|
+
case 'checkpoint-unvalidated':
|
|
163
|
+
return 8;
|
|
161
164
|
default: {
|
|
162
165
|
const _exhaustive: never = status;
|
|
163
166
|
throw new Error(`Unknown status: ${status}`);
|
|
@@ -168,15 +171,21 @@ export class SentinelStore {
|
|
|
168
171
|
private statusFromNumber(status: number): ValidatorStatusInSlot {
|
|
169
172
|
switch (status) {
|
|
170
173
|
case 1:
|
|
171
|
-
return '
|
|
174
|
+
return 'checkpoint-mined';
|
|
172
175
|
case 2:
|
|
173
|
-
return '
|
|
176
|
+
return 'checkpoint-valid';
|
|
174
177
|
case 3:
|
|
175
|
-
return '
|
|
178
|
+
return 'checkpoint-missed';
|
|
176
179
|
case 4:
|
|
177
180
|
return 'attestation-sent';
|
|
178
181
|
case 5:
|
|
179
182
|
return 'attestation-missed';
|
|
183
|
+
case 6:
|
|
184
|
+
return 'blocks-missed';
|
|
185
|
+
case 7:
|
|
186
|
+
return 'checkpoint-invalid';
|
|
187
|
+
case 8:
|
|
188
|
+
return 'checkpoint-unvalidated';
|
|
180
189
|
default:
|
|
181
190
|
throw new Error(`Unknown status: ${status}`);
|
|
182
191
|
}
|
package/src/test/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
2
|
import type { P2P } from '@aztec/p2p';
|
|
3
3
|
import { SequencerClient } from '@aztec/sequencer-client';
|
|
4
|
-
import {
|
|
4
|
+
import { DataWithholdingWatcher, type SlasherClientInterface } from '@aztec/slasher';
|
|
5
5
|
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
6
6
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
7
7
|
import type { L2LogsSource, Service, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
@@ -23,7 +23,7 @@ export declare class TestAztecNodeService extends AztecNodeService {
|
|
|
23
23
|
declare public sequencer: SequencerClient | undefined;
|
|
24
24
|
declare public slasherClient: SlasherClientInterface | undefined;
|
|
25
25
|
declare public validatorsSentinel: Sentinel | undefined;
|
|
26
|
-
declare public
|
|
26
|
+
declare public dataWithholdingWatcher: DataWithholdingWatcher | undefined;
|
|
27
27
|
declare public l1ChainId: number;
|
|
28
28
|
declare public version: number;
|
|
29
29
|
declare public globalVariableBuilder: GlobalVariableBuilderInterface;
|