@aztec/pxe 0.32.0 → 0.33.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 (84) hide show
  1. package/dest/contract_data_oracle/index.d.ts +6 -6
  2. package/dest/contract_data_oracle/index.d.ts.map +1 -1
  3. package/dest/contract_data_oracle/index.js +1 -1
  4. package/dest/contract_data_oracle/private_functions_tree.d.ts +3 -3
  5. package/dest/contract_data_oracle/private_functions_tree.d.ts.map +1 -1
  6. package/dest/database/contracts/contract_artifact_db.d.ts +2 -2
  7. package/dest/database/contracts/contract_artifact_db.d.ts.map +1 -1
  8. package/dest/database/contracts/contract_instance_db.d.ts +2 -2
  9. package/dest/database/contracts/contract_instance_db.d.ts.map +1 -1
  10. package/dest/database/deferred_note_dao.d.ts +1 -1
  11. package/dest/database/deferred_note_dao.d.ts.map +1 -1
  12. package/dest/database/deferred_note_dao.js +1 -1
  13. package/dest/database/kv_pxe_database.d.ts +7 -7
  14. package/dest/database/kv_pxe_database.d.ts.map +1 -1
  15. package/dest/database/kv_pxe_database.js +1 -1
  16. package/dest/database/note_dao.d.ts +2 -2
  17. package/dest/database/note_dao.d.ts.map +1 -1
  18. package/dest/database/note_dao.js +1 -1
  19. package/dest/database/pxe_database.d.ts +11 -11
  20. package/dest/database/pxe_database.d.ts.map +1 -1
  21. package/dest/database/pxe_database_test_suite.d.ts +1 -1
  22. package/dest/database/pxe_database_test_suite.d.ts.map +1 -1
  23. package/dest/database/pxe_database_test_suite.js +1 -1
  24. package/dest/kernel_oracle/index.d.ts +4 -4
  25. package/dest/kernel_oracle/index.d.ts.map +1 -1
  26. package/dest/kernel_prover/hints_builder.d.ts +3 -3
  27. package/dest/kernel_prover/hints_builder.d.ts.map +1 -1
  28. package/dest/kernel_prover/kernel_prover.d.ts +5 -44
  29. package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
  30. package/dest/kernel_prover/kernel_prover.js +9 -37
  31. package/dest/kernel_prover/proof_creator.d.ts +3 -3
  32. package/dest/kernel_prover/proof_creator.d.ts.map +1 -1
  33. package/dest/kernel_prover/proof_creator.js +4 -3
  34. package/dest/kernel_prover/proving_data_oracle.d.ts +3 -3
  35. package/dest/kernel_prover/proving_data_oracle.d.ts.map +1 -1
  36. package/dest/note_processor/note_processor.d.ts +11 -13
  37. package/dest/note_processor/note_processor.d.ts.map +1 -1
  38. package/dest/note_processor/note_processor.js +18 -20
  39. package/dest/note_processor/produce_note_dao.d.ts +3 -3
  40. package/dest/note_processor/produce_note_dao.d.ts.map +1 -1
  41. package/dest/note_processor/produce_note_dao.js +1 -1
  42. package/dest/pxe_http/pxe_http_server.d.ts +1 -1
  43. package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
  44. package/dest/pxe_http/pxe_http_server.js +3 -3
  45. package/dest/pxe_service/create_pxe_service.d.ts +2 -2
  46. package/dest/pxe_service/create_pxe_service.d.ts.map +1 -1
  47. package/dest/pxe_service/pxe_service.d.ts +9 -8
  48. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  49. package/dest/pxe_service/pxe_service.js +52 -34
  50. package/dest/pxe_service/test/pxe_test_suite.d.ts +1 -1
  51. package/dest/pxe_service/test/pxe_test_suite.d.ts.map +1 -1
  52. package/dest/pxe_service/test/pxe_test_suite.js +3 -3
  53. package/dest/simulator/index.d.ts +2 -2
  54. package/dest/simulator/index.d.ts.map +1 -1
  55. package/dest/simulator_oracle/index.d.ts +7 -7
  56. package/dest/simulator_oracle/index.d.ts.map +1 -1
  57. package/dest/simulator_oracle/index.js +1 -1
  58. package/dest/synchronizer/synchronizer.d.ts +4 -4
  59. package/dest/synchronizer/synchronizer.d.ts.map +1 -1
  60. package/dest/synchronizer/synchronizer.js +9 -13
  61. package/package.json +22 -16
  62. package/src/contract_data_oracle/index.ts +9 -9
  63. package/src/contract_data_oracle/private_functions_tree.ts +3 -3
  64. package/src/database/contracts/contract_artifact_db.ts +2 -2
  65. package/src/database/contracts/contract_instance_db.ts +2 -2
  66. package/src/database/deferred_note_dao.ts +1 -1
  67. package/src/database/kv_pxe_database.ts +13 -7
  68. package/src/database/note_dao.ts +2 -2
  69. package/src/database/pxe_database.ts +12 -12
  70. package/src/database/pxe_database_test_suite.ts +3 -3
  71. package/src/kernel_oracle/index.ts +9 -9
  72. package/src/kernel_prover/hints_builder.ts +9 -9
  73. package/src/kernel_prover/kernel_prover.ts +29 -95
  74. package/src/kernel_prover/proof_creator.ts +15 -12
  75. package/src/kernel_prover/proving_data_oracle.ts +11 -11
  76. package/src/note_processor/note_processor.ts +29 -34
  77. package/src/note_processor/produce_note_dao.ts +3 -3
  78. package/src/pxe_http/pxe_http_server.ts +3 -2
  79. package/src/pxe_service/create_pxe_service.ts +2 -2
  80. package/src/pxe_service/pxe_service.ts +89 -66
  81. package/src/pxe_service/test/pxe_test_suite.ts +3 -3
  82. package/src/simulator/index.ts +2 -2
  83. package/src/simulator_oracle/index.ts +19 -19
  84. package/src/synchronizer/synchronizer.ts +23 -22
@@ -1,19 +1,19 @@
1
- import { CircuitSimulationStats } from '@aztec/circuit-types/stats';
1
+ import { type CircuitSimulationStats } from '@aztec/circuit-types/stats';
2
2
  import {
3
- PrivateCircuitPublicInputs,
4
- PrivateKernelInitCircuitPrivateInputs,
5
- PrivateKernelInnerCircuitPrivateInputs,
6
- PrivateKernelInnerCircuitPublicInputs,
7
- PrivateKernelTailCircuitPrivateInputs,
8
- PrivateKernelTailCircuitPublicInputs,
9
- Proof,
3
+ type PrivateCircuitPublicInputs,
4
+ type PrivateKernelCircuitPublicInputs,
5
+ type PrivateKernelInitCircuitPrivateInputs,
6
+ type PrivateKernelInnerCircuitPrivateInputs,
7
+ type PrivateKernelTailCircuitPrivateInputs,
8
+ type PrivateKernelTailCircuitPublicInputs,
9
+ type Proof,
10
10
  makeEmptyProof,
11
11
  } from '@aztec/circuits.js';
12
12
  import { siloNoteHash } from '@aztec/circuits.js/hash';
13
- import { Fr } from '@aztec/foundation/fields';
13
+ import { type Fr } from '@aztec/foundation/fields';
14
14
  import { createDebugLogger } from '@aztec/foundation/log';
15
15
  import { elapsed } from '@aztec/foundation/timer';
16
- import { executeInit, executeInner, executeTail } from '@aztec/noir-protocol-circuits-types';
16
+ import { executeInit, executeInner, executeTail, executeTailForPublic } from '@aztec/noir-protocol-circuits-types';
17
17
 
18
18
  /**
19
19
  * Represents the output of the proof creation process for init and inner private kernel circuit.
@@ -23,7 +23,7 @@ export interface ProofOutput {
23
23
  /**
24
24
  * The public inputs required for the proof generation process.
25
25
  */
26
- publicInputs: PrivateKernelInnerCircuitPublicInputs;
26
+ publicInputs: PrivateKernelCircuitPublicInputs;
27
27
  /**
28
28
  * The zk-SNARK proof for the kernel execution.
29
29
  */
@@ -138,7 +138,10 @@ export class KernelProofCreator implements ProofCreator {
138
138
  }
139
139
 
140
140
  public async createProofTail(privateInputs: PrivateKernelTailCircuitPrivateInputs): Promise<ProofOutputFinal> {
141
- const [duration, result] = await elapsed(() => executeTail(privateInputs));
141
+ const isForPublic = privateInputs.isForPublic();
142
+ const [duration, result] = await elapsed(() =>
143
+ isForPublic ? executeTailForPublic(privateInputs) : executeTail(privateInputs),
144
+ );
142
145
  this.log(`Simulated private kernel ordering`, {
143
146
  eventName: 'circuit-simulation',
144
147
  circuitName: 'private-kernel-ordering',
@@ -1,16 +1,16 @@
1
- import { NullifierMembershipWitness } from '@aztec/circuit-types';
1
+ import { type NullifierMembershipWitness } from '@aztec/circuit-types';
2
2
  import {
3
- FUNCTION_TREE_HEIGHT,
4
- Fr,
5
- FunctionSelector,
6
- GrumpkinPrivateKey,
7
- MembershipWitness,
8
- NOTE_HASH_TREE_HEIGHT,
9
- Point,
10
- VK_TREE_HEIGHT,
11
- VerificationKey,
3
+ type FUNCTION_TREE_HEIGHT,
4
+ type Fr,
5
+ type FunctionSelector,
6
+ type GrumpkinPrivateKey,
7
+ type MembershipWitness,
8
+ type NOTE_HASH_TREE_HEIGHT,
9
+ type Point,
10
+ type VK_TREE_HEIGHT,
11
+ type VerificationKey,
12
12
  } from '@aztec/circuits.js';
13
- import { AztecAddress } from '@aztec/foundation/aztec-address';
13
+ import { type AztecAddress } from '@aztec/foundation/aztec-address';
14
14
 
15
15
  /**
16
16
  * Provides functionality to fetch membership witnesses for verification keys,
@@ -1,22 +1,22 @@
1
1
  import {
2
- AztecNode,
3
- EncryptedL2BlockL2Logs,
4
- KeyStore,
2
+ type AztecNode,
3
+ type EncryptedL2BlockL2Logs,
4
+ type KeyStore,
5
5
  L1NotePayload,
6
- L2BlockContext,
6
+ type L2Block,
7
7
  TaggedNote,
8
8
  } from '@aztec/circuit-types';
9
- import { NoteProcessorStats } from '@aztec/circuit-types/stats';
10
- import { INITIAL_L2_BLOCK_NUM, MAX_NEW_NOTE_HASHES_PER_TX, PublicKey } from '@aztec/circuits.js';
9
+ import { type NoteProcessorStats } from '@aztec/circuit-types/stats';
10
+ import { INITIAL_L2_BLOCK_NUM, MAX_NEW_NOTE_HASHES_PER_TX, type PublicKey } from '@aztec/circuits.js';
11
11
  import { Grumpkin } from '@aztec/circuits.js/barretenberg';
12
- import { Fr } from '@aztec/foundation/fields';
12
+ import { type Fr } from '@aztec/foundation/fields';
13
13
  import { createDebugLogger } from '@aztec/foundation/log';
14
14
  import { Timer } from '@aztec/foundation/timer';
15
15
  import { ContractNotFoundError } from '@aztec/simulator';
16
16
 
17
17
  import { DeferredNoteDao } from '../database/deferred_note_dao.js';
18
- import { PxeDatabase } from '../database/index.js';
19
- import { NoteDao } from '../database/note_dao.js';
18
+ import { type PxeDatabase } from '../database/index.js';
19
+ import { type NoteDao } from '../database/note_dao.js';
20
20
  import { getAcirSimulator } from '../simulator/index.js';
21
21
  import { produceNoteDao } from './produce_note_dao.js';
22
22
 
@@ -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,7 +181,7 @@ 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
187
  this.log(`Synched block ${syncedToBlock}`);
@@ -199,7 +194,7 @@ 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);
@@ -215,7 +210,7 @@ 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 => {
@@ -1,7 +1,7 @@
1
- import { L1NotePayload, TxHash } from '@aztec/circuit-types';
2
- import { Fr, PublicKey } from '@aztec/circuits.js';
1
+ import { type L1NotePayload, type TxHash } from '@aztec/circuit-types';
2
+ import { Fr, type PublicKey } from '@aztec/circuits.js';
3
3
  import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/hash';
4
- import { AcirSimulator } from '@aztec/simulator';
4
+ import { type AcirSimulator } from '@aztec/simulator';
5
5
 
6
6
  import { NoteDao } from '../database/note_dao.js';
7
7
 
@@ -8,7 +8,8 @@ import {
8
8
  LogId,
9
9
  Note,
10
10
  NullifierMembershipWitness,
11
- PXE,
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
  }
@@ -1,4 +1,4 @@
1
- import { AztecNode } from '@aztec/circuit-types';
1
+ import { type AztecNode } from '@aztec/circuit-types';
2
2
  import { Grumpkin } from '@aztec/circuits.js/barretenberg';
3
3
  import { randomBytes } from '@aztec/foundation/crypto';
4
4
  import { TestKeyStore } from '@aztec/key-store';
@@ -11,7 +11,7 @@ import { getCanonicalMultiCallEntrypointContract } from '@aztec/protocol-contrac
11
11
 
12
12
  import { join } from 'path';
13
13
 
14
- import { PXEServiceConfig } from '../config/index.js';
14
+ import { type PXEServiceConfig } from '../config/index.js';
15
15
  import { KVPxeDatabase } from '../database/kv_pxe_database.js';
16
16
  import { PXEService } from './pxe_service.js';
17
17
 
@@ -1,61 +1,61 @@
1
1
  import {
2
- AuthWitness,
3
- AztecNode,
2
+ type AuthWitness,
3
+ type AztecNode,
4
4
  EncryptedTxL2Logs,
5
5
  ExtendedNote,
6
- FunctionCall,
7
- GetUnencryptedLogsResponse,
8
- KeyStore,
9
- L2Block,
10
- LogFilter,
6
+ type FunctionCall,
7
+ type GetUnencryptedLogsResponse,
8
+ type KeyStore,
9
+ type L2Block,
10
+ type LogFilter,
11
11
  MerkleTreeId,
12
- NoteFilter,
13
- PXE,
12
+ type NoteFilter,
13
+ type PXE,
14
+ SimulatedTx,
14
15
  SimulationError,
15
16
  Tx,
16
- TxEffect,
17
- TxExecutionRequest,
18
- TxHash,
19
- TxReceipt,
17
+ type TxEffect,
18
+ type TxExecutionRequest,
19
+ type TxHash,
20
+ type TxReceipt,
20
21
  UnencryptedTxL2Logs,
21
22
  isNoirCallStackUnresolved,
22
23
  } from '@aztec/circuit-types';
23
- import { TxPXEProcessingStats } from '@aztec/circuit-types/stats';
24
+ import { type TxPXEProcessingStats } from '@aztec/circuit-types/stats';
24
25
  import {
25
26
  AztecAddress,
26
27
  CallRequest,
27
28
  CompleteAddress,
28
29
  FunctionData,
29
- GrumpkinPrivateKey,
30
- MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX,
31
- MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX,
32
- PartialAddress,
33
- PrivateKernelTailCircuitPublicInputs,
34
- PublicCallRequest,
30
+ type GrumpkinPrivateKey,
31
+ MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX,
32
+ type PartialAddress,
33
+ type PrivateKernelTailCircuitPublicInputs,
34
+ type PublicCallRequest,
35
35
  computeContractClassId,
36
36
  getContractClassFromArtifact,
37
37
  } from '@aztec/circuits.js';
38
38
  import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/hash';
39
- import { ContractArtifact, DecodedReturn, FunctionSelector, encodeArguments } from '@aztec/foundation/abi';
39
+ import { type ContractArtifact, type DecodedReturn, FunctionSelector, encodeArguments } from '@aztec/foundation/abi';
40
40
  import { arrayNonEmptyLength, padArrayEnd } from '@aztec/foundation/collection';
41
41
  import { Fr } from '@aztec/foundation/fields';
42
42
  import { SerialQueue } from '@aztec/foundation/fifo';
43
- import { DebugLogger, createDebugLogger } from '@aztec/foundation/log';
43
+ import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
44
44
  import { Timer } from '@aztec/foundation/timer';
45
45
  import {
46
- AcirSimulator,
47
- ExecutionResult,
46
+ type AcirSimulator,
47
+ type ExecutionResult,
48
48
  collectEncryptedLogs,
49
49
  collectEnqueuedPublicFunctionCalls,
50
50
  collectUnencryptedLogs,
51
51
  resolveOpcodeLocations,
52
52
  } from '@aztec/simulator';
53
- import { ContractClassWithId, ContractInstanceWithAddress } from '@aztec/types/contracts';
54
- import { NodeInfo } from '@aztec/types/interfaces';
53
+ import { type ContractClassWithId, type ContractInstanceWithAddress } from '@aztec/types/contracts';
54
+ import { type NodeInfo } from '@aztec/types/interfaces';
55
55
 
56
- import { PXEServiceConfig, getPackageInfo } from '../config/index.js';
56
+ import { type PXEServiceConfig, getPackageInfo } from '../config/index.js';
57
57
  import { ContractDataOracle } from '../contract_data_oracle/index.js';
58
- import { PxeDatabase } from '../database/index.js';
58
+ import { type PxeDatabase } from '../database/index.js';
59
59
  import { NoteDao } from '../database/note_dao.js';
60
60
  import { KernelOracle } from '../kernel_oracle/index.js';
61
61
  import { KernelProver } from '../kernel_prover/kernel_prover.js';
@@ -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
 
@@ -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(`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,14 +541,14 @@ 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
549
  this.log('Executing simulator...');
533
550
  try {
534
- const result = await this.simulator.run(txRequest, functionArtifact, contractAddress, portalContract);
551
+ const result = await this.simulator.run(txRequest, functionArtifact, contractAddress, portalContract, msgSender);
535
552
  this.log('Simulation completed!');
536
553
  return result;
537
554
  } 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
637
  this.log(`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
 
@@ -1,5 +1,5 @@
1
1
  import {
2
- PXE,
2
+ type PXE,
3
3
  TxExecutionRequest,
4
4
  randomContractArtifact,
5
5
  randomContractInstanceWithAddress,
@@ -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,8 +1,8 @@
1
- import { AztecNode, KeyStore } from '@aztec/circuit-types';
1
+ import { type AztecNode, type KeyStore } from '@aztec/circuit-types';
2
2
  import { AcirSimulator } from '@aztec/simulator';
3
3
 
4
4
  import { ContractDataOracle } from '../contract_data_oracle/index.js';
5
- import { PxeDatabase } from '../database/pxe_database.js';
5
+ import { type PxeDatabase } from '../database/pxe_database.js';
6
6
  import { SimulatorOracle } from '../simulator_oracle/index.js';
7
7
 
8
8
  /**
@@ -1,30 +1,30 @@
1
1
  import {
2
- AztecNode,
3
- KeyStore,
4
- L2Block,
2
+ type AztecNode,
3
+ type KeyStore,
4
+ type L2Block,
5
5
  MerkleTreeId,
6
- NoteStatus,
7
- NullifierMembershipWitness,
8
- PublicDataWitness,
9
- SiblingPath,
6
+ type NoteStatus,
7
+ type NullifierMembershipWitness,
8
+ type PublicDataWitness,
9
+ type SiblingPath,
10
10
  } from '@aztec/circuit-types';
11
11
  import {
12
- AztecAddress,
13
- CompleteAddress,
14
- EthAddress,
15
- Fr,
16
- FunctionSelector,
17
- Header,
18
- L1_TO_L2_MSG_TREE_HEIGHT,
12
+ type AztecAddress,
13
+ type CompleteAddress,
14
+ type EthAddress,
15
+ type Fr,
16
+ type FunctionSelector,
17
+ type Header,
18
+ type L1_TO_L2_MSG_TREE_HEIGHT,
19
19
  } from '@aztec/circuits.js';
20
20
  import { computeL1ToL2MessageNullifier } from '@aztec/circuits.js/hash';
21
- import { FunctionArtifactWithDebugMetadata, getFunctionArtifactWithDebugMetadata } from '@aztec/foundation/abi';
21
+ import { type FunctionArtifactWithDebugMetadata, getFunctionArtifactWithDebugMetadata } from '@aztec/foundation/abi';
22
22
  import { createDebugLogger } from '@aztec/foundation/log';
23
- import { DBOracle, KeyPair, MessageLoadOracleInputs } from '@aztec/simulator';
24
- import { ContractInstance } from '@aztec/types/contracts';
23
+ import { type DBOracle, type KeyPair, MessageLoadOracleInputs } from '@aztec/simulator';
24
+ import { type ContractInstance } from '@aztec/types/contracts';
25
25
 
26
- import { ContractDataOracle } from '../contract_data_oracle/index.js';
27
- import { PxeDatabase } from '../database/index.js';
26
+ import { type ContractDataOracle } from '../contract_data_oracle/index.js';
27
+ import { type PxeDatabase } from '../database/index.js';
28
28
 
29
29
  /**
30
30
  * A data oracle that provides information needed for simulating a transaction.