@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.
- package/dest/config.d.ts +4 -10
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +8 -7
- package/dest/index.d.ts +1 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -1
- package/dest/mocks/test_context.js +3 -2
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +10 -18
- package/dest/orchestrator/block-proving-state.js +2 -2
- package/dest/prover-agent/memory-proving-queue.d.ts +10 -8
- package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
- package/dest/prover-agent/memory-proving-queue.js +35 -35
- package/dest/prover-agent/prover-agent.d.ts +1 -0
- package/dest/prover-agent/prover-agent.d.ts.map +1 -1
- package/dest/prover-agent/prover-agent.js +12 -9
- package/dest/proving_broker/caching_broker_facade.d.ts +30 -0
- package/dest/proving_broker/caching_broker_facade.d.ts.map +1 -0
- package/dest/proving_broker/caching_broker_facade.js +150 -0
- package/dest/proving_broker/factory.d.ts +4 -0
- package/dest/proving_broker/factory.d.ts.map +1 -0
- package/dest/proving_broker/factory.js +17 -0
- package/dest/proving_broker/index.d.ts +9 -0
- package/dest/proving_broker/index.d.ts.map +1 -0
- package/dest/proving_broker/index.js +9 -0
- package/dest/proving_broker/proof_store.d.ts +46 -0
- package/dest/proving_broker/proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store.js +37 -0
- package/dest/proving_broker/prover_cache/memory.d.ts +9 -0
- package/dest/proving_broker/prover_cache/memory.d.ts.map +1 -0
- package/dest/proving_broker/prover_cache/memory.js +16 -0
- package/dest/proving_broker/proving_agent.d.ts +11 -6
- package/dest/proving_broker/proving_agent.d.ts.map +1 -1
- package/dest/proving_broker/proving_agent.js +48 -20
- package/dest/proving_broker/proving_broker.d.ts +17 -16
- package/dest/proving_broker/proving_broker.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker.js +44 -23
- package/dest/proving_broker/proving_broker_database/memory.d.ts +14 -0
- package/dest/proving_broker/proving_broker_database/memory.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_database/memory.js +35 -0
- package/dest/proving_broker/proving_broker_database/persisted.d.ts +15 -0
- package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_database/persisted.js +35 -0
- package/dest/proving_broker/{proving_job_database.d.ts → proving_broker_database.d.ts} +8 -8
- package/dest/proving_broker/proving_broker_database.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_database.js +2 -0
- package/dest/proving_broker/proving_job_controller.d.ts +13 -8
- package/dest/proving_broker/proving_job_controller.d.ts.map +1 -1
- package/dest/proving_broker/proving_job_controller.js +43 -43
- package/dest/proving_broker/rpc.d.ts +11 -0
- package/dest/proving_broker/rpc.d.ts.map +1 -0
- package/dest/proving_broker/rpc.js +44 -0
- package/dest/test/mock_prover.d.ts +15 -1
- package/dest/test/mock_prover.d.ts.map +1 -1
- package/dest/test/mock_prover.js +36 -1
- package/dest/tx-prover/factory.d.ts +2 -1
- package/dest/tx-prover/factory.d.ts.map +1 -1
- package/dest/tx-prover/factory.js +3 -3
- package/dest/tx-prover/tx-prover.d.ts +13 -7
- package/dest/tx-prover/tx-prover.d.ts.map +1 -1
- package/dest/tx-prover/tx-prover.js +52 -35
- package/package.json +14 -12
- package/src/config.ts +17 -16
- package/src/index.ts +1 -0
- package/src/mocks/test_context.ts +2 -2
- package/src/orchestrator/block-building-helpers.ts +22 -33
- package/src/orchestrator/block-proving-state.ts +1 -1
- package/src/prover-agent/memory-proving-queue.ts +43 -44
- package/src/prover-agent/prover-agent.ts +16 -20
- package/src/proving_broker/caching_broker_facade.ts +312 -0
- package/src/proving_broker/factory.ts +21 -0
- package/src/proving_broker/index.ts +8 -0
- package/src/proving_broker/proof_store.ts +106 -0
- package/src/proving_broker/prover_cache/memory.ts +20 -0
- package/src/proving_broker/proving_agent.ts +75 -20
- package/src/proving_broker/proving_broker.ts +98 -65
- package/src/proving_broker/proving_broker_database/memory.ts +43 -0
- package/src/proving_broker/proving_broker_database/persisted.ts +45 -0
- package/src/proving_broker/{proving_job_database.ts → proving_broker_database.ts} +7 -12
- package/src/proving_broker/proving_job_controller.ts +54 -46
- package/src/proving_broker/rpc.ts +64 -0
- package/src/test/mock_prover.ts +51 -0
- package/src/tx-prover/factory.ts +7 -2
- package/src/tx-prover/tx-prover.ts +78 -46
- package/dest/proving_broker/proving_broker_interface.d.ts +0 -61
- package/dest/proving_broker/proving_broker_interface.d.ts.map +0 -1
- package/dest/proving_broker/proving_broker_interface.js +0 -2
- package/dest/proving_broker/proving_job_database/memory.d.ts +0 -14
- package/dest/proving_broker/proving_job_database/memory.d.ts.map +0 -1
- package/dest/proving_broker/proving_job_database/memory.js +0 -35
- package/dest/proving_broker/proving_job_database/persisted.d.ts +0 -15
- package/dest/proving_broker/proving_job_database/persisted.d.ts.map +0 -1
- package/dest/proving_broker/proving_job_database/persisted.js +0 -35
- package/dest/proving_broker/proving_job_database.d.ts.map +0 -1
- package/dest/proving_broker/proving_job_database.js +0 -2
- package/src/proving_broker/proving_broker_interface.ts +0 -74
- package/src/proving_broker/proving_job_database/memory.ts +0 -43
- package/src/proving_broker/proving_job_database/persisted.ts +0 -45
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ProvingError,
|
|
3
|
-
type
|
|
3
|
+
type ProvingJob,
|
|
4
|
+
type ProvingJobConsumer,
|
|
5
|
+
type ProvingJobId,
|
|
6
|
+
type ProvingJobInputs,
|
|
7
|
+
type ProvingJobResultsMap,
|
|
8
|
+
ProvingRequestType,
|
|
4
9
|
type ServerCircuitProver,
|
|
5
|
-
type V2ProvingJob,
|
|
6
10
|
} from '@aztec/circuit-types';
|
|
7
11
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
8
12
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
9
13
|
|
|
10
|
-
import { type
|
|
11
|
-
import { ProvingJobController,
|
|
14
|
+
import { type ProofStore } from './proof_store.js';
|
|
15
|
+
import { ProvingJobController, ProvingJobControllerStatus } from './proving_job_controller.js';
|
|
12
16
|
|
|
13
17
|
/**
|
|
14
18
|
* A helper class that encapsulates a circuit prover and connects it to a job source.
|
|
@@ -19,14 +23,16 @@ export class ProvingAgent {
|
|
|
19
23
|
|
|
20
24
|
constructor(
|
|
21
25
|
/** The source of proving jobs */
|
|
22
|
-
private
|
|
26
|
+
private broker: ProvingJobConsumer,
|
|
27
|
+
/** Database holding proof inputs and outputs */
|
|
28
|
+
private proofStore: ProofStore,
|
|
23
29
|
/** The prover implementation to defer jobs to */
|
|
24
30
|
private circuitProver: ServerCircuitProver,
|
|
25
31
|
/** Optional list of allowed proof types to build */
|
|
26
|
-
private proofAllowList
|
|
32
|
+
private proofAllowList: Array<ProvingRequestType> = [],
|
|
27
33
|
/** How long to wait between jobs */
|
|
28
34
|
private pollIntervalMs = 1000,
|
|
29
|
-
private log = createDebugLogger('aztec:
|
|
35
|
+
private log = createDebugLogger('aztec:prover-client:proving-agent'),
|
|
30
36
|
) {
|
|
31
37
|
this.runningPromise = new RunningPromise(this.safeWork, this.pollIntervalMs);
|
|
32
38
|
}
|
|
@@ -54,37 +60,86 @@ export class ProvingAgent {
|
|
|
54
60
|
// (1) either do a heartbeat, telling the broker that we're working
|
|
55
61
|
// (2) get a new job
|
|
56
62
|
// If during (1) the broker returns a new job that means we can cancel the current job and start the new one
|
|
57
|
-
let maybeJob: { job:
|
|
58
|
-
if (this.currentJobController?.getStatus() ===
|
|
59
|
-
maybeJob = await this.
|
|
63
|
+
let maybeJob: { job: ProvingJob; time: number } | undefined;
|
|
64
|
+
if (this.currentJobController?.getStatus() === ProvingJobControllerStatus.PROVING) {
|
|
65
|
+
maybeJob = await this.broker.reportProvingJobProgress(
|
|
60
66
|
this.currentJobController.getJobId(),
|
|
61
67
|
this.currentJobController.getStartedAt(),
|
|
62
68
|
{ allowList: this.proofAllowList },
|
|
63
69
|
);
|
|
64
70
|
} else {
|
|
65
|
-
maybeJob = await this.
|
|
71
|
+
maybeJob = await this.broker.getProvingJob({ allowList: this.proofAllowList });
|
|
66
72
|
}
|
|
67
73
|
|
|
68
74
|
if (!maybeJob) {
|
|
69
75
|
return;
|
|
70
76
|
}
|
|
71
77
|
|
|
72
|
-
|
|
78
|
+
let abortedProofJobId: string | undefined;
|
|
79
|
+
let abortedProofName: string | undefined;
|
|
80
|
+
if (this.currentJobController?.getStatus() === ProvingJobControllerStatus.PROVING) {
|
|
81
|
+
abortedProofJobId = this.currentJobController.getJobId();
|
|
82
|
+
abortedProofName = this.currentJobController.getProofTypeName();
|
|
73
83
|
this.currentJobController?.abort();
|
|
74
84
|
}
|
|
75
85
|
|
|
76
86
|
const { job, time } = maybeJob;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
87
|
+
let inputs: ProvingJobInputs;
|
|
88
|
+
try {
|
|
89
|
+
inputs = await this.proofStore.getProofInput(job.inputsUri);
|
|
90
|
+
} catch (err) {
|
|
91
|
+
await this.broker.reportProvingJobError(job.id, 'Failed to load proof inputs', true);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
this.currentJobController = new ProvingJobController(
|
|
96
|
+
job.id,
|
|
97
|
+
inputs,
|
|
98
|
+
time,
|
|
99
|
+
this.circuitProver,
|
|
100
|
+
this.handleJobResult,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
if (abortedProofJobId) {
|
|
104
|
+
this.log.info(
|
|
105
|
+
`Aborting job id=${abortedProofJobId} type=${abortedProofName} to start new job id=${this.currentJobController.getJobId()} type=${this.currentJobController.getProofTypeName()} inputsUri=${truncateString(
|
|
106
|
+
job.inputsUri,
|
|
107
|
+
)}`,
|
|
108
|
+
);
|
|
109
|
+
} else {
|
|
110
|
+
this.log.info(
|
|
111
|
+
`Starting job id=${this.currentJobController.getJobId()} type=${this.currentJobController.getProofTypeName()} inputsUri=${truncateString(
|
|
112
|
+
job.inputsUri,
|
|
113
|
+
)}`,
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
85
117
|
this.currentJobController.start();
|
|
86
118
|
} catch (err) {
|
|
87
119
|
this.log.error(`Error in ProvingAgent: ${String(err)}`);
|
|
88
120
|
}
|
|
89
121
|
};
|
|
122
|
+
|
|
123
|
+
handleJobResult = async <T extends ProvingRequestType>(
|
|
124
|
+
jobId: ProvingJobId,
|
|
125
|
+
type: T,
|
|
126
|
+
err: Error | undefined,
|
|
127
|
+
result: ProvingJobResultsMap[T] | undefined,
|
|
128
|
+
) => {
|
|
129
|
+
if (err) {
|
|
130
|
+
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}`);
|
|
132
|
+
return this.broker.reportProvingJobError(jobId, err.message, retry);
|
|
133
|
+
} else if (result) {
|
|
134
|
+
const outputUri = await this.proofStore.saveProofOutput(jobId, type, result);
|
|
135
|
+
this.log.info(
|
|
136
|
+
`Job id=${jobId} type=${ProvingRequestType[type]} completed outputUri=${truncateString(outputUri)}`,
|
|
137
|
+
);
|
|
138
|
+
return this.broker.reportProvingJobSuccess(jobId, outputUri);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function truncateString(str: string, length: number = 64): string {
|
|
144
|
+
return str.length > length ? str.slice(0, length) + '...' : str;
|
|
90
145
|
}
|
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type ProofUri,
|
|
3
|
+
type ProvingJob,
|
|
4
|
+
type ProvingJobConsumer,
|
|
5
|
+
type ProvingJobFilter,
|
|
6
|
+
type ProvingJobId,
|
|
7
|
+
type ProvingJobProducer,
|
|
8
|
+
type ProvingJobSettledResult,
|
|
9
|
+
type ProvingJobStatus,
|
|
2
10
|
ProvingRequestType,
|
|
3
|
-
type V2ProofOutput,
|
|
4
|
-
type V2ProvingJob,
|
|
5
|
-
type V2ProvingJobId,
|
|
6
|
-
type V2ProvingJobResult,
|
|
7
|
-
type V2ProvingJobStatus,
|
|
8
11
|
} from '@aztec/circuit-types';
|
|
9
12
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
10
|
-
import { RunningPromise } from '@aztec/foundation/promise';
|
|
13
|
+
import { type PromiseWithResolvers, RunningPromise, promiseWithResolvers } from '@aztec/foundation/promise';
|
|
11
14
|
import { PriorityMemoryQueue } from '@aztec/foundation/queue';
|
|
12
15
|
|
|
13
16
|
import assert from 'assert';
|
|
14
17
|
|
|
15
|
-
import
|
|
16
|
-
import { type ProvingJobDatabase } from './proving_job_database.js';
|
|
18
|
+
import { type ProvingBrokerDatabase } from './proving_broker_database.js';
|
|
17
19
|
|
|
18
20
|
type InProgressMetadata = {
|
|
19
|
-
id:
|
|
21
|
+
id: ProvingJobId;
|
|
20
22
|
startedAt: number;
|
|
21
23
|
lastUpdatedAt: number;
|
|
22
24
|
};
|
|
23
25
|
|
|
24
26
|
type ProofRequestBrokerConfig = {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
timeoutIntervalMs?: number;
|
|
28
|
+
jobTimeoutMs?: number;
|
|
27
29
|
maxRetries?: number;
|
|
28
30
|
};
|
|
29
31
|
|
|
@@ -33,50 +35,53 @@ type ProofRequestBrokerConfig = {
|
|
|
33
35
|
*/
|
|
34
36
|
export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
35
37
|
private queues: ProvingQueues = {
|
|
36
|
-
[ProvingRequestType.PUBLIC_VM]: new PriorityMemoryQueue<
|
|
37
|
-
[ProvingRequestType.TUBE_PROOF]: new PriorityMemoryQueue<
|
|
38
|
-
[ProvingRequestType.PRIVATE_KERNEL_EMPTY]: new PriorityMemoryQueue<
|
|
38
|
+
[ProvingRequestType.PUBLIC_VM]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
39
|
+
[ProvingRequestType.TUBE_PROOF]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
40
|
+
[ProvingRequestType.PRIVATE_KERNEL_EMPTY]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
39
41
|
|
|
40
|
-
[ProvingRequestType.PRIVATE_BASE_ROLLUP]: new PriorityMemoryQueue<
|
|
41
|
-
[ProvingRequestType.PUBLIC_BASE_ROLLUP]: new PriorityMemoryQueue<
|
|
42
|
-
[ProvingRequestType.MERGE_ROLLUP]: new PriorityMemoryQueue<
|
|
43
|
-
[ProvingRequestType.ROOT_ROLLUP]: new PriorityMemoryQueue<
|
|
42
|
+
[ProvingRequestType.PRIVATE_BASE_ROLLUP]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
43
|
+
[ProvingRequestType.PUBLIC_BASE_ROLLUP]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
44
|
+
[ProvingRequestType.MERGE_ROLLUP]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
45
|
+
[ProvingRequestType.ROOT_ROLLUP]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
44
46
|
|
|
45
|
-
[ProvingRequestType.BLOCK_MERGE_ROLLUP]: new PriorityMemoryQueue<
|
|
46
|
-
[ProvingRequestType.BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<
|
|
47
|
-
[ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<
|
|
47
|
+
[ProvingRequestType.BLOCK_MERGE_ROLLUP]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
48
|
+
[ProvingRequestType.BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
49
|
+
[ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
48
50
|
|
|
49
|
-
[ProvingRequestType.BASE_PARITY]: new PriorityMemoryQueue<
|
|
50
|
-
[ProvingRequestType.ROOT_PARITY]: new PriorityMemoryQueue<
|
|
51
|
+
[ProvingRequestType.BASE_PARITY]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
52
|
+
[ProvingRequestType.ROOT_PARITY]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
51
53
|
};
|
|
52
54
|
|
|
53
55
|
// holds a copy of the database in memory in order to quickly fulfill requests
|
|
54
56
|
// this is fine because this broker is the only one that can modify the database
|
|
55
|
-
private jobsCache = new Map<
|
|
57
|
+
private jobsCache = new Map<ProvingJobId, ProvingJob>();
|
|
56
58
|
// as above, but for results
|
|
57
|
-
private resultsCache = new Map<
|
|
59
|
+
private resultsCache = new Map<ProvingJobId, ProvingJobSettledResult>();
|
|
58
60
|
|
|
59
61
|
// keeps track of which jobs are currently being processed
|
|
60
62
|
// in the event of a crash this information is lost, but that's ok
|
|
61
63
|
// the next time the broker starts it will recreate jobsCache and still
|
|
62
64
|
// accept results from the workers
|
|
63
|
-
private inProgress = new Map<
|
|
65
|
+
private inProgress = new Map<ProvingJobId, InProgressMetadata>();
|
|
64
66
|
|
|
65
67
|
// keep track of which proving job has been retried
|
|
66
|
-
private retries = new Map<
|
|
68
|
+
private retries = new Map<ProvingJobId, number>();
|
|
69
|
+
|
|
70
|
+
// a map of promises that will be resolved when a job is settled
|
|
71
|
+
private promises = new Map<ProvingJobId, PromiseWithResolvers<ProvingJobSettledResult>>();
|
|
67
72
|
|
|
68
73
|
private timeoutPromise: RunningPromise;
|
|
69
74
|
private timeSource = () => Math.floor(Date.now() / 1000);
|
|
70
|
-
private
|
|
75
|
+
private jobTimeoutMs: number;
|
|
71
76
|
private maxRetries: number;
|
|
72
77
|
|
|
73
78
|
public constructor(
|
|
74
|
-
private database:
|
|
75
|
-
{
|
|
76
|
-
private logger = createDebugLogger('aztec:prover-client:
|
|
79
|
+
private database: ProvingBrokerDatabase,
|
|
80
|
+
{ jobTimeoutMs = 30, timeoutIntervalMs = 10, maxRetries = 3 }: ProofRequestBrokerConfig = {},
|
|
81
|
+
private logger = createDebugLogger('aztec:prover-client:proving-broker'),
|
|
77
82
|
) {
|
|
78
|
-
this.timeoutPromise = new RunningPromise(this.timeoutCheck,
|
|
79
|
-
this.
|
|
83
|
+
this.timeoutPromise = new RunningPromise(this.timeoutCheck, timeoutIntervalMs);
|
|
84
|
+
this.jobTimeoutMs = jobTimeoutMs;
|
|
80
85
|
this.maxRetries = maxRetries;
|
|
81
86
|
}
|
|
82
87
|
|
|
@@ -86,7 +91,10 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
86
91
|
this.logger.info(`Restoring proving job id=${item.id} settled=${!!result}`);
|
|
87
92
|
|
|
88
93
|
this.jobsCache.set(item.id, item);
|
|
94
|
+
this.promises.set(item.id, promiseWithResolvers());
|
|
95
|
+
|
|
89
96
|
if (result) {
|
|
97
|
+
this.promises.get(item.id)!.resolve(result);
|
|
90
98
|
this.resultsCache.set(item.id, result);
|
|
91
99
|
} else {
|
|
92
100
|
this.logger.debug(`Re-enqueuing proving job id=${item.id}`);
|
|
@@ -101,7 +109,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
101
109
|
return this.timeoutPromise.stop();
|
|
102
110
|
}
|
|
103
111
|
|
|
104
|
-
public async enqueueProvingJob(job:
|
|
112
|
+
public async enqueueProvingJob(job: ProvingJob): Promise<void> {
|
|
105
113
|
if (this.jobsCache.has(job.id)) {
|
|
106
114
|
const existing = this.jobsCache.get(job.id);
|
|
107
115
|
assert.deepStrictEqual(job, existing, 'Duplicate proving job ID');
|
|
@@ -113,20 +121,35 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
113
121
|
this.enqueueJobInternal(job);
|
|
114
122
|
}
|
|
115
123
|
|
|
116
|
-
public
|
|
124
|
+
public waitForJobToSettle(id: ProvingJobId): Promise<ProvingJobSettledResult> {
|
|
125
|
+
const promiseWithResolvers = this.promises.get(id);
|
|
126
|
+
if (!promiseWithResolvers) {
|
|
127
|
+
return Promise.resolve({ status: 'rejected', reason: `Job ${id} not found` });
|
|
128
|
+
}
|
|
129
|
+
return promiseWithResolvers.promise;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
public async removeAndCancelProvingJob(id: ProvingJobId): Promise<void> {
|
|
117
133
|
this.logger.info(`Cancelling job id=${id}`);
|
|
118
134
|
await this.database.deleteProvingJobAndResult(id);
|
|
119
135
|
|
|
136
|
+
// notify listeners of the cancellation
|
|
137
|
+
if (!this.resultsCache.has(id)) {
|
|
138
|
+
this.promises.get(id)?.resolve({ status: 'rejected', reason: 'Aborted' });
|
|
139
|
+
}
|
|
140
|
+
|
|
120
141
|
this.jobsCache.delete(id);
|
|
142
|
+
this.promises.delete(id);
|
|
121
143
|
this.resultsCache.delete(id);
|
|
122
144
|
this.inProgress.delete(id);
|
|
123
145
|
this.retries.delete(id);
|
|
124
146
|
}
|
|
125
147
|
|
|
126
|
-
|
|
127
|
-
public async getProvingJobStatus(id: V2ProvingJobId): Promise<V2ProvingJobStatus> {
|
|
148
|
+
public getProvingJobStatus(id: ProvingJobId): Promise<ProvingJobStatus> {
|
|
128
149
|
const result = this.resultsCache.get(id);
|
|
129
|
-
if (
|
|
150
|
+
if (result) {
|
|
151
|
+
return Promise.resolve(result);
|
|
152
|
+
} else {
|
|
130
153
|
// no result yet, check if we know the item
|
|
131
154
|
const item = this.jobsCache.get(id);
|
|
132
155
|
|
|
@@ -136,29 +159,26 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
136
159
|
}
|
|
137
160
|
|
|
138
161
|
return Promise.resolve({ status: this.inProgress.has(id) ? 'in-progress' : 'in-queue' });
|
|
139
|
-
} else if ('value' in result) {
|
|
140
|
-
return Promise.resolve({ status: 'resolved', value: result.value });
|
|
141
|
-
} else {
|
|
142
|
-
return Promise.resolve({ status: 'rejected', error: result.error });
|
|
143
162
|
}
|
|
144
163
|
}
|
|
145
164
|
|
|
146
165
|
// eslint-disable-next-line require-await
|
|
147
|
-
async getProvingJob
|
|
148
|
-
filter: ProvingJobFilter
|
|
149
|
-
): Promise<{ job:
|
|
150
|
-
const allowedProofs: ProvingRequestType[] =
|
|
151
|
-
|
|
152
|
-
|
|
166
|
+
async getProvingJob(
|
|
167
|
+
filter: ProvingJobFilter = { allowList: [] },
|
|
168
|
+
): Promise<{ job: ProvingJob; time: number } | undefined> {
|
|
169
|
+
const allowedProofs: ProvingRequestType[] =
|
|
170
|
+
Array.isArray(filter.allowList) && filter.allowList.length > 0
|
|
171
|
+
? [...filter.allowList]
|
|
172
|
+
: Object.values(ProvingRequestType).filter((x): x is ProvingRequestType => typeof x === 'number');
|
|
153
173
|
allowedProofs.sort(proofTypeComparator);
|
|
154
174
|
|
|
155
175
|
for (const proofType of allowedProofs) {
|
|
156
176
|
const queue = this.queues[proofType];
|
|
157
|
-
let job:
|
|
177
|
+
let job: ProvingJob | undefined;
|
|
158
178
|
// exhaust the queue and make sure we're not sending a job that's already in progress
|
|
159
179
|
// or has already been completed
|
|
160
180
|
// this can happen if the broker crashes and restarts
|
|
161
|
-
// it's possible agents will report progress or results for jobs that are
|
|
181
|
+
// it's possible agents will report progress or results for jobs that are in the queue (after the restart)
|
|
162
182
|
while ((job = queue.getImmediate())) {
|
|
163
183
|
if (!this.inProgress.has(job.id) && !this.resultsCache.has(job.id)) {
|
|
164
184
|
const time = this.timeSource();
|
|
@@ -176,7 +196,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
176
196
|
return undefined;
|
|
177
197
|
}
|
|
178
198
|
|
|
179
|
-
async reportProvingJobError(id:
|
|
199
|
+
async reportProvingJobError(id: ProvingJobId, err: string, retry = false): Promise<void> {
|
|
180
200
|
const info = this.inProgress.get(id);
|
|
181
201
|
const item = this.jobsCache.get(id);
|
|
182
202
|
const retries = this.retries.get(id) ?? 0;
|
|
@@ -202,15 +222,19 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
202
222
|
this.logger.debug(
|
|
203
223
|
`Marking proving job id=${id} type=${ProvingRequestType[item.type]} totalAttempts=${retries + 1} as failed`,
|
|
204
224
|
);
|
|
225
|
+
|
|
205
226
|
await this.database.setProvingJobError(id, err);
|
|
206
|
-
|
|
227
|
+
|
|
228
|
+
const result: ProvingJobSettledResult = { status: 'rejected', reason: String(err) };
|
|
229
|
+
this.resultsCache.set(id, result);
|
|
230
|
+
this.promises.get(id)!.resolve(result);
|
|
207
231
|
}
|
|
208
232
|
|
|
209
|
-
reportProvingJobProgress
|
|
210
|
-
id:
|
|
233
|
+
reportProvingJobProgress(
|
|
234
|
+
id: ProvingJobId,
|
|
211
235
|
startedAt: number,
|
|
212
|
-
filter?: ProvingJobFilter
|
|
213
|
-
): Promise<{ job:
|
|
236
|
+
filter?: ProvingJobFilter,
|
|
237
|
+
): Promise<{ job: ProvingJob; time: number } | undefined> {
|
|
214
238
|
const job = this.jobsCache.get(id);
|
|
215
239
|
if (!job) {
|
|
216
240
|
this.logger.warn(`Proving job id=${id} does not exist`);
|
|
@@ -255,7 +279,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
255
279
|
}
|
|
256
280
|
}
|
|
257
281
|
|
|
258
|
-
async reportProvingJobSuccess(id:
|
|
282
|
+
async reportProvingJobSuccess(id: ProvingJobId, value: ProofUri): Promise<void> {
|
|
259
283
|
const info = this.inProgress.get(id);
|
|
260
284
|
const item = this.jobsCache.get(id);
|
|
261
285
|
const retries = this.retries.get(id) ?? 0;
|
|
@@ -273,8 +297,12 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
273
297
|
this.logger.debug(
|
|
274
298
|
`Proving job complete id=${id} type=${ProvingRequestType[item.type]} totalAttempts=${retries + 1}`,
|
|
275
299
|
);
|
|
300
|
+
|
|
276
301
|
await this.database.setProvingJobResult(id, value);
|
|
277
|
-
|
|
302
|
+
|
|
303
|
+
const result: ProvingJobSettledResult = { status: 'fulfilled', value };
|
|
304
|
+
this.resultsCache.set(id, result);
|
|
305
|
+
this.promises.get(id)!.resolve(result);
|
|
278
306
|
}
|
|
279
307
|
|
|
280
308
|
private timeoutCheck = () => {
|
|
@@ -287,8 +315,8 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
287
315
|
continue;
|
|
288
316
|
}
|
|
289
317
|
|
|
290
|
-
const
|
|
291
|
-
if (
|
|
318
|
+
const msSinceLastUpdate = (this.timeSource() - metadata.lastUpdatedAt) * 1000;
|
|
319
|
+
if (msSinceLastUpdate >= this.jobTimeoutMs) {
|
|
292
320
|
this.logger.warn(`Proving job id=${id} timed out. Adding it back to the queue.`);
|
|
293
321
|
this.inProgress.delete(id);
|
|
294
322
|
this.enqueueJobInternal(item);
|
|
@@ -296,14 +324,17 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
296
324
|
}
|
|
297
325
|
};
|
|
298
326
|
|
|
299
|
-
private enqueueJobInternal(job:
|
|
327
|
+
private enqueueJobInternal(job: ProvingJob): void {
|
|
328
|
+
if (!this.promises.has(job.id)) {
|
|
329
|
+
this.promises.set(job.id, promiseWithResolvers());
|
|
330
|
+
}
|
|
300
331
|
this.queues[job.type].put(job);
|
|
301
332
|
this.logger.debug(`Enqueued new proving job id=${job.id}`);
|
|
302
333
|
}
|
|
303
334
|
}
|
|
304
335
|
|
|
305
336
|
type ProvingQueues = {
|
|
306
|
-
[K in ProvingRequestType]: PriorityMemoryQueue<
|
|
337
|
+
[K in ProvingRequestType]: PriorityMemoryQueue<ProvingJob>;
|
|
307
338
|
};
|
|
308
339
|
|
|
309
340
|
/**
|
|
@@ -312,10 +343,12 @@ type ProvingQueues = {
|
|
|
312
343
|
* @param b - Another proving job
|
|
313
344
|
* @returns A number indicating the relative priority of the two proving jobs
|
|
314
345
|
*/
|
|
315
|
-
function provingJobComparator(a:
|
|
316
|
-
|
|
346
|
+
function provingJobComparator(a: ProvingJob, b: ProvingJob): -1 | 0 | 1 {
|
|
347
|
+
const aBlockNumber = a.blockNumber ?? 0;
|
|
348
|
+
const bBlockNumber = b.blockNumber ?? 0;
|
|
349
|
+
if (aBlockNumber < bBlockNumber) {
|
|
317
350
|
return -1;
|
|
318
|
-
} else if (
|
|
351
|
+
} else if (aBlockNumber > bBlockNumber) {
|
|
319
352
|
return 1;
|
|
320
353
|
} else {
|
|
321
354
|
return 0;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ProofUri, ProvingJob, ProvingJobId, ProvingJobSettledResult } from '@aztec/circuit-types';
|
|
2
|
+
|
|
3
|
+
import { type ProvingBrokerDatabase } from '../proving_broker_database.js';
|
|
4
|
+
|
|
5
|
+
export class InMemoryBrokerDatabase implements ProvingBrokerDatabase {
|
|
6
|
+
private jobs = new Map<ProvingJobId, ProvingJob>();
|
|
7
|
+
private results = new Map<ProvingJobId, ProvingJobSettledResult>();
|
|
8
|
+
|
|
9
|
+
getProvingJob(id: ProvingJobId): ProvingJob | undefined {
|
|
10
|
+
return this.jobs.get(id);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
getProvingJobResult(id: ProvingJobId): ProvingJobSettledResult | undefined {
|
|
14
|
+
return this.results.get(id);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
addProvingJob(request: ProvingJob): Promise<void> {
|
|
18
|
+
this.jobs.set(request.id, request);
|
|
19
|
+
return Promise.resolve();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
setProvingJobResult(id: ProvingJobId, value: ProofUri): Promise<void> {
|
|
23
|
+
this.results.set(id, { status: 'fulfilled', value });
|
|
24
|
+
return Promise.resolve();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setProvingJobError(id: ProvingJobId, reason: string): Promise<void> {
|
|
28
|
+
this.results.set(id, { status: 'rejected', reason });
|
|
29
|
+
return Promise.resolve();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
deleteProvingJobAndResult(id: ProvingJobId): Promise<void> {
|
|
33
|
+
this.jobs.delete(id);
|
|
34
|
+
this.results.delete(id);
|
|
35
|
+
return Promise.resolve();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
*allProvingJobs(): Iterable<[ProvingJob, ProvingJobSettledResult | undefined]> {
|
|
39
|
+
for (const item of this.jobs.values()) {
|
|
40
|
+
yield [item, this.results.get(item.id)] as const;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type ProofUri, ProvingJob, type ProvingJobId, ProvingJobSettledResult } from '@aztec/circuit-types';
|
|
2
|
+
import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
|
|
3
|
+
import { type AztecKVStore, type AztecMap } from '@aztec/kv-store';
|
|
4
|
+
|
|
5
|
+
import { type ProvingBrokerDatabase } from '../proving_broker_database.js';
|
|
6
|
+
|
|
7
|
+
export class KVBrokerDatabase implements ProvingBrokerDatabase {
|
|
8
|
+
private jobs: AztecMap<ProvingJobId, string>;
|
|
9
|
+
private jobResults: AztecMap<ProvingJobId, string>;
|
|
10
|
+
|
|
11
|
+
constructor(private store: AztecKVStore) {
|
|
12
|
+
this.jobs = store.openMap('proving_jobs');
|
|
13
|
+
this.jobResults = store.openMap('proving_job_results');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async addProvingJob(job: ProvingJob): Promise<void> {
|
|
17
|
+
await this.jobs.set(job.id, jsonStringify(job));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
*allProvingJobs(): Iterable<[ProvingJob, ProvingJobSettledResult | undefined]> {
|
|
21
|
+
for (const jobStr of this.jobs.values()) {
|
|
22
|
+
const job = jsonParseWithSchema(jobStr, ProvingJob);
|
|
23
|
+
const resultStr = this.jobResults.get(job.id);
|
|
24
|
+
const result = resultStr ? jsonParseWithSchema(resultStr, ProvingJobSettledResult) : undefined;
|
|
25
|
+
yield [job, result];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
deleteProvingJobAndResult(id: ProvingJobId): Promise<void> {
|
|
30
|
+
return this.store.transaction(() => {
|
|
31
|
+
void this.jobs.delete(id);
|
|
32
|
+
void this.jobResults.delete(id);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async setProvingJobError(id: ProvingJobId, reason: string): Promise<void> {
|
|
37
|
+
const result: ProvingJobSettledResult = { status: 'rejected', reason };
|
|
38
|
+
await this.jobResults.set(id, jsonStringify(result));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async setProvingJobResult(id: ProvingJobId, value: ProofUri): Promise<void> {
|
|
42
|
+
const result: ProvingJobSettledResult = { status: 'fulfilled', value };
|
|
43
|
+
await this.jobResults.set(id, jsonStringify(result));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -1,30 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type V2ProofOutput,
|
|
3
|
-
type V2ProvingJob,
|
|
4
|
-
type V2ProvingJobId,
|
|
5
|
-
type V2ProvingJobResult,
|
|
6
|
-
} from '@aztec/circuit-types';
|
|
1
|
+
import { type ProofUri, type ProvingJob, type ProvingJobId, type ProvingJobSettledResult } from '@aztec/circuit-types';
|
|
7
2
|
|
|
8
3
|
/**
|
|
9
4
|
* A database for storing proof requests and their results
|
|
10
5
|
*/
|
|
11
|
-
export interface
|
|
6
|
+
export interface ProvingBrokerDatabase {
|
|
12
7
|
/**
|
|
13
8
|
* Saves a proof request so it can be retrieved later
|
|
14
9
|
* @param request - The proof request to save
|
|
15
10
|
*/
|
|
16
|
-
addProvingJob(request:
|
|
11
|
+
addProvingJob(request: ProvingJob): Promise<void>;
|
|
17
12
|
|
|
18
13
|
/**
|
|
19
14
|
* Removes a proof request from the backend
|
|
20
15
|
* @param id - The ID of the proof request to remove
|
|
21
16
|
*/
|
|
22
|
-
deleteProvingJobAndResult(id:
|
|
17
|
+
deleteProvingJobAndResult(id: ProvingJobId): Promise<void>;
|
|
23
18
|
|
|
24
19
|
/**
|
|
25
20
|
* Returns an iterator over all saved proving jobs
|
|
26
21
|
*/
|
|
27
|
-
allProvingJobs(): Iterable<[
|
|
22
|
+
allProvingJobs(): Iterable<[ProvingJob, ProvingJobSettledResult | undefined]>;
|
|
28
23
|
|
|
29
24
|
/**
|
|
30
25
|
* Saves the result of a proof request
|
|
@@ -32,7 +27,7 @@ export interface ProvingJobDatabase {
|
|
|
32
27
|
* @param ProvingRequestType - The type of proof that was requested
|
|
33
28
|
* @param value - The result of the proof request
|
|
34
29
|
*/
|
|
35
|
-
setProvingJobResult(id:
|
|
30
|
+
setProvingJobResult(id: ProvingJobId, value: ProofUri): Promise<void>;
|
|
36
31
|
|
|
37
32
|
/**
|
|
38
33
|
* Saves an error that occurred while processing a proof request
|
|
@@ -40,5 +35,5 @@ export interface ProvingJobDatabase {
|
|
|
40
35
|
* @param ProvingRequestType - The type of proof that was requested
|
|
41
36
|
* @param err - The error that occurred while processing the proof request
|
|
42
37
|
*/
|
|
43
|
-
setProvingJobError(id:
|
|
38
|
+
setProvingJobError(id: ProvingJobId, err: string): Promise<void>;
|
|
44
39
|
}
|