@aztec/pxe 0.32.1 → 0.34.0

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 (33) hide show
  1. package/dest/database/kv_pxe_database.d.ts +1 -1
  2. package/dest/database/kv_pxe_database.d.ts.map +1 -1
  3. package/dest/database/pxe_database.d.ts +1 -1
  4. package/dest/database/pxe_database.d.ts.map +1 -1
  5. package/dest/kernel_prover/kernel_prover.d.ts +3 -42
  6. package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
  7. package/dest/kernel_prover/kernel_prover.js +9 -37
  8. package/dest/kernel_prover/proof_creator.d.ts +3 -3
  9. package/dest/kernel_prover/proof_creator.d.ts.map +1 -1
  10. package/dest/kernel_prover/proof_creator.js +7 -9
  11. package/dest/note_processor/note_processor.d.ts +8 -10
  12. package/dest/note_processor/note_processor.d.ts.map +1 -1
  13. package/dest/note_processor/note_processor.js +22 -24
  14. package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
  15. package/dest/pxe_http/pxe_http_server.js +3 -3
  16. package/dest/pxe_service/pxe_service.d.ts +3 -2
  17. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  18. package/dest/pxe_service/pxe_service.js +58 -40
  19. package/dest/pxe_service/test/pxe_test_suite.js +3 -3
  20. package/dest/simulator_oracle/index.d.ts +1 -1
  21. package/dest/simulator_oracle/index.d.ts.map +1 -1
  22. package/dest/synchronizer/synchronizer.d.ts.map +1 -1
  23. package/dest/synchronizer/synchronizer.js +16 -20
  24. package/package.json +22 -16
  25. package/src/database/kv_pxe_database.ts +1 -1
  26. package/src/database/pxe_database.ts +1 -1
  27. package/src/kernel_prover/kernel_prover.ts +22 -88
  28. package/src/kernel_prover/proof_creator.ts +10 -10
  29. package/src/note_processor/note_processor.ts +25 -30
  30. package/src/pxe_http/pxe_http_server.ts +2 -1
  31. package/src/pxe_service/pxe_service.ts +69 -46
  32. package/src/pxe_service/test/pxe_test_suite.ts +2 -2
  33. package/src/synchronizer/synchronizer.ts +18 -22
@@ -3,7 +3,7 @@ import {
3
3
  type EncryptedL2BlockL2Logs,
4
4
  type KeyStore,
5
5
  L1NotePayload,
6
- type L2BlockContext,
6
+ type L2Block,
7
7
  TaggedNote,
8
8
  } from '@aztec/circuit-types';
9
9
  import { type NoteProcessorStats } from '@aztec/circuit-types/stats';
@@ -25,9 +25,9 @@ import { produceNoteDao } from './produce_note_dao.js';
25
25
  */
26
26
  interface ProcessedData {
27
27
  /**
28
- * Holds L2 block and a cache of already requested tx hashes.
28
+ * Holds L2 block.
29
29
  */
30
- blockContext: L2BlockContext;
30
+ block: L2Block;
31
31
  /**
32
32
  * DAOs of processed notes.
33
33
  */
@@ -82,25 +82,20 @@ export class NoteProcessor {
82
82
  }
83
83
 
84
84
  /**
85
- * Process the given L2 block contexts and encrypted logs to update the note processor.
86
- * It synchronizes the user's account by decrypting the encrypted logs and processing
87
- * the transactions and auxiliary data associated with them.
88
- * Throws an error if the number of block contexts and encrypted logs do not match.
85
+ * Extracts new user-relevant notes from the information contained in the provided L2 blocks and encrypted logs.
89
86
  *
90
- * @param l2BlockContexts - An array of L2 block contexts to be processed.
91
- * @param encryptedL2BlockLogs - An array of encrypted logs associated with the L2 block contexts.
87
+ * @throws If the number of blocks and encrypted logs do not match.
88
+ * @param l2Blocks - L2 blocks to be processed.
89
+ * @param encryptedL2BlockLogs - Encrypted logs associated with the L2 blocks.
92
90
  * @returns A promise that resolves once the processing is completed.
93
91
  */
94
- public async process(
95
- l2BlockContexts: L2BlockContext[],
96
- encryptedL2BlockLogs: EncryptedL2BlockL2Logs[],
97
- ): Promise<void> {
98
- if (l2BlockContexts.length !== encryptedL2BlockLogs.length) {
92
+ public async process(l2Blocks: L2Block[], encryptedL2BlockLogs: EncryptedL2BlockL2Logs[]): Promise<void> {
93
+ if (l2Blocks.length !== encryptedL2BlockLogs.length) {
99
94
  throw new Error(
100
- `Number of blocks and EncryptedLogs is not equal. Received ${l2BlockContexts.length} blocks, ${encryptedL2BlockLogs.length} encrypted logs.`,
95
+ `Number of blocks and EncryptedLogs is not equal. Received ${l2Blocks.length} blocks, ${encryptedL2BlockLogs.length} encrypted logs.`,
101
96
  );
102
97
  }
103
- if (!l2BlockContexts.length) {
98
+ if (l2Blocks.length === 0) {
104
99
  return;
105
100
  }
106
101
 
@@ -113,9 +108,10 @@ export class NoteProcessor {
113
108
  for (let blockIndex = 0; blockIndex < encryptedL2BlockLogs.length; ++blockIndex) {
114
109
  this.stats.blocks++;
115
110
  const { txLogs } = encryptedL2BlockLogs[blockIndex];
116
- const blockContext = l2BlockContexts[blockIndex];
117
- const block = blockContext.block;
118
- const dataEndIndexForBlock = block.header.state.partial.noteHashTree.nextAvailableLeafIndex;
111
+ const block = l2Blocks[blockIndex];
112
+ const dataStartIndexForBlock =
113
+ block.header.state.partial.noteHashTree.nextAvailableLeafIndex -
114
+ block.body.numberOfTxsIncludingPadded * MAX_NEW_NOTE_HASHES_PER_TX;
119
115
 
120
116
  // We are using set for `userPertainingTxIndices` to avoid duplicates. This would happen in case there were
121
117
  // multiple encrypted logs in a tx pertaining to a user.
@@ -125,8 +121,7 @@ export class NoteProcessor {
125
121
  // Iterate over all the encrypted logs and try decrypting them. If successful, store the note.
126
122
  for (let indexOfTxInABlock = 0; indexOfTxInABlock < txLogs.length; ++indexOfTxInABlock) {
127
123
  this.stats.txs++;
128
- const dataStartIndexForTx =
129
- dataEndIndexForBlock - (txLogs.length - indexOfTxInABlock) * MAX_NEW_NOTE_HASHES_PER_TX;
124
+ const dataStartIndexForTx = dataStartIndexForBlock + indexOfTxInABlock * MAX_NEW_NOTE_HASHES_PER_TX;
130
125
  const newNoteHashes = block.body.txEffects[indexOfTxInABlock].noteHashes;
131
126
  // Note: Each tx generates a `TxL2Logs` object and for this reason we can rely on its index corresponding
132
127
  // to the index of a tx in a block.
@@ -139,7 +134,7 @@ export class NoteProcessor {
139
134
  if (taggedNote?.notePayload) {
140
135
  const { notePayload: payload } = taggedNote;
141
136
  // We have successfully decrypted the data.
142
- const txHash = blockContext.getTxHash(indexOfTxInABlock);
137
+ const txHash = block.body.txEffects[indexOfTxInABlock].txHash;
143
138
  try {
144
139
  const noteDao = await produceNoteDao(
145
140
  this.simulator,
@@ -178,7 +173,7 @@ export class NoteProcessor {
178
173
  }
179
174
 
180
175
  blocksAndNotes.push({
181
- blockContext: l2BlockContexts[blockIndex],
176
+ block: l2Blocks[blockIndex],
182
177
  noteDaos,
183
178
  });
184
179
  }
@@ -186,10 +181,10 @@ export class NoteProcessor {
186
181
  await this.processBlocksAndNotes(blocksAndNotes);
187
182
  await this.processDeferredNotes(deferredNoteDaos);
188
183
 
189
- const syncedToBlock = l2BlockContexts[l2BlockContexts.length - 1].block.number;
184
+ const syncedToBlock = l2Blocks[l2Blocks.length - 1].number;
190
185
  await this.db.setSynchedBlockNumberForPublicKey(this.publicKey, syncedToBlock);
191
186
 
192
- this.log(`Synched block ${syncedToBlock}`);
187
+ this.log.debug(`Synched block ${syncedToBlock}`);
193
188
  }
194
189
 
195
190
  /**
@@ -199,14 +194,14 @@ export class NoteProcessor {
199
194
  * transaction auxiliary data from the database. This function keeps track of new nullifiers
200
195
  * and ensures all other transactions are updated with newly settled block information.
201
196
  *
202
- * @param blocksAndNotes - Array of objects containing L2BlockContexts, user-pertaining transaction indices, and NoteDaos.
197
+ * @param blocksAndNotes - Array of objects containing L2 blocks, user-pertaining transaction indices, and NoteDaos.
203
198
  */
204
199
  private async processBlocksAndNotes(blocksAndNotes: ProcessedData[]) {
205
200
  const noteDaos = blocksAndNotes.flatMap(b => b.noteDaos);
206
201
  if (noteDaos.length) {
207
202
  await this.db.addNotes(noteDaos);
208
203
  noteDaos.forEach(noteDao => {
209
- this.log(
204
+ this.log.verbose(
210
205
  `Added note for contract ${noteDao.contractAddress} at slot ${
211
206
  noteDao.storageSlot
212
207
  } with nullifier ${noteDao.siloedNullifier.toString()}`,
@@ -215,11 +210,11 @@ export class NoteProcessor {
215
210
  }
216
211
 
217
212
  const newNullifiers: Fr[] = blocksAndNotes.flatMap(b =>
218
- b.blockContext.block.body.txEffects.flatMap(txEffect => txEffect.nullifiers),
213
+ b.block.body.txEffects.flatMap(txEffect => txEffect.nullifiers),
219
214
  );
220
215
  const removedNotes = await this.db.removeNullifiedNotes(newNullifiers, this.publicKey);
221
216
  removedNotes.forEach(noteDao => {
222
- this.log(
217
+ this.log.verbose(
223
218
  `Removed note for contract ${noteDao.contractAddress} at slot ${
224
219
  noteDao.storageSlot
225
220
  } with nullifier ${noteDao.siloedNullifier.toString()}`,
@@ -236,7 +231,7 @@ export class NoteProcessor {
236
231
  if (deferredNoteDaos.length) {
237
232
  await this.db.addDeferredNotes(deferredNoteDaos);
238
233
  deferredNoteDaos.forEach(noteDao => {
239
- this.log(
234
+ this.log.verbose(
240
235
  `Deferred note for contract ${noteDao.contractAddress} at slot ${
241
236
  noteDao.storageSlot
242
237
  } in tx ${noteDao.txHash.toString()}`,
@@ -9,6 +9,7 @@ import {
9
9
  Note,
10
10
  NullifierMembershipWitness,
11
11
  type PXE,
12
+ SimulatedTx,
12
13
  Tx,
13
14
  TxEffect,
14
15
  TxExecutionRequest,
@@ -49,7 +50,7 @@ export function createPXERpcServer(pxeService: PXE): JsonRpcServer {
49
50
  TxEffect,
50
51
  LogId,
51
52
  },
52
- { Tx, TxReceipt, EncryptedL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness },
53
+ { SimulatedTx, Tx, TxReceipt, EncryptedL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness },
53
54
  ['start', 'stop'],
54
55
  );
55
56
  }
@@ -11,6 +11,7 @@ import {
11
11
  MerkleTreeId,
12
12
  type NoteFilter,
13
13
  type PXE,
14
+ SimulatedTx,
14
15
  SimulationError,
15
16
  Tx,
16
17
  type TxEffect,
@@ -27,8 +28,7 @@ import {
27
28
  CompleteAddress,
28
29
  FunctionData,
29
30
  type GrumpkinPrivateKey,
30
- MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX,
31
- MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX,
31
+ MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX,
32
32
  type PartialAddress,
33
33
  type PrivateKernelTailCircuitPublicInputs,
34
34
  type PublicCallRequest,
@@ -71,7 +71,7 @@ export class PXEService implements PXE {
71
71
  private simulator: AcirSimulator;
72
72
  private log: DebugLogger;
73
73
  private nodeVersion: string;
74
- // serialize synchronizer and calls to simulateTx.
74
+ // serialize synchronizer and calls to proveTx.
75
75
  // ensures that state is not changed while simulating
76
76
  private jobQueue = new SerialQueue();
77
77
 
@@ -121,7 +121,7 @@ export class PXEService implements PXE {
121
121
  }
122
122
 
123
123
  if (count > 0) {
124
- this.log(`Restored ${count} accounts`);
124
+ this.log.info(`Restored ${count} accounts`);
125
125
  }
126
126
  }
127
127
 
@@ -388,26 +388,43 @@ export class PXEService implements PXE {
388
388
  return await this.node.getBlock(blockNumber);
389
389
  }
390
390
 
391
- public async simulateTx(txRequest: TxExecutionRequest, simulatePublic: boolean) {
391
+ public async proveTx(txRequest: TxExecutionRequest, simulatePublic: boolean) {
392
+ return (await this.simulateTx(txRequest, simulatePublic)).tx;
393
+ }
394
+
395
+ public async simulateTx(
396
+ txRequest: TxExecutionRequest,
397
+ simulatePublic: boolean,
398
+ msgSender: AztecAddress | undefined = undefined,
399
+ ) {
392
400
  if (!txRequest.functionData.isPrivate) {
393
401
  throw new Error(`Public entrypoints are not allowed`);
394
402
  }
395
-
396
- // all simulations must be serialized w.r.t. the synchronizer
397
403
  return await this.jobQueue.put(async () => {
398
404
  const timer = new Timer();
399
- const tx = await this.#simulateAndProve(txRequest);
400
- this.log(`Processed private part of ${tx.getTxHash()}`, {
401
- eventName: 'tx-pxe-processing',
402
- duration: timer.ms(),
403
- ...tx.getStats(),
404
- } satisfies TxPXEProcessingStats);
405
+ const simulatedTx = await this.#simulateAndProve(txRequest, msgSender);
406
+ // We log only if the msgSender is undefined, as simulating with a different msgSender
407
+ // is unlikely to be a real transaction, and likely to be only used to read data.
408
+ // Meaning that it will not necessarily have produced a nullifier (and thus have no TxHash)
409
+ // If we log, the `getTxHash` function will throw.
410
+
411
+ if (!msgSender) {
412
+ this.log.debug(`Processed private part of ${simulatedTx.tx.getTxHash()}`, {
413
+ eventName: 'tx-pxe-processing',
414
+ duration: timer.ms(),
415
+ ...simulatedTx.tx.getStats(),
416
+ } satisfies TxPXEProcessingStats);
417
+ }
418
+
405
419
  if (simulatePublic) {
406
- await this.#simulatePublicCalls(tx);
420
+ // Only one transaction, so we can take index 0.
421
+ simulatedTx.publicReturnValues = (await this.#simulatePublicCalls(simulatedTx.tx))[0];
407
422
  }
408
- this.log.info(`Executed local simulation for ${tx.getTxHash()}`);
409
423
 
410
- return tx;
424
+ if (!msgSender) {
425
+ this.log.info(`Executed local simulation for ${simulatedTx.tx.getTxHash()}`);
426
+ }
427
+ return simulatedTx;
411
428
  });
412
429
  }
413
430
 
@@ -524,15 +541,15 @@ export class PXEService implements PXE {
524
541
  };
525
542
  }
526
543
 
527
- async #simulate(txRequest: TxExecutionRequest): Promise<ExecutionResult> {
544
+ async #simulate(txRequest: TxExecutionRequest, msgSender?: AztecAddress): Promise<ExecutionResult> {
528
545
  // TODO - Pause syncing while simulating.
529
546
 
530
547
  const { contractAddress, functionArtifact, portalContract } = await this.#getSimulationParameters(txRequest);
531
548
 
532
- this.log('Executing simulator...');
549
+ this.log.debug('Executing simulator...');
533
550
  try {
534
- const result = await this.simulator.run(txRequest, functionArtifact, contractAddress, portalContract);
535
- this.log('Simulation completed!');
551
+ const result = await this.simulator.run(txRequest, functionArtifact, contractAddress, portalContract, msgSender);
552
+ this.log.verbose(`Simulation completed for ${contractAddress.toString()}:${functionArtifact.name}`);
536
553
  return result;
537
554
  } catch (err) {
538
555
  if (err instanceof SimulationError) {
@@ -553,10 +570,10 @@ export class PXEService implements PXE {
553
570
  async #simulateUnconstrained(execRequest: FunctionCall) {
554
571
  const { contractAddress, functionArtifact } = await this.#getSimulationParameters(execRequest);
555
572
 
556
- this.log('Executing unconstrained simulator...');
573
+ this.log.debug('Executing unconstrained simulator...');
557
574
  try {
558
575
  const result = await this.simulator.runUnconstrained(execRequest, functionArtifact, contractAddress);
559
- this.log('Unconstrained simulation completed!');
576
+ this.log.verbose(`Unconstrained simulation for ${contractAddress}.${functionArtifact.name} completed`);
560
577
 
561
578
  return result;
562
579
  } catch (err) {
@@ -575,7 +592,7 @@ export class PXEService implements PXE {
575
592
  */
576
593
  async #simulatePublicCalls(tx: Tx) {
577
594
  try {
578
- await this.node.simulatePublicCalls(tx);
595
+ return await this.node.simulatePublicCalls(tx);
579
596
  } catch (err) {
580
597
  // Try to fill in the noir call stack since the PXE may have access to the debug metadata
581
598
  if (err instanceof SimulationError) {
@@ -599,28 +616,26 @@ export class PXEService implements PXE {
599
616
 
600
617
  /**
601
618
  * Simulate a transaction, generate a kernel proof, and create a private transaction object.
602
- * The function takes in a transaction request and an ECDSA signature. It simulates the transaction,
603
- * then generates a kernel proof using the simulation result. Finally, it creates a private
619
+ * The function takes in a transaction request, simulates it, and then generates a kernel proof
620
+ * using the simulation result. Finally, it creates a private
604
621
  * transaction object with the generated proof and public inputs. If a new contract address is provided,
605
622
  * the function will also include the new contract's public functions in the transaction object.
606
623
  *
607
624
  * @param txExecutionRequest - The transaction request to be simulated and proved.
608
625
  * @param signature - The ECDSA signature for the transaction request.
609
- * @returns A private transaction object containing the proof, public inputs, and encrypted logs.
626
+ * @param msgSender - (Optional) The message sender to use for the simulation.
627
+ * @returns An object tract contains:
628
+ * A private transaction object containing the proof, public inputs, and encrypted logs.
629
+ * The return values of the private execution
610
630
  */
611
- async #simulateAndProve(txExecutionRequest: TxExecutionRequest) {
612
- // TODO - Pause syncing while simulating.
613
-
631
+ async #simulateAndProve(txExecutionRequest: TxExecutionRequest, msgSender?: AztecAddress) {
614
632
  // Get values that allow us to reconstruct the block hash
615
- const executionResult = await this.#simulate(txExecutionRequest);
633
+ const executionResult = await this.#simulate(txExecutionRequest, msgSender);
616
634
 
617
635
  const kernelOracle = new KernelOracle(this.contractDataOracle, this.keyStore, this.node);
618
636
  const kernelProver = new KernelProver(kernelOracle);
619
- this.log(`Executing kernel prover...`);
637
+ this.log.debug(`Executing kernel prover...`);
620
638
  const { proof, publicInputs } = await kernelProver.prove(txExecutionRequest.toTxRequest(), executionResult);
621
- this.log(
622
- `Needs setup: ${publicInputs.needsSetup}, needs app logic: ${publicInputs.needsAppLogic}, needs teardown: ${publicInputs.needsTeardown}`,
623
- );
624
639
 
625
640
  const encryptedLogs = new EncryptedTxL2Logs(collectEncryptedLogs(executionResult));
626
641
  const unencryptedLogs = new UnencryptedTxL2Logs(collectUnencryptedLogs(executionResult));
@@ -630,7 +645,8 @@ export class PXEService implements PXE {
630
645
  // TODO(#757): Enforce proper ordering of enqueued public calls
631
646
  await this.patchPublicCallStackOrdering(publicInputs, enqueuedPublicFunctions);
632
647
 
633
- return new Tx(publicInputs, proof, encryptedLogs, unencryptedLogs, enqueuedPublicFunctions);
648
+ const tx = new Tx(publicInputs, proof, encryptedLogs, unencryptedLogs, enqueuedPublicFunctions);
649
+ return new SimulatedTx(tx, [executionResult.returnValues]);
634
650
  }
635
651
 
636
652
  /**
@@ -681,55 +697,62 @@ export class PXEService implements PXE {
681
697
  publicInputs: PrivateKernelTailCircuitPublicInputs,
682
698
  enqueuedPublicCalls: PublicCallRequest[],
683
699
  ) {
700
+ if (!publicInputs.forPublic) {
701
+ return;
702
+ }
703
+
684
704
  const enqueuedPublicCallStackItems = await Promise.all(enqueuedPublicCalls.map(c => c.toCallRequest()));
685
705
 
686
706
  // Validate all items in enqueued public calls are in the kernel emitted stack
687
707
  const enqueuedRevertiblePublicCallStackItems = enqueuedPublicCallStackItems.filter(enqueued =>
688
- publicInputs.end.publicCallStack.find(item => item.equals(enqueued)),
708
+ publicInputs.forPublic!.end.publicCallStack.find(item => item.equals(enqueued)),
689
709
  );
690
710
 
691
- const revertibleStackSize = arrayNonEmptyLength(publicInputs.end.publicCallStack, item => item.isEmpty());
711
+ const revertibleStackSize = arrayNonEmptyLength(publicInputs.forPublic.end.publicCallStack, item => item.isEmpty());
692
712
 
693
713
  if (enqueuedRevertiblePublicCallStackItems.length !== revertibleStackSize) {
694
714
  throw new Error(
695
715
  `Enqueued revertible public function calls and revertible public call stack do not match.\nEnqueued calls: ${enqueuedRevertiblePublicCallStackItems
696
716
  .map(h => h.hash.toString())
697
- .join(', ')}\nPublic call stack: ${publicInputs.end.publicCallStack.map(i => i.toString()).join(', ')}`,
717
+ .join(', ')}\nPublic call stack: ${publicInputs.forPublic.end.publicCallStack
718
+ .map(i => i.toString())
719
+ .join(', ')}`,
698
720
  );
699
721
  }
700
722
 
701
723
  // Override kernel output
702
- publicInputs.end.publicCallStack = padArrayEnd(
724
+ publicInputs.forPublic.end.publicCallStack = padArrayEnd(
703
725
  enqueuedRevertiblePublicCallStackItems,
704
726
  CallRequest.empty(),
705
- MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX,
727
+ MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX,
706
728
  );
707
729
 
708
730
  // Do the same for non-revertible
709
731
 
710
732
  const enqueuedNonRevertiblePublicCallStackItems = enqueuedPublicCallStackItems.filter(enqueued =>
711
- publicInputs.endNonRevertibleData.publicCallStack.find(item => item.equals(enqueued)),
733
+ publicInputs.forPublic!.endNonRevertibleData.publicCallStack.find(item => item.equals(enqueued)),
712
734
  );
713
735
 
714
- const nonRevertibleStackSize = arrayNonEmptyLength(publicInputs.endNonRevertibleData.publicCallStack, item =>
715
- item.isEmpty(),
736
+ const nonRevertibleStackSize = arrayNonEmptyLength(
737
+ publicInputs.forPublic.endNonRevertibleData.publicCallStack,
738
+ item => item.isEmpty(),
716
739
  );
717
740
 
718
741
  if (enqueuedNonRevertiblePublicCallStackItems.length !== nonRevertibleStackSize) {
719
742
  throw new Error(
720
743
  `Enqueued non-revertible public function calls and non-revertible public call stack do not match.\nEnqueued calls: ${enqueuedNonRevertiblePublicCallStackItems
721
744
  .map(h => h.hash.toString())
722
- .join(', ')}\nPublic call stack: ${publicInputs.endNonRevertibleData.publicCallStack
745
+ .join(', ')}\nPublic call stack: ${publicInputs.forPublic.endNonRevertibleData.publicCallStack
723
746
  .map(i => i.toString())
724
747
  .join(', ')}`,
725
748
  );
726
749
  }
727
750
 
728
751
  // Override kernel output
729
- publicInputs.endNonRevertibleData.publicCallStack = padArrayEnd(
752
+ publicInputs.forPublic.endNonRevertibleData.publicCallStack = padArrayEnd(
730
753
  enqueuedNonRevertiblePublicCallStackItems,
731
754
  CallRequest.empty(),
732
- MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX,
755
+ MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX,
733
756
  );
734
757
  }
735
758
 
@@ -135,12 +135,12 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise<PXE>) =>
135
135
  authWitnesses: [],
136
136
  });
137
137
 
138
- await expect(async () => await pxe.simulateTx(txExecutionRequest, false)).rejects.toThrow(
138
+ await expect(async () => await pxe.proveTx(txExecutionRequest, false)).rejects.toThrow(
139
139
  'Public entrypoints are not allowed',
140
140
  );
141
141
  });
142
142
 
143
- // Note: Not testing a successful run of `simulateTx`, `sendTx`, `getTxReceipt` and `viewTx` here as it requires
143
+ // Note: Not testing a successful run of `proveTx`, `sendTx`, `getTxReceipt` and `viewTx` here as it requires
144
144
  // a larger setup and it's sufficiently tested in the e2e tests.
145
145
 
146
146
  it('throws when getting public storage for non-existent contract', async () => {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  type AztecNode,
3
3
  type KeyStore,
4
- L2BlockContext,
4
+ type L2Block,
5
5
  L2BlockL2Logs,
6
6
  MerkleTreeId,
7
7
  type TxHash,
@@ -51,10 +51,10 @@ export class Synchronizer {
51
51
  this.running = true;
52
52
 
53
53
  await this.jobQueue.put(() => this.initialSync());
54
- this.log('Initial sync complete');
54
+ this.log.info('Initial sync complete');
55
55
  this.runningPromise = new RunningPromise(() => this.sync(limit), retryInterval);
56
56
  this.runningPromise.start();
57
- this.log('Started loop');
57
+ this.log.debug('Started loop');
58
58
  }
59
59
 
60
60
  protected async initialSync() {
@@ -107,17 +107,16 @@ export class Synchronizer {
107
107
 
108
108
  const encryptedLogs = blocks.flatMap(block => block.body.encryptedLogs);
109
109
 
110
- // Wrap blocks in block contexts & only keep those that match our query
111
- const blockContexts = blocks.filter(block => block.number >= from).map(block => new L2BlockContext(block));
112
-
113
110
  // Update latest tree roots from the most recent block
114
- const latestBlock = blockContexts[blockContexts.length - 1];
111
+ const latestBlock = blocks[blocks.length - 1];
115
112
  await this.setHeaderFromBlock(latestBlock);
116
113
 
117
114
  const logCount = L2BlockL2Logs.getTotalLogCount(encryptedLogs);
118
- this.log(`Forwarding ${logCount} encrypted logs and blocks to ${this.noteProcessors.length} note processors`);
115
+ this.log.debug(
116
+ `Forwarding ${logCount} encrypted logs and blocks to ${this.noteProcessors.length} note processors`,
117
+ );
119
118
  for (const noteProcessor of this.noteProcessors) {
120
- await noteProcessor.process(blockContexts, encryptedLogs);
119
+ await noteProcessor.process(blocks, encryptedLogs);
121
120
  }
122
121
  return true;
123
122
  } catch (err) {
@@ -185,14 +184,12 @@ export class Synchronizer {
185
184
 
186
185
  const encryptedLogs = blocks.flatMap(block => block.body.encryptedLogs);
187
186
 
188
- const blockContexts = blocks.map(block => new L2BlockContext(block));
189
-
190
187
  const logCount = L2BlockL2Logs.getTotalLogCount(encryptedLogs);
191
- this.log(`Forwarding ${logCount} encrypted logs and blocks to note processors in catch up mode`);
188
+ this.log.debug(`Forwarding ${logCount} encrypted logs and blocks to note processors in catch up mode`);
192
189
 
193
190
  for (const noteProcessor of catchUpGroup) {
194
191
  // find the index of the first block that the note processor is not yet synced to
195
- const index = blockContexts.findIndex(block => block.block.number > noteProcessor.status.syncedToBlock);
192
+ const index = blocks.findIndex(block => block.number > noteProcessor.status.syncedToBlock);
196
193
  if (index === -1) {
197
194
  // Due to the limit, we might not have fetched a new enough block for the note processor.
198
195
  // And since the group is sorted, we break as soon as we find a note processor
@@ -202,14 +199,14 @@ export class Synchronizer {
202
199
 
203
200
  this.log.debug(
204
201
  `Catching up note processor ${noteProcessor.publicKey.toString()} by processing ${
205
- blockContexts.length - index
202
+ blocks.length - index
206
203
  } blocks`,
207
204
  );
208
- await noteProcessor.process(blockContexts.slice(index), encryptedLogs.slice(index));
205
+ await noteProcessor.process(blocks.slice(index), encryptedLogs.slice(index));
209
206
 
210
207
  if (noteProcessor.status.syncedToBlock === toBlockNumber) {
211
208
  // Note processor caught up, move it to `noteProcessors` from `noteProcessorsToCatchUp`.
212
- this.log(`Note processor for ${noteProcessor.publicKey.toString()} has caught up`, {
209
+ this.log.debug(`Note processor for ${noteProcessor.publicKey.toString()} has caught up`, {
213
210
  eventName: 'note-processor-caught-up',
214
211
  publicKey: noteProcessor.publicKey.toString(),
215
212
  duration: noteProcessor.timer.ms(),
@@ -231,13 +228,12 @@ export class Synchronizer {
231
228
  }
232
229
  }
233
230
 
234
- private async setHeaderFromBlock(latestBlock: L2BlockContext) {
235
- const { block } = latestBlock;
236
- if (block.number < this.initialSyncBlockNumber) {
231
+ private async setHeaderFromBlock(latestBlock: L2Block) {
232
+ if (latestBlock.number < this.initialSyncBlockNumber) {
237
233
  return;
238
234
  }
239
235
 
240
- await this.db.setHeader(block.header);
236
+ await this.db.setHeader(latestBlock.header);
241
237
  }
242
238
 
243
239
  /**
@@ -250,7 +246,7 @@ export class Synchronizer {
250
246
  public async stop() {
251
247
  this.running = false;
252
248
  await this.runningPromise?.stop();
253
- this.log('Stopped');
249
+ this.log.info('Stopped');
254
250
  }
255
251
 
256
252
  /**
@@ -360,7 +356,7 @@ export class Synchronizer {
360
356
  await this.db.addNotes(newNotes);
361
357
 
362
358
  newNotes.forEach(noteDao => {
363
- this.log(
359
+ this.log.debug(
364
360
  `Decoded deferred note for contract ${noteDao.contractAddress} at slot ${
365
361
  noteDao.storageSlot
366
362
  } with nullifier ${noteDao.siloedNullifier.toString()}`,