@aztec/prover-client 0.47.0 → 0.48.0

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 (54) hide show
  1. package/dest/config.d.ts +2 -0
  2. package/dest/config.d.ts.map +1 -1
  3. package/dest/config.js +28 -30
  4. package/dest/mocks/fixtures.d.ts.map +1 -1
  5. package/dest/mocks/fixtures.js +11 -7
  6. package/dest/mocks/test_context.d.ts +3 -3
  7. package/dest/mocks/test_context.d.ts.map +1 -1
  8. package/dest/mocks/test_context.js +6 -24
  9. package/dest/orchestrator/block-building-helpers.d.ts +3 -3
  10. package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
  11. package/dest/orchestrator/block-building-helpers.js +6 -5
  12. package/dest/orchestrator/orchestrator.d.ts +11 -6
  13. package/dest/orchestrator/orchestrator.d.ts.map +1 -1
  14. package/dest/orchestrator/orchestrator.js +115 -89
  15. package/dest/orchestrator/orchestrator_metrics.d.ts +8 -0
  16. package/dest/orchestrator/orchestrator_metrics.d.ts.map +1 -0
  17. package/dest/orchestrator/orchestrator_metrics.js +19 -0
  18. package/dest/orchestrator/proving-state.d.ts +3 -1
  19. package/dest/orchestrator/proving-state.d.ts.map +1 -1
  20. package/dest/orchestrator/proving-state.js +5 -1
  21. package/dest/orchestrator/tx-proving-state.d.ts +3 -2
  22. package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
  23. package/dest/orchestrator/tx-proving-state.js +26 -8
  24. package/dest/prover-agent/memory-proving-queue.d.ts +15 -13
  25. package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
  26. package/dest/prover-agent/memory-proving-queue.js +37 -55
  27. package/dest/prover-agent/prover-agent.d.ts.map +1 -1
  28. package/dest/prover-agent/prover-agent.js +30 -8
  29. package/dest/prover-agent/queue_metrics.d.ts +10 -0
  30. package/dest/prover-agent/queue_metrics.d.ts.map +1 -0
  31. package/dest/prover-agent/queue_metrics.js +23 -0
  32. package/dest/prover-agent/rpc.d.ts.map +1 -1
  33. package/dest/prover-agent/rpc.js +4 -2
  34. package/dest/tx-prover/factory.d.ts +1 -3
  35. package/dest/tx-prover/factory.d.ts.map +1 -1
  36. package/dest/tx-prover/factory.js +3 -3
  37. package/dest/tx-prover/tx-prover.d.ts +8 -33
  38. package/dest/tx-prover/tx-prover.d.ts.map +1 -1
  39. package/dest/tx-prover/tx-prover.js +18 -46
  40. package/package.json +10 -10
  41. package/src/config.ts +28 -47
  42. package/src/mocks/fixtures.ts +14 -4
  43. package/src/mocks/test_context.ts +7 -27
  44. package/src/orchestrator/block-building-helpers.ts +6 -5
  45. package/src/orchestrator/orchestrator.ts +197 -103
  46. package/src/orchestrator/orchestrator_metrics.ts +32 -0
  47. package/src/orchestrator/proving-state.ts +5 -0
  48. package/src/orchestrator/tx-proving-state.ts +33 -7
  49. package/src/prover-agent/memory-proving-queue.ts +54 -70
  50. package/src/prover-agent/prover-agent.ts +42 -7
  51. package/src/prover-agent/queue_metrics.ts +29 -0
  52. package/src/prover-agent/rpc.ts +3 -0
  53. package/src/tx-prover/factory.ts +2 -9
  54. package/src/tx-prover/tx-prover.ts +21 -64
@@ -0,0 +1,32 @@
1
+ import {
2
+ type Histogram,
3
+ Metrics,
4
+ type TelemetryClient,
5
+ type Tracer,
6
+ ValueType,
7
+ millisecondBuckets,
8
+ } from '@aztec/telemetry-client';
9
+
10
+ export class ProvingOrchestratorMetrics {
11
+ public readonly tracer: Tracer;
12
+
13
+ private baseRollupInputsDuration: Histogram;
14
+
15
+ constructor(client: TelemetryClient, name = 'ProvingOrchestrator') {
16
+ this.tracer = client.getTracer(name);
17
+ const meter = client.getMeter(name);
18
+
19
+ this.baseRollupInputsDuration = meter.createHistogram(Metrics.PROVING_ORCHESTRATOR_BASE_ROLLUP_INPUTS_DURATION, {
20
+ unit: 'ms',
21
+ description: 'Duration to build base rollup inputs',
22
+ valueType: ValueType.INT,
23
+ advice: {
24
+ explicitBucketBoundaries: millisecondBuckets(1), // 10ms -> ~327s
25
+ },
26
+ });
27
+ }
28
+
29
+ recordBaseRollupInputs(durationMs: number) {
30
+ this.baseRollupInputsDuration.record(Math.ceil(durationMs));
31
+ }
32
+ }
@@ -143,6 +143,11 @@ export class ProvingState {
143
143
  return this.txs;
144
144
  }
145
145
 
146
+ /** Returns the block number as an epoch number. Used for prioritizing proof requests. */
147
+ public get epochNumber(): number {
148
+ return this.globalVariables.blockNumber.toNumber();
149
+ }
150
+
146
151
  /**
147
152
  * Stores the inputs to a merge circuit and determines if the circuit is ready to be executed
148
153
  * @param mergeInputs - The inputs to store
@@ -11,6 +11,7 @@ import {
11
11
  type BaseRollupInputs,
12
12
  type NESTED_RECURSIVE_PROOF_LENGTH,
13
13
  type Proof,
14
+ type RECURSIVE_PROOF_LENGTH,
14
15
  type RecursiveProof,
15
16
  type VerificationKeyData,
16
17
  } from '@aztec/circuits.js';
@@ -48,23 +49,17 @@ export class TxProvingState {
48
49
  public readonly processedTx: ProcessedTx,
49
50
  public readonly baseRollupInputs: BaseRollupInputs,
50
51
  public readonly treeSnapshots: Map<MerkleTreeId, AppendOnlyTreeSnapshot>,
51
- privateKernelVk: VerificationKeyData,
52
52
  ) {
53
53
  let previousProofType = PublicKernelType.NON_PUBLIC;
54
54
  for (let i = 0; i < processedTx.publicProvingRequests.length; i++) {
55
55
  const provingRequest = processedTx.publicProvingRequests[i];
56
56
  const kernelRequest = provingRequest.type === AVM_REQUEST ? provingRequest.kernelRequest : provingRequest;
57
- // the first circuit has a valid previous proof, it came from private
58
- if (i === 0) {
59
- kernelRequest.inputs.previousKernel.vk = privateKernelVk;
60
- kernelRequest.inputs.previousKernel.clientIvcProof = processedTx.clientIvcProof;
61
- }
62
57
  const vmRequest = provingRequest.type === AVM_REQUEST ? provingRequest : undefined;
63
58
  const publicFunction: PublicFunction = {
64
59
  vmRequest,
65
60
  vmProof: undefined,
66
61
  previousProofType,
67
- previousKernelProven: i === 0,
62
+ previousKernelProven: false,
68
63
  publicKernelRequest: kernelRequest,
69
64
  };
70
65
  this.publicFunctions.push(publicFunction);
@@ -105,6 +100,37 @@ export class TxProvingState {
105
100
  return { code: TX_PROVING_CODE.READY, function: nextFunction };
106
101
  }
107
102
 
103
+ // Updates the transaction's proving state after completion of a tube proof
104
+ // Returns an instruction as to the next stage of tx proving
105
+ public getNextPublicKernelFromTubeProof(
106
+ proof: RecursiveProof<typeof RECURSIVE_PROOF_LENGTH>,
107
+ verificationKey: VerificationKeyData,
108
+ ): TxProvingInstruction {
109
+ const nextKernelIndex = 0;
110
+ if (nextKernelIndex >= this.publicFunctions.length) {
111
+ // The next kernel index is greater than our set of functions, we are done!
112
+ return { code: TX_PROVING_CODE.COMPLETED, function: undefined };
113
+ }
114
+
115
+ // There is more work to do, are we ready?
116
+ const nextFunction = this.publicFunctions[nextKernelIndex];
117
+
118
+ // pass both the proof and verification key forward to the next circuit
119
+ nextFunction.publicKernelRequest.inputs.previousKernel.proof = proof;
120
+ nextFunction.publicKernelRequest.inputs.previousKernel.vk = verificationKey;
121
+
122
+ // We need to update this so the state machine knows this proof is ready
123
+ nextFunction.previousKernelProven = true;
124
+ nextFunction.previousProofType = PublicKernelType.NON_PUBLIC;
125
+ if (nextFunction.vmProof === undefined) {
126
+ // The VM proof for the next function is not ready
127
+ return { code: TX_PROVING_CODE.NOT_READY, function: undefined };
128
+ }
129
+
130
+ // The VM proof is ready, we can continue
131
+ return { code: TX_PROVING_CODE.READY, function: nextFunction };
132
+ }
133
+
108
134
  // Updates the transaction's proving state after completion of a VM proof
109
135
  // Returns an instruction as to the next stage of tx proving
110
136
  public getNextPublicKernelFromVMProof(provenIndex: number, proof: Proof): TxProvingInstruction {
@@ -31,35 +31,43 @@ import type {
31
31
  } from '@aztec/circuits.js';
32
32
  import { randomBytes } from '@aztec/foundation/crypto';
33
33
  import { AbortError, TimeoutError } from '@aztec/foundation/error';
34
- import { MemoryFifo } from '@aztec/foundation/fifo';
35
34
  import { createDebugLogger } from '@aztec/foundation/log';
36
35
  import { type PromiseWithResolvers, RunningPromise, promiseWithResolvers } from '@aztec/foundation/promise';
37
-
38
- type ProvingJobWithResolvers<T extends ProvingRequest = ProvingRequest> = {
39
- id: string;
40
- request: T;
41
- signal?: AbortSignal;
42
- attempts: number;
43
- heartbeat: number;
44
- } & PromiseWithResolvers<ProvingRequestResult<T['type']>>;
36
+ import { PriorityMemoryQueue } from '@aztec/foundation/queue';
37
+ import { serializeToBuffer } from '@aztec/foundation/serialize';
38
+ import { type TelemetryClient } from '@aztec/telemetry-client';
39
+
40
+ import { ProvingQueueMetrics } from './queue_metrics.js';
41
+
42
+ type ProvingJobWithResolvers<T extends ProvingRequest = ProvingRequest> = ProvingJob<T> &
43
+ PromiseWithResolvers<ProvingRequestResult<T['type']>> & {
44
+ signal?: AbortSignal;
45
+ epochNumber?: number;
46
+ attempts: number;
47
+ heartbeat: number;
48
+ };
45
49
 
46
50
  const MAX_RETRIES = 3;
47
51
 
48
52
  const defaultIdGenerator = () => randomBytes(4).toString('hex');
49
53
  const defaultTimeSource = () => Date.now();
50
-
51
54
  /**
52
55
  * A helper class that sits in between services that need proofs created and agents that can create them.
53
- * The queue accumulates jobs and provides them to agents in FIFO order.
56
+ * The queue accumulates jobs and provides them to agents prioritized by block number.
54
57
  */
55
58
  export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource {
56
59
  private log = createDebugLogger('aztec:prover-client:prover-pool:queue');
57
- private queue = new MemoryFifo<ProvingJobWithResolvers>();
60
+ private queue = new PriorityMemoryQueue<ProvingJobWithResolvers>(
61
+ (a, b) => (a.epochNumber ?? 0) - (b.epochNumber ?? 0),
62
+ );
58
63
  private jobsInProgress = new Map<string, ProvingJobWithResolvers>();
59
64
 
60
65
  private runningPromise: RunningPromise;
61
66
 
67
+ private metrics: ProvingQueueMetrics;
68
+
62
69
  constructor(
70
+ client: TelemetryClient,
63
71
  /** Timeout the job if an agent doesn't report back in this time */
64
72
  private jobTimeoutMs = 60 * 1000,
65
73
  /** How often to check for timed out jobs */
@@ -67,6 +75,7 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
67
75
  private generateId = defaultIdGenerator,
68
76
  private timeSource = defaultTimeSource,
69
77
  ) {
78
+ this.metrics = new ProvingQueueMetrics(client, 'MemoryProvingQueue');
70
79
  this.runningPromise = new RunningPromise(this.poll, pollingIntervalMs);
71
80
  }
72
81
 
@@ -156,7 +165,8 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
156
165
  return Promise.resolve();
157
166
  }
158
167
 
159
- if (job.attempts < MAX_RETRIES) {
168
+ // every job should be retried with the exception of the public VM since its in development and can fail
169
+ if (job.attempts < MAX_RETRIES && job.request.type !== ProvingRequestType.PUBLIC_VM) {
160
170
  job.attempts++;
161
171
  this.log.warn(
162
172
  `Job id=${job.id} type=${ProvingRequestType[job.request.type]} failed with error: ${err}. Retry ${
@@ -190,6 +200,7 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
190
200
 
191
201
  private poll = () => {
192
202
  const now = this.timeSource();
203
+ this.metrics.recordQueueSize(this.queue.length());
193
204
 
194
205
  for (const job of this.jobsInProgress.values()) {
195
206
  if (job.signal?.aborted) {
@@ -210,6 +221,7 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
210
221
  private enqueue<T extends ProvingRequest>(
211
222
  request: T,
212
223
  signal?: AbortSignal,
224
+ epochNumber?: number,
213
225
  ): Promise<ProvingRequestResult<T['type']>> {
214
226
  if (!this.runningPromise.isRunning()) {
215
227
  return Promise.reject(new Error('Proving queue is not running.'));
@@ -225,6 +237,7 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
225
237
  reject,
226
238
  attempts: 1,
227
239
  heartbeat: 0,
240
+ epochNumber,
228
241
  };
229
242
 
230
243
  if (signal) {
@@ -239,28 +252,34 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
239
252
  throw new Error();
240
253
  }
241
254
 
255
+ const byteSize = serializeToBuffer(item.request.inputs).length;
256
+ this.metrics.recordNewJob(item.request.type, byteSize);
257
+
242
258
  return promise;
243
259
  }
244
260
 
245
261
  getEmptyPrivateKernelProof(
246
262
  inputs: PrivateKernelEmptyInputData,
247
263
  signal?: AbortSignal,
264
+ epochNumber?: number,
248
265
  ): Promise<PublicInputsAndRecursiveProof<KernelCircuitPublicInputs>> {
249
- return this.enqueue({ type: ProvingRequestType.PRIVATE_KERNEL_EMPTY, inputs }, signal);
266
+ return this.enqueue({ type: ProvingRequestType.PRIVATE_KERNEL_EMPTY, inputs }, signal, epochNumber);
250
267
  }
251
268
 
252
269
  getTubeProof(
253
270
  inputs: TubeInputs,
254
- signal?: AbortSignal | undefined,
271
+ signal?: AbortSignal,
272
+ epochNumber?: number,
255
273
  ): Promise<{ tubeVK: VerificationKeyData; tubeProof: RecursiveProof<typeof RECURSIVE_PROOF_LENGTH> }> {
256
- return this.enqueue({ type: ProvingRequestType.TUBE_PROOF, inputs }, signal);
274
+ return this.enqueue({ type: ProvingRequestType.TUBE_PROOF, inputs }, signal, epochNumber);
257
275
  }
258
276
 
259
277
  getEmptyTubeProof(
260
278
  inputs: PrivateKernelEmptyInputData,
261
279
  signal?: AbortSignal,
280
+ epochNumber?: number,
262
281
  ): Promise<PublicInputsAndRecursiveProof<KernelCircuitPublicInputs>> {
263
- return this.enqueue({ type: ProvingRequestType.PRIVATE_KERNEL_EMPTY, inputs }, signal);
282
+ return this.enqueue({ type: ProvingRequestType.PRIVATE_KERNEL_EMPTY, inputs }, signal, epochNumber);
264
283
  }
265
284
 
266
285
  /**
@@ -270,14 +289,9 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
270
289
  getBaseParityProof(
271
290
  inputs: BaseParityInputs,
272
291
  signal?: AbortSignal,
292
+ epochNumber?: number,
273
293
  ): Promise<RootParityInput<typeof RECURSIVE_PROOF_LENGTH>> {
274
- return this.enqueue(
275
- {
276
- type: ProvingRequestType.BASE_PARITY,
277
- inputs,
278
- },
279
- signal,
280
- );
294
+ return this.enqueue({ type: ProvingRequestType.BASE_PARITY, inputs }, signal, epochNumber);
281
295
  }
282
296
 
283
297
  /**
@@ -287,14 +301,9 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
287
301
  getRootParityProof(
288
302
  inputs: RootParityInputs,
289
303
  signal?: AbortSignal,
304
+ epochNumber?: number,
290
305
  ): Promise<RootParityInput<typeof NESTED_RECURSIVE_PROOF_LENGTH>> {
291
- return this.enqueue(
292
- {
293
- type: ProvingRequestType.ROOT_PARITY,
294
- inputs,
295
- },
296
- signal,
297
- );
306
+ return this.enqueue({ type: ProvingRequestType.ROOT_PARITY, inputs }, signal, epochNumber);
298
307
  }
299
308
 
300
309
  /**
@@ -304,14 +313,9 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
304
313
  getBaseRollupProof(
305
314
  baseRollupInput: BaseRollupInputs,
306
315
  signal?: AbortSignal,
316
+ epochNumber?: number,
307
317
  ): Promise<PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs>> {
308
- return this.enqueue(
309
- {
310
- type: ProvingRequestType.BASE_ROLLUP,
311
- inputs: baseRollupInput,
312
- },
313
- signal,
314
- );
318
+ return this.enqueue({ type: ProvingRequestType.BASE_ROLLUP, inputs: baseRollupInput }, signal, epochNumber);
315
319
  }
316
320
 
317
321
  /**
@@ -321,14 +325,9 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
321
325
  getMergeRollupProof(
322
326
  input: MergeRollupInputs,
323
327
  signal?: AbortSignal,
328
+ epochNumber?: number,
324
329
  ): Promise<PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs>> {
325
- return this.enqueue(
326
- {
327
- type: ProvingRequestType.MERGE_ROLLUP,
328
- inputs: input,
329
- },
330
- signal,
331
- );
330
+ return this.enqueue({ type: ProvingRequestType.MERGE_ROLLUP, inputs: input }, signal, epochNumber);
332
331
  }
333
332
 
334
333
  /**
@@ -338,14 +337,9 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
338
337
  getRootRollupProof(
339
338
  input: RootRollupInputs,
340
339
  signal?: AbortSignal,
340
+ epochNumber?: number,
341
341
  ): Promise<PublicInputsAndRecursiveProof<RootRollupPublicInputs>> {
342
- return this.enqueue(
343
- {
344
- type: ProvingRequestType.ROOT_ROLLUP,
345
- inputs: input,
346
- },
347
- signal,
348
- );
342
+ return this.enqueue({ type: ProvingRequestType.ROOT_ROLLUP, inputs: input }, signal, epochNumber);
349
343
  }
350
344
 
351
345
  /**
@@ -355,14 +349,12 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
355
349
  getPublicKernelProof(
356
350
  kernelRequest: PublicKernelNonTailRequest,
357
351
  signal?: AbortSignal,
352
+ epochNumber?: number,
358
353
  ): Promise<PublicInputsAndRecursiveProof<PublicKernelCircuitPublicInputs>> {
359
354
  return this.enqueue(
360
- {
361
- type: ProvingRequestType.PUBLIC_KERNEL_NON_TAIL,
362
- kernelType: kernelRequest.type,
363
- inputs: kernelRequest.inputs,
364
- },
355
+ { type: ProvingRequestType.PUBLIC_KERNEL_NON_TAIL, kernelType: kernelRequest.type, inputs: kernelRequest.inputs },
365
356
  signal,
357
+ epochNumber,
366
358
  );
367
359
  }
368
360
 
@@ -373,28 +365,20 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
373
365
  getPublicTailProof(
374
366
  kernelRequest: PublicKernelTailRequest,
375
367
  signal?: AbortSignal,
368
+ epochNumber?: number,
376
369
  ): Promise<PublicInputsAndRecursiveProof<KernelCircuitPublicInputs>> {
377
370
  return this.enqueue(
378
- {
379
- type: ProvingRequestType.PUBLIC_KERNEL_TAIL,
380
- kernelType: kernelRequest.type,
381
- inputs: kernelRequest.inputs,
382
- },
371
+ { type: ProvingRequestType.PUBLIC_KERNEL_TAIL, kernelType: kernelRequest.type, inputs: kernelRequest.inputs },
383
372
  signal,
373
+ epochNumber,
384
374
  );
385
375
  }
386
376
 
387
377
  /**
388
378
  * Creates an AVM proof.
389
379
  */
390
- getAvmProof(inputs: AvmCircuitInputs, signal?: AbortSignal | undefined): Promise<ProofAndVerificationKey> {
391
- return this.enqueue(
392
- {
393
- type: ProvingRequestType.PUBLIC_VM,
394
- inputs,
395
- },
396
- signal,
397
- );
380
+ getAvmProof(inputs: AvmCircuitInputs, signal?: AbortSignal, epochNumber?: number): Promise<ProofAndVerificationKey> {
381
+ return this.enqueue({ type: ProvingRequestType.PUBLIC_VM, inputs }, signal, epochNumber);
398
382
  }
399
383
 
400
384
  /**
@@ -12,11 +12,20 @@ import { elapsed } from '@aztec/foundation/timer';
12
12
 
13
13
  import { ProvingError } from './proving-error.js';
14
14
 
15
+ const PRINT_THRESHOLD_NS = 6e10; // 60 seconds
16
+
15
17
  /**
16
18
  * A helper class that encapsulates a circuit prover and connects it to a job source.
17
19
  */
18
20
  export class ProverAgent {
19
- private inFlightPromises = new Map<string, Promise<any>>();
21
+ private inFlightPromises = new Map<
22
+ string,
23
+ {
24
+ id: string;
25
+ type: ProvingRequestType;
26
+ promise: Promise<any>;
27
+ }
28
+ >();
20
29
  private runningPromise?: RunningPromise;
21
30
 
22
31
  constructor(
@@ -49,11 +58,26 @@ export class ProverAgent {
49
58
  throw new Error('Agent is already running');
50
59
  }
51
60
 
61
+ let lastPrint = process.hrtime.bigint();
62
+
52
63
  this.runningPromise = new RunningPromise(async () => {
53
64
  for (const jobId of this.inFlightPromises.keys()) {
54
65
  await jobSource.heartbeat(jobId);
55
66
  }
56
67
 
68
+ const now = process.hrtime.bigint();
69
+
70
+ if (now - lastPrint >= PRINT_THRESHOLD_NS) {
71
+ // only log if we're actually doing work
72
+ if (this.inFlightPromises.size > 0) {
73
+ const jobs = Array.from(this.inFlightPromises.values())
74
+ .map(job => `id=${job.id},type=${ProvingRequestType[job.type]}`)
75
+ .join(' ');
76
+ this.log.info(`Agent is running with ${this.inFlightPromises.size} in-flight jobs: ${jobs}`);
77
+ }
78
+ lastPrint = now;
79
+ }
80
+
57
81
  while (this.inFlightPromises.size < this.maxConcurrency) {
58
82
  try {
59
83
  const job = await jobSource.getProvingJob();
@@ -62,10 +86,20 @@ export class ProverAgent {
62
86
  return;
63
87
  }
64
88
 
65
- const promise = this.work(jobSource, job).finally(() => this.inFlightPromises.delete(job.id));
66
- this.inFlightPromises.set(job.id, promise);
89
+ try {
90
+ const promise = this.work(jobSource, job).finally(() => this.inFlightPromises.delete(job.id));
91
+ this.inFlightPromises.set(job.id, {
92
+ id: job.id,
93
+ type: job.request.type,
94
+ promise,
95
+ });
96
+ } catch (err) {
97
+ this.log.warn(
98
+ `Error processing job! type=${ProvingRequestType[job.request.type]}: ${err}. ${(err as Error).stack}`,
99
+ );
100
+ }
67
101
  } catch (err) {
68
- this.log.warn(`Error processing job: ${err}`);
102
+ this.log.error(`Error fetching job`, err);
69
103
  }
70
104
  }
71
105
  }, this.pollIntervalMs);
@@ -90,12 +124,12 @@ export class ProverAgent {
90
124
  this.log.debug(`Picked up proving job id=${job.id} type=${ProvingRequestType[job.request.type]}`);
91
125
  const [time, result] = await elapsed(this.getProof(job.request));
92
126
  if (this.isRunning()) {
93
- this.log.debug(
127
+ this.log.verbose(
94
128
  `Processed proving job id=${job.id} type=${ProvingRequestType[job.request.type]} duration=${time}ms`,
95
129
  );
96
130
  await jobSource.resolveProvingJob(job.id, result);
97
131
  } else {
98
- this.log.debug(
132
+ this.log.verbose(
99
133
  `Dropping proving job id=${job.id} type=${
100
134
  ProvingRequestType[job.request.type]
101
135
  } duration=${time}ms: agent stopped`,
@@ -107,10 +141,11 @@ export class ProverAgent {
107
141
  `Error processing proving job id=${job.id} type=${ProvingRequestType[job.request.type]}: ${
108
142
  (err as any).stack || err
109
143
  }`,
144
+ err,
110
145
  );
111
146
  await jobSource.rejectProvingJob(job.id, new ProvingError((err as any)?.message ?? String(err)));
112
147
  } else {
113
- this.log.debug(
148
+ this.log.verbose(
114
149
  `Dropping proving job id=${job.id} type=${ProvingRequestType[job.request.type]}: agent stopped: ${
115
150
  (err as any).stack || err
116
151
  }`,
@@ -0,0 +1,29 @@
1
+ import { ProvingRequestType } from '@aztec/circuit-types';
2
+ import { Attributes, type Gauge, type Histogram, Metrics, type TelemetryClient } from '@aztec/telemetry-client';
3
+
4
+ export class ProvingQueueMetrics {
5
+ private jobSize: Histogram;
6
+ private queueSize: Gauge;
7
+
8
+ constructor(client: TelemetryClient, name = 'ProvingQueueMetrics') {
9
+ const meter = client.getMeter(name);
10
+ this.jobSize = meter.createHistogram(Metrics.PROVING_QUEUE_JOB_SIZE, {
11
+ description: 'Size of proving job',
12
+ unit: 'by',
13
+ });
14
+
15
+ this.queueSize = meter.createGauge(Metrics.PROVING_QUEUE_SIZE, {
16
+ description: 'Size of proving queue',
17
+ });
18
+ }
19
+
20
+ recordNewJob(type: ProvingRequestType, size: number) {
21
+ this.jobSize.record(size, {
22
+ [Attributes.PROVING_JOB_TYPE]: ProvingRequestType[type],
23
+ });
24
+ }
25
+
26
+ recordQueueSize(size: number) {
27
+ this.queueSize.record(size);
28
+ }
29
+ }
@@ -9,6 +9,7 @@ import {
9
9
  KernelCircuitPublicInputs,
10
10
  MergeRollupInputs,
11
11
  ParityPublicInputs,
12
+ PrivateKernelEmptyInputData,
12
13
  Proof,
13
14
  PublicKernelCircuitPrivateInputs,
14
15
  PublicKernelCircuitPublicInputs,
@@ -41,6 +42,7 @@ export function createProvingJobSourceServer(queue: ProvingJobSource): JsonRpcSe
41
42
  ParityPublicInputs,
42
43
  Proof,
43
44
  ProvingError,
45
+ PrivateKernelEmptyInputData,
44
46
  PublicKernelCircuitPrivateInputs,
45
47
  PublicKernelCircuitPublicInputs,
46
48
  PublicKernelTailCircuitPrivateInputs,
@@ -75,6 +77,7 @@ export function createProvingJobSourceClient(
75
77
  ParityPublicInputs,
76
78
  Proof,
77
79
  ProvingError,
80
+ PrivateKernelEmptyInputData,
78
81
  PublicKernelCircuitPrivateInputs,
79
82
  PublicKernelCircuitPublicInputs,
80
83
  PublicKernelTailCircuitPrivateInputs,
@@ -1,16 +1,9 @@
1
- import { type L2BlockSource } from '@aztec/circuit-types';
2
1
  import { type TelemetryClient } from '@aztec/telemetry-client';
3
2
  import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
4
- import { type WorldStateSynchronizer } from '@aztec/world-state';
5
3
 
6
4
  import { type ProverClientConfig } from '../config.js';
7
5
  import { TxProver } from './tx-prover.js';
8
6
 
9
- export function createProverClient(
10
- config: ProverClientConfig,
11
- worldStateSynchronizer: WorldStateSynchronizer,
12
- blockSource: L2BlockSource,
13
- telemetry: TelemetryClient = new NoopTelemetryClient(),
14
- ) {
15
- return config.disableProver ? undefined : TxProver.new(config, worldStateSynchronizer, blockSource, telemetry);
7
+ export function createProverClient(config: ProverClientConfig, telemetry: TelemetryClient = new NoopTelemetryClient()) {
8
+ return config.disableProver ? undefined : TxProver.new(config, telemetry);
16
9
  }