@aztec/prover-client 0.65.2 → 0.67.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 (98) hide show
  1. package/dest/block_builder/index.d.ts +6 -0
  2. package/dest/block_builder/index.d.ts.map +1 -0
  3. package/dest/block_builder/index.js +2 -0
  4. package/dest/block_builder/light.d.ts +32 -0
  5. package/dest/block_builder/light.d.ts.map +1 -0
  6. package/dest/block_builder/light.js +75 -0
  7. package/dest/index.d.ts +1 -2
  8. package/dest/index.d.ts.map +1 -1
  9. package/dest/index.js +2 -3
  10. package/dest/mocks/fixtures.d.ts +4 -5
  11. package/dest/mocks/fixtures.d.ts.map +1 -1
  12. package/dest/mocks/fixtures.js +4 -8
  13. package/dest/mocks/test_context.d.ts +30 -12
  14. package/dest/mocks/test_context.d.ts.map +1 -1
  15. package/dest/mocks/test_context.js +61 -24
  16. package/dest/orchestrator/block-building-helpers.d.ts +5 -5
  17. package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
  18. package/dest/orchestrator/block-building-helpers.js +10 -11
  19. package/dest/orchestrator/epoch-proving-state.d.ts +5 -6
  20. package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
  21. package/dest/orchestrator/epoch-proving-state.js +10 -12
  22. package/dest/orchestrator/orchestrator.d.ts +8 -6
  23. package/dest/orchestrator/orchestrator.d.ts.map +1 -1
  24. package/dest/orchestrator/orchestrator.js +85 -74
  25. package/dest/orchestrator/orchestrator_metrics.d.ts.map +1 -1
  26. package/dest/orchestrator/orchestrator_metrics.js +2 -5
  27. package/dest/orchestrator/tx-proving-state.d.ts +0 -1
  28. package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
  29. package/dest/orchestrator/tx-proving-state.js +2 -34
  30. package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
  31. package/dest/prover-agent/memory-proving-queue.js +5 -4
  32. package/dest/prover-agent/prover-agent.d.ts.map +1 -1
  33. package/dest/prover-agent/prover-agent.js +3 -3
  34. package/dest/prover-client/factory.d.ts +6 -0
  35. package/dest/prover-client/factory.d.ts.map +1 -0
  36. package/dest/prover-client/factory.js +6 -0
  37. package/dest/prover-client/index.d.ts +3 -0
  38. package/dest/prover-client/index.d.ts.map +1 -0
  39. package/dest/prover-client/index.js +3 -0
  40. package/dest/{tx-prover/tx-prover.d.ts → prover-client/prover-client.d.ts} +8 -11
  41. package/dest/prover-client/prover-client.d.ts.map +1 -0
  42. package/dest/prover-client/prover-client.js +107 -0
  43. package/dest/proving_broker/caching_broker_facade.d.ts +12 -12
  44. package/dest/proving_broker/caching_broker_facade.d.ts.map +1 -1
  45. package/dest/proving_broker/caching_broker_facade.js +32 -29
  46. package/dest/proving_broker/factory.d.ts +2 -1
  47. package/dest/proving_broker/factory.d.ts.map +1 -1
  48. package/dest/proving_broker/factory.js +4 -4
  49. package/dest/proving_broker/proving_agent.d.ts +5 -0
  50. package/dest/proving_broker/proving_agent.d.ts.map +1 -1
  51. package/dest/proving_broker/proving_agent.js +15 -4
  52. package/dest/proving_broker/proving_agent_instrumentation.d.ts +8 -0
  53. package/dest/proving_broker/proving_agent_instrumentation.d.ts.map +1 -0
  54. package/dest/proving_broker/proving_agent_instrumentation.js +16 -0
  55. package/dest/proving_broker/proving_broker.d.ts +29 -5
  56. package/dest/proving_broker/proving_broker.d.ts.map +1 -1
  57. package/dest/proving_broker/proving_broker.js +142 -41
  58. package/dest/proving_broker/proving_broker_database/persisted.d.ts +3 -1
  59. package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -1
  60. package/dest/proving_broker/proving_broker_database/persisted.js +6 -2
  61. package/dest/proving_broker/proving_broker_instrumentation.d.ts +25 -0
  62. package/dest/proving_broker/proving_broker_instrumentation.d.ts.map +1 -0
  63. package/dest/proving_broker/proving_broker_instrumentation.js +85 -0
  64. package/dest/proving_broker/rpc.d.ts.map +1 -1
  65. package/dest/proving_broker/rpc.js +3 -2
  66. package/dest/test/mock_prover.d.ts +3 -2
  67. package/dest/test/mock_prover.d.ts.map +1 -1
  68. package/dest/test/mock_prover.js +9 -5
  69. package/package.json +18 -13
  70. package/src/block_builder/index.ts +6 -0
  71. package/src/block_builder/light.ts +120 -0
  72. package/src/index.ts +1 -2
  73. package/src/mocks/fixtures.ts +6 -18
  74. package/src/mocks/test_context.ts +85 -29
  75. package/src/orchestrator/block-building-helpers.ts +13 -14
  76. package/src/orchestrator/epoch-proving-state.ts +10 -13
  77. package/src/orchestrator/orchestrator.ts +101 -81
  78. package/src/orchestrator/orchestrator_metrics.ts +1 -11
  79. package/src/orchestrator/tx-proving-state.ts +1 -56
  80. package/src/prover-agent/memory-proving-queue.ts +4 -3
  81. package/src/prover-agent/prover-agent.ts +2 -2
  82. package/src/{tx-prover → prover-client}/factory.ts +4 -3
  83. package/src/prover-client/index.ts +2 -0
  84. package/src/{tx-prover/tx-prover.ts → prover-client/prover-client.ts} +25 -15
  85. package/src/proving_broker/caching_broker_facade.ts +31 -15
  86. package/src/proving_broker/factory.ts +7 -3
  87. package/src/proving_broker/proving_agent.ts +18 -3
  88. package/src/proving_broker/proving_agent_instrumentation.ts +21 -0
  89. package/src/proving_broker/proving_broker.ts +182 -50
  90. package/src/proving_broker/proving_broker_database/persisted.ts +11 -2
  91. package/src/proving_broker/proving_broker_instrumentation.ts +123 -0
  92. package/src/proving_broker/rpc.ts +2 -1
  93. package/src/test/mock_prover.ts +8 -4
  94. package/dest/tx-prover/factory.d.ts +0 -6
  95. package/dest/tx-prover/factory.d.ts.map +0 -1
  96. package/dest/tx-prover/factory.js +0 -6
  97. package/dest/tx-prover/tx-prover.d.ts.map +0 -1
  98. package/dest/tx-prover/tx-prover.js +0 -110
@@ -3,7 +3,7 @@ import {
3
3
  type ActualProverConfig,
4
4
  type EpochProver,
5
5
  type EpochProverManager,
6
- type MerkleTreeWriteOperations,
6
+ type ForkMerkleTreeOperations,
7
7
  type ProverCache,
8
8
  type ProvingJobBroker,
9
9
  type ProvingJobConsumer,
@@ -12,7 +12,7 @@ import {
12
12
  } from '@aztec/circuit-types/interfaces';
13
13
  import { Fr } from '@aztec/circuits.js';
14
14
  import { times } from '@aztec/foundation/collection';
15
- import { createDebugLogger } from '@aztec/foundation/log';
15
+ import { createLogger } from '@aztec/foundation/log';
16
16
  import { NativeACVMSimulator } from '@aztec/simulator';
17
17
  import { type TelemetryClient } from '@aztec/telemetry-client';
18
18
 
@@ -25,11 +25,8 @@ import { InlineProofStore } from '../proving_broker/proof_store.js';
25
25
  import { InMemoryProverCache } from '../proving_broker/prover_cache/memory.js';
26
26
  import { ProvingAgent } from '../proving_broker/proving_agent.js';
27
27
 
28
- /**
29
- * A prover factory.
30
- * TODO(palla/prover-node): Rename this class
31
- */
32
- export class TxProver implements EpochProverManager {
28
+ /** Manages proving of epochs by orchestrating the proving of individual blocks relying on a pool of prover agents. */
29
+ export class ProverClient implements EpochProverManager {
33
30
  private running = false;
34
31
  private agents: ProvingAgent[] = [];
35
32
 
@@ -37,19 +34,20 @@ export class TxProver implements EpochProverManager {
37
34
 
38
35
  private constructor(
39
36
  private config: ProverClientConfig,
37
+ private worldState: ForkMerkleTreeOperations,
40
38
  private telemetry: TelemetryClient,
41
39
  private orchestratorClient: ProvingJobProducer,
42
40
  private agentClient?: ProvingJobConsumer,
43
- private log = createDebugLogger('aztec:prover-client:tx-prover'),
41
+ private log = createLogger('prover-client:tx-prover'),
44
42
  ) {
45
43
  // TODO(palla/prover-node): Cache the paddingTx here, and not in each proving orchestrator,
46
44
  // so it can be reused across multiple ones and not recomputed every time.
47
45
  this.cacheDir = this.config.cacheDir ? join(this.config.cacheDir, `tx_prover_${this.config.proverId}`) : undefined;
48
46
  }
49
47
 
50
- public createEpochProver(db: MerkleTreeWriteOperations, cache: ProverCache = new InMemoryProverCache()): EpochProver {
48
+ public createEpochProver(cache: ProverCache = new InMemoryProverCache()): EpochProver {
51
49
  return new ProvingOrchestrator(
52
- db,
50
+ this.worldState,
53
51
  new CachingBrokerFacade(this.orchestratorClient, cache),
54
52
  this.telemetry,
55
53
  this.config.proverId,
@@ -104,12 +102,16 @@ export class TxProver implements EpochProverManager {
104
102
  /**
105
103
  * Creates a new prover client and starts it
106
104
  * @param config - The prover configuration.
107
- * @param vks - The verification keys for the prover
108
- * @param worldStateSynchronizer - An instance of the world state
105
+ * @param worldState - An instance of the world state
109
106
  * @returns An instance of the prover, constructed and started.
110
107
  */
111
- public static async new(config: ProverClientConfig, broker: ProvingJobBroker, telemetry: TelemetryClient) {
112
- const prover = new TxProver(config, telemetry, broker, broker);
108
+ public static async new(
109
+ config: ProverClientConfig,
110
+ worldState: ForkMerkleTreeOperations,
111
+ broker: ProvingJobBroker,
112
+ telemetry: TelemetryClient,
113
+ ) {
114
+ const prover = new ProverClient(config, worldState, telemetry, broker, broker);
113
115
  await prover.start();
114
116
  return prover;
115
117
  }
@@ -135,7 +137,15 @@ export class TxProver implements EpochProverManager {
135
137
  const prover = await buildServerCircuitProver(this.config, this.telemetry);
136
138
  this.agents = times(
137
139
  this.config.proverAgentCount,
138
- () => new ProvingAgent(this.agentClient!, proofStore, prover, [], this.config.proverAgentPollIntervalMs),
140
+ () =>
141
+ new ProvingAgent(
142
+ this.agentClient!,
143
+ proofStore,
144
+ prover,
145
+ this.telemetry,
146
+ [],
147
+ this.config.proverAgentPollIntervalMs,
148
+ ),
139
149
  );
140
150
 
141
151
  await Promise.all(this.agents.map(agent => agent.start()));
@@ -33,7 +33,7 @@ import {
33
33
  type TubeInputs,
34
34
  } from '@aztec/circuits.js';
35
35
  import { sha256 } from '@aztec/foundation/crypto';
36
- import { createDebugLogger } from '@aztec/foundation/log';
36
+ import { createLogger } from '@aztec/foundation/log';
37
37
  import { retryUntil } from '@aztec/foundation/retry';
38
38
 
39
39
  import { InlineProofStore, type ProofStore } from './proof_store.js';
@@ -52,13 +52,14 @@ export class CachingBrokerFacade implements ServerCircuitProver {
52
52
  private proofStore: ProofStore = new InlineProofStore(),
53
53
  private waitTimeoutMs = MAX_WAIT_MS,
54
54
  private pollIntervalMs = 1000,
55
- private log = createDebugLogger('aztec:prover-client:caching-prover-broker'),
55
+ private log = createLogger('prover-client:caching-prover-broker'),
56
56
  ) {}
57
57
 
58
58
  private async enqueueAndWaitForJob<T extends ProvingRequestType>(
59
59
  id: ProvingJobId,
60
60
  type: T,
61
61
  inputs: ProvingJobInputsMap[T],
62
+ epochNumber = 0,
62
63
  signal?: AbortSignal,
63
64
  ): Promise<ProvingJobResultsMap[T]> {
64
65
  // first try the cache
@@ -95,6 +96,7 @@ export class CachingBrokerFacade implements ServerCircuitProver {
95
96
  id,
96
97
  type,
97
98
  inputsUri,
99
+ epochNumber,
98
100
  });
99
101
  await this.cache.setProvingJobStatus(id, { status: 'in-queue' });
100
102
  } catch (err) {
@@ -107,7 +109,7 @@ export class CachingBrokerFacade implements ServerCircuitProver {
107
109
  // notify broker of cancelled job
108
110
  const abortFn = async () => {
109
111
  signal?.removeEventListener('abort', abortFn);
110
- await this.broker.removeAndCancelProvingJob(id);
112
+ await this.broker.cancelProvingJob(id);
111
113
  };
112
114
 
113
115
  signal?.addEventListener('abort', abortFn);
@@ -147,18 +149,21 @@ export class CachingBrokerFacade implements ServerCircuitProver {
147
149
  }
148
150
  } finally {
149
151
  signal?.removeEventListener('abort', abortFn);
152
+ // we've saved the result in our cache. We can tell the broker to clear its state
153
+ await this.broker.cleanUpProvingJobState(id);
150
154
  }
151
155
  }
152
156
 
153
157
  getAvmProof(
154
158
  inputs: AvmCircuitInputs,
155
159
  signal?: AbortSignal,
156
- _blockNumber?: number,
160
+ epochNumber?: number,
157
161
  ): Promise<ProofAndVerificationKey<typeof AVM_PROOF_LENGTH_IN_FIELDS>> {
158
162
  return this.enqueueAndWaitForJob(
159
163
  this.generateId(ProvingRequestType.PUBLIC_VM, inputs),
160
164
  ProvingRequestType.PUBLIC_VM,
161
165
  inputs,
166
+ epochNumber,
162
167
  signal,
163
168
  );
164
169
  }
@@ -166,12 +171,13 @@ export class CachingBrokerFacade implements ServerCircuitProver {
166
171
  getBaseParityProof(
167
172
  inputs: BaseParityInputs,
168
173
  signal?: AbortSignal,
169
- _epochNumber?: number,
174
+ epochNumber?: number,
170
175
  ): Promise<PublicInputsAndRecursiveProof<ParityPublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
171
176
  return this.enqueueAndWaitForJob(
172
177
  this.generateId(ProvingRequestType.BASE_PARITY, inputs),
173
178
  ProvingRequestType.BASE_PARITY,
174
179
  inputs,
180
+ epochNumber,
175
181
  signal,
176
182
  );
177
183
  }
@@ -179,12 +185,13 @@ export class CachingBrokerFacade implements ServerCircuitProver {
179
185
  getBlockMergeRollupProof(
180
186
  input: BlockMergeRollupInputs,
181
187
  signal?: AbortSignal,
182
- _epochNumber?: number,
188
+ epochNumber?: number,
183
189
  ): Promise<PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
184
190
  return this.enqueueAndWaitForJob(
185
191
  this.generateId(ProvingRequestType.BLOCK_MERGE_ROLLUP, input),
186
192
  ProvingRequestType.BLOCK_MERGE_ROLLUP,
187
193
  input,
194
+ epochNumber,
188
195
  signal,
189
196
  );
190
197
  }
@@ -192,12 +199,13 @@ export class CachingBrokerFacade implements ServerCircuitProver {
192
199
  getBlockRootRollupProof(
193
200
  input: BlockRootRollupInputs,
194
201
  signal?: AbortSignal,
195
- _epochNumber?: number,
202
+ epochNumber?: number,
196
203
  ): Promise<PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
197
204
  return this.enqueueAndWaitForJob(
198
205
  this.generateId(ProvingRequestType.BLOCK_ROOT_ROLLUP, input),
199
206
  ProvingRequestType.BLOCK_ROOT_ROLLUP,
200
207
  input,
208
+ epochNumber,
201
209
  signal,
202
210
  );
203
211
  }
@@ -205,12 +213,13 @@ export class CachingBrokerFacade implements ServerCircuitProver {
205
213
  getEmptyBlockRootRollupProof(
206
214
  input: EmptyBlockRootRollupInputs,
207
215
  signal?: AbortSignal,
208
- _epochNumber?: number,
216
+ epochNumber?: number,
209
217
  ): Promise<PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs>> {
210
218
  return this.enqueueAndWaitForJob(
211
219
  this.generateId(ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP, input),
212
220
  ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP,
213
221
  input,
222
+ epochNumber,
214
223
  signal,
215
224
  );
216
225
  }
@@ -218,12 +227,13 @@ export class CachingBrokerFacade implements ServerCircuitProver {
218
227
  getEmptyPrivateKernelProof(
219
228
  inputs: PrivateKernelEmptyInputData,
220
229
  signal?: AbortSignal,
221
- _epochNumber?: number,
230
+ epochNumber?: number,
222
231
  ): Promise<PublicInputsAndRecursiveProof<KernelCircuitPublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
223
232
  return this.enqueueAndWaitForJob(
224
233
  this.generateId(ProvingRequestType.PRIVATE_KERNEL_EMPTY, inputs),
225
234
  ProvingRequestType.PRIVATE_KERNEL_EMPTY,
226
235
  inputs,
236
+ epochNumber,
227
237
  signal,
228
238
  );
229
239
  }
@@ -231,24 +241,26 @@ export class CachingBrokerFacade implements ServerCircuitProver {
231
241
  getMergeRollupProof(
232
242
  input: MergeRollupInputs,
233
243
  signal?: AbortSignal,
234
- _epochNumber?: number,
244
+ epochNumber?: number,
235
245
  ): Promise<PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
236
246
  return this.enqueueAndWaitForJob(
237
247
  this.generateId(ProvingRequestType.MERGE_ROLLUP, input),
238
248
  ProvingRequestType.MERGE_ROLLUP,
239
249
  input,
250
+ epochNumber,
240
251
  signal,
241
252
  );
242
253
  }
243
254
  getPrivateBaseRollupProof(
244
255
  baseRollupInput: PrivateBaseRollupInputs,
245
256
  signal?: AbortSignal,
246
- _epochNumber?: number,
257
+ epochNumber?: number,
247
258
  ): Promise<PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
248
259
  return this.enqueueAndWaitForJob(
249
260
  this.generateId(ProvingRequestType.PRIVATE_BASE_ROLLUP, baseRollupInput),
250
261
  ProvingRequestType.PRIVATE_BASE_ROLLUP,
251
262
  baseRollupInput,
263
+ epochNumber,
252
264
  signal,
253
265
  );
254
266
  }
@@ -256,12 +268,13 @@ export class CachingBrokerFacade implements ServerCircuitProver {
256
268
  getPublicBaseRollupProof(
257
269
  inputs: PublicBaseRollupInputs,
258
270
  signal?: AbortSignal,
259
- _epochNumber?: number,
271
+ epochNumber?: number,
260
272
  ): Promise<PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
261
273
  return this.enqueueAndWaitForJob(
262
274
  this.generateId(ProvingRequestType.PUBLIC_BASE_ROLLUP, inputs),
263
275
  ProvingRequestType.PUBLIC_BASE_ROLLUP,
264
276
  inputs,
277
+ epochNumber,
265
278
  signal,
266
279
  );
267
280
  }
@@ -269,12 +282,13 @@ export class CachingBrokerFacade implements ServerCircuitProver {
269
282
  getRootParityProof(
270
283
  inputs: RootParityInputs,
271
284
  signal?: AbortSignal,
272
- _epochNumber?: number,
285
+ epochNumber?: number,
273
286
  ): Promise<PublicInputsAndRecursiveProof<ParityPublicInputs, typeof NESTED_RECURSIVE_PROOF_LENGTH>> {
274
287
  return this.enqueueAndWaitForJob(
275
288
  this.generateId(ProvingRequestType.ROOT_PARITY, inputs),
276
289
  ProvingRequestType.ROOT_PARITY,
277
290
  inputs,
291
+ epochNumber,
278
292
  signal,
279
293
  );
280
294
  }
@@ -282,12 +296,13 @@ export class CachingBrokerFacade implements ServerCircuitProver {
282
296
  getRootRollupProof(
283
297
  input: RootRollupInputs,
284
298
  signal?: AbortSignal,
285
- _epochNumber?: number,
299
+ epochNumber?: number,
286
300
  ): Promise<PublicInputsAndRecursiveProof<RootRollupPublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
287
301
  return this.enqueueAndWaitForJob(
288
302
  this.generateId(ProvingRequestType.ROOT_ROLLUP, input),
289
303
  ProvingRequestType.ROOT_ROLLUP,
290
304
  input,
305
+ epochNumber,
291
306
  signal,
292
307
  );
293
308
  }
@@ -295,12 +310,13 @@ export class CachingBrokerFacade implements ServerCircuitProver {
295
310
  getTubeProof(
296
311
  tubeInput: TubeInputs,
297
312
  signal?: AbortSignal,
298
- _epochNumber?: number,
313
+ epochNumber?: number,
299
314
  ): Promise<ProofAndVerificationKey<typeof TUBE_PROOF_LENGTH>> {
300
315
  return this.enqueueAndWaitForJob(
301
316
  this.generateId(ProvingRequestType.TUBE_PROOF, tubeInput),
302
317
  ProvingRequestType.TUBE_PROOF,
303
318
  tubeInput,
319
+ epochNumber,
304
320
  signal,
305
321
  );
306
322
  }
@@ -1,16 +1,20 @@
1
1
  import { type ProverBrokerConfig } from '@aztec/circuit-types';
2
2
  import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
3
+ import { type TelemetryClient } from '@aztec/telemetry-client';
3
4
 
4
5
  import { ProvingBroker } from './proving_broker.js';
5
6
  import { InMemoryBrokerDatabase } from './proving_broker_database/memory.js';
6
7
  import { KVBrokerDatabase } from './proving_broker_database/persisted.js';
7
8
 
8
- export async function createAndStartProvingBroker(config: ProverBrokerConfig): Promise<ProvingBroker> {
9
+ export async function createAndStartProvingBroker(
10
+ config: ProverBrokerConfig,
11
+ client: TelemetryClient,
12
+ ): Promise<ProvingBroker> {
9
13
  const database = config.proverBrokerDataDirectory
10
- ? new KVBrokerDatabase(AztecLmdbStore.open(config.proverBrokerDataDirectory))
14
+ ? new KVBrokerDatabase(AztecLmdbStore.open(config.proverBrokerDataDirectory), client)
11
15
  : new InMemoryBrokerDatabase();
12
16
 
13
- const broker = new ProvingBroker(database, {
17
+ const broker = new ProvingBroker(database, client, {
14
18
  jobTimeoutMs: config.proverBrokerJobTimeoutMs,
15
19
  maxRetries: config.proverBrokerJobMaxRetries,
16
20
  timeoutIntervalMs: config.proverBrokerPollIntervalMs,
@@ -8,10 +8,13 @@ import {
8
8
  ProvingRequestType,
9
9
  type ServerCircuitProver,
10
10
  } from '@aztec/circuit-types';
11
- import { createDebugLogger } from '@aztec/foundation/log';
11
+ import { createLogger } from '@aztec/foundation/log';
12
12
  import { RunningPromise } from '@aztec/foundation/running-promise';
13
+ import { Timer } from '@aztec/foundation/timer';
14
+ import { type TelemetryClient } from '@aztec/telemetry-client';
13
15
 
14
16
  import { type ProofStore } from './proof_store.js';
17
+ import { ProvingAgentInstrumentation } from './proving_agent_instrumentation.js';
15
18
  import { ProvingJobController, ProvingJobControllerStatus } from './proving_job_controller.js';
16
19
 
17
20
  /**
@@ -20,6 +23,8 @@ import { ProvingJobController, ProvingJobControllerStatus } from './proving_job_
20
23
  export class ProvingAgent {
21
24
  private currentJobController?: ProvingJobController;
22
25
  private runningPromise: RunningPromise;
26
+ private instrumentation: ProvingAgentInstrumentation;
27
+ private idleTimer: Timer | undefined;
23
28
 
24
29
  constructor(
25
30
  /** The source of proving jobs */
@@ -28,12 +33,15 @@ export class ProvingAgent {
28
33
  private proofStore: ProofStore,
29
34
  /** The prover implementation to defer jobs to */
30
35
  private circuitProver: ServerCircuitProver,
36
+ /** A telemetry client through which to emit metrics */
37
+ client: TelemetryClient,
31
38
  /** Optional list of allowed proof types to build */
32
39
  private proofAllowList: Array<ProvingRequestType> = [],
33
40
  /** How long to wait between jobs */
34
41
  private pollIntervalMs = 1000,
35
- private log = createDebugLogger('aztec:prover-client:proving-agent'),
42
+ private log = createLogger('prover-client:proving-agent'),
36
43
  ) {
44
+ this.instrumentation = new ProvingAgentInstrumentation(client);
37
45
  this.runningPromise = new RunningPromise(this.safeWork, this.pollIntervalMs);
38
46
  }
39
47
 
@@ -46,6 +54,7 @@ export class ProvingAgent {
46
54
  }
47
55
 
48
56
  public start(): void {
57
+ this.idleTimer = new Timer();
49
58
  this.runningPromise.start();
50
59
  }
51
60
 
@@ -114,6 +123,11 @@ export class ProvingAgent {
114
123
  );
115
124
  }
116
125
 
126
+ if (this.idleTimer) {
127
+ this.instrumentation.recordIdleTime(this.idleTimer);
128
+ }
129
+ this.idleTimer = undefined;
130
+
117
131
  this.currentJobController.start();
118
132
  } catch (err) {
119
133
  this.log.error(`Error in ProvingAgent: ${String(err)}`);
@@ -126,9 +140,10 @@ export class ProvingAgent {
126
140
  err: Error | undefined,
127
141
  result: ProvingJobResultsMap[T] | undefined,
128
142
  ) => {
143
+ this.idleTimer = new Timer();
129
144
  if (err) {
130
145
  const retry = err.name === ProvingError.NAME ? (err as ProvingError).retry : false;
131
- this.log.info(`Job id=${jobId} type=${ProvingRequestType[type]} failed err=${err.message} retry=${retry}`);
146
+ this.log.error(`Job id=${jobId} type=${ProvingRequestType[type]} failed err=${err.message} retry=${retry}`, err);
132
147
  return this.broker.reportProvingJobError(jobId, err.message, retry);
133
148
  } else if (result) {
134
149
  const outputUri = await this.proofStore.saveProofOutput(jobId, type, result);
@@ -0,0 +1,21 @@
1
+ import { type Timer } from '@aztec/foundation/timer';
2
+ import { type Histogram, Metrics, type TelemetryClient, ValueType } from '@aztec/telemetry-client';
3
+
4
+ export class ProvingAgentInstrumentation {
5
+ private idleTime: Histogram;
6
+
7
+ constructor(client: TelemetryClient, name = 'ProvingAgent') {
8
+ const meter = client.getMeter(name);
9
+
10
+ this.idleTime = meter.createHistogram(Metrics.PROVING_AGENT_IDLE, {
11
+ description: 'Records how long an agent was idle',
12
+ unit: 'ms',
13
+ valueType: ValueType.INT,
14
+ });
15
+ }
16
+
17
+ recordIdleTime(msOrTimer: Timer | number) {
18
+ const duration = typeof msOrTimer === 'number' ? msOrTimer : Math.floor(msOrTimer.ms());
19
+ this.idleTime.record(duration);
20
+ }
21
+ }