@aztec/prover-client 0.69.1 → 0.71.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.
- package/dest/bin/get-proof-inputs.d.ts +2 -0
- package/dest/bin/get-proof-inputs.d.ts.map +1 -0
- package/dest/bin/get-proof-inputs.js +50 -0
- package/dest/block_builder/light.d.ts +3 -5
- package/dest/block_builder/light.d.ts.map +1 -1
- package/dest/block_builder/light.js +9 -22
- package/dest/config.d.ts +2 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +3 -2
- package/dest/mocks/fixtures.d.ts +1 -1
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +2 -2
- package/dest/mocks/test_context.d.ts +1 -1
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +11 -12
- package/dest/orchestrator/block-building-helpers.d.ts +15 -29
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +51 -58
- package/dest/orchestrator/block-proving-state.d.ts +40 -44
- package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/block-proving-state.js +149 -85
- package/dest/orchestrator/epoch-proving-state.d.ts +23 -30
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/epoch-proving-state.js +92 -65
- package/dest/orchestrator/orchestrator.d.ts +17 -48
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +208 -351
- package/dest/orchestrator/tx-proving-state.d.ts +10 -6
- package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/tx-proving-state.js +57 -46
- package/dest/prover-agent/memory-proving-queue.d.ts +4 -4
- package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
- package/dest/prover-agent/memory-proving-queue.js +5 -5
- package/dest/prover-agent/prover-agent.d.ts +0 -2
- package/dest/prover-agent/prover-agent.d.ts.map +1 -1
- package/dest/prover-agent/prover-agent.js +7 -9
- package/dest/prover-client/factory.d.ts.map +1 -1
- package/dest/prover-client/factory.js +3 -3
- package/dest/prover-client/prover-client.d.ts +4 -2
- package/dest/prover-client/prover-client.d.ts.map +1 -1
- package/dest/prover-client/prover-client.js +16 -15
- package/dest/prover-client/server-epoch-prover.d.ts +25 -0
- package/dest/prover-client/server-epoch-prover.d.ts.map +1 -0
- package/dest/prover-client/server-epoch-prover.js +40 -0
- package/dest/proving_broker/broker_prover_facade.d.ts +19 -7
- package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
- package/dest/proving_broker/broker_prover_facade.js +271 -49
- package/dest/proving_broker/config.d.ts +61 -0
- package/dest/proving_broker/config.d.ts.map +1 -0
- package/dest/proving_broker/config.js +83 -0
- package/dest/proving_broker/factory.d.ts +1 -1
- package/dest/proving_broker/factory.d.ts.map +1 -1
- package/dest/proving_broker/factory.js +4 -7
- package/dest/proving_broker/fixtures.d.ts +5 -0
- package/dest/proving_broker/fixtures.d.ts.map +1 -0
- package/dest/proving_broker/fixtures.js +12 -0
- package/dest/proving_broker/index.d.ts +2 -1
- package/dest/proving_broker/index.d.ts.map +1 -1
- package/dest/proving_broker/index.js +3 -2
- package/dest/proving_broker/proof_store/factory.d.ts +6 -0
- package/dest/proving_broker/proof_store/factory.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/factory.js +39 -0
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts +13 -0
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/gcs_proof_store.js +46 -0
- package/dest/proving_broker/proof_store/index.d.ts +4 -0
- package/dest/proving_broker/proof_store/index.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/index.js +4 -0
- package/dest/proving_broker/proof_store/inline_proof_store.d.ts +14 -0
- package/dest/proving_broker/proof_store/inline_proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/inline_proof_store.js +37 -0
- package/dest/proving_broker/{proof_store.d.ts → proof_store/proof_store.d.ts} +1 -12
- package/dest/proving_broker/proof_store/proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/proof_store.js +2 -0
- package/dest/proving_broker/proving_agent.d.ts +4 -4
- package/dest/proving_broker/proving_agent.d.ts.map +1 -1
- package/dest/proving_broker/proving_agent.js +5 -5
- package/dest/proving_broker/proving_broker.d.ts +16 -12
- package/dest/proving_broker/proving_broker.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker.js +307 -274
- package/dest/proving_broker/proving_broker_database/memory.d.ts +4 -2
- package/dest/proving_broker/proving_broker_database/memory.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_database/memory.js +17 -4
- package/dest/proving_broker/proving_broker_database/persisted.d.ts +10 -6
- package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_database/persisted.js +106 -14
- package/dest/proving_broker/proving_broker_database.d.ts +7 -3
- package/dest/proving_broker/proving_broker_database.d.ts.map +1 -1
- package/dest/proving_broker/proving_job_controller.js +4 -4
- package/dest/proving_broker/rpc.d.ts.map +1 -1
- package/dest/proving_broker/rpc.js +4 -4
- package/dest/test/mock_prover.d.ts +8 -8
- package/dest/test/mock_prover.d.ts.map +1 -1
- package/dest/test/mock_prover.js +9 -10
- package/package.json +14 -12
- package/src/bin/get-proof-inputs.ts +60 -0
- package/src/block_builder/light.ts +7 -31
- package/src/config.ts +4 -4
- package/src/mocks/fixtures.ts +1 -1
- package/src/mocks/test_context.ts +9 -11
- package/src/orchestrator/block-building-helpers.ts +360 -402
- package/src/orchestrator/block-proving-state.ts +251 -121
- package/src/orchestrator/epoch-proving-state.ts +159 -88
- package/src/orchestrator/orchestrator.ts +262 -542
- package/src/orchestrator/tx-proving-state.ts +30 -18
- package/src/prover-agent/memory-proving-queue.ts +12 -16
- package/src/prover-agent/prover-agent.ts +14 -8
- package/src/prover-client/factory.ts +2 -3
- package/src/prover-client/prover-client.ts +17 -20
- package/src/prover-client/server-epoch-prover.ts +44 -0
- package/src/proving_broker/broker_prover_facade.ts +347 -67
- package/src/proving_broker/config.ts +93 -0
- package/src/proving_broker/factory.ts +11 -10
- package/src/proving_broker/fixtures.ts +14 -0
- package/src/proving_broker/index.ts +2 -1
- package/src/proving_broker/proof_store/factory.ts +42 -0
- package/src/proving_broker/proof_store/gcs_proof_store.ts +72 -0
- package/src/proving_broker/proof_store/index.ts +3 -0
- package/src/proving_broker/{proof_store.ts → proof_store/inline_proof_store.ts} +1 -44
- package/src/proving_broker/proof_store/proof_store.ts +54 -0
- package/src/proving_broker/proving_agent.ts +11 -5
- package/src/proving_broker/proving_broker.ts +122 -73
- package/src/proving_broker/proving_broker_database/memory.ts +24 -4
- package/src/proving_broker/proving_broker_database/persisted.ts +142 -20
- package/src/proving_broker/proving_broker_database.ts +8 -3
- package/src/proving_broker/proving_job_controller.ts +5 -5
- package/src/proving_broker/rpc.ts +2 -3
- package/src/test/mock_prover.ts +12 -18
- package/dest/proving_broker/proof_store.d.ts.map +0 -1
- package/dest/proving_broker/proof_store.js +0 -37
|
@@ -9,12 +9,17 @@ import {
|
|
|
9
9
|
type ProvingJobStatus,
|
|
10
10
|
ProvingRequestType,
|
|
11
11
|
} from '@aztec/circuit-types';
|
|
12
|
-
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
13
12
|
import { createLogger } from '@aztec/foundation/log';
|
|
14
13
|
import { type PromiseWithResolvers, RunningPromise, promiseWithResolvers } from '@aztec/foundation/promise';
|
|
15
|
-
import { PriorityMemoryQueue } from '@aztec/foundation/queue';
|
|
14
|
+
import { PriorityMemoryQueue, SerialQueue } from '@aztec/foundation/queue';
|
|
16
15
|
import { Timer } from '@aztec/foundation/timer';
|
|
17
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
type TelemetryClient,
|
|
18
|
+
type Traceable,
|
|
19
|
+
type Tracer,
|
|
20
|
+
getTelemetryClient,
|
|
21
|
+
trackSpan,
|
|
22
|
+
} from '@aztec/telemetry-client';
|
|
18
23
|
|
|
19
24
|
import assert from 'assert';
|
|
20
25
|
|
|
@@ -45,7 +50,6 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
45
50
|
private queues: ProvingQueues = {
|
|
46
51
|
[ProvingRequestType.PUBLIC_VM]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
47
52
|
[ProvingRequestType.TUBE_PROOF]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
48
|
-
[ProvingRequestType.PRIVATE_KERNEL_EMPTY]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
49
53
|
|
|
50
54
|
[ProvingRequestType.PRIVATE_BASE_ROLLUP]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
51
55
|
[ProvingRequestType.PUBLIC_BASE_ROLLUP]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
@@ -54,6 +58,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
54
58
|
|
|
55
59
|
[ProvingRequestType.BLOCK_MERGE_ROLLUP]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
56
60
|
[ProvingRequestType.BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
61
|
+
[ProvingRequestType.SINGLE_TX_BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
57
62
|
[ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
58
63
|
|
|
59
64
|
[ProvingRequestType.BASE_PARITY]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
@@ -89,31 +94,33 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
89
94
|
private instrumentation: ProvingBrokerInstrumentation;
|
|
90
95
|
public readonly tracer: Tracer;
|
|
91
96
|
|
|
92
|
-
private
|
|
97
|
+
private completedJobNotifications: ProvingJobId[] = [];
|
|
93
98
|
|
|
94
99
|
/**
|
|
95
100
|
* The broker keeps track of the highest epoch its seen.
|
|
96
101
|
* This information is used for garbage collection: once it reaches the next epoch, it can start pruning the database of old state.
|
|
97
|
-
*
|
|
98
|
-
*
|
|
102
|
+
* It is important that this value is initialised to zero. This ensures that we don't delete any old jobs until the current
|
|
103
|
+
* process instance receives a job request informing it of the actual current highest epoch
|
|
99
104
|
* Example:
|
|
100
|
-
* proving epoch 11 - the broker will wipe all
|
|
101
|
-
* finished proving epoch 11 and got first job for epoch 12 -> the broker will wipe all
|
|
102
|
-
* reorged back to end of epoch 10 -> epoch 11 is skipped and epoch 12 starts -> the broker will wipe all
|
|
105
|
+
* proving epoch 11 - the broker will wipe all jobs for epochs 9 and lower
|
|
106
|
+
* finished proving epoch 11 and got first job for epoch 12 -> the broker will wipe all settled jobs for epochs 10 and lower
|
|
107
|
+
* reorged back to end of epoch 10 -> epoch 11 is skipped and epoch 12 starts -> the broker will wipe all settled jobs for epochs 10 and lower
|
|
103
108
|
*/
|
|
104
109
|
private epochHeight = 0;
|
|
105
110
|
private maxEpochsToKeepResultsFor = 1;
|
|
106
111
|
|
|
112
|
+
private requestQueue: SerialQueue = new SerialQueue();
|
|
113
|
+
private started = false;
|
|
114
|
+
|
|
107
115
|
public constructor(
|
|
108
116
|
private database: ProvingBrokerDatabase,
|
|
109
|
-
client: TelemetryClient,
|
|
110
117
|
{
|
|
111
118
|
jobTimeoutMs = 30_000,
|
|
112
119
|
timeoutIntervalMs = 10_000,
|
|
113
120
|
maxRetries = 3,
|
|
114
121
|
maxEpochsToKeepResultsFor = 1,
|
|
115
|
-
maxParallelCleanUps = 20,
|
|
116
122
|
}: ProofRequestBrokerConfig = {},
|
|
123
|
+
client: TelemetryClient = getTelemetryClient(),
|
|
117
124
|
private logger = createLogger('prover-client:proving-broker'),
|
|
118
125
|
) {
|
|
119
126
|
this.tracer = client.getTracer('ProvingBroker');
|
|
@@ -122,7 +129,6 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
122
129
|
this.jobTimeoutMs = jobTimeoutMs;
|
|
123
130
|
this.maxRetries = maxRetries;
|
|
124
131
|
this.maxEpochsToKeepResultsFor = maxEpochsToKeepResultsFor;
|
|
125
|
-
this.maxParallelCleanUps = maxParallelCleanUps;
|
|
126
132
|
}
|
|
127
133
|
|
|
128
134
|
private measureQueueDepth: MonitorCallback = (type: ProvingRequestType) => {
|
|
@@ -142,6 +148,11 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
142
148
|
};
|
|
143
149
|
|
|
144
150
|
public start(): Promise<void> {
|
|
151
|
+
if (this.started) {
|
|
152
|
+
this.logger.info('Proving Broker already started');
|
|
153
|
+
return Promise.resolve();
|
|
154
|
+
}
|
|
155
|
+
this.logger.info('Proving Broker started');
|
|
145
156
|
for (const [item, result] of this.database.allProvingJobs()) {
|
|
146
157
|
this.logger.info(`Restoring proving job id=${item.id} settled=${!!result}`, {
|
|
147
158
|
provingJobId: item.id,
|
|
@@ -161,24 +172,71 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
161
172
|
|
|
162
173
|
this.cleanupPromise.start();
|
|
163
174
|
|
|
175
|
+
this.requestQueue.start();
|
|
176
|
+
|
|
164
177
|
this.instrumentation.monitorQueueDepth(this.measureQueueDepth);
|
|
165
178
|
this.instrumentation.monitorActiveJobs(this.countActiveJobs);
|
|
166
179
|
|
|
180
|
+
this.started = true;
|
|
181
|
+
|
|
167
182
|
return Promise.resolve();
|
|
168
183
|
}
|
|
169
184
|
|
|
170
185
|
public async stop(): Promise<void> {
|
|
186
|
+
if (!this.started) {
|
|
187
|
+
this.logger.warn('ProvingBroker not started');
|
|
188
|
+
return Promise.resolve();
|
|
189
|
+
}
|
|
190
|
+
await this.requestQueue.cancel();
|
|
171
191
|
await this.cleanupPromise.stop();
|
|
172
192
|
}
|
|
173
193
|
|
|
174
|
-
public
|
|
194
|
+
public enqueueProvingJob(job: ProvingJob): Promise<ProvingJobStatus> {
|
|
195
|
+
return this.requestQueue.put(() => this.#enqueueProvingJob(job));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
public cancelProvingJob(id: ProvingJobId): Promise<void> {
|
|
199
|
+
return this.requestQueue.put(() => this.#cancelProvingJob(id));
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
public getProvingJobStatus(id: ProvingJobId): Promise<ProvingJobStatus> {
|
|
203
|
+
return this.requestQueue.put(() => this.#getProvingJobStatus(id));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
public getCompletedJobs(ids: ProvingJobId[]): Promise<ProvingJobId[]> {
|
|
207
|
+
return this.requestQueue.put(() => this.#getCompletedJobs(ids));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
public getProvingJob(filter?: ProvingJobFilter): Promise<{ job: ProvingJob; time: number } | undefined> {
|
|
211
|
+
return this.requestQueue.put(() => this.#getProvingJob(filter));
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
public reportProvingJobSuccess(id: ProvingJobId, value: ProofUri): Promise<void> {
|
|
215
|
+
return this.requestQueue.put(() => this.#reportProvingJobSuccess(id, value));
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
public reportProvingJobError(id: ProvingJobId, err: string, retry = false): Promise<void> {
|
|
219
|
+
return this.requestQueue.put(() => this.#reportProvingJobError(id, err, retry));
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
public reportProvingJobProgress(
|
|
223
|
+
id: ProvingJobId,
|
|
224
|
+
startedAt: number,
|
|
225
|
+
filter?: ProvingJobFilter,
|
|
226
|
+
): Promise<{ job: ProvingJob; time: number } | undefined> {
|
|
227
|
+
return this.requestQueue.put(() => this.#reportProvingJobProgress(id, startedAt, filter));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async #enqueueProvingJob(job: ProvingJob): Promise<ProvingJobStatus> {
|
|
231
|
+
// We return the job status at the start of this call
|
|
232
|
+
const jobStatus = await this.#getProvingJobStatus(job.id);
|
|
175
233
|
if (this.jobsCache.has(job.id)) {
|
|
176
234
|
const existing = this.jobsCache.get(job.id);
|
|
177
235
|
assert.deepStrictEqual(job, existing, 'Duplicate proving job ID');
|
|
178
236
|
this.logger.debug(`Duplicate proving job id=${job.id} epochNumber=${job.epochNumber}. Ignoring`, {
|
|
179
237
|
provingJobId: job.id,
|
|
180
238
|
});
|
|
181
|
-
return;
|
|
239
|
+
return jobStatus;
|
|
182
240
|
}
|
|
183
241
|
|
|
184
242
|
if (this.isJobStale(job)) {
|
|
@@ -199,18 +257,10 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
199
257
|
this.jobsCache.delete(job.id);
|
|
200
258
|
throw err;
|
|
201
259
|
}
|
|
260
|
+
return jobStatus;
|
|
202
261
|
}
|
|
203
262
|
|
|
204
|
-
|
|
205
|
-
const promiseWithResolvers = this.promises.get(id);
|
|
206
|
-
if (!promiseWithResolvers) {
|
|
207
|
-
this.logger.warn(`Job id=${id} not found`, { provingJobId: id });
|
|
208
|
-
return Promise.resolve({ status: 'rejected', reason: `Job ${id} not found` });
|
|
209
|
-
}
|
|
210
|
-
return promiseWithResolvers.promise;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
public async cancelProvingJob(id: ProvingJobId): Promise<void> {
|
|
263
|
+
async #cancelProvingJob(id: ProvingJobId): Promise<void> {
|
|
214
264
|
if (!this.jobsCache.has(id)) {
|
|
215
265
|
this.logger.warn(`Can't cancel a job that doesn't exist id=${id}`, { provingJobId: id });
|
|
216
266
|
return;
|
|
@@ -219,31 +269,21 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
219
269
|
// notify listeners of the cancellation
|
|
220
270
|
if (!this.resultsCache.has(id)) {
|
|
221
271
|
this.logger.info(`Cancelling job id=${id}`, { provingJobId: id });
|
|
222
|
-
await this
|
|
272
|
+
await this.#reportProvingJobError(id, 'Aborted', false);
|
|
223
273
|
}
|
|
224
274
|
}
|
|
225
275
|
|
|
226
|
-
private
|
|
227
|
-
|
|
228
|
-
this.
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
this.logger.warn(`Can't cleanup busy proving job: id=${id}`, { provingJobId: id });
|
|
234
|
-
return;
|
|
276
|
+
private cleanUpProvingJobState(ids: ProvingJobId[]) {
|
|
277
|
+
for (const id of ids) {
|
|
278
|
+
this.jobsCache.delete(id);
|
|
279
|
+
this.promises.delete(id);
|
|
280
|
+
this.resultsCache.delete(id);
|
|
281
|
+
this.inProgress.delete(id);
|
|
282
|
+
this.retries.delete(id);
|
|
235
283
|
}
|
|
236
|
-
|
|
237
|
-
this.logger.debug(`Cleaning up state for job id=${id}`, { provingJobId: id });
|
|
238
|
-
await this.database.deleteProvingJobAndResult(id);
|
|
239
|
-
this.jobsCache.delete(id);
|
|
240
|
-
this.promises.delete(id);
|
|
241
|
-
this.resultsCache.delete(id);
|
|
242
|
-
this.inProgress.delete(id);
|
|
243
|
-
this.retries.delete(id);
|
|
244
284
|
}
|
|
245
285
|
|
|
246
|
-
|
|
286
|
+
#getProvingJobStatus(id: ProvingJobId): Promise<ProvingJobStatus> {
|
|
247
287
|
const result = this.resultsCache.get(id);
|
|
248
288
|
if (result) {
|
|
249
289
|
return Promise.resolve(result);
|
|
@@ -252,7 +292,6 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
252
292
|
const item = this.jobsCache.get(id);
|
|
253
293
|
|
|
254
294
|
if (!item) {
|
|
255
|
-
this.logger.warn(`Proving job id=${id} not found`, { provingJobId: id });
|
|
256
295
|
return Promise.resolve({ status: 'not-found' });
|
|
257
296
|
}
|
|
258
297
|
|
|
@@ -260,8 +299,15 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
260
299
|
}
|
|
261
300
|
}
|
|
262
301
|
|
|
302
|
+
#getCompletedJobs(ids: ProvingJobId[]): Promise<ProvingJobId[]> {
|
|
303
|
+
const completedJobs = ids.filter(id => this.resultsCache.has(id));
|
|
304
|
+
const notifications = this.completedJobNotifications;
|
|
305
|
+
this.completedJobNotifications = [];
|
|
306
|
+
return Promise.resolve(notifications.concat(completedJobs));
|
|
307
|
+
}
|
|
308
|
+
|
|
263
309
|
// eslint-disable-next-line require-await
|
|
264
|
-
async getProvingJob(
|
|
310
|
+
async #getProvingJob(
|
|
265
311
|
filter: ProvingJobFilter = { allowList: [] },
|
|
266
312
|
): Promise<{ job: ProvingJob; time: number } | undefined> {
|
|
267
313
|
const allowedProofs: ProvingRequestType[] =
|
|
@@ -299,7 +345,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
299
345
|
return undefined;
|
|
300
346
|
}
|
|
301
347
|
|
|
302
|
-
async reportProvingJobError(id: ProvingJobId, err: string, retry = false): Promise<void> {
|
|
348
|
+
async #reportProvingJobError(id: ProvingJobId, err: string, retry = false): Promise<void> {
|
|
303
349
|
const info = this.inProgress.get(id);
|
|
304
350
|
const item = this.jobsCache.get(id);
|
|
305
351
|
const retries = this.retries.get(id) ?? 0;
|
|
@@ -351,6 +397,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
351
397
|
const result: ProvingJobSettledResult = { status: 'rejected', reason: String(err) };
|
|
352
398
|
this.resultsCache.set(id, result);
|
|
353
399
|
this.promises.get(id)!.resolve(result);
|
|
400
|
+
this.completedJobNotifications.push(id);
|
|
354
401
|
|
|
355
402
|
this.instrumentation.incRejectedJobs(item.type);
|
|
356
403
|
if (info) {
|
|
@@ -369,7 +416,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
369
416
|
}
|
|
370
417
|
}
|
|
371
418
|
|
|
372
|
-
reportProvingJobProgress(
|
|
419
|
+
#reportProvingJobProgress(
|
|
373
420
|
id: ProvingJobId,
|
|
374
421
|
startedAt: number,
|
|
375
422
|
filter?: ProvingJobFilter,
|
|
@@ -377,12 +424,12 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
377
424
|
const job = this.jobsCache.get(id);
|
|
378
425
|
if (!job) {
|
|
379
426
|
this.logger.warn(`Proving job id=${id} does not exist`, { provingJobId: id });
|
|
380
|
-
return filter ? this
|
|
427
|
+
return filter ? this.#getProvingJob(filter) : Promise.resolve(undefined);
|
|
381
428
|
}
|
|
382
429
|
|
|
383
430
|
if (this.resultsCache.has(id)) {
|
|
384
431
|
this.logger.warn(`Proving job id=${id} has already been completed`, { provingJobId: id });
|
|
385
|
-
return filter ? this
|
|
432
|
+
return filter ? this.#getProvingJob(filter) : Promise.resolve(undefined);
|
|
386
433
|
}
|
|
387
434
|
|
|
388
435
|
const metadata = this.inProgress.get(id);
|
|
@@ -420,13 +467,13 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
420
467
|
} already being worked on by another agent. Sending new one`,
|
|
421
468
|
{ provingJobId: id },
|
|
422
469
|
);
|
|
423
|
-
return this
|
|
470
|
+
return this.#getProvingJob(filter);
|
|
424
471
|
} else {
|
|
425
472
|
return Promise.resolve(undefined);
|
|
426
473
|
}
|
|
427
474
|
}
|
|
428
475
|
|
|
429
|
-
async reportProvingJobSuccess(id: ProvingJobId, value: ProofUri): Promise<void> {
|
|
476
|
+
async #reportProvingJobSuccess(id: ProvingJobId, value: ProofUri): Promise<void> {
|
|
430
477
|
const info = this.inProgress.get(id);
|
|
431
478
|
const item = this.jobsCache.get(id);
|
|
432
479
|
const retries = this.retries.get(id) ?? 0;
|
|
@@ -459,6 +506,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
459
506
|
const result: ProvingJobSettledResult = { status: 'fulfilled', value };
|
|
460
507
|
this.resultsCache.set(id, result);
|
|
461
508
|
this.promises.get(id)!.resolve(result);
|
|
509
|
+
this.completedJobNotifications.push(id);
|
|
462
510
|
|
|
463
511
|
this.instrumentation.incResolvedJobs(item.type);
|
|
464
512
|
if (info) {
|
|
@@ -479,30 +527,32 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
479
527
|
|
|
480
528
|
@trackSpan('ProvingBroker.cleanupPass')
|
|
481
529
|
private async cleanupPass() {
|
|
482
|
-
|
|
483
|
-
|
|
530
|
+
this.cleanupStaleJobs();
|
|
531
|
+
this.reEnqueueExpiredJobs();
|
|
532
|
+
const oldestEpochToKeep = this.oldestEpochToKeep();
|
|
533
|
+
if (oldestEpochToKeep > 0) {
|
|
534
|
+
await this.requestQueue.put(() => this.database.deleteAllProvingJobsOlderThanEpoch(oldestEpochToKeep));
|
|
535
|
+
this.logger.trace(`Deleted all epochs older than ${oldestEpochToKeep}`);
|
|
536
|
+
}
|
|
484
537
|
}
|
|
485
538
|
|
|
486
|
-
private
|
|
539
|
+
private cleanupStaleJobs() {
|
|
487
540
|
const jobIds = Array.from(this.jobsCache.keys());
|
|
488
541
|
const jobsToClean: ProvingJobId[] = [];
|
|
489
542
|
for (const id of jobIds) {
|
|
490
543
|
const job = this.jobsCache.get(id)!;
|
|
491
|
-
|
|
492
|
-
if (isComplete && this.isJobStale(job)) {
|
|
544
|
+
if (this.isJobStale(job)) {
|
|
493
545
|
jobsToClean.push(id);
|
|
494
546
|
}
|
|
495
547
|
}
|
|
496
548
|
|
|
497
549
|
if (jobsToClean.length > 0) {
|
|
498
|
-
this.
|
|
499
|
-
|
|
500
|
-
await this.cleanUpProvingJobState(jobId);
|
|
501
|
-
});
|
|
550
|
+
this.cleanUpProvingJobState(jobsToClean);
|
|
551
|
+
this.logger.info(`Cleaned up jobs=${jobsToClean.length}`);
|
|
502
552
|
}
|
|
503
553
|
}
|
|
504
554
|
|
|
505
|
-
private
|
|
555
|
+
private reEnqueueExpiredJobs() {
|
|
506
556
|
const inProgressEntries = Array.from(this.inProgress.entries());
|
|
507
557
|
for (const [id, metadata] of inProgressEntries) {
|
|
508
558
|
const item = this.jobsCache.get(id);
|
|
@@ -515,15 +565,10 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
515
565
|
const now = this.msTimeSource();
|
|
516
566
|
const msSinceLastUpdate = now - metadata.lastUpdatedAt;
|
|
517
567
|
if (msSinceLastUpdate >= this.jobTimeoutMs) {
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
this.logger.warn(`Proving job id=${id} timed out. Adding it back to the queue.`, { provingJobId: id });
|
|
523
|
-
this.inProgress.delete(id);
|
|
524
|
-
this.enqueueJobInternal(item);
|
|
525
|
-
this.instrumentation.incTimedOutJobs(item.type);
|
|
526
|
-
}
|
|
568
|
+
this.logger.warn(`Proving job id=${id} timed out. Adding it back to the queue.`, { provingJobId: id });
|
|
569
|
+
this.inProgress.delete(id);
|
|
570
|
+
this.enqueueJobInternal(item);
|
|
571
|
+
this.instrumentation.incTimedOutJobs(item.type);
|
|
527
572
|
}
|
|
528
573
|
}
|
|
529
574
|
}
|
|
@@ -541,7 +586,11 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
541
586
|
}
|
|
542
587
|
|
|
543
588
|
private isJobStale(job: ProvingJob) {
|
|
544
|
-
return job.epochNumber < this.
|
|
589
|
+
return job.epochNumber < this.oldestEpochToKeep();
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
private oldestEpochToKeep() {
|
|
593
|
+
return this.epochHeight - this.maxEpochsToKeepResultsFor;
|
|
545
594
|
}
|
|
546
595
|
}
|
|
547
596
|
|
|
@@ -601,6 +650,7 @@ function proofTypeComparator(a: ProvingRequestType, b: ProvingRequestType): -1 |
|
|
|
601
650
|
*/
|
|
602
651
|
const PROOF_TYPES_IN_PRIORITY_ORDER: ProvingRequestType[] = [
|
|
603
652
|
ProvingRequestType.BLOCK_ROOT_ROLLUP,
|
|
653
|
+
ProvingRequestType.SINGLE_TX_BLOCK_ROOT_ROLLUP,
|
|
604
654
|
ProvingRequestType.BLOCK_MERGE_ROLLUP,
|
|
605
655
|
ProvingRequestType.ROOT_ROLLUP,
|
|
606
656
|
ProvingRequestType.MERGE_ROLLUP,
|
|
@@ -611,5 +661,4 @@ const PROOF_TYPES_IN_PRIORITY_ORDER: ProvingRequestType[] = [
|
|
|
611
661
|
ProvingRequestType.ROOT_PARITY,
|
|
612
662
|
ProvingRequestType.BASE_PARITY,
|
|
613
663
|
ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP,
|
|
614
|
-
ProvingRequestType.PRIVATE_KERNEL_EMPTY,
|
|
615
664
|
];
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
type ProofUri,
|
|
3
|
+
type ProvingJob,
|
|
4
|
+
type ProvingJobId,
|
|
5
|
+
type ProvingJobSettledResult,
|
|
6
|
+
getEpochFromProvingJobId,
|
|
7
|
+
} from '@aztec/circuit-types';
|
|
2
8
|
|
|
3
9
|
import { type ProvingBrokerDatabase } from '../proving_broker_database.js';
|
|
4
10
|
|
|
@@ -29,15 +35,29 @@ export class InMemoryBrokerDatabase implements ProvingBrokerDatabase {
|
|
|
29
35
|
return Promise.resolve();
|
|
30
36
|
}
|
|
31
37
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
deleteProvingJobs(ids: ProvingJobId[]): Promise<void> {
|
|
39
|
+
for (const id of ids) {
|
|
40
|
+
this.jobs.delete(id);
|
|
41
|
+
this.results.delete(id);
|
|
42
|
+
}
|
|
35
43
|
return Promise.resolve();
|
|
36
44
|
}
|
|
37
45
|
|
|
46
|
+
deleteAllProvingJobsOlderThanEpoch(epochNumber: number): Promise<void> {
|
|
47
|
+
const toDelete = [
|
|
48
|
+
...Array.from(this.jobs.keys()).filter(x => getEpochFromProvingJobId(x) < epochNumber),
|
|
49
|
+
...Array.from(this.results.keys()).filter(x => getEpochFromProvingJobId(x) < epochNumber),
|
|
50
|
+
];
|
|
51
|
+
return this.deleteProvingJobs(toDelete);
|
|
52
|
+
}
|
|
53
|
+
|
|
38
54
|
*allProvingJobs(): Iterable<[ProvingJob, ProvingJobSettledResult | undefined]> {
|
|
39
55
|
for (const item of this.jobs.values()) {
|
|
40
56
|
yield [item, this.results.get(item.id)] as const;
|
|
41
57
|
}
|
|
42
58
|
}
|
|
59
|
+
|
|
60
|
+
close(): Promise<void> {
|
|
61
|
+
return Promise.resolve();
|
|
62
|
+
}
|
|
43
63
|
}
|
|
@@ -1,27 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type ProofUri,
|
|
3
|
+
ProvingJob,
|
|
4
|
+
type ProvingJobId,
|
|
5
|
+
ProvingJobSettledResult,
|
|
6
|
+
getEpochFromProvingJobId,
|
|
7
|
+
} from '@aztec/circuit-types';
|
|
2
8
|
import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
|
|
3
|
-
import { type
|
|
4
|
-
import {
|
|
9
|
+
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
10
|
+
import { type AztecMap } from '@aztec/kv-store';
|
|
11
|
+
import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
|
|
12
|
+
import { Attributes, LmdbMetrics, type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
5
13
|
|
|
14
|
+
import { mkdir, readdir } from 'fs/promises';
|
|
15
|
+
import { join } from 'path';
|
|
16
|
+
|
|
17
|
+
import { type ProverBrokerConfig } from '../config.js';
|
|
6
18
|
import { type ProvingBrokerDatabase } from '../proving_broker_database.js';
|
|
7
19
|
|
|
8
|
-
|
|
20
|
+
class SingleEpochDatabase {
|
|
9
21
|
private jobs: AztecMap<ProvingJobId, string>;
|
|
10
22
|
private jobResults: AztecMap<ProvingJobId, string>;
|
|
11
|
-
private metrics: LmdbMetrics;
|
|
12
23
|
|
|
13
|
-
constructor(
|
|
14
|
-
this.metrics = new LmdbMetrics(
|
|
15
|
-
client.getMeter('KVBrokerDatabase'),
|
|
16
|
-
{
|
|
17
|
-
[Attributes.DB_DATA_TYPE]: 'prover-broker',
|
|
18
|
-
},
|
|
19
|
-
() => store.estimateSize(),
|
|
20
|
-
);
|
|
24
|
+
constructor(public readonly store: AztecLmdbStore) {
|
|
21
25
|
this.jobs = store.openMap('proving_jobs');
|
|
22
26
|
this.jobResults = store.openMap('proving_job_results');
|
|
23
27
|
}
|
|
24
28
|
|
|
29
|
+
estimateSize() {
|
|
30
|
+
return this.store.estimateSize();
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
async addProvingJob(job: ProvingJob): Promise<void> {
|
|
26
34
|
await this.jobs.set(job.id, jsonStringify(job));
|
|
27
35
|
}
|
|
@@ -35,13 +43,6 @@ export class KVBrokerDatabase implements ProvingBrokerDatabase {
|
|
|
35
43
|
}
|
|
36
44
|
}
|
|
37
45
|
|
|
38
|
-
deleteProvingJobAndResult(id: ProvingJobId): Promise<void> {
|
|
39
|
-
return this.store.transaction(() => {
|
|
40
|
-
void this.jobs.delete(id);
|
|
41
|
-
void this.jobResults.delete(id);
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
|
|
45
46
|
async setProvingJobError(id: ProvingJobId, reason: string): Promise<void> {
|
|
46
47
|
const result: ProvingJobSettledResult = { status: 'rejected', reason };
|
|
47
48
|
await this.jobResults.set(id, jsonStringify(result));
|
|
@@ -51,4 +52,125 @@ export class KVBrokerDatabase implements ProvingBrokerDatabase {
|
|
|
51
52
|
const result: ProvingJobSettledResult = { status: 'fulfilled', value };
|
|
52
53
|
await this.jobResults.set(id, jsonStringify(result));
|
|
53
54
|
}
|
|
55
|
+
|
|
56
|
+
delete() {
|
|
57
|
+
return this.store.delete();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
close() {
|
|
61
|
+
return this.store.close();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export class KVBrokerDatabase implements ProvingBrokerDatabase {
|
|
66
|
+
private metrics: LmdbMetrics;
|
|
67
|
+
|
|
68
|
+
private constructor(
|
|
69
|
+
private epochs: Map<number, SingleEpochDatabase>,
|
|
70
|
+
private config: ProverBrokerConfig,
|
|
71
|
+
client: TelemetryClient = getTelemetryClient(),
|
|
72
|
+
private logger: Logger,
|
|
73
|
+
) {
|
|
74
|
+
this.metrics = new LmdbMetrics(
|
|
75
|
+
client.getMeter('KVBrokerDatabase'),
|
|
76
|
+
{
|
|
77
|
+
[Attributes.DB_DATA_TYPE]: 'prover-broker',
|
|
78
|
+
},
|
|
79
|
+
() => this.estimateSize(),
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private estimateSize() {
|
|
84
|
+
const sizes = Array.from(this.epochs.values()).map(x => x.estimateSize());
|
|
85
|
+
return {
|
|
86
|
+
mappingSize: this.config.dataStoreMapSizeKB,
|
|
87
|
+
numItems: sizes.reduce((prev, curr) => prev + curr.numItems, 0),
|
|
88
|
+
actualSize: sizes.reduce((prev, curr) => prev + curr.actualSize, 0),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public static async new(
|
|
93
|
+
config: ProverBrokerConfig,
|
|
94
|
+
client: TelemetryClient = getTelemetryClient(),
|
|
95
|
+
logger = createLogger('prover-client:proving-broker-database'),
|
|
96
|
+
) {
|
|
97
|
+
const epochs: Map<number, SingleEpochDatabase> = new Map<number, SingleEpochDatabase>();
|
|
98
|
+
const files = await readdir(config.dataDirectory!, { recursive: false, withFileTypes: true });
|
|
99
|
+
for (const file of files) {
|
|
100
|
+
if (!file.isDirectory()) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const fullDirectory = join(config.dataDirectory!, file.name);
|
|
104
|
+
const epochDirectory = file.name;
|
|
105
|
+
const epochNumber = parseInt(epochDirectory, 10);
|
|
106
|
+
if (!Number.isSafeInteger(epochNumber) || epochNumber < 0) {
|
|
107
|
+
logger.warn(`Found invalid epoch directory ${fullDirectory} when loading epoch databases, ignoring`);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
logger.info(
|
|
111
|
+
`Loading broker database for epoch ${epochNumber} from ${fullDirectory} with map size ${config.dataStoreMapSizeKB}KB`,
|
|
112
|
+
);
|
|
113
|
+
const db = AztecLmdbStore.open(fullDirectory, config.dataStoreMapSizeKB, false);
|
|
114
|
+
const epochDb = new SingleEpochDatabase(db);
|
|
115
|
+
epochs.set(epochNumber, epochDb);
|
|
116
|
+
}
|
|
117
|
+
return new KVBrokerDatabase(epochs, config, client, logger);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async close(): Promise<void> {
|
|
121
|
+
for (const [_, v] of this.epochs) {
|
|
122
|
+
await v.close();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async deleteAllProvingJobsOlderThanEpoch(epochNumber: number): Promise<void> {
|
|
127
|
+
const oldEpochs = Array.from(this.epochs.keys()).filter(e => e < epochNumber);
|
|
128
|
+
for (const old of oldEpochs) {
|
|
129
|
+
const db = this.epochs.get(old);
|
|
130
|
+
if (!db) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
this.logger.info(`Deleting broker database for epoch ${old}`);
|
|
134
|
+
await db.delete();
|
|
135
|
+
this.epochs.delete(old);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async addProvingJob(job: ProvingJob): Promise<void> {
|
|
140
|
+
let epochDb = this.epochs.get(job.epochNumber);
|
|
141
|
+
if (!epochDb) {
|
|
142
|
+
const newEpochDirectory = join(this.config.dataDirectory!, job.epochNumber.toString());
|
|
143
|
+
await mkdir(newEpochDirectory, { recursive: true });
|
|
144
|
+
this.logger.info(
|
|
145
|
+
`Creating broker database for epoch ${job.epochNumber} at ${newEpochDirectory} with map size ${this.config.dataStoreMapSizeKB}`,
|
|
146
|
+
);
|
|
147
|
+
const db = AztecLmdbStore.open(newEpochDirectory, this.config.dataStoreMapSizeKB, false);
|
|
148
|
+
epochDb = new SingleEpochDatabase(db);
|
|
149
|
+
this.epochs.set(job.epochNumber, epochDb);
|
|
150
|
+
}
|
|
151
|
+
await epochDb.addProvingJob(job);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
*allProvingJobs(): Iterable<[ProvingJob, ProvingJobSettledResult | undefined]> {
|
|
155
|
+
const iterators = Array.from(this.epochs.values()).map(x => x.allProvingJobs());
|
|
156
|
+
for (const it of iterators) {
|
|
157
|
+
yield* it;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async setProvingJobError(id: ProvingJobId, reason: string): Promise<void> {
|
|
162
|
+
const epochDb = this.epochs.get(getEpochFromProvingJobId(id));
|
|
163
|
+
if (!epochDb) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
await epochDb.setProvingJobError(id, reason);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async setProvingJobResult(id: ProvingJobId, value: ProofUri): Promise<void> {
|
|
170
|
+
const epochDb = this.epochs.get(getEpochFromProvingJobId(id));
|
|
171
|
+
if (!epochDb) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
await epochDb.setProvingJobResult(id, value);
|
|
175
|
+
}
|
|
54
176
|
}
|
|
@@ -11,10 +11,10 @@ export interface ProvingBrokerDatabase {
|
|
|
11
11
|
addProvingJob(request: ProvingJob): Promise<void>;
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
15
|
-
* @param
|
|
14
|
+
* Deletes all proving jobs belonging to epochs older than the given epoch
|
|
15
|
+
* @param epochNumber - The epoch number beyond which jobs should be deleted
|
|
16
16
|
*/
|
|
17
|
-
|
|
17
|
+
deleteAllProvingJobsOlderThanEpoch(epochNumber: number): Promise<void>;
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Returns an iterator over all saved proving jobs
|
|
@@ -36,4 +36,9 @@ export interface ProvingBrokerDatabase {
|
|
|
36
36
|
* @param err - The error that occurred while processing the proof request
|
|
37
37
|
*/
|
|
38
38
|
setProvingJobError(id: ProvingJobId, err: string): Promise<void>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Closes the database
|
|
42
|
+
*/
|
|
43
|
+
close(): Promise<void>;
|
|
39
44
|
}
|