@aztec/pxe 0.0.1-commit.3e3d0c9cd → 0.0.1-commit.3f5453c7b

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 (155) hide show
  1. package/dest/bin/check_oracle_version.js +4 -4
  2. package/dest/block_synchronizer/block_synchronizer.d.ts +1 -1
  3. package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
  4. package/dest/block_synchronizer/block_synchronizer.js +6 -0
  5. package/dest/contract_function_simulator/contract_function_simulator.d.ts +3 -4
  6. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  7. package/dest/contract_function_simulator/contract_function_simulator.js +13 -4
  8. package/dest/contract_function_simulator/ephemeral_array_service.d.ts +28 -0
  9. package/dest/contract_function_simulator/ephemeral_array_service.d.ts.map +1 -0
  10. package/dest/contract_function_simulator/ephemeral_array_service.js +78 -0
  11. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +3 -4
  12. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts.map +1 -1
  13. package/dest/contract_function_simulator/noir-structs/event_validation_request.js +3 -6
  14. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts +1 -1
  15. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.js +1 -1
  16. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +1 -1
  17. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +1 -1
  18. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +3 -4
  19. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts.map +1 -1
  20. package/dest/contract_function_simulator/noir-structs/note_validation_request.js +3 -6
  21. package/dest/contract_function_simulator/oracle/interfaces.d.ts +31 -19
  22. package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
  23. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.d.ts +1 -1
  24. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.d.ts.map +1 -1
  25. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.js +28 -24
  26. package/dest/contract_function_simulator/oracle/oracle.d.ts +50 -19
  27. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
  28. package/dest/contract_function_simulator/oracle/oracle.js +177 -41
  29. package/dest/contract_function_simulator/oracle/private_execution.js +1 -1
  30. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +7 -11
  31. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  32. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +16 -9
  33. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +61 -38
  34. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  35. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +210 -92
  36. package/dest/contract_function_simulator/pick_notes.d.ts +1 -1
  37. package/dest/contract_function_simulator/pick_notes.d.ts.map +1 -1
  38. package/dest/contract_function_simulator/pick_notes.js +9 -2
  39. package/dest/contract_function_simulator/proxied_contract_data_source.d.ts +1 -1
  40. package/dest/contract_function_simulator/proxied_contract_data_source.d.ts.map +1 -1
  41. package/dest/contract_function_simulator/proxied_contract_data_source.js +3 -0
  42. package/dest/contract_logging.d.ts +9 -4
  43. package/dest/contract_logging.d.ts.map +1 -1
  44. package/dest/contract_logging.js +21 -6
  45. package/dest/contract_sync/contract_sync_service.d.ts +6 -5
  46. package/dest/contract_sync/contract_sync_service.d.ts.map +1 -1
  47. package/dest/contract_sync/contract_sync_service.js +44 -37
  48. package/dest/contract_sync/helpers.d.ts +2 -3
  49. package/dest/contract_sync/helpers.d.ts.map +1 -1
  50. package/dest/contract_sync/helpers.js +7 -2
  51. package/dest/debug/pxe_debug_utils.d.ts +3 -3
  52. package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
  53. package/dest/entrypoints/client/bundle/index.d.ts +1 -2
  54. package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
  55. package/dest/entrypoints/client/bundle/index.js +0 -1
  56. package/dest/entrypoints/client/bundle/utils.d.ts +2 -2
  57. package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
  58. package/dest/entrypoints/client/bundle/utils.js +2 -2
  59. package/dest/entrypoints/client/lazy/index.d.ts +1 -2
  60. package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
  61. package/dest/entrypoints/client/lazy/index.js +0 -1
  62. package/dest/entrypoints/client/lazy/utils.d.ts +2 -2
  63. package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
  64. package/dest/entrypoints/client/lazy/utils.js +2 -2
  65. package/dest/entrypoints/pxe_creation_options.d.ts +3 -1
  66. package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
  67. package/dest/entrypoints/pxe_creation_options.js +3 -1
  68. package/dest/entrypoints/server/index.d.ts +2 -3
  69. package/dest/entrypoints/server/index.d.ts.map +1 -1
  70. package/dest/entrypoints/server/index.js +1 -2
  71. package/dest/entrypoints/server/utils.d.ts +2 -2
  72. package/dest/entrypoints/server/utils.d.ts.map +1 -1
  73. package/dest/entrypoints/server/utils.js +2 -2
  74. package/dest/events/event_service.d.ts +3 -2
  75. package/dest/events/event_service.d.ts.map +1 -1
  76. package/dest/events/event_service.js +16 -4
  77. package/dest/logs/log_service.d.ts +5 -8
  78. package/dest/logs/log_service.d.ts.map +1 -1
  79. package/dest/logs/log_service.js +24 -37
  80. package/dest/messages/message_context_service.d.ts +3 -3
  81. package/dest/messages/message_context_service.d.ts.map +1 -1
  82. package/dest/messages/message_context_service.js +3 -3
  83. package/dest/notes/note_service.d.ts +4 -5
  84. package/dest/notes/note_service.d.ts.map +1 -1
  85. package/dest/notes/note_service.js +14 -5
  86. package/dest/notes_filter.d.ts +2 -3
  87. package/dest/notes_filter.d.ts.map +1 -1
  88. package/dest/oracle_version.d.ts +4 -3
  89. package/dest/oracle_version.d.ts.map +1 -1
  90. package/dest/oracle_version.js +20 -10
  91. package/dest/pxe.d.ts +4 -5
  92. package/dest/pxe.d.ts.map +1 -1
  93. package/dest/pxe.js +12 -6
  94. package/dest/storage/capsule_store/capsule_service.d.ts +21 -0
  95. package/dest/storage/capsule_store/capsule_service.d.ts.map +1 -0
  96. package/dest/storage/capsule_store/capsule_service.js +50 -0
  97. package/dest/storage/capsule_store/capsule_store.d.ts +9 -9
  98. package/dest/storage/capsule_store/capsule_store.d.ts.map +1 -1
  99. package/dest/storage/capsule_store/capsule_store.js +33 -28
  100. package/dest/storage/capsule_store/index.d.ts +2 -1
  101. package/dest/storage/capsule_store/index.d.ts.map +1 -1
  102. package/dest/storage/capsule_store/index.js +1 -0
  103. package/dest/storage/metadata.d.ts +1 -1
  104. package/dest/storage/metadata.js +1 -1
  105. package/dest/storage/note_store/note_store.d.ts +1 -1
  106. package/dest/storage/note_store/note_store.d.ts.map +1 -1
  107. package/dest/storage/note_store/note_store.js +2 -2
  108. package/package.json +16 -16
  109. package/src/bin/check_oracle_version.ts +4 -4
  110. package/src/block_synchronizer/block_synchronizer.ts +6 -0
  111. package/src/contract_function_simulator/contract_function_simulator.ts +17 -7
  112. package/src/contract_function_simulator/ephemeral_array_service.ts +110 -0
  113. package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -4
  114. package/src/contract_function_simulator/noir-structs/log_retrieval_request.ts +1 -1
  115. package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +1 -1
  116. package/src/contract_function_simulator/noir-structs/note_validation_request.ts +1 -4
  117. package/src/contract_function_simulator/oracle/interfaces.ts +46 -17
  118. package/src/contract_function_simulator/oracle/legacy_oracle_mappings.ts +20 -58
  119. package/src/contract_function_simulator/oracle/oracle.ts +242 -36
  120. package/src/contract_function_simulator/oracle/private_execution.ts +1 -1
  121. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +19 -14
  122. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +351 -118
  123. package/src/contract_function_simulator/pick_notes.ts +9 -2
  124. package/src/contract_function_simulator/proxied_contract_data_source.ts +8 -1
  125. package/src/contract_logging.ts +18 -5
  126. package/src/contract_sync/contract_sync_service.ts +77 -59
  127. package/src/contract_sync/helpers.ts +4 -4
  128. package/src/debug/pxe_debug_utils.ts +3 -3
  129. package/src/entrypoints/client/bundle/index.ts +0 -1
  130. package/src/entrypoints/client/bundle/utils.ts +2 -3
  131. package/src/entrypoints/client/lazy/index.ts +0 -1
  132. package/src/entrypoints/client/lazy/utils.ts +2 -3
  133. package/src/entrypoints/pxe_creation_options.ts +7 -0
  134. package/src/entrypoints/server/index.ts +1 -2
  135. package/src/entrypoints/server/utils.ts +2 -3
  136. package/src/events/event_service.ts +17 -4
  137. package/src/logs/log_service.ts +52 -78
  138. package/src/messages/message_context_service.ts +3 -4
  139. package/src/notes/note_service.ts +18 -8
  140. package/src/notes_filter.ts +1 -3
  141. package/src/oracle_version.ts +20 -10
  142. package/src/pxe.ts +17 -12
  143. package/src/storage/capsule_store/capsule_service.ts +90 -0
  144. package/src/storage/capsule_store/capsule_store.ts +34 -26
  145. package/src/storage/capsule_store/index.ts +1 -0
  146. package/src/storage/metadata.ts +1 -1
  147. package/src/storage/note_store/note_store.ts +2 -5
  148. package/dest/access_scopes.d.ts +0 -9
  149. package/dest/access_scopes.d.ts.map +0 -1
  150. package/dest/access_scopes.js +0 -6
  151. package/dest/contract_function_simulator/noir-structs/message_tx_context.d.ts +0 -16
  152. package/dest/contract_function_simulator/noir-structs/message_tx_context.d.ts.map +0 -1
  153. package/dest/contract_function_simulator/noir-structs/message_tx_context.js +0 -57
  154. package/src/access_scopes.ts +0 -9
  155. package/src/contract_function_simulator/noir-structs/message_tx_context.ts +0 -55
@@ -15,6 +15,7 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address';
15
15
  import { BlockHash } from '@aztec/stdlib/block';
16
16
  import { ContractClassLog, ContractClassLogFields } from '@aztec/stdlib/logs';
17
17
 
18
+ import { ORACLE_VERSION_MAJOR, ORACLE_VERSION_MINOR } from '../../oracle_version.js';
18
19
  import type { IMiscOracle, IPrivateExecutionOracle, IUtilityExecutionOracle } from './interfaces.js';
19
20
  import { buildLegacyOracleCallbacks } from './legacy_oracle_mappings.js';
20
21
  import { packAsHintedNote } from './note_packing_utils.js';
@@ -27,6 +28,25 @@ export class UnavailableOracleError extends Error {
27
28
 
28
29
  /**
29
30
  * A data source that has all the apis required by Aztec.nr.
31
+ *
32
+ * ## Oracle naming conventions
33
+ *
34
+ * We try to keep oracle naming consistent, please see below the conventions we adhere to.
35
+ *
36
+ * Each oracle method name has the form `aztec_{scope}_{verb}{Object}`, where:
37
+ *
38
+ * - **Scope prefix** indicates the execution context required:
39
+ * - `aztec_prv_` — available only during private function execution.
40
+ * - `aztec_utl_` — available during both utility and private execution.
41
+ *
42
+ * - **Verb** signals the operation's semantics (verb-first, then object):
43
+ * - `get` — read / lookup / get data from oracle into contract.
44
+ * - `does`/`is`/`has` — predicate (returns boolean).
45
+ * - `emit`/`notify` — propagate data from contract to oracle.
46
+ * - `set` — contract driven oracle state mutation (capsules, execution cache, tagging, etc).
47
+ * - `call` — trigger nested execution (control flow).
48
+ * - `assert` — validate a condition, throw on failure.
49
+ * - Standalone verbs (`delete`, `copy`, `decrypt`, `log`, etc) are used when no generic verb fits.
30
50
  */
31
51
  export class Oracle {
32
52
  constructor(private handler: IMiscOracle | IUtilityExecutionOracle | IPrivateExecutionOracle) {}
@@ -92,12 +112,67 @@ export class Oracle {
92
112
  return acc;
93
113
  }, {} as ACIRCallback);
94
114
 
95
- return { ...callback, ...buildLegacyOracleCallbacks(this) };
115
+ const allCallbacks = { ...callback, ...buildLegacyOracleCallbacks(this) };
116
+
117
+ // Wrap in a Proxy to intercept access to missing oracle names and provide enhanced error messages when the
118
+ // contract's minor version is higher than the PXE's (i.e. the contract expects oracles that were added in a newer
119
+ // minor version).
120
+ const handler = this.handler;
121
+ return new Proxy(allCallbacks, {
122
+ get(target, prop: string) {
123
+ if (prop in target) {
124
+ return target[prop];
125
+ }
126
+ // Return a function that throws with an enhanced error message if applicable
127
+ return () => {
128
+ type NonOracleFunctionGetContractOracleVersion = {
129
+ nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined;
130
+ };
131
+
132
+ let contractVersion = undefined;
133
+ if ('nonOracleFunctionGetContractOracleVersion' in handler) {
134
+ contractVersion = (
135
+ handler as unknown as NonOracleFunctionGetContractOracleVersion
136
+ ).nonOracleFunctionGetContractOracleVersion();
137
+ }
138
+ if (!contractVersion) {
139
+ throw new Error(
140
+ `Oracle '${prop}' not found and the contract's oracle version is unknown (the version check oracle ` +
141
+ `was not called before '${prop}'). This usually means the contract was not compiled with the ` +
142
+ `#[aztec] macro, which injects the version check as the first oracle call in every private/utility ` +
143
+ `external function. If you're using a custom entry point, ensure assert_compatible_oracle_version() ` +
144
+ `is called before any other oracle calls. See https://docs.aztec.network/errors/8`,
145
+ );
146
+ } else if (contractVersion.minor > ORACLE_VERSION_MINOR) {
147
+ throw new Error(
148
+ `Oracle '${prop}' not found.` +
149
+ ` This usually means the contract requires a newer private execution environment than you have.` +
150
+ ` Upgrade your private execution environment to a compatible version. The contract was compiled with` +
151
+ ` Aztec.nr oracle version ${contractVersion.major}.${contractVersion.minor}, but this private` +
152
+ ` execution environment only supports up to ${ORACLE_VERSION_MAJOR}.${ORACLE_VERSION_MINOR}.` +
153
+ ` See https://docs.aztec.network/errors/8`,
154
+ );
155
+ } else {
156
+ throw new Error(
157
+ `Oracle '${prop}' not found.` +
158
+ ` The contract's oracle version (${contractVersion.major}.${contractVersion.minor}) is compatible` +
159
+ ` with this private execution environment (${ORACLE_VERSION_MAJOR}.${ORACLE_VERSION_MINOR}), so all` +
160
+ ` standard oracles should be available. This could mean the contract was compiled against a modified` +
161
+ ` version of Aztec.nr, or that it references an oracle that does not exist.` +
162
+ ` See https://docs.aztec.network/errors/8`,
163
+ );
164
+ }
165
+ };
166
+ },
167
+ });
96
168
  }
97
169
 
98
170
  // eslint-disable-next-line camelcase
99
- aztec_utl_assertCompatibleOracleVersion([version]: ACVMField[]) {
100
- this.handlerAsMisc().assertCompatibleOracleVersion(Fr.fromString(version).toNumber());
171
+ aztec_utl_assertCompatibleOracleVersionV2([major]: ACVMField[], [minor]: ACVMField[]) {
172
+ this.handlerAsMisc().assertCompatibleOracleVersion(
173
+ Fr.fromString(major).toNumber(),
174
+ Fr.fromString(minor).toNumber(),
175
+ );
101
176
  return Promise.resolve([]);
102
177
  }
103
178
 
@@ -108,14 +183,14 @@ export class Oracle {
108
183
  }
109
184
 
110
185
  // eslint-disable-next-line camelcase
111
- aztec_prv_storeInExecutionCache(values: ACVMField[], [hash]: ACVMField[]): Promise<ACVMField[]> {
112
- this.handlerAsPrivate().storeInExecutionCache(values.map(Fr.fromString), Fr.fromString(hash));
186
+ aztec_prv_setHashPreimage(values: ACVMField[], [hash]: ACVMField[]): Promise<ACVMField[]> {
187
+ this.handlerAsPrivate().setHashPreimage(values.map(Fr.fromString), Fr.fromString(hash));
113
188
  return Promise.resolve([]);
114
189
  }
115
190
 
116
191
  // eslint-disable-next-line camelcase
117
- async aztec_prv_loadFromExecutionCache([returnsHash]: ACVMField[]): Promise<ACVMField[][]> {
118
- const values = await this.handlerAsPrivate().loadFromExecutionCache(Fr.fromString(returnsHash));
192
+ async aztec_prv_getHashPreimage([returnsHash]: ACVMField[]): Promise<ACVMField[][]> {
193
+ const values = await this.handlerAsPrivate().getHashPreimage(Fr.fromString(returnsHash));
119
194
  return [values.map(toACVMField)];
120
195
  }
121
196
 
@@ -252,9 +327,9 @@ export class Oracle {
252
327
  }
253
328
 
254
329
  // eslint-disable-next-line camelcase
255
- async aztec_utl_tryGetPublicKeysAndPartialAddress([address]: ACVMField[]): Promise<(ACVMField | ACVMField[])[]> {
330
+ async aztec_utl_getPublicKeysAndPartialAddress([address]: ACVMField[]): Promise<(ACVMField | ACVMField[])[]> {
256
331
  const parsedAddress = AztecAddress.fromField(Fr.fromString(address));
257
- const result = await this.handlerAsUtility().tryGetPublicKeysAndPartialAddress(parsedAddress);
332
+ const result = await this.handlerAsUtility().getPublicKeysAndPartialAddress(parsedAddress);
258
333
 
259
334
  // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
260
335
  // with two fields: `some` (a boolean) and `value` (a field array in this case).
@@ -380,8 +455,8 @@ export class Oracle {
380
455
  }
381
456
 
382
457
  // eslint-disable-next-line camelcase
383
- async aztec_utl_checkNullifierExists([innerNullifier]: ACVMField[]): Promise<ACVMField[]> {
384
- const exists = await this.handlerAsUtility().checkNullifierExists(Fr.fromString(innerNullifier));
458
+ async aztec_utl_doesNullifierExist([innerNullifier]: ACVMField[]): Promise<ACVMField[]> {
459
+ const exists = await this.handlerAsUtility().doesNullifierExist(Fr.fromString(innerNullifier));
385
460
  return [toACVMField(exists)];
386
461
  }
387
462
 
@@ -400,13 +475,13 @@ export class Oracle {
400
475
  }
401
476
 
402
477
  // eslint-disable-next-line camelcase
403
- async aztec_utl_storageRead(
478
+ async aztec_utl_getFromPublicStorage(
404
479
  [blockHash]: ACVMField[],
405
480
  [contractAddress]: ACVMField[],
406
481
  [startStorageSlot]: ACVMField[],
407
482
  [numberOfElements]: ACVMField[],
408
483
  ): Promise<ACVMField[][]> {
409
- const values = await this.handlerAsUtility().storageRead(
484
+ const values = await this.handlerAsUtility().getFromPublicStorage(
410
485
  BlockHash.fromString(blockHash),
411
486
  new AztecAddress(Fr.fromString(contractAddress)),
412
487
  Fr.fromString(startStorageSlot),
@@ -464,8 +539,8 @@ export class Oracle {
464
539
  }
465
540
 
466
541
  // eslint-disable-next-line camelcase
467
- async aztec_prv_validatePublicCalldata([calldataHash]: ACVMField[]): Promise<ACVMField[]> {
468
- await this.handlerAsPrivate().validatePublicCalldata(Fr.fromString(calldataHash));
542
+ async aztec_prv_assertValidPublicCalldata([calldataHash]: ACVMField[]): Promise<ACVMField[]> {
543
+ await this.handlerAsPrivate().assertValidPublicCalldata(Fr.fromString(calldataHash));
469
544
  return [];
470
545
  }
471
546
 
@@ -476,8 +551,10 @@ export class Oracle {
476
551
  }
477
552
 
478
553
  // eslint-disable-next-line camelcase
479
- async aztec_prv_inRevertiblePhase([sideEffectCounter]: ACVMField[]): Promise<ACVMField[]> {
480
- const isRevertible = await this.handlerAsPrivate().inRevertiblePhase(Fr.fromString(sideEffectCounter).toNumber());
554
+ async aztec_prv_isExecutionInRevertiblePhase([sideEffectCounter]: ACVMField[]): Promise<ACVMField[]> {
555
+ const isRevertible = await this.handlerAsPrivate().isExecutionInRevertiblePhase(
556
+ Fr.fromString(sideEffectCounter).toNumber(),
557
+ );
481
558
  return Promise.resolve([toACVMField(isRevertible)]);
482
559
  }
483
560
 
@@ -491,11 +568,23 @@ export class Oracle {
491
568
  }
492
569
 
493
570
  // eslint-disable-next-line camelcase
494
- async aztec_utl_fetchTaggedLogs([pendingTaggedLogArrayBaseSlot]: ACVMField[]): Promise<ACVMField[]> {
495
- await this.handlerAsUtility().fetchTaggedLogs(Fr.fromString(pendingTaggedLogArrayBaseSlot));
571
+ async aztec_utl_getPendingTaggedLogs(
572
+ [pendingTaggedLogArrayBaseSlot]: ACVMField[],
573
+ [scope]: ACVMField[],
574
+ ): Promise<ACVMField[]> {
575
+ await this.handlerAsUtility().getPendingTaggedLogs(
576
+ Fr.fromString(pendingTaggedLogArrayBaseSlot),
577
+ AztecAddress.fromString(scope),
578
+ );
496
579
  return [];
497
580
  }
498
581
 
582
+ // eslint-disable-next-line camelcase
583
+ async aztec_utl_getPendingTaggedLogs_v2([scope]: ACVMField[]): Promise<ACVMField[]> {
584
+ const slot = await this.handlerAsUtility().getPendingTaggedLogsV2(AztecAddress.fromString(scope));
585
+ return [toACVMField(slot)];
586
+ }
587
+
499
588
  // eslint-disable-next-line camelcase
500
589
  async aztec_utl_validateAndStoreEnqueuedNotesAndEvents(
501
590
  [contractAddress]: ACVMField[],
@@ -503,6 +592,7 @@ export class Oracle {
503
592
  [eventValidationRequestsArrayBaseSlot]: ACVMField[],
504
593
  [maxNotePackedLen]: ACVMField[],
505
594
  [maxEventSerializedLen]: ACVMField[],
595
+ [scope]: ACVMField[],
506
596
  ): Promise<ACVMField[]> {
507
597
  await this.handlerAsUtility().validateAndStoreEnqueuedNotesAndEvents(
508
598
  AztecAddress.fromString(contractAddress),
@@ -510,62 +600,103 @@ export class Oracle {
510
600
  Fr.fromString(eventValidationRequestsArrayBaseSlot),
511
601
  Fr.fromString(maxNotePackedLen).toNumber(),
512
602
  Fr.fromString(maxEventSerializedLen).toNumber(),
603
+ AztecAddress.fromString(scope),
513
604
  );
514
605
 
515
606
  return [];
516
607
  }
517
608
 
518
609
  // eslint-disable-next-line camelcase
519
- async aztec_utl_bulkRetrieveLogs(
610
+ async aztec_utl_validateAndStoreEnqueuedNotesAndEvents_v2(
611
+ [noteValidationRequestsArrayBaseSlot]: ACVMField[],
612
+ [eventValidationRequestsArrayBaseSlot]: ACVMField[],
613
+ [maxNotePackedLen]: ACVMField[],
614
+ [maxEventSerializedLen]: ACVMField[],
615
+ [scope]: ACVMField[],
616
+ ): Promise<ACVMField[]> {
617
+ await this.handlerAsUtility().validateAndStoreEnqueuedNotesAndEventsV2(
618
+ Fr.fromString(noteValidationRequestsArrayBaseSlot),
619
+ Fr.fromString(eventValidationRequestsArrayBaseSlot),
620
+ Fr.fromString(maxNotePackedLen).toNumber(),
621
+ Fr.fromString(maxEventSerializedLen).toNumber(),
622
+ AztecAddress.fromString(scope),
623
+ );
624
+ return [];
625
+ }
626
+
627
+ // eslint-disable-next-line camelcase
628
+ async aztec_utl_getLogsByTag(
520
629
  [contractAddress]: ACVMField[],
521
630
  [logRetrievalRequestsArrayBaseSlot]: ACVMField[],
522
631
  [logRetrievalResponsesArrayBaseSlot]: ACVMField[],
632
+ [scope]: ACVMField[],
523
633
  ): Promise<ACVMField[]> {
524
- await this.handlerAsUtility().bulkRetrieveLogs(
634
+ await this.handlerAsUtility().getLogsByTag(
525
635
  AztecAddress.fromString(contractAddress),
526
636
  Fr.fromString(logRetrievalRequestsArrayBaseSlot),
527
637
  Fr.fromString(logRetrievalResponsesArrayBaseSlot),
638
+ AztecAddress.fromString(scope),
528
639
  );
529
640
  return [];
530
641
  }
531
642
 
532
643
  // eslint-disable-next-line camelcase
533
- async aztec_utl_utilityResolveMessageContexts(
644
+ async aztec_utl_getMessageContextsByTxHash(
534
645
  [contractAddress]: ACVMField[],
535
646
  [messageContextRequestsArrayBaseSlot]: ACVMField[],
536
647
  [messageContextResponsesArrayBaseSlot]: ACVMField[],
648
+ [scope]: ACVMField[],
537
649
  ): Promise<ACVMField[]> {
538
- await this.handlerAsUtility().utilityResolveMessageContexts(
650
+ await this.handlerAsUtility().getMessageContextsByTxHash(
539
651
  AztecAddress.fromString(contractAddress),
540
652
  Fr.fromString(messageContextRequestsArrayBaseSlot),
541
653
  Fr.fromString(messageContextResponsesArrayBaseSlot),
654
+ AztecAddress.fromString(scope),
542
655
  );
543
656
  return [];
544
657
  }
545
658
 
546
659
  // eslint-disable-next-line camelcase
547
- async aztec_utl_storeCapsule(
660
+ async aztec_utl_getLogsByTag_v2([requestArrayBaseSlot]: ACVMField[]): Promise<ACVMField[]> {
661
+ const responseSlot = await this.handlerAsUtility().getLogsByTagV2(Fr.fromString(requestArrayBaseSlot));
662
+ return [toACVMField(responseSlot)];
663
+ }
664
+
665
+ // eslint-disable-next-line camelcase
666
+ async aztec_utl_getMessageContextsByTxHash_v2([requestArrayBaseSlot]: ACVMField[]): Promise<ACVMField[]> {
667
+ const responseSlot = await this.handlerAsUtility().getMessageContextsByTxHashV2(
668
+ Fr.fromString(requestArrayBaseSlot),
669
+ );
670
+ return [toACVMField(responseSlot)];
671
+ }
672
+
673
+ // eslint-disable-next-line camelcase
674
+ aztec_utl_setCapsule(
548
675
  [contractAddress]: ACVMField[],
549
676
  [slot]: ACVMField[],
550
677
  capsule: ACVMField[],
678
+ [scope]: ACVMField[],
551
679
  ): Promise<ACVMField[]> {
552
- await this.handlerAsUtility().storeCapsule(
680
+ this.handlerAsUtility().setCapsule(
553
681
  AztecAddress.fromField(Fr.fromString(contractAddress)),
554
682
  Fr.fromString(slot),
555
683
  capsule.map(Fr.fromString),
684
+ AztecAddress.fromField(Fr.fromString(scope)),
556
685
  );
557
- return [];
686
+ return Promise.resolve([]);
558
687
  }
559
688
 
560
689
  // eslint-disable-next-line camelcase
561
- async aztec_utl_loadCapsule(
690
+ async aztec_utl_getCapsule(
562
691
  [contractAddress]: ACVMField[],
563
692
  [slot]: ACVMField[],
564
693
  [tSize]: ACVMField[],
694
+ [scope]: ACVMField[],
565
695
  ): Promise<(ACVMField | ACVMField[])[]> {
566
- const values = await this.handlerAsUtility().loadCapsule(
696
+ const values = await this.handlerAsUtility().getCapsule(
567
697
  AztecAddress.fromField(Fr.fromString(contractAddress)),
568
698
  Fr.fromString(slot),
699
+ AztecAddress.fromField(Fr.fromString(scope)),
569
700
  );
570
701
 
571
702
  // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
@@ -580,12 +711,17 @@ export class Oracle {
580
711
  }
581
712
 
582
713
  // eslint-disable-next-line camelcase
583
- async aztec_utl_deleteCapsule([contractAddress]: ACVMField[], [slot]: ACVMField[]): Promise<ACVMField[]> {
584
- await this.handlerAsUtility().deleteCapsule(
714
+ aztec_utl_deleteCapsule(
715
+ [contractAddress]: ACVMField[],
716
+ [slot]: ACVMField[],
717
+ [scope]: ACVMField[],
718
+ ): Promise<ACVMField[]> {
719
+ this.handlerAsUtility().deleteCapsule(
585
720
  AztecAddress.fromField(Fr.fromString(contractAddress)),
586
721
  Fr.fromString(slot),
722
+ AztecAddress.fromField(Fr.fromString(scope)),
587
723
  );
588
- return [];
724
+ return Promise.resolve([]);
589
725
  }
590
726
 
591
727
  // eslint-disable-next-line camelcase
@@ -594,19 +730,66 @@ export class Oracle {
594
730
  [srcSlot]: ACVMField[],
595
731
  [dstSlot]: ACVMField[],
596
732
  [numEntries]: ACVMField[],
733
+ [scope]: ACVMField[],
597
734
  ): Promise<ACVMField[]> {
598
735
  await this.handlerAsUtility().copyCapsule(
599
736
  AztecAddress.fromField(Fr.fromString(contractAddress)),
600
737
  Fr.fromString(srcSlot),
601
738
  Fr.fromString(dstSlot),
602
739
  Fr.fromString(numEntries).toNumber(),
740
+ AztecAddress.fromField(Fr.fromString(scope)),
603
741
  );
604
742
  return [];
605
743
  }
606
744
 
607
- // TODO(F-452): Return Option and wrap in try/catch so BB exceptions don't crash PXE.
608
745
  // eslint-disable-next-line camelcase
609
- async aztec_utl_aes128Decrypt(
746
+ aztec_utl_pushEphemeral([slot]: ACVMField[], elements: ACVMField[]): Promise<ACVMField[]> {
747
+ const newLen = this.handlerAsUtility().pushEphemeral(Fr.fromString(slot), elements.map(Fr.fromString));
748
+ return Promise.resolve([toACVMField(newLen)]);
749
+ }
750
+
751
+ // eslint-disable-next-line camelcase
752
+ aztec_utl_popEphemeral([slot]: ACVMField[]): Promise<ACVMField[][]> {
753
+ const element = this.handlerAsUtility().popEphemeral(Fr.fromString(slot));
754
+ return Promise.resolve([element.map(toACVMField)]);
755
+ }
756
+
757
+ // eslint-disable-next-line camelcase
758
+ aztec_utl_getEphemeral([slot]: ACVMField[], [index]: ACVMField[]): Promise<ACVMField[][]> {
759
+ const element = this.handlerAsUtility().getEphemeral(Fr.fromString(slot), Fr.fromString(index).toNumber());
760
+ return Promise.resolve([element.map(toACVMField)]);
761
+ }
762
+
763
+ // eslint-disable-next-line camelcase
764
+ aztec_utl_setEphemeral([slot]: ACVMField[], [index]: ACVMField[], elements: ACVMField[]): Promise<ACVMField[]> {
765
+ this.handlerAsUtility().setEphemeral(
766
+ Fr.fromString(slot),
767
+ Fr.fromString(index).toNumber(),
768
+ elements.map(Fr.fromString),
769
+ );
770
+ return Promise.resolve([]);
771
+ }
772
+
773
+ // eslint-disable-next-line camelcase
774
+ aztec_utl_getEphemeralLen([slot]: ACVMField[]): Promise<ACVMField[]> {
775
+ const len = this.handlerAsUtility().getEphemeralLen(Fr.fromString(slot));
776
+ return Promise.resolve([toACVMField(len)]);
777
+ }
778
+
779
+ // eslint-disable-next-line camelcase
780
+ aztec_utl_removeEphemeral([slot]: ACVMField[], [index]: ACVMField[]): Promise<ACVMField[]> {
781
+ this.handlerAsUtility().removeEphemeral(Fr.fromString(slot), Fr.fromString(index).toNumber());
782
+ return Promise.resolve([]);
783
+ }
784
+
785
+ // eslint-disable-next-line camelcase
786
+ aztec_utl_clearEphemeral([slot]: ACVMField[]): Promise<ACVMField[]> {
787
+ this.handlerAsUtility().clearEphemeral(Fr.fromString(slot));
788
+ return Promise.resolve([]);
789
+ }
790
+
791
+ // eslint-disable-next-line camelcase
792
+ async aztec_utl_decryptAes128(
610
793
  ciphertextBVecStorage: ACVMField[],
611
794
  [ciphertextLength]: ACVMField[],
612
795
  iv: ACVMField[],
@@ -616,8 +799,15 @@ export class Oracle {
616
799
  const ivBuffer = fromUintArray(iv, 8);
617
800
  const symKeyBuffer = fromUintArray(symKey, 8);
618
801
 
619
- const plaintext = await this.handlerAsUtility().aes128Decrypt(ciphertext, ivBuffer, symKeyBuffer);
620
- return bufferToBoundedVec(plaintext, ciphertextBVecStorage.length);
802
+ // Noir Option<BoundedVec> is encoded as [is_some: Field, storage: Field[], length: Field].
803
+ try {
804
+ const plaintext = await this.handlerAsUtility().decryptAes128(ciphertext, ivBuffer, symKeyBuffer);
805
+ const [storage, length] = bufferToBoundedVec(plaintext, ciphertextBVecStorage.length);
806
+ return [toACVMField(1), storage, length];
807
+ } catch {
808
+ const zeroStorage = Array(ciphertextBVecStorage.length).fill(toACVMField(0));
809
+ return [toACVMField(0), zeroStorage, toACVMField(0)];
810
+ }
621
811
  }
622
812
 
623
813
  // eslint-disable-next-line camelcase
@@ -626,12 +816,28 @@ export class Oracle {
626
816
  [ephPKField0]: ACVMField[],
627
817
  [ephPKField1]: ACVMField[],
628
818
  [ephPKField2]: ACVMField[],
819
+ [contractAddress]: ACVMField[],
629
820
  ): Promise<ACVMField[]> {
630
821
  const secret = await this.handlerAsUtility().getSharedSecret(
631
822
  AztecAddress.fromField(Fr.fromString(address)),
632
823
  Point.fromFields([ephPKField0, ephPKField1, ephPKField2].map(Fr.fromString)),
824
+ AztecAddress.fromField(Fr.fromString(contractAddress)),
633
825
  );
634
- return secret.toFields().map(toACVMField);
826
+ return [toACVMField(secret)];
827
+ }
828
+
829
+ // eslint-disable-next-line camelcase
830
+ aztec_utl_setContractSyncCacheInvalid(
831
+ [contractAddress]: ACVMField[],
832
+ scopes: ACVMField[],
833
+ [scopeCount]: ACVMField[],
834
+ ): Promise<ACVMField[]> {
835
+ const scopeAddresses = scopes.slice(0, +scopeCount).map(s => AztecAddress.fromField(Fr.fromString(s)));
836
+ this.handlerAsUtility().setContractSyncCacheInvalid(
837
+ AztecAddress.fromField(Fr.fromString(contractAddress)),
838
+ scopeAddresses,
839
+ );
840
+ return Promise.resolve([]);
635
841
  }
636
842
 
637
843
  // eslint-disable-next-line camelcase
@@ -76,7 +76,7 @@ export async function executePrivateFunction(
76
76
 
77
77
  const contractClassLogs = privateExecutionOracle.getContractClassLogs();
78
78
 
79
- const rawReturnValues = await privateExecutionOracle.loadFromExecutionCache(publicInputs.returnsHash);
79
+ const rawReturnValues = await privateExecutionOracle.getHashPreimage(publicInputs.returnsHash);
80
80
 
81
81
  const newNotes = privateExecutionOracle.getNewNotes();
82
82
  const noteHashNullifierCounterMap = privateExecutionOracle.getNoteHashNullifierCounterMap();
@@ -25,8 +25,6 @@ import {
25
25
  type TxContext,
26
26
  } from '@aztec/stdlib/tx';
27
27
 
28
- import type { AccessScopes } from '../../access_scopes.js';
29
- import type { ContractSyncService } from '../../contract_sync/contract_sync_service.js';
30
28
  import { NoteService } from '../../notes/note_service.js';
31
29
  import type { SenderTaggingStore } from '../../storage/tagging_store/sender_tagging_store.js';
32
30
  import { syncSenderTaggingIndexes } from '../../tagging/index.js';
@@ -44,12 +42,11 @@ export type PrivateExecutionOracleArgs = Omit<UtilityExecutionOracleArgs, 'contr
44
42
  txContext: TxContext;
45
43
  callContext: CallContext;
46
44
  /** Needed to trigger contract synchronization before nested calls */
47
- utilityExecutor: (call: FunctionCall, scopes: AccessScopes) => Promise<void>;
45
+ utilityExecutor: (call: FunctionCall, scopes: AztecAddress[]) => Promise<void>;
48
46
  executionCache: HashedValuesCache;
49
47
  noteCache: ExecutionNoteCache;
50
48
  taggingIndexCache: ExecutionTaggingIndexCache;
51
49
  senderTaggingStore: SenderTaggingStore;
52
- contractSyncService: ContractSyncService;
53
50
  totalPublicCalldataCount?: number;
54
51
  sideEffectCounter?: number;
55
52
  senderForTags?: AztecAddress;
@@ -78,12 +75,11 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
78
75
  private readonly argsHash: Fr;
79
76
  private readonly txContext: TxContext;
80
77
  private readonly callContext: CallContext;
81
- private readonly utilityExecutor: (call: FunctionCall, scopes: AccessScopes) => Promise<void>;
78
+ private readonly utilityExecutor: (call: FunctionCall, scopes: AztecAddress[]) => Promise<void>;
82
79
  private readonly executionCache: HashedValuesCache;
83
80
  private readonly noteCache: ExecutionNoteCache;
84
81
  private readonly taggingIndexCache: ExecutionTaggingIndexCache;
85
82
  private readonly senderTaggingStore: SenderTaggingStore;
86
- private readonly contractSyncService: ContractSyncService;
87
83
  private totalPublicCalldataCount: number;
88
84
  protected sideEffectCounter: number;
89
85
  private senderForTags?: AztecAddress;
@@ -103,7 +99,6 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
103
99
  this.noteCache = args.noteCache;
104
100
  this.taggingIndexCache = args.taggingIndexCache;
105
101
  this.senderTaggingStore = args.senderTaggingStore;
106
- this.contractSyncService = args.contractSyncService;
107
102
  this.totalPublicCalldataCount = args.totalPublicCalldataCount ?? 0;
108
103
  this.sideEffectCounter = args.sideEffectCounter ?? 0;
109
104
  this.senderForTags = args.senderForTags;
@@ -214,6 +209,16 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
214
209
  recipient,
215
210
  );
216
211
 
212
+ if (!extendedSecret) {
213
+ // We'd only fail to compute an extended secret if the recipient is an invalid address. To prevent
214
+ // king-of-the-hill attacks, instead of failing we use a random tag. By including a correct-looking tag in the
215
+ // log, the transaction shape is preserved and no privacy is leaked, even if the tag is bogus.
216
+ this.logger.warn(`Computing a tag for invalid recipient ${recipient} - returning a random tag instead`, {
217
+ contractAddress: this.contractAddress,
218
+ });
219
+ return new Tag(Fr.random());
220
+ }
221
+
217
222
  const index = await this.#getIndexToUseForSecret(extendedSecret);
218
223
  this.logger.debug(
219
224
  `Incrementing tagging index for sender: ${sender}, recipient: ${recipient}, contract: ${this.contractAddress} to ${index}`,
@@ -269,7 +274,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
269
274
  * @param values - Values to store.
270
275
  * @returns The hash of the values.
271
276
  */
272
- public storeInExecutionCache(values: Fr[], hash: Fr) {
277
+ public setHashPreimage(values: Fr[], hash: Fr) {
273
278
  return this.executionCache.store(values, hash);
274
279
  }
275
280
 
@@ -278,7 +283,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
278
283
  * @param hash - Hash of the values.
279
284
  * @returns The values.
280
285
  */
281
- public loadFromExecutionCache(hash: Fr): Promise<Fr[]> {
286
+ public getHashPreimage(hash: Fr): Promise<Fr[]> {
282
287
  const preimage = this.executionCache.getPreimage(hash);
283
288
  if (!preimage) {
284
289
  throw new Error(`Preimage for hash ${hash.toString()} not found in cache`);
@@ -286,7 +291,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
286
291
  return Promise.resolve(preimage);
287
292
  }
288
293
 
289
- override async checkNullifierExists(innerNullifier: Fr): Promise<boolean> {
294
+ override async doesNullifierExist(innerNullifier: Fr): Promise<boolean> {
290
295
  // This oracle must be overridden because while utility execution can only meaningfully check if a nullifier exists
291
296
  // in the synched block, during private execution there's also the possibility of it being pending, i.e. created
292
297
  // in the current transaction.
@@ -299,7 +304,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
299
304
 
300
305
  return (
301
306
  this.noteCache.getNullifiers(this.contractAddress).has(nullifier) ||
302
- (await super.checkNullifierExists(innerNullifier))
307
+ (await super.doesNullifierExist(innerNullifier))
303
308
  );
304
309
  }
305
310
 
@@ -559,7 +564,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
559
564
  senderTaggingStore: this.senderTaggingStore,
560
565
  recipientTaggingStore: this.recipientTaggingStore,
561
566
  senderAddressBookStore: this.senderAddressBookStore,
562
- capsuleStore: this.capsuleStore,
567
+ capsuleService: this.capsuleService,
563
568
  privateEventStore: this.privateEventStore,
564
569
  messageContextService: this.messageContextService,
565
570
  contractSyncService: this.contractSyncService,
@@ -602,7 +607,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
602
607
  }
603
608
 
604
609
  /** Validates the calldata preimage exists in the cache and checks cumulative calldata size is within limits. */
605
- public validatePublicCalldata(calldataHash: Fr) {
610
+ public assertValidPublicCalldata(calldataHash: Fr) {
606
611
  const calldata = this.executionCache.getPreimage(calldataHash);
607
612
  if (!calldata) {
608
613
  throw new Error('Calldata for public call not found in cache');
@@ -619,7 +624,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
619
624
  return this.noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
620
625
  }
621
626
 
622
- public inRevertiblePhase(sideEffectCounter: number): Promise<boolean> {
627
+ public isExecutionInRevertiblePhase(sideEffectCounter: number): Promise<boolean> {
623
628
  return Promise.resolve(this.noteCache.isSideEffectCounterRevertible(sideEffectCounter));
624
629
  }
625
630