@aztec/pxe 3.0.0-nightly.20251210 → 3.0.0-nightly.20251212

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 (47) hide show
  1. package/dest/bin/check_oracle_version.js +104 -14
  2. package/dest/contract_function_simulator/execution_data_provider.d.ts +3 -3
  3. package/dest/contract_function_simulator/execution_data_provider.d.ts.map +1 -1
  4. package/dest/contract_function_simulator/execution_note_cache.d.ts +3 -3
  5. package/dest/contract_function_simulator/execution_note_cache.d.ts.map +1 -1
  6. package/dest/contract_function_simulator/execution_note_cache.js +2 -2
  7. package/dest/contract_function_simulator/oracle/interfaces.d.ts +2 -2
  8. package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
  9. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts +6 -2
  10. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts.map +1 -1
  11. package/dest/contract_function_simulator/oracle/note_packing_utils.js +6 -2
  12. package/dest/contract_function_simulator/oracle/oracle.d.ts +2 -2
  13. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
  14. package/dest/contract_function_simulator/oracle/oracle.js +13 -3
  15. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +3 -3
  16. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  17. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +1 -1
  18. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +3 -3
  19. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  20. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +1 -1
  21. package/dest/contract_function_simulator/pxe_oracle_interface.d.ts +2 -2
  22. package/dest/contract_function_simulator/pxe_oracle_interface.d.ts.map +1 -1
  23. package/dest/contract_function_simulator/pxe_oracle_interface.js +12 -1
  24. package/dest/entrypoints/client/bundle/utils.js +1 -1
  25. package/dest/entrypoints/client/lazy/utils.js +1 -1
  26. package/dest/entrypoints/pxe_creation_options.d.ts +3 -1
  27. package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
  28. package/dest/oracle_version.d.ts +2 -2
  29. package/dest/oracle_version.js +2 -2
  30. package/dest/storage/note_data_provider/note_data_provider.d.ts +3 -2
  31. package/dest/storage/note_data_provider/note_data_provider.d.ts.map +1 -1
  32. package/dest/storage/note_data_provider/note_data_provider.js +10 -2
  33. package/package.json +16 -16
  34. package/src/bin/check_oracle_version.ts +129 -19
  35. package/src/contract_function_simulator/execution_data_provider.ts +2 -2
  36. package/src/contract_function_simulator/execution_note_cache.ts +6 -3
  37. package/src/contract_function_simulator/oracle/interfaces.ts +1 -1
  38. package/src/contract_function_simulator/oracle/note_packing_utils.ts +16 -2
  39. package/src/contract_function_simulator/oracle/oracle.ts +16 -3
  40. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +2 -2
  41. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +2 -2
  42. package/src/contract_function_simulator/pxe_oracle_interface.ts +16 -2
  43. package/src/entrypoints/client/bundle/utils.ts +1 -1
  44. package/src/entrypoints/client/lazy/utils.ts +1 -1
  45. package/src/entrypoints/pxe_creation_options.ts +2 -0
  46. package/src/oracle_version.ts +2 -2
  47. package/src/storage/note_data_provider/note_data_provider.ts +11 -2
@@ -24,7 +24,9 @@ function fromRawData(nonzeroNoteHashCounter: boolean, maybeNoteNonce: Fr): { sta
24
24
  * and only after that it packs the retrieved note. Hence it doesn't map one to one with `RetrievedNote::pack()`.
25
25
  *
26
26
  * @param contractAddress - The address of the contract that owns the note
27
+ * @param owner - The owner of the note
27
28
  * @param randomness - The randomness injected into the note to get the hiding property of commitments
29
+ * @param storageSlot - The storage slot of the note
28
30
  * @param noteNonce - The nonce injected into the note hash preimage by kernels.
29
31
  * @param index - Optional index in the note hash tree. If undefined, indicates a transient note
30
32
  * @param note - The note content containing the actual note data
@@ -32,13 +34,17 @@ function fromRawData(nonzeroNoteHashCounter: boolean, maybeNoteNonce: Fr): { sta
32
34
  */
33
35
  export function packAsRetrievedNote({
34
36
  contractAddress,
37
+ owner,
35
38
  randomness,
39
+ storageSlot,
36
40
  noteNonce,
37
41
  index,
38
42
  note,
39
43
  }: {
40
44
  contractAddress: AztecAddress;
45
+ owner: AztecAddress;
41
46
  randomness: Fr;
47
+ storageSlot: Fr;
42
48
  noteNonce: Fr;
43
49
  index?: bigint;
44
50
  note: Note;
@@ -49,6 +55,14 @@ export function packAsRetrievedNote({
49
55
  // To pack the note as retrieved note we first need to reconstruct the note metadata.
50
56
  const noteMetadata = fromRawData(nonzeroNoteHashCounter, noteNonce);
51
57
 
52
- // Pack metadata first (stage and maybe_note_nonce), followed by the rest
53
- return [...note.items, contractAddress, randomness, new Fr(noteMetadata.stage), noteMetadata.maybeNoteNonce];
58
+ // Pack in order: note, contract_address, owner, randomness, storage_slot, metadata (stage, maybe_note_nonce)
59
+ return [
60
+ ...note.items,
61
+ contractAddress,
62
+ owner,
63
+ randomness,
64
+ storageSlot,
65
+ new Fr(noteMetadata.stage),
66
+ noteMetadata.maybeNoteNonce,
67
+ ];
54
68
  }
@@ -240,7 +240,8 @@ export class Oracle {
240
240
  }
241
241
 
242
242
  async utilityGetNotes(
243
- [owner]: ACVMField[],
243
+ [ownerSome]: ACVMField[],
244
+ [ownerValue]: ACVMField[],
244
245
  [storageSlot]: ACVMField[],
245
246
  [numSelects]: ACVMField[],
246
247
  selectByIndexes: ACVMField[],
@@ -258,8 +259,10 @@ export class Oracle {
258
259
  [maxNotes]: ACVMField[],
259
260
  [packedRetrievedNoteLength]: ACVMField[],
260
261
  ): Promise<(ACVMField | ACVMField[])[]> {
262
+ // Parse Option<AztecAddress>: ownerSome is 0 for None, 1 for Some
263
+ const owner = Fr.fromString(ownerSome).toNumber() === 1 ? AztecAddress.fromString(ownerValue) : undefined;
261
264
  const noteDatas = await this.handlerAsUtility().utilityGetNotes(
262
- AztecAddress.fromString(owner),
265
+ owner,
263
266
  Fr.fromString(storageSlot),
264
267
  +numSelects,
265
268
  selectByIndexes.map(s => +s),
@@ -276,7 +279,17 @@ export class Oracle {
276
279
  +status,
277
280
  );
278
281
 
279
- const returnDataAsArrayOfPackedRetrievedNotes = noteDatas.map(packAsRetrievedNote);
282
+ const returnDataAsArrayOfPackedRetrievedNotes = noteDatas.map(noteData =>
283
+ packAsRetrievedNote({
284
+ contractAddress: noteData.contractAddress,
285
+ owner: noteData.owner,
286
+ randomness: noteData.randomness,
287
+ storageSlot: noteData.storageSlot,
288
+ noteNonce: noteData.noteNonce,
289
+ index: noteData.index,
290
+ note: noteData.note,
291
+ }),
292
+ );
280
293
 
281
294
  // Now we convert each sub-array to an array of ACVMField
282
295
  const returnDataAsArrayOfACVMFieldArrays = returnDataAsArrayOfPackedRetrievedNotes.map(subArray =>
@@ -282,7 +282,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
282
282
  * Real notes coming from DB will have a leafIndex which
283
283
  * represents their index in the note hash tree.
284
284
  *
285
- * @param owner - The owner of the notes.
285
+ * @param owner - The owner of the notes. If undefined, returns notes for all owners.
286
286
  * @param storageSlot - The storage slot.
287
287
  * @param numSelects - The number of valid selects in selectBy and selectValues.
288
288
  * @param selectBy - An array of indices of the fields to selects.
@@ -296,7 +296,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
296
296
  * @returns Array of note data.
297
297
  */
298
298
  public override async utilityGetNotes(
299
- owner: AztecAddress,
299
+ owner: AztecAddress | undefined,
300
300
  storageSlot: Fr,
301
301
  numSelects: number,
302
302
  selectByIndexes: number[],
@@ -169,7 +169,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
169
169
  * Real notes coming from DB will have a leafIndex which
170
170
  * represents their index in the note hash tree.
171
171
  *
172
- * @param owner - The owner of the notes.
172
+ * @param owner - The owner of the notes. If undefined, returns notes for all owners.
173
173
  * @param storageSlot - The storage slot.
174
174
  * @param numSelects - The number of valid selects in selectBy and selectValues.
175
175
  * @param selectBy - An array of indices of the fields to selects.
@@ -183,7 +183,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
183
183
  * @returns Array of note data.
184
184
  */
185
185
  public async utilityGetNotes(
186
- owner: AztecAddress,
186
+ owner: AztecAddress | undefined,
187
187
  storageSlot: Fr,
188
188
  numSelects: number,
189
189
  selectByIndexes: number[],
@@ -93,7 +93,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
93
93
 
94
94
  async getNotes(
95
95
  contractAddress: AztecAddress,
96
- owner: AztecAddress,
96
+ owner: AztecAddress | undefined,
97
97
  storageSlot: Fr,
98
98
  status: NoteStatus,
99
99
  scopes?: AztecAddress[],
@@ -680,6 +680,20 @@ export class PXEOracleInterface implements ExecutionDataProvider {
680
680
  const uniqueNoteHash = await computeUniqueNoteHash(noteNonce, await siloNoteHash(contractAddress, noteHash));
681
681
  const siloedNullifier = await siloNullifier(contractAddress, nullifier);
682
682
 
683
+ const txEffect = await this.aztecNode.getTxEffect(txHash);
684
+ if (!txEffect) {
685
+ throw new Error(`Could not find tx effect for tx hash ${txHash}`);
686
+ }
687
+
688
+ if (txEffect.l2BlockNumber > syncedBlockNumber) {
689
+ throw new Error(`Could not find tx effect for tx hash ${txHash} as of block number ${syncedBlockNumber}`);
690
+ }
691
+
692
+ const noteInTx = txEffect.data.noteHashes.some(nh => nh.equals(uniqueNoteHash));
693
+ if (!noteInTx) {
694
+ throw new Error(`Note hash ${noteHash} (uniqued as ${uniqueNoteHash}) is not present in tx ${txHash}`);
695
+ }
696
+
683
697
  // We store notes by their index in the global note hash tree, which has the convenient side effect of validating
684
698
  // note existence in said tree. We concurrently also check if the note's nullifier exists, performing all node
685
699
  // queries in a single round-trip.
@@ -814,7 +828,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
814
828
  throw new Error(`Could not find tx effect for tx hash ${txHash} as of block number ${syncedBlockNumber}`);
815
829
  }
816
830
 
817
- const eventInTx = txEffect.data.nullifiers.some(nullifier => nullifier.equals(siloedEventCommitment));
831
+ const eventInTx = txEffect.data.nullifiers.some(n => n.equals(siloedEventCommitment));
818
832
  if (!eventInTx) {
819
833
  throw new Error(
820
834
  `Event commitment ${eventCommitment} (siloed as ${siloedEventCommitment}) is not present in tx ${txHash}`,
@@ -44,7 +44,7 @@ export async function createPXE(
44
44
 
45
45
  const store = options.store ?? (await createStore('pxe_data', configWithContracts, storeLogger));
46
46
 
47
- const simulator = new WASMSimulator();
47
+ const simulator = options.simulator ?? new WASMSimulator();
48
48
  const proverLogger = loggers.prover
49
49
  ? loggers.prover
50
50
  : createLogger('pxe:bb:wasm:bundle' + (logSuffix ? `:${logSuffix}` : ''));
@@ -43,7 +43,7 @@ export async function createPXE(
43
43
 
44
44
  const store = options.store ?? (await createStore('pxe_data', configWithContracts, storeLogger));
45
45
 
46
- const simulator = new WASMSimulator();
46
+ const simulator = options.simulator ?? new WASMSimulator();
47
47
  const proverLogger = loggers.prover
48
48
  ? loggers.prover
49
49
  : createLogger('pxe:bb:wasm:bundle' + (logSuffix ? `:${logSuffix}` : ''));
@@ -1,5 +1,6 @@
1
1
  import type { Logger } from '@aztec/foundation/log';
2
2
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
3
+ import type { CircuitSimulator } from '@aztec/simulator/client';
3
4
  import type { PrivateKernelProver } from '@aztec/stdlib/interfaces/client';
4
5
 
5
6
  export type PXECreationOptions = {
@@ -7,4 +8,5 @@ export type PXECreationOptions = {
7
8
  useLogSuffix?: boolean | string;
8
9
  prover?: PrivateKernelProver;
9
10
  store?: AztecAsyncKVStore;
11
+ simulator?: CircuitSimulator;
10
12
  };
@@ -4,8 +4,8 @@
4
4
  ///
5
5
  /// @dev Whenever a contract function or Noir test is run, the `utilityAssertCompatibleOracleVersion` oracle is called
6
6
  /// and if the oracle version is incompatible an error is thrown.
7
- export const ORACLE_VERSION = 4;
7
+ export const ORACLE_VERSION = 5;
8
8
 
9
9
  /// This hash is computed as by hashing the Oracle interface and it is used to detect when the Oracle interface changes,
10
10
  /// which in turn implies that you need to update the ORACLE_VERSION constant.
11
- export const ORACLE_INTERFACE_HASH = 'd1496df59c0b51a481d5ef93f218b5c35ddfce6242da28d60bb5c66386940eac';
11
+ export const ORACLE_INTERFACE_HASH = 'd603c17a97034d978ca453d2bce3aacae139539dee28bbc46e8f8c7177a348ec';
@@ -225,7 +225,8 @@ export class NoteDataProvider {
225
225
  *
226
226
  * @param filter - Filter criteria including contractAddress (required), and optional
227
227
  * owner, storageSlot, status, scopes, and siloedNullifier.
228
- * @returns Promise resolving to array of NoteDao objects matching the filter
228
+ * @returns Filtered and deduplicated notes (a note might be present in multiple scopes - we ensure it is only
229
+ * returned once if this is the case)
229
230
  * @throws If filtering by an empty scopes array. Scopes have to be set to undefined or to a non-empty array.
230
231
  */
231
232
  async getNotes(filter: NotesFilter): Promise<NoteDao[]> {
@@ -323,7 +324,15 @@ export class NoteDataProvider {
323
324
  }
324
325
  }
325
326
 
326
- return result;
327
+ // A note might be present in multiple scopes - we ensure it is only returned once
328
+ const deduplicated: NoteDao[] = [];
329
+ for (const note of result) {
330
+ if (!deduplicated.some(existing => existing.equals(note))) {
331
+ deduplicated.push(note);
332
+ }
333
+ }
334
+
335
+ return deduplicated;
327
336
  }
328
337
 
329
338
  /**