@aztec/prover-client 0.65.1 → 0.65.2

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/config.d.ts +4 -10
  2. package/dest/config.d.ts.map +1 -1
  3. package/dest/config.js +8 -7
  4. package/dest/index.d.ts +1 -0
  5. package/dest/index.d.ts.map +1 -1
  6. package/dest/index.js +2 -1
  7. package/dest/mocks/test_context.js +3 -2
  8. package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
  9. package/dest/orchestrator/block-building-helpers.js +10 -18
  10. package/dest/orchestrator/block-proving-state.js +2 -2
  11. package/dest/prover-agent/memory-proving-queue.d.ts +10 -8
  12. package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
  13. package/dest/prover-agent/memory-proving-queue.js +35 -35
  14. package/dest/prover-agent/prover-agent.d.ts +1 -0
  15. package/dest/prover-agent/prover-agent.d.ts.map +1 -1
  16. package/dest/prover-agent/prover-agent.js +12 -9
  17. package/dest/proving_broker/caching_broker_facade.d.ts +30 -0
  18. package/dest/proving_broker/caching_broker_facade.d.ts.map +1 -0
  19. package/dest/proving_broker/caching_broker_facade.js +150 -0
  20. package/dest/proving_broker/factory.d.ts +4 -0
  21. package/dest/proving_broker/factory.d.ts.map +1 -0
  22. package/dest/proving_broker/factory.js +17 -0
  23. package/dest/proving_broker/index.d.ts +9 -0
  24. package/dest/proving_broker/index.d.ts.map +1 -0
  25. package/dest/proving_broker/index.js +9 -0
  26. package/dest/proving_broker/proof_store.d.ts +46 -0
  27. package/dest/proving_broker/proof_store.d.ts.map +1 -0
  28. package/dest/proving_broker/proof_store.js +37 -0
  29. package/dest/proving_broker/prover_cache/memory.d.ts +9 -0
  30. package/dest/proving_broker/prover_cache/memory.d.ts.map +1 -0
  31. package/dest/proving_broker/prover_cache/memory.js +16 -0
  32. package/dest/proving_broker/proving_agent.d.ts +11 -6
  33. package/dest/proving_broker/proving_agent.d.ts.map +1 -1
  34. package/dest/proving_broker/proving_agent.js +48 -20
  35. package/dest/proving_broker/proving_broker.d.ts +17 -16
  36. package/dest/proving_broker/proving_broker.d.ts.map +1 -1
  37. package/dest/proving_broker/proving_broker.js +44 -23
  38. package/dest/proving_broker/proving_broker_database/memory.d.ts +14 -0
  39. package/dest/proving_broker/proving_broker_database/memory.d.ts.map +1 -0
  40. package/dest/proving_broker/proving_broker_database/memory.js +35 -0
  41. package/dest/proving_broker/proving_broker_database/persisted.d.ts +15 -0
  42. package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -0
  43. package/dest/proving_broker/proving_broker_database/persisted.js +35 -0
  44. package/dest/proving_broker/{proving_job_database.d.ts → proving_broker_database.d.ts} +8 -8
  45. package/dest/proving_broker/proving_broker_database.d.ts.map +1 -0
  46. package/dest/proving_broker/proving_broker_database.js +2 -0
  47. package/dest/proving_broker/proving_job_controller.d.ts +13 -8
  48. package/dest/proving_broker/proving_job_controller.d.ts.map +1 -1
  49. package/dest/proving_broker/proving_job_controller.js +43 -43
  50. package/dest/proving_broker/rpc.d.ts +11 -0
  51. package/dest/proving_broker/rpc.d.ts.map +1 -0
  52. package/dest/proving_broker/rpc.js +44 -0
  53. package/dest/test/mock_prover.d.ts +15 -1
  54. package/dest/test/mock_prover.d.ts.map +1 -1
  55. package/dest/test/mock_prover.js +36 -1
  56. package/dest/tx-prover/factory.d.ts +2 -1
  57. package/dest/tx-prover/factory.d.ts.map +1 -1
  58. package/dest/tx-prover/factory.js +3 -3
  59. package/dest/tx-prover/tx-prover.d.ts +13 -7
  60. package/dest/tx-prover/tx-prover.d.ts.map +1 -1
  61. package/dest/tx-prover/tx-prover.js +52 -35
  62. package/package.json +14 -12
  63. package/src/config.ts +17 -16
  64. package/src/index.ts +1 -0
  65. package/src/mocks/test_context.ts +2 -2
  66. package/src/orchestrator/block-building-helpers.ts +22 -33
  67. package/src/orchestrator/block-proving-state.ts +1 -1
  68. package/src/prover-agent/memory-proving-queue.ts +43 -44
  69. package/src/prover-agent/prover-agent.ts +16 -20
  70. package/src/proving_broker/caching_broker_facade.ts +312 -0
  71. package/src/proving_broker/factory.ts +21 -0
  72. package/src/proving_broker/index.ts +8 -0
  73. package/src/proving_broker/proof_store.ts +106 -0
  74. package/src/proving_broker/prover_cache/memory.ts +20 -0
  75. package/src/proving_broker/proving_agent.ts +75 -20
  76. package/src/proving_broker/proving_broker.ts +98 -65
  77. package/src/proving_broker/proving_broker_database/memory.ts +43 -0
  78. package/src/proving_broker/proving_broker_database/persisted.ts +45 -0
  79. package/src/proving_broker/{proving_job_database.ts → proving_broker_database.ts} +7 -12
  80. package/src/proving_broker/proving_job_controller.ts +54 -46
  81. package/src/proving_broker/rpc.ts +64 -0
  82. package/src/test/mock_prover.ts +51 -0
  83. package/src/tx-prover/factory.ts +7 -2
  84. package/src/tx-prover/tx-prover.ts +78 -46
  85. package/dest/proving_broker/proving_broker_interface.d.ts +0 -61
  86. package/dest/proving_broker/proving_broker_interface.d.ts.map +0 -1
  87. package/dest/proving_broker/proving_broker_interface.js +0 -2
  88. package/dest/proving_broker/proving_job_database/memory.d.ts +0 -14
  89. package/dest/proving_broker/proving_job_database/memory.d.ts.map +0 -1
  90. package/dest/proving_broker/proving_job_database/memory.js +0 -35
  91. package/dest/proving_broker/proving_job_database/persisted.d.ts +0 -15
  92. package/dest/proving_broker/proving_job_database/persisted.d.ts.map +0 -1
  93. package/dest/proving_broker/proving_job_database/persisted.js +0 -35
  94. package/dest/proving_broker/proving_job_database.d.ts.map +0 -1
  95. package/dest/proving_broker/proving_job_database.js +0 -2
  96. package/src/proving_broker/proving_broker_interface.ts +0 -74
  97. package/src/proving_broker/proving_job_database/memory.ts +0 -43
  98. package/src/proving_broker/proving_job_database/persisted.ts +0 -45
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  type ProverAgentApi,
3
3
  type ProvingJob,
4
+ type ProvingJobInputs,
5
+ type ProvingJobResultsMap,
4
6
  type ProvingJobSource,
5
- type ProvingRequest,
6
- type ProvingRequestResultFor,
7
7
  ProvingRequestType,
8
8
  type ServerCircuitProver,
9
9
  makeProvingRequestResult,
@@ -12,6 +12,8 @@ import { createDebugLogger } from '@aztec/foundation/log';
12
12
  import { RunningPromise } from '@aztec/foundation/running-promise';
13
13
  import { elapsed } from '@aztec/foundation/timer';
14
14
 
15
+ import { InlineProofStore } from '../proving_broker/proof_store.js';
16
+
15
17
  const PRINT_THRESHOLD_NS = 6e10; // 60 seconds
16
18
 
17
19
  /**
@@ -27,6 +29,7 @@ export class ProverAgent implements ProverAgentApi {
27
29
  }
28
30
  >();
29
31
  private runningPromise?: RunningPromise;
32
+ private proofInputsDatabase = new InlineProofStore();
30
33
 
31
34
  constructor(
32
35
  /** The prover implementation to defer jobs to */
@@ -101,12 +104,12 @@ export class ProverAgent implements ProverAgentApi {
101
104
  const promise = this.work(jobSource, job).finally(() => this.inFlightPromises.delete(job.id));
102
105
  this.inFlightPromises.set(job.id, {
103
106
  id: job.id,
104
- type: job.request.type,
107
+ type: job.type,
105
108
  promise,
106
109
  });
107
110
  } catch (err) {
108
111
  this.log.warn(
109
- `Error processing job! type=${ProvingRequestType[job.request.type]}: ${err}. ${(err as Error).stack}`,
112
+ `Error processing job! type=${ProvingRequestType[job.type]}: ${err}. ${(err as Error).stack}`,
110
113
  );
111
114
  }
112
115
  } catch (err) {
@@ -130,28 +133,24 @@ export class ProverAgent implements ProverAgentApi {
130
133
  this.log.info('Agent stopped');
131
134
  }
132
135
 
133
- private async work<TRequest extends ProvingRequest>(
134
- jobSource: ProvingJobSource,
135
- job: ProvingJob<TRequest>,
136
- ): Promise<void> {
136
+ private async work(jobSource: ProvingJobSource, job: ProvingJob): Promise<void> {
137
137
  try {
138
- this.log.debug(`Picked up proving job id=${job.id} type=${ProvingRequestType[job.request.type]}`);
139
- const type: TRequest['type'] = job.request.type;
140
- const [time, result] = await elapsed(this.getProof(job.request));
138
+ this.log.debug(`Picked up proving job id=${job.id} type=${ProvingRequestType[job.type]}`);
139
+ const type = job.type;
140
+ const inputs = await this.proofInputsDatabase.getProofInput(job.inputsUri);
141
+ const [time, result] = await elapsed(this.getProof(inputs));
141
142
  if (this.#isRunning()) {
142
143
  this.log.verbose(`Processed proving job id=${job.id} type=${ProvingRequestType[type]} duration=${time}ms`);
143
144
  await jobSource.resolveProvingJob(job.id, makeProvingRequestResult(type, result));
144
145
  } else {
145
146
  this.log.verbose(
146
- `Dropping proving job id=${job.id} type=${
147
- ProvingRequestType[job.request.type]
148
- } duration=${time}ms: agent stopped`,
147
+ `Dropping proving job id=${job.id} type=${ProvingRequestType[job.type]} duration=${time}ms: agent stopped`,
149
148
  );
150
149
  }
151
150
  } catch (err) {
152
- const type = ProvingRequestType[job.request.type];
151
+ const type = ProvingRequestType[job.type];
153
152
  if (this.#isRunning()) {
154
- if (job.request.type === ProvingRequestType.PUBLIC_VM && !process.env.AVM_PROVING_STRICT) {
153
+ if (job.type === ProvingRequestType.PUBLIC_VM && !process.env.AVM_PROVING_STRICT) {
155
154
  this.log.warn(`Expected error processing VM proving job id=${job.id} type=${type}: ${err}`);
156
155
  } else {
157
156
  this.log.error(`Error processing proving job id=${job.id} type=${type}: ${err}`, err);
@@ -164,10 +163,7 @@ export class ProverAgent implements ProverAgentApi {
164
163
  }
165
164
  }
166
165
 
167
- private getProof<TRequest extends ProvingRequest>(
168
- request: TRequest,
169
- ): Promise<ProvingRequestResultFor<TRequest['type']>['result']>;
170
- private getProof(request: ProvingRequest): Promise<ProvingRequestResultFor<typeof type>['result']> {
166
+ private getProof(request: ProvingJobInputs): Promise<ProvingJobResultsMap[ProvingRequestType]> {
171
167
  const { type, inputs } = request;
172
168
  switch (type) {
173
169
  case ProvingRequestType.PUBLIC_VM: {
@@ -0,0 +1,312 @@
1
+ import {
2
+ type ProofAndVerificationKey,
3
+ type ProverCache,
4
+ type ProvingJobId,
5
+ type ProvingJobInputsMap,
6
+ type ProvingJobProducer,
7
+ type ProvingJobResultsMap,
8
+ ProvingRequestType,
9
+ type PublicInputsAndRecursiveProof,
10
+ type ServerCircuitProver,
11
+ } from '@aztec/circuit-types';
12
+ import {
13
+ type AVM_PROOF_LENGTH_IN_FIELDS,
14
+ type AvmCircuitInputs,
15
+ type BaseOrMergeRollupPublicInputs,
16
+ type BaseParityInputs,
17
+ type BlockMergeRollupInputs,
18
+ type BlockRootOrBlockMergePublicInputs,
19
+ type BlockRootRollupInputs,
20
+ type EmptyBlockRootRollupInputs,
21
+ type KernelCircuitPublicInputs,
22
+ type MergeRollupInputs,
23
+ type NESTED_RECURSIVE_PROOF_LENGTH,
24
+ type ParityPublicInputs,
25
+ type PrivateBaseRollupInputs,
26
+ type PrivateKernelEmptyInputData,
27
+ type PublicBaseRollupInputs,
28
+ type RECURSIVE_PROOF_LENGTH,
29
+ type RootParityInputs,
30
+ type RootRollupInputs,
31
+ type RootRollupPublicInputs,
32
+ type TUBE_PROOF_LENGTH,
33
+ type TubeInputs,
34
+ } from '@aztec/circuits.js';
35
+ import { sha256 } from '@aztec/foundation/crypto';
36
+ import { createDebugLogger } from '@aztec/foundation/log';
37
+ import { retryUntil } from '@aztec/foundation/retry';
38
+
39
+ import { InlineProofStore, type ProofStore } from './proof_store.js';
40
+ import { InMemoryProverCache } from './prover_cache/memory.js';
41
+
42
+ // 20 minutes, roughly the length of an Aztec epoch. If a proof isn't ready in this amount of time then we've failed to prove the whole epoch
43
+ const MAX_WAIT_MS = 1_200_000;
44
+
45
+ /**
46
+ * A facade around a job broker that generates stable job ids and caches results
47
+ */
48
+ export class CachingBrokerFacade implements ServerCircuitProver {
49
+ constructor(
50
+ private broker: ProvingJobProducer,
51
+ private cache: ProverCache = new InMemoryProverCache(),
52
+ private proofStore: ProofStore = new InlineProofStore(),
53
+ private waitTimeoutMs = MAX_WAIT_MS,
54
+ private pollIntervalMs = 1000,
55
+ private log = createDebugLogger('aztec:prover-client:caching-prover-broker'),
56
+ ) {}
57
+
58
+ private async enqueueAndWaitForJob<T extends ProvingRequestType>(
59
+ id: ProvingJobId,
60
+ type: T,
61
+ inputs: ProvingJobInputsMap[T],
62
+ signal?: AbortSignal,
63
+ ): Promise<ProvingJobResultsMap[T]> {
64
+ // first try the cache
65
+ let jobEnqueued = false;
66
+ try {
67
+ const cachedResult = await this.cache.getProvingJobStatus(id);
68
+ if (cachedResult.status !== 'not-found') {
69
+ this.log.debug(`Found cached result for job=${id}: status=${cachedResult.status}`);
70
+ }
71
+
72
+ if (cachedResult.status === 'fulfilled') {
73
+ const output = await this.proofStore.getProofOutput(cachedResult.value);
74
+ if (output.type === type) {
75
+ return output.result as ProvingJobResultsMap[T];
76
+ } else {
77
+ this.log.warn(`Cached result type mismatch for job=${id}. Expected=${type} but got=${output.type}`);
78
+ }
79
+ } else if (cachedResult.status === 'rejected') {
80
+ // prefer returning a rejected promises so that we don't trigger the catch block below
81
+ return Promise.reject(new Error(cachedResult.reason));
82
+ } else if (cachedResult.status === 'in-progress' || cachedResult.status === 'in-queue') {
83
+ jobEnqueued = true;
84
+ } else {
85
+ jobEnqueued = false;
86
+ }
87
+ } catch (err) {
88
+ this.log.warn(`Failed to get cached proving job id=${id}: ${err}. Re-running job`);
89
+ }
90
+
91
+ if (!jobEnqueued) {
92
+ try {
93
+ const inputsUri = await this.proofStore.saveProofInput(id, type, inputs);
94
+ await this.broker.enqueueProvingJob({
95
+ id,
96
+ type,
97
+ inputsUri,
98
+ });
99
+ await this.cache.setProvingJobStatus(id, { status: 'in-queue' });
100
+ } catch (err) {
101
+ this.log.error(`Failed to enqueue proving job id=${id}: ${err}`);
102
+ await this.cache.setProvingJobStatus(id, { status: 'not-found' });
103
+ throw err;
104
+ }
105
+ }
106
+
107
+ // notify broker of cancelled job
108
+ const abortFn = async () => {
109
+ signal?.removeEventListener('abort', abortFn);
110
+ await this.broker.removeAndCancelProvingJob(id);
111
+ };
112
+
113
+ signal?.addEventListener('abort', abortFn);
114
+
115
+ try {
116
+ // loop here until the job settles
117
+ // NOTE: this could also terminate because the job was cancelled through event listener above
118
+ const result = await retryUntil(
119
+ async () => {
120
+ try {
121
+ return await this.broker.waitForJobToSettle(id);
122
+ } catch (err) {
123
+ // waitForJobToSettle can only fail for network errors
124
+ // keep retrying until we time out
125
+ }
126
+ },
127
+ `Proving job=${id} type=${ProvingRequestType[type]}`,
128
+ this.waitTimeoutMs / 1000,
129
+ this.pollIntervalMs / 1000,
130
+ );
131
+
132
+ try {
133
+ await this.cache.setProvingJobStatus(id, result);
134
+ } catch (err) {
135
+ this.log.warn(`Failed to cache proving job id=${id} resultStatus=${result.status}: ${err}`);
136
+ }
137
+
138
+ if (result.status === 'fulfilled') {
139
+ const output = await this.proofStore.getProofOutput(result.value);
140
+ if (output.type === type) {
141
+ return output.result as ProvingJobResultsMap[T];
142
+ } else {
143
+ return Promise.reject(new Error(`Unexpected proof type: ${output.type}. Expected: ${type}`));
144
+ }
145
+ } else {
146
+ return Promise.reject(new Error(result.reason));
147
+ }
148
+ } finally {
149
+ signal?.removeEventListener('abort', abortFn);
150
+ }
151
+ }
152
+
153
+ getAvmProof(
154
+ inputs: AvmCircuitInputs,
155
+ signal?: AbortSignal,
156
+ _blockNumber?: number,
157
+ ): Promise<ProofAndVerificationKey<typeof AVM_PROOF_LENGTH_IN_FIELDS>> {
158
+ return this.enqueueAndWaitForJob(
159
+ this.generateId(ProvingRequestType.PUBLIC_VM, inputs),
160
+ ProvingRequestType.PUBLIC_VM,
161
+ inputs,
162
+ signal,
163
+ );
164
+ }
165
+
166
+ getBaseParityProof(
167
+ inputs: BaseParityInputs,
168
+ signal?: AbortSignal,
169
+ _epochNumber?: number,
170
+ ): Promise<PublicInputsAndRecursiveProof<ParityPublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
171
+ return this.enqueueAndWaitForJob(
172
+ this.generateId(ProvingRequestType.BASE_PARITY, inputs),
173
+ ProvingRequestType.BASE_PARITY,
174
+ inputs,
175
+ signal,
176
+ );
177
+ }
178
+
179
+ getBlockMergeRollupProof(
180
+ input: BlockMergeRollupInputs,
181
+ signal?: AbortSignal,
182
+ _epochNumber?: number,
183
+ ): Promise<PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
184
+ return this.enqueueAndWaitForJob(
185
+ this.generateId(ProvingRequestType.BLOCK_MERGE_ROLLUP, input),
186
+ ProvingRequestType.BLOCK_MERGE_ROLLUP,
187
+ input,
188
+ signal,
189
+ );
190
+ }
191
+
192
+ getBlockRootRollupProof(
193
+ input: BlockRootRollupInputs,
194
+ signal?: AbortSignal,
195
+ _epochNumber?: number,
196
+ ): Promise<PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
197
+ return this.enqueueAndWaitForJob(
198
+ this.generateId(ProvingRequestType.BLOCK_ROOT_ROLLUP, input),
199
+ ProvingRequestType.BLOCK_ROOT_ROLLUP,
200
+ input,
201
+ signal,
202
+ );
203
+ }
204
+
205
+ getEmptyBlockRootRollupProof(
206
+ input: EmptyBlockRootRollupInputs,
207
+ signal?: AbortSignal,
208
+ _epochNumber?: number,
209
+ ): Promise<PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs>> {
210
+ return this.enqueueAndWaitForJob(
211
+ this.generateId(ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP, input),
212
+ ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP,
213
+ input,
214
+ signal,
215
+ );
216
+ }
217
+
218
+ getEmptyPrivateKernelProof(
219
+ inputs: PrivateKernelEmptyInputData,
220
+ signal?: AbortSignal,
221
+ _epochNumber?: number,
222
+ ): Promise<PublicInputsAndRecursiveProof<KernelCircuitPublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
223
+ return this.enqueueAndWaitForJob(
224
+ this.generateId(ProvingRequestType.PRIVATE_KERNEL_EMPTY, inputs),
225
+ ProvingRequestType.PRIVATE_KERNEL_EMPTY,
226
+ inputs,
227
+ signal,
228
+ );
229
+ }
230
+
231
+ getMergeRollupProof(
232
+ input: MergeRollupInputs,
233
+ signal?: AbortSignal,
234
+ _epochNumber?: number,
235
+ ): Promise<PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
236
+ return this.enqueueAndWaitForJob(
237
+ this.generateId(ProvingRequestType.MERGE_ROLLUP, input),
238
+ ProvingRequestType.MERGE_ROLLUP,
239
+ input,
240
+ signal,
241
+ );
242
+ }
243
+ getPrivateBaseRollupProof(
244
+ baseRollupInput: PrivateBaseRollupInputs,
245
+ signal?: AbortSignal,
246
+ _epochNumber?: number,
247
+ ): Promise<PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
248
+ return this.enqueueAndWaitForJob(
249
+ this.generateId(ProvingRequestType.PRIVATE_BASE_ROLLUP, baseRollupInput),
250
+ ProvingRequestType.PRIVATE_BASE_ROLLUP,
251
+ baseRollupInput,
252
+ signal,
253
+ );
254
+ }
255
+
256
+ getPublicBaseRollupProof(
257
+ inputs: PublicBaseRollupInputs,
258
+ signal?: AbortSignal,
259
+ _epochNumber?: number,
260
+ ): Promise<PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
261
+ return this.enqueueAndWaitForJob(
262
+ this.generateId(ProvingRequestType.PUBLIC_BASE_ROLLUP, inputs),
263
+ ProvingRequestType.PUBLIC_BASE_ROLLUP,
264
+ inputs,
265
+ signal,
266
+ );
267
+ }
268
+
269
+ getRootParityProof(
270
+ inputs: RootParityInputs,
271
+ signal?: AbortSignal,
272
+ _epochNumber?: number,
273
+ ): Promise<PublicInputsAndRecursiveProof<ParityPublicInputs, typeof NESTED_RECURSIVE_PROOF_LENGTH>> {
274
+ return this.enqueueAndWaitForJob(
275
+ this.generateId(ProvingRequestType.ROOT_PARITY, inputs),
276
+ ProvingRequestType.ROOT_PARITY,
277
+ inputs,
278
+ signal,
279
+ );
280
+ }
281
+
282
+ getRootRollupProof(
283
+ input: RootRollupInputs,
284
+ signal?: AbortSignal,
285
+ _epochNumber?: number,
286
+ ): Promise<PublicInputsAndRecursiveProof<RootRollupPublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
287
+ return this.enqueueAndWaitForJob(
288
+ this.generateId(ProvingRequestType.ROOT_ROLLUP, input),
289
+ ProvingRequestType.ROOT_ROLLUP,
290
+ input,
291
+ signal,
292
+ );
293
+ }
294
+
295
+ getTubeProof(
296
+ tubeInput: TubeInputs,
297
+ signal?: AbortSignal,
298
+ _epochNumber?: number,
299
+ ): Promise<ProofAndVerificationKey<typeof TUBE_PROOF_LENGTH>> {
300
+ return this.enqueueAndWaitForJob(
301
+ this.generateId(ProvingRequestType.TUBE_PROOF, tubeInput),
302
+ ProvingRequestType.TUBE_PROOF,
303
+ tubeInput,
304
+ signal,
305
+ );
306
+ }
307
+
308
+ private generateId(type: ProvingRequestType, inputs: { toBuffer(): Buffer }) {
309
+ const inputsHash = sha256(inputs.toBuffer());
310
+ return `${ProvingRequestType[type]}:${inputsHash.toString('hex')}`;
311
+ }
312
+ }
@@ -0,0 +1,21 @@
1
+ import { type ProverBrokerConfig } from '@aztec/circuit-types';
2
+ import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
3
+
4
+ import { ProvingBroker } from './proving_broker.js';
5
+ import { InMemoryBrokerDatabase } from './proving_broker_database/memory.js';
6
+ import { KVBrokerDatabase } from './proving_broker_database/persisted.js';
7
+
8
+ export async function createAndStartProvingBroker(config: ProverBrokerConfig): Promise<ProvingBroker> {
9
+ const database = config.proverBrokerDataDirectory
10
+ ? new KVBrokerDatabase(AztecLmdbStore.open(config.proverBrokerDataDirectory))
11
+ : new InMemoryBrokerDatabase();
12
+
13
+ const broker = new ProvingBroker(database, {
14
+ jobTimeoutMs: config.proverBrokerJobTimeoutMs,
15
+ maxRetries: config.proverBrokerJobMaxRetries,
16
+ timeoutIntervalMs: config.proverBrokerPollIntervalMs,
17
+ });
18
+
19
+ await broker.start();
20
+ return broker;
21
+ }
@@ -0,0 +1,8 @@
1
+ export * from './proving_agent.js';
2
+ export * from './proving_broker.js';
3
+ export * from './rpc.js';
4
+ export * from './proving_broker_database.js';
5
+ export * from './proving_broker_database/memory.js';
6
+ export * from './proving_broker_database/persisted.js';
7
+ export * from './proof_store.js';
8
+ export * from './factory.js';
@@ -0,0 +1,106 @@
1
+ import {
2
+ type ProofUri,
3
+ type ProvingJobId,
4
+ ProvingJobInputs,
5
+ type ProvingJobInputsMap,
6
+ ProvingJobResult,
7
+ type ProvingJobResultsMap,
8
+ type ProvingRequestType,
9
+ } from '@aztec/circuit-types';
10
+ import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
11
+ import { type ZodFor } from '@aztec/foundation/schemas';
12
+
13
+ /**
14
+ * A database for storing proof inputs and outputs.
15
+ */
16
+ export interface ProofStore {
17
+ /**
18
+ * Save a proof input to the database.
19
+ * @param jobId - The ID of the job the proof input is associated with.
20
+ * @param type - The type of the proving request.
21
+ * @param inputs - The proof input to save.
22
+ * @returns The URI of the saved proof input.
23
+ */
24
+ saveProofInput<T extends ProvingRequestType>(
25
+ jobId: ProvingJobId,
26
+ type: T,
27
+ inputs: ProvingJobInputsMap[T],
28
+ ): Promise<ProofUri>;
29
+
30
+ /**
31
+ * Save a proof output to the database.
32
+ * @param jobId - The ID of the job the proof input is associated with.
33
+ * @param type - The type of the proving request.
34
+ * @param result - The proof output to save.
35
+ * @returns The URI of the saved proof output.
36
+ */
37
+ saveProofOutput<T extends ProvingRequestType>(
38
+ id: ProvingJobId,
39
+ type: T,
40
+ result: ProvingJobResultsMap[T],
41
+ ): Promise<ProofUri>;
42
+
43
+ /**
44
+ * Retrieve a proof input from the database.
45
+ * @param uri - The URI of the proof input to retrieve.
46
+ * @returns The proof input.
47
+ */
48
+ getProofInput(uri: ProofUri): Promise<ProvingJobInputs>;
49
+
50
+ /**
51
+ * Retrieve a proof output from the database.
52
+ * @param uri - The URI of the proof output to retrieve.
53
+ * @returns The proof output.
54
+ */
55
+ getProofOutput(uri: ProofUri): Promise<ProvingJobResult>;
56
+ }
57
+
58
+ // use an ASCII encoded data uri https://datatracker.ietf.org/doc/html/rfc2397#section-2
59
+ // we do this to avoid double encoding to base64 (since the inputs already serialize to a base64 string)
60
+ const PREFIX = 'data:application/json;charset=utf-8';
61
+ const SEPARATOR = ',';
62
+
63
+ /**
64
+ * An implementation of a proof input/output database that stores data inline in the URI.
65
+ */
66
+ export class InlineProofStore implements ProofStore {
67
+ saveProofInput<T extends ProvingRequestType>(
68
+ _id: ProvingJobId,
69
+ type: T,
70
+ inputs: ProvingJobInputsMap[T],
71
+ ): Promise<ProofUri> {
72
+ const jobInputs = { type, inputs } as ProvingJobInputs;
73
+ return Promise.resolve(this.encode(jobInputs));
74
+ }
75
+
76
+ saveProofOutput<T extends ProvingRequestType>(
77
+ _id: ProvingJobId,
78
+ type: T,
79
+ result: ProvingJobResultsMap[T],
80
+ ): Promise<ProofUri> {
81
+ const jobResult = { type, result } as ProvingJobResult;
82
+ return Promise.resolve(this.encode(jobResult));
83
+ }
84
+
85
+ getProofInput(uri: ProofUri): Promise<ProvingJobInputs> {
86
+ return Promise.resolve(this.decode(uri, ProvingJobInputs));
87
+ }
88
+
89
+ getProofOutput(uri: ProofUri): Promise<ProvingJobResult> {
90
+ return Promise.resolve(this.decode(uri, ProvingJobResult));
91
+ }
92
+
93
+ private encode(obj: object): ProofUri {
94
+ const encoded = encodeURIComponent(jsonStringify(obj));
95
+ return (PREFIX + SEPARATOR + encoded) as ProofUri;
96
+ }
97
+
98
+ private decode<T>(uri: ProofUri, schema: ZodFor<T>): T {
99
+ const [prefix, data] = uri.split(SEPARATOR);
100
+ if (prefix !== PREFIX) {
101
+ throw new Error('Invalid proof input URI: ' + prefix);
102
+ }
103
+
104
+ return jsonParseWithSchema(decodeURIComponent(data), schema);
105
+ }
106
+ }
@@ -0,0 +1,20 @@
1
+ import type { ProverCache, ProvingJobStatus } from '@aztec/circuit-types';
2
+
3
+ export class InMemoryProverCache implements ProverCache {
4
+ private proofs: Record<string, ProvingJobStatus> = {};
5
+
6
+ constructor() {}
7
+
8
+ setProvingJobStatus(jobId: string, status: ProvingJobStatus): Promise<void> {
9
+ this.proofs[jobId] = status;
10
+ return Promise.resolve();
11
+ }
12
+
13
+ getProvingJobStatus(jobId: string): Promise<ProvingJobStatus> {
14
+ return Promise.resolve(this.proofs[jobId] ?? { status: 'not-found' });
15
+ }
16
+
17
+ close(): Promise<void> {
18
+ return Promise.resolve();
19
+ }
20
+ }