@aztec/prover-client 0.0.1-commit.9593d84 → 0.0.1-commit.96bb3f7

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 (99) hide show
  1. package/dest/block-factory/light.d.ts +3 -3
  2. package/dest/block-factory/light.d.ts.map +1 -1
  3. package/dest/block-factory/light.js +4 -6
  4. package/dest/config.d.ts +2 -2
  5. package/dest/config.d.ts.map +1 -1
  6. package/dest/config.js +1 -1
  7. package/dest/light/index.d.ts +2 -0
  8. package/dest/light/index.d.ts.map +1 -0
  9. package/dest/light/index.js +1 -0
  10. package/dest/light/lightweight_checkpoint_builder.d.ts +28 -13
  11. package/dest/light/lightweight_checkpoint_builder.d.ts.map +1 -1
  12. package/dest/light/lightweight_checkpoint_builder.js +94 -18
  13. package/dest/mocks/fixtures.js +4 -4
  14. package/dest/mocks/test_context.d.ts +3 -2
  15. package/dest/mocks/test_context.d.ts.map +1 -1
  16. package/dest/mocks/test_context.js +19 -10
  17. package/dest/orchestrator/block-building-helpers.d.ts +4 -4
  18. package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
  19. package/dest/orchestrator/block-building-helpers.js +4 -3
  20. package/dest/orchestrator/block-proving-state.d.ts +5 -4
  21. package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
  22. package/dest/orchestrator/block-proving-state.js +1 -1
  23. package/dest/orchestrator/checkpoint-proving-state.d.ts +6 -5
  24. package/dest/orchestrator/checkpoint-proving-state.d.ts.map +1 -1
  25. package/dest/orchestrator/checkpoint-proving-state.js +6 -4
  26. package/dest/orchestrator/epoch-proving-state.d.ts +5 -5
  27. package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
  28. package/dest/orchestrator/epoch-proving-state.js +1 -1
  29. package/dest/orchestrator/orchestrator.d.ts +7 -7
  30. package/dest/orchestrator/orchestrator.d.ts.map +1 -1
  31. package/dest/orchestrator/orchestrator.js +421 -60
  32. package/dest/orchestrator/orchestrator_metrics.d.ts +1 -3
  33. package/dest/orchestrator/orchestrator_metrics.d.ts.map +1 -1
  34. package/dest/orchestrator/orchestrator_metrics.js +2 -15
  35. package/dest/orchestrator/tx-proving-state.d.ts +6 -5
  36. package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
  37. package/dest/orchestrator/tx-proving-state.js +8 -8
  38. package/dest/prover-client/factory.d.ts +3 -3
  39. package/dest/prover-client/factory.d.ts.map +1 -1
  40. package/dest/prover-client/prover-client.d.ts +3 -3
  41. package/dest/prover-client/prover-client.d.ts.map +1 -1
  42. package/dest/prover-client/prover-client.js +1 -1
  43. package/dest/prover-client/server-epoch-prover.d.ts +5 -5
  44. package/dest/prover-client/server-epoch-prover.d.ts.map +1 -1
  45. package/dest/proving_broker/broker_prover_facade.d.ts +4 -3
  46. package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
  47. package/dest/proving_broker/broker_prover_facade.js +3 -10
  48. package/dest/proving_broker/config.d.ts +2 -2
  49. package/dest/proving_broker/config.d.ts.map +1 -1
  50. package/dest/proving_broker/config.js +1 -1
  51. package/dest/proving_broker/fixtures.js +1 -1
  52. package/dest/proving_broker/proving_agent.d.ts +3 -8
  53. package/dest/proving_broker/proving_agent.d.ts.map +1 -1
  54. package/dest/proving_broker/proving_agent.js +1 -16
  55. package/dest/proving_broker/proving_broker.d.ts +1 -1
  56. package/dest/proving_broker/proving_broker.d.ts.map +1 -1
  57. package/dest/proving_broker/proving_broker.js +4 -10
  58. package/dest/proving_broker/proving_broker_database/persisted.d.ts +3 -2
  59. package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -1
  60. package/dest/proving_broker/proving_broker_database/persisted.js +389 -1
  61. package/dest/proving_broker/proving_broker_instrumentation.d.ts +1 -1
  62. package/dest/proving_broker/proving_broker_instrumentation.d.ts.map +1 -1
  63. package/dest/proving_broker/proving_broker_instrumentation.js +11 -35
  64. package/dest/proving_broker/proving_job_controller.d.ts +1 -1
  65. package/dest/proving_broker/proving_job_controller.d.ts.map +1 -1
  66. package/dest/proving_broker/proving_job_controller.js +2 -3
  67. package/dest/test/mock_prover.d.ts +2 -2
  68. package/dest/test/mock_prover.d.ts.map +1 -1
  69. package/dest/test/mock_prover.js +4 -4
  70. package/package.json +19 -17
  71. package/src/block-factory/light.ts +5 -6
  72. package/src/config.ts +1 -1
  73. package/src/light/index.ts +1 -0
  74. package/src/light/lightweight_checkpoint_builder.ts +133 -26
  75. package/src/mocks/fixtures.ts +4 -4
  76. package/src/mocks/test_context.ts +20 -10
  77. package/src/orchestrator/block-building-helpers.ts +4 -3
  78. package/src/orchestrator/block-proving-state.ts +3 -2
  79. package/src/orchestrator/checkpoint-proving-state.ts +9 -7
  80. package/src/orchestrator/epoch-proving-state.ts +8 -5
  81. package/src/orchestrator/orchestrator.ts +16 -40
  82. package/src/orchestrator/orchestrator_metrics.ts +2 -25
  83. package/src/orchestrator/tx-proving-state.ts +10 -14
  84. package/src/prover-client/factory.ts +6 -2
  85. package/src/prover-client/prover-client.ts +4 -11
  86. package/src/prover-client/server-epoch-prover.ts +4 -4
  87. package/src/proving_broker/broker_prover_facade.ts +4 -14
  88. package/src/proving_broker/config.ts +1 -1
  89. package/src/proving_broker/fixtures.ts +1 -1
  90. package/src/proving_broker/proving_agent.ts +1 -17
  91. package/src/proving_broker/proving_broker.ts +4 -8
  92. package/src/proving_broker/proving_broker_database/persisted.ts +15 -1
  93. package/src/proving_broker/proving_broker_instrumentation.ts +10 -35
  94. package/src/proving_broker/proving_job_controller.ts +2 -3
  95. package/src/test/mock_prover.ts +2 -14
  96. package/dest/proving_broker/proving_agent_instrumentation.d.ts +0 -8
  97. package/dest/proving_broker/proving_agent_instrumentation.d.ts.map +0 -1
  98. package/dest/proving_broker/proving_agent_instrumentation.js +0 -16
  99. package/src/proving_broker/proving_agent_instrumentation.ts +0 -21
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "@aztec/prover-client",
3
- "version": "0.0.1-commit.9593d84",
3
+ "version": "0.0.1-commit.96bb3f7",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
7
7
  "./block-factory": "./dest/block-factory/index.js",
8
8
  "./broker": "./dest/proving_broker/index.js",
9
+ "./broker/config": "./dest/proving_broker/config.js",
9
10
  "./orchestrator": "./dest/orchestrator/index.js",
10
11
  "./helpers": "./dest/orchestrator/block-building-helpers.js",
12
+ "./light": "./dest/light/index.js",
11
13
  "./config": "./dest/config.js"
12
14
  },
13
15
  "typedocOptions": {
@@ -22,8 +24,8 @@
22
24
  "./package.local.json"
23
25
  ],
24
26
  "scripts": {
25
- "build": "yarn clean && tsgo -b",
26
- "build:dev": "tsgo -b --watch",
27
+ "build": "yarn clean && ../scripts/tsc.sh",
28
+ "build:dev": "../scripts/tsc.sh --watch",
27
29
  "clean": "rm -rf ./dest .tsbuildinfo",
28
30
  "bb": "node --no-warnings ./dest/bb/index.js",
29
31
  "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --testTimeout=3500000 --forceExit",
@@ -67,19 +69,19 @@
67
69
  ]
68
70
  },
69
71
  "dependencies": {
70
- "@aztec/bb-prover": "0.0.1-commit.9593d84",
71
- "@aztec/blob-lib": "0.0.1-commit.9593d84",
72
- "@aztec/constants": "0.0.1-commit.9593d84",
73
- "@aztec/ethereum": "0.0.1-commit.9593d84",
74
- "@aztec/foundation": "0.0.1-commit.9593d84",
75
- "@aztec/kv-store": "0.0.1-commit.9593d84",
76
- "@aztec/noir-protocol-circuits-types": "0.0.1-commit.9593d84",
77
- "@aztec/noir-types": "0.0.1-commit.9593d84",
78
- "@aztec/protocol-contracts": "0.0.1-commit.9593d84",
79
- "@aztec/simulator": "0.0.1-commit.9593d84",
80
- "@aztec/stdlib": "0.0.1-commit.9593d84",
81
- "@aztec/telemetry-client": "0.0.1-commit.9593d84",
82
- "@aztec/world-state": "0.0.1-commit.9593d84",
72
+ "@aztec/bb-prover": "0.0.1-commit.96bb3f7",
73
+ "@aztec/blob-lib": "0.0.1-commit.96bb3f7",
74
+ "@aztec/constants": "0.0.1-commit.96bb3f7",
75
+ "@aztec/ethereum": "0.0.1-commit.96bb3f7",
76
+ "@aztec/foundation": "0.0.1-commit.96bb3f7",
77
+ "@aztec/kv-store": "0.0.1-commit.96bb3f7",
78
+ "@aztec/noir-protocol-circuits-types": "0.0.1-commit.96bb3f7",
79
+ "@aztec/noir-types": "0.0.1-commit.96bb3f7",
80
+ "@aztec/protocol-contracts": "0.0.1-commit.96bb3f7",
81
+ "@aztec/simulator": "0.0.1-commit.96bb3f7",
82
+ "@aztec/stdlib": "0.0.1-commit.96bb3f7",
83
+ "@aztec/telemetry-client": "0.0.1-commit.96bb3f7",
84
+ "@aztec/world-state": "0.0.1-commit.96bb3f7",
83
85
  "@google-cloud/storage": "^7.15.0",
84
86
  "@iarna/toml": "^2.2.5",
85
87
  "commander": "^12.1.0",
@@ -89,7 +91,7 @@
89
91
  "zod": "^3.23.8"
90
92
  },
91
93
  "devDependencies": {
92
- "@aztec/noir-contracts.js": "0.0.1-commit.9593d84",
94
+ "@aztec/noir-contracts.js": "0.0.1-commit.96bb3f7",
93
95
  "@jest/globals": "^30.0.0",
94
96
  "@types/jest": "^30.0.0",
95
97
  "@types/node": "^22.15.17",
@@ -1,13 +1,13 @@
1
1
  import { SpongeBlob, computeBlobsHashFromBlobs, encodeCheckpointEndMarker, getBlobsPerL1Block } from '@aztec/blob-lib';
2
2
  import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
3
3
  import { padArrayEnd } from '@aztec/foundation/collection';
4
- import { Fr } from '@aztec/foundation/fields';
4
+ import { Fr } from '@aztec/foundation/curves/bn254';
5
5
  import { createLogger } from '@aztec/foundation/log';
6
6
  import { L2Block, L2BlockHeader } from '@aztec/stdlib/block';
7
7
  import type { IBlockFactory, MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
8
- import { computeBlockOutHash, computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
8
+ import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
9
9
  import { MerkleTreeId } from '@aztec/stdlib/trees';
10
- import { ContentCommitment, type GlobalVariables, type ProcessedTx } from '@aztec/stdlib/tx';
10
+ import type { GlobalVariables, ProcessedTx } from '@aztec/stdlib/tx';
11
11
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
12
12
 
13
13
  import {
@@ -87,17 +87,16 @@ export class LightweightBlockFactory implements IBlockFactory {
87
87
  await this.db.updateArchive(header);
88
88
  const newArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, this.db);
89
89
 
90
- const outHash = computeBlockOutHash(txs.map(tx => tx.txEffect.l2ToL1Msgs));
91
90
  const inHash = computeInHashFromL1ToL2Messages(this.l1ToL2Messages!);
92
91
  const numBlobFields = blockBlobFields.length + 1;
93
92
  const blobFields = blockBlobFields.concat([encodeCheckpointEndMarker({ numBlobFields })]);
94
93
  const blobsHash = computeBlobsHashFromBlobs(getBlobsPerL1Block(blobFields));
95
94
  const blockHeaderHash = await header.hash();
96
- const contentCommitment = new ContentCommitment(blobsHash, inHash, outHash);
97
95
  const l2BlockHeader = L2BlockHeader.from({
98
96
  ...header,
99
97
  blockHeadersHash: blockHeaderHash,
100
- contentCommitment,
98
+ blobsHash,
99
+ inHash,
101
100
  });
102
101
 
103
102
  const block = new L2Block(newArchive, l2BlockHeader, body);
package/src/config.ts CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  getConfigFromMappings,
6
6
  numberConfigHelper,
7
7
  } from '@aztec/foundation/config';
8
- import { type ProverConfig, proverConfigMappings } from '@aztec/stdlib/interfaces/server';
8
+ import { type ProverConfig, proverConfigMappings } from '@aztec/stdlib/interfaces/prover-config';
9
9
 
10
10
  import {
11
11
  type ProverAgentConfig,
@@ -0,0 +1 @@
1
+ export * from './lightweight_checkpoint_builder.js';
@@ -1,15 +1,21 @@
1
1
  import { SpongeBlob, computeBlobsHashFromBlobs, encodeCheckpointEndMarker, getBlobsPerL1Block } from '@aztec/blob-lib';
2
2
  import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
3
+ import type { CheckpointNumber } from '@aztec/foundation/branded-types';
3
4
  import { padArrayEnd } from '@aztec/foundation/collection';
4
- import { Fr } from '@aztec/foundation/fields';
5
+ import { Fr } from '@aztec/foundation/curves/bn254';
5
6
  import { createLogger } from '@aztec/foundation/log';
6
7
  import { L2BlockNew } from '@aztec/stdlib/block';
7
8
  import { Checkpoint } from '@aztec/stdlib/checkpoint';
8
9
  import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
9
- import { computeCheckpointOutHash, computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
10
- import { CheckpointConstantData, CheckpointHeader, computeBlockHeadersHash } from '@aztec/stdlib/rollup';
10
+ import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
11
+ import { CheckpointHeader, computeBlockHeadersHash } from '@aztec/stdlib/rollup';
11
12
  import { AppendOnlyTreeSnapshot, MerkleTreeId } from '@aztec/stdlib/trees';
12
- import { ContentCommitment, type GlobalVariables, type ProcessedTx, StateReference } from '@aztec/stdlib/tx';
13
+ import {
14
+ type CheckpointGlobalVariables,
15
+ type GlobalVariables,
16
+ type ProcessedTx,
17
+ StateReference,
18
+ } from '@aztec/stdlib/tx';
13
19
 
14
20
  import {
15
21
  buildHeaderAndBodyFromTxs,
@@ -20,29 +26,30 @@ import {
20
26
  /**
21
27
  * Builds a checkpoint and its header and the blocks in it from a set of processed tx without running any circuits.
22
28
  *
23
- * It updates the l1-to-l2 message tree when starting a new checkpoint, inserts the side effects to note hash,
24
- * nullifier, and public data trees, then updates the archive tree when a block is added.
29
+ * It updates the l1-to-l2 message tree when starting a new checkpoint, and then updates the archive tree when each block is added.
30
+ * Finally completes the checkpoint by computing its header.
25
31
  */
26
32
  export class LightweightCheckpointBuilder {
27
33
  private readonly logger = createLogger('lightweight-checkpoint-builder');
34
+
28
35
  private lastArchives: AppendOnlyTreeSnapshot[] = [];
29
36
  private spongeBlob: SpongeBlob;
30
37
  private blocks: L2BlockNew[] = [];
31
38
  private blobFields: Fr[] = [];
32
39
 
33
40
  constructor(
34
- private checkpointNumber: number,
35
- private constants: CheckpointConstantData,
36
- private l1ToL2Messages: Fr[],
37
- private db: MerkleTreeWriteOperations,
41
+ public readonly checkpointNumber: CheckpointNumber,
42
+ public readonly constants: CheckpointGlobalVariables,
43
+ public readonly l1ToL2Messages: Fr[],
44
+ public readonly db: MerkleTreeWriteOperations,
38
45
  ) {
39
46
  this.spongeBlob = SpongeBlob.init();
40
- this.logger.debug('Starting new checkpoint', { constants: constants.toInspect(), l1ToL2Messages });
47
+ this.logger.debug('Starting new checkpoint', { constants, l1ToL2Messages });
41
48
  }
42
49
 
43
50
  static async startNewCheckpoint(
44
- checkpointNumber: number,
45
- constants: CheckpointConstantData,
51
+ checkpointNumber: CheckpointNumber,
52
+ constants: CheckpointGlobalVariables,
46
53
  l1ToL2Messages: Fr[],
47
54
  db: MerkleTreeWriteOperations,
48
55
  ): Promise<LightweightCheckpointBuilder> {
@@ -55,16 +62,99 @@ export class LightweightCheckpointBuilder {
55
62
  return new LightweightCheckpointBuilder(checkpointNumber, constants, l1ToL2Messages, db);
56
63
  }
57
64
 
58
- async addBlock(globalVariables: GlobalVariables, endState: StateReference, txs: ProcessedTx[]): Promise<L2BlockNew> {
65
+ /**
66
+ * Resumes building a checkpoint from existing blocks. This is used for validator re-execution
67
+ * where blocks have already been built and their effects are already in the database.
68
+ * Unlike startNewCheckpoint, this does NOT append l1ToL2Messages to the tree since they
69
+ * were already added when the blocks were originally built.
70
+ */
71
+ static async resumeCheckpoint(
72
+ checkpointNumber: CheckpointNumber,
73
+ constants: CheckpointGlobalVariables,
74
+ l1ToL2Messages: Fr[],
75
+ db: MerkleTreeWriteOperations,
76
+ existingBlocks: L2BlockNew[],
77
+ ): Promise<LightweightCheckpointBuilder> {
78
+ const builder = new LightweightCheckpointBuilder(checkpointNumber, constants, l1ToL2Messages, db);
79
+
80
+ builder.logger.debug('Resuming checkpoint from existing blocks', {
81
+ checkpointNumber,
82
+ numExistingBlocks: existingBlocks.length,
83
+ blockNumbers: existingBlocks.map(b => b.header.getBlockNumber()),
84
+ });
85
+
86
+ // Validate block order and consistency
87
+ for (let i = 1; i < existingBlocks.length; i++) {
88
+ const prev = existingBlocks[i - 1];
89
+ const curr = existingBlocks[i];
90
+ if (curr.number !== prev.number + 1) {
91
+ throw new Error(`Non-sequential block numbers in resumeCheckpoint: ${prev.number} -> ${curr.number}`);
92
+ }
93
+ if (!prev.archive.root.equals(curr.header.lastArchive.root)) {
94
+ throw new Error(`Archive root mismatch between blocks ${prev.number} and ${curr.number}`);
95
+ }
96
+ }
97
+
98
+ for (let i = 0; i < existingBlocks.length; i++) {
99
+ const block = existingBlocks[i];
100
+ const isFirstBlock = i === 0;
101
+
102
+ if (isFirstBlock) {
103
+ builder.lastArchives.push(block.header.lastArchive);
104
+ }
105
+
106
+ builder.lastArchives.push(block.archive);
107
+
108
+ const blockBlobFields = block.toBlobFields();
109
+ await builder.spongeBlob.absorb(blockBlobFields);
110
+ builder.blobFields.push(...blockBlobFields);
111
+
112
+ builder.blocks.push(block);
113
+ }
114
+
115
+ return builder;
116
+ }
117
+
118
+ /**
119
+ * Adds a new block to the checkpoint. The tx effects must have already been inserted into the db if
120
+ * this is called after tx processing, if that's not the case, then set `insertTxsEffects` to true.
121
+ */
122
+ public async addBlock(
123
+ globalVariables: GlobalVariables,
124
+ txs: ProcessedTx[],
125
+ opts: { insertTxsEffects?: boolean; expectedEndState?: StateReference } = {},
126
+ ): Promise<L2BlockNew> {
59
127
  const isFirstBlock = this.blocks.length === 0;
128
+
129
+ // Empty blocks are only allowed as the first block in a checkpoint
130
+ if (!isFirstBlock && txs.length === 0) {
131
+ throw new Error('Cannot add empty block that is not the first block in the checkpoint.');
132
+ }
133
+
60
134
  if (isFirstBlock) {
61
135
  this.lastArchives.push(await getTreeSnapshot(MerkleTreeId.ARCHIVE, this.db));
62
136
  }
63
137
 
64
138
  const lastArchive = this.lastArchives.at(-1)!;
65
139
 
66
- for (const tx of txs) {
67
- await insertSideEffects(tx, this.db);
140
+ if (opts.insertTxsEffects) {
141
+ this.logger.debug(
142
+ `Inserting side effects for ${txs.length} txs for block ${globalVariables.blockNumber} into db`,
143
+ { txs: txs.map(tx => tx.hash.toString()) },
144
+ );
145
+ for (const tx of txs) {
146
+ await insertSideEffects(tx, this.db);
147
+ }
148
+ }
149
+
150
+ const endState = await this.db.getStateReference();
151
+ if (opts.expectedEndState && !endState.equals(opts.expectedEndState)) {
152
+ this.logger.error('End state after processing txs does not match expected end state', {
153
+ globalVariables: globalVariables.toInspect(),
154
+ expectedEndState: opts.expectedEndState.toInspect(),
155
+ actualEndState: endState.toInspect(),
156
+ });
157
+ throw new Error(`End state does not match expected end state when building block ${globalVariables.blockNumber}`);
68
158
  }
69
159
 
70
160
  const { header, body, blockBlobFields } = await buildHeaderAndBodyFromTxs(
@@ -76,11 +166,14 @@ export class LightweightCheckpointBuilder {
76
166
  isFirstBlock,
77
167
  );
78
168
 
169
+ header.state.validate();
170
+
79
171
  await this.db.updateArchive(header);
80
172
  const newArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, this.db);
81
173
  this.lastArchives.push(newArchive);
82
174
 
83
- const block = new L2BlockNew(newArchive, header, body);
175
+ const indexWithinCheckpoint = this.blocks.length;
176
+ const block = new L2BlockNew(newArchive, header, body, this.checkpointNumber, indexWithinCheckpoint);
84
177
  this.blocks.push(block);
85
178
 
86
179
  await this.spongeBlob.absorb(blockBlobFields);
@@ -99,7 +192,7 @@ export class LightweightCheckpointBuilder {
99
192
 
100
193
  async completeCheckpoint(): Promise<Checkpoint> {
101
194
  if (!this.blocks.length) {
102
- throw new Error('No blocks added to checkpoint.');
195
+ throw new Error('Cannot complete a checkpoint with no blocks');
103
196
  }
104
197
 
105
198
  const numBlobFields = this.blobFields.length + 1; // +1 for the checkpoint end marker.
@@ -116,10 +209,9 @@ export class LightweightCheckpointBuilder {
116
209
 
117
210
  const inHash = computeInHashFromL1ToL2Messages(this.l1ToL2Messages);
118
211
 
119
- const outHash = computeCheckpointOutHash(blocks.map(block => block.body.txEffects.map(tx => tx.l2ToL1Msgs)));
120
-
121
- const constants = this.constants!;
212
+ const { slotNumber, coinbase, feeRecipient, gasFees } = this.constants;
122
213
 
214
+ // TODO(palla/mbps): Should we source this from the constants instead?
123
215
  // timestamp of a checkpoint is the timestamp of the last block in the checkpoint.
124
216
  const timestamp = blocks[blocks.length - 1].timestamp;
125
217
 
@@ -127,16 +219,31 @@ export class LightweightCheckpointBuilder {
127
219
 
128
220
  const header = CheckpointHeader.from({
129
221
  lastArchiveRoot: this.lastArchives[0].root,
222
+ blobsHash,
223
+ inHash,
130
224
  blockHeadersHash,
131
- contentCommitment: new ContentCommitment(blobsHash, inHash, outHash),
132
- slotNumber: constants.slotNumber,
225
+ slotNumber,
133
226
  timestamp,
134
- coinbase: constants.coinbase,
135
- feeRecipient: constants.feeRecipient,
136
- gasFees: constants.gasFees,
227
+ coinbase,
228
+ feeRecipient,
229
+ gasFees,
137
230
  totalManaUsed,
138
231
  });
139
232
 
140
233
  return new Checkpoint(newArchive, header, blocks, this.checkpointNumber);
141
234
  }
235
+
236
+ clone() {
237
+ const clone = new LightweightCheckpointBuilder(
238
+ this.checkpointNumber,
239
+ this.constants,
240
+ [...this.l1ToL2Messages],
241
+ this.db,
242
+ );
243
+ clone.lastArchives = [...this.lastArchives];
244
+ clone.spongeBlob = this.spongeBlob.clone();
245
+ clone.blocks = [...this.blocks];
246
+ clone.blobFields = [...this.blobFields];
247
+ return clone;
248
+ }
142
249
  }
@@ -1,7 +1,7 @@
1
- import { SlotNumber } from '@aztec/foundation/branded-types';
2
- import { randomBytes } from '@aztec/foundation/crypto';
1
+ import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
2
+ import { randomBytes } from '@aztec/foundation/crypto/random';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
3
4
  import { EthAddress } from '@aztec/foundation/eth-address';
4
- import { Fr } from '@aztec/foundation/fields';
5
5
  import type { Logger } from '@aztec/foundation/log';
6
6
  import type { FieldsOf } from '@aztec/foundation/types';
7
7
  import { fileURLToPath } from '@aztec/foundation/url';
@@ -93,7 +93,7 @@ export const makeGlobals = (
93
93
  return GlobalVariables.from({
94
94
  chainId: checkpointConstants.chainId,
95
95
  version: checkpointConstants.version,
96
- blockNumber /** block number */,
96
+ blockNumber: BlockNumber(blockNumber) /** block number */,
97
97
  slotNumber: SlotNumber(slotNumber) /** slot number */,
98
98
  timestamp: BigInt(blockNumber * 123) /** block number * 123 as pseudo-timestamp for testing */,
99
99
  coinbase: checkpointConstants.coinbase,
@@ -1,8 +1,9 @@
1
1
  import type { BBProverConfig } from '@aztec/bb-prover';
2
2
  import { TestCircuitProver } from '@aztec/bb-prover';
3
3
  import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
4
+ import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
4
5
  import { padArrayEnd, times, timesAsync } from '@aztec/foundation/collection';
5
- import { Fr } from '@aztec/foundation/fields';
6
+ import { Fr } from '@aztec/foundation/curves/bn254';
6
7
  import type { Logger } from '@aztec/foundation/log';
7
8
  import type { FieldsOf } from '@aztec/foundation/types';
8
9
  import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
@@ -44,6 +45,7 @@ export class TestContext {
44
45
  private headers: Map<number, BlockHeader> = new Map();
45
46
  private checkpoints: Checkpoint[] = [];
46
47
  private nextCheckpointIndex = 0;
48
+ private nextCheckpointNumber = CheckpointNumber(1);
47
49
  private nextBlockNumber = 1;
48
50
  private epochNumber = 1;
49
51
  private feePayerBalance: Fr;
@@ -186,7 +188,8 @@ export class TestContext {
186
188
  }
187
189
 
188
190
  const checkpointIndex = this.nextCheckpointIndex++;
189
- const checkpointNumber = checkpointIndex + 1;
191
+ const checkpointNumber = this.nextCheckpointNumber;
192
+ this.nextCheckpointNumber++;
190
193
  const slotNumber = checkpointNumber * 15; // times an arbitrary number to make it different to the checkpoint number
191
194
 
192
195
  const constants = makeCheckpointConstants(slotNumber, constantOpts);
@@ -202,7 +205,9 @@ export class TestContext {
202
205
  const newL1ToL2Snapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, fork);
203
206
 
204
207
  const startBlockNumber = this.nextBlockNumber;
205
- const previousBlockHeader = this.getBlockHeader(startBlockNumber - 1);
208
+ const previousBlockHeader = this.getBlockHeader(BlockNumber(startBlockNumber - 1));
209
+ // All blocks in the same slot/checkpoint share the same timestamp.
210
+ const timestamp = BigInt(slotNumber * 26);
206
211
 
207
212
  // Build global variables.
208
213
  const blockGlobalVariables = times(numBlocks, i =>
@@ -210,6 +215,7 @@ export class TestContext {
210
215
  coinbase: constants.coinbase,
211
216
  feeRecipient: constants.feeRecipient,
212
217
  gasFees: constants.gasFees,
218
+ timestamp,
213
219
  }),
214
220
  );
215
221
  this.nextBlockNumber += numBlocks;
@@ -249,17 +255,19 @@ export class TestContext {
249
255
  // Add tx effects to db and build block headers.
250
256
  const blocks = [];
251
257
  for (let i = 0; i < numBlocks; i++) {
252
- const isFirstBlock = i === 0;
253
258
  const txs = blockTxs[i];
254
259
  const state = blockEndStates[i];
255
260
 
256
- const block = await builder.addBlock(blockGlobalVariables[i], state, txs);
261
+ const block = await builder.addBlock(blockGlobalVariables[i], txs, {
262
+ expectedEndState: state,
263
+ insertTxsEffects: true,
264
+ });
257
265
 
258
266
  const header = block.header;
259
267
  this.headers.set(block.number, header);
260
268
 
261
- const blockMsgs = isFirstBlock ? l1ToL2Messages : [];
262
- await this.worldState.handleL2BlockAndMessages(block, blockMsgs, isFirstBlock);
269
+ const blockMsgs = block.indexWithinCheckpoint === 0 ? l1ToL2Messages : [];
270
+ await this.worldState.handleL2BlockAndMessages(block, blockMsgs);
263
271
 
264
272
  blocks.push({ header, txs });
265
273
  }
@@ -296,11 +304,13 @@ export class TestContext {
296
304
  return tx;
297
305
  }
298
306
 
299
- private getBlockHeader(blockNumber: number): BlockHeader {
300
- if (blockNumber > 0 && blockNumber >= this.nextBlockNumber) {
307
+ private getBlockHeader(blockNumber: BlockNumber): BlockHeader {
308
+ if (Number(blockNumber) > 0 && Number(blockNumber) >= this.nextBlockNumber) {
301
309
  throw new Error(`Block header not built for block number ${blockNumber}.`);
302
310
  }
303
- return blockNumber === 0 ? this.worldState.getCommitted().getInitialHeader() : this.headers.get(blockNumber)!;
311
+ return Number(blockNumber) === 0
312
+ ? this.worldState.getCommitted().getInitialHeader()
313
+ : this.headers.get(Number(blockNumber))!;
304
314
  }
305
315
 
306
316
  private async updateTrees(txs: ProcessedTx[], fork: MerkleTreeWriteOperations) {
@@ -20,8 +20,9 @@ import {
20
20
  PUBLIC_DATA_TREE_HEIGHT,
21
21
  } from '@aztec/constants';
22
22
  import { makeTuple } from '@aztec/foundation/array';
23
+ import { BlockNumber } from '@aztec/foundation/branded-types';
23
24
  import { padArrayEnd } from '@aztec/foundation/collection';
24
- import { Fr } from '@aztec/foundation/fields';
25
+ import { Fr } from '@aztec/foundation/curves/bn254';
25
26
  import { type Bufferable, assertLength, toFriendlyJSON } from '@aztec/foundation/serialize';
26
27
  import { MembershipWitness } from '@aztec/foundation/trees';
27
28
  import { getVkData } from '@aztec/noir-protocol-circuits-types/server/vks';
@@ -280,8 +281,8 @@ export const buildHeaderFromCircuitOutputs = runInSpan(
280
281
  const globalVariables = GlobalVariables.from({
281
282
  chainId: constants.chainId,
282
283
  version: constants.version,
283
- blockNumber: blockRootRollupOutput.previousArchive.nextAvailableLeafIndex,
284
- timestamp: blockRootRollupOutput.endTimestamp,
284
+ blockNumber: BlockNumber(blockRootRollupOutput.previousArchive.nextAvailableLeafIndex),
285
+ timestamp: blockRootRollupOutput.timestamp,
285
286
  slotNumber: constants.slotNumber,
286
287
  coinbase: constants.coinbase,
287
288
  feeRecipient: constants.feeRecipient,
@@ -6,7 +6,8 @@ import {
6
6
  type NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
7
7
  NUM_BASE_PARITY_PER_ROOT_PARITY,
8
8
  } from '@aztec/constants';
9
- import { Fr } from '@aztec/foundation/fields';
9
+ import { BlockNumber } from '@aztec/foundation/branded-types';
10
+ import { Fr } from '@aztec/foundation/curves/bn254';
10
11
  import { type Tuple, assertLength } from '@aztec/foundation/serialize';
11
12
  import { type TreeNodeLocation, UnbalancedTreeStore } from '@aztec/foundation/trees';
12
13
  import type { PublicInputsAndRecursiveProof } from '@aztec/stdlib/interfaces/server';
@@ -62,7 +63,7 @@ export class BlockProvingState {
62
63
 
63
64
  constructor(
64
65
  public readonly index: number,
65
- public readonly blockNumber: number,
66
+ public readonly blockNumber: BlockNumber,
66
67
  public readonly totalNumTxs: number,
67
68
  private readonly constants: CheckpointConstantData,
68
69
  private readonly timestamp: UInt64,
@@ -12,8 +12,10 @@ import {
12
12
  type NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
13
13
  NUM_MSGS_PER_BASE_PARITY,
14
14
  } from '@aztec/constants';
15
+ import { BlockNumber } from '@aztec/foundation/branded-types';
15
16
  import { padArrayEnd } from '@aztec/foundation/collection';
16
- import { BLS12Point, Fr } from '@aztec/foundation/fields';
17
+ import { BLS12Point } from '@aztec/foundation/curves/bls12';
18
+ import { Fr } from '@aztec/foundation/curves/bn254';
17
19
  import type { Tuple } from '@aztec/foundation/serialize';
18
20
  import { type TreeNodeLocation, UnbalancedTreeStore } from '@aztec/foundation/trees';
19
21
  import type { PublicInputsAndRecursiveProof } from '@aztec/stdlib/interfaces/server';
@@ -48,7 +50,7 @@ export class CheckpointProvingState {
48
50
  private endBlobAccumulator: BatchedBlobAccumulator | undefined;
49
51
  private blobFields: Fr[] | undefined;
50
52
  private error: string | undefined;
51
- public readonly firstBlockNumber: number;
53
+ public readonly firstBlockNumber: BlockNumber;
52
54
 
53
55
  constructor(
54
56
  public readonly index: number,
@@ -74,7 +76,7 @@ export class CheckpointProvingState {
74
76
  private onBlobAccumulatorSet: (checkpoint: CheckpointProvingState) => void,
75
77
  ) {
76
78
  this.blockProofs = new UnbalancedTreeStore(totalNumBlocks);
77
- this.firstBlockNumber = headerOfLastBlockInPreviousCheckpoint.globalVariables.blockNumber + 1;
79
+ this.firstBlockNumber = BlockNumber(headerOfLastBlockInPreviousCheckpoint.globalVariables.blockNumber + 1);
78
80
  }
79
81
 
80
82
  public get epochNumber(): number {
@@ -82,13 +84,13 @@ export class CheckpointProvingState {
82
84
  }
83
85
 
84
86
  public startNewBlock(
85
- blockNumber: number,
87
+ blockNumber: BlockNumber,
86
88
  timestamp: UInt64,
87
89
  totalNumTxs: number,
88
90
  lastArchiveTreeSnapshot: AppendOnlyTreeSnapshot,
89
91
  lastArchiveSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>,
90
92
  ): BlockProvingState {
91
- const index = blockNumber - this.firstBlockNumber;
93
+ const index = Number(blockNumber) - Number(this.firstBlockNumber);
92
94
  if (index >= this.totalNumBlocks) {
93
95
  throw new Error(`Unable to start a new block at index ${index}. Expected at most ${this.totalNumBlocks} blocks.`);
94
96
  }
@@ -260,8 +262,8 @@ export class CheckpointProvingState {
260
262
  : new CheckpointRootRollupPrivateInputs([left, right], hints);
261
263
  }
262
264
 
263
- public getBlockProvingStateByBlockNumber(blockNumber: number) {
264
- const index = blockNumber - this.firstBlockNumber;
265
+ public getBlockProvingStateByBlockNumber(blockNumber: BlockNumber) {
266
+ const index = Number(blockNumber) - Number(this.firstBlockNumber);
265
267
  return this.blocks[index];
266
268
  }
267
269
 
@@ -5,8 +5,8 @@ import type {
5
5
  NESTED_RECURSIVE_PROOF_LENGTH,
6
6
  NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
7
7
  } from '@aztec/constants';
8
- import { EpochNumber } from '@aztec/foundation/branded-types';
9
- import type { Fr } from '@aztec/foundation/fields';
8
+ import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
9
+ import type { Fr } from '@aztec/foundation/curves/bn254';
10
10
  import type { Tuple } from '@aztec/foundation/serialize';
11
11
  import { type TreeNodeLocation, UnbalancedTreeStore } from '@aztec/foundation/trees';
12
12
  import type { PublicInputsAndRecursiveProof } from '@aztec/stdlib/interfaces/server';
@@ -126,13 +126,16 @@ export class EpochProvingState {
126
126
  return this.checkpoints[index];
127
127
  }
128
128
 
129
- public getCheckpointProvingStateByBlockNumber(blockNumber: number) {
129
+ public getCheckpointProvingStateByBlockNumber(blockNumber: BlockNumber) {
130
130
  return this.checkpoints.find(
131
- c => c && blockNumber >= c.firstBlockNumber && blockNumber < c.firstBlockNumber + c.totalNumBlocks,
131
+ c =>
132
+ c &&
133
+ Number(blockNumber) >= Number(c.firstBlockNumber) &&
134
+ Number(blockNumber) < Number(c.firstBlockNumber) + c.totalNumBlocks,
132
135
  );
133
136
  }
134
137
 
135
- public getBlockProvingStateByBlockNumber(blockNumber: number) {
138
+ public getBlockProvingStateByBlockNumber(blockNumber: BlockNumber) {
136
139
  return this.getCheckpointProvingStateByBlockNumber(blockNumber)?.getBlockProvingStateByBlockNumber(blockNumber);
137
140
  }
138
141