@aztec/prover-node 0.0.1-commit.2eb6648a → 0.0.1-commit.2f68f620

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.
Files changed (44) hide show
  1. package/dest/actions/download-epoch-proving-job.js +1 -1
  2. package/dest/actions/rerun-epoch-proving-job.d.ts +4 -3
  3. package/dest/actions/rerun-epoch-proving-job.d.ts.map +1 -1
  4. package/dest/actions/rerun-epoch-proving-job.js +105 -27
  5. package/dest/actions/upload-epoch-proof-failure.d.ts +2 -2
  6. package/dest/actions/upload-epoch-proof-failure.d.ts.map +1 -1
  7. package/dest/bin/run-failed-epoch.js +6 -5
  8. package/dest/config.d.ts +7 -8
  9. package/dest/config.d.ts.map +1 -1
  10. package/dest/config.js +23 -19
  11. package/dest/factory.d.ts +19 -13
  12. package/dest/factory.d.ts.map +1 -1
  13. package/dest/factory.js +41 -60
  14. package/dest/job/epoch-proving-job.d.ts +6 -2
  15. package/dest/job/epoch-proving-job.d.ts.map +1 -1
  16. package/dest/job/epoch-proving-job.js +206 -35
  17. package/dest/metrics.d.ts +21 -1
  18. package/dest/metrics.d.ts.map +1 -1
  19. package/dest/metrics.js +47 -0
  20. package/dest/monitors/epoch-monitor.d.ts +1 -1
  21. package/dest/monitors/epoch-monitor.d.ts.map +1 -1
  22. package/dest/monitors/epoch-monitor.js +11 -9
  23. package/dest/prover-node-publisher.d.ts +25 -3
  24. package/dest/prover-node-publisher.d.ts.map +1 -1
  25. package/dest/prover-node-publisher.js +206 -9
  26. package/dest/prover-node.d.ts +24 -14
  27. package/dest/prover-node.d.ts.map +1 -1
  28. package/dest/prover-node.js +91 -41
  29. package/dest/prover-publisher-factory.d.ts +6 -4
  30. package/dest/prover-publisher-factory.d.ts.map +1 -1
  31. package/dest/prover-publisher-factory.js +4 -3
  32. package/package.json +23 -22
  33. package/src/actions/download-epoch-proving-job.ts +1 -1
  34. package/src/actions/rerun-epoch-proving-job.ts +17 -6
  35. package/src/actions/upload-epoch-proof-failure.ts +1 -1
  36. package/src/bin/run-failed-epoch.ts +5 -3
  37. package/src/config.ts +33 -31
  38. package/src/factory.ts +69 -103
  39. package/src/job/epoch-proving-job.ts +137 -41
  40. package/src/metrics.ts +71 -0
  41. package/src/monitors/epoch-monitor.ts +5 -6
  42. package/src/prover-node-publisher.ts +241 -14
  43. package/src/prover-node.ts +98 -55
  44. package/src/prover-publisher-factory.ts +8 -5
@@ -378,7 +378,7 @@ import { createLogger } from '@aztec/foundation/log';
378
378
  import { DateProvider } from '@aztec/foundation/timer';
379
379
  import { PublicProcessorFactory } from '@aztec/simulator/server';
380
380
  import { getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
381
- import { EpochProvingJobTerminalState, tryStop } from '@aztec/stdlib/interfaces/server';
381
+ import { tryStop } from '@aztec/stdlib/interfaces/server';
382
382
  import { Attributes, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
383
383
  import { uploadEpochProofFailure } from './actions/upload-epoch-proof-failure.js';
384
384
  import { EpochProvingJob } from './job/epoch-proving-job.js';
@@ -404,6 +404,8 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
404
404
  rollupContract;
405
405
  l1Metrics;
406
406
  telemetryClient;
407
+ delayer;
408
+ dateProvider;
407
409
  static{
408
410
  ({ e: [_initProto] } = _apply_decs_2203_r(this, [
409
411
  [
@@ -424,14 +426,14 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
424
426
  ], []));
425
427
  }
426
428
  log;
427
- dateProvider;
428
429
  jobs;
429
430
  config;
430
431
  jobMetrics;
431
432
  rewardsMetrics;
433
+ startingProofEpochs;
432
434
  tracer;
433
435
  publisher;
434
- constructor(prover, publisherFactory, l2BlockSource, l1ToL2MessageSource, contractDataSource, worldState, p2pClient, epochsMonitor, rollupContract, l1Metrics, config = {}, telemetryClient = getTelemetryClient()){
436
+ constructor(prover, publisherFactory, l2BlockSource, l1ToL2MessageSource, contractDataSource, worldState, p2pClient, epochsMonitor, rollupContract, l1Metrics, config = {}, telemetryClient = getTelemetryClient(), delayer, dateProvider = new DateProvider()){
435
437
  this.prover = prover;
436
438
  this.publisherFactory = publisherFactory;
437
439
  this.l2BlockSource = l2BlockSource;
@@ -443,13 +445,15 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
443
445
  this.rollupContract = rollupContract;
444
446
  this.l1Metrics = l1Metrics;
445
447
  this.telemetryClient = telemetryClient;
448
+ this.delayer = delayer;
449
+ this.dateProvider = dateProvider;
446
450
  this.log = (_initProto(this), createLogger('prover-node'));
447
- this.dateProvider = new DateProvider();
448
451
  this.jobs = new Map();
452
+ this.startingProofEpochs = new Set();
449
453
  this.config = {
450
454
  proverNodePollingIntervalMs: 1_000,
451
455
  proverNodeMaxPendingJobs: 100,
452
- proverNodeMaxParallelBlocksPerEpoch: 32,
456
+ proverNodeMaxParallelBlocksPerEpoch: 0,
453
457
  txGatheringIntervalMs: 1_000,
454
458
  txGatheringBatchSize: 10,
455
459
  txGatheringMaxParallelRequestsPerNode: 100,
@@ -470,6 +474,9 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
470
474
  getP2P() {
471
475
  return this.p2pClient;
472
476
  }
477
+ /** Returns the shared tx delayer for prover L1 txs, if enabled. Test-only. */ getDelayer() {
478
+ return this.delayer;
479
+ }
473
480
  /**
474
481
  * Handles an epoch being completed by starting a proof for it if there are no active jobs for it.
475
482
  * @param epochNumber - The epoch number that was just completed.
@@ -479,15 +486,7 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
479
486
  this.log.debug(`Running jobs as ${epochNumber} is ready to prove`, {
480
487
  jobs: Array.from(this.jobs.values()).map((job)=>`${job.getEpochNumber()}:${job.getId()}`)
481
488
  });
482
- const activeJobs = await this.getActiveJobsForEpoch(epochNumber);
483
- if (activeJobs.length > 0) {
484
- this.log.warn(`Not starting proof for ${epochNumber} since there are active jobs for the epoch`, {
485
- activeJobs: activeJobs.map((job)=>job.uuid)
486
- });
487
- return true;
488
- }
489
- await this.startProof(epochNumber);
490
- return true;
489
+ return await this.startProofIfNeeded(epochNumber);
491
490
  } catch (err) {
492
491
  if (err instanceof EmptyEpochError) {
493
492
  this.log.info(`Not starting proof for ${epochNumber} since no blocks were found`);
@@ -510,16 +509,14 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
510
509
  }
511
510
  /**
512
511
  * Stops the prover node and all its dependencies.
512
+ * Resources not owned by this node (shared with the parent aztec-node) are skipped.
513
513
  */ async stop() {
514
514
  this.log.info('Stopping ProverNode');
515
515
  await this.epochsMonitor.stop();
516
- await this.prover.stop();
517
- await tryStop(this.p2pClient);
518
- await tryStop(this.l2BlockSource);
519
- await tryStop(this.publisherFactory);
520
516
  this.publisher?.interrupt();
521
517
  await Promise.all(Array.from(this.jobs.values()).map((job)=>job.stop()));
522
- await this.worldState.stop();
518
+ await this.prover.stop();
519
+ await tryStop(this.publisherFactory);
523
520
  this.rewardsMetrics.stop();
524
521
  this.l1Metrics.stop();
525
522
  await this.telemetryClient.stop();
@@ -535,9 +532,35 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
535
532
  /**
536
533
  * Starts a proving process and returns immediately.
537
534
  */ async startProof(epochNumber) {
538
- const job = await this.createProvingJob(epochNumber, {
535
+ await this.startProofIfNeeded(epochNumber, {
539
536
  skipEpochCheck: true
540
537
  });
538
+ }
539
+ async startProofIfNeeded(epochNumber, opts = {}) {
540
+ if (this.startingProofEpochs.has(epochNumber)) {
541
+ this.log.warn(`Not starting proof for ${epochNumber} since a proof is already being started for the epoch`, {
542
+ epochNumber
543
+ });
544
+ return false;
545
+ }
546
+ this.startingProofEpochs.add(epochNumber);
547
+ try {
548
+ const activeJobs = await this.activeJobsCoverEpoch(epochNumber);
549
+ if (activeJobs.length > 0) {
550
+ this.log.warn(`Not starting proof for ${epochNumber} since an active job already covers the epoch`, {
551
+ epochNumber,
552
+ activeJobs
553
+ });
554
+ return true;
555
+ }
556
+ await this.startProofInternal(epochNumber, opts);
557
+ return true;
558
+ } finally{
559
+ this.startingProofEpochs.delete(epochNumber);
560
+ }
561
+ }
562
+ async startProofInternal(epochNumber, opts = {}) {
563
+ const job = await this.createProvingJob(epochNumber, opts);
541
564
  void this.runJob(job);
542
565
  }
543
566
  async runJob(job) {
@@ -579,15 +602,40 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
579
602
  /**
580
603
  * Returns an array of jobs being processed.
581
604
  */ getJobs() {
582
- return Promise.resolve(Array.from(this.jobs.entries()).map(([uuid, job])=>({
605
+ return Promise.resolve(this.getJobsInternal());
606
+ }
607
+ getJobsInternal() {
608
+ return Array.from(this.jobs.entries()).map(([uuid, job])=>({
583
609
  uuid,
584
610
  status: job.getState(),
585
611
  epochNumber: job.getEpochNumber()
586
- })));
612
+ }));
587
613
  }
588
- async getActiveJobsForEpoch(epochNumber) {
589
- const jobs = await this.getJobs();
590
- return jobs.filter((job)=>job.epochNumber === epochNumber && !EpochProvingJobTerminalState.includes(job.status));
614
+ async activeJobsCoverEpoch(epochNumber) {
615
+ const checkpoints = await this.l2BlockSource.getCheckpointsData({
616
+ epoch: epochNumber
617
+ });
618
+ if (checkpoints.length === 0) {
619
+ return [];
620
+ }
621
+ const firstCheckpoint = checkpoints.at(0).checkpointNumber;
622
+ const latestCheckpoint = checkpoints.at(-1).checkpointNumber;
623
+ const jobs = [];
624
+ for (const job of this.jobs.values()){
625
+ if (job.getEpochNumber() !== epochNumber) {
626
+ continue;
627
+ }
628
+ const jobCheckpoints = job.getProvingData().checkpoints;
629
+ const checkpointOverlap = jobCheckpoints.at(0).number <= firstCheckpoint && jobCheckpoints.at(-1).number >= latestCheckpoint;
630
+ if (checkpointOverlap && ![
631
+ 'failed',
632
+ 'stopped',
633
+ 'timed-out'
634
+ ].includes(job.getState())) {
635
+ jobs.push(job.getId());
636
+ }
637
+ }
638
+ return jobs;
591
639
  }
592
640
  checkMaximumPendingJobs() {
593
641
  const { proverNodeMaxPendingJobs: maxPendingJobs } = this.config;
@@ -603,10 +651,12 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
603
651
  const fromCheckpoint = epochData.checkpoints[0].number;
604
652
  const toCheckpoint = epochData.checkpoints.at(-1).number;
605
653
  const fromBlock = epochData.checkpoints[0].blocks[0].number;
606
- const toBlock = epochData.checkpoints.at(-1).blocks.at(-1).number;
654
+ const lastBlock = epochData.checkpoints.at(-1).blocks.at(-1);
655
+ const toBlock = lastBlock.number;
607
656
  this.log.verbose(`Creating proving job for epoch ${epochNumber} for checkpoint range ${fromCheckpoint} to ${toCheckpoint} and block range ${fromBlock} to ${toBlock}`);
608
657
  // Fast forward world state to right before the target block and get a fork
609
- await this.worldState.syncImmediate(toBlock);
658
+ const lastBlockHash = await lastBlock.header.hash();
659
+ await this.worldState.syncImmediate(toBlock, lastBlockHash);
610
660
  // Create a processor factory
611
661
  const publicProcessorFactory = new PublicProcessorFactory(this.contractDataSource, this.dateProvider, this.telemetryClient, this.log.getBindings());
612
662
  // Set deadline for this job to run. It will abort if it takes too long.
@@ -620,7 +670,14 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
620
670
  return this.l2BlockSource.getL1Constants();
621
671
  }
622
672
  async gatherEpochData(epochNumber) {
623
- const checkpoints = await this.gatherCheckpoints(epochNumber);
673
+ const publishedCheckpoints = await this.l2BlockSource.getCheckpoints({
674
+ epoch: epochNumber
675
+ });
676
+ if (publishedCheckpoints.length === 0) {
677
+ throw new EmptyEpochError(epochNumber);
678
+ }
679
+ const checkpoints = publishedCheckpoints.map((p)=>p.checkpoint);
680
+ const attestations = publishedCheckpoints.at(-1)?.attestations ?? [];
624
681
  const txArray = await this.gatherTxs(epochNumber, checkpoints);
625
682
  const txs = new Map(txArray.map((tx)=>[
626
683
  tx.getTxHash().toString(),
@@ -629,8 +686,6 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
629
686
  const l1ToL2Messages = await this.gatherMessages(epochNumber, checkpoints);
630
687
  const [firstBlock] = checkpoints[0].blocks;
631
688
  const previousBlockHeader = await this.gatherPreviousBlockHeader(epochNumber, firstBlock.number - 1);
632
- const [lastPublishedCheckpoint] = await this.l2BlockSource.getCheckpoints(checkpoints.at(-1).number, 1);
633
- const attestations = lastPublishedCheckpoint?.attestations ?? [];
634
689
  return {
635
690
  checkpoints,
636
691
  txs,
@@ -640,13 +695,6 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
640
695
  attestations
641
696
  };
642
697
  }
643
- async gatherCheckpoints(epochNumber) {
644
- const checkpoints = await this.l2BlockSource.getCheckpointsForEpoch(epochNumber);
645
- if (checkpoints.length === 0) {
646
- throw new EmptyEpochError(epochNumber);
647
- }
648
- return checkpoints;
649
- }
650
698
  async gatherTxs(epochNumber, checkpoints) {
651
699
  const deadline = new Date(this.dateProvider.now() + this.config.txGatheringTimeoutMs);
652
700
  const txProvider = this.p2pClient.getTxProvider();
@@ -677,12 +725,14 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
677
725
  return messagesByCheckpoint;
678
726
  }
679
727
  async gatherPreviousBlockHeader(epochNumber, previousBlockNumber) {
680
- const header = await (previousBlockNumber === 0 ? this.worldState.getCommitted().getInitialHeader() : this.l2BlockSource.getBlockHeader(BlockNumber(previousBlockNumber)));
681
- if (!header) {
728
+ const data = await this.l2BlockSource.getBlockData({
729
+ number: BlockNumber(previousBlockNumber)
730
+ });
731
+ if (!data?.header) {
682
732
  throw new Error(`Previous block header ${previousBlockNumber} not found for proving epoch ${epochNumber}`);
683
733
  }
684
- this.log.verbose(`Gathered previous block header ${header.getBlockNumber()} for epoch ${epochNumber}`);
685
- return header;
734
+ this.log.verbose(`Gathered previous block header ${data.header.getBlockNumber()} for epoch ${epochNumber}`);
735
+ return data.header;
686
736
  }
687
737
  /** Extracted for testing purposes. */ doCreateEpochProvingJob(data, deadline, publicProcessorFactory, publisher, opts = {}) {
688
738
  const { proverNodeMaxParallelBlocksPerEpoch: parallelBlockLimit, proverNodeDisableProofPublish } = this.config;
@@ -1,25 +1,27 @@
1
1
  import type { RollupContract } from '@aztec/ethereum/contracts';
2
2
  import type { L1TxUtils } from '@aztec/ethereum/l1-tx-utils';
3
3
  import type { PublisherManager } from '@aztec/ethereum/publisher-manager';
4
+ import type { EthAddress } from '@aztec/foundation/eth-address';
4
5
  import type { LoggerBindings } from '@aztec/foundation/log';
5
- import type { PublisherConfig, TxSenderConfig } from '@aztec/sequencer-client';
6
+ import type { ProverPublisherConfig, ProverTxSenderConfig } from '@aztec/sequencer-client';
6
7
  import type { TelemetryClient } from '@aztec/telemetry-client';
7
8
  import { ProverNodePublisher } from './prover-node-publisher.js';
8
9
  export declare class ProverPublisherFactory {
9
10
  private config;
10
11
  private deps;
11
12
  private bindings?;
12
- constructor(config: TxSenderConfig & PublisherConfig, deps: {
13
+ constructor(config: ProverTxSenderConfig & ProverPublisherConfig, deps: {
13
14
  rollupContract: RollupContract;
14
15
  publisherManager: PublisherManager<L1TxUtils>;
16
+ proofSubmissionTarget?: EthAddress;
15
17
  telemetry?: TelemetryClient;
16
18
  }, bindings?: LoggerBindings | undefined);
17
19
  start(): Promise<void>;
18
- stop(): void;
20
+ stop(): Promise<void>;
19
21
  /**
20
22
  * Creates a new Prover Publisher instance.
21
23
  * @returns A new ProverNodePublisher instance.
22
24
  */
23
25
  create(): Promise<ProverNodePublisher>;
24
26
  }
25
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmVyLXB1Ymxpc2hlci1mYWN0b3J5LmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJvdmVyLXB1Ymxpc2hlci1mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2hFLE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzdELE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDMUUsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUQsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQy9FLE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRS9ELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRWpFLHFCQUFhLHNCQUFzQjtJQUUvQixPQUFPLENBQUMsTUFBTTtJQUNkLE9BQU8sQ0FBQyxJQUFJO0lBS1osT0FBTyxDQUFDLFFBQVEsQ0FBQztJQVBuQixZQUNVLE1BQU0sRUFBRSxjQUFjLEdBQUcsZUFBZSxFQUN4QyxJQUFJLEVBQUU7UUFDWixjQUFjLEVBQUUsY0FBYyxDQUFDO1FBQy9CLGdCQUFnQixFQUFFLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzlDLFNBQVMsQ0FBQyxFQUFFLGVBQWUsQ0FBQztLQUM3QixFQUNPLFFBQVEsQ0FBQyw0QkFBZ0IsRUFDL0I7SUFFUyxLQUFLLGtCQUVqQjtJQUVNLElBQUksU0FFVjtJQUVEOzs7T0FHRztJQUNVLE1BQU0sSUFBSSxPQUFPLENBQUMsbUJBQW1CLENBQUMsQ0FXbEQ7Q0FDRiJ9
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmVyLXB1Ymxpc2hlci1mYWN0b3J5LmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJvdmVyLXB1Ymxpc2hlci1mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2hFLE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzdELE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDMUUsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUQsT0FBTyxLQUFLLEVBQUUscUJBQXFCLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMzRixPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUUvRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUVqRSxxQkFBYSxzQkFBc0I7SUFFL0IsT0FBTyxDQUFDLE1BQU07SUFDZCxPQUFPLENBQUMsSUFBSTtJQU1aLE9BQU8sQ0FBQyxRQUFRLENBQUM7SUFSbkIsWUFDVSxNQUFNLEVBQUUsb0JBQW9CLEdBQUcscUJBQXFCLEVBQ3BELElBQUksRUFBRTtRQUNaLGNBQWMsRUFBRSxjQUFjLENBQUM7UUFDL0IsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDOUMscUJBQXFCLENBQUMsRUFBRSxVQUFVLENBQUM7UUFDbkMsU0FBUyxDQUFDLEVBQUUsZUFBZSxDQUFDO0tBQzdCLEVBQ08sUUFBUSxDQUFDLDRCQUFnQixFQUMvQjtJQUVTLEtBQUssa0JBRWpCO0lBRVksSUFBSSxrQkFFaEI7SUFFRDs7O09BR0c7SUFDVSxNQUFNLElBQUksT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBWWxEO0NBQ0YifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"prover-publisher-factory.d.ts","sourceRoot":"","sources":["../src/prover-publisher-factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,qBAAa,sBAAsB;IAE/B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,QAAQ,CAAC;IAPnB,YACU,MAAM,EAAE,cAAc,GAAG,eAAe,EACxC,IAAI,EAAE;QACZ,cAAc,EAAE,cAAc,CAAC;QAC/B,gBAAgB,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC9C,SAAS,CAAC,EAAE,eAAe,CAAC;KAC7B,EACO,QAAQ,CAAC,4BAAgB,EAC/B;IAES,KAAK,kBAEjB;IAEM,IAAI,SAEV;IAED;;;OAGG;IACU,MAAM,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAWlD;CACF"}
1
+ {"version":3,"file":"prover-publisher-factory.d.ts","sourceRoot":"","sources":["../src/prover-publisher-factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC3F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,qBAAa,sBAAsB;IAE/B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,QAAQ,CAAC;IARnB,YACU,MAAM,EAAE,oBAAoB,GAAG,qBAAqB,EACpD,IAAI,EAAE;QACZ,cAAc,EAAE,cAAc,CAAC;QAC/B,gBAAgB,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC9C,qBAAqB,CAAC,EAAE,UAAU,CAAC;QACnC,SAAS,CAAC,EAAE,eAAe,CAAC;KAC7B,EACO,QAAQ,CAAC,4BAAgB,EAC/B;IAES,KAAK,kBAEjB;IAEY,IAAI,kBAEhB;IAED;;;OAGG;IACU,MAAM,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAYlD;CACF"}
@@ -9,10 +9,10 @@ export class ProverPublisherFactory {
9
9
  this.bindings = bindings;
10
10
  }
11
11
  async start() {
12
- await this.deps.publisherManager.loadState();
12
+ await this.deps.publisherManager.start();
13
13
  }
14
- stop() {
15
- this.deps.publisherManager.interrupt();
14
+ async stop() {
15
+ await this.deps.publisherManager.stop();
16
16
  }
17
17
  /**
18
18
  * Creates a new Prover Publisher instance.
@@ -22,6 +22,7 @@ export class ProverPublisherFactory {
22
22
  return new ProverNodePublisher(this.config, {
23
23
  rollupContract: this.deps.rollupContract,
24
24
  l1TxUtils: l1Publisher,
25
+ proofSubmissionTarget: this.deps.proofSubmissionTarget,
25
26
  telemetry: this.deps.telemetry
26
27
  }, this.bindings);
27
28
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/prover-node",
3
- "version": "0.0.1-commit.2eb6648a",
3
+ "version": "0.0.1-commit.2f68f620",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -56,27 +56,28 @@
56
56
  ]
57
57
  },
58
58
  "dependencies": {
59
- "@aztec/archiver": "0.0.1-commit.2eb6648a",
60
- "@aztec/bb-prover": "0.0.1-commit.2eb6648a",
61
- "@aztec/blob-client": "0.0.1-commit.2eb6648a",
62
- "@aztec/blob-lib": "0.0.1-commit.2eb6648a",
63
- "@aztec/constants": "0.0.1-commit.2eb6648a",
64
- "@aztec/epoch-cache": "0.0.1-commit.2eb6648a",
65
- "@aztec/ethereum": "0.0.1-commit.2eb6648a",
66
- "@aztec/foundation": "0.0.1-commit.2eb6648a",
67
- "@aztec/kv-store": "0.0.1-commit.2eb6648a",
68
- "@aztec/l1-artifacts": "0.0.1-commit.2eb6648a",
69
- "@aztec/node-keystore": "0.0.1-commit.2eb6648a",
70
- "@aztec/node-lib": "0.0.1-commit.2eb6648a",
71
- "@aztec/noir-protocol-circuits-types": "0.0.1-commit.2eb6648a",
72
- "@aztec/p2p": "0.0.1-commit.2eb6648a",
73
- "@aztec/protocol-contracts": "0.0.1-commit.2eb6648a",
74
- "@aztec/prover-client": "0.0.1-commit.2eb6648a",
75
- "@aztec/sequencer-client": "0.0.1-commit.2eb6648a",
76
- "@aztec/simulator": "0.0.1-commit.2eb6648a",
77
- "@aztec/stdlib": "0.0.1-commit.2eb6648a",
78
- "@aztec/telemetry-client": "0.0.1-commit.2eb6648a",
79
- "@aztec/world-state": "0.0.1-commit.2eb6648a",
59
+ "@aztec/archiver": "0.0.1-commit.2f68f620",
60
+ "@aztec/bb-prover": "0.0.1-commit.2f68f620",
61
+ "@aztec/blob-client": "0.0.1-commit.2f68f620",
62
+ "@aztec/blob-lib": "0.0.1-commit.2f68f620",
63
+ "@aztec/constants": "0.0.1-commit.2f68f620",
64
+ "@aztec/epoch-cache": "0.0.1-commit.2f68f620",
65
+ "@aztec/ethereum": "0.0.1-commit.2f68f620",
66
+ "@aztec/foundation": "0.0.1-commit.2f68f620",
67
+ "@aztec/kv-store": "0.0.1-commit.2f68f620",
68
+ "@aztec/l1-artifacts": "0.0.1-commit.2f68f620",
69
+ "@aztec/native": "0.0.1-commit.2f68f620",
70
+ "@aztec/node-keystore": "0.0.1-commit.2f68f620",
71
+ "@aztec/node-lib": "0.0.1-commit.2f68f620",
72
+ "@aztec/noir-protocol-circuits-types": "0.0.1-commit.2f68f620",
73
+ "@aztec/p2p": "0.0.1-commit.2f68f620",
74
+ "@aztec/protocol-contracts": "0.0.1-commit.2f68f620",
75
+ "@aztec/prover-client": "0.0.1-commit.2f68f620",
76
+ "@aztec/sequencer-client": "0.0.1-commit.2f68f620",
77
+ "@aztec/simulator": "0.0.1-commit.2f68f620",
78
+ "@aztec/stdlib": "0.0.1-commit.2f68f620",
79
+ "@aztec/telemetry-client": "0.0.1-commit.2f68f620",
80
+ "@aztec/world-state": "0.0.1-commit.2f68f620",
80
81
  "source-map-support": "^0.5.21",
81
82
  "tslib": "^2.4.0",
82
83
  "viem": "npm:@aztec/viem@2.38.2"
@@ -30,7 +30,7 @@ export async function downloadEpochProvingJob(
30
30
 
31
31
  const dataUrls = makeSnapshotPaths(location);
32
32
  log.info(`Downloading state snapshot from ${location} to local data directory`, { metadata, dataUrls });
33
- await snapshotSync({ dataUrls }, log, { ...config, ...metadata, snapshotsUrl: location });
33
+ await snapshotSync({ dataUrls }, log, { ...config, ...metadata, fileStore });
34
34
 
35
35
  const dataPath = urlJoin(location, 'data.bin');
36
36
  const localPath = config.jobDataDownloadPath;
@@ -1,10 +1,11 @@
1
- import { createArchiverStore } from '@aztec/archiver';
1
+ import { createArchiverStore, createContractDataSource } from '@aztec/archiver';
2
2
  import type { L1ContractsConfig } from '@aztec/ethereum/config';
3
3
  import type { Logger } from '@aztec/foundation/log';
4
- import type { DataStoreConfig } from '@aztec/kv-store/config';
5
4
  import { type ProverClientConfig, createProverClient } from '@aztec/prover-client';
6
5
  import { ProverBrokerConfig, createAndStartProvingBroker } from '@aztec/prover-client/broker';
7
6
  import { PublicProcessorFactory } from '@aztec/simulator/server';
7
+ import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
8
+ import type { GenesisData } from '@aztec/stdlib/world-state';
8
9
  import { getTelemetryClient } from '@aztec/telemetry-client';
9
10
  import { createWorldState } from '@aztec/world-state';
10
11
 
@@ -23,17 +24,27 @@ export async function rerunEpochProvingJob(
23
24
  localPath: string,
24
25
  log: Logger,
25
26
  config: DataStoreConfig & ProverBrokerConfig & ProverClientConfig & Pick<L1ContractsConfig, 'aztecEpochDuration'>,
27
+ genesis?: GenesisData,
26
28
  ) {
27
29
  const jobData = deserializeEpochProvingJobData(readFileSync(localPath));
28
30
  log.info(`Loaded proving job data for epoch ${jobData.epochNumber}`);
29
31
 
30
32
  const telemetry = getTelemetryClient();
31
33
  const metrics = new ProverNodeJobMetrics(telemetry.getMeter('prover-job'), telemetry.getTracer('prover-job'));
32
- const worldState = await createWorldState(config);
33
- const archiver = await createArchiverStore(config, { epochDuration: config.aztecEpochDuration });
34
- const publicProcessorFactory = new PublicProcessorFactory(archiver, undefined, undefined, log.getBindings());
34
+ await using worldState = await createWorldState(config, genesis);
35
+ const initialBlockHash = await worldState.getInitialHeader().hash();
36
+ const archiver = await createArchiverStore(config, initialBlockHash);
37
+ const publicProcessorFactory = new PublicProcessorFactory(
38
+ createContractDataSource(archiver),
39
+ undefined,
40
+ undefined,
41
+ log.getBindings(),
42
+ );
35
43
 
36
- const publisher = { submitEpochProof: () => Promise.resolve(true) };
44
+ const publisher = {
45
+ submitEpochProof: () => Promise.resolve(true),
46
+ analyzeEpochProofSubmission: () => Promise.resolve(),
47
+ };
37
48
  const l2BlockSourceForReorgDetection = undefined;
38
49
  const deadline = undefined;
39
50
 
@@ -3,11 +3,11 @@ import { tryRmDir } from '@aztec/foundation/fs';
3
3
  import { jsonStringify } from '@aztec/foundation/json-rpc';
4
4
  import type { Logger } from '@aztec/foundation/log';
5
5
  import { isoDate } from '@aztec/foundation/string';
6
- import type { DataStoreConfig } from '@aztec/kv-store/config';
7
6
  import { buildSnapshotMetadata, createBackups } from '@aztec/node-lib/actions';
8
7
  import type { ChainConfig } from '@aztec/stdlib/config';
9
8
  import { type FileStore, createFileStore } from '@aztec/stdlib/file-store';
10
9
  import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
10
+ import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
11
11
  import { type UploadSnapshotMetadata, getBasePath, uploadSnapshotData } from '@aztec/stdlib/snapshots';
12
12
  import { WORLD_STATE_DB_VERSION } from '@aztec/world-state';
13
13
 
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable no-console */
2
- import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
2
+ import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config';
3
3
  import { EthAddress } from '@aztec/foundation/eth-address';
4
4
  import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
5
5
  import { createLogger } from '@aztec/foundation/log';
@@ -22,8 +22,10 @@ async function rerunFailedEpoch(provingJobUrl: string, baseLocalDir: string) {
22
22
  const dataDir = join(localDir, 'state');
23
23
 
24
24
  const env = getProverNodeConfigFromEnv();
25
+ const l1Config = getL1ContractsConfigEnvVars();
25
26
  const config = {
26
- ...getProverNodeConfigFromEnv(),
27
+ ...env,
28
+ ...l1Config,
27
29
  dataDirectory: dataDir,
28
30
  dataStoreMapSizeKb: env.dataStoreMapSizeKb ?? 1024 * 1024,
29
31
  proverId: env.proverId ?? EthAddress.random(),
@@ -47,7 +49,7 @@ async function rerunFailedEpoch(provingJobUrl: string, baseLocalDir: string) {
47
49
  logger.info(`Rerunning proving job from ${jobPath} with state from ${dataDir}`, metadata);
48
50
  const result = await rerunEpochProvingJob(jobPath, logger, {
49
51
  ...config,
50
- l1Contracts: { rollupAddress: metadata.rollupAddress } as L1ContractAddresses,
52
+ rollupAddress: metadata.rollupAddress,
51
53
  rollupVersion: metadata.rollupVersion,
52
54
  });
53
55
 
package/src/config.ts CHANGED
@@ -1,18 +1,16 @@
1
- import { type ArchiverConfig, archiverConfigMappings } from '@aztec/archiver/config';
2
1
  import type { ACVMConfig, BBConfig } from '@aztec/bb-prover/config';
3
- import { type GenesisStateConfig, genesisStateConfigMappings } from '@aztec/ethereum/config';
4
2
  import {
5
3
  type ConfigMappingsType,
6
4
  booleanConfigHelper,
7
5
  getConfigFromMappings,
8
6
  numberConfigHelper,
7
+ pickConfigMappings,
9
8
  } from '@aztec/foundation/config';
10
- import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
9
+ import { EthAddress } from '@aztec/foundation/eth-address';
11
10
  import { type KeyStoreConfig, keyStoreConfigMappings } from '@aztec/node-keystore/config';
12
11
  import { ethPrivateKeySchema } from '@aztec/node-keystore/schemas';
13
12
  import type { KeyStore } from '@aztec/node-keystore/types';
14
13
  import { type SharedNodeConfig, sharedNodeConfigMappings } from '@aztec/node-lib/config';
15
- import { type P2PConfig, p2pConfigMappings } from '@aztec/p2p/config';
16
14
  import {
17
15
  type ProverAgentConfig,
18
16
  type ProverBrokerConfig,
@@ -21,24 +19,20 @@ import {
21
19
  } from '@aztec/prover-client/broker/config';
22
20
  import { type ProverClientUserConfig, bbConfigMappings, proverClientConfigMappings } from '@aztec/prover-client/config';
23
21
  import {
24
- type PublisherConfig,
25
- type TxSenderConfig,
26
- getPublisherConfigMappings,
27
- getTxSenderConfigMappings,
22
+ type ProverPublisherConfig,
23
+ type ProverTxSenderConfig,
24
+ proverPublisherConfigMappings,
25
+ proverTxSenderConfigMappings,
28
26
  } from '@aztec/sequencer-client/config';
29
- import { type WorldStateConfig, worldStateConfigMappings } from '@aztec/world-state/config';
30
-
31
- export type ProverNodeConfig = ArchiverConfig &
32
- ProverClientUserConfig &
33
- P2PConfig &
34
- WorldStateConfig &
35
- PublisherConfig &
36
- TxSenderConfig &
27
+ import { type DataStoreConfig, dataConfigMappings } from '@aztec/stdlib/kv-store';
28
+
29
+ export type ProverNodeConfig = ProverClientUserConfig &
30
+ ProverPublisherConfig &
31
+ ProverTxSenderConfig &
37
32
  DataStoreConfig &
38
33
  KeyStoreConfig &
39
- SharedNodeConfig &
40
34
  SpecificProverNodeConfig &
41
- GenesisStateConfig;
35
+ Pick<SharedNodeConfig, 'web3SignerUrl'>;
42
36
 
43
37
  export type SpecificProverNodeConfig = {
44
38
  proverNodeMaxPendingJobs: number;
@@ -51,9 +45,10 @@ export type SpecificProverNodeConfig = {
51
45
  txGatheringIntervalMs: number;
52
46
  txGatheringBatchSize: number;
53
47
  txGatheringMaxParallelRequestsPerNode: number;
48
+ proofSubmissionTargetAddress?: EthAddress;
54
49
  };
55
50
 
56
- const specificProverNodeConfigMappings: ConfigMappingsType<SpecificProverNodeConfig> = {
51
+ export const specificProverNodeConfigMappings: ConfigMappingsType<SpecificProverNodeConfig> = {
57
52
  proverNodeMaxPendingJobs: {
58
53
  env: 'PROVER_NODE_MAX_PENDING_JOBS',
59
54
  description: 'The maximum number of pending jobs for the prover node',
@@ -67,7 +62,7 @@ const specificProverNodeConfigMappings: ConfigMappingsType<SpecificProverNodeCon
67
62
  proverNodeMaxParallelBlocksPerEpoch: {
68
63
  env: 'PROVER_NODE_MAX_PARALLEL_BLOCKS_PER_EPOCH',
69
64
  description: 'The Maximum number of blocks to process in parallel while proving an epoch',
70
- ...numberConfigHelper(32),
65
+ ...numberConfigHelper(0),
71
66
  },
72
67
  proverNodeFailedEpochStore: {
73
68
  env: 'PROVER_NODE_FAILED_EPOCH_STORE',
@@ -103,20 +98,24 @@ const specificProverNodeConfigMappings: ConfigMappingsType<SpecificProverNodeCon
103
98
  description: 'Whether the prover node skips publishing proofs to L1',
104
99
  ...booleanConfigHelper(false),
105
100
  },
101
+ proofSubmissionTargetAddress: {
102
+ env: 'PROVER_NODE_PROOF_SUBMISSION_TARGET_ADDRESS',
103
+ description:
104
+ 'Optional L1 address the submitEpochRootProof tx is sent to. Must expose the identical submitEpochRootProof ABI ' +
105
+ 'and forward to the rollup. Defaults to the rollup address.',
106
+ parseEnv: (val: string) => EthAddress.fromString(val),
107
+ defaultValue: undefined,
108
+ },
106
109
  };
107
110
 
108
111
  export const proverNodeConfigMappings: ConfigMappingsType<ProverNodeConfig> = {
109
112
  ...dataConfigMappings,
110
113
  ...keyStoreConfigMappings,
111
- ...archiverConfigMappings,
112
114
  ...proverClientConfigMappings,
113
- ...p2pConfigMappings,
114
- ...worldStateConfigMappings,
115
- ...getPublisherConfigMappings('PROVER'),
116
- ...getTxSenderConfigMappings('PROVER'),
115
+ ...proverPublisherConfigMappings,
116
+ ...proverTxSenderConfigMappings,
117
117
  ...specificProverNodeConfigMappings,
118
- ...genesisStateConfigMappings,
119
- ...sharedNodeConfigMappings,
118
+ ...pickConfigMappings(sharedNodeConfigMappings, ['web3SignerUrl']),
120
119
  };
121
120
 
122
121
  export function getProverNodeConfigFromEnv(): ProverNodeConfig {
@@ -143,7 +142,7 @@ function createKeyStoreFromWeb3Signer(config: ProverNodeConfig): KeyStore | unde
143
142
  }
144
143
 
145
144
  // Also, we need at least one publisher address.
146
- const publishers = config.publisherAddresses ?? [];
145
+ const publishers = config.proverPublisherAddresses ?? [];
147
146
 
148
147
  if (publishers.length === 0) {
149
148
  return undefined;
@@ -164,8 +163,8 @@ function createKeyStoreFromWeb3Signer(config: ProverNodeConfig): KeyStore | unde
164
163
 
165
164
  function createKeyStoreFromPublisherKeys(config: ProverNodeConfig): KeyStore | undefined {
166
165
  // Extract the publisher keys from the provided config.
167
- const publisherKeys = config.publisherPrivateKeys
168
- ? config.publisherPrivateKeys.map((k: { getValue: () => string }) => ethPrivateKeySchema.parse(k.getValue()))
166
+ const publisherKeys = config.proverPublisherPrivateKeys
167
+ ? config.proverPublisherPrivateKeys.map((k: { getValue: () => string }) => ethPrivateKeySchema.parse(k.getValue()))
169
168
  : [];
170
169
 
171
170
  // There must be at least 1.
@@ -194,7 +193,10 @@ function createKeyStoreFromPublisherKeys(config: ProverNodeConfig): KeyStore | u
194
193
 
195
194
  export function createKeyStoreForProver(config: ProverNodeConfig): KeyStore | undefined {
196
195
  if (config.web3SignerUrl !== undefined && config.web3SignerUrl.length > 0) {
197
- return createKeyStoreFromWeb3Signer(config);
196
+ const keyStore = createKeyStoreFromWeb3Signer(config);
197
+ if (keyStore) {
198
+ return keyStore;
199
+ }
198
200
  }
199
201
 
200
202
  return createKeyStoreFromPublisherKeys(config);