@aztec/sequencer-client 0.6.7 → 0.7.2

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 (112) hide show
  1. package/Dockerfile +21 -0
  2. package/package.json +10 -10
  3. package/src/block_builder/solo_block_builder.test.ts +8 -8
  4. package/src/block_builder/solo_block_builder.ts +114 -44
  5. package/src/block_builder/types.ts +1 -1
  6. package/src/publisher/viem-tx-sender.ts +4 -1
  7. package/src/sequencer/sequencer.ts +18 -6
  8. package/src/simulator/public_executor.ts +2 -16
  9. package/src/simulator/rollup.ts +25 -6
  10. package/.tsbuildinfo +0 -1
  11. package/dest/block_builder/index.d.ts +0 -19
  12. package/dest/block_builder/index.d.ts.map +0 -1
  13. package/dest/block_builder/index.js +0 -2
  14. package/dest/block_builder/solo_block_builder.d.ts +0 -76
  15. package/dest/block_builder/solo_block_builder.d.ts.map +0 -1
  16. package/dest/block_builder/solo_block_builder.js +0 -452
  17. package/dest/block_builder/solo_block_builder.test.d.ts +0 -3
  18. package/dest/block_builder/solo_block_builder.test.d.ts.map +0 -1
  19. package/dest/block_builder/solo_block_builder.test.js +0 -277
  20. package/dest/block_builder/types.d.ts +0 -12
  21. package/dest/block_builder/types.d.ts.map +0 -1
  22. package/dest/block_builder/types.js +0 -2
  23. package/dest/client/index.d.ts +0 -2
  24. package/dest/client/index.d.ts.map +0 -1
  25. package/dest/client/index.js +0 -2
  26. package/dest/client/sequencer-client.d.ts +0 -32
  27. package/dest/client/sequencer-client.d.ts.map +0 -1
  28. package/dest/client/sequencer-client.js +0 -47
  29. package/dest/config.d.ts +0 -12
  30. package/dest/config.d.ts.map +0 -1
  31. package/dest/config.js +0 -28
  32. package/dest/global_variable_builder/config.d.ts +0 -19
  33. package/dest/global_variable_builder/config.d.ts.map +0 -1
  34. package/dest/global_variable_builder/config.js +0 -2
  35. package/dest/global_variable_builder/global_builder.d.ts +0 -58
  36. package/dest/global_variable_builder/global_builder.d.ts.map +0 -1
  37. package/dest/global_variable_builder/global_builder.js +0 -36
  38. package/dest/global_variable_builder/index.d.ts +0 -12
  39. package/dest/global_variable_builder/index.d.ts.map +0 -1
  40. package/dest/global_variable_builder/index.js +0 -12
  41. package/dest/global_variable_builder/viem-reader.d.ts +0 -16
  42. package/dest/global_variable_builder/viem-reader.d.ts.map +0 -1
  43. package/dest/global_variable_builder/viem-reader.js +0 -37
  44. package/dest/index.d.ts +0 -12
  45. package/dest/index.d.ts.map +0 -1
  46. package/dest/index.js +0 -14
  47. package/dest/mocks/verification_keys.d.ts +0 -28
  48. package/dest/mocks/verification_keys.d.ts.map +0 -1
  49. package/dest/mocks/verification_keys.js +0 -14
  50. package/dest/prover/empty.d.ts +0 -41
  51. package/dest/prover/empty.d.ts.map +0 -1
  52. package/dest/prover/empty.js +0 -57
  53. package/dest/prover/index.d.ts +0 -40
  54. package/dest/prover/index.d.ts.map +0 -1
  55. package/dest/prover/index.js +0 -2
  56. package/dest/publisher/config.d.ts +0 -32
  57. package/dest/publisher/config.d.ts.map +0 -1
  58. package/dest/publisher/config.js +0 -2
  59. package/dest/publisher/index.d.ts +0 -10
  60. package/dest/publisher/index.d.ts.map +0 -1
  61. package/dest/publisher/index.js +0 -11
  62. package/dest/publisher/l1-publisher.d.ts +0 -105
  63. package/dest/publisher/l1-publisher.d.ts.map +0 -1
  64. package/dest/publisher/l1-publisher.js +0 -156
  65. package/dest/publisher/l1-publisher.test.d.ts +0 -2
  66. package/dest/publisher/l1-publisher.test.d.ts.map +0 -1
  67. package/dest/publisher/l1-publisher.test.js +0 -58
  68. package/dest/publisher/viem-tx-sender.d.ts +0 -42
  69. package/dest/publisher/viem-tx-sender.d.ts.map +0 -1
  70. package/dest/publisher/viem-tx-sender.js +0 -118
  71. package/dest/receiver.d.ts +0 -13
  72. package/dest/receiver.d.ts.map +0 -1
  73. package/dest/receiver.js +0 -2
  74. package/dest/sequencer/config.d.ts +0 -26
  75. package/dest/sequencer/config.d.ts.map +0 -1
  76. package/dest/sequencer/config.js +0 -2
  77. package/dest/sequencer/index.d.ts +0 -4
  78. package/dest/sequencer/index.d.ts.map +0 -1
  79. package/dest/sequencer/index.js +0 -4
  80. package/dest/sequencer/processed_tx.d.ts +0 -51
  81. package/dest/sequencer/processed_tx.d.ts.map +0 -1
  82. package/dest/sequencer/processed_tx.js +0 -40
  83. package/dest/sequencer/public_processor.d.ts +0 -75
  84. package/dest/sequencer/public_processor.d.ts.map +0 -1
  85. package/dest/sequencer/public_processor.js +0 -269
  86. package/dest/sequencer/public_processor.test.d.ts +0 -2
  87. package/dest/sequencer/public_processor.test.d.ts.map +0 -1
  88. package/dest/sequencer/public_processor.test.js +0 -164
  89. package/dest/sequencer/sequencer.d.ts +0 -133
  90. package/dest/sequencer/sequencer.d.ts.map +0 -1
  91. package/dest/sequencer/sequencer.js +0 -297
  92. package/dest/sequencer/sequencer.test.d.ts +0 -2
  93. package/dest/sequencer/sequencer.test.d.ts.map +0 -1
  94. package/dest/sequencer/sequencer.test.js +0 -99
  95. package/dest/sequencer/utils.d.ts +0 -7
  96. package/dest/sequencer/utils.d.ts.map +0 -1
  97. package/dest/sequencer/utils.js +0 -12
  98. package/dest/simulator/index.d.ts +0 -43
  99. package/dest/simulator/index.d.ts.map +0 -1
  100. package/dest/simulator/index.js +0 -2
  101. package/dest/simulator/public_executor.d.ts +0 -22
  102. package/dest/simulator/public_executor.d.ts.map +0 -1
  103. package/dest/simulator/public_executor.js +0 -99
  104. package/dest/simulator/public_kernel.d.ts +0 -20
  105. package/dest/simulator/public_kernel.d.ts.map +0 -1
  106. package/dest/simulator/public_kernel.js +0 -27
  107. package/dest/simulator/rollup.d.ts +0 -33
  108. package/dest/simulator/rollup.d.ts.map +0 -1
  109. package/dest/simulator/rollup.js +0 -41
  110. package/dest/utils.d.ts +0 -12
  111. package/dest/utils.d.ts.map +0 -1
  112. package/dest/utils.js +0 -16
package/Dockerfile ADDED
@@ -0,0 +1,21 @@
1
+ FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/yarn-project-base AS builder
2
+
3
+ # (1) project
4
+ COPY . .
5
+
6
+ # (2) build
7
+ WORKDIR /usr/src/yarn-project/sequencer-client
8
+ RUN yarn build && yarn formatting
9
+
10
+ # (3) test
11
+ RUN yarn test
12
+
13
+ # (4) Prune dev dependencies. See comment in base image.
14
+ RUN yarn cache clean
15
+ RUN yarn workspaces focus --production > /dev/null
16
+
17
+ # (5) set up entry point
18
+ FROM node:18-alpine
19
+ COPY --from=builder /usr/src/yarn-project /usr/src/yarn-project
20
+ WORKDIR /usr/src/yarn-project/sequencer-client
21
+ ENTRYPOINT ["yarn", "test"]
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@aztec/sequencer-client",
3
- "version": "0.6.7",
3
+ "version": "0.7.2",
4
4
  "exports": "./dest/index.js",
5
5
  "type": "module",
6
6
  "dependencies": {
7
- "@aztec/acir-simulator": "0.6.7",
8
- "@aztec/circuits.js": "0.6.7",
9
- "@aztec/ethereum": "0.6.7",
10
- "@aztec/foundation": "0.6.7",
11
- "@aztec/l1-artifacts": "0.6.7",
12
- "@aztec/merkle-tree": "0.6.7",
13
- "@aztec/p2p": "0.6.7",
14
- "@aztec/types": "0.6.7",
15
- "@aztec/world-state": "0.6.7",
7
+ "@aztec/acir-simulator": "0.7.2",
8
+ "@aztec/circuits.js": "0.7.2",
9
+ "@aztec/ethereum": "0.7.2",
10
+ "@aztec/foundation": "0.7.2",
11
+ "@aztec/l1-artifacts": "0.7.2",
12
+ "@aztec/merkle-tree": "0.7.2",
13
+ "@aztec/p2p": "0.7.2",
14
+ "@aztec/types": "0.7.2",
15
+ "@aztec/world-state": "0.7.2",
16
16
  "lodash.chunk": "^4.2.0",
17
17
  "lodash.flatmap": "^4.5.0",
18
18
  "lodash.pick": "^4.4.0",
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  AppendOnlyTreeSnapshot,
3
3
  BaseOrMergeRollupPublicInputs,
4
- BaseRollupInputs,
5
4
  CircuitsWasm,
6
5
  Fr,
7
6
  GlobalVariables,
@@ -11,6 +10,7 @@ import {
11
10
  MAX_NEW_NULLIFIERS_PER_TX,
12
11
  MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX,
13
12
  MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
13
+ NULLIFIER_SUBTREE_HEIGHT,
14
14
  NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
15
15
  Proof,
16
16
  PublicDataUpdateRequest,
@@ -138,7 +138,7 @@ describe('sequencer/solo_block_builder', () => {
138
138
  await expectsDb.batchInsert(
139
139
  MerkleTreeId.NULLIFIER_TREE,
140
140
  flatMap(txs, tx => tx.data.end.newNullifiers.map(x => x.toBuffer())),
141
- BaseRollupInputs.NULLIFIER_SUBTREE_HEIGHT,
141
+ NULLIFIER_SUBTREE_HEIGHT,
142
142
  );
143
143
  for (const write of txs.flatMap(tx => tx.data.end.publicDataUpdateRequests)) {
144
144
  await expectsDb.updateLeaf(MerkleTreeId.PUBLIC_DATA_TREE, write.newValue.toBuffer(), write.leafIndex.value);
@@ -157,7 +157,7 @@ describe('sequencer/solo_block_builder', () => {
157
157
  rootRollupOutput.endPrivateDataTreeSnapshot.root,
158
158
  rootRollupOutput.endNullifierTreeSnapshot.root,
159
159
  rootRollupOutput.endContractTreeSnapshot.root,
160
- rootRollupOutput.endL1ToL2MessageTreeSnapshot.root,
160
+ rootRollupOutput.endL1ToL2MessagesTreeSnapshot.root,
161
161
  rootRollupOutput.endPublicDataTreeRoot,
162
162
  );
163
163
  await expectsDb.appendLeaves(MerkleTreeId.BLOCKS_TREE, [blockHash.toBuffer()]);
@@ -208,7 +208,7 @@ describe('sequencer/solo_block_builder', () => {
208
208
  rootRollupOutput.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE);
209
209
  rootRollupOutput.endPublicDataTreeRoot = (await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE)).root;
210
210
 
211
- rootRollupOutput.endL1ToL2MessageTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGES_TREE);
211
+ rootRollupOutput.endL1ToL2MessagesTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGES_TREE);
212
212
 
213
213
  // Calculate block hash
214
214
  rootRollupOutput.globalVariables = globalVariables;
@@ -241,8 +241,8 @@ describe('sequencer/solo_block_builder', () => {
241
241
  endContractTreeSnapshot: rootRollupOutput.endContractTreeSnapshot,
242
242
  startPublicDataTreeRoot: rootRollupOutput.startPublicDataTreeRoot,
243
243
  endPublicDataTreeRoot: rootRollupOutput.endPublicDataTreeRoot,
244
- startL1ToL2MessageTreeSnapshot: rootRollupOutput.startL1ToL2MessageTreeSnapshot,
245
- endL1ToL2MessageTreeSnapshot: rootRollupOutput.endL1ToL2MessageTreeSnapshot,
244
+ startL1ToL2MessagesTreeSnapshot: rootRollupOutput.startL1ToL2MessagesTreeSnapshot,
245
+ endL1ToL2MessagesTreeSnapshot: rootRollupOutput.endL1ToL2MessagesTreeSnapshot,
246
246
  startHistoricBlocksTreeSnapshot: rootRollupOutput.startHistoricBlocksTreeSnapshot,
247
247
  endHistoricBlocksTreeSnapshot: rootRollupOutput.endHistoricBlocksTreeSnapshot,
248
248
  newCommitments,
@@ -384,7 +384,7 @@ describe('sequencer/solo_block_builder', () => {
384
384
 
385
385
  const [l2Block] = await builder.buildL2Block(globalVariables, txs, l1ToL2Messages);
386
386
  expect(l2Block.number).toEqual(blockNumber);
387
- }, 20_000);
387
+ }, 40_000);
388
388
 
389
389
  // This test specifically tests nullifier values which previously caused e2e_private_token test to fail
390
390
  it('e2e_private_token edge case regression test on nullifier values', async () => {
@@ -411,7 +411,7 @@ describe('sequencer/solo_block_builder', () => {
411
411
  await builderDb.batchInsert(
412
412
  MerkleTreeId.NULLIFIER_TREE,
413
413
  updateVals.map(v => toBufferBE(v, 32)),
414
- BaseRollupInputs.NULLIFIER_SUBTREE_HEIGHT,
414
+ NULLIFIER_SUBTREE_HEIGHT,
415
415
  );
416
416
 
417
417
  const [l2Block] = await builder.buildL2Block(globalVariables, txs, mockL1ToL2Messages);
@@ -2,16 +2,29 @@ import {
2
2
  AppendOnlyTreeSnapshot,
3
3
  BaseOrMergeRollupPublicInputs,
4
4
  BaseRollupInputs,
5
+ CONTRACT_SUBTREE_HEIGHT,
6
+ CONTRACT_SUBTREE_SIBLING_PATH_LENGTH,
5
7
  CircuitsWasm,
6
- ConstantBaseRollupData,
8
+ ConstantRollupData,
7
9
  GlobalVariables,
8
10
  HISTORIC_BLOCKS_TREE_HEIGHT,
9
11
  L1_TO_L2_MSG_SUBTREE_HEIGHT,
12
+ L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH,
13
+ MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP,
14
+ MAX_PUBLIC_DATA_READS_PER_BASE_ROLLUP,
15
+ MAX_PUBLIC_DATA_READS_PER_TX,
16
+ MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_BASE_ROLLUP,
17
+ MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
10
18
  MembershipWitness,
11
19
  MergeRollupInputs,
20
+ NULLIFIER_SUBTREE_HEIGHT,
21
+ NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH,
12
22
  NULLIFIER_TREE_HEIGHT,
13
23
  NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
14
24
  NullifierLeafPreimage,
25
+ PRIVATE_DATA_SUBTREE_HEIGHT,
26
+ PRIVATE_DATA_SUBTREE_SIBLING_PATH_LENGTH,
27
+ PUBLIC_DATA_TREE_HEIGHT,
15
28
  PreviousKernelData,
16
29
  PreviousRollupData,
17
30
  Proof,
@@ -29,7 +42,7 @@ import { toBigIntBE } from '@aztec/foundation/bigint-buffer';
29
42
  import { padArrayEnd } from '@aztec/foundation/collection';
30
43
  import { Fr } from '@aztec/foundation/fields';
31
44
  import { createDebugLogger } from '@aztec/foundation/log';
32
- import { assertLength } from '@aztec/foundation/serialize';
45
+ import { Tuple, assertLength } from '@aztec/foundation/serialize';
33
46
  import { ContractData, L2Block, L2BlockL2Logs, MerkleTreeId, PublicDataWrite, TxL2Logs } from '@aztec/types';
34
47
  import { MerkleTreeOperations, computeGlobalVariablesHash } from '@aztec/world-state';
35
48
 
@@ -109,7 +122,7 @@ export class SoloBlockBuilder implements BlockBuilder {
109
122
  endNullifierTreeSnapshot,
110
123
  endContractTreeSnapshot,
111
124
  endPublicDataTreeRoot,
112
- endL1ToL2MessageTreeSnapshot,
125
+ endL1ToL2MessagesTreeSnapshot,
113
126
  endHistoricBlocksTreeSnapshot,
114
127
  } = circuitsOutput;
115
128
 
@@ -149,8 +162,8 @@ export class SoloBlockBuilder implements BlockBuilder {
149
162
  endContractTreeSnapshot,
150
163
  startPublicDataTreeRoot: startPublicDataTreeSnapshot.root,
151
164
  endPublicDataTreeRoot,
152
- startL1ToL2MessageTreeSnapshot,
153
- endL1ToL2MessageTreeSnapshot,
165
+ startL1ToL2MessagesTreeSnapshot: startL1ToL2MessageTreeSnapshot,
166
+ endL1ToL2MessagesTreeSnapshot,
154
167
  startHistoricBlocksTreeSnapshot,
155
168
  endHistoricBlocksTreeSnapshot,
156
169
  newCommitments,
@@ -207,7 +220,7 @@ export class SoloBlockBuilder implements BlockBuilder {
207
220
  }
208
221
 
209
222
  // padArrayEnd throws if the array is already full. Otherwise it pads till we reach the required size
210
- newL1ToL2Messages = padArrayEnd(newL1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
223
+ const newL1ToL2MessagesTuple = padArrayEnd(newL1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
211
224
 
212
225
  // Run the base rollup circuits for the txs
213
226
  const baseRollupOutputs: [BaseOrMergeRollupPublicInputs, Proof][] = [];
@@ -230,7 +243,7 @@ export class SoloBlockBuilder implements BlockBuilder {
230
243
 
231
244
  // Run the root rollup with the last two merge rollups (or base, if no merge layers)
232
245
  const [mergeOutputLeft, mergeOutputRight] = mergeRollupInputs;
233
- return this.rootRollupCircuit(mergeOutputLeft, mergeOutputRight, newL1ToL2Messages);
246
+ return this.rootRollupCircuit(mergeOutputLeft, mergeOutputRight, newL1ToL2MessagesTuple);
234
247
  }
235
248
 
236
249
  protected async baseRollupCircuit(
@@ -276,7 +289,7 @@ export class SoloBlockBuilder implements BlockBuilder {
276
289
  protected async rootRollupCircuit(
277
290
  left: [BaseOrMergeRollupPublicInputs, Proof],
278
291
  right: [BaseOrMergeRollupPublicInputs, Proof],
279
- newL1ToL2Messages: Fr[],
292
+ newL1ToL2Messages: Tuple<Fr, typeof NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP>,
280
293
  ): Promise<[RootRollupPublicInputs, Proof]> {
281
294
  this.debug(`Running root rollup circuit`);
282
295
  const rootInput = await this.getRootRollupInput(...left, ...right, newL1ToL2Messages);
@@ -351,7 +364,7 @@ export class SoloBlockBuilder implements BlockBuilder {
351
364
  await Promise.all([
352
365
  this.validateTrees(rootOutput),
353
366
  this.validateTree(rootOutput, MerkleTreeId.BLOCKS_TREE, 'HistoricBlocks'),
354
- this.validateTree(rootOutput, MerkleTreeId.L1_TO_L2_MESSAGES_TREE, 'L1ToL2Message'),
367
+ this.validateTree(rootOutput, MerkleTreeId.L1_TO_L2_MESSAGES_TREE, 'L1ToL2Messages'),
355
368
  ]);
356
369
  }
357
370
 
@@ -359,7 +372,7 @@ export class SoloBlockBuilder implements BlockBuilder {
359
372
  protected async validateRootTree(
360
373
  rootOutput: RootRollupPublicInputs,
361
374
  treeId: MerkleTreeId,
362
- name: 'Contract' | 'PrivateData' | 'L1ToL2Message',
375
+ name: 'Contract' | 'PrivateData' | 'L1ToL2Messages',
363
376
  ) {
364
377
  const localTree = await this.getTreeSnapshot(treeId);
365
378
  const simulatedTree = rootOutput[`endTreeOfHistoric${name}TreeRootsSnapshot`];
@@ -400,7 +413,7 @@ export class SoloBlockBuilder implements BlockBuilder {
400
413
  protected validateSimulatedTree(
401
414
  localTree: AppendOnlyTreeSnapshot,
402
415
  simulatedTree: AppendOnlyTreeSnapshot,
403
- name: 'PrivateData' | 'Contract' | 'Nullifier' | 'L1ToL2Message' | 'HistoricBlocks',
416
+ name: 'PrivateData' | 'Contract' | 'Nullifier' | 'L1ToL2Messages' | 'HistoricBlocks',
404
417
  label?: string,
405
418
  ) {
406
419
  if (!simulatedTree.root.toBuffer().equals(localTree.root.toBuffer())) {
@@ -421,7 +434,7 @@ export class SoloBlockBuilder implements BlockBuilder {
421
434
  rollupProofLeft: Proof,
422
435
  rollupOutputRight: BaseOrMergeRollupPublicInputs,
423
436
  rollupProofRight: Proof,
424
- newL1ToL2Messages: Fr[],
437
+ newL1ToL2Messages: Tuple<Fr, typeof NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP>,
425
438
  ) {
426
439
  const vk = this.getVerificationKey(rollupOutputLeft.rollupType);
427
440
  const previousRollupData: RootRollupInputs['previousRollupData'] = [
@@ -437,23 +450,36 @@ export class SoloBlockBuilder implements BlockBuilder {
437
450
  return path.toFieldArray();
438
451
  };
439
452
 
440
- const newL1ToL2MessageTreeRootSiblingPath = await this.getSubtreeSiblingPath(
453
+ const newL1ToL2MessagesTreeRootSiblingPathArray = await this.getSubtreeSiblingPath(
441
454
  MerkleTreeId.L1_TO_L2_MESSAGES_TREE,
442
455
  L1_TO_L2_MSG_SUBTREE_HEIGHT,
443
456
  );
444
457
 
458
+ const newL1ToL2MessagesTreeRootSiblingPath = makeTuple(
459
+ L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH,
460
+ i =>
461
+ i < newL1ToL2MessagesTreeRootSiblingPathArray.length ? newL1ToL2MessagesTreeRootSiblingPathArray[i] : Fr.ZERO,
462
+ 0,
463
+ );
464
+
445
465
  // Get tree snapshots
446
- const startL1ToL2MessageTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGES_TREE);
466
+ const startL1ToL2MessagesTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGES_TREE);
447
467
 
448
468
  // Get historic block tree roots
449
469
  const startHistoricBlocksTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.BLOCKS_TREE);
450
- const newHistoricBlocksTreeSiblingPath = await getRootTreeSiblingPath(MerkleTreeId.BLOCKS_TREE);
470
+ const newHistoricBlocksTreeSiblingPathArray = await getRootTreeSiblingPath(MerkleTreeId.BLOCKS_TREE);
471
+
472
+ const newHistoricBlocksTreeSiblingPath = makeTuple(
473
+ HISTORIC_BLOCKS_TREE_HEIGHT,
474
+ i => (i < newHistoricBlocksTreeSiblingPathArray.length ? newHistoricBlocksTreeSiblingPathArray[i] : Fr.ZERO),
475
+ 0,
476
+ );
451
477
 
452
478
  return RootRollupInputs.from({
453
479
  previousRollupData,
454
480
  newL1ToL2Messages,
455
- newL1ToL2MessageTreeRootSiblingPath,
456
- startL1ToL2MessageTreeSnapshot,
481
+ newL1ToL2MessagesTreeRootSiblingPath,
482
+ startL1ToL2MessagesTreeSnapshot,
457
483
  startHistoricBlocksTreeSnapshot,
458
484
  newHistoricBlocksTreeSiblingPath,
459
485
  });
@@ -528,8 +554,8 @@ export class SoloBlockBuilder implements BlockBuilder {
528
554
  return this.getMembershipWitnessFor(blockHash, MerkleTreeId.BLOCKS_TREE, HISTORIC_BLOCKS_TREE_HEIGHT);
529
555
  }
530
556
 
531
- protected async getConstantBaseRollupData(globalVariables: GlobalVariables): Promise<ConstantBaseRollupData> {
532
- return ConstantBaseRollupData.from({
557
+ protected async getConstantRollupData(globalVariables: GlobalVariables): Promise<ConstantRollupData> {
558
+ return ConstantRollupData.from({
533
559
  baseRollupVkHash: DELETE_FR,
534
560
  mergeRollupVkHash: DELETE_FR,
535
561
  privateKernelVkTreeRoot: FUTURE_FR,
@@ -579,22 +605,38 @@ export class SoloBlockBuilder implements BlockBuilder {
579
605
  }
580
606
 
581
607
  protected async processPublicDataUpdateRequests(tx: ProcessedTx) {
582
- const newPublicDataUpdateRequestsSiblingPaths: Fr[][] = [];
583
- for (const publicDataUpdateRequest of tx.data.end.publicDataUpdateRequests) {
584
- const index = publicDataUpdateRequest.leafIndex.value;
608
+ const newPublicDataUpdateRequestsSiblingPaths: Tuple<
609
+ Tuple<Fr, typeof PUBLIC_DATA_TREE_HEIGHT>,
610
+ typeof MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX
611
+ > = makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, () => makeTuple(PUBLIC_DATA_TREE_HEIGHT, Fr.zero));
612
+ for (const i in tx.data.end.publicDataUpdateRequests) {
613
+ const index = tx.data.end.publicDataUpdateRequests[i].leafIndex.value;
614
+ await this.db.updateLeaf(
615
+ MerkleTreeId.PUBLIC_DATA_TREE,
616
+ tx.data.end.publicDataUpdateRequests[i].newValue.toBuffer(),
617
+ index,
618
+ );
585
619
  const path = await this.db.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, index);
586
- await this.db.updateLeaf(MerkleTreeId.PUBLIC_DATA_TREE, publicDataUpdateRequest.newValue.toBuffer(), index);
587
- newPublicDataUpdateRequestsSiblingPaths.push(path.toFieldArray());
620
+ const array = path.toFieldArray();
621
+ newPublicDataUpdateRequestsSiblingPaths[i] = makeTuple(PUBLIC_DATA_TREE_HEIGHT, j =>
622
+ j < array.length ? array[j] : Fr.ZERO,
623
+ );
588
624
  }
589
625
  return newPublicDataUpdateRequestsSiblingPaths;
590
626
  }
591
627
 
592
628
  protected async getPublicDataReadsSiblingPaths(tx: ProcessedTx) {
593
- const newPublicDataReadsSiblingPaths: Fr[][] = [];
594
- for (const publicDataRead of tx.data.end.publicDataReads) {
595
- const index = publicDataRead.leafIndex.value;
629
+ const newPublicDataReadsSiblingPaths: Tuple<
630
+ Tuple<Fr, typeof PUBLIC_DATA_TREE_HEIGHT>,
631
+ typeof MAX_PUBLIC_DATA_READS_PER_TX
632
+ > = makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => makeTuple(PUBLIC_DATA_TREE_HEIGHT, Fr.zero));
633
+ for (const i in tx.data.end.publicDataReads) {
634
+ const index = tx.data.end.publicDataReads[i].leafIndex.value;
596
635
  const path = await this.db.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, index);
597
- newPublicDataReadsSiblingPaths.push(path.toFieldArray());
636
+ const array = path.toFieldArray();
637
+ newPublicDataReadsSiblingPaths[i] = makeTuple(PUBLIC_DATA_TREE_HEIGHT, j =>
638
+ j < array.length ? array[j] : Fr.ZERO,
639
+ );
598
640
  }
599
641
  return newPublicDataReadsSiblingPaths;
600
642
  }
@@ -604,7 +646,7 @@ export class SoloBlockBuilder implements BlockBuilder {
604
646
  const wasm = await CircuitsWasm.get();
605
647
 
606
648
  // Get trees info before any changes hit
607
- const constants = await this.getConstantBaseRollupData(globalVariables);
649
+ const constants = await this.getConstantRollupData(globalVariables);
608
650
  const startNullifierTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE);
609
651
  const startContractTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.CONTRACT_TREE);
610
652
  const startPrivateDataTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE);
@@ -612,13 +654,22 @@ export class SoloBlockBuilder implements BlockBuilder {
612
654
  const startHistoricBlocksTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.BLOCKS_TREE);
613
655
 
614
656
  // Get the subtree sibling paths for the circuit
615
- const newCommitmentsSubtreeSiblingPath = await this.getSubtreeSiblingPath(
657
+ const newCommitmentsSubtreeSiblingPathArray = await this.getSubtreeSiblingPath(
616
658
  MerkleTreeId.PRIVATE_DATA_TREE,
617
- BaseRollupInputs.PRIVATE_DATA_SUBTREE_HEIGHT,
659
+ PRIVATE_DATA_SUBTREE_HEIGHT,
618
660
  );
619
- const newContractsSubtreeSiblingPath = await this.getSubtreeSiblingPath(
661
+
662
+ const newCommitmentsSubtreeSiblingPath = makeTuple(PRIVATE_DATA_SUBTREE_SIBLING_PATH_LENGTH, i =>
663
+ i < newCommitmentsSubtreeSiblingPathArray.length ? newCommitmentsSubtreeSiblingPathArray[i] : Fr.ZERO,
664
+ );
665
+
666
+ const newContractsSubtreeSiblingPathArray = await this.getSubtreeSiblingPath(
620
667
  MerkleTreeId.CONTRACT_TREE,
621
- BaseRollupInputs.CONTRACT_SUBTREE_HEIGHT,
668
+ CONTRACT_SUBTREE_HEIGHT,
669
+ );
670
+
671
+ const newContractsSubtreeSiblingPath = makeTuple(CONTRACT_SUBTREE_SIBLING_PATH_LENGTH, i =>
672
+ i < newContractsSubtreeSiblingPathArray.length ? newContractsSubtreeSiblingPathArray[i] : Fr.ZERO,
622
673
  );
623
674
 
624
675
  // Update the contract and private data trees with the new items being inserted to get the new roots
@@ -644,11 +695,17 @@ export class SoloBlockBuilder implements BlockBuilder {
644
695
  const rightPublicDataReadSiblingPaths = await this.getPublicDataReadsSiblingPaths(right);
645
696
  const rightPublicDataUpdateRequestsSiblingPaths = await this.processPublicDataUpdateRequests(right);
646
697
 
647
- const newPublicDataReadsSiblingPaths = [...leftPublicDataReadSiblingPaths, ...rightPublicDataReadSiblingPaths];
648
- const newPublicDataUpdateRequestsSiblingPaths = [
649
- ...leftPublicDataUpdateRequestsSiblingPaths,
650
- ...rightPublicDataUpdateRequestsSiblingPaths,
651
- ];
698
+ const newPublicDataReadsSiblingPaths = makeTuple(MAX_PUBLIC_DATA_READS_PER_BASE_ROLLUP, i =>
699
+ i < MAX_PUBLIC_DATA_READS_PER_TX
700
+ ? leftPublicDataReadSiblingPaths[i]
701
+ : rightPublicDataReadSiblingPaths[i - MAX_PUBLIC_DATA_READS_PER_TX],
702
+ );
703
+
704
+ const newPublicDataUpdateRequestsSiblingPaths = makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_BASE_ROLLUP, i =>
705
+ i < MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX
706
+ ? leftPublicDataUpdateRequestsSiblingPaths[i]
707
+ : rightPublicDataUpdateRequestsSiblingPaths[i - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX],
708
+ );
652
709
 
653
710
  // Update the nullifier tree, capturing the low nullifier info for each individual operation
654
711
  const newNullifiers = [...left.data.end.newNullifiers, ...right.data.end.newNullifiers];
@@ -656,7 +713,7 @@ export class SoloBlockBuilder implements BlockBuilder {
656
713
  const [nullifierWitnessLeaves, newNullifiersSubtreeSiblingPath] = await this.db.batchInsert(
657
714
  MerkleTreeId.NULLIFIER_TREE,
658
715
  newNullifiers.map(fr => fr.toBuffer()),
659
- BaseRollupInputs.NULLIFIER_SUBTREE_HEIGHT,
716
+ NULLIFIER_SUBTREE_HEIGHT,
660
717
  );
661
718
  if (nullifierWitnessLeaves === undefined) {
662
719
  throw new Error(`Could not craft nullifier batch insertion proofs`);
@@ -668,6 +725,8 @@ export class SoloBlockBuilder implements BlockBuilder {
668
725
  MembershipWitness.fromBufferArray(l.index, assertLength(l.siblingPath.toBufferArray(), NULLIFIER_TREE_HEIGHT)),
669
726
  );
670
727
 
728
+ const newNullifiersSubtreeSiblingPathArray = newNullifiersSubtreeSiblingPath.toFieldArray();
729
+
671
730
  return BaseRollupInputs.from({
672
731
  constants,
673
732
  startNullifierTreeSnapshot,
@@ -677,14 +736,25 @@ export class SoloBlockBuilder implements BlockBuilder {
677
736
  startHistoricBlocksTreeSnapshot,
678
737
  newCommitmentsSubtreeSiblingPath,
679
738
  newContractsSubtreeSiblingPath,
680
- newNullifiersSubtreeSiblingPath: newNullifiersSubtreeSiblingPath.toFieldArray(),
739
+ newNullifiersSubtreeSiblingPath: makeTuple(NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, i =>
740
+ i < newNullifiersSubtreeSiblingPathArray.length ? newNullifiersSubtreeSiblingPathArray[i] : Fr.ZERO,
741
+ ),
681
742
  newPublicDataUpdateRequestsSiblingPaths,
682
743
  newPublicDataReadsSiblingPaths,
683
- lowNullifierLeafPreimages: nullifierWitnessLeaves.map(
684
- ({ leafData }) =>
685
- new NullifierLeafPreimage(new Fr(leafData.value), new Fr(leafData.nextValue), Number(leafData.nextIndex)),
744
+ lowNullifierLeafPreimages: makeTuple(MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, i =>
745
+ i < nullifierWitnessLeaves.length
746
+ ? new NullifierLeafPreimage(
747
+ new Fr(nullifierWitnessLeaves[i].leafData.value),
748
+ new Fr(nullifierWitnessLeaves[i].leafData.nextValue),
749
+ Number(nullifierWitnessLeaves[i].leafData.nextIndex),
750
+ )
751
+ : new NullifierLeafPreimage(Fr.ZERO, Fr.ZERO, 0),
752
+ ),
753
+ lowNullifierMembershipWitness: makeTuple(MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, i =>
754
+ i < lowNullifierMembershipWitnesses.length
755
+ ? lowNullifierMembershipWitnesses[i]
756
+ : this.makeEmptyMembershipWitness(NULLIFIER_TREE_HEIGHT),
686
757
  ),
687
- lowNullifierMembershipWitness: lowNullifierMembershipWitnesses,
688
758
  kernelData: [this.getKernelDataFor(left), this.getKernelDataFor(right)],
689
759
  historicBlocksTreeRootMembershipWitnesses: [
690
760
  await this.getHistoricTreesMembershipWitnessFor(left),
@@ -5,7 +5,7 @@ import { AppendOnlyTreeSnapshot, BaseOrMergeRollupPublicInputs, RootRollupPublic
5
5
  */
6
6
  export type AllowedTreeNames<T extends BaseOrMergeRollupPublicInputs | RootRollupPublicInputs> =
7
7
  T extends RootRollupPublicInputs
8
- ? 'PrivateData' | 'Contract' | 'Nullifier' | 'L1ToL2Message' | 'HistoricBlocks'
8
+ ? 'PrivateData' | 'Contract' | 'Nullifier' | 'L1ToL2Messages' | 'HistoricBlocks'
9
9
  : 'PrivateData' | 'Contract' | 'Nullifier';
10
10
 
11
11
  /**
@@ -1,7 +1,7 @@
1
1
  import { createEthereumChain } from '@aztec/ethereum';
2
2
  import { createDebugLogger } from '@aztec/foundation/log';
3
3
  import { ContractDeploymentEmitterAbi, RollupAbi } from '@aztec/l1-artifacts';
4
- import { ExtendedContractData } from '@aztec/types';
4
+ import { BLOB_SIZE_IN_BYTES, ExtendedContractData } from '@aztec/types';
5
5
 
6
6
  import {
7
7
  GetContractReturnType,
@@ -141,6 +141,9 @@ export class ViemTxSender implements L1PublisherTxSender {
141
141
  `0x${extendedContractData.bytecode.toString('hex')}`,
142
142
  ] as const;
143
143
 
144
+ const codeSize = extendedContractData.bytecode.length;
145
+ this.log(`Bytecode is ${codeSize} bytes and require ${codeSize / BLOB_SIZE_IN_BYTES} blobs`);
146
+
144
147
  const gas = await this.contractDeploymentEmitterContract.estimateGas.emitContractDeployment(args, {
145
148
  account: this.account,
146
149
  });
@@ -129,10 +129,11 @@ export class Sequencer {
129
129
  return;
130
130
  }
131
131
 
132
- this.log(`Processing ${validTxs.length} txs...`);
132
+ const blockNumber = (await this.l2BlockSource.getBlockNumber()) + 1;
133
+
134
+ this.log.info(`Building block ${blockNumber} with ${validTxs.length} transactions...`);
133
135
  this.state = SequencerState.CREATING_BLOCK;
134
136
 
135
- const blockNumber = (await this.l2BlockSource.getBlockNumber()) + 1;
136
137
  const newGlobalVariables = await this.globalsBuilder.buildGlobalVariables(new Fr(blockNumber));
137
138
  const prevGlobalVariables = (await this.l2BlockSource.getL2Block(-1))?.globalVariables ?? GlobalVariables.empty();
138
139
 
@@ -146,7 +147,11 @@ export class Sequencer {
146
147
  await this.p2pClient.deleteTxs(await Tx.getHashes(failedTxData));
147
148
  }
148
149
 
149
- if (processedTxs.length === 0) {
150
+ // Only accept processed transactions that are not double-spends
151
+ // public functions emitting nullifiers would pass earlier check but fail here
152
+ const processedValidTxs = await this.takeValidProcessedTxs(processedTxs);
153
+
154
+ if (processedValidTxs.length === 0) {
150
155
  this.log('No txs processed correctly to build block. Exiting');
151
156
  return;
152
157
  }
@@ -157,16 +162,16 @@ export class Sequencer {
157
162
  this.log('Successfully retrieved L1 to L2 messages from contract');
158
163
 
159
164
  // Build the new block by running the rollup circuits
160
- this.log(`Assembling block with txs ${processedTxs.map(tx => tx.hash).join(', ')}`);
165
+ this.log(`Assembling block with txs ${processedValidTxs.map(tx => tx.hash).join(', ')}`);
161
166
 
162
167
  const emptyTx = await processor.makeEmptyProcessedTx();
163
- const block = await this.buildBlock(processedTxs, l1ToL2Messages, emptyTx, newGlobalVariables);
168
+ const block = await this.buildBlock(processedValidTxs, l1ToL2Messages, emptyTx, newGlobalVariables);
164
169
  this.log(`Assembled block ${block.number}`);
165
170
 
166
171
  await this.publishExtendedContractData(validTxs, block);
167
172
 
168
173
  await this.publishL2Block(block);
169
- this.log.info(`Submitted rollup block ${block.number} with ${processedTxs.length} transactions`);
174
+ this.log.info(`Submitted rollup block ${block.number} with ${processedValidTxs.length} transactions`);
170
175
  } catch (err) {
171
176
  this.log.error(err);
172
177
  this.log.error(`Rolling back world state DB`);
@@ -248,6 +253,13 @@ export class Sequencer {
248
253
  return validTxs;
249
254
  }
250
255
 
256
+ protected async takeValidProcessedTxs(txs: ProcessedTx[]) {
257
+ const isDoubleSpends = await Promise.all(txs.map(async tx => await this.isTxDoubleSpend(tx as unknown as Tx)));
258
+ const doubleSpends = txs.filter((tx, index) => isDoubleSpends[index]).map(tx => tx.hash);
259
+ await this.p2pClient.deleteTxs(doubleSpends);
260
+ return txs.filter((tx, index) => !isDoubleSpends[index]);
261
+ }
262
+
251
263
  /**
252
264
  * Returns whether the previous block sent has been mined, and all dependencies have caught up with it.
253
265
  * @returns Boolean indicating if our dependencies are synced to the latest block.
@@ -1,5 +1,4 @@
1
1
  import {
2
- CommitmentDataOracleInputs,
3
2
  CommitmentsDB,
4
3
  MessageLoadOracleInputs,
5
4
  PublicContractsDB,
@@ -7,7 +6,6 @@ import {
7
6
  PublicStateDB,
8
7
  } from '@aztec/acir-simulator';
9
8
  import { AztecAddress, CircuitsWasm, EthAddress, Fr, FunctionSelector, HistoricBlockData } from '@aztec/circuits.js';
10
- import { siloCommitment } from '@aztec/circuits.js/abis';
11
9
  import { ContractDataSource, L1ToL2MessageSource, MerkleTreeId } from '@aztec/types';
12
10
  import { MerkleTreeOperations, computePublicDataTreeLeafIndex } from '@aztec/world-state';
13
11
 
@@ -100,19 +98,7 @@ export class WorldStateDB implements CommitmentsDB {
100
98
  };
101
99
  }
102
100
 
103
- public async getCommitmentOracle(address: AztecAddress, innerCommitment: Fr): Promise<CommitmentDataOracleInputs> {
104
- const siloedCommitment = siloCommitment(await CircuitsWasm.get(), address, innerCommitment);
105
- // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): shoild be
106
- // unique commitment that exists in tree (should be siloed and then made unique via
107
- // nonce). Once public kernel or base rollup circuit injects nonces, this can be updated
108
- // to use uniqueSiloedCommitment.
109
- const index = (await this.db.findLeafIndex(MerkleTreeId.PRIVATE_DATA_TREE, siloedCommitment.toBuffer()))!;
110
- const siblingPath = await this.db.getSiblingPath(MerkleTreeId.PRIVATE_DATA_TREE, index);
111
-
112
- return {
113
- commitment: siloedCommitment,
114
- siblingPath: siblingPath.toFieldArray(),
115
- index,
116
- };
101
+ public async getCommitmentIndex(commitment: Fr): Promise<bigint | undefined> {
102
+ return await this.db.findLeafIndex(MerkleTreeId.PRIVATE_DATA_TREE, commitment.toBuffer());
117
103
  }
118
104
  }
@@ -1,11 +1,14 @@
1
1
  import {
2
2
  BaseOrMergeRollupPublicInputs,
3
3
  BaseRollupInputs,
4
+ CircuitError,
4
5
  CircuitsWasm,
5
6
  MergeRollupInputs,
6
- RollupWasmWrapper,
7
7
  RootRollupInputs,
8
8
  RootRollupPublicInputs,
9
+ baseRollupSim,
10
+ mergeRollupSim,
11
+ rootRollupSim,
9
12
  } from '@aztec/circuits.js';
10
13
 
11
14
  import { RollupSimulator } from './index.js';
@@ -14,10 +17,10 @@ import { RollupSimulator } from './index.js';
14
17
  * Implements the rollup circuit simulator using the wasm circuits implementation.
15
18
  */
16
19
  export class WasmRollupCircuitSimulator implements RollupSimulator {
17
- private rollupWasmWrapper: RollupWasmWrapper;
20
+ private wasm: CircuitsWasm;
18
21
 
19
22
  constructor(wasm: CircuitsWasm) {
20
- this.rollupWasmWrapper = new RollupWasmWrapper(wasm);
23
+ this.wasm = wasm;
21
24
  }
22
25
 
23
26
  /**
@@ -34,7 +37,12 @@ export class WasmRollupCircuitSimulator implements RollupSimulator {
34
37
  * @returns The public inputs as outputs of the simulation.
35
38
  */
36
39
  baseRollupCircuit(input: BaseRollupInputs): Promise<BaseOrMergeRollupPublicInputs> {
37
- return Promise.resolve(this.rollupWasmWrapper.simulateBaseRollup(input));
40
+ const result = baseRollupSim(this.wasm, input);
41
+ if (result instanceof CircuitError) {
42
+ throw new CircuitError(result.code, result.message);
43
+ }
44
+
45
+ return Promise.resolve(result);
38
46
  }
39
47
  /**
40
48
  * Simulates the merge rollup circuit from its inputs.
@@ -42,14 +50,25 @@ export class WasmRollupCircuitSimulator implements RollupSimulator {
42
50
  * @returns The public inputs as outputs of the simulation.
43
51
  */
44
52
  mergeRollupCircuit(input: MergeRollupInputs): Promise<BaseOrMergeRollupPublicInputs> {
45
- return Promise.resolve(this.rollupWasmWrapper.simulateMergeRollup(input));
53
+ const result = mergeRollupSim(this.wasm, input);
54
+ if (result instanceof CircuitError) {
55
+ throw new CircuitError(result.code, result.message);
56
+ }
57
+
58
+ return Promise.resolve(result);
46
59
  }
60
+
47
61
  /**
48
62
  * Simulates the root rollup circuit from its inputs.
49
63
  * @param input - Inputs to the circuit.
50
64
  * @returns The public inputs as outputs of the simulation.
51
65
  */
52
66
  rootRollupCircuit(input: RootRollupInputs): Promise<RootRollupPublicInputs> {
53
- return Promise.resolve(this.rollupWasmWrapper.simulateRootRollup(input));
67
+ const result = rootRollupSim(this.wasm, input);
68
+ if (result instanceof CircuitError) {
69
+ throw new CircuitError(result.code, result.message);
70
+ }
71
+
72
+ return Promise.resolve(result);
54
73
  }
55
74
  }