@aztec/validator-client 1.0.0 → 1.1.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAKjB,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,6EAA6E;IAC7E,oBAAoB,EAAE,WAAW,CAAC,KAAK,MAAM,EAAE,EAAE,CAAC,CAAC;IAEnD,+BAA+B;IAC/B,gBAAgB,EAAE,OAAO,CAAC;IAE1B,+DAA+D;IAC/D,4BAA4B,EAAE,MAAM,CAAC;IAErC,+CAA+C;IAC/C,kBAAkB,EAAE,OAAO,CAAC;IAE5B,wEAAwE;IACxE,4BAA4B,EAAE,MAAM,CAAC;CACtC;AAED,eAAO,MAAM,6BAA6B,EAAE,kBAAkB,CAAC,qBAAqB,CA4BnF,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,qBAAqB,CAExD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAKjB,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,6EAA6E;IAC7E,oBAAoB,EAAE,WAAW,CAAC,KAAK,MAAM,EAAE,EAAE,CAAC,CAAC;IAEnD,+BAA+B;IAC/B,gBAAgB,EAAE,OAAO,CAAC;IAE1B,+DAA+D;IAC/D,4BAA4B,EAAE,MAAM,CAAC;IAErC,+CAA+C;IAC/C,kBAAkB,EAAE,OAAO,CAAC;IAE5B,wEAAwE;IACxE,4BAA4B,EAAE,MAAM,CAAC;CACtC;AAED,eAAO,MAAM,6BAA6B,EAAE,kBAAkB,CAAC,qBAAqB,CA6BnF,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,qBAAqB,CAExD"}
package/dest/config.js CHANGED
@@ -3,7 +3,10 @@ export const validatorClientConfigMappings = {
3
3
  validatorPrivateKeys: {
4
4
  env: 'VALIDATOR_PRIVATE_KEYS',
5
5
  description: 'List of private keys of the validators participating in attestation duties',
6
- ...secretValueConfigHelper((val)=>val ? val.split(',').map((key)=>`0x${key.replace('0x', '')}`) : [])
6
+ ...secretValueConfigHelper((val)=>val ? val.split(',').map((key)=>`0x${key.replace('0x', '')}`) : []),
7
+ fallback: [
8
+ 'VALIDATOR_PRIVATE_KEY'
9
+ ]
7
10
  },
8
11
  disableValidator: {
9
12
  env: 'VALIDATOR_DISABLED',
@@ -1,4 +1,5 @@
1
1
  import type { EpochCache } from '@aztec/epoch-cache';
2
+ import { Buffer32 } from '@aztec/foundation/buffer';
2
3
  import type { EthAddress } from '@aztec/foundation/eth-address';
3
4
  import { Fr } from '@aztec/foundation/fields';
4
5
  import { DateProvider } from '@aztec/foundation/timer';
@@ -48,6 +49,7 @@ export declare class ValidatorClient extends ValidatorClient_base implements Val
48
49
  private handleEpochCommitteeUpdate;
49
50
  static new(config: ValidatorClientConfig & Pick<SlasherConfig, 'slashInvalidBlockEnabled' | 'slashInvalidBlockPenalty' | 'slashInvalidBlockMaxPenalty'>, blockBuilder: IFullNodeBlockBuilder, epochCache: EpochCache, p2pClient: P2P, blockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, dateProvider?: DateProvider, telemetry?: TelemetryClient): ValidatorClient;
50
51
  getValidatorAddresses(): EthAddress[];
52
+ signWithAddress(addr: EthAddress, msg: Buffer32): Promise<import("@aztec/stdlib/block").Signature>;
51
53
  configureSlashing(config: Partial<Pick<SlasherConfig, 'slashInvalidBlockEnabled' | 'slashInvalidBlockPenalty' | 'slashInvalidBlockMaxPenalty'>>): void;
52
54
  start(): Promise<void>;
53
55
  stop(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
package/dest/validator.js CHANGED
@@ -2,6 +2,7 @@ import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
2
2
  import { Buffer32 } from '@aztec/foundation/buffer';
3
3
  import { Fr } from '@aztec/foundation/fields';
4
4
  import { createLogger } from '@aztec/foundation/log';
5
+ import { retryUntil } from '@aztec/foundation/retry';
5
6
  import { RunningPromise } from '@aztec/foundation/running-promise';
6
7
  import { sleep } from '@aztec/foundation/sleep';
7
8
  import { DateProvider, Timer } from '@aztec/foundation/timer';
@@ -90,6 +91,9 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
90
91
  getValidatorAddresses() {
91
92
  return this.keyStore.getAddresses();
92
93
  }
94
+ signWithAddress(addr, msg) {
95
+ return this.keyStore.signWithAddress(addr, msg);
96
+ }
93
97
  configureSlashing(config) {
94
98
  this.config.slashInvalidBlockEnabled = config.slashInvalidBlockEnabled ?? this.config.slashInvalidBlockEnabled;
95
99
  this.config.slashInvalidBlockPenalty = config.slashInvalidBlockPenalty ?? this.config.slashInvalidBlockPenalty;
@@ -121,6 +125,9 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
121
125
  const slotNumber = proposal.slotNumber.toNumber();
122
126
  const blockNumber = proposal.blockNumber;
123
127
  const proposer = proposal.getSender();
128
+ // Check that I have any address in current committee before attesting
129
+ const inCommittee = await this.epochCache.filterInCommittee(this.keyStore.getAddresses());
130
+ const partOfCommittee = inCommittee.length > 0;
124
131
  const proposalInfo = {
125
132
  slotNumber,
126
133
  blockNumber,
@@ -135,7 +142,9 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
135
142
  const invalidProposal = await this.blockProposalValidator.validate(proposal);
136
143
  if (invalidProposal) {
137
144
  this.log.warn(`Proposal is not valid, skipping attestation`);
138
- this.metrics.incFailedAttestations(1, 'invalid_proposal');
145
+ if (partOfCommittee) {
146
+ this.metrics.incFailedAttestations(1, 'invalid_proposal');
147
+ }
139
148
  return undefined;
140
149
  }
141
150
  // Check that the parent proposal is a block we know, otherwise reexecution would fail.
@@ -144,10 +153,23 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
144
153
  // would not be rebroadcasted. But it also means that nodes that have not fully synced would
145
154
  // not rebroadcast the proposal.
146
155
  if (blockNumber > INITIAL_L2_BLOCK_NUM) {
147
- const parentBlock = await this.blockSource.getBlock(blockNumber - 1);
156
+ const config = this.blockBuilder.getConfig();
157
+ const deadline = this.getReexecutionDeadline(proposal, config);
158
+ const currentTime = this.dateProvider.now();
159
+ const timeoutDurationMs = deadline.getTime() - currentTime;
160
+ const parentBlock = timeoutDurationMs <= 0 ? undefined : await retryUntil(async ()=>{
161
+ const block = await this.blockSource.getBlock(blockNumber - 1);
162
+ if (block) {
163
+ return block;
164
+ }
165
+ await this.blockSource.syncImmediate();
166
+ return await this.blockSource.getBlock(blockNumber - 1);
167
+ }, 'Force Archiver Sync', timeoutDurationMs / 1000, 0.5);
148
168
  if (parentBlock === undefined) {
149
169
  this.log.warn(`Parent block for ${blockNumber} not found, skipping attestation`);
150
- this.metrics.incFailedAttestations(1, 'parent_block_not_found');
170
+ if (partOfCommittee) {
171
+ this.metrics.incFailedAttestations(1, 'parent_block_not_found');
172
+ }
151
173
  return undefined;
152
174
  }
153
175
  if (!proposal.payload.header.lastArchiveRoot.equals(parentBlock.archive.root)) {
@@ -156,25 +178,23 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
156
178
  parentBlockArchiveRoot: parentBlock.archive.root.toString(),
157
179
  ...proposalInfo
158
180
  });
159
- this.metrics.incFailedAttestations(1, 'parent_block_does_not_match');
181
+ if (partOfCommittee) {
182
+ this.metrics.incFailedAttestations(1, 'parent_block_does_not_match');
183
+ }
160
184
  return undefined;
161
185
  }
162
186
  }
163
187
  // Collect txs from the proposal
164
188
  const { missing, txs } = await this.txCollector.collectForBlockProposal(proposal, proposalSender);
165
- // Check that I have any address in current committee before attesting
166
- const inCommittee = await this.epochCache.filterInCommittee(this.keyStore.getAddresses());
167
- if (inCommittee.length === 0) {
168
- this.log.verbose(`No validator in the committee, skipping attestation`);
169
- return undefined;
170
- }
171
189
  // Check that all of the transactions in the proposal are available in the tx pool before attesting
172
190
  if (missing && missing.length > 0) {
173
191
  this.log.warn(`Missing ${missing.length}/${proposal.payload.txHashes.length} txs to attest to proposal`, {
174
192
  ...proposalInfo,
175
193
  missing
176
194
  });
177
- this.metrics.incFailedAttestations(1, 'TransactionsNotAvailableError');
195
+ if (partOfCommittee) {
196
+ this.metrics.incFailedAttestations(1, 'tx_not_available');
197
+ }
178
198
  return undefined;
179
199
  }
180
200
  // Check that I have the same set of l1ToL2Messages as the proposal
@@ -187,7 +207,13 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
187
207
  computedInHash: computedInHash.toString(),
188
208
  ...proposalInfo
189
209
  });
190
- this.metrics.incFailedAttestations(1, 'in_hash_mismatch');
210
+ if (partOfCommittee) {
211
+ this.metrics.incFailedAttestations(1, 'in_hash_mismatch');
212
+ }
213
+ return undefined;
214
+ }
215
+ if (!partOfCommittee) {
216
+ this.log.verbose(`No validator in the committee, skipping attestation`);
191
217
  return undefined;
192
218
  }
193
219
  // Try re-executing the transactions in the proposal
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/validator-client",
3
- "version": "1.0.0",
3
+ "version": "1.1.2",
4
4
  "main": "dest/index.js",
5
5
  "type": "module",
6
6
  "exports": {
@@ -64,15 +64,15 @@
64
64
  ]
65
65
  },
66
66
  "dependencies": {
67
- "@aztec/constants": "1.0.0",
68
- "@aztec/epoch-cache": "1.0.0",
69
- "@aztec/ethereum": "1.0.0",
70
- "@aztec/foundation": "1.0.0",
71
- "@aztec/p2p": "1.0.0",
72
- "@aztec/prover-client": "1.0.0",
73
- "@aztec/slasher": "1.0.0",
74
- "@aztec/stdlib": "1.0.0",
75
- "@aztec/telemetry-client": "1.0.0",
67
+ "@aztec/constants": "1.1.2",
68
+ "@aztec/epoch-cache": "1.1.2",
69
+ "@aztec/ethereum": "1.1.2",
70
+ "@aztec/foundation": "1.1.2",
71
+ "@aztec/p2p": "1.1.2",
72
+ "@aztec/prover-client": "1.1.2",
73
+ "@aztec/slasher": "1.1.2",
74
+ "@aztec/stdlib": "1.1.2",
75
+ "@aztec/telemetry-client": "1.1.2",
76
76
  "koa": "^2.16.1",
77
77
  "koa-router": "^12.0.0",
78
78
  "tslib": "^2.4.0",
package/src/config.ts CHANGED
@@ -34,6 +34,7 @@ export const validatorClientConfigMappings: ConfigMappingsType<ValidatorClientCo
34
34
  ...secretValueConfigHelper<`0x${string}`[]>(val =>
35
35
  val ? val.split(',').map<`0x${string}`>(key => `0x${key.replace('0x', '')}`) : [],
36
36
  ),
37
+ fallback: ['VALIDATOR_PRIVATE_KEY'],
37
38
  },
38
39
  disableValidator: {
39
40
  env: 'VALIDATOR_DISABLED',
package/src/validator.ts CHANGED
@@ -4,6 +4,7 @@ import { Buffer32 } from '@aztec/foundation/buffer';
4
4
  import type { EthAddress } from '@aztec/foundation/eth-address';
5
5
  import { Fr } from '@aztec/foundation/fields';
6
6
  import { createLogger } from '@aztec/foundation/log';
7
+ import { retryUntil } from '@aztec/foundation/retry';
7
8
  import { RunningPromise } from '@aztec/foundation/running-promise';
8
9
  import { sleep } from '@aztec/foundation/sleep';
9
10
  import { DateProvider, Timer } from '@aztec/foundation/timer';
@@ -181,6 +182,10 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
181
182
  return this.keyStore.getAddresses();
182
183
  }
183
184
 
185
+ public signWithAddress(addr: EthAddress, msg: Buffer32) {
186
+ return this.keyStore.signWithAddress(addr, msg);
187
+ }
188
+
184
189
  public configureSlashing(
185
190
  config: Partial<
186
191
  Pick<SlasherConfig, 'slashInvalidBlockEnabled' | 'slashInvalidBlockPenalty' | 'slashInvalidBlockMaxPenalty'>
@@ -226,6 +231,10 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
226
231
  const blockNumber = proposal.blockNumber;
227
232
  const proposer = proposal.getSender();
228
233
 
234
+ // Check that I have any address in current committee before attesting
235
+ const inCommittee = await this.epochCache.filterInCommittee(this.keyStore.getAddresses());
236
+ const partOfCommittee = inCommittee.length > 0;
237
+
229
238
  const proposalInfo = {
230
239
  slotNumber,
231
240
  blockNumber,
@@ -241,7 +250,9 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
241
250
  const invalidProposal = await this.blockProposalValidator.validate(proposal);
242
251
  if (invalidProposal) {
243
252
  this.log.warn(`Proposal is not valid, skipping attestation`);
244
- this.metrics.incFailedAttestations(1, 'invalid_proposal');
253
+ if (partOfCommittee) {
254
+ this.metrics.incFailedAttestations(1, 'invalid_proposal');
255
+ }
245
256
  return undefined;
246
257
  }
247
258
 
@@ -251,10 +262,34 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
251
262
  // would not be rebroadcasted. But it also means that nodes that have not fully synced would
252
263
  // not rebroadcast the proposal.
253
264
  if (blockNumber > INITIAL_L2_BLOCK_NUM) {
254
- const parentBlock = await this.blockSource.getBlock(blockNumber - 1);
265
+ const config = this.blockBuilder.getConfig();
266
+ const deadline = this.getReexecutionDeadline(proposal, config);
267
+ const currentTime = this.dateProvider.now();
268
+ const timeoutDurationMs = deadline.getTime() - currentTime;
269
+ const parentBlock =
270
+ timeoutDurationMs <= 0
271
+ ? undefined
272
+ : await retryUntil(
273
+ async () => {
274
+ const block = await this.blockSource.getBlock(blockNumber - 1);
275
+ if (block) {
276
+ return block;
277
+ }
278
+ await this.blockSource.syncImmediate();
279
+ return await this.blockSource.getBlock(blockNumber - 1);
280
+ },
281
+ 'Force Archiver Sync',
282
+ timeoutDurationMs / 1000, // Continue retrying until the deadline
283
+ 0.5, // Retry every 500ms
284
+ );
285
+
255
286
  if (parentBlock === undefined) {
256
287
  this.log.warn(`Parent block for ${blockNumber} not found, skipping attestation`);
257
- this.metrics.incFailedAttestations(1, 'parent_block_not_found');
288
+
289
+ if (partOfCommittee) {
290
+ this.metrics.incFailedAttestations(1, 'parent_block_not_found');
291
+ }
292
+
258
293
  return undefined;
259
294
  }
260
295
  if (!proposal.payload.header.lastArchiveRoot.equals(parentBlock.archive.root)) {
@@ -263,7 +298,9 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
263
298
  parentBlockArchiveRoot: parentBlock.archive.root.toString(),
264
299
  ...proposalInfo,
265
300
  });
266
- this.metrics.incFailedAttestations(1, 'parent_block_does_not_match');
301
+ if (partOfCommittee) {
302
+ this.metrics.incFailedAttestations(1, 'parent_block_does_not_match');
303
+ }
267
304
  return undefined;
268
305
  }
269
306
  }
@@ -271,20 +308,15 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
271
308
  // Collect txs from the proposal
272
309
  const { missing, txs } = await this.txCollector.collectForBlockProposal(proposal, proposalSender);
273
310
 
274
- // Check that I have any address in current committee before attesting
275
- const inCommittee = await this.epochCache.filterInCommittee(this.keyStore.getAddresses());
276
- if (inCommittee.length === 0) {
277
- this.log.verbose(`No validator in the committee, skipping attestation`);
278
- return undefined;
279
- }
280
-
281
311
  // Check that all of the transactions in the proposal are available in the tx pool before attesting
282
312
  if (missing && missing.length > 0) {
283
313
  this.log.warn(`Missing ${missing.length}/${proposal.payload.txHashes.length} txs to attest to proposal`, {
284
314
  ...proposalInfo,
285
315
  missing,
286
316
  });
287
- this.metrics.incFailedAttestations(1, 'TransactionsNotAvailableError');
317
+ if (partOfCommittee) {
318
+ this.metrics.incFailedAttestations(1, 'tx_not_available');
319
+ }
288
320
  return undefined;
289
321
  }
290
322
 
@@ -298,7 +330,14 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
298
330
  computedInHash: computedInHash.toString(),
299
331
  ...proposalInfo,
300
332
  });
301
- this.metrics.incFailedAttestations(1, 'in_hash_mismatch');
333
+ if (partOfCommittee) {
334
+ this.metrics.incFailedAttestations(1, 'in_hash_mismatch');
335
+ }
336
+ return undefined;
337
+ }
338
+
339
+ if (!partOfCommittee) {
340
+ this.log.verbose(`No validator in the committee, skipping attestation`);
302
341
  return undefined;
303
342
  }
304
343