@aztec/stdlib 0.0.1-commit.c949de6bc → 0.0.1-commit.cbf2c2d5d

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 (258) hide show
  1. package/dest/abi/abi.d.ts +138 -1
  2. package/dest/abi/abi.d.ts.map +1 -1
  3. package/dest/abi/abi.js +10 -2
  4. package/dest/abi/buffer.d.ts +14 -4
  5. package/dest/abi/buffer.d.ts.map +1 -1
  6. package/dest/abi/buffer.js +25 -4
  7. package/dest/abi/decoder.d.ts +2 -2
  8. package/dest/abi/decoder.d.ts.map +1 -1
  9. package/dest/abi/decoder.js +6 -1
  10. package/dest/abi/encoder.d.ts +1 -1
  11. package/dest/abi/encoder.d.ts.map +1 -1
  12. package/dest/abi/encoder.js +28 -1
  13. package/dest/abi/event_metadata_definition.d.ts +3 -1
  14. package/dest/abi/event_metadata_definition.d.ts.map +1 -1
  15. package/dest/abi/event_metadata_definition.js +1 -1
  16. package/dest/abi/utils.d.ts +14 -1
  17. package/dest/abi/utils.d.ts.map +1 -1
  18. package/dest/abi/utils.js +15 -0
  19. package/dest/avm/avm.d.ts +300 -300
  20. package/dest/block/l2_block.d.ts +9 -1
  21. package/dest/block/l2_block.d.ts.map +1 -1
  22. package/dest/block/l2_block.js +12 -2
  23. package/dest/block/l2_block_source.d.ts +16 -8
  24. package/dest/block/l2_block_source.d.ts.map +1 -1
  25. package/dest/checkpoint/checkpoint.d.ts +2 -1
  26. package/dest/checkpoint/checkpoint.d.ts.map +1 -1
  27. package/dest/checkpoint/checkpoint.js +9 -4
  28. package/dest/checkpoint/index.d.ts +2 -1
  29. package/dest/checkpoint/index.d.ts.map +1 -1
  30. package/dest/checkpoint/index.js +1 -0
  31. package/dest/checkpoint/validate.d.ts +36 -0
  32. package/dest/checkpoint/validate.d.ts.map +1 -0
  33. package/dest/checkpoint/validate.js +120 -0
  34. package/dest/config/index.d.ts +2 -1
  35. package/dest/config/index.d.ts.map +1 -1
  36. package/dest/config/index.js +1 -0
  37. package/dest/config/pipelining-config.d.ts +19 -0
  38. package/dest/config/pipelining-config.d.ts.map +1 -0
  39. package/dest/config/pipelining-config.js +18 -0
  40. package/dest/config/sequencer-config.d.ts +4 -2
  41. package/dest/config/sequencer-config.d.ts.map +1 -1
  42. package/dest/config/sequencer-config.js +6 -0
  43. package/dest/contract/contract_address.d.ts +3 -3
  44. package/dest/contract/contract_address.js +3 -3
  45. package/dest/contract/contract_class_id.d.ts +2 -2
  46. package/dest/contract/contract_class_id.js +2 -2
  47. package/dest/contract/index.d.ts +1 -3
  48. package/dest/contract/index.d.ts.map +1 -1
  49. package/dest/contract/index.js +0 -2
  50. package/dest/contract/interfaces/contract_class.d.ts +3 -156
  51. package/dest/contract/interfaces/contract_class.d.ts.map +1 -1
  52. package/dest/contract/interfaces/contract_class.js +1 -28
  53. package/dest/epoch-helpers/index.d.ts +7 -1
  54. package/dest/epoch-helpers/index.d.ts.map +1 -1
  55. package/dest/epoch-helpers/index.js +10 -2
  56. package/dest/gas/gas_fees.d.ts +1 -1
  57. package/dest/gas/gas_fees.d.ts.map +1 -1
  58. package/dest/gas/gas_fees.js +4 -1
  59. package/dest/ha-signing/config.d.ts +49 -14
  60. package/dest/ha-signing/config.d.ts.map +1 -1
  61. package/dest/ha-signing/config.js +20 -15
  62. package/dest/ha-signing/index.d.ts +3 -2
  63. package/dest/ha-signing/index.d.ts.map +1 -1
  64. package/dest/ha-signing/index.js +2 -1
  65. package/dest/ha-signing/local_config.d.ts +63 -0
  66. package/dest/ha-signing/local_config.d.ts.map +1 -0
  67. package/dest/ha-signing/local_config.js +24 -0
  68. package/dest/hash/hash.d.ts +16 -1
  69. package/dest/hash/hash.d.ts.map +1 -1
  70. package/dest/hash/hash.js +24 -0
  71. package/dest/interfaces/allowed_element.d.ts +26 -20
  72. package/dest/interfaces/allowed_element.d.ts.map +1 -1
  73. package/dest/interfaces/allowed_element.js +8 -8
  74. package/dest/interfaces/archiver.d.ts +1 -1
  75. package/dest/interfaces/archiver.d.ts.map +1 -1
  76. package/dest/interfaces/archiver.js +3 -2
  77. package/dest/interfaces/aztec-node-admin.d.ts +76 -30
  78. package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
  79. package/dest/interfaces/aztec-node.d.ts +12 -6
  80. package/dest/interfaces/aztec-node.d.ts.map +1 -1
  81. package/dest/interfaces/aztec-node.js +5 -2
  82. package/dest/interfaces/block-builder.d.ts +38 -11
  83. package/dest/interfaces/block-builder.d.ts.map +1 -1
  84. package/dest/interfaces/block-builder.js +13 -6
  85. package/dest/interfaces/configs.d.ts +62 -32
  86. package/dest/interfaces/configs.d.ts.map +1 -1
  87. package/dest/interfaces/configs.js +6 -2
  88. package/dest/interfaces/l2_logs_source.d.ts +5 -3
  89. package/dest/interfaces/l2_logs_source.d.ts.map +1 -1
  90. package/dest/interfaces/merkle_tree_operations.d.ts +9 -19
  91. package/dest/interfaces/merkle_tree_operations.d.ts.map +1 -1
  92. package/dest/interfaces/prover-client.d.ts +6 -1
  93. package/dest/interfaces/prover-client.d.ts.map +1 -1
  94. package/dest/interfaces/prover-client.js +7 -1
  95. package/dest/interfaces/proving-job.d.ts +200 -200
  96. package/dest/interfaces/validator.d.ts +103 -41
  97. package/dest/interfaces/validator.d.ts.map +1 -1
  98. package/dest/interfaces/validator.js +8 -4
  99. package/dest/interfaces/world_state.d.ts +5 -4
  100. package/dest/interfaces/world_state.d.ts.map +1 -1
  101. package/dest/kernel/private_kernel_tail_circuit_public_inputs.d.ts +2 -1
  102. package/dest/kernel/private_kernel_tail_circuit_public_inputs.d.ts.map +1 -1
  103. package/dest/kernel/private_kernel_tail_circuit_public_inputs.js +4 -0
  104. package/dest/kv-store/config.d.ts +17 -0
  105. package/dest/kv-store/config.d.ts.map +1 -0
  106. package/dest/kv-store/config.js +26 -0
  107. package/dest/kv-store/index.d.ts +2 -0
  108. package/dest/kv-store/index.d.ts.map +1 -0
  109. package/dest/kv-store/index.js +1 -0
  110. package/dest/logs/index.d.ts +2 -1
  111. package/dest/logs/index.d.ts.map +1 -1
  112. package/dest/logs/index.js +1 -0
  113. package/dest/logs/log_filter.d.ts +4 -1
  114. package/dest/logs/log_filter.d.ts.map +1 -1
  115. package/dest/logs/log_filter.js +2 -1
  116. package/dest/logs/public_log.d.ts +4 -3
  117. package/dest/logs/public_log.d.ts.map +1 -1
  118. package/dest/logs/public_log.js +2 -1
  119. package/dest/logs/tagging_index_range.d.ts +40 -0
  120. package/dest/logs/tagging_index_range.d.ts.map +1 -0
  121. package/dest/logs/tagging_index_range.js +8 -0
  122. package/dest/logs/tx_scoped_l2_log.d.ts +3 -1
  123. package/dest/logs/tx_scoped_l2_log.d.ts.map +1 -1
  124. package/dest/logs/tx_scoped_l2_log.js +7 -0
  125. package/dest/messaging/l1_to_l2_message_source.d.ts +4 -2
  126. package/dest/messaging/l1_to_l2_message_source.d.ts.map +1 -1
  127. package/dest/messaging/l2_to_l1_membership.d.ts +32 -6
  128. package/dest/messaging/l2_to_l1_membership.d.ts.map +1 -1
  129. package/dest/messaging/l2_to_l1_membership.js +69 -26
  130. package/dest/noir/index.d.ts +3 -3
  131. package/dest/noir/index.d.ts.map +1 -1
  132. package/dest/p2p/checkpoint_proposal.d.ts +1 -6
  133. package/dest/p2p/checkpoint_proposal.d.ts.map +1 -1
  134. package/dest/p2p/checkpoint_proposal.js +13 -23
  135. package/dest/p2p/peer_error.d.ts +3 -1
  136. package/dest/p2p/peer_error.d.ts.map +1 -1
  137. package/dest/p2p/peer_error.js +5 -0
  138. package/dest/slashing/tally.d.ts +7 -2
  139. package/dest/slashing/tally.d.ts.map +1 -1
  140. package/dest/slashing/tally.js +30 -2
  141. package/dest/tests/factories.d.ts +2 -4
  142. package/dest/tests/factories.d.ts.map +1 -1
  143. package/dest/tests/factories.js +0 -27
  144. package/dest/tests/mocks.d.ts +4 -2
  145. package/dest/tests/mocks.d.ts.map +1 -1
  146. package/dest/tests/mocks.js +13 -8
  147. package/dest/tx/block_header.d.ts +3 -1
  148. package/dest/tx/block_header.d.ts.map +1 -1
  149. package/dest/tx/block_header.js +4 -0
  150. package/dest/tx/private_execution_result.d.ts +6 -6
  151. package/dest/tx/private_execution_result.d.ts.map +1 -1
  152. package/dest/tx/private_execution_result.js +6 -6
  153. package/dest/tx/profiling.d.ts +14 -2
  154. package/dest/tx/profiling.d.ts.map +1 -1
  155. package/dest/tx/profiling.js +13 -3
  156. package/dest/tx/simulated_tx.d.ts +113 -2
  157. package/dest/tx/simulated_tx.d.ts.map +1 -1
  158. package/dest/tx/simulated_tx.js +4 -1
  159. package/dest/tx/tx.d.ts +6 -5
  160. package/dest/tx/tx.d.ts.map +1 -1
  161. package/dest/tx/tx.js +18 -6
  162. package/dest/tx/tx_receipt.d.ts +7 -2
  163. package/dest/tx/tx_receipt.d.ts.map +1 -1
  164. package/dest/tx/tx_receipt.js +6 -3
  165. package/dest/tx/validator/error_texts.d.ts +9 -1
  166. package/dest/tx/validator/error_texts.d.ts.map +1 -1
  167. package/dest/tx/validator/error_texts.js +10 -0
  168. package/dest/update-checker/index.d.ts +3 -2
  169. package/dest/update-checker/index.d.ts.map +1 -1
  170. package/dest/update-checker/index.js +2 -1
  171. package/dest/update-checker/package_version.d.ts +3 -0
  172. package/dest/update-checker/package_version.d.ts.map +1 -0
  173. package/dest/update-checker/package_version.js +24 -0
  174. package/dest/update-checker/version_checker.d.ts +25 -0
  175. package/dest/update-checker/version_checker.d.ts.map +1 -0
  176. package/dest/update-checker/version_checker.js +50 -0
  177. package/dest/validators/errors.d.ts +6 -1
  178. package/dest/validators/errors.d.ts.map +1 -1
  179. package/dest/validators/errors.js +7 -0
  180. package/dest/versioning/versioning.d.ts +4 -2
  181. package/dest/versioning/versioning.d.ts.map +1 -1
  182. package/dest/versioning/versioning.js +4 -1
  183. package/package.json +10 -9
  184. package/src/abi/abi.ts +25 -2
  185. package/src/abi/buffer.ts +25 -4
  186. package/src/abi/decoder.ts +14 -2
  187. package/src/abi/encoder.ts +41 -1
  188. package/src/abi/event_metadata_definition.ts +2 -0
  189. package/src/abi/utils.ts +25 -0
  190. package/src/block/l2_block.ts +13 -1
  191. package/src/block/l2_block_source.ts +16 -7
  192. package/src/checkpoint/checkpoint.ts +12 -3
  193. package/src/checkpoint/index.ts +1 -0
  194. package/src/checkpoint/validate.ts +230 -0
  195. package/src/config/index.ts +1 -0
  196. package/src/config/pipelining-config.ts +31 -0
  197. package/src/config/sequencer-config.ts +9 -1
  198. package/src/contract/contract_address.ts +3 -3
  199. package/src/contract/contract_class_id.ts +2 -2
  200. package/src/contract/index.ts +0 -2
  201. package/src/contract/interfaces/contract_class.ts +2 -82
  202. package/src/epoch-helpers/index.ts +14 -0
  203. package/src/gas/README.md +123 -0
  204. package/src/gas/gas_fees.ts +7 -1
  205. package/src/ha-signing/config.ts +45 -38
  206. package/src/ha-signing/index.ts +9 -0
  207. package/src/ha-signing/local_config.ts +46 -0
  208. package/src/hash/hash.ts +29 -0
  209. package/src/interfaces/allowed_element.ts +29 -9
  210. package/src/interfaces/archiver.ts +3 -2
  211. package/src/interfaces/aztec-node.ts +24 -5
  212. package/src/interfaces/block-builder.ts +60 -14
  213. package/src/interfaces/configs.ts +25 -8
  214. package/src/interfaces/l2_logs_source.ts +4 -1
  215. package/src/interfaces/merkle_tree_operations.ts +8 -18
  216. package/src/interfaces/prover-client.ts +8 -0
  217. package/src/interfaces/validator.ts +50 -28
  218. package/src/interfaces/world_state.ts +4 -3
  219. package/src/kernel/private_kernel_tail_circuit_public_inputs.ts +9 -0
  220. package/src/kv-store/config.ts +36 -0
  221. package/src/kv-store/index.ts +1 -0
  222. package/src/logs/index.ts +1 -0
  223. package/src/logs/log_filter.ts +5 -0
  224. package/src/logs/public_log.ts +4 -2
  225. package/src/logs/tagging_index_range.ts +24 -0
  226. package/src/logs/tx_scoped_l2_log.ts +16 -0
  227. package/src/messaging/l1_to_l2_message_source.ts +3 -1
  228. package/src/messaging/l2_to_l1_membership.ts +98 -33
  229. package/src/noir/index.ts +2 -2
  230. package/src/p2p/checkpoint_proposal.ts +23 -37
  231. package/src/p2p/peer_error.ts +7 -0
  232. package/src/slashing/tally.ts +34 -1
  233. package/src/tests/factories.ts +0 -33
  234. package/src/tests/mocks.ts +18 -7
  235. package/src/tx/block_header.ts +6 -0
  236. package/src/tx/private_execution_result.ts +5 -5
  237. package/src/tx/profiling.ts +11 -2
  238. package/src/tx/simulated_tx.ts +8 -1
  239. package/src/tx/tx.ts +20 -11
  240. package/src/tx/tx_receipt.ts +7 -2
  241. package/src/tx/validator/error_texts.ts +12 -0
  242. package/src/update-checker/index.ts +2 -1
  243. package/src/update-checker/package_version.ts +30 -0
  244. package/src/update-checker/version_checker.ts +65 -0
  245. package/src/validators/errors.ts +9 -0
  246. package/src/versioning/versioning.ts +4 -1
  247. package/dest/contract/private_function_membership_proof.d.ts +0 -32
  248. package/dest/contract/private_function_membership_proof.d.ts.map +0 -1
  249. package/dest/contract/private_function_membership_proof.js +0 -124
  250. package/dest/contract/utility_function_membership_proof.d.ts +0 -27
  251. package/dest/contract/utility_function_membership_proof.d.ts.map +0 -1
  252. package/dest/contract/utility_function_membership_proof.js +0 -87
  253. package/dest/update-checker/update-checker.d.ts +0 -49
  254. package/dest/update-checker/update-checker.d.ts.map +0 -1
  255. package/dest/update-checker/update-checker.js +0 -130
  256. package/src/contract/private_function_membership_proof.ts +0 -167
  257. package/src/contract/utility_function_membership_proof.ts +0 -118
  258. package/src/update-checker/update-checker.ts +0 -166
@@ -1,4 +1,5 @@
1
1
  import { type BlockBlobData, encodeBlockBlobData } from '@aztec/blob-lib/encoding';
2
+ import { DA_GAS_PER_FIELD } from '@aztec/constants';
2
3
  import {
3
4
  BlockNumber,
4
5
  CheckpointNumber,
@@ -175,7 +176,7 @@ export class L2Block {
175
176
  } & Partial<Parameters<typeof BlockHeader.random>[0]> = {},
176
177
  ): Promise<L2Block> {
177
178
  const archive = new AppendOnlyTreeSnapshot(Fr.random(), blockNumber + 1);
178
- const header = BlockHeader.random({ blockNumber, ...blockHeaderOverrides });
179
+ const header = BlockHeader.random({ ...blockHeaderOverrides, blockNumber });
179
180
  const body = await Body.random({ txsPerBlock, makeTxOptions, ...txOptions });
180
181
  return new L2Block(archive, header, body, checkpointNumber, indexWithinCheckpoint);
181
182
  }
@@ -221,4 +222,15 @@ export class L2Block {
221
222
  timestamp: this.header.globalVariables.timestamp,
222
223
  };
223
224
  }
225
+
226
+ /**
227
+ * Compute how much DA gas this block uses.
228
+ *
229
+ * @remarks This assumes DA gas is computed solely based on the number of blob fields in transactions.
230
+ * This may change in the future, but we cannot access the actual DA gas used in a block since it's not exposed
231
+ * in the L2BlockHeader, so we have to rely on recomputing it.
232
+ */
233
+ computeDAGasUsed(): number {
234
+ return this.body.txEffects.reduce((total, txEffect) => total + txEffect.getNumBlobFields(), 0) * DA_GAS_PER_FIELD;
235
+ }
224
236
  }
@@ -49,6 +49,12 @@ export interface L2BlockSource {
49
49
  */
50
50
  getBlockNumber(): Promise<BlockNumber>;
51
51
 
52
+ /**
53
+ * Gets the number of the latest L2 checkpoint processed by the block source implementation.
54
+ * @returns The number of the latest L2 checkpoint processed by the block source implementation.
55
+ */
56
+ getCheckpointNumber(): Promise<CheckpointNumber>;
57
+
52
58
  /**
53
59
  * Gets the number of the latest L2 block proven seen by the block source implementation.
54
60
  * @returns The number of the latest L2 block proven seen by the block source implementation.
@@ -62,9 +68,8 @@ export interface L2BlockSource {
62
68
  getCheckpointedL2BlockNumber(): Promise<BlockNumber>;
63
69
 
64
70
  /**
65
- * Computes the finalized block number based on the proven block number.
66
- * A block is considered finalized when it's 2 epochs behind the proven block.
67
- * TODO(#13569): Compute proper finalized block number based on L1 finalized block.
71
+ * Returns the finalized L2 block number. A block is finalized when it was proven
72
+ * in an L1 block that has itself been finalized on Ethereum.
68
73
  * @returns The finalized block number.
69
74
  */
70
75
  getFinalizedL2BlockNumber(): Promise<BlockNumber>;
@@ -170,14 +175,18 @@ export interface L2BlockSource {
170
175
  getSettledTxReceipt(txHash: TxHash): Promise<TxReceipt | undefined>;
171
176
 
172
177
  /**
173
- * Returns the current L2 slot number based on the currently synced L1 timestamp.
178
+ * Returns the last L2 slot number for which we have all L1 data needed to build the next checkpoint.
179
+ * Determined by the max of two signals: L1 block sync progress and latest synced checkpoint slot.
180
+ * The checkpoint signal handles missed L1 blocks, since a published checkpoint seals the message tree
181
+ * for the next checkpoint via the inbox LAG mechanism.
174
182
  */
175
- getL2SlotNumber(): Promise<SlotNumber | undefined>;
183
+ getSyncedL2SlotNumber(): Promise<SlotNumber | undefined>;
176
184
 
177
185
  /**
178
- * Returns the current L2 epoch number based on the currently synced L1 timestamp.
186
+ * Returns the last L2 epoch number that has been fully synchronized from L1.
187
+ * An epoch is fully synced when all its L2 slots have been fully synced.
179
188
  */
180
- getL2EpochNumber(): Promise<EpochNumber | undefined>;
189
+ getSyncedL2EpochNumber(): Promise<EpochNumber | undefined>;
181
190
 
182
191
  /**
183
192
  * Returns all checkpointed block headers for a given epoch.
@@ -6,7 +6,7 @@ import {
6
6
  IndexWithinCheckpoint,
7
7
  SlotNumber,
8
8
  } from '@aztec/foundation/branded-types';
9
- import { sum } from '@aztec/foundation/collection';
9
+ import { pick, sum } from '@aztec/foundation/collection';
10
10
  import { Fr } from '@aztec/foundation/curves/bn254';
11
11
  import { BufferReader, serializeSignedBigInt, serializeToBuffer } from '@aztec/foundation/serialize';
12
12
  import type { FieldsOf } from '@aztec/foundation/types';
@@ -152,10 +152,12 @@ export class Checkpoint {
152
152
  startBlockNumber?: number;
153
153
  previousArchive?: AppendOnlyTreeSnapshot;
154
154
  feeAssetPriceModifier?: bigint;
155
+ archive?: AppendOnlyTreeSnapshot;
155
156
  } & Partial<Parameters<typeof CheckpointHeader.random>[0]> &
156
157
  Partial<Parameters<typeof L2Block.random>[1]> = {},
157
158
  ) {
158
- const header = CheckpointHeader.random(options);
159
+ const headerOptions = previousArchive ? { lastArchiveRoot: previousArchive.root, ...options } : options;
160
+ const header = CheckpointHeader.random(headerOptions);
159
161
 
160
162
  // Create blocks sequentially to chain archive roots properly.
161
163
  // Each block's header.lastArchive must equal the previous block's archive.
@@ -166,11 +168,18 @@ export class Checkpoint {
166
168
  indexWithinCheckpoint: IndexWithinCheckpoint(i),
167
169
  ...options,
168
170
  ...(lastArchive ? { lastArchive } : {}),
171
+ ...pick(header, 'slotNumber', 'timestamp', 'coinbase', 'feeRecipient', 'gasFees'),
169
172
  });
170
173
  lastArchive = block.archive;
171
174
  blocks.push(block);
172
175
  }
173
176
 
174
- return new Checkpoint(AppendOnlyTreeSnapshot.random(), header, blocks, checkpointNumber, feeAssetPriceModifier);
177
+ return new Checkpoint(
178
+ options.archive ?? AppendOnlyTreeSnapshot.random(),
179
+ header,
180
+ blocks,
181
+ checkpointNumber,
182
+ feeAssetPriceModifier,
183
+ );
175
184
  }
176
185
  }
@@ -2,3 +2,4 @@ export * from './checkpoint.js';
2
2
  export * from './checkpoint_data.js';
3
3
  export * from './checkpoint_info.js';
4
4
  export * from './published_checkpoint.js';
5
+ export * from './validate.js';
@@ -0,0 +1,230 @@
1
+ import { BLOBS_PER_CHECKPOINT, FIELDS_PER_BLOB, MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT } from '@aztec/constants';
2
+ import type { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
+ import { sum } from '@aztec/foundation/collection';
4
+
5
+ import { MAX_BLOCKS_PER_CHECKPOINT } from '../deserialization/index.js';
6
+ import type { Checkpoint } from './checkpoint.js';
7
+
8
+ export class CheckpointValidationError extends Error {
9
+ constructor(
10
+ message: string,
11
+ public readonly checkpointNumber: CheckpointNumber,
12
+ public readonly slot: SlotNumber,
13
+ ) {
14
+ super(message);
15
+ this.name = 'CheckpointValidationError';
16
+ }
17
+ }
18
+
19
+ /**
20
+ * Validates a checkpoint. Throws a CheckpointValidationError if any validation fails.
21
+ * - Validates structural integrity (non-empty, block count, sequential numbers, archive chaining, slot consistency)
22
+ * - Validates checkpoint blob field count against maxBlobFields limit
23
+ * - Validates total L2 gas used by checkpoint blocks against the Rollup contract mana limit
24
+ * - Validates total DA gas used by checkpoint blocks against MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT
25
+ * - Validates individual block L2 gas and DA gas against maxL2BlockGas and maxDABlockGas limits
26
+ */
27
+ export function validateCheckpoint(
28
+ checkpoint: Checkpoint,
29
+ opts: {
30
+ rollupManaLimit?: number;
31
+ maxL2BlockGas?: number;
32
+ maxDABlockGas?: number;
33
+ maxTxsPerCheckpoint?: number;
34
+ maxTxsPerBlock?: number;
35
+ },
36
+ ): void {
37
+ validateCheckpointStructure(checkpoint);
38
+ validateCheckpointLimits(checkpoint, opts);
39
+ validateCheckpointBlocksLimits(checkpoint, opts);
40
+ }
41
+
42
+ /**
43
+ * Validates structural integrity of a checkpoint.
44
+ * - Non-empty block list
45
+ * - Block count within MAX_BLOCKS_PER_CHECKPOINT
46
+ * - Checkpoint slot matches the first block's slot
47
+ * - Checkpoint lastArchiveRoot matches the first block's lastArchive root
48
+ * - Sequential block numbers without gaps
49
+ * - Sequential indexWithinCheckpoint starting at 0
50
+ * - Archive root chaining between consecutive blocks
51
+ * - Consistent slot number across all blocks
52
+ * - Global variables (slot, timestamp, coinbase, feeRecipient, gasFees) match checkpoint header for each block
53
+ */
54
+ export function validateCheckpointStructure(checkpoint: Checkpoint): void {
55
+ const { blocks, number, slot } = checkpoint;
56
+
57
+ if (blocks.length === 0) {
58
+ throw new CheckpointValidationError('Checkpoint has no blocks', number, slot);
59
+ }
60
+
61
+ if (blocks.length > MAX_BLOCKS_PER_CHECKPOINT) {
62
+ throw new CheckpointValidationError(
63
+ `Checkpoint has ${blocks.length} blocks, exceeding limit of ${MAX_BLOCKS_PER_CHECKPOINT}`,
64
+ number,
65
+ slot,
66
+ );
67
+ }
68
+
69
+ const firstBlock = blocks[0];
70
+
71
+ if (!checkpoint.header.lastArchiveRoot.equals(firstBlock.header.lastArchive.root)) {
72
+ throw new CheckpointValidationError(
73
+ `Checkpoint lastArchiveRoot does not match first block's lastArchive root`,
74
+ number,
75
+ slot,
76
+ );
77
+ }
78
+
79
+ for (let i = 0; i < blocks.length; i++) {
80
+ const block = blocks[i];
81
+
82
+ if (block.indexWithinCheckpoint !== i) {
83
+ throw new CheckpointValidationError(
84
+ `Block at index ${i} has indexWithinCheckpoint ${block.indexWithinCheckpoint}, expected ${i}`,
85
+ number,
86
+ slot,
87
+ );
88
+ }
89
+
90
+ if (block.slot !== slot) {
91
+ throw new CheckpointValidationError(
92
+ `Block ${block.number} has slot ${block.slot}, expected ${slot} (all blocks must share the same slot)`,
93
+ number,
94
+ slot,
95
+ );
96
+ }
97
+
98
+ if (!checkpoint.header.matchesGlobalVariables(block.header.globalVariables)) {
99
+ throw new CheckpointValidationError(
100
+ `Block ${block.number} global variables (slot, timestamp, coinbase, feeRecipient, gasFees) do not match checkpoint header`,
101
+ number,
102
+ slot,
103
+ );
104
+ }
105
+
106
+ if (i > 0) {
107
+ const prev = blocks[i - 1];
108
+ if (block.number !== prev.number + 1) {
109
+ throw new CheckpointValidationError(
110
+ `Block numbers are not sequential: block at index ${i - 1} has number ${prev.number}, block at index ${i} has number ${block.number}`,
111
+ number,
112
+ slot,
113
+ );
114
+ }
115
+
116
+ if (!block.header.lastArchive.root.equals(prev.archive.root)) {
117
+ throw new CheckpointValidationError(
118
+ `Block ${block.number} lastArchive root does not match archive root of block ${prev.number}`,
119
+ number,
120
+ slot,
121
+ );
122
+ }
123
+ }
124
+ }
125
+ }
126
+
127
+ /** Validates checkpoint blocks gas limits */
128
+ function validateCheckpointBlocksLimits(
129
+ checkpoint: Checkpoint,
130
+ opts: {
131
+ maxL2BlockGas?: number;
132
+ maxDABlockGas?: number;
133
+ maxTxsPerBlock?: number;
134
+ },
135
+ ): void {
136
+ const { maxL2BlockGas, maxDABlockGas, maxTxsPerBlock } = opts;
137
+
138
+ if (maxL2BlockGas !== undefined) {
139
+ for (const block of checkpoint.blocks) {
140
+ const blockL2Gas = block.header.totalManaUsed.toNumber();
141
+ if (blockL2Gas > maxL2BlockGas) {
142
+ throw new CheckpointValidationError(
143
+ `Block ${block.number} in checkpoint has L2 gas used ${blockL2Gas} exceeding limit of ${maxL2BlockGas}`,
144
+ checkpoint.number,
145
+ checkpoint.slot,
146
+ );
147
+ }
148
+ }
149
+ }
150
+
151
+ if (maxDABlockGas !== undefined) {
152
+ for (const block of checkpoint.blocks) {
153
+ const blockDAGas = block.computeDAGasUsed();
154
+ if (blockDAGas > maxDABlockGas) {
155
+ throw new CheckpointValidationError(
156
+ `Block ${block.number} in checkpoint has DA gas used ${blockDAGas} exceeding limit of ${maxDABlockGas}`,
157
+ checkpoint.number,
158
+ checkpoint.slot,
159
+ );
160
+ }
161
+ }
162
+ }
163
+
164
+ if (maxTxsPerBlock !== undefined) {
165
+ for (const block of checkpoint.blocks) {
166
+ const blockTxCount = block.body.txEffects.length;
167
+ if (blockTxCount > maxTxsPerBlock) {
168
+ throw new CheckpointValidationError(
169
+ `Block ${block.number} in checkpoint has ${blockTxCount} txs exceeding limit of ${maxTxsPerBlock}`,
170
+ checkpoint.number,
171
+ checkpoint.slot,
172
+ );
173
+ }
174
+ }
175
+ }
176
+ }
177
+
178
+ /** Validates checkpoint max blob fields, gas limits, and tx limits */
179
+ function validateCheckpointLimits(
180
+ checkpoint: Checkpoint,
181
+ opts: {
182
+ rollupManaLimit?: number;
183
+ maxTxsPerCheckpoint?: number;
184
+ },
185
+ ): void {
186
+ const { rollupManaLimit, maxTxsPerCheckpoint } = opts;
187
+
188
+ const maxBlobFields = BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB;
189
+ const maxDAGas = MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT;
190
+
191
+ if (rollupManaLimit !== undefined) {
192
+ const checkpointMana = sum(checkpoint.blocks.map(block => block.header.totalManaUsed.toNumber()));
193
+ if (checkpointMana > rollupManaLimit) {
194
+ throw new CheckpointValidationError(
195
+ `Checkpoint mana cost ${checkpointMana} exceeds rollup limit of ${rollupManaLimit}`,
196
+ checkpoint.number,
197
+ checkpoint.slot,
198
+ );
199
+ }
200
+ }
201
+
202
+ const checkpointDAGas = sum(checkpoint.blocks.map(block => block.computeDAGasUsed()));
203
+ if (checkpointDAGas > maxDAGas) {
204
+ throw new CheckpointValidationError(
205
+ `Checkpoint DA gas cost ${checkpointDAGas} exceeds limit of ${maxDAGas}`,
206
+ checkpoint.number,
207
+ checkpoint.slot,
208
+ );
209
+ }
210
+
211
+ const checkpointBlobFields = checkpoint.toBlobFields().length;
212
+ if (checkpointBlobFields > maxBlobFields) {
213
+ throw new CheckpointValidationError(
214
+ `Checkpoint blob field count ${checkpointBlobFields} exceeds limit of ${maxBlobFields}`,
215
+ checkpoint.number,
216
+ checkpoint.slot,
217
+ );
218
+ }
219
+
220
+ if (maxTxsPerCheckpoint !== undefined) {
221
+ const checkpointTxCount = sum(checkpoint.blocks.map(block => block.body.txEffects.length));
222
+ if (checkpointTxCount > maxTxsPerCheckpoint) {
223
+ throw new CheckpointValidationError(
224
+ `Checkpoint tx count ${checkpointTxCount} exceeds limit of ${maxTxsPerCheckpoint}`,
225
+ checkpoint.number,
226
+ checkpoint.slot,
227
+ );
228
+ }
229
+ }
230
+ }
@@ -1,3 +1,4 @@
1
1
  export * from './chain-config.js';
2
2
  export * from './node-rpc-config.js';
3
+ export * from './pipelining-config.js';
3
4
  export * from './sequencer-config.js';
@@ -0,0 +1,31 @@
1
+ import { type ConfigMappingsType, booleanConfigHelper, getConfigFromMappings } from '@aztec/foundation/config';
2
+
3
+ import { z } from 'zod';
4
+
5
+ import { zodFor } from '../schemas/index.js';
6
+
7
+ export type PipelineConfig = {
8
+ /** Whether to enable build-ahead proposer pipelining. */
9
+ enableProposerPipelining: boolean;
10
+ };
11
+
12
+ /**
13
+ * Pipelining config mappings for fields that need to be shared across packages.
14
+ */
15
+ export const pipelineConfigMappings: ConfigMappingsType<PipelineConfig> = {
16
+ enableProposerPipelining: {
17
+ env: 'SEQ_ENABLE_PROPOSER_PIPELINING',
18
+ description: 'Whether to enable build-ahead proposer pipelining.',
19
+ ...booleanConfigHelper(false),
20
+ },
21
+ };
22
+
23
+ export const PipelineConfigSchema = zodFor<PipelineConfig>()(
24
+ z.object({
25
+ enableProposerPipelining: z.boolean(),
26
+ }),
27
+ );
28
+
29
+ export function getPipelineConfigEnvVars(): PipelineConfig {
30
+ return getConfigFromMappings(pipelineConfigMappings);
31
+ }
@@ -2,6 +2,9 @@ import type { ConfigMappingsType } from '@aztec/foundation/config';
2
2
 
3
3
  import type { SequencerConfig } from '../interfaces/configs.js';
4
4
 
5
+ /** Default maximum number of transactions per block. */
6
+ export const DEFAULT_MAX_TXS_PER_BLOCK = 32;
7
+
5
8
  /**
6
9
  * Partial sequencer config mappings for fields that need to be shared across packages.
7
10
  * The full sequencer config mappings remain in sequencer-client, but shared fields
@@ -9,7 +12,7 @@ import type { SequencerConfig } from '../interfaces/configs.js';
9
12
  * to avoid duplication.
10
13
  */
11
14
  export const sharedSequencerConfigMappings: ConfigMappingsType<
12
- Pick<SequencerConfig, 'blockDurationMs' | 'expectedBlockProposalsPerSlot'>
15
+ Pick<SequencerConfig, 'blockDurationMs' | 'expectedBlockProposalsPerSlot' | 'maxTxsPerBlock'>
13
16
  > = {
14
17
  blockDurationMs: {
15
18
  env: 'SEQ_BLOCK_DURATION_MS',
@@ -26,4 +29,9 @@ export const sharedSequencerConfigMappings: ConfigMappingsType<
26
29
  parseEnv: (val: string) => (val ? parseInt(val, 10) : 0),
27
30
  defaultValue: 0,
28
31
  },
32
+ maxTxsPerBlock: {
33
+ env: 'SEQ_MAX_TX_PER_BLOCK',
34
+ description: 'The maximum number of txs to include in a block.',
35
+ parseEnv: (val: string) => (val ? parseInt(val, 10) : undefined),
36
+ },
29
37
  };
@@ -13,9 +13,9 @@ import type { ContractInstance } from './interfaces/contract_instance.js';
13
13
  /**
14
14
  * Returns the deployment address for a given contract instance.
15
15
  * ```
16
- * salted_initialization_hash = pedersen([salt, initialization_hash, deployer], GENERATOR__SALTED_INITIALIZATION_HASH)
17
- * partial_address = pedersen([contract_class_id, salted_initialization_hash], GENERATOR__CONTRACT_PARTIAL_ADDRESS_V1)
18
- * address = ((poseidon2Hash([public_keys_hash, partial_address, GENERATOR__CONTRACT_ADDRESS_V1]) * G) + ivpk_m).x <- the x-coordinate of the address point
16
+ * salted_initialization_hash = poseidon2(DOM_SEP__PARTIAL_ADDRESS, [salt, initialization_hash, deployer])
17
+ * partial_address = poseidon2(DOM_SEP__PARTIAL_ADDRESS, [contract_class_id, salted_initialization_hash])
18
+ * address = ((poseidon2(DOM_SEP__CONTRACT_ADDRESS_V1, [public_keys_hash, partial_address]) * G) + ivpk_m).x <- the x-coordinate of the address point
19
19
  * ```
20
20
  * @param instance - A contract instance for which to calculate the deployment address.
21
21
  */
@@ -13,10 +13,10 @@ import { computePrivateFunctionsRoot } from './private_function.js';
13
13
  *
14
14
  * ```
15
15
  * version = 1
16
- * private_function_leaves = private_functions.map(fn => pedersen([fn.function_selector as Field, fn.vk_hash], GENERATOR__PRIVATE_FUNCTION_LEAF))
16
+ * private_function_leaves = private_functions.map(fn => poseidon2(DOM_SEP__PRIVATE_FUNCTION_LEAF, [fn.function_selector as Field, fn.vk_hash]))
17
17
  * private_functions_root = merkleize(private_function_leaves)
18
18
  * bytecode_commitment = calculate_commitment(packed_bytecode)
19
- * contract_class_id = pedersen([version, artifact_hash, private_functions_root, bytecode_commitment], GENERATOR__CLASS_IDENTIFIER)
19
+ * contract_class_id = poseidon2(DOM_SEP__CONTRACT_CLASS_ID, [version, artifact_hash, private_functions_root, bytecode_commitment])
20
20
  * ```
21
21
  * @param contractClass - Contract class.
22
22
  * @returns The identifier.
@@ -6,8 +6,6 @@ export * from './contract_deployment_data.js';
6
6
  export * from './contract_instance.js';
7
7
  export * from './contract_instance_update.js';
8
8
  export * from './private_function.js';
9
- export * from './private_function_membership_proof.js';
10
- export * from './utility_function_membership_proof.js';
11
9
  export * from './interfaces/index.js';
12
10
  export * from './contract_function_dao.js';
13
11
  export * from './partial_address.js';
@@ -42,79 +42,6 @@ const PrivateFunctionSchema = zodFor<PrivateFunction>()(
42
42
  }),
43
43
  );
44
44
 
45
- /** Private function definition with executable bytecode. */
46
- export interface ExecutablePrivateFunction extends PrivateFunction {
47
- /** ACIR and Brillig bytecode */
48
- bytecode: Buffer;
49
- }
50
-
51
- const ExecutablePrivateFunctionSchema = zodFor<ExecutablePrivateFunction>()(
52
- PrivateFunctionSchema.and(z.object({ bytecode: schemas.Buffer })),
53
- );
54
-
55
- /** Utility function definition. */
56
- export interface UtilityFunction {
57
- /** Selector of the function. Calculated as the hash of the method name and parameters. The specification of this is not enforced by the protocol. */
58
- selector: FunctionSelector;
59
- /** Brillig. */
60
- bytecode: Buffer;
61
- }
62
-
63
- const UtilityFunctionSchema = zodFor<UtilityFunction>()(
64
- z.object({
65
- selector: FunctionSelector.schema,
66
- bytecode: schemas.Buffer,
67
- }),
68
- );
69
-
70
- /** Sibling paths and sibling commitments for proving membership of a private function within a contract class. */
71
- export type PrivateFunctionMembershipProof = {
72
- artifactMetadataHash: Fr;
73
- functionMetadataHash: Fr;
74
- utilityFunctionsTreeRoot: Fr;
75
- privateFunctionTreeSiblingPath: Fr[];
76
- privateFunctionTreeLeafIndex: number;
77
- artifactTreeSiblingPath: Fr[];
78
- artifactTreeLeafIndex: number;
79
- };
80
-
81
- const PrivateFunctionMembershipProofSchema = zodFor<PrivateFunctionMembershipProof>()(
82
- z.object({
83
- artifactMetadataHash: schemas.Fr,
84
- functionMetadataHash: schemas.Fr,
85
- utilityFunctionsTreeRoot: schemas.Fr,
86
- privateFunctionTreeSiblingPath: z.array(schemas.Fr),
87
- privateFunctionTreeLeafIndex: schemas.Integer,
88
- artifactTreeSiblingPath: z.array(schemas.Fr),
89
- artifactTreeLeafIndex: schemas.Integer,
90
- }),
91
- );
92
-
93
- /** A private function with a membership proof. */
94
- export type ExecutablePrivateFunctionWithMembershipProof = ExecutablePrivateFunction & PrivateFunctionMembershipProof;
95
-
96
- /** Sibling paths and commitments for proving membership of a utility function within a contract class. */
97
- export type UtilityFunctionMembershipProof = {
98
- artifactMetadataHash: Fr;
99
- functionMetadataHash: Fr;
100
- privateFunctionsArtifactTreeRoot: Fr;
101
- artifactTreeSiblingPath: Fr[];
102
- artifactTreeLeafIndex: number;
103
- };
104
-
105
- const UtilityFunctionMembershipProofSchema = zodFor<UtilityFunctionMembershipProof>()(
106
- z.object({
107
- artifactMetadataHash: schemas.Fr,
108
- functionMetadataHash: schemas.Fr,
109
- privateFunctionsArtifactTreeRoot: schemas.Fr,
110
- artifactTreeSiblingPath: z.array(schemas.Fr),
111
- artifactTreeLeafIndex: schemas.Integer,
112
- }),
113
- );
114
-
115
- /** A utility function with a membership proof. */
116
- export type UtilityFunctionWithMembershipProof = UtilityFunction & UtilityFunctionMembershipProof;
117
-
118
45
  export const ContractClassSchema = zodFor<ContractClass>()(
119
46
  z.object({
120
47
  version: z.literal(VERSION),
@@ -143,11 +70,8 @@ export const ContractClassWithIdSchema = zodFor<ContractClassWithId>()(
143
70
  }),
144
71
  );
145
72
 
146
- /** A contract class with public bytecode information, and optional private and utility functions. */
147
- export type ContractClassPublic = {
148
- privateFunctions: ExecutablePrivateFunctionWithMembershipProof[];
149
- utilityFunctions: UtilityFunctionWithMembershipProof[];
150
- } & Pick<ContractClassCommitments, 'id' | 'privateFunctionsRoot'> &
73
+ /** A contract class with public bytecode information. */
74
+ export type ContractClassPublic = Pick<ContractClassCommitments, 'id' | 'privateFunctionsRoot'> &
151
75
  Omit<ContractClass, 'privateFunctions'>;
152
76
 
153
77
  export type ContractClassPublicWithCommitment = ContractClassPublic &
@@ -158,8 +82,6 @@ export const ContractClassPublicSchema = zodFor<ContractClassPublic>()(
158
82
  .object({
159
83
  id: schemas.Fr,
160
84
  privateFunctionsRoot: schemas.Fr,
161
- privateFunctions: z.array(ExecutablePrivateFunctionSchema.and(PrivateFunctionMembershipProofSchema)),
162
- utilityFunctions: z.array(UtilityFunctionSchema.and(UtilityFunctionMembershipProofSchema)),
163
85
  })
164
86
  .and(ContractClassSchema.omit({ privateFunctions: true })),
165
87
  );
@@ -179,8 +101,6 @@ export function contractClassPublicFromPlainObject(obj: any): ContractClassPubli
179
101
  version: 1,
180
102
  artifactHash: Fr.fromPlainObject(obj.artifactHash),
181
103
  privateFunctionsRoot: Fr.fromPlainObject(obj.privateFunctionsRoot),
182
- privateFunctions: [],
183
- utilityFunctions: [],
184
104
  packedBytecode: obj.packedBytecode instanceof Buffer ? obj.packedBytecode : Buffer.from(obj.packedBytecode),
185
105
  };
186
106
  }
@@ -12,6 +12,7 @@ export type L1RollupConstants = {
12
12
  ethereumSlotDuration: number;
13
13
  proofSubmissionEpochs: number;
14
14
  targetCommitteeSize: number;
15
+ rollupManaLimit: number;
15
16
  };
16
17
 
17
18
  export const EmptyL1RollupConstants: L1RollupConstants = {
@@ -22,6 +23,7 @@ export const EmptyL1RollupConstants: L1RollupConstants = {
22
23
  ethereumSlotDuration: 1,
23
24
  proofSubmissionEpochs: 1,
24
25
  targetCommitteeSize: 48,
26
+ rollupManaLimit: Number.MAX_SAFE_INTEGER,
25
27
  };
26
28
 
27
29
  export const L1RollupConstantsSchema = zodFor<L1RollupConstants>()(
@@ -33,6 +35,7 @@ export const L1RollupConstantsSchema = zodFor<L1RollupConstants>()(
33
35
  ethereumSlotDuration: z.number(),
34
36
  proofSubmissionEpochs: z.number(),
35
37
  targetCommitteeSize: z.number(),
38
+ rollupManaLimit: z.number(),
36
39
  }),
37
40
  );
38
41
 
@@ -54,6 +57,17 @@ export function getSlotAtTimestamp(
54
57
  : SlotNumber.fromBigInt((ts - constants.l1GenesisTime) / BigInt(constants.slotDuration));
55
58
  }
56
59
 
60
+ /** Returns the timestamp of the next L1 slot boundary after the given wall-clock time. */
61
+ export function getNextL1SlotTimestamp(
62
+ nowInSeconds: number,
63
+ constants: Pick<L1RollupConstants, 'l1GenesisTime' | 'ethereumSlotDuration'>,
64
+ ): bigint {
65
+ const now = BigInt(nowInSeconds);
66
+ const elapsed = now - constants.l1GenesisTime;
67
+ const currentL1Slot = elapsed / BigInt(constants.ethereumSlotDuration);
68
+ return constants.l1GenesisTime + (currentL1Slot + 1n) * BigInt(constants.ethereumSlotDuration);
69
+ }
70
+
57
71
  /** Returns the L2 slot number at the next L1 block based on the current timestamp. */
58
72
  export function getSlotAtNextL1Block(
59
73
  currentL1Timestamp: bigint,