@aztec/prover-client 0.0.0-test.1 → 0.0.1-fake-ceab37513c
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.js +1 -1
- package/dest/block-factory/index.d.ts +2 -0
- package/dest/block-factory/index.d.ts.map +1 -0
- package/dest/block-factory/light.d.ts +36 -0
- package/dest/block-factory/light.d.ts.map +1 -0
- package/dest/{block_builder → block-factory}/light.js +35 -30
- package/dest/config.d.ts +6 -6
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +11 -1
- package/dest/mocks/fixtures.d.ts +3 -3
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +2 -2
- package/dest/mocks/test_context.d.ts +18 -13
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +44 -38
- package/dest/orchestrator/block-building-helpers.d.ts +18 -11
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +80 -63
- package/dest/orchestrator/block-proving-state.d.ts +19 -10
- package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/block-proving-state.js +63 -46
- package/dest/orchestrator/epoch-proving-state.d.ts +13 -6
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/epoch-proving-state.js +40 -14
- package/dest/orchestrator/orchestrator.d.ts +7 -5
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +78 -52
- package/dest/orchestrator/orchestrator_metrics.d.ts +2 -0
- package/dest/orchestrator/orchestrator_metrics.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator_metrics.js +9 -0
- package/dest/orchestrator/tx-proving-state.d.ts +2 -2
- package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/tx-proving-state.js +9 -20
- package/dest/prover-client/prover-client.d.ts +3 -3
- package/dest/prover-client/prover-client.d.ts.map +1 -1
- package/dest/prover-client/prover-client.js +5 -4
- package/dest/prover-client/server-epoch-prover.d.ts +6 -4
- package/dest/prover-client/server-epoch-prover.d.ts.map +1 -1
- package/dest/prover-client/server-epoch-prover.js +4 -4
- package/dest/proving_broker/broker_prover_facade.d.ts +5 -3
- package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
- package/dest/proving_broker/broker_prover_facade.js +31 -21
- package/dest/proving_broker/config.d.ts +9 -4
- package/dest/proving_broker/config.d.ts.map +1 -1
- package/dest/proving_broker/config.js +15 -4
- 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 +5 -1
- package/dest/proving_broker/proof_store/factory.js +1 -1
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +1 -1
- package/dest/proving_broker/proof_store/gcs_proof_store.js +1 -0
- package/dest/proving_broker/proving_agent.d.ts +3 -3
- package/dest/proving_broker/proving_agent.d.ts.map +1 -1
- package/dest/proving_broker/proving_agent.js +83 -47
- package/dest/proving_broker/proving_broker.d.ts +11 -2
- package/dest/proving_broker/proving_broker.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker.js +6 -5
- package/dest/proving_broker/proving_broker_database/memory.js +1 -1
- package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_database/persisted.js +9 -8
- package/dest/proving_broker/proving_job_controller.d.ts +7 -8
- package/dest/proving_broker/proving_job_controller.d.ts.map +1 -1
- package/dest/proving_broker/proving_job_controller.js +53 -45
- package/dest/proving_broker/rpc.d.ts +3 -5
- package/dest/proving_broker/rpc.d.ts.map +1 -1
- package/dest/proving_broker/rpc.js +1 -4
- package/dest/test/mock_proof_store.d.ts +9 -0
- package/dest/test/mock_proof_store.d.ts.map +1 -0
- package/dest/test/mock_proof_store.js +10 -0
- package/dest/test/mock_prover.d.ts +7 -5
- package/dest/test/mock_prover.d.ts.map +1 -1
- package/dest/test/mock_prover.js +6 -3
- package/package.json +28 -27
- package/src/bin/get-proof-inputs.ts +1 -1
- package/src/block-factory/index.ts +1 -0
- package/src/{block_builder → block-factory}/light.ts +42 -29
- package/src/config.ts +24 -8
- package/src/mocks/fixtures.ts +5 -5
- package/src/mocks/test_context.ts +79 -59
- package/src/orchestrator/block-building-helpers.ts +96 -92
- package/src/orchestrator/block-proving-state.ts +78 -52
- package/src/orchestrator/epoch-proving-state.ts +51 -20
- package/src/orchestrator/orchestrator.ts +119 -60
- package/src/orchestrator/orchestrator_metrics.ts +20 -1
- package/src/orchestrator/tx-proving-state.ts +17 -24
- package/src/prover-client/prover-client.ts +16 -14
- package/src/prover-client/server-epoch-prover.ts +16 -7
- package/src/proving_broker/broker_prover_facade.ts +52 -36
- package/src/proving_broker/config.ts +17 -6
- package/src/proving_broker/factory.ts +2 -1
- package/src/proving_broker/proof_store/factory.ts +1 -1
- package/src/proving_broker/proof_store/gcs_proof_store.ts +5 -1
- package/src/proving_broker/proof_store/inline_proof_store.ts +1 -1
- package/src/proving_broker/proving_agent.ts +89 -47
- package/src/proving_broker/proving_broker.ts +16 -15
- package/src/proving_broker/proving_broker_database/memory.ts +1 -1
- package/src/proving_broker/proving_broker_database/persisted.ts +9 -8
- package/src/proving_broker/proving_job_controller.ts +56 -65
- package/src/proving_broker/rpc.ts +1 -6
- package/src/test/mock_proof_store.ts +14 -0
- package/src/test/mock_prover.ts +27 -5
- package/dest/block_builder/index.d.ts +0 -6
- package/dest/block_builder/index.d.ts.map +0 -1
- package/dest/block_builder/light.d.ts +0 -33
- package/dest/block_builder/light.d.ts.map +0 -1
- package/src/block_builder/index.ts +0 -6
- /package/dest/{block_builder → block-factory}/index.js +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { BatchedBlob, FinalBlobBatchingChallenges } from '@aztec/blob-lib';
|
|
1
2
|
import type { Fr } from '@aztec/foundation/fields';
|
|
2
|
-
import type { L2Block } from '@aztec/stdlib/block';
|
|
3
|
+
import type { EthAddress, L2Block } from '@aztec/stdlib/block';
|
|
3
4
|
import type { EpochProver } from '@aztec/stdlib/interfaces/server';
|
|
4
5
|
import type { Proof } from '@aztec/stdlib/proofs';
|
|
5
6
|
import type { RootRollupPublicInputs } from '@aztec/stdlib/rollup';
|
|
@@ -10,10 +11,18 @@ import type { BrokerCircuitProverFacade } from '../proving_broker/broker_prover_
|
|
|
10
11
|
|
|
11
12
|
/** Encapsulates the proving orchestrator and the broker facade */
|
|
12
13
|
export class ServerEpochProver implements EpochProver {
|
|
13
|
-
constructor(
|
|
14
|
+
constructor(
|
|
15
|
+
private facade: BrokerCircuitProverFacade,
|
|
16
|
+
private orchestrator: ProvingOrchestrator,
|
|
17
|
+
) {}
|
|
14
18
|
|
|
15
|
-
startNewEpoch(
|
|
16
|
-
|
|
19
|
+
startNewEpoch(
|
|
20
|
+
epochNumber: number,
|
|
21
|
+
firstBlockNumber: number,
|
|
22
|
+
totalNumBlocks: number,
|
|
23
|
+
finalBlobBatchingChallenges: FinalBlobBatchingChallenges,
|
|
24
|
+
): void {
|
|
25
|
+
this.orchestrator.startNewEpoch(epochNumber, firstBlockNumber, totalNumBlocks, finalBlobBatchingChallenges);
|
|
17
26
|
this.facade.start();
|
|
18
27
|
}
|
|
19
28
|
startTubeCircuits(txs: Tx[]): Promise<void> {
|
|
@@ -22,13 +31,13 @@ export class ServerEpochProver implements EpochProver {
|
|
|
22
31
|
setBlockCompleted(blockNumber: number, expectedBlockHeader?: BlockHeader): Promise<L2Block> {
|
|
23
32
|
return this.orchestrator.setBlockCompleted(blockNumber, expectedBlockHeader);
|
|
24
33
|
}
|
|
25
|
-
|
|
26
|
-
return this.orchestrator.
|
|
34
|
+
finalizeEpoch(): Promise<{ publicInputs: RootRollupPublicInputs; proof: Proof; batchedBlobInputs: BatchedBlob }> {
|
|
35
|
+
return this.orchestrator.finalizeEpoch();
|
|
27
36
|
}
|
|
28
37
|
cancel(): void {
|
|
29
38
|
this.orchestrator.cancel();
|
|
30
39
|
}
|
|
31
|
-
getProverId():
|
|
40
|
+
getProverId(): EthAddress {
|
|
32
41
|
return this.orchestrator.getProverId();
|
|
33
42
|
}
|
|
34
43
|
getBlock(index: number): L2Block {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
2
|
+
AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED,
|
|
3
3
|
NESTED_RECURSIVE_PROOF_LENGTH,
|
|
4
4
|
NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
|
|
5
5
|
RECURSIVE_PROOF_LENGTH,
|
|
6
6
|
TUBE_PROOF_LENGTH,
|
|
7
7
|
} from '@aztec/constants';
|
|
8
8
|
import { sha256 } from '@aztec/foundation/crypto';
|
|
9
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
9
10
|
import { createLogger } from '@aztec/foundation/log';
|
|
10
11
|
import { type PromiseWithResolvers, RunningPromise, promiseWithResolvers } from '@aztec/foundation/promise';
|
|
11
12
|
import { truncate } from '@aztec/foundation/string';
|
|
@@ -31,6 +32,7 @@ import type {
|
|
|
31
32
|
BlockRootRollupInputs,
|
|
32
33
|
EmptyBlockRootRollupInputs,
|
|
33
34
|
MergeRollupInputs,
|
|
35
|
+
PaddingBlockRootRollupInputs,
|
|
34
36
|
PrivateBaseRollupInputs,
|
|
35
37
|
PublicBaseRollupInputs,
|
|
36
38
|
RootRollupInputs,
|
|
@@ -93,7 +95,15 @@ export class BrokerCircuitProverFacade implements ServerCircuitProver {
|
|
|
93
95
|
|
|
94
96
|
// Create a promise for this job id, regardless of whether it was enqueued at the broker
|
|
95
97
|
// The running promise will monitor for the job to be completed and resolve it either way
|
|
98
|
+
// We install an error handler to prevent unhandled rejections in the process before the
|
|
99
|
+
// job promise is awaited by the caller (see #13166)
|
|
96
100
|
const promise = promiseWithResolvers<ProvingJobResultsMap[T]>();
|
|
101
|
+
promise.promise.catch(err =>
|
|
102
|
+
this.log.error(`Job errored with '${err.message ?? err}' id=${id} type=${ProvingRequestType[type]}`, {
|
|
103
|
+
provingJobId: id,
|
|
104
|
+
provingJobType: ProvingRequestType[type],
|
|
105
|
+
}),
|
|
106
|
+
);
|
|
97
107
|
const abortFn = () => {
|
|
98
108
|
signal?.removeEventListener('abort', abortFn);
|
|
99
109
|
void this.broker.cancelProvingJob(id).catch(err => this.log.warn(`Error cancelling job id=${id}`, err));
|
|
@@ -125,27 +135,26 @@ export class BrokerCircuitProverFacade implements ServerCircuitProver {
|
|
|
125
135
|
try {
|
|
126
136
|
const inputsUri = await this.proofStore.saveProofInput(id, type, inputs);
|
|
127
137
|
job.inputsUri = inputsUri;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
138
|
+
|
|
139
|
+
// Send the job to the broker
|
|
140
|
+
const jobStatus = await this.broker.enqueueProvingJob({ id, type, inputsUri, epochNumber });
|
|
141
|
+
|
|
142
|
+
const jobLogText = `id=${id} type=${ProvingRequestType[type]} epochNumber=${epochNumber}`;
|
|
143
|
+
const jobLogData = {
|
|
144
|
+
provingJobId: id,
|
|
145
|
+
provingJobType: ProvingRequestType[type],
|
|
132
146
|
epochNumber,
|
|
133
|
-
|
|
147
|
+
inputsUri: truncate(inputsUri),
|
|
148
|
+
status: jobStatus.status,
|
|
149
|
+
numOutstandingJobs: this.jobs.size,
|
|
150
|
+
};
|
|
134
151
|
|
|
135
152
|
// If we are here then the job was successfully accepted by the broker
|
|
136
153
|
// the returned status is for before any action was performed
|
|
137
154
|
if (jobStatus.status === 'fulfilled' || jobStatus.status === 'rejected') {
|
|
138
155
|
// Job was already completed by the broker
|
|
139
156
|
// No need to notify the broker on aborted job
|
|
140
|
-
this.log.verbose(
|
|
141
|
-
`Job already completed when sent to broker id=${id} type=${ProvingRequestType[type]} epochNumber=${epochNumber}`,
|
|
142
|
-
{
|
|
143
|
-
provingJobId: id,
|
|
144
|
-
provingJobType: ProvingRequestType[type],
|
|
145
|
-
epochNumber,
|
|
146
|
-
inputsUri: truncate(inputsUri),
|
|
147
|
-
},
|
|
148
|
-
);
|
|
157
|
+
this.log.verbose(`Job already completed when sent to broker ${jobLogText}`, jobLogData);
|
|
149
158
|
|
|
150
159
|
// Job was not enqueued. It must be completed already, add to our set of already completed jobs
|
|
151
160
|
this.jobsToRetrieve.add(id);
|
|
@@ -155,27 +164,10 @@ export class BrokerCircuitProverFacade implements ServerCircuitProver {
|
|
|
155
164
|
|
|
156
165
|
// Job added for the first time
|
|
157
166
|
if (jobStatus.status === 'not-found') {
|
|
158
|
-
this.log.verbose(
|
|
159
|
-
`Job enqueued with broker id=${id} type=${ProvingRequestType[type]} epochNumber=${epochNumber}`,
|
|
160
|
-
{
|
|
161
|
-
provingJobId: id,
|
|
162
|
-
provingJobType: ProvingRequestType[type],
|
|
163
|
-
epochNumber,
|
|
164
|
-
inputsUri: truncate(inputsUri),
|
|
165
|
-
numOutstandingJobs: this.jobs.size,
|
|
166
|
-
},
|
|
167
|
-
);
|
|
167
|
+
this.log.verbose(`Job enqueued with broker ${jobLogText}`, jobLogData);
|
|
168
168
|
} else {
|
|
169
169
|
// Job was previously sent to the broker but is not completed
|
|
170
|
-
this.log.verbose(
|
|
171
|
-
`Job already in queue or in progress when sent to broker id=${id} type=${ProvingRequestType[type]} epochNumber=${epochNumber}`,
|
|
172
|
-
{
|
|
173
|
-
provingJobId: id,
|
|
174
|
-
provingJobType: ProvingRequestType[type],
|
|
175
|
-
epochNumber,
|
|
176
|
-
inputsUri: truncate(inputsUri),
|
|
177
|
-
},
|
|
178
|
-
);
|
|
170
|
+
this.log.verbose(`Job already in queue or in progress when sent to broker ${jobLogText}`, jobLogData);
|
|
179
171
|
}
|
|
180
172
|
}
|
|
181
173
|
} catch (err) {
|
|
@@ -399,16 +391,24 @@ export class BrokerCircuitProverFacade implements ServerCircuitProver {
|
|
|
399
391
|
|
|
400
392
|
getAvmProof(
|
|
401
393
|
inputs: AvmCircuitInputs,
|
|
394
|
+
skipPublicInputsValidation?: boolean, // TODO(#14234)[Unconditional PIs validation]: remove this argument
|
|
402
395
|
signal?: AbortSignal,
|
|
403
396
|
epochNumber?: number,
|
|
404
|
-
): Promise<ProofAndVerificationKey<typeof
|
|
397
|
+
): Promise<ProofAndVerificationKey<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
|
|
398
|
+
this.log.info(`getAvmProof() called with skipPublicInputsValidation: ${skipPublicInputsValidation}`);
|
|
399
|
+
|
|
405
400
|
return this.enqueueJob(
|
|
406
401
|
this.generateId(ProvingRequestType.PUBLIC_VM, inputs, epochNumber),
|
|
407
402
|
ProvingRequestType.PUBLIC_VM,
|
|
408
403
|
inputs,
|
|
409
404
|
epochNumber,
|
|
410
405
|
signal,
|
|
411
|
-
)
|
|
406
|
+
).then(result => {
|
|
407
|
+
// TODO(#14234)[Unconditional PIs validation]: Remove ".then()".
|
|
408
|
+
// Override the default value of skipPublicInputsValidation potentially set in BBNativeRollupProver.getAvmProof().
|
|
409
|
+
result.proof.proof[0] = skipPublicInputsValidation ? new Fr(1) : new Fr(0);
|
|
410
|
+
return result;
|
|
411
|
+
});
|
|
412
412
|
}
|
|
413
413
|
|
|
414
414
|
getBaseParityProof(
|
|
@@ -489,6 +489,22 @@ export class BrokerCircuitProverFacade implements ServerCircuitProver {
|
|
|
489
489
|
);
|
|
490
490
|
}
|
|
491
491
|
|
|
492
|
+
getPaddingBlockRootRollupProof(
|
|
493
|
+
input: PaddingBlockRootRollupInputs,
|
|
494
|
+
signal?: AbortSignal,
|
|
495
|
+
epochNumber?: number,
|
|
496
|
+
): Promise<
|
|
497
|
+
PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
|
|
498
|
+
> {
|
|
499
|
+
return this.enqueueJob(
|
|
500
|
+
this.generateId(ProvingRequestType.PADDING_BLOCK_ROOT_ROLLUP, input, epochNumber),
|
|
501
|
+
ProvingRequestType.PADDING_BLOCK_ROOT_ROLLUP,
|
|
502
|
+
input,
|
|
503
|
+
epochNumber,
|
|
504
|
+
signal,
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
|
|
492
508
|
getMergeRollupProof(
|
|
493
509
|
input: MergeRollupInputs,
|
|
494
510
|
signal?: AbortSignal,
|
|
@@ -5,7 +5,9 @@ import {
|
|
|
5
5
|
getDefaultConfig,
|
|
6
6
|
numberConfigHelper,
|
|
7
7
|
} from '@aztec/foundation/config';
|
|
8
|
+
import { pickConfigMappings } from '@aztec/foundation/config';
|
|
8
9
|
import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
|
|
10
|
+
import { type ChainConfig, chainConfigMappings } from '@aztec/stdlib/config';
|
|
9
11
|
import { ProvingRequestType } from '@aztec/stdlib/proofs';
|
|
10
12
|
|
|
11
13
|
import { z } from 'zod';
|
|
@@ -20,7 +22,9 @@ export const ProverBrokerConfig = z.object({
|
|
|
20
22
|
/** If starting a prover broker locally, the directory to store broker data */
|
|
21
23
|
dataDirectory: z.string().optional(),
|
|
22
24
|
/** The size of the data store map */
|
|
23
|
-
|
|
25
|
+
dataStoreMapSizeKb: z.number().int().nonnegative(),
|
|
26
|
+
/** The size of the prover broker's database. Will override the dataStoreMapSizeKb if set. */
|
|
27
|
+
proverBrokerStoreMapSizeKb: z.number().int().nonnegative().optional(),
|
|
24
28
|
/** The prover broker may batch jobs together before writing to the database */
|
|
25
29
|
proverBrokerBatchSize: z.number().int().nonnegative(),
|
|
26
30
|
/** How often the job batches get flushed */
|
|
@@ -30,8 +34,9 @@ export const ProverBrokerConfig = z.object({
|
|
|
30
34
|
});
|
|
31
35
|
|
|
32
36
|
export type ProverBrokerConfig = z.infer<typeof ProverBrokerConfig> &
|
|
33
|
-
Pick<DataStoreConfig, '
|
|
34
|
-
L1ReaderConfig
|
|
37
|
+
Pick<DataStoreConfig, 'dataStoreMapSizeKb' | 'dataDirectory'> &
|
|
38
|
+
L1ReaderConfig &
|
|
39
|
+
Pick<ChainConfig, 'rollupVersion'>;
|
|
35
40
|
|
|
36
41
|
export const proverBrokerConfigMappings: ConfigMappingsType<ProverBrokerConfig> = {
|
|
37
42
|
proverBrokerJobTimeoutMs: {
|
|
@@ -64,8 +69,14 @@ export const proverBrokerConfigMappings: ConfigMappingsType<ProverBrokerConfig>
|
|
|
64
69
|
description: 'The maximum number of epochs to keep results for',
|
|
65
70
|
...numberConfigHelper(1),
|
|
66
71
|
},
|
|
67
|
-
|
|
72
|
+
proverBrokerStoreMapSizeKb: {
|
|
73
|
+
env: 'PROVER_BROKER_STORE_MAP_SIZE_KB',
|
|
74
|
+
parseEnv: (val: string | undefined) => (val ? +val : undefined),
|
|
75
|
+
description: "The size of the prover broker's database. Will override the dataStoreMapSizeKb if set.",
|
|
76
|
+
},
|
|
68
77
|
...dataConfigMappings,
|
|
78
|
+
...l1ReaderConfigMappings,
|
|
79
|
+
...pickConfigMappings(chainConfigMappings, ['rollupVersion']),
|
|
69
80
|
};
|
|
70
81
|
|
|
71
82
|
export const defaultProverBrokerConfig: ProverBrokerConfig = getDefaultConfig(proverBrokerConfigMappings);
|
|
@@ -100,7 +111,7 @@ export const proverAgentConfigMappings: ConfigMappingsType<ProverAgentConfig> =
|
|
|
100
111
|
proverAgentPollIntervalMs: {
|
|
101
112
|
env: 'PROVER_AGENT_POLL_INTERVAL_MS',
|
|
102
113
|
description: 'The interval agents poll for jobs at',
|
|
103
|
-
...numberConfigHelper(
|
|
114
|
+
...numberConfigHelper(1000),
|
|
104
115
|
},
|
|
105
116
|
proverAgentProofTypes: {
|
|
106
117
|
env: 'PROVER_AGENT_PROOF_TYPES',
|
|
@@ -118,7 +129,7 @@ export const proverAgentConfigMappings: ConfigMappingsType<ProverAgentConfig> =
|
|
|
118
129
|
realProofs: {
|
|
119
130
|
env: 'PROVER_REAL_PROOFS',
|
|
120
131
|
description: 'Whether to construct real proofs',
|
|
121
|
-
...booleanConfigHelper(
|
|
132
|
+
...booleanConfigHelper(true),
|
|
122
133
|
},
|
|
123
134
|
proverTestDelayType: {
|
|
124
135
|
env: 'PROVER_TEST_DELAY_TYPE',
|
|
@@ -6,9 +6,10 @@ import { InMemoryBrokerDatabase } from './proving_broker_database/memory.js';
|
|
|
6
6
|
import { KVBrokerDatabase } from './proving_broker_database/persisted.js';
|
|
7
7
|
|
|
8
8
|
export async function createAndStartProvingBroker(
|
|
9
|
-
|
|
9
|
+
_config: ProverBrokerConfig,
|
|
10
10
|
client: TelemetryClient,
|
|
11
11
|
): Promise<ProvingBroker> {
|
|
12
|
+
const config = { ..._config, dataStoreMapSizeKb: _config.proverBrokerStoreMapSizeKb ?? _config.dataStoreMapSizeKb };
|
|
12
13
|
const database = config.dataDirectory ? await KVBrokerDatabase.new(config, client) : new InMemoryBrokerDatabase();
|
|
13
14
|
|
|
14
15
|
const broker = new ProvingBroker(database, config, client);
|
|
@@ -15,7 +15,7 @@ export function createProofStore(config: string | undefined, logger = createLogg
|
|
|
15
15
|
const path = url.pathname.replace(/^\/+/, '');
|
|
16
16
|
logger.info(`Creating google cloud proof store at ${bucket}`, { bucket, path });
|
|
17
17
|
return new GoogleCloudStorageProofStore(bucket, path);
|
|
18
|
-
} catch
|
|
18
|
+
} catch {
|
|
19
19
|
throw new Error(
|
|
20
20
|
`Invalid google cloud proof store definition: '${config}'. Supported values are 'gs://bucket-name/path/to/store'.`,
|
|
21
21
|
);
|
|
@@ -16,10 +16,14 @@ import type { ProofStore } from './proof_store.js';
|
|
|
16
16
|
|
|
17
17
|
const INPUTS_PATH = 'inputs';
|
|
18
18
|
|
|
19
|
+
// REFACTOR(#13067): Use the stdlib/file-store instead of referencing google-cloud-storage directly.
|
|
19
20
|
export class GoogleCloudStorageProofStore implements ProofStore {
|
|
20
21
|
private readonly storage: Storage;
|
|
21
22
|
|
|
22
|
-
constructor(
|
|
23
|
+
constructor(
|
|
24
|
+
private readonly bucketName: string,
|
|
25
|
+
private readonly path: string,
|
|
26
|
+
) {
|
|
23
27
|
this.storage = new Storage();
|
|
24
28
|
}
|
|
25
29
|
|
|
@@ -52,7 +52,7 @@ export class InlineProofStore implements ProofStore {
|
|
|
52
52
|
return (PREFIX + SEPARATOR + encoded) as ProofUri;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
private decode<T>(uri: ProofUri, schema: ZodFor<T>):
|
|
55
|
+
private decode<T>(uri: ProofUri, schema: ZodFor<T>): T {
|
|
56
56
|
const [prefix, data] = uri.split(SEPARATOR);
|
|
57
57
|
if (prefix !== PREFIX) {
|
|
58
58
|
throw new Error('Invalid proof input URI: ' + prefix);
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { AbortError } from '@aztec/foundation/error';
|
|
1
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
3
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
3
4
|
import { truncate } from '@aztec/foundation/string';
|
|
4
|
-
import { Timer } from '@aztec/foundation/timer';
|
|
5
5
|
import { ProvingError } from '@aztec/stdlib/errors';
|
|
6
6
|
import type {
|
|
7
|
-
|
|
7
|
+
GetProvingJobResponse,
|
|
8
|
+
ProverAgentStatus,
|
|
8
9
|
ProvingJobConsumer,
|
|
9
10
|
ProvingJobId,
|
|
10
11
|
ProvingJobInputs,
|
|
@@ -31,7 +32,6 @@ export class ProvingAgent implements Traceable {
|
|
|
31
32
|
private currentJobController?: ProvingJobController;
|
|
32
33
|
private runningPromise: RunningPromise;
|
|
33
34
|
private instrumentation: ProvingAgentInstrumentation;
|
|
34
|
-
private idleTimer: Timer | undefined;
|
|
35
35
|
|
|
36
36
|
public readonly tracer: Tracer;
|
|
37
37
|
|
|
@@ -64,7 +64,6 @@ export class ProvingAgent implements Traceable {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
public start(): void {
|
|
67
|
-
this.idleTimer = new Timer();
|
|
68
67
|
this.runningPromise.start();
|
|
69
68
|
}
|
|
70
69
|
|
|
@@ -73,41 +72,78 @@ export class ProvingAgent implements Traceable {
|
|
|
73
72
|
await this.runningPromise.stop();
|
|
74
73
|
}
|
|
75
74
|
|
|
75
|
+
public getStatus(): ProverAgentStatus {
|
|
76
|
+
if (this.currentJobController) {
|
|
77
|
+
return {
|
|
78
|
+
status: 'proving',
|
|
79
|
+
jobId: this.currentJobController.getJobId(),
|
|
80
|
+
proofType: this.currentJobController.getProofType(),
|
|
81
|
+
startedAtISO: new Date(this.currentJobController.getStartedAt()).toISOString(),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return this.runningPromise.isRunning() ? { status: 'running' } : { status: 'stopped' };
|
|
86
|
+
}
|
|
87
|
+
|
|
76
88
|
@trackSpan('ProvingAgent.safeWork')
|
|
77
89
|
private async work() {
|
|
78
|
-
// every tick we need to
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
// every tick we need to take one of the following actions:
|
|
91
|
+
// 1. send a hearbeat to the broker that we're working on some job
|
|
92
|
+
// 2. if the job is complete, send its result to the broker
|
|
93
|
+
// 3. get a job from the broker
|
|
94
|
+
// Any one of these actions could give us a new job to work on. If that happens we abort the current job.
|
|
95
|
+
//
|
|
96
|
+
// This loop gets triggered in one of two ways:
|
|
97
|
+
// - either on a timer (see pollIntervalMs)
|
|
98
|
+
// - or when a proof completes
|
|
99
|
+
let maybeJob: GetProvingJobResponse | undefined;
|
|
100
|
+
|
|
101
|
+
if (this.currentJobController) {
|
|
102
|
+
const status = this.currentJobController.getStatus();
|
|
103
|
+
const jobId = this.currentJobController.getJobId();
|
|
104
|
+
const proofType = this.currentJobController.getProofType();
|
|
105
|
+
const startedAt = this.currentJobController.getStartedAt();
|
|
106
|
+
const result = this.currentJobController.getResult();
|
|
107
|
+
|
|
108
|
+
if (status === ProvingJobControllerStatus.RUNNING) {
|
|
109
|
+
maybeJob = await this.broker.reportProvingJobProgress(jobId, startedAt, { allowList: this.proofAllowList });
|
|
110
|
+
} else if (status === ProvingJobControllerStatus.DONE) {
|
|
111
|
+
if (result) {
|
|
112
|
+
maybeJob = await this.reportResult(jobId, proofType, result);
|
|
113
|
+
} else {
|
|
114
|
+
this.log.warn(
|
|
115
|
+
`Job controller for job ${this.currentJobController.getJobId()} is done but doesn't have a result`,
|
|
116
|
+
{ jobId },
|
|
117
|
+
);
|
|
118
|
+
maybeJob = await this.reportResult(
|
|
119
|
+
jobId,
|
|
120
|
+
proofType,
|
|
121
|
+
new ProvingError('No result found after proving', undefined, /* retry */ true),
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
this.currentJobController = undefined;
|
|
126
|
+
} else {
|
|
127
|
+
// IDLE status should not be seen because a job is started as soon as it is created
|
|
128
|
+
this.log.warn(`Idle job controller for job: ${this.currentJobController.getJobId()}. Skipping main loop work`, {
|
|
129
|
+
jobId: this.currentJobController.getJobId(),
|
|
130
|
+
});
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
89
133
|
} else {
|
|
90
134
|
maybeJob = await this.broker.getProvingJob({ allowList: this.proofAllowList });
|
|
91
135
|
}
|
|
92
136
|
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (this.idleTimer) {
|
|
98
|
-
this.instrumentation.recordIdleTime(this.idleTimer);
|
|
137
|
+
if (maybeJob) {
|
|
138
|
+
await this.startJob(maybeJob);
|
|
99
139
|
}
|
|
100
|
-
this.idleTimer = undefined;
|
|
101
|
-
|
|
102
|
-
const { job, time } = maybeJob;
|
|
103
|
-
await this.startJob(job, time);
|
|
104
140
|
}
|
|
105
141
|
|
|
106
|
-
private async startJob(job:
|
|
142
|
+
private async startJob({ job, time: startedAt }: GetProvingJobResponse): Promise<void> {
|
|
107
143
|
let abortedProofJobId: string | undefined;
|
|
108
144
|
let abortedProofName: string | undefined;
|
|
109
145
|
|
|
110
|
-
if (this.currentJobController?.getStatus() === ProvingJobControllerStatus.
|
|
146
|
+
if (this.currentJobController?.getStatus() === ProvingJobControllerStatus.RUNNING) {
|
|
111
147
|
abortedProofJobId = this.currentJobController.getJobId();
|
|
112
148
|
abortedProofName = this.currentJobController.getProofTypeName();
|
|
113
149
|
this.currentJobController?.abort();
|
|
@@ -116,13 +152,13 @@ export class ProvingAgent implements Traceable {
|
|
|
116
152
|
let inputs: ProvingJobInputs;
|
|
117
153
|
try {
|
|
118
154
|
inputs = await this.proofStore.getProofInput(job.inputsUri);
|
|
119
|
-
} catch
|
|
155
|
+
} catch {
|
|
120
156
|
const maybeJob = await this.broker.reportProvingJobError(job.id, 'Failed to load proof inputs', true, {
|
|
121
157
|
allowList: this.proofAllowList,
|
|
122
158
|
});
|
|
123
159
|
|
|
124
160
|
if (maybeJob) {
|
|
125
|
-
return this.startJob(maybeJob
|
|
161
|
+
return this.startJob(maybeJob);
|
|
126
162
|
}
|
|
127
163
|
|
|
128
164
|
return;
|
|
@@ -134,7 +170,11 @@ export class ProvingAgent implements Traceable {
|
|
|
134
170
|
job.epochNumber,
|
|
135
171
|
startedAt,
|
|
136
172
|
this.circuitProver,
|
|
137
|
-
|
|
173
|
+
() => {
|
|
174
|
+
// trigger a run of the main work loop when proving completes
|
|
175
|
+
// no need to await this here. The controller will stay alive (in DONE state) until the result is send to the broker
|
|
176
|
+
void this.runningPromise.trigger();
|
|
177
|
+
},
|
|
138
178
|
);
|
|
139
179
|
|
|
140
180
|
if (abortedProofJobId) {
|
|
@@ -154,28 +194,30 @@ export class ProvingAgent implements Traceable {
|
|
|
154
194
|
this.currentJobController.start();
|
|
155
195
|
}
|
|
156
196
|
|
|
157
|
-
|
|
197
|
+
private async reportResult<T extends ProvingRequestType>(
|
|
158
198
|
jobId: ProvingJobId,
|
|
159
199
|
type: T,
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
200
|
+
result: ProvingJobResultsMap[T] | Error,
|
|
201
|
+
): Promise<GetProvingJobResponse | undefined> {
|
|
202
|
+
let maybeJob: GetProvingJobResponse | undefined;
|
|
203
|
+
if (result instanceof AbortError) {
|
|
204
|
+
// no-op
|
|
205
|
+
this.log.warn(`Job id=${jobId} was aborted. Not reporting result back to broker`, result);
|
|
206
|
+
} else if (result instanceof Error) {
|
|
207
|
+
const retry = result.name === ProvingError.NAME ? (result as ProvingError).retry : false;
|
|
208
|
+
this.log.error(
|
|
209
|
+
`Job id=${jobId} type=${ProvingRequestType[type]} failed err=${result.message} retry=${retry}`,
|
|
210
|
+
result,
|
|
211
|
+
);
|
|
212
|
+
maybeJob = await this.broker.reportProvingJobError(jobId, result.message, retry, {
|
|
213
|
+
allowList: this.proofAllowList,
|
|
214
|
+
});
|
|
215
|
+
} else {
|
|
169
216
|
const outputUri = await this.proofStore.saveProofOutput(jobId, type, result);
|
|
170
217
|
this.log.info(`Job id=${jobId} type=${ProvingRequestType[type]} completed outputUri=${truncate(outputUri)}`);
|
|
171
218
|
maybeJob = await this.broker.reportProvingJobSuccess(jobId, outputUri, { allowList: this.proofAllowList });
|
|
172
219
|
}
|
|
173
220
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
await this.startJob(job, time);
|
|
177
|
-
} else {
|
|
178
|
-
this.idleTimer = new Timer();
|
|
179
|
-
}
|
|
180
|
-
};
|
|
221
|
+
return maybeJob;
|
|
222
|
+
}
|
|
181
223
|
}
|
|
@@ -2,16 +2,17 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
2
2
|
import { type PromiseWithResolvers, RunningPromise, promiseWithResolvers } from '@aztec/foundation/promise';
|
|
3
3
|
import { PriorityMemoryQueue } from '@aztec/foundation/queue';
|
|
4
4
|
import { Timer } from '@aztec/foundation/timer';
|
|
5
|
-
import
|
|
6
|
-
GetProvingJobResponse,
|
|
7
|
-
ProofUri,
|
|
8
|
-
ProvingJob,
|
|
9
|
-
ProvingJobConsumer,
|
|
10
|
-
ProvingJobFilter,
|
|
11
|
-
ProvingJobId,
|
|
12
|
-
ProvingJobProducer,
|
|
13
|
-
ProvingJobSettledResult,
|
|
14
|
-
ProvingJobStatus,
|
|
5
|
+
import {
|
|
6
|
+
type GetProvingJobResponse,
|
|
7
|
+
type ProofUri,
|
|
8
|
+
type ProvingJob,
|
|
9
|
+
type ProvingJobConsumer,
|
|
10
|
+
type ProvingJobFilter,
|
|
11
|
+
type ProvingJobId,
|
|
12
|
+
type ProvingJobProducer,
|
|
13
|
+
type ProvingJobSettledResult,
|
|
14
|
+
type ProvingJobStatus,
|
|
15
|
+
tryStop,
|
|
15
16
|
} from '@aztec/stdlib/interfaces/server';
|
|
16
17
|
import { ProvingRequestType } from '@aztec/stdlib/proofs';
|
|
17
18
|
import {
|
|
@@ -54,6 +55,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
54
55
|
[ProvingRequestType.BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
55
56
|
[ProvingRequestType.SINGLE_TX_BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
56
57
|
[ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
58
|
+
[ProvingRequestType.PADDING_BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
57
59
|
|
|
58
60
|
[ProvingRequestType.BASE_PARITY]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
59
61
|
[ProvingRequestType.ROOT_PARITY]: new PriorityMemoryQueue<EnqueuedProvingJob>(provingJobComparator),
|
|
@@ -93,7 +95,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
93
95
|
/**
|
|
94
96
|
* The broker keeps track of the highest epoch its seen.
|
|
95
97
|
* This information is used for garbage collection: once it reaches the next epoch, it can start pruning the database of old state.
|
|
96
|
-
* It is important that this value is
|
|
98
|
+
* It is important that this value is initialized to zero. This ensures that we don't delete any old jobs until the current
|
|
97
99
|
* process instance receives a job request informing it of the actual current highest epoch
|
|
98
100
|
* Example:
|
|
99
101
|
* proving epoch 11 - the broker will wipe all jobs for epochs 9 and lower
|
|
@@ -184,7 +186,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
184
186
|
this.logger.warn('ProvingBroker not started');
|
|
185
187
|
return Promise.resolve();
|
|
186
188
|
}
|
|
187
|
-
await this.cleanupPromise
|
|
189
|
+
await tryStop(this.cleanupPromise);
|
|
188
190
|
}
|
|
189
191
|
|
|
190
192
|
public enqueueProvingJob(job: ProvingJob): Promise<ProvingJobStatus> {
|
|
@@ -313,7 +315,6 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
313
315
|
return Promise.resolve(notifications.concat(completedJobs));
|
|
314
316
|
}
|
|
315
317
|
|
|
316
|
-
// eslint-disable-next-line require-await
|
|
317
318
|
#getProvingJob(filter: ProvingJobFilter = { allowList: [] }): { job: ProvingJob; time: number } | undefined {
|
|
318
319
|
const allowedProofs: ProvingRequestType[] =
|
|
319
320
|
Array.isArray(filter.allowList) && filter.allowList.length > 0
|
|
@@ -571,7 +572,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Tr
|
|
|
571
572
|
|
|
572
573
|
if (jobsToClean.length > 0) {
|
|
573
574
|
this.cleanUpProvingJobState(jobsToClean);
|
|
574
|
-
this.logger.
|
|
575
|
+
this.logger.verbose(`Cleaned up proving jobs=${jobsToClean.length}`);
|
|
575
576
|
}
|
|
576
577
|
}
|
|
577
578
|
|
|
@@ -671,7 +672,7 @@ function proofTypeComparator(a: ProvingRequestType, b: ProvingRequestType): -1 |
|
|
|
671
672
|
* The aim is that this will speed up block proving as the closer we get to a block's root proof the more likely it
|
|
672
673
|
* is to get picked up by agents
|
|
673
674
|
*/
|
|
674
|
-
const PROOF_TYPES_IN_PRIORITY_ORDER: ProvingRequestType[] = [
|
|
675
|
+
export const PROOF_TYPES_IN_PRIORITY_ORDER: ProvingRequestType[] = [
|
|
675
676
|
ProvingRequestType.BLOCK_ROOT_ROLLUP,
|
|
676
677
|
ProvingRequestType.SINGLE_TX_BLOCK_ROOT_ROLLUP,
|
|
677
678
|
ProvingRequestType.BLOCK_MERGE_ROLLUP,
|
|
@@ -52,7 +52,7 @@ export class InMemoryBrokerDatabase implements ProvingBrokerDatabase {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
async *allProvingJobs(): AsyncIterableIterator<[ProvingJob, ProvingJobSettledResult | undefined]> {
|
|
55
|
-
for
|
|
55
|
+
for (const item of this.jobs.values()) {
|
|
56
56
|
yield [item, this.results.get(item.id)] as const;
|
|
57
57
|
}
|
|
58
58
|
}
|