@aztec/prover-client 3.0.0-nightly.20250916 → 3.0.0-nightly.20250918

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dest/block-factory/light.d.ts +5 -3
  2. package/dest/block-factory/light.d.ts.map +1 -1
  3. package/dest/block-factory/light.js +16 -9
  4. package/dest/mocks/fixtures.d.ts +3 -1
  5. package/dest/mocks/fixtures.d.ts.map +1 -1
  6. package/dest/mocks/fixtures.js +19 -2
  7. package/dest/mocks/test_context.d.ts +30 -9
  8. package/dest/mocks/test_context.d.ts.map +1 -1
  9. package/dest/mocks/test_context.js +68 -15
  10. package/dest/orchestrator/block-building-helpers.d.ts +16 -14
  11. package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
  12. package/dest/orchestrator/block-building-helpers.js +69 -66
  13. package/dest/orchestrator/block-proving-state.d.ts +53 -46
  14. package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
  15. package/dest/orchestrator/block-proving-state.js +209 -172
  16. package/dest/orchestrator/checkpoint-proving-state.d.ts +62 -0
  17. package/dest/orchestrator/checkpoint-proving-state.d.ts.map +1 -0
  18. package/dest/orchestrator/checkpoint-proving-state.js +208 -0
  19. package/dest/orchestrator/epoch-proving-state.d.ts +32 -25
  20. package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
  21. package/dest/orchestrator/epoch-proving-state.js +132 -81
  22. package/dest/orchestrator/orchestrator.d.ts +25 -24
  23. package/dest/orchestrator/orchestrator.d.ts.map +1 -1
  24. package/dest/orchestrator/orchestrator.js +318 -190
  25. package/dest/prover-client/server-epoch-prover.d.ts +8 -7
  26. package/dest/prover-client/server-epoch-prover.d.ts.map +1 -1
  27. package/dest/prover-client/server-epoch-prover.js +7 -7
  28. package/dest/proving_broker/broker_prover_facade.d.ts +12 -7
  29. package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
  30. package/dest/proving_broker/broker_prover_facade.js +30 -15
  31. package/dest/proving_broker/proving_broker.d.ts.map +1 -1
  32. package/dest/proving_broker/proving_broker.js +18 -7
  33. package/dest/proving_broker/proving_job_controller.d.ts.map +1 -1
  34. package/dest/proving_broker/proving_job_controller.js +26 -6
  35. package/dest/test/mock_prover.d.ts +12 -7
  36. package/dest/test/mock_prover.d.ts.map +1 -1
  37. package/dest/test/mock_prover.js +25 -10
  38. package/package.json +15 -15
  39. package/src/block-factory/light.ts +33 -9
  40. package/src/mocks/fixtures.ts +25 -7
  41. package/src/mocks/test_context.ts +113 -21
  42. package/src/orchestrator/block-building-helpers.ts +107 -93
  43. package/src/orchestrator/block-proving-state.ts +225 -212
  44. package/src/orchestrator/checkpoint-proving-state.ts +294 -0
  45. package/src/orchestrator/epoch-proving-state.ts +169 -121
  46. package/src/orchestrator/orchestrator.ts +466 -247
  47. package/src/prover-client/server-epoch-prover.ts +30 -16
  48. package/src/proving_broker/broker_prover_facade.ts +145 -71
  49. package/src/proving_broker/proving_broker.ts +24 -6
  50. package/src/proving_broker/proving_job_controller.ts +26 -6
  51. package/src/test/mock_prover.ts +105 -28
@@ -0,0 +1,294 @@
1
+ import {
2
+ BatchedBlobAccumulator,
3
+ BlobAccumulatorPublicInputs,
4
+ type FinalBlobBatchingChallenges,
5
+ SpongeBlob,
6
+ } from '@aztec/blob-lib';
7
+ import {
8
+ type ARCHIVE_HEIGHT,
9
+ BLOBS_PER_BLOCK,
10
+ FIELDS_PER_BLOB,
11
+ type L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH,
12
+ type NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
13
+ NUM_MSGS_PER_BASE_PARITY,
14
+ } from '@aztec/constants';
15
+ import { padArrayEnd } from '@aztec/foundation/collection';
16
+ import { BLS12Point, Fr } from '@aztec/foundation/fields';
17
+ import type { Tuple } from '@aztec/foundation/serialize';
18
+ import { type TreeNodeLocation, UnbalancedTreeStore } from '@aztec/foundation/trees';
19
+ import type { PublicInputsAndRecursiveProof } from '@aztec/stdlib/interfaces/server';
20
+ import { BaseParityInputs } from '@aztec/stdlib/parity';
21
+ import {
22
+ BlockMergeRollupPrivateInputs,
23
+ BlockRollupPublicInputs,
24
+ CheckpointConstantData,
25
+ CheckpointRollupPublicInputs,
26
+ CheckpointRootRollupHints,
27
+ CheckpointRootRollupPrivateInputs,
28
+ CheckpointRootSingleBlockRollupPrivateInputs,
29
+ } from '@aztec/stdlib/rollup';
30
+ import type { CircuitName } from '@aztec/stdlib/stats';
31
+ import type { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
32
+ import type { BlockHeader } from '@aztec/stdlib/tx';
33
+ import type { UInt64 } from '@aztec/stdlib/types';
34
+
35
+ import { accumulateBlobs, buildBlobHints, toProofData } from './block-building-helpers.js';
36
+ import { BlockProvingState, type ProofState } from './block-proving-state.js';
37
+ import type { EpochProvingState } from './epoch-proving-state.js';
38
+
39
+ export class CheckpointProvingState {
40
+ private blockProofs: UnbalancedTreeStore<
41
+ ProofState<BlockRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
42
+ >;
43
+ private checkpointRootProof:
44
+ | ProofState<CheckpointRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
45
+ | undefined;
46
+ private blocks: (BlockProvingState | undefined)[] = [];
47
+ private startBlobAccumulator: BatchedBlobAccumulator | undefined;
48
+ private endBlobAccumulator: BatchedBlobAccumulator | undefined;
49
+ private error: string | undefined;
50
+ public readonly firstBlockNumber: number;
51
+
52
+ constructor(
53
+ public readonly index: number,
54
+ public readonly constants: CheckpointConstantData,
55
+ public readonly totalNumBlocks: number,
56
+ private readonly totalNumBlobFields: number,
57
+ private readonly finalBlobBatchingChallenges: FinalBlobBatchingChallenges,
58
+ private readonly headerOfLastBlockInPreviousCheckpoint: BlockHeader,
59
+ private readonly lastArchiveSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>,
60
+ private readonly l1ToL2Messages: Fr[],
61
+ // The snapshot and sibling path before the new l1 to l2 message subtree is inserted.
62
+ private readonly lastL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot,
63
+ private readonly lastL1ToL2MessageSubtreeSiblingPath: Tuple<Fr, typeof L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH>,
64
+ // The snapshot and sibling path after the new l1 to l2 message subtree is inserted.
65
+ private readonly newL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot,
66
+ private readonly newL1ToL2MessageSubtreeSiblingPath: Tuple<Fr, typeof L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH>,
67
+ public parentEpoch: EpochProvingState,
68
+ private onBlobAccumulatorSet: (checkpoint: CheckpointProvingState) => void,
69
+ ) {
70
+ this.blockProofs = new UnbalancedTreeStore(totalNumBlocks);
71
+ this.firstBlockNumber = headerOfLastBlockInPreviousCheckpoint.globalVariables.blockNumber + 1;
72
+ }
73
+
74
+ public get epochNumber(): number {
75
+ return this.parentEpoch.epochNumber;
76
+ }
77
+
78
+ public startNewBlock(
79
+ blockNumber: number,
80
+ timestamp: UInt64,
81
+ totalNumTxs: number,
82
+ lastArchiveTreeSnapshot: AppendOnlyTreeSnapshot,
83
+ lastArchiveSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>,
84
+ ): BlockProvingState {
85
+ const index = blockNumber - this.firstBlockNumber;
86
+ if (index >= this.totalNumBlocks) {
87
+ throw new Error(`Unable to start a new block at index ${index}. Expected at most ${this.totalNumBlocks} blocks.`);
88
+ }
89
+
90
+ // If this is the first block, we use the snapshot and sibling path before the new l1 to l2 messages are inserted.
91
+ // Otherwise, we use the snapshot and sibling path after the new l1 to l2 messages are inserted, which will always
92
+ // happen in the first block.
93
+ const lastL1ToL2MessageTreeSnapshot =
94
+ index === 0 ? this.lastL1ToL2MessageTreeSnapshot : this.newL1ToL2MessageTreeSnapshot;
95
+ const lastL1ToL2MessageSubtreeSiblingPath =
96
+ index === 0 ? this.lastL1ToL2MessageSubtreeSiblingPath : this.newL1ToL2MessageSubtreeSiblingPath;
97
+
98
+ const startSpongeBlob =
99
+ index === 0 ? SpongeBlob.init(this.totalNumBlobFields) : this.blocks[index - 1]?.getEndSpongeBlob();
100
+ if (!startSpongeBlob) {
101
+ throw new Error(
102
+ 'Cannot start a new block before the trees have progressed from the tx effects in the previous block.',
103
+ );
104
+ }
105
+
106
+ const block = new BlockProvingState(
107
+ index,
108
+ blockNumber,
109
+ totalNumTxs,
110
+ this.constants,
111
+ timestamp,
112
+ lastArchiveTreeSnapshot,
113
+ lastArchiveSiblingPath,
114
+ lastL1ToL2MessageTreeSnapshot,
115
+ lastL1ToL2MessageSubtreeSiblingPath,
116
+ this.newL1ToL2MessageTreeSnapshot,
117
+ this.headerOfLastBlockInPreviousCheckpoint,
118
+ startSpongeBlob,
119
+ this,
120
+ );
121
+ this.blocks[index] = block;
122
+
123
+ return block;
124
+ }
125
+
126
+ // Returns true if we are still able to accept blocks, false otherwise.
127
+ public isAcceptingBlocks() {
128
+ return this.blocks.filter(b => !!b).length < this.totalNumBlocks;
129
+ }
130
+
131
+ public setBlockRootRollupProof(
132
+ blockIndex: number,
133
+ provingOutput: PublicInputsAndRecursiveProof<
134
+ BlockRollupPublicInputs,
135
+ typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
136
+ >,
137
+ ): TreeNodeLocation {
138
+ return this.blockProofs.setLeaf(blockIndex, { provingOutput });
139
+ }
140
+
141
+ public tryStartProvingBlockMerge(location: TreeNodeLocation) {
142
+ if (this.blockProofs.getNode(location)?.isProving) {
143
+ return false;
144
+ } else {
145
+ this.blockProofs.setNode(location, { isProving: true });
146
+ return true;
147
+ }
148
+ }
149
+
150
+ public setBlockMergeRollupProof(
151
+ location: TreeNodeLocation,
152
+ provingOutput: PublicInputsAndRecursiveProof<
153
+ BlockRollupPublicInputs,
154
+ typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
155
+ >,
156
+ ) {
157
+ this.blockProofs.setNode(location, { provingOutput });
158
+ }
159
+
160
+ public tryStartProvingCheckpointRoot() {
161
+ if (this.checkpointRootProof?.isProving) {
162
+ return false;
163
+ } else {
164
+ this.checkpointRootProof = { isProving: true };
165
+ return true;
166
+ }
167
+ }
168
+
169
+ public setCheckpointRootRollupProof(
170
+ provingOutput: PublicInputsAndRecursiveProof<
171
+ CheckpointRollupPublicInputs,
172
+ typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
173
+ >,
174
+ ): TreeNodeLocation {
175
+ this.checkpointRootProof = { provingOutput };
176
+ return this.parentEpoch.setCheckpointRootRollupProof(this.index, provingOutput);
177
+ }
178
+
179
+ public getBaseParityInputs(baseParityIndex: number) {
180
+ const messages = padArrayEnd(
181
+ this.l1ToL2Messages.slice(
182
+ baseParityIndex * NUM_MSGS_PER_BASE_PARITY,
183
+ (baseParityIndex + 1) * NUM_MSGS_PER_BASE_PARITY,
184
+ ),
185
+ Fr.ZERO,
186
+ NUM_MSGS_PER_BASE_PARITY,
187
+ );
188
+ return new BaseParityInputs(messages, this.constants.vkTreeRoot);
189
+ }
190
+
191
+ public async accumulateBlobs(startBlobAccumulator: BatchedBlobAccumulator) {
192
+ if (this.isAcceptingBlocks() || this.blocks.some(b => b!.isAcceptingTxs())) {
193
+ return;
194
+ }
195
+
196
+ const blobFields = this.blocks.flatMap(b => b!.getBlockBlobFields());
197
+ this.endBlobAccumulator = await accumulateBlobs(blobFields, startBlobAccumulator);
198
+ this.startBlobAccumulator = startBlobAccumulator;
199
+
200
+ this.onBlobAccumulatorSet(this);
201
+
202
+ return this.endBlobAccumulator;
203
+ }
204
+
205
+ public getEndBlobAccumulator() {
206
+ return this.endBlobAccumulator;
207
+ }
208
+
209
+ public getParentLocation(location: TreeNodeLocation) {
210
+ return this.blockProofs.getParentLocation(location);
211
+ }
212
+
213
+ public getBlockMergeRollupInputs(mergeLocation: TreeNodeLocation) {
214
+ const [left, right] = this.blockProofs.getChildren(mergeLocation).map(c => c?.provingOutput);
215
+ if (!left || !right) {
216
+ throw new Error('At least one child is not ready for the block merge rollup.');
217
+ }
218
+
219
+ return new BlockMergeRollupPrivateInputs([toProofData(left), toProofData(right)]);
220
+ }
221
+
222
+ public getCheckpointRootRollupType(): CircuitName {
223
+ return this.totalNumBlocks === 1 ? 'checkpoint-root-single-block-rollup' : 'checkpoint-root-rollup';
224
+ }
225
+
226
+ public async getCheckpointRootRollupInputs() {
227
+ const proofs = this.#getChildProofsForRoot();
228
+ const nonEmptyProofs = proofs.filter(p => !!p);
229
+ if (proofs.length !== nonEmptyProofs.length) {
230
+ throw new Error('At least one child is not ready for the checkpoint root rollup.');
231
+ }
232
+ if (!this.startBlobAccumulator) {
233
+ throw new Error('Start blob accumulator is not set.');
234
+ }
235
+
236
+ const blobFields = this.blocks.flatMap(b => b!.getBlockBlobFields());
237
+ const { blobCommitments, blobsHash } = await buildBlobHints(blobFields);
238
+
239
+ const hints = CheckpointRootRollupHints.from({
240
+ previousBlockHeader: this.headerOfLastBlockInPreviousCheckpoint,
241
+ previousArchiveSiblingPath: this.lastArchiveSiblingPath,
242
+ startBlobAccumulator: BlobAccumulatorPublicInputs.fromBatchedBlobAccumulator(this.startBlobAccumulator),
243
+ finalBlobChallenges: this.finalBlobBatchingChallenges,
244
+ blobFields: padArrayEnd(blobFields, Fr.ZERO, FIELDS_PER_BLOB * BLOBS_PER_BLOCK),
245
+ blobCommitments: padArrayEnd(blobCommitments, BLS12Point.ZERO, BLOBS_PER_BLOCK),
246
+ blobsHash,
247
+ });
248
+
249
+ const [left, right] = nonEmptyProofs.map(p => toProofData(p));
250
+
251
+ return !right
252
+ ? new CheckpointRootSingleBlockRollupPrivateInputs(left, hints)
253
+ : new CheckpointRootRollupPrivateInputs([left, right], hints);
254
+ }
255
+
256
+ public getBlockProvingStateByBlockNumber(blockNumber: number) {
257
+ const index = blockNumber - this.firstBlockNumber;
258
+ return this.blocks[index];
259
+ }
260
+
261
+ public isReadyForBlockMerge(location: TreeNodeLocation) {
262
+ return !!this.blockProofs.getSibling(location)?.provingOutput;
263
+ }
264
+
265
+ public isReadyForCheckpointRoot() {
266
+ const allChildProofsReady = this.#getChildProofsForRoot().every(p => !!p);
267
+ return allChildProofsReady && !!this.startBlobAccumulator;
268
+ }
269
+
270
+ public verifyState() {
271
+ return this.parentEpoch.verifyState();
272
+ }
273
+
274
+ public getError() {
275
+ return this.error;
276
+ }
277
+
278
+ // Attempts to reject the proving state promise with a reason of 'cancelled'
279
+ public cancel() {
280
+ this.reject('Proving cancelled');
281
+ }
282
+
283
+ public reject(reason: string) {
284
+ this.error = reason;
285
+ this.parentEpoch.reject(reason);
286
+ }
287
+
288
+ #getChildProofsForRoot() {
289
+ const rootLocation = { level: 0, index: 0 };
290
+ return this.totalNumBlocks === 1
291
+ ? [this.blockProofs.getNode(rootLocation)?.provingOutput] // If there's only 1 block, its proof will be stored at the root.
292
+ : this.blockProofs.getChildren(rootLocation).map(c => c?.provingOutput);
293
+ }
294
+ }