@aztec/prover-node 0.69.0-devnet → 0.69.1-devnet

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.
@@ -11,12 +11,18 @@ import {
11
11
  type ProverNodeApi,
12
12
  type Service,
13
13
  type Tx,
14
+ type TxHash,
14
15
  type WorldStateSynchronizer,
16
+ getTimestampRangeForEpoch,
15
17
  tryStop,
16
18
  } from '@aztec/circuit-types';
17
19
  import { type ContractDataSource } from '@aztec/circuits.js';
20
+ import { asyncPool } from '@aztec/foundation/async-pool';
18
21
  import { compact } from '@aztec/foundation/collection';
22
+ import { memoize } from '@aztec/foundation/decorators';
23
+ import { TimeoutError } from '@aztec/foundation/error';
19
24
  import { createLogger } from '@aztec/foundation/log';
25
+ import { retryUntil } from '@aztec/foundation/retry';
20
26
  import { DateProvider } from '@aztec/foundation/timer';
21
27
  import { type Maybe } from '@aztec/foundation/types';
22
28
  import { type P2P } from '@aztec/p2p';
@@ -36,6 +42,9 @@ export type ProverNodeOptions = {
36
42
  pollingIntervalMs: number;
37
43
  maxPendingJobs: number;
38
44
  maxParallelBlocksPerEpoch: number;
45
+ txGatheringTimeoutMs: number;
46
+ txGatheringIntervalMs: number;
47
+ txGatheringMaxParallelRequests: number;
39
48
  };
40
49
 
41
50
  /**
@@ -57,25 +66,28 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr
57
66
  public readonly tracer: Tracer;
58
67
 
59
68
  constructor(
60
- private readonly prover: EpochProverManager,
61
- private readonly publisher: L1Publisher,
62
- private readonly l2BlockSource: L2BlockSource & Maybe<Service>,
63
- private readonly l1ToL2MessageSource: L1ToL2MessageSource,
64
- private readonly contractDataSource: ContractDataSource,
65
- private readonly worldState: WorldStateSynchronizer,
66
- private readonly coordination: ProverCoordination & Maybe<Service>,
67
- private readonly quoteProvider: QuoteProvider,
68
- private readonly quoteSigner: QuoteSigner,
69
- private readonly claimsMonitor: ClaimsMonitor,
70
- private readonly epochsMonitor: EpochMonitor,
71
- private readonly bondManager: BondManager,
72
- private readonly telemetryClient: TelemetryClient,
69
+ protected readonly prover: EpochProverManager,
70
+ protected readonly publisher: L1Publisher,
71
+ protected readonly l2BlockSource: L2BlockSource & Maybe<Service>,
72
+ protected readonly l1ToL2MessageSource: L1ToL2MessageSource,
73
+ protected readonly contractDataSource: ContractDataSource,
74
+ protected readonly worldState: WorldStateSynchronizer,
75
+ protected readonly coordination: ProverCoordination & Maybe<Service>,
76
+ protected readonly quoteProvider: QuoteProvider,
77
+ protected readonly quoteSigner: QuoteSigner,
78
+ protected readonly claimsMonitor: ClaimsMonitor,
79
+ protected readonly epochsMonitor: EpochMonitor,
80
+ protected readonly bondManager: BondManager,
81
+ protected readonly telemetryClient: TelemetryClient,
73
82
  options: Partial<ProverNodeOptions> = {},
74
83
  ) {
75
84
  this.options = {
76
85
  pollingIntervalMs: 1_000,
77
86
  maxPendingJobs: 100,
78
87
  maxParallelBlocksPerEpoch: 32,
88
+ txGatheringTimeoutMs: 60_000,
89
+ txGatheringIntervalMs: 1_000,
90
+ txGatheringMaxParallelRequests: 100,
79
91
  ...compact(options),
80
92
  };
81
93
 
@@ -279,11 +291,19 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr
279
291
  return Promise.resolve();
280
292
  };
281
293
 
282
- const job = this.doCreateEpochProvingJob(epochNumber, blocks, txs, publicProcessorFactory, cleanUp);
294
+ const [_, endTimestamp] = getTimestampRangeForEpoch(epochNumber + 1n, await this.getL1Constants());
295
+ const deadline = new Date(Number(endTimestamp) * 1000);
296
+
297
+ const job = this.doCreateEpochProvingJob(epochNumber, deadline, blocks, txs, publicProcessorFactory, cleanUp);
283
298
  this.jobs.set(job.getId(), job);
284
299
  return job;
285
300
  }
286
301
 
302
+ @memoize
303
+ private getL1Constants() {
304
+ return this.l2BlockSource.getL1Constants();
305
+ }
306
+
287
307
  @trackSpan('ProverNode.gatherEpochData', epochNumber => ({ [Attributes.EPOCH_NUMBER]: Number(epochNumber) }))
288
308
  private async gatherEpochData(epochNumber: bigint) {
289
309
  // Gather blocks for this epoch and their txs
@@ -302,26 +322,74 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr
302
322
  }
303
323
 
304
324
  private async gatherTxs(epochNumber: bigint, blocks: L2Block[]) {
305
- const txs = await Promise.all(
306
- blocks.flatMap(block =>
307
- block.body.txEffects
308
- .map(tx => tx.txHash)
309
- .map(txHash => this.coordination.getTxByHash(txHash).then(tx => [block.number, txHash, tx] as const)),
310
- ),
325
+ let txsToFind: TxHash[] = [];
326
+ const txHashToBlock = new Map<string, number>();
327
+ const results = new Map<string, Tx>();
328
+
329
+ for (const block of blocks) {
330
+ for (const tx of block.body.txEffects) {
331
+ txsToFind.push(tx.txHash);
332
+ txHashToBlock.set(tx.txHash.toString(), block.number);
333
+ }
334
+ }
335
+
336
+ const totalTxsRequired = txsToFind.length;
337
+ this.log.info(
338
+ `Gathering a total of ${totalTxsRequired} txs for epoch=${epochNumber} made up of ${blocks.length} blocks`,
339
+ { epochNumber },
311
340
  );
312
341
 
313
- const notFound = txs.filter(([_blockNum, _txHash, tx]) => !tx);
314
- if (notFound.length) {
315
- const notFoundList = notFound.map(([blockNum, txHash]) => `${txHash.toString()} (block ${blockNum})`).join(', ');
316
- throw new Error(`Txs not found for epoch ${epochNumber}: ${notFoundList}`);
342
+ let iteration = 0;
343
+ try {
344
+ await retryUntil(
345
+ async () => {
346
+ const batch = [...txsToFind];
347
+ txsToFind = [];
348
+ const batchResults = await asyncPool(this.options.txGatheringMaxParallelRequests, batch, async txHash => {
349
+ const tx = await this.coordination.getTxByHash(txHash);
350
+ return [txHash, tx] as const;
351
+ });
352
+ let found = 0;
353
+ for (const [txHash, maybeTx] of batchResults) {
354
+ if (maybeTx) {
355
+ found++;
356
+ results.set(txHash.toString(), maybeTx);
357
+ } else {
358
+ txsToFind.push(txHash);
359
+ }
360
+ }
361
+
362
+ this.log.verbose(
363
+ `Gathered ${found}/${batch.length} txs in iteration ${iteration} for epoch ${epochNumber}. In total ${results.size}/${totalTxsRequired} have been retrieved.`,
364
+ { epochNumber },
365
+ );
366
+ iteration++;
367
+
368
+ // stop when we found all transactions
369
+ return txsToFind.length === 0;
370
+ },
371
+ 'Gather txs',
372
+ this.options.txGatheringTimeoutMs / 1_000,
373
+ this.options.txGatheringIntervalMs / 1_000,
374
+ );
375
+ } catch (err) {
376
+ if (err && err instanceof TimeoutError) {
377
+ const notFoundList = txsToFind
378
+ .map(txHash => `${txHash.toString()} (block ${txHashToBlock.get(txHash.toString())})`)
379
+ .join(', ');
380
+ throw new Error(`Txs not found for epoch ${epochNumber}: ${notFoundList}`);
381
+ } else {
382
+ throw err;
383
+ }
317
384
  }
318
385
 
319
- return txs.map(([_blockNumber, _txHash, tx]) => tx!);
386
+ return Array.from(results.values());
320
387
  }
321
388
 
322
389
  /** Extracted for testing purposes. */
323
390
  protected doCreateEpochProvingJob(
324
391
  epochNumber: bigint,
392
+ deadline: Date | undefined,
325
393
  blocks: L2Block[],
326
394
  txs: Tx[],
327
395
  publicProcessorFactory: PublicProcessorFactory,
@@ -338,6 +406,7 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr
338
406
  this.l2BlockSource,
339
407
  this.l1ToL2MessageSource,
340
408
  this.metrics,
409
+ deadline,
341
410
  { parallelBlockLimit: this.options.maxParallelBlocksPerEpoch },
342
411
  cleanUp,
343
412
  );
@@ -0,0 +1,11 @@
1
+ import { type EpochProverManager } from '@aztec/circuit-types';
2
+ import { type L1Publisher } from '@aztec/sequencer-client';
3
+
4
+ import { ProverNode } from '../prover-node.js';
5
+
6
+ class TestProverNode_ extends ProverNode {
7
+ public override prover!: EpochProverManager;
8
+ public override publisher!: L1Publisher;
9
+ }
10
+
11
+ export type TestProverNode = TestProverNode_;