@aztec/validator-client 0.82.2 → 0.82.3
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/validator.d.ts +6 -1
- package/dest/validator.d.ts.map +1 -1
- package/dest/validator.js +31 -18
- package/package.json +7 -7
- package/src/validator.ts +34 -24
package/dest/validator.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
2
|
+
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
3
|
import type { Fr } from '@aztec/foundation/fields';
|
|
3
4
|
import { DateProvider, type Timer } from '@aztec/foundation/timer';
|
|
4
5
|
import type { P2P } from '@aztec/p2p';
|
|
@@ -45,11 +46,14 @@ export declare class ValidatorClient extends WithTracer implements Validator {
|
|
|
45
46
|
private metrics;
|
|
46
47
|
private previousProposal?;
|
|
47
48
|
private blockBuilder?;
|
|
49
|
+
private myAddress;
|
|
50
|
+
private lastEpoch;
|
|
48
51
|
private epochCacheUpdateLoop;
|
|
49
52
|
private blockProposalValidator;
|
|
50
53
|
constructor(keyStore: ValidatorKeyStore, epochCache: EpochCache, p2pClient: P2P, config: ValidatorClientConfig, dateProvider?: DateProvider, telemetry?: TelemetryClient, log?: import("@aztec/foundation/log").Logger);
|
|
54
|
+
private handleEpochCommiteeUpdate;
|
|
51
55
|
static new(config: ValidatorClientConfig, epochCache: EpochCache, p2pClient: P2P, dateProvider?: DateProvider, telemetry?: TelemetryClient): ValidatorClient;
|
|
52
|
-
getValidatorAddress():
|
|
56
|
+
getValidatorAddress(): EthAddress;
|
|
53
57
|
start(): Promise<void>;
|
|
54
58
|
stop(): Promise<void>;
|
|
55
59
|
registerBlockProposalHandler(): void;
|
|
@@ -77,6 +81,7 @@ export declare class ValidatorClient extends WithTracer implements Validator {
|
|
|
77
81
|
createBlockProposal(header: BlockHeader, archive: Fr, txs: TxHash[]): Promise<BlockProposal | undefined>;
|
|
78
82
|
broadcastBlockProposal(proposal: BlockProposal): void;
|
|
79
83
|
collectAttestations(proposal: BlockProposal, required: number, deadline: Date): Promise<BlockAttestation[]>;
|
|
84
|
+
private doAttestToProposal;
|
|
80
85
|
}
|
|
81
86
|
export {};
|
|
82
87
|
//# sourceMappingURL=validator.d.ts.map
|
package/dest/validator.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAInD,OAAO,EAAE,YAAY,EAAE,KAAK,KAAK,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,KAAK,eAAe,EAAE,UAAU,EAAsB,MAAM,yBAAyB,CAAC;AAE/F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAWzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAIlE;;;;GAIG;AACH,KAAK,oBAAoB,GAAG,CAC1B,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,qBAAqB,CAAC,EAAE,CAAC,EAC7C,eAAe,EAAE,eAAe,EAChC,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,KAC9B,OAAO,CAAC;IACX,KAAK,EAAE,OAAO,CAAC;IACf,uBAAuB,EAAE,MAAM,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,KAAK,CAAC;CAC3B,CAAC,CAAC;AAEH,MAAM,WAAW,SAAS;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,4BAA4B,IAAI,IAAI,CAAC;IACrC,oBAAoB,CAAC,YAAY,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAG/D,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IACzG,gBAAgB,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAEhD,sBAAsB,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IACtD,mBAAmB,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;CAC7G;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,UAAW,YAAW,SAAS;
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
|
package/dest/validator.js
CHANGED
|
@@ -24,6 +24,8 @@ import { ValidatorMetrics } from './metrics.js';
|
|
|
24
24
|
previousProposal;
|
|
25
25
|
// Callback registered to: sequencer.buildBlock
|
|
26
26
|
blockBuilder;
|
|
27
|
+
myAddress;
|
|
28
|
+
lastEpoch;
|
|
27
29
|
epochCacheUpdateLoop;
|
|
28
30
|
blockProposalValidator;
|
|
29
31
|
constructor(keyStore, epochCache, p2pClient, config, dateProvider = new DateProvider(), telemetry = getTelemetryClient(), log = createLogger('validator')){
|
|
@@ -32,19 +34,27 @@ import { ValidatorMetrics } from './metrics.js';
|
|
|
32
34
|
this.metrics = new ValidatorMetrics(telemetry);
|
|
33
35
|
this.validationService = new ValidationService(keyStore);
|
|
34
36
|
this.blockProposalValidator = new BlockProposalValidator(epochCache);
|
|
35
|
-
// Refresh epoch cache every second to trigger
|
|
36
|
-
this.
|
|
37
|
-
|
|
38
|
-
this.epochCache.on('committeeChanged', (newCommittee, epochNumber)=>{
|
|
39
|
-
const me = this.keyStore.getAddress();
|
|
40
|
-
if (newCommittee.some((addr)=>addr.equals(me))) {
|
|
41
|
-
this.log.info(`Validator ${me.toString()} is on the validator committee for epoch ${epochNumber}`);
|
|
42
|
-
} else {
|
|
43
|
-
this.log.verbose(`Validator ${me.toString()} not on the validator committee for epoch ${epochNumber}`);
|
|
44
|
-
}
|
|
45
|
-
});
|
|
37
|
+
// Refresh epoch cache every second to trigger alert if participation in commitee changes
|
|
38
|
+
this.myAddress = this.keyStore.getAddress();
|
|
39
|
+
this.epochCacheUpdateLoop = new RunningPromise(this.handleEpochCommiteeUpdate.bind(this), log, 1000);
|
|
46
40
|
this.log.verbose(`Initialized validator with address ${this.keyStore.getAddress().toString()}`);
|
|
47
41
|
}
|
|
42
|
+
async handleEpochCommiteeUpdate() {
|
|
43
|
+
try {
|
|
44
|
+
const { committee, epoch } = await this.epochCache.getCommittee('now');
|
|
45
|
+
if (epoch !== this.lastEpoch) {
|
|
46
|
+
const me = this.myAddress;
|
|
47
|
+
if (committee.some((addr)=>addr.equals(me))) {
|
|
48
|
+
this.log.info(`Validator ${me.toString()} is on the validator committee for epoch ${epoch}`);
|
|
49
|
+
} else {
|
|
50
|
+
this.log.verbose(`Validator ${me.toString()} not on the validator committee for epoch ${epoch}`);
|
|
51
|
+
}
|
|
52
|
+
this.lastEpoch = epoch;
|
|
53
|
+
}
|
|
54
|
+
} catch (err) {
|
|
55
|
+
this.log.error(`Error updating epoch committee`, err);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
48
58
|
static new(config, epochCache, p2pClient, dateProvider = new DateProvider(), telemetry = getTelemetryClient()) {
|
|
49
59
|
if (!config.validatorPrivateKey) {
|
|
50
60
|
throw new InvalidValidatorPrivateKeyError();
|
|
@@ -130,7 +140,7 @@ import { ValidatorMetrics } from './metrics.js';
|
|
|
130
140
|
// Provided all of the above checks pass, we can attest to the proposal
|
|
131
141
|
this.log.info(`Attesting to proposal for slot ${slotNumber}`, proposalInfo);
|
|
132
142
|
// If the above function does not throw an error, then we can attest to the proposal
|
|
133
|
-
return this.
|
|
143
|
+
return this.doAttestToProposal(proposal);
|
|
134
144
|
}
|
|
135
145
|
/**
|
|
136
146
|
* Re-execute the transactions in the proposal and check that the state updates match the header state
|
|
@@ -212,17 +222,15 @@ import { ValidatorMetrics } from './metrics.js';
|
|
|
212
222
|
throw new AttestationTimeoutError(required, slot);
|
|
213
223
|
}
|
|
214
224
|
const proposalId = proposal.archive.toString();
|
|
215
|
-
|
|
225
|
+
await this.doAttestToProposal(proposal);
|
|
226
|
+
const me = this.keyStore.getAddress();
|
|
216
227
|
let attestations = [];
|
|
217
228
|
while(true){
|
|
218
|
-
const collectedAttestations =
|
|
219
|
-
myAttestation,
|
|
220
|
-
...await this.p2pClient.getAttestationsForSlot(slot, proposalId)
|
|
221
|
-
];
|
|
229
|
+
const collectedAttestations = await this.p2pClient.getAttestationsForSlot(slot, proposalId);
|
|
222
230
|
const oldSenders = await Promise.all(attestations.map((attestation)=>attestation.getSender()));
|
|
223
231
|
for (const collected of collectedAttestations){
|
|
224
232
|
const collectedSender = await collected.getSender();
|
|
225
|
-
if (!oldSenders.some((sender)=>sender.equals(collectedSender))) {
|
|
233
|
+
if (!collectedSender.equals(me) && !oldSenders.some((sender)=>sender.equals(collectedSender))) {
|
|
226
234
|
this.log.debug(`Received attestation for slot ${slot} from ${collectedSender.toString()}`);
|
|
227
235
|
}
|
|
228
236
|
}
|
|
@@ -239,6 +247,11 @@ import { ValidatorMetrics } from './metrics.js';
|
|
|
239
247
|
await sleep(this.config.attestationPollingIntervalMs);
|
|
240
248
|
}
|
|
241
249
|
}
|
|
250
|
+
async doAttestToProposal(proposal) {
|
|
251
|
+
const attestation = await this.validationService.attestToProposal(proposal);
|
|
252
|
+
await this.p2pClient.addAttestation(attestation);
|
|
253
|
+
return attestation;
|
|
254
|
+
}
|
|
242
255
|
}
|
|
243
256
|
function validatePrivateKey(privateKey) {
|
|
244
257
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/validator-client",
|
|
3
|
-
"version": "0.82.
|
|
3
|
+
"version": "0.82.3",
|
|
4
4
|
"main": "dest/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -62,12 +62,12 @@
|
|
|
62
62
|
]
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@aztec/epoch-cache": "0.82.
|
|
66
|
-
"@aztec/ethereum": "0.82.
|
|
67
|
-
"@aztec/foundation": "0.82.
|
|
68
|
-
"@aztec/p2p": "0.82.
|
|
69
|
-
"@aztec/stdlib": "0.82.
|
|
70
|
-
"@aztec/telemetry-client": "0.82.
|
|
65
|
+
"@aztec/epoch-cache": "0.82.3",
|
|
66
|
+
"@aztec/ethereum": "0.82.3",
|
|
67
|
+
"@aztec/foundation": "0.82.3",
|
|
68
|
+
"@aztec/p2p": "0.82.3",
|
|
69
|
+
"@aztec/stdlib": "0.82.3",
|
|
70
|
+
"@aztec/telemetry-client": "0.82.3",
|
|
71
71
|
"koa": "^2.14.2",
|
|
72
72
|
"koa-router": "^12.0.0",
|
|
73
73
|
"tslib": "^2.4.0",
|
package/src/validator.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
2
2
|
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
3
|
+
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
4
|
import type { Fr } from '@aztec/foundation/fields';
|
|
4
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
6
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
@@ -70,6 +71,8 @@ export class ValidatorClient extends WithTracer implements Validator {
|
|
|
70
71
|
// Callback registered to: sequencer.buildBlock
|
|
71
72
|
private blockBuilder?: BlockBuilderCallback = undefined;
|
|
72
73
|
|
|
74
|
+
private myAddress: EthAddress;
|
|
75
|
+
private lastEpoch: bigint | undefined;
|
|
73
76
|
private epochCacheUpdateLoop: RunningPromise;
|
|
74
77
|
|
|
75
78
|
private blockProposalValidator: BlockProposalValidator;
|
|
@@ -91,30 +94,30 @@ export class ValidatorClient extends WithTracer implements Validator {
|
|
|
91
94
|
|
|
92
95
|
this.blockProposalValidator = new BlockProposalValidator(epochCache);
|
|
93
96
|
|
|
94
|
-
// Refresh epoch cache every second to trigger
|
|
95
|
-
this.
|
|
96
|
-
|
|
97
|
-
this.epochCache
|
|
98
|
-
.getCommittee()
|
|
99
|
-
.then(() => {})
|
|
100
|
-
.catch(err => log.error('Error updating validator committee', err)),
|
|
101
|
-
log,
|
|
102
|
-
1000,
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
// Listen to commiteeChanged event to alert operator when their validator has entered the committee
|
|
106
|
-
this.epochCache.on('committeeChanged', (newCommittee, epochNumber) => {
|
|
107
|
-
const me = this.keyStore.getAddress();
|
|
108
|
-
if (newCommittee.some(addr => addr.equals(me))) {
|
|
109
|
-
this.log.info(`Validator ${me.toString()} is on the validator committee for epoch ${epochNumber}`);
|
|
110
|
-
} else {
|
|
111
|
-
this.log.verbose(`Validator ${me.toString()} not on the validator committee for epoch ${epochNumber}`);
|
|
112
|
-
}
|
|
113
|
-
});
|
|
97
|
+
// Refresh epoch cache every second to trigger alert if participation in commitee changes
|
|
98
|
+
this.myAddress = this.keyStore.getAddress();
|
|
99
|
+
this.epochCacheUpdateLoop = new RunningPromise(this.handleEpochCommiteeUpdate.bind(this), log, 1000);
|
|
114
100
|
|
|
115
101
|
this.log.verbose(`Initialized validator with address ${this.keyStore.getAddress().toString()}`);
|
|
116
102
|
}
|
|
117
103
|
|
|
104
|
+
private async handleEpochCommiteeUpdate() {
|
|
105
|
+
try {
|
|
106
|
+
const { committee, epoch } = await this.epochCache.getCommittee('now');
|
|
107
|
+
if (epoch !== this.lastEpoch) {
|
|
108
|
+
const me = this.myAddress;
|
|
109
|
+
if (committee.some(addr => addr.equals(me))) {
|
|
110
|
+
this.log.info(`Validator ${me.toString()} is on the validator committee for epoch ${epoch}`);
|
|
111
|
+
} else {
|
|
112
|
+
this.log.verbose(`Validator ${me.toString()} not on the validator committee for epoch ${epoch}`);
|
|
113
|
+
}
|
|
114
|
+
this.lastEpoch = epoch;
|
|
115
|
+
}
|
|
116
|
+
} catch (err) {
|
|
117
|
+
this.log.error(`Error updating epoch committee`, err);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
118
121
|
static new(
|
|
119
122
|
config: ValidatorClientConfig,
|
|
120
123
|
epochCache: EpochCache,
|
|
@@ -222,7 +225,7 @@ export class ValidatorClient extends WithTracer implements Validator {
|
|
|
222
225
|
this.log.info(`Attesting to proposal for slot ${slotNumber}`, proposalInfo);
|
|
223
226
|
|
|
224
227
|
// If the above function does not throw an error, then we can attest to the proposal
|
|
225
|
-
return this.
|
|
228
|
+
return this.doAttestToProposal(proposal);
|
|
226
229
|
}
|
|
227
230
|
|
|
228
231
|
/**
|
|
@@ -327,15 +330,16 @@ export class ValidatorClient extends WithTracer implements Validator {
|
|
|
327
330
|
}
|
|
328
331
|
|
|
329
332
|
const proposalId = proposal.archive.toString();
|
|
330
|
-
|
|
333
|
+
await this.doAttestToProposal(proposal);
|
|
334
|
+
const me = this.keyStore.getAddress();
|
|
331
335
|
|
|
332
336
|
let attestations: BlockAttestation[] = [];
|
|
333
337
|
while (true) {
|
|
334
|
-
const collectedAttestations =
|
|
338
|
+
const collectedAttestations = await this.p2pClient.getAttestationsForSlot(slot, proposalId);
|
|
335
339
|
const oldSenders = await Promise.all(attestations.map(attestation => attestation.getSender()));
|
|
336
340
|
for (const collected of collectedAttestations) {
|
|
337
341
|
const collectedSender = await collected.getSender();
|
|
338
|
-
if (!oldSenders.some(sender => sender.equals(collectedSender))) {
|
|
342
|
+
if (!collectedSender.equals(me) && !oldSenders.some(sender => sender.equals(collectedSender))) {
|
|
339
343
|
this.log.debug(`Received attestation for slot ${slot} from ${collectedSender.toString()}`);
|
|
340
344
|
}
|
|
341
345
|
}
|
|
@@ -355,6 +359,12 @@ export class ValidatorClient extends WithTracer implements Validator {
|
|
|
355
359
|
await sleep(this.config.attestationPollingIntervalMs);
|
|
356
360
|
}
|
|
357
361
|
}
|
|
362
|
+
|
|
363
|
+
private async doAttestToProposal(proposal: BlockProposal): Promise<BlockAttestation> {
|
|
364
|
+
const attestation = await this.validationService.attestToProposal(proposal);
|
|
365
|
+
await this.p2pClient.addAttestation(attestation);
|
|
366
|
+
return attestation;
|
|
367
|
+
}
|
|
358
368
|
}
|
|
359
369
|
|
|
360
370
|
function validatePrivateKey(privateKey: string): Buffer32 {
|