@aztec/prover-node 0.67.0 → 0.67.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.
Files changed (39) hide show
  1. package/dest/config.d.ts +7 -7
  2. package/dest/config.d.ts.map +1 -1
  3. package/dest/config.js +7 -7
  4. package/dest/factory.d.ts.map +1 -1
  5. package/dest/factory.js +4 -8
  6. package/dest/job/epoch-proving-job.d.ts +3 -1
  7. package/dest/job/epoch-proving-job.d.ts.map +1 -1
  8. package/dest/job/epoch-proving-job.js +145 -121
  9. package/dest/metrics.d.ts +1 -0
  10. package/dest/metrics.d.ts.map +1 -1
  11. package/dest/metrics.js +2 -1
  12. package/dest/monitors/claims-monitor.d.ts +4 -2
  13. package/dest/monitors/claims-monitor.d.ts.map +1 -1
  14. package/dest/monitors/claims-monitor.js +51 -34
  15. package/dest/monitors/epoch-monitor.d.ts +4 -2
  16. package/dest/monitors/epoch-monitor.d.ts.map +1 -1
  17. package/dest/monitors/epoch-monitor.js +47 -31
  18. package/dest/prover-coordination/factory.d.ts.map +1 -1
  19. package/dest/prover-coordination/factory.js +3 -3
  20. package/dest/prover-node.d.ts +7 -8
  21. package/dest/prover-node.d.ts.map +1 -1
  22. package/dest/prover-node.js +223 -212
  23. package/package.json +18 -17
  24. package/src/config.ts +7 -7
  25. package/src/factory.ts +2 -8
  26. package/src/job/epoch-proving-job.ts +30 -21
  27. package/src/metrics.ts +1 -1
  28. package/src/monitors/claims-monitor.ts +13 -3
  29. package/src/monitors/epoch-monitor.ts +11 -3
  30. package/src/prover-coordination/factory.ts +7 -1
  31. package/src/prover-node.ts +19 -21
  32. package/dest/prover-cache/cache_manager.d.ts +0 -15
  33. package/dest/prover-cache/cache_manager.d.ts.map +0 -1
  34. package/dest/prover-cache/cache_manager.js +0 -57
  35. package/dest/prover-cache/kv_cache.d.ts +0 -11
  36. package/dest/prover-cache/kv_cache.d.ts.map +0 -1
  37. package/dest/prover-cache/kv_cache.js +0 -20
  38. package/src/prover-cache/cache_manager.ts +0 -69
  39. package/src/prover-cache/kv_cache.ts +0 -27
package/src/factory.ts CHANGED
@@ -12,14 +12,12 @@ import { type TelemetryClient } from '@aztec/telemetry-client';
12
12
  import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
13
13
  import { createWorldStateSynchronizer } from '@aztec/world-state';
14
14
 
15
- import { join } from 'path';
16
15
  import { createPublicClient, getAddress, getContract, http } from 'viem';
17
16
 
18
17
  import { createBondManager } from './bond/factory.js';
19
18
  import { type ProverNodeConfig, type QuoteProviderConfig } from './config.js';
20
19
  import { ClaimsMonitor } from './monitors/claims-monitor.js';
21
20
  import { EpochMonitor } from './monitors/epoch-monitor.js';
22
- import { ProverCacheManager } from './prover-cache/cache_manager.js';
23
21
  import { createProverCoordination } from './prover-coordination/factory.js';
24
22
  import { ProverNode, type ProverNodeOptions } from './prover-node.js';
25
23
  import { HttpQuoteProvider } from './quote-provider/http.js';
@@ -71,16 +69,13 @@ export async function createProverNode(
71
69
  maxParallelBlocksPerEpoch: config.proverNodeMaxParallelBlocksPerEpoch,
72
70
  };
73
71
 
74
- const claimsMonitor = new ClaimsMonitor(publisher, proverNodeConfig);
75
- const epochMonitor = new EpochMonitor(archiver, proverNodeConfig);
72
+ const claimsMonitor = new ClaimsMonitor(publisher, telemetry, proverNodeConfig);
73
+ const epochMonitor = new EpochMonitor(archiver, telemetry, proverNodeConfig);
76
74
 
77
75
  const rollupContract = publisher.getRollupContract();
78
76
  const walletClient = publisher.getClient();
79
77
  const bondManager = await createBondManager(rollupContract, walletClient, config);
80
78
 
81
- const cacheDir = config.cacheDir ? join(config.cacheDir, `prover_${config.proverId}`) : undefined;
82
- const cacheManager = new ProverCacheManager(cacheDir);
83
-
84
79
  return new ProverNode(
85
80
  prover,
86
81
  publisher,
@@ -95,7 +90,6 @@ export async function createProverNode(
95
90
  epochMonitor,
96
91
  bondManager,
97
92
  telemetry,
98
- cacheManager,
99
93
  proverNodeConfig,
100
94
  );
101
95
  }
@@ -17,6 +17,7 @@ import { promiseWithResolvers } from '@aztec/foundation/promise';
17
17
  import { Timer } from '@aztec/foundation/timer';
18
18
  import { type L1Publisher } from '@aztec/sequencer-client';
19
19
  import { type PublicProcessor, type PublicProcessorFactory } from '@aztec/simulator';
20
+ import { Attributes, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client';
20
21
 
21
22
  import * as crypto from 'node:crypto';
22
23
 
@@ -27,13 +28,15 @@ import { type ProverNodeMetrics } from '../metrics.js';
27
28
  * re-executes their public calls, generates a rollup proof, and submits it to L1. This job will update the
28
29
  * world state as part of public call execution via the public processor.
29
30
  */
30
- export class EpochProvingJob {
31
+ export class EpochProvingJob implements Traceable {
31
32
  private state: EpochProvingJobState = 'initialized';
32
33
  private log = createLogger('prover-node:epoch-proving-job');
33
34
  private uuid: string;
34
35
 
35
36
  private runPromise: Promise<void> | undefined;
36
37
 
38
+ public readonly tracer: Tracer;
39
+
37
40
  constructor(
38
41
  private dbProvider: ForkMerkleTreeOperations,
39
42
  private epochNumber: bigint,
@@ -49,6 +52,7 @@ export class EpochProvingJob {
49
52
  private cleanUp: (job: EpochProvingJob) => Promise<void> = () => Promise.resolve(),
50
53
  ) {
51
54
  this.uuid = crypto.randomUUID();
55
+ this.tracer = metrics.client.getTracer('EpochProvingJob');
52
56
  }
53
57
 
54
58
  public getId(): string {
@@ -62,11 +66,20 @@ export class EpochProvingJob {
62
66
  /**
63
67
  * Proves the given epoch and submits the proof to L1.
64
68
  */
69
+ @trackSpan('EpochProvingJob.run', function () {
70
+ return { [Attributes.EPOCH_NUMBER]: Number(this.epochNumber) };
71
+ })
65
72
  public async run() {
66
73
  const epochNumber = Number(this.epochNumber);
67
74
  const epochSize = this.blocks.length;
68
- const firstBlockNumber = this.blocks[0].number;
69
- this.log.info(`Starting epoch proving job`, { firstBlockNumber, epochSize, epochNumber, uuid: this.uuid });
75
+ const [fromBlock, toBlock] = [this.blocks[0].number, this.blocks.at(-1)!.number];
76
+ this.log.info(`Starting epoch ${epochNumber} proving job with blocks ${fromBlock} to ${toBlock}`, {
77
+ fromBlock,
78
+ toBlock,
79
+ epochSize,
80
+ epochNumber,
81
+ uuid: this.uuid,
82
+ });
70
83
  this.state = 'processing';
71
84
  const timer = new Timer();
72
85
 
@@ -74,17 +87,17 @@ export class EpochProvingJob {
74
87
  this.runPromise = promise;
75
88
 
76
89
  try {
77
- this.prover.startNewEpoch(epochNumber, firstBlockNumber, epochSize);
90
+ this.prover.startNewEpoch(epochNumber, fromBlock, epochSize);
78
91
 
79
92
  await asyncPool(this.config.parallelBlockLimit, this.blocks, async block => {
80
93
  const globalVariables = block.header.globalVariables;
81
94
  const txHashes = block.body.txEffects.map(tx => tx.txHash);
82
95
  const txCount = block.body.numberOfTxsIncludingPadded;
83
96
  const l1ToL2Messages = await this.getL1ToL2Messages(block);
84
- const txs = await this.getTxs(txHashes);
97
+ const txs = await this.getTxs(txHashes, block.number);
85
98
  const previousHeader = await this.getBlockHeader(block.number - 1);
86
99
 
87
- this.log.verbose(`Starting block processing`, {
100
+ this.log.verbose(`Starting processing block ${block.number}`, {
88
101
  number: block.number,
89
102
  blockHash: block.hash().toString(),
90
103
  lastArchive: block.header.lastArchive.root,
@@ -95,16 +108,16 @@ export class EpochProvingJob {
95
108
  uuid: this.uuid,
96
109
  ...globalVariables,
97
110
  });
98
-
99
111
  // Start block proving
100
- await this.prover.startNewBlock(txCount, globalVariables, l1ToL2Messages);
112
+ await this.prover.startNewBlock(globalVariables, l1ToL2Messages);
101
113
 
102
114
  // Process public fns
103
115
  const db = await this.dbProvider.fork(block.number - 1);
104
116
  const publicProcessor = this.publicProcessorFactory.create(db, previousHeader, globalVariables);
105
- await this.processTxs(publicProcessor, txs, txCount);
117
+ const processed = await this.processTxs(publicProcessor, txs, txCount);
118
+ await this.prover.addTxs(processed);
106
119
  await db.close();
107
- this.log.verbose(`Processed all txs for block`, {
120
+ this.log.verbose(`Processed all ${txs.length} txs for block ${block.number}`, {
108
121
  blockNumber: block.number,
109
122
  blockHash: block.hash().toString(),
110
123
  uuid: this.uuid,
@@ -116,17 +129,16 @@ export class EpochProvingJob {
116
129
 
117
130
  this.state = 'awaiting-prover';
118
131
  const { publicInputs, proof } = await this.prover.finaliseEpoch();
119
- this.log.info(`Finalised proof for epoch`, { epochNumber, uuid: this.uuid, duration: timer.ms() });
132
+ this.log.info(`Finalised proof for epoch ${epochNumber}`, { epochNumber, uuid: this.uuid, duration: timer.ms() });
120
133
 
121
134
  this.state = 'publishing-proof';
122
- const [fromBlock, toBlock] = [this.blocks[0].number, this.blocks.at(-1)!.number];
123
135
  await this.publisher.submitEpochProof({ fromBlock, toBlock, epochNumber, publicInputs, proof });
124
136
  this.log.info(`Submitted proof for epoch`, { epochNumber, uuid: this.uuid });
125
137
 
126
138
  this.state = 'completed';
127
139
  this.metrics.recordProvingJob(timer);
128
140
  } catch (err) {
129
- this.log.error(`Error running epoch prover job`, err, { uuid: this.uuid });
141
+ this.log.error(`Error running epoch ${epochNumber} prover job`, err, { uuid: this.uuid, epochNumber });
130
142
  this.state = 'failed';
131
143
  } finally {
132
144
  await this.cleanUp(this);
@@ -149,13 +161,15 @@ export class EpochProvingJob {
149
161
  return this.l2BlockSource.getBlockHeader(blockNumber);
150
162
  }
151
163
 
152
- private async getTxs(txHashes: TxHash[]): Promise<Tx[]> {
164
+ private async getTxs(txHashes: TxHash[], blockNumber: number): Promise<Tx[]> {
153
165
  const txs = await Promise.all(
154
166
  txHashes.map(txHash => this.coordination.getTxByHash(txHash).then(tx => [txHash, tx] as const)),
155
167
  );
156
168
  const notFound = txs.filter(([_, tx]) => !tx);
157
169
  if (notFound.length) {
158
- throw new Error(`Txs not found: ${notFound.map(([txHash]) => txHash.toString()).join(', ')}`);
170
+ throw new Error(
171
+ `Txs not found for block ${blockNumber}: ${notFound.map(([txHash]) => txHash.toString()).join(', ')}`,
172
+ );
159
173
  }
160
174
  return txs.map(([_, tx]) => tx!);
161
175
  }
@@ -169,12 +183,7 @@ export class EpochProvingJob {
169
183
  txs: Tx[],
170
184
  totalNumberOfTxs: number,
171
185
  ): Promise<ProcessedTx[]> {
172
- const [processedTxs, failedTxs] = await publicProcessor.process(
173
- txs,
174
- totalNumberOfTxs,
175
- this.prover,
176
- new EmptyTxValidator(),
177
- );
186
+ const [processedTxs, failedTxs] = await publicProcessor.process(txs, totalNumberOfTxs, new EmptyTxValidator());
178
187
 
179
188
  if (failedTxs.length) {
180
189
  throw new Error(
package/src/metrics.ts CHANGED
@@ -4,7 +4,7 @@ import { type Histogram, Metrics, type TelemetryClient, ValueType } from '@aztec
4
4
  export class ProverNodeMetrics {
5
5
  provingJobDuration: Histogram;
6
6
 
7
- constructor(client: TelemetryClient, name = 'ProverNode') {
7
+ constructor(public readonly client: TelemetryClient, name = 'ProverNode') {
8
8
  const meter = client.getMeter(name);
9
9
  this.provingJobDuration = meter.createHistogram(Metrics.PROVER_NODE_JOB_DURATION, {
10
10
  description: 'Duration of proving job',
@@ -3,20 +3,28 @@ import { type EthAddress } from '@aztec/circuits.js';
3
3
  import { createLogger } from '@aztec/foundation/log';
4
4
  import { RunningPromise } from '@aztec/foundation/running-promise';
5
5
  import { type L1Publisher } from '@aztec/sequencer-client';
6
+ import { type TelemetryClient, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client';
6
7
 
7
8
  export interface ClaimsMonitorHandler {
8
9
  handleClaim(proofClaim: EpochProofClaim): Promise<void>;
9
10
  }
10
11
 
11
- export class ClaimsMonitor {
12
+ export class ClaimsMonitor implements Traceable {
12
13
  private runningPromise: RunningPromise;
13
14
  private log = createLogger('prover-node:claims-monitor');
14
15
 
15
16
  private handler: ClaimsMonitorHandler | undefined;
16
17
  private lastClaimEpochNumber: bigint | undefined;
17
18
 
18
- constructor(private readonly l1Publisher: L1Publisher, private options: { pollingIntervalMs: number }) {
19
- this.runningPromise = new RunningPromise(this.work.bind(this), this.options.pollingIntervalMs);
19
+ public readonly tracer: Tracer;
20
+
21
+ constructor(
22
+ private readonly l1Publisher: L1Publisher,
23
+ telemetry: TelemetryClient,
24
+ private options: { pollingIntervalMs: number },
25
+ ) {
26
+ this.tracer = telemetry.getTracer('ClaimsMonitor');
27
+ this.runningPromise = new RunningPromise(this.work.bind(this), this.log, this.options.pollingIntervalMs);
20
28
  }
21
29
 
22
30
  public start(handler: ClaimsMonitorHandler) {
@@ -31,9 +39,11 @@ export class ClaimsMonitor {
31
39
  this.log.info('Stopped ClaimsMonitor');
32
40
  }
33
41
 
42
+ @trackSpan('ClaimsMonitor.work')
34
43
  public async work() {
35
44
  const proofClaim = await this.l1Publisher.getProofClaim();
36
45
  if (!proofClaim) {
46
+ this.log.trace(`Found no proof claim`);
37
47
  return;
38
48
  }
39
49
 
@@ -1,22 +1,29 @@
1
1
  import { type L2BlockSource } from '@aztec/circuit-types';
2
2
  import { createLogger } from '@aztec/foundation/log';
3
3
  import { RunningPromise } from '@aztec/foundation/running-promise';
4
+ import { type TelemetryClient, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client';
4
5
 
5
6
  export interface EpochMonitorHandler {
6
7
  handleInitialEpochSync(epochNumber: bigint): Promise<void>;
7
8
  handleEpochCompleted(epochNumber: bigint): Promise<void>;
8
9
  }
9
10
 
10
- export class EpochMonitor {
11
+ export class EpochMonitor implements Traceable {
11
12
  private runningPromise: RunningPromise;
12
13
  private log = createLogger('prover-node:epoch-monitor');
14
+ public readonly tracer: Tracer;
13
15
 
14
16
  private handler: EpochMonitorHandler | undefined;
15
17
 
16
18
  private latestEpochNumber: bigint | undefined;
17
19
 
18
- constructor(private readonly l2BlockSource: L2BlockSource, private options: { pollingIntervalMs: number }) {
19
- this.runningPromise = new RunningPromise(this.work.bind(this), this.options.pollingIntervalMs);
20
+ constructor(
21
+ private readonly l2BlockSource: L2BlockSource,
22
+ telemetry: TelemetryClient,
23
+ private options: { pollingIntervalMs: number },
24
+ ) {
25
+ this.tracer = telemetry.getTracer('EpochMonitor');
26
+ this.runningPromise = new RunningPromise(this.work.bind(this), this.log, this.options.pollingIntervalMs);
20
27
  }
21
28
 
22
29
  public start(handler: EpochMonitorHandler) {
@@ -30,6 +37,7 @@ export class EpochMonitor {
30
37
  this.log.info('Stopped EpochMonitor');
31
38
  }
32
39
 
40
+ @trackSpan('EpochMonitor.work')
33
41
  public async work() {
34
42
  if (!this.latestEpochNumber) {
35
43
  const epochNumber = await this.l2BlockSource.getL2EpochNumber();
@@ -1,6 +1,11 @@
1
1
  import { type ArchiveSource, type Archiver } from '@aztec/archiver';
2
2
  import { BBCircuitVerifier, TestCircuitVerifier } from '@aztec/bb-prover';
3
- import { type ProverCoordination, type WorldStateSynchronizer, createAztecNodeClient } from '@aztec/circuit-types';
3
+ import {
4
+ P2PClientType,
5
+ type ProverCoordination,
6
+ type WorldStateSynchronizer,
7
+ createAztecNodeClient,
8
+ } from '@aztec/circuit-types';
4
9
  import { createLogger } from '@aztec/foundation/log';
5
10
  import { type DataStoreConfig } from '@aztec/kv-store/config';
6
11
  import { createP2PClient } from '@aztec/p2p';
@@ -42,6 +47,7 @@ export async function createProverCoordination(
42
47
 
43
48
  const proofVerifier = config.realProofs ? await BBCircuitVerifier.new(config) : new TestCircuitVerifier();
44
49
  const p2pClient = await createP2PClient(
50
+ P2PClientType.Prover,
45
51
  config,
46
52
  deps.archiver,
47
53
  proofVerifier,
@@ -6,7 +6,7 @@ import {
6
6
  type L1ToL2MessageSource,
7
7
  type L2Block,
8
8
  type L2BlockSource,
9
- type ProverCache,
9
+ type P2PClientType,
10
10
  type ProverCoordination,
11
11
  type ProverNodeApi,
12
12
  type Service,
@@ -15,20 +15,18 @@ import {
15
15
  } from '@aztec/circuit-types';
16
16
  import { type ContractDataSource } from '@aztec/circuits.js';
17
17
  import { compact } from '@aztec/foundation/collection';
18
- import { sha256 } from '@aztec/foundation/crypto';
19
18
  import { createLogger } from '@aztec/foundation/log';
20
19
  import { type Maybe } from '@aztec/foundation/types';
21
20
  import { type P2P } from '@aztec/p2p';
22
21
  import { type L1Publisher } from '@aztec/sequencer-client';
23
22
  import { PublicProcessorFactory } from '@aztec/simulator';
24
- import { type TelemetryClient } from '@aztec/telemetry-client';
23
+ import { Attributes, type TelemetryClient, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client';
25
24
 
26
25
  import { type BondManager } from './bond/bond-manager.js';
27
26
  import { EpochProvingJob, type EpochProvingJobState } from './job/epoch-proving-job.js';
28
27
  import { ProverNodeMetrics } from './metrics.js';
29
28
  import { type ClaimsMonitor, type ClaimsMonitorHandler } from './monitors/claims-monitor.js';
30
29
  import { type EpochMonitor, type EpochMonitorHandler } from './monitors/epoch-monitor.js';
31
- import { type ProverCacheManager } from './prover-cache/cache_manager.js';
32
30
  import { type QuoteProvider } from './quote-provider/index.js';
33
31
  import { type QuoteSigner } from './quote-signer.js';
34
32
 
@@ -44,7 +42,7 @@ export type ProverNodeOptions = {
44
42
  * from a tx source in the p2p network or an external node, re-executes their public functions, creates a rollup
45
43
  * proof for the epoch, and submits it to L1.
46
44
  */
47
- export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, ProverNodeApi {
45
+ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, ProverNodeApi, Traceable {
48
46
  private log = createLogger('prover-node');
49
47
 
50
48
  private latestEpochWeAreProving: bigint | undefined;
@@ -52,6 +50,8 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr
52
50
  private options: ProverNodeOptions;
53
51
  private metrics: ProverNodeMetrics;
54
52
 
53
+ public readonly tracer: Tracer;
54
+
55
55
  constructor(
56
56
  private readonly prover: EpochProverManager,
57
57
  private readonly publisher: L1Publisher,
@@ -66,7 +66,6 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr
66
66
  private readonly epochsMonitor: EpochMonitor,
67
67
  private readonly bondManager: BondManager,
68
68
  private readonly telemetryClient: TelemetryClient,
69
- private readonly proverCacheManager: ProverCacheManager,
70
69
  options: Partial<ProverNodeOptions> = {},
71
70
  ) {
72
71
  this.options = {
@@ -77,10 +76,11 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr
77
76
  };
78
77
 
79
78
  this.metrics = new ProverNodeMetrics(telemetryClient, 'ProverNode');
79
+ this.tracer = telemetryClient.getTracer('ProverNode');
80
80
  }
81
81
 
82
82
  public getP2P() {
83
- const asP2PClient = this.coordination as P2P;
83
+ const asP2PClient = this.coordination as P2P<P2PClientType.Prover>;
84
84
  if (typeof asP2PClient.isP2PClient === 'function' && asP2PClient.isP2PClient()) {
85
85
  return asP2PClient;
86
86
  }
@@ -93,6 +93,12 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr
93
93
  return;
94
94
  }
95
95
 
96
+ const provenEpoch = await this.l2BlockSource.getProvenL2EpochNumber();
97
+ if (provenEpoch !== undefined && proofClaim.epochToProve <= provenEpoch) {
98
+ this.log.verbose(`Claim for epoch ${proofClaim.epochToProve} is already proven`);
99
+ return;
100
+ }
101
+
96
102
  try {
97
103
  await this.startProof(proofClaim.epochToProve);
98
104
  this.latestEpochWeAreProving = proofClaim.epochToProve;
@@ -117,12 +123,8 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr
117
123
  try {
118
124
  const claim = await this.publisher.getProofClaim();
119
125
  if (!claim || claim.epochToProve < epochNumber) {
126
+ this.log.verbose(`Handling epoch ${epochNumber} completed as initial sync`);
120
127
  await this.handleEpochCompleted(epochNumber);
121
- } else if (claim && claim.bondProvider.equals(this.publisher.getSenderAddress())) {
122
- const lastEpochProven = await this.l2BlockSource.getProvenL2EpochNumber();
123
- if (lastEpochProven === undefined || lastEpochProven < claim.epochToProve) {
124
- await this.handleClaim(claim);
125
- }
126
128
  }
127
129
  } catch (err) {
128
130
  this.log.error(`Error handling initial epoch sync`, err);
@@ -245,6 +247,7 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr
245
247
  return maxPendingJobs === 0 || this.jobs.size < maxPendingJobs;
246
248
  }
247
249
 
250
+ @trackSpan('ProverNode.createProvingJob', epochNumber => ({ [Attributes.EPOCH_NUMBER]: Number(epochNumber) }))
248
251
  private async createProvingJob(epochNumber: bigint) {
249
252
  if (!this.checkMaximumPendingJobs()) {
250
253
  throw new Error(`Maximum pending proving jobs ${this.options.maxPendingJobs} reached. Cannot create new job.`);
@@ -265,16 +268,12 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr
265
268
  // Create a processor using the forked world state
266
269
  const publicProcessorFactory = new PublicProcessorFactory(this.contractDataSource, this.telemetryClient);
267
270
 
268
- const epochHash = sha256(Buffer.concat(blocks.map(block => block.hash().toBuffer())));
269
- const proverCache = await this.proverCacheManager.openCache(epochNumber, epochHash);
270
-
271
- const cleanUp = async () => {
272
- await proverCache.close();
273
- await this.proverCacheManager.removeStaleCaches(epochNumber);
271
+ const cleanUp = () => {
274
272
  this.jobs.delete(job.getId());
273
+ return Promise.resolve();
275
274
  };
276
275
 
277
- const job = this.doCreateEpochProvingJob(epochNumber, blocks, proverCache, publicProcessorFactory, cleanUp);
276
+ const job = this.doCreateEpochProvingJob(epochNumber, blocks, publicProcessorFactory, cleanUp);
278
277
  this.jobs.set(job.getId(), job);
279
278
  return job;
280
279
  }
@@ -283,7 +282,6 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr
283
282
  protected doCreateEpochProvingJob(
284
283
  epochNumber: bigint,
285
284
  blocks: L2Block[],
286
- proverCache: ProverCache,
287
285
  publicProcessorFactory: PublicProcessorFactory,
288
286
  cleanUp: () => Promise<void>,
289
287
  ) {
@@ -291,7 +289,7 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr
291
289
  this.worldState,
292
290
  epochNumber,
293
291
  blocks,
294
- this.prover.createEpochProver(proverCache),
292
+ this.prover.createEpochProver(),
295
293
  publicProcessorFactory,
296
294
  this.publisher,
297
295
  this.l2BlockSource,
@@ -1,15 +0,0 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
- /// <reference types="node" resolution-mode="require"/>
3
- import { type ProverCache } from '@aztec/circuit-types';
4
- export declare class ProverCacheManager {
5
- private cacheDir?;
6
- private log;
7
- constructor(cacheDir?: string | undefined, log?: import("@aztec/foundation/log").Logger);
8
- openCache(epochNumber: bigint, epochHash: Buffer): Promise<ProverCache>;
9
- /**
10
- * Removes all caches for epochs older than the given epoch (including)
11
- * @param upToAndIncludingEpoch - The epoch number up to which to remove caches
12
- */
13
- removeStaleCaches(upToAndIncludingEpoch: bigint): Promise<void>;
14
- }
15
- //# sourceMappingURL=cache_manager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cache_manager.d.ts","sourceRoot":"","sources":["../../src/prover-cache/cache_manager.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAexD,qBAAa,kBAAkB;IACjB,OAAO,CAAC,QAAQ,CAAC;IAAU,OAAO,CAAC,GAAG;gBAA9B,QAAQ,CAAC,oBAAQ,EAAU,GAAG,yCAA4C;IAEjF,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAsBpF;;;OAGG;IACU,iBAAiB,CAAC,qBAAqB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAwB7E"}
@@ -1,57 +0,0 @@
1
- import { createLogger } from '@aztec/foundation/log';
2
- import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
3
- import { InMemoryProverCache } from '@aztec/prover-client';
4
- import { mkdir, readFile, readdir, rm, writeFile } from 'fs/promises';
5
- import { join } from 'path';
6
- import { KVProverCache } from './kv_cache.js';
7
- const EPOCH_DIR_PREFIX = 'epoch';
8
- const EPOCH_DIR_SEPARATOR = '_';
9
- const EPOCH_HASH_FILENAME = 'epoch_hash.txt';
10
- export class ProverCacheManager {
11
- constructor(cacheDir, log = createLogger('prover-node:cache-manager')) {
12
- this.cacheDir = cacheDir;
13
- this.log = log;
14
- }
15
- async openCache(epochNumber, epochHash) {
16
- if (!this.cacheDir) {
17
- return new InMemoryProverCache();
18
- }
19
- const epochDir = EPOCH_DIR_PREFIX + EPOCH_DIR_SEPARATOR + epochNumber;
20
- const dataDir = join(this.cacheDir, epochDir);
21
- const storedEpochHash = await readFile(join(dataDir, EPOCH_HASH_FILENAME), 'hex').catch(() => Buffer.alloc(0));
22
- if (storedEpochHash.toString() !== epochHash.toString()) {
23
- await rm(dataDir, { recursive: true, force: true });
24
- }
25
- await mkdir(dataDir, { recursive: true });
26
- await writeFile(join(dataDir, EPOCH_HASH_FILENAME), epochHash.toString('hex'));
27
- const store = AztecLmdbStore.open(dataDir);
28
- this.log.debug(`Created new database for epoch ${epochNumber} at ${dataDir}`);
29
- const cleanup = () => store.close();
30
- return new KVProverCache(store, cleanup);
31
- }
32
- /**
33
- * Removes all caches for epochs older than the given epoch (including)
34
- * @param upToAndIncludingEpoch - The epoch number up to which to remove caches
35
- */
36
- async removeStaleCaches(upToAndIncludingEpoch) {
37
- if (!this.cacheDir) {
38
- return;
39
- }
40
- const entries = await readdir(this.cacheDir, { withFileTypes: true }).catch(() => []);
41
- for (const item of entries) {
42
- if (!item.isDirectory()) {
43
- continue;
44
- }
45
- const [prefix, epochNumber] = item.name.split(EPOCH_DIR_SEPARATOR);
46
- if (prefix !== EPOCH_DIR_PREFIX) {
47
- continue;
48
- }
49
- const epochNumberInt = BigInt(epochNumber);
50
- if (epochNumberInt <= upToAndIncludingEpoch) {
51
- this.log.info(`Removing old epoch database for epoch ${epochNumberInt} at ${join(this.cacheDir, item.name)}`);
52
- await rm(join(this.cacheDir, item.name), { recursive: true });
53
- }
54
- }
55
- }
56
- }
57
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGVfbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wcm92ZXItY2FjaGUvY2FjaGVfbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDckQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRzNELE9BQU8sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFNUIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU5QyxNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQztBQUNqQyxNQUFNLG1CQUFtQixHQUFHLEdBQUcsQ0FBQztBQUNoQyxNQUFNLG1CQUFtQixHQUFHLGdCQUFnQixDQUFDO0FBRTdDLE1BQU0sT0FBTyxrQkFBa0I7SUFDN0IsWUFBb0IsUUFBaUIsRUFBVSxNQUFNLFlBQVksQ0FBQywyQkFBMkIsQ0FBQztRQUExRSxhQUFRLEdBQVIsUUFBUSxDQUFTO1FBQVUsUUFBRyxHQUFILEdBQUcsQ0FBNEM7SUFBRyxDQUFDO0lBRTNGLEtBQUssQ0FBQyxTQUFTLENBQUMsV0FBbUIsRUFBRSxTQUFpQjtRQUMzRCxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ25CLE9BQU8sSUFBSSxtQkFBbUIsRUFBRSxDQUFDO1FBQ25DLENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxnQkFBZ0IsR0FBRyxtQkFBbUIsR0FBRyxXQUFXLENBQUM7UUFDdEUsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxD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
@@ -1,11 +0,0 @@
1
- import type { ProverCache, ProvingJobStatus } from '@aztec/circuit-types';
2
- import type { AztecKVStore } from '@aztec/kv-store';
3
- export declare class KVProverCache implements ProverCache {
4
- private cleanup?;
5
- private proofs;
6
- constructor(store: AztecKVStore, cleanup?: (() => Promise<void>) | undefined);
7
- getProvingJobStatus(jobId: string): Promise<ProvingJobStatus>;
8
- setProvingJobStatus(jobId: string, status: ProvingJobStatus): Promise<void>;
9
- close(): Promise<void>;
10
- }
11
- //# sourceMappingURL=kv_cache.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"kv_cache.d.ts","sourceRoot":"","sources":["../../src/prover-cache/kv_cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,iBAAiB,CAAC;AAE9D,qBAAa,aAAc,YAAW,WAAW;IAGd,OAAO,CAAC,OAAO,CAAC;IAFjD,OAAO,CAAC,MAAM,CAA2B;gBAE7B,KAAK,EAAE,YAAY,EAAU,OAAO,CAAC,SAAQ,QAAQ,IAAI,CAAC,aAAA;IAItE,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAS7D,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
@@ -1,20 +0,0 @@
1
- export class KVProverCache {
2
- constructor(store, cleanup) {
3
- this.cleanup = cleanup;
4
- this.proofs = store.openMap('prover_node_proof_status');
5
- }
6
- getProvingJobStatus(jobId) {
7
- const item = this.proofs.get(jobId);
8
- if (!item) {
9
- return Promise.resolve({ status: 'not-found' });
10
- }
11
- return Promise.resolve(JSON.parse(item));
12
- }
13
- setProvingJobStatus(jobId, status) {
14
- return this.proofs.set(jobId, JSON.stringify(status));
15
- }
16
- async close() {
17
- await this.cleanup?.();
18
- }
19
- }
20
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia3ZfY2FjaGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJvdmVyLWNhY2hlL2t2X2NhY2hlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE1BQU0sT0FBTyxhQUFhO0lBR3hCLFlBQVksS0FBbUIsRUFBVSxPQUE2QjtRQUE3QixZQUFPLEdBQVAsT0FBTyxDQUFzQjtRQUNwRSxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsMEJBQTBCLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRUQsbUJBQW1CLENBQUMsS0FBYTtRQUMvQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNwQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDVixPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUNsRCxDQUFDO1FBRUQsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBRUQsbUJBQW1CLENBQUMsS0FBYSxFQUFFLE1BQXdCO1FBQ3pELE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRUQsS0FBSyxDQUFDLEtBQUs7UUFDVCxNQUFNLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO0lBQ3pCLENBQUM7Q0FDRiJ9
@@ -1,69 +0,0 @@
1
- import { type ProverCache } from '@aztec/circuit-types';
2
- import { createLogger } from '@aztec/foundation/log';
3
- import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
4
- import { InMemoryProverCache } from '@aztec/prover-client';
5
-
6
- import { type Dirent } from 'fs';
7
- import { mkdir, readFile, readdir, rm, writeFile } from 'fs/promises';
8
- import { join } from 'path';
9
-
10
- import { KVProverCache } from './kv_cache.js';
11
-
12
- const EPOCH_DIR_PREFIX = 'epoch';
13
- const EPOCH_DIR_SEPARATOR = '_';
14
- const EPOCH_HASH_FILENAME = 'epoch_hash.txt';
15
-
16
- export class ProverCacheManager {
17
- constructor(private cacheDir?: string, private log = createLogger('prover-node:cache-manager')) {}
18
-
19
- public async openCache(epochNumber: bigint, epochHash: Buffer): Promise<ProverCache> {
20
- if (!this.cacheDir) {
21
- return new InMemoryProverCache();
22
- }
23
-
24
- const epochDir = EPOCH_DIR_PREFIX + EPOCH_DIR_SEPARATOR + epochNumber;
25
- const dataDir = join(this.cacheDir, epochDir);
26
-
27
- const storedEpochHash = await readFile(join(dataDir, EPOCH_HASH_FILENAME), 'hex').catch(() => Buffer.alloc(0));
28
- if (storedEpochHash.toString() !== epochHash.toString()) {
29
- await rm(dataDir, { recursive: true, force: true });
30
- }
31
-
32
- await mkdir(dataDir, { recursive: true });
33
- await writeFile(join(dataDir, EPOCH_HASH_FILENAME), epochHash.toString('hex'));
34
-
35
- const store = AztecLmdbStore.open(dataDir);
36
- this.log.debug(`Created new database for epoch ${epochNumber} at ${dataDir}`);
37
- const cleanup = () => store.close();
38
- return new KVProverCache(store, cleanup);
39
- }
40
-
41
- /**
42
- * Removes all caches for epochs older than the given epoch (including)
43
- * @param upToAndIncludingEpoch - The epoch number up to which to remove caches
44
- */
45
- public async removeStaleCaches(upToAndIncludingEpoch: bigint): Promise<void> {
46
- if (!this.cacheDir) {
47
- return;
48
- }
49
-
50
- const entries: Dirent[] = await readdir(this.cacheDir, { withFileTypes: true }).catch(() => []);
51
-
52
- for (const item of entries) {
53
- if (!item.isDirectory()) {
54
- continue;
55
- }
56
-
57
- const [prefix, epochNumber] = item.name.split(EPOCH_DIR_SEPARATOR);
58
- if (prefix !== EPOCH_DIR_PREFIX) {
59
- continue;
60
- }
61
-
62
- const epochNumberInt = BigInt(epochNumber);
63
- if (epochNumberInt <= upToAndIncludingEpoch) {
64
- this.log.info(`Removing old epoch database for epoch ${epochNumberInt} at ${join(this.cacheDir, item.name)}`);
65
- await rm(join(this.cacheDir, item.name), { recursive: true });
66
- }
67
- }
68
- }
69
- }