@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,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.
|
|
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.
|
|
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
|
|
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.
|
|
139
|
-
const type
|
|
140
|
-
const
|
|
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.
|
|
151
|
+
const type = ProvingRequestType[job.type];
|
|
153
152
|
if (this.#isRunning()) {
|
|
154
|
-
if (job.
|
|
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
|
|
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
|
+
}
|