@aztec/prover-client 0.0.1-commit.993d52e → 0.0.1-commit.9a89641

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 (105) hide show
  1. package/dest/config.d.ts +1 -1
  2. package/dest/config.d.ts.map +1 -1
  3. package/dest/config.js +16 -2
  4. package/dest/light/lightweight_checkpoint_builder.d.ts +6 -2
  5. package/dest/light/lightweight_checkpoint_builder.d.ts.map +1 -1
  6. package/dest/light/lightweight_checkpoint_builder.js +43 -12
  7. package/dest/mocks/fixtures.d.ts +1 -1
  8. package/dest/mocks/fixtures.d.ts.map +1 -1
  9. package/dest/mocks/fixtures.js +3 -3
  10. package/dest/mocks/test_context.d.ts +11 -11
  11. package/dest/mocks/test_context.d.ts.map +1 -1
  12. package/dest/mocks/test_context.js +27 -29
  13. package/dest/orchestrator/block-building-helpers.d.ts +1 -1
  14. package/dest/orchestrator/checkpoint-proving-state.d.ts +20 -36
  15. package/dest/orchestrator/checkpoint-proving-state.d.ts.map +1 -1
  16. package/dest/orchestrator/checkpoint-proving-state.js +22 -120
  17. package/dest/orchestrator/checkpoint-sub-tree-orchestrator.d.ts +161 -0
  18. package/dest/orchestrator/checkpoint-sub-tree-orchestrator.d.ts.map +1 -0
  19. package/dest/orchestrator/{orchestrator.js → checkpoint-sub-tree-orchestrator.js} +267 -435
  20. package/dest/orchestrator/chonk-cache.d.ts +39 -0
  21. package/dest/orchestrator/chonk-cache.d.ts.map +1 -0
  22. package/dest/orchestrator/chonk-cache.js +80 -0
  23. package/dest/orchestrator/index.d.ts +4 -2
  24. package/dest/orchestrator/index.d.ts.map +1 -1
  25. package/dest/orchestrator/index.js +3 -1
  26. package/dest/orchestrator/proving-scheduler.d.ts +81 -0
  27. package/dest/orchestrator/proving-scheduler.d.ts.map +1 -0
  28. package/dest/orchestrator/proving-scheduler.js +120 -0
  29. package/dest/orchestrator/top-tree-orchestrator.d.ts +88 -0
  30. package/dest/orchestrator/top-tree-orchestrator.d.ts.map +1 -0
  31. package/dest/orchestrator/top-tree-orchestrator.js +232 -0
  32. package/dest/orchestrator/top-tree-proving-state.d.ts +61 -0
  33. package/dest/orchestrator/top-tree-proving-state.d.ts.map +1 -0
  34. package/dest/orchestrator/top-tree-proving-state.js +185 -0
  35. package/dest/orchestrator/tx-proving-state.d.ts +3 -3
  36. package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
  37. package/dest/prover-client/prover-client.d.ts +62 -5
  38. package/dest/prover-client/prover-client.d.ts.map +1 -1
  39. package/dest/prover-client/prover-client.js +54 -7
  40. package/dest/proving_broker/broker_prover_facade.d.ts +3 -3
  41. package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
  42. package/dest/proving_broker/broker_prover_facade.js +26 -20
  43. package/dest/proving_broker/config.d.ts +9 -73
  44. package/dest/proving_broker/config.d.ts.map +1 -1
  45. package/dest/proving_broker/config.js +3 -3
  46. package/dest/proving_broker/index.d.ts +2 -1
  47. package/dest/proving_broker/index.d.ts.map +1 -1
  48. package/dest/proving_broker/index.js +1 -0
  49. package/dest/proving_broker/proving_broker.d.ts +3 -2
  50. package/dest/proving_broker/proving_broker.d.ts.map +1 -1
  51. package/dest/proving_broker/proving_broker.js +219 -76
  52. package/dest/proving_broker/proving_broker_database/memory.d.ts +5 -2
  53. package/dest/proving_broker/proving_broker_database/memory.d.ts.map +1 -1
  54. package/dest/proving_broker/proving_broker_database/memory.js +14 -1
  55. package/dest/proving_broker/proving_broker_database/persisted.d.ts +15 -2
  56. package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -1
  57. package/dest/proving_broker/proving_broker_database/persisted.js +57 -6
  58. package/dest/proving_broker/proving_broker_database.d.ts +27 -1
  59. package/dest/proving_broker/proving_broker_database.d.ts.map +1 -1
  60. package/dest/proving_broker/rpc.d.ts +15 -4
  61. package/dest/proving_broker/rpc.d.ts.map +1 -1
  62. package/dest/proving_broker/rpc.js +91 -24
  63. package/dest/test/epoch_settlement.d.ts +36 -0
  64. package/dest/test/epoch_settlement.d.ts.map +1 -0
  65. package/dest/test/epoch_settlement.js +52 -0
  66. package/dest/test/index.d.ts +2 -0
  67. package/dest/test/index.d.ts.map +1 -0
  68. package/dest/test/index.js +1 -0
  69. package/dest/test/mock_prover.d.ts +4 -4
  70. package/dest/test/mock_prover.js +2 -2
  71. package/package.json +20 -19
  72. package/src/config.ts +18 -2
  73. package/src/light/lightweight_checkpoint_builder.ts +48 -20
  74. package/src/mocks/fixtures.ts +2 -4
  75. package/src/mocks/test_context.ts +26 -42
  76. package/src/orchestrator/checkpoint-proving-state.ts +21 -162
  77. package/src/orchestrator/{orchestrator.ts → checkpoint-sub-tree-orchestrator.ts} +415 -646
  78. package/src/orchestrator/chonk-cache.ts +99 -0
  79. package/src/orchestrator/index.ts +8 -1
  80. package/src/orchestrator/proving-scheduler.ts +160 -0
  81. package/src/orchestrator/top-tree-orchestrator.ts +384 -0
  82. package/src/orchestrator/top-tree-proving-state.ts +219 -0
  83. package/src/orchestrator/tx-proving-state.ts +3 -3
  84. package/src/prover-client/prover-client.ts +129 -18
  85. package/src/proving_broker/broker_prover_facade.ts +29 -23
  86. package/src/proving_broker/config.ts +3 -2
  87. package/src/proving_broker/index.ts +1 -0
  88. package/src/proving_broker/proving_broker.ts +209 -78
  89. package/src/proving_broker/proving_broker_database/memory.ts +16 -2
  90. package/src/proving_broker/proving_broker_database/persisted.ts +71 -8
  91. package/src/proving_broker/proving_broker_database.ts +30 -0
  92. package/src/proving_broker/rpc.ts +52 -24
  93. package/src/test/epoch_settlement.ts +82 -0
  94. package/src/test/index.ts +1 -0
  95. package/src/test/mock_prover.ts +2 -2
  96. package/dest/orchestrator/epoch-proving-state.d.ts +0 -75
  97. package/dest/orchestrator/epoch-proving-state.d.ts.map +0 -1
  98. package/dest/orchestrator/epoch-proving-state.js +0 -269
  99. package/dest/orchestrator/orchestrator.d.ts +0 -128
  100. package/dest/orchestrator/orchestrator.d.ts.map +0 -1
  101. package/dest/prover-client/server-epoch-prover.d.ts +0 -32
  102. package/dest/prover-client/server-epoch-prover.d.ts.map +0 -1
  103. package/dest/prover-client/server-epoch-prover.js +0 -40
  104. package/src/orchestrator/epoch-proving-state.ts +0 -380
  105. package/src/prover-client/server-epoch-prover.ts +0 -69
package/src/config.ts CHANGED
@@ -44,14 +44,30 @@ export const bbConfigMappings: ConfigMappingsType<BBConfig & ACVMConfig> = {
44
44
  },
45
45
  numConcurrentIVCVerifiers: {
46
46
  env: 'BB_NUM_IVC_VERIFIERS',
47
- description: 'Max number of chonk verifiers to run concurrently',
47
+ description: 'Max concurrent verifications for the RPC verifier (QueuedIVCVerifier).',
48
48
  ...numberConfigHelper(8),
49
49
  },
50
50
  bbIVCConcurrency: {
51
51
  env: 'BB_IVC_CONCURRENCY',
52
- description: 'Number of threads to use for IVC verification',
52
+ description: 'Thread count for the RPC IVC verifier.',
53
53
  ...numberConfigHelper(1),
54
54
  },
55
+ bbChonkVerifyMaxBatch: {
56
+ env: 'BB_CHONK_VERIFY_MAX_BATCH',
57
+ description:
58
+ 'Upper bound on proofs per batch for the peer chonk batch verifier. Proofs are verified immediately as they arrive; this only caps how many can accumulate while a batch is already being processed.',
59
+ ...numberConfigHelper(16),
60
+ },
61
+ bbChonkVerifyConcurrency: {
62
+ env: 'BB_CHONK_VERIFY_BATCH_CONCURRENCY',
63
+ description: 'Thread count for the peer batch verifier parallel reduce. 0 = auto.',
64
+ ...numberConfigHelper(6),
65
+ },
66
+ bbDebugOutputDir: {
67
+ env: 'BB_DEBUG_OUTPUT_DIR',
68
+ description:
69
+ 'When set, bb.js operations write input/output files and log equivalent CLI commands to this directory',
70
+ },
55
71
  };
56
72
 
57
73
  export const proverClientConfigMappings: ConfigMappingsType<ProverClientUserConfig> = {
@@ -1,14 +1,14 @@
1
1
  import { SpongeBlob, computeBlobsHashFromBlobs, encodeCheckpointEndMarker, getBlobsPerL1Block } from '@aztec/blob-lib';
2
- import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
3
2
  import { type CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types';
4
- import { padArrayEnd } from '@aztec/foundation/collection';
5
3
  import { Fr } from '@aztec/foundation/curves/bn254';
6
4
  import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
5
+ import { elapsed } from '@aztec/foundation/timer';
7
6
  import { L2Block } from '@aztec/stdlib/block';
8
7
  import { Checkpoint } from '@aztec/stdlib/checkpoint';
9
8
  import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
10
9
  import {
11
10
  accumulateCheckpointOutHashes,
11
+ appendL1ToL2MessagesToTree,
12
12
  computeCheckpointOutHash,
13
13
  computeInHashFromL1ToL2Messages,
14
14
  } from '@aztec/stdlib/messaging';
@@ -68,10 +68,7 @@ export class LightweightCheckpointBuilder {
68
68
  feeAssetPriceModifier: bigint = 0n,
69
69
  ): Promise<LightweightCheckpointBuilder> {
70
70
  // Insert l1-to-l2 messages into the tree.
71
- await db.appendLeaves(
72
- MerkleTreeId.L1_TO_L2_MESSAGE_TREE,
73
- padArrayEnd<Fr, number>(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP),
74
- );
71
+ await appendL1ToL2MessagesToTree(db, l1ToL2Messages);
75
72
 
76
73
  return new LightweightCheckpointBuilder(
77
74
  checkpointNumber,
@@ -116,6 +113,10 @@ export class LightweightCheckpointBuilder {
116
113
  blockNumbers: existingBlocks.map(b => b.header.getBlockNumber()),
117
114
  });
118
115
 
116
+ if (existingBlocks.length === 0) {
117
+ throw new Error(`Cannot resume checkpoint ${checkpointNumber} with no existing blocks`);
118
+ }
119
+
119
120
  // Validate block order and consistency
120
121
  for (let i = 1; i < existingBlocks.length; i++) {
121
122
  const prev = existingBlocks[i - 1];
@@ -153,6 +154,10 @@ export class LightweightCheckpointBuilder {
153
154
  return this.blocks.length;
154
155
  }
155
156
 
157
+ public getBlocks() {
158
+ return this.blocks;
159
+ }
160
+
156
161
  /**
157
162
  * Adds a new block to the checkpoint. The tx effects must have already been inserted into the db if
158
163
  * this is called after tx processing, if that's not the case, then set `insertTxsEffects` to true.
@@ -161,7 +166,8 @@ export class LightweightCheckpointBuilder {
161
166
  globalVariables: GlobalVariables,
162
167
  txs: ProcessedTx[],
163
168
  opts: { insertTxsEffects?: boolean; expectedEndState?: StateReference } = {},
164
- ): Promise<L2Block> {
169
+ ): Promise<{ block: L2Block; timings: Record<string, number> }> {
170
+ const timings: Record<string, number> = {};
165
171
  const isFirstBlock = this.blocks.length === 0;
166
172
 
167
173
  // Empty blocks are only allowed as the first block in a checkpoint
@@ -170,7 +176,9 @@ export class LightweightCheckpointBuilder {
170
176
  }
171
177
 
172
178
  if (isFirstBlock) {
173
- this.lastArchives.push(await getTreeSnapshot(MerkleTreeId.ARCHIVE, this.db));
179
+ const [msGetInitialArchive, initialArchive] = await elapsed(() => getTreeSnapshot(MerkleTreeId.ARCHIVE, this.db));
180
+ this.lastArchives.push(initialArchive);
181
+ timings.getInitialArchive = msGetInitialArchive;
174
182
  }
175
183
 
176
184
  const lastArchive = this.lastArchives.at(-1)!;
@@ -180,12 +188,17 @@ export class LightweightCheckpointBuilder {
180
188
  `Inserting side effects for ${txs.length} txs for block ${globalVariables.blockNumber} into db`,
181
189
  { txs: txs.map(tx => tx.hash.toString()) },
182
190
  );
191
+ let msInsertSideEffects = 0;
183
192
  for (const tx of txs) {
184
- await insertSideEffects(tx, this.db);
193
+ const [ms] = await elapsed(() => insertSideEffects(tx, this.db));
194
+ msInsertSideEffects += ms;
185
195
  }
196
+ timings.insertSideEffects = msInsertSideEffects;
186
197
  }
187
198
 
188
- const endState = await this.db.getStateReference();
199
+ const [msGetEndState, endState] = await elapsed(() => this.db.getStateReference());
200
+ timings.getEndState = msGetEndState;
201
+
189
202
  if (opts.expectedEndState && !endState.equals(opts.expectedEndState)) {
190
203
  this.logger.error('End state after processing txs does not match expected end state', {
191
204
  globalVariables: globalVariables.toInspect(),
@@ -195,26 +208,31 @@ export class LightweightCheckpointBuilder {
195
208
  throw new Error(`End state does not match expected end state when building block ${globalVariables.blockNumber}`);
196
209
  }
197
210
 
198
- const { header, body, blockBlobFields } = await buildHeaderAndBodyFromTxs(
199
- txs,
200
- lastArchive,
201
- endState,
202
- globalVariables,
203
- this.spongeBlob,
204
- isFirstBlock,
211
+ const [msBuildHeaderAndBody, { header, body, blockBlobFields }] = await elapsed(() =>
212
+ buildHeaderAndBodyFromTxs(txs, lastArchive, endState, globalVariables, this.spongeBlob, isFirstBlock),
205
213
  );
214
+ timings.buildHeaderAndBody = msBuildHeaderAndBody;
206
215
 
207
216
  header.state.validate();
208
217
 
209
218
  await this.db.updateArchive(header);
210
- const newArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, this.db);
219
+ const [msUpdateArchive, newArchive] = await elapsed(() => getTreeSnapshot(MerkleTreeId.ARCHIVE, this.db));
220
+ timings.updateArchive = msUpdateArchive;
211
221
  this.lastArchives.push(newArchive);
212
222
 
223
+ const expectedNextLeafIndex = Number(globalVariables.blockNumber) + 1;
224
+ if (newArchive.nextAvailableLeafIndex !== expectedNextLeafIndex) {
225
+ throw new Error(
226
+ `Archive tree next leaf index mismatch after building block ${globalVariables.blockNumber} (expected ${expectedNextLeafIndex} but got ${newArchive.nextAvailableLeafIndex})`,
227
+ );
228
+ }
229
+
213
230
  const indexWithinCheckpoint = IndexWithinCheckpoint(this.blocks.length);
214
231
  const block = new L2Block(newArchive, header, body, this.checkpointNumber, indexWithinCheckpoint);
215
232
  this.blocks.push(block);
216
233
 
217
- await this.spongeBlob.absorb(blockBlobFields);
234
+ const [msSpongeAbsorb] = await elapsed(() => this.spongeBlob.absorb(blockBlobFields));
235
+ timings.spongeAbsorb = msSpongeAbsorb;
218
236
  this.blobFields.push(...blockBlobFields);
219
237
 
220
238
  this.logger.debug(`Built block ${header.getBlockNumber()}`, {
@@ -225,7 +243,7 @@ export class LightweightCheckpointBuilder {
225
243
  txs: block.body.txEffects.map(tx => tx.txHash.toString()),
226
244
  });
227
245
 
228
- return block;
246
+ return { block, timings };
229
247
  }
230
248
 
231
249
  async completeCheckpoint(): Promise<Checkpoint> {
@@ -257,6 +275,7 @@ export class LightweightCheckpointBuilder {
257
275
  const timestamp = blocks[blocks.length - 1].timestamp;
258
276
 
259
277
  const totalManaUsed = blocks.reduce((acc, block) => acc.add(block.header.totalManaUsed), Fr.ZERO);
278
+ const accumulatedFees = blocks.reduce((acc, block) => acc.add(block.header.totalFees), Fr.ZERO);
260
279
 
261
280
  const header = CheckpointHeader.from({
262
281
  lastArchiveRoot: this.lastArchives[0].root,
@@ -270,6 +289,15 @@ export class LightweightCheckpointBuilder {
270
289
  feeRecipient,
271
290
  gasFees,
272
291
  totalManaUsed,
292
+ accumulatedFees,
293
+ });
294
+
295
+ this.logger.debug(`Completed checkpoint ${this.checkpointNumber}`, {
296
+ checkpointNumber: this.checkpointNumber,
297
+ headerHash: header.hash().toString(),
298
+ checkpointOutHash: checkpointOutHash.toString(),
299
+ numPreviousCheckpointOutHashes: this.previousCheckpointOutHashes.length,
300
+ ...header.toInspect(),
273
301
  });
274
302
 
275
303
  return new Checkpoint(newArchive, header, blocks, this.checkpointNumber, this.feeAssetPriceModifier);
@@ -17,12 +17,10 @@ import { promises as fs } from 'fs';
17
17
  import path from 'path';
18
18
 
19
19
  const {
20
- BB_RELEASE_DIR = 'cpp/build/bin',
21
20
  TEMP_DIR = '/tmp',
22
21
  BB_BINARY_PATH = '',
23
22
  BB_WORKING_DIRECTORY = '',
24
23
  BB_SKIP_CLEANUP = '',
25
- NOIR_RELEASE_DIR = 'noir-repo/target/release',
26
24
  ACVM_BINARY_PATH = '',
27
25
  ACVM_WORKING_DIRECTORY = '',
28
26
  } = process.env;
@@ -32,7 +30,7 @@ export const getEnvironmentConfig = async (logger: Logger) => {
32
30
  try {
33
31
  const expectedBBPath = BB_BINARY_PATH
34
32
  ? BB_BINARY_PATH
35
- : `${path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../barretenberg/', BB_RELEASE_DIR)}/bb-avm`;
33
+ : `${path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../labs-aztec-toolchain/bin')}/bb-avm`;
36
34
  await fs.access(expectedBBPath, fs.constants.R_OK);
37
35
  const tempWorkingDirectory = `${TEMP_DIR}/${randomBytes(4).toString('hex')}`;
38
36
  const bbWorkingDirectory = BB_WORKING_DIRECTORY ? BB_WORKING_DIRECTORY : `${tempWorkingDirectory}/bb`;
@@ -41,7 +39,7 @@ export const getEnvironmentConfig = async (logger: Logger) => {
41
39
 
42
40
  const expectedAcvmPath = ACVM_BINARY_PATH
43
41
  ? ACVM_BINARY_PATH
44
- : `${path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../noir/', NOIR_RELEASE_DIR)}/acvm`;
42
+ : `${path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../labs-aztec-toolchain/bin')}/acvm`;
45
43
  await fs.access(expectedAcvmPath, fs.constants.R_OK);
46
44
  const acvmWorkingDirectory = ACVM_WORKING_DIRECTORY ? ACVM_WORKING_DIRECTORY : `${tempWorkingDirectory}/acvm`;
47
45
  await fs.mkdir(acvmWorkingDirectory, { recursive: true });
@@ -5,13 +5,13 @@ import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
5
5
  import { padArrayEnd, times, timesAsync } from '@aztec/foundation/collection';
6
6
  import { Fr } from '@aztec/foundation/curves/bn254';
7
7
  import type { Logger } from '@aztec/foundation/log';
8
+ import { SerialQueue } from '@aztec/foundation/queue';
8
9
  import type { FieldsOf } from '@aztec/foundation/types';
9
10
  import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
10
11
  import { ProtocolContractsList } from '@aztec/protocol-contracts';
11
12
  import { computeFeePayerBalanceLeafSlot } from '@aztec/protocol-contracts/fee-juice';
12
13
  import { PublicDataWrite } from '@aztec/stdlib/avm';
13
14
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
14
- import { EthAddress } from '@aztec/stdlib/block';
15
15
  import type { Checkpoint } from '@aztec/stdlib/checkpoint';
16
16
  import type { MerkleTreeWriteOperations, ServerCircuitProver } from '@aztec/stdlib/interfaces/server';
17
17
  import type { CheckpointConstantData } from '@aztec/stdlib/rollup';
@@ -24,6 +24,7 @@ import {
24
24
  StateReference,
25
25
  TreeSnapshots,
26
26
  } from '@aztec/stdlib/tx';
27
+ import type { GenesisData } from '@aztec/stdlib/world-state';
27
28
  import type { MerkleTreeAdminDatabase } from '@aztec/world-state';
28
29
  import { NativeWorldStateService } from '@aztec/world-state/native';
29
30
 
@@ -35,12 +36,21 @@ import {
35
36
  getTreeSnapshot,
36
37
  insertSideEffects,
37
38
  } from '../orchestrator/block-building-helpers.js';
38
- import type { BlockProvingState } from '../orchestrator/block-proving-state.js';
39
- import { ProvingOrchestrator } from '../orchestrator/index.js';
40
39
  import { BrokerCircuitProverFacade } from '../proving_broker/broker_prover_facade.js';
41
40
  import { TestBroker } from '../test/mock_prover.js';
42
41
  import { getEnvironmentConfig, getSimulator, makeCheckpointConstants, makeGlobals } from './fixtures.js';
43
42
 
43
+ /**
44
+ * Builds a started `SerialQueue` for use as an orchestrator's deferred-job queue in
45
+ * tests. Production wires a single shared queue via `ProverClient`; tests that construct
46
+ * orchestrators directly use one of these per orchestrator (or share one).
47
+ */
48
+ export function makeTestDeferredJobQueue(concurrency = 10): SerialQueue {
49
+ const queue = new SerialQueue();
50
+ queue.start(concurrency);
51
+ return queue;
52
+ }
53
+
44
54
  export class TestContext {
45
55
  private headers: Map<number, BlockHeader> = new Map();
46
56
  private checkpoints: Checkpoint[] = [];
@@ -56,7 +66,6 @@ export class TestContext {
56
66
  public prover: ServerCircuitProver,
57
67
  public broker: TestBroker,
58
68
  public brokerProverFacade: BrokerCircuitProverFacade,
59
- public orchestrator: TestProvingOrchestrator,
60
69
  private feePayer: AztecAddress,
61
70
  initialFeePayerBalance: Fr,
62
71
  private directoriesToCleanup: string[],
@@ -65,10 +74,6 @@ export class TestContext {
65
74
  this.feePayerBalance = initialFeePayerBalance;
66
75
  }
67
76
 
68
- public get epochProver() {
69
- return this.orchestrator;
70
- }
71
-
72
77
  static async new(
73
78
  logger: Logger,
74
79
  {
@@ -81,17 +86,16 @@ export class TestContext {
81
86
  ) {
82
87
  const directoriesToCleanup: string[] = [];
83
88
 
84
- const feePayer = AztecAddress.fromNumber(42222);
89
+ const feePayer = AztecAddress.fromNumberUnsafe(42222);
85
90
  const initialFeePayerBalance = new Fr(10n ** 20n);
86
91
  const feePayerSlot = await computeFeePayerBalanceLeafSlot(feePayer);
87
- const prefilledPublicData = [new PublicDataTreeLeaf(feePayerSlot, initialFeePayerBalance)];
92
+ const genesis: GenesisData = {
93
+ prefilledPublicData: [new PublicDataTreeLeaf(feePayerSlot, initialFeePayerBalance)],
94
+ genesisTimestamp: 0n,
95
+ };
88
96
 
89
97
  // Separated dbs for public processor and prover - see public_processor for context
90
- const ws = await NativeWorldStateService.tmp(
91
- /*rollupAddress=*/ undefined,
92
- /*cleanupTmpDir=*/ true,
93
- prefilledPublicData,
94
- );
98
+ const ws = await NativeWorldStateService.tmp(/*cleanupTmpDir=*/ true, genesis);
95
99
 
96
100
  let localProver: ServerCircuitProver;
97
101
  const config = await getEnvironmentConfig(logger);
@@ -104,8 +108,10 @@ export class TestContext {
104
108
  bbBinaryPath: config.expectedBBPath,
105
109
  bbWorkingDirectory: config.bbWorkingDirectory,
106
110
  bbSkipCleanup: config.bbSkipCleanup,
107
- numConcurrentIVCVerifiers: 2,
111
+ numConcurrentIVCVerifiers: 8,
108
112
  bbIVCConcurrency: 1,
113
+ bbChonkVerifyMaxBatch: 16,
114
+ bbChonkVerifyConcurrency: 6,
109
115
  };
110
116
  localProver = await createProver(bbConfig);
111
117
  }
@@ -116,22 +122,11 @@ export class TestContext {
116
122
 
117
123
  const broker = new TestBroker(proverCount, localProver);
118
124
  const facade = new BrokerCircuitProverFacade(broker);
119
- const orchestrator = new TestProvingOrchestrator(ws, facade, EthAddress.ZERO);
120
125
 
121
126
  await broker.start();
122
127
  facade.start();
123
128
 
124
- return new this(
125
- ws,
126
- localProver,
127
- broker,
128
- facade,
129
- orchestrator,
130
- feePayer,
131
- initialFeePayerBalance,
132
- directoriesToCleanup,
133
- logger,
134
- );
129
+ return new this(ws, localProver, broker, facade, feePayer, initialFeePayerBalance, directoriesToCleanup, logger);
135
130
  }
136
131
 
137
132
  public getFork() {
@@ -141,6 +136,7 @@ export class TestContext {
141
136
  async cleanup() {
142
137
  await this.brokerProverFacade.stop();
143
138
  await this.broker.stop();
139
+ await this.worldState.close();
144
140
  for (const dir of this.directoriesToCleanup.filter(x => x !== '')) {
145
141
  try {
146
142
  await fs.rm(dir, { recursive: true, force: true, maxRetries: 3 });
@@ -262,7 +258,7 @@ export class TestContext {
262
258
  const txs = blockTxs[i];
263
259
  const state = blockEndStates[i];
264
260
 
265
- const block = await builder.addBlock(blockGlobalVariables[i], txs, {
261
+ const { block } = await builder.addBlock(blockGlobalVariables[i], txs, {
266
262
  expectedEndState: state,
267
263
  insertTxsEffects: true,
268
264
  });
@@ -282,6 +278,7 @@ export class TestContext {
282
278
 
283
279
  return {
284
280
  constants,
281
+ checkpoint,
285
282
  header: checkpoint.header,
286
283
  blocks,
287
284
  l1ToL2Messages,
@@ -349,16 +346,3 @@ export class TestContext {
349
346
  return endStateReference;
350
347
  }
351
348
  }
352
-
353
- class TestProvingOrchestrator extends ProvingOrchestrator {
354
- public isVerifyBuiltBlockAgainstSyncedStateEnabled = false;
355
-
356
- // Disable this check by default, since it requires seeding world state with the block being built
357
- // This is only enabled in some tests with multiple blocks that populate the pending chain via makePendingBlock
358
- protected override verifyBuiltBlockAgainstSyncedState(provingState: BlockProvingState): Promise<void> {
359
- if (this.isVerifyBuiltBlockAgainstSyncedStateEnabled) {
360
- return super.verifyBuiltBlockAgainstSyncedState(provingState);
361
- }
362
- return Promise.resolve();
363
- }
364
- }
@@ -1,66 +1,30 @@
1
- import {
2
- BatchedBlobAccumulator,
3
- type FinalBlobBatchingChallenges,
4
- SpongeBlob,
5
- encodeCheckpointBlobDataFromBlocks,
6
- } from '@aztec/blob-lib';
1
+ import { SpongeBlob } from '@aztec/blob-lib';
7
2
  import {
8
3
  type ARCHIVE_HEIGHT,
9
- BLOBS_PER_CHECKPOINT,
10
- FIELDS_PER_BLOB,
11
4
  type L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
12
5
  type NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
13
6
  NUM_MSGS_PER_BASE_PARITY,
14
- OUT_HASH_TREE_HEIGHT,
15
7
  } from '@aztec/constants';
16
8
  import { BlockNumber } from '@aztec/foundation/branded-types';
17
9
  import { padArrayEnd } from '@aztec/foundation/collection';
18
- import { BLS12Point } from '@aztec/foundation/curves/bls12';
19
10
  import { Fr } from '@aztec/foundation/curves/bn254';
20
11
  import type { Tuple } from '@aztec/foundation/serialize';
21
12
  import { type TreeNodeLocation, UnbalancedTreeStore } from '@aztec/foundation/trees';
22
13
  import type { PublicInputsAndRecursiveProof } from '@aztec/stdlib/interfaces/server';
23
- import { computeCheckpointOutHash } from '@aztec/stdlib/messaging';
24
14
  import { ParityBasePrivateInputs } from '@aztec/stdlib/parity';
25
- import {
26
- BlockMergeRollupPrivateInputs,
27
- BlockRollupPublicInputs,
28
- CheckpointConstantData,
29
- CheckpointRollupPublicInputs,
30
- CheckpointRootRollupHints,
31
- CheckpointRootRollupPrivateInputs,
32
- CheckpointRootSingleBlockRollupPrivateInputs,
33
- } from '@aztec/stdlib/rollup';
34
- import type { CircuitName } from '@aztec/stdlib/stats';
15
+ import { BlockMergeRollupPrivateInputs, BlockRollupPublicInputs, CheckpointConstantData } from '@aztec/stdlib/rollup';
35
16
  import type { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
36
17
  import type { BlockHeader } from '@aztec/stdlib/tx';
37
18
  import type { UInt64 } from '@aztec/stdlib/types';
38
19
 
39
- import { accumulateBlobs, buildBlobHints, toProofData } from './block-building-helpers.js';
20
+ import { toProofData } from './block-building-helpers.js';
40
21
  import { BlockProvingState, type ProofState } from './block-proving-state.js';
41
- import type { EpochProvingState } from './epoch-proving-state.js';
42
-
43
- type OutHashHint = {
44
- treeSnapshot: AppendOnlyTreeSnapshot;
45
- siblingPath: Tuple<Fr, typeof OUT_HASH_TREE_HEIGHT>;
46
- };
47
22
 
48
23
  export class CheckpointProvingState {
49
24
  private blockProofs: UnbalancedTreeStore<
50
25
  ProofState<BlockRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
51
26
  >;
52
- private checkpointRootProof:
53
- | ProofState<CheckpointRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
54
- | undefined;
55
27
  private blocks: (BlockProvingState | undefined)[] = [];
56
- private previousOutHashHint: OutHashHint | undefined;
57
- private outHash: Fr | undefined;
58
- // The snapshot and sibling path after the checkpoint's out hash is inserted.
59
- // Stored here to be retrieved for the next checkpoint when it's added.
60
- private newOutHashHint: OutHashHint | undefined;
61
- private startBlobAccumulator: BatchedBlobAccumulator | undefined;
62
- private endBlobAccumulator: BatchedBlobAccumulator | undefined;
63
- private blobFields: Fr[] | undefined;
64
28
  private error: string | undefined;
65
29
  public readonly firstBlockNumber: BlockNumber;
66
30
 
@@ -68,7 +32,6 @@ export class CheckpointProvingState {
68
32
  public readonly index: number,
69
33
  public readonly constants: CheckpointConstantData,
70
34
  public readonly totalNumBlocks: number,
71
- private readonly finalBlobBatchingChallenges: FinalBlobBatchingChallenges,
72
35
  private readonly headerOfLastBlockInPreviousCheckpoint: BlockHeader,
73
36
  private readonly lastArchiveSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>,
74
37
  private readonly l1ToL2Messages: Fr[],
@@ -84,17 +47,16 @@ export class CheckpointProvingState {
84
47
  Fr,
85
48
  typeof L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH
86
49
  >,
87
- public parentEpoch: EpochProvingState,
88
- private onBlobAccumulatorSet: (checkpoint: CheckpointProvingState) => Promise<void>,
50
+ public readonly epochNumber: number,
51
+ /** Owner's liveness check. `verifyState()` returns false once this returns false. */
52
+ private readonly isAlive: () => boolean,
53
+ /** Owner's failure callback. Invoked from `reject` to surface the error upward. */
54
+ private readonly onReject: (reason: string) => void,
89
55
  ) {
90
56
  this.blockProofs = new UnbalancedTreeStore(totalNumBlocks);
91
57
  this.firstBlockNumber = BlockNumber(headerOfLastBlockInPreviousCheckpoint.globalVariables.blockNumber + 1);
92
58
  }
93
59
 
94
- public get epochNumber(): number {
95
- return this.parentEpoch.epochNumber;
96
- }
97
-
98
60
  public startNewBlock(
99
61
  blockNumber: BlockNumber,
100
62
  timestamp: UInt64,
@@ -176,25 +138,6 @@ export class CheckpointProvingState {
176
138
  this.blockProofs.setNode(location, { provingOutput });
177
139
  }
178
140
 
179
- public tryStartProvingCheckpointRoot() {
180
- if (this.checkpointRootProof?.isProving) {
181
- return false;
182
- } else {
183
- this.checkpointRootProof = { isProving: true };
184
- return true;
185
- }
186
- }
187
-
188
- public setCheckpointRootRollupProof(
189
- provingOutput: PublicInputsAndRecursiveProof<
190
- CheckpointRollupPublicInputs,
191
- typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
192
- >,
193
- ): TreeNodeLocation {
194
- this.checkpointRootProof = { provingOutput };
195
- return this.parentEpoch.setCheckpointRootRollupProof(this.index, provingOutput);
196
- }
197
-
198
141
  public getBaseParityInputs(baseParityIndex: number) {
199
142
  const messages = padArrayEnd(
200
143
  this.l1ToL2Messages.slice(
@@ -204,54 +147,7 @@ export class CheckpointProvingState {
204
147
  Fr.ZERO,
205
148
  NUM_MSGS_PER_BASE_PARITY,
206
149
  );
207
- return new ParityBasePrivateInputs(messages, this.constants.vkTreeRoot);
208
- }
209
-
210
- public setOutHashHint(hint: OutHashHint) {
211
- this.previousOutHashHint = hint;
212
- }
213
-
214
- public getOutHashHint() {
215
- return this.previousOutHashHint;
216
- }
217
-
218
- public accumulateBlockOutHashes() {
219
- if (this.isAcceptingBlocks() || this.blocks.some(b => !b?.hasEndState())) {
220
- return;
221
- }
222
-
223
- if (!this.outHash) {
224
- const messagesPerBlock = this.blocks.map(b => b!.getTxEffects().map(tx => tx.l2ToL1Msgs));
225
- this.outHash = computeCheckpointOutHash(messagesPerBlock);
226
- }
227
-
228
- return this.outHash;
229
- }
230
-
231
- public setOutHashHintForNextCheckpoint(hint: OutHashHint) {
232
- this.newOutHashHint = hint;
233
- }
234
-
235
- public getOutHashHintForNextCheckpoint() {
236
- return this.newOutHashHint;
237
- }
238
-
239
- public async accumulateBlobs(startBlobAccumulator: BatchedBlobAccumulator) {
240
- if (this.isAcceptingBlocks() || this.blocks.some(b => !b?.hasEndState())) {
241
- return;
242
- }
243
-
244
- this.blobFields = encodeCheckpointBlobDataFromBlocks(this.blocks.map(b => b!.getBlockBlobData()));
245
- this.endBlobAccumulator = await accumulateBlobs(this.blobFields!, startBlobAccumulator);
246
- this.startBlobAccumulator = startBlobAccumulator;
247
-
248
- await this.onBlobAccumulatorSet(this);
249
-
250
- return this.endBlobAccumulator;
251
- }
252
-
253
- public getEndBlobAccumulator() {
254
- return this.endBlobAccumulator;
150
+ return new ParityBasePrivateInputs(messages, this.constants.vkTreeRoot, this.constants.proverId);
255
151
  }
256
152
 
257
153
  public getParentLocation(location: TreeNodeLocation) {
@@ -267,47 +163,6 @@ export class CheckpointProvingState {
267
163
  return new BlockMergeRollupPrivateInputs([toProofData(left), toProofData(right)]);
268
164
  }
269
165
 
270
- public getCheckpointRootRollupType(): CircuitName {
271
- return this.totalNumBlocks === 1 ? 'rollup-checkpoint-root-single-block' : 'rollup-checkpoint-root';
272
- }
273
-
274
- public async getCheckpointRootRollupInputs() {
275
- const proofs = this.#getChildProofsForRoot();
276
- const nonEmptyProofs = proofs.filter(p => !!p);
277
- if (proofs.length !== nonEmptyProofs.length) {
278
- throw new Error('At least one child is not ready for the checkpoint root rollup.');
279
- }
280
- if (!this.previousOutHashHint) {
281
- throw new Error('Out hash hint is not set.');
282
- }
283
- if (!this.startBlobAccumulator) {
284
- throw new Error('Start blob accumulator is not set.');
285
- }
286
-
287
- // `blobFields` must've been set if `startBlobAccumulator` is set (in `accumulateBlobs`).
288
- const blobFields = this.blobFields!;
289
-
290
- const { blobCommitments, blobsHash } = await buildBlobHints(blobFields);
291
-
292
- const hints = CheckpointRootRollupHints.from({
293
- previousBlockHeader: this.headerOfLastBlockInPreviousCheckpoint,
294
- previousArchiveSiblingPath: this.lastArchiveSiblingPath,
295
- previousOutHash: this.previousOutHashHint.treeSnapshot,
296
- newOutHashSiblingPath: this.previousOutHashHint.siblingPath,
297
- startBlobAccumulator: this.startBlobAccumulator.toBlobAccumulator(),
298
- finalBlobChallenges: this.finalBlobBatchingChallenges,
299
- blobFields: padArrayEnd(blobFields, Fr.ZERO, FIELDS_PER_BLOB * BLOBS_PER_CHECKPOINT),
300
- blobCommitments: padArrayEnd(blobCommitments, BLS12Point.ZERO, BLOBS_PER_CHECKPOINT),
301
- blobsHash,
302
- });
303
-
304
- const [left, right] = nonEmptyProofs.map(p => toProofData(p));
305
-
306
- return !right
307
- ? new CheckpointRootSingleBlockRollupPrivateInputs(left, hints)
308
- : new CheckpointRootRollupPrivateInputs([left, right], hints);
309
- }
310
-
311
166
  public getBlockProvingStateByBlockNumber(blockNumber: BlockNumber) {
312
167
  const index = Number(blockNumber) - Number(this.firstBlockNumber);
313
168
  return this.blocks[index];
@@ -317,13 +172,8 @@ export class CheckpointProvingState {
317
172
  return !!this.blockProofs.getSibling(location)?.provingOutput;
318
173
  }
319
174
 
320
- public isReadyForCheckpointRoot() {
321
- const allChildProofsReady = this.#getChildProofsForRoot().every(p => !!p);
322
- return allChildProofsReady && !!this.previousOutHashHint && !!this.startBlobAccumulator;
323
- }
324
-
325
175
  public verifyState() {
326
- return this.parentEpoch.verifyState();
176
+ return this.isAlive();
327
177
  }
328
178
 
329
179
  public getError() {
@@ -337,13 +187,22 @@ export class CheckpointProvingState {
337
187
 
338
188
  public reject(reason: string) {
339
189
  this.error = reason;
340
- this.parentEpoch.reject(reason);
190
+ this.onReject(reason);
341
191
  }
342
192
 
343
- #getChildProofsForRoot() {
193
+ /**
194
+ * Returns the block-level proof outputs that feed into the checkpoint root rollup.
195
+ * Used by `CheckpointSubTreeOrchestrator` to surface its sub-tree result.
196
+ */
197
+ public getSubTreeOutputProofs() {
344
198
  const rootLocation = { level: 0, index: 0 };
345
199
  return this.totalNumBlocks === 1
346
200
  ? [this.blockProofs.getNode(rootLocation)?.provingOutput] // If there's only 1 block, its proof will be stored at the root.
347
201
  : this.blockProofs.getChildren(rootLocation).map(c => c?.provingOutput);
348
202
  }
203
+
204
+ /** Sibling path of the archive tree captured before any block in this checkpoint landed. */
205
+ public getLastArchiveSiblingPath() {
206
+ return this.lastArchiveSiblingPath;
207
+ }
349
208
  }