@aztec/pxe 5.0.0-rc.2 → 5.0.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 (188) hide show
  1. package/dest/block_synchronizer/block_synchronizer.d.ts +5 -3
  2. package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
  3. package/dest/block_synchronizer/block_synchronizer.js +7 -1
  4. package/dest/contract/contract_class_service.d.ts +31 -0
  5. package/dest/contract/contract_class_service.d.ts.map +1 -0
  6. package/dest/contract/contract_class_service.js +68 -0
  7. package/dest/{contract_sync → contract}/contract_sync_service.d.ts +7 -6
  8. package/dest/contract/contract_sync_service.d.ts.map +1 -0
  9. package/dest/{contract_sync → contract}/contract_sync_service.js +10 -30
  10. package/dest/contract/helpers.d.ts +7 -0
  11. package/dest/contract/helpers.d.ts.map +1 -0
  12. package/dest/contract/helpers.js +20 -0
  13. package/dest/contract_function_simulator/anchored_contract_data.d.ts +36 -0
  14. package/dest/contract_function_simulator/anchored_contract_data.d.ts.map +1 -0
  15. package/dest/contract_function_simulator/anchored_contract_data.js +54 -0
  16. package/dest/contract_function_simulator/aztec_node_read_cache.d.ts +39 -0
  17. package/dest/contract_function_simulator/aztec_node_read_cache.d.ts.map +1 -0
  18. package/dest/contract_function_simulator/aztec_node_read_cache.js +60 -0
  19. package/dest/contract_function_simulator/contract_function_simulator.d.ts +9 -3
  20. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  21. package/dest/contract_function_simulator/contract_function_simulator.js +31 -14
  22. package/dest/contract_function_simulator/execution_note_cache.d.ts +3 -9
  23. package/dest/contract_function_simulator/execution_note_cache.d.ts.map +1 -1
  24. package/dest/contract_function_simulator/execution_note_cache.js +8 -28
  25. package/dest/contract_function_simulator/index.d.ts +4 -2
  26. package/dest/contract_function_simulator/index.d.ts.map +1 -1
  27. package/dest/contract_function_simulator/index.js +2 -1
  28. package/dest/contract_function_simulator/noir-structs/fact.d.ts +5 -5
  29. package/dest/contract_function_simulator/noir-structs/fact.d.ts.map +1 -1
  30. package/dest/contract_function_simulator/noir-structs/fact.js +2 -2
  31. package/dest/contract_function_simulator/noir-structs/fact_collection.d.ts +3 -3
  32. package/dest/contract_function_simulator/noir-structs/fact_collection.d.ts.map +1 -1
  33. package/dest/contract_function_simulator/noir-structs/fact_collection.js +3 -1
  34. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +7 -1
  35. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts.map +1 -1
  36. package/dest/contract_function_simulator/noir-structs/pending_tagged_log.d.ts +11 -0
  37. package/dest/contract_function_simulator/noir-structs/pending_tagged_log.d.ts.map +1 -0
  38. package/dest/contract_function_simulator/noir-structs/pending_tagged_log.js +4 -0
  39. package/dest/contract_function_simulator/noir-structs/provided_secret.d.ts +2 -2
  40. package/dest/contract_function_simulator/noir-structs/provided_secret.d.ts.map +1 -1
  41. package/dest/contract_function_simulator/noir-structs/provided_secret.js +1 -1
  42. package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.d.ts +8 -1
  43. package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.d.ts.map +1 -1
  44. package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.js +17 -0
  45. package/dest/contract_function_simulator/oracle/acir_callback.d.ts +7 -2
  46. package/dest/contract_function_simulator/oracle/acir_callback.d.ts.map +1 -1
  47. package/dest/contract_function_simulator/oracle/acir_callback.js +55 -11
  48. package/dest/contract_function_simulator/oracle/legacy_oracle_registry.d.ts +39 -0
  49. package/dest/contract_function_simulator/oracle/legacy_oracle_registry.d.ts.map +1 -0
  50. package/dest/contract_function_simulator/oracle/legacy_oracle_registry.js +107 -0
  51. package/dest/contract_function_simulator/oracle/oracle_registry.d.ts +10 -7
  52. package/dest/contract_function_simulator/oracle/oracle_registry.d.ts.map +1 -1
  53. package/dest/contract_function_simulator/oracle/oracle_registry.js +41 -10
  54. package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts +48 -9
  55. package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts.map +1 -1
  56. package/dest/contract_function_simulator/oracle/oracle_type_mappings.js +51 -30
  57. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +10 -2
  58. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  59. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +73 -32
  60. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +20 -16
  61. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  62. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +68 -47
  63. package/dest/debug/pxe_debug_utils.d.ts +2 -2
  64. package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
  65. package/dest/entrypoints/client/bundle/utils.js +2 -2
  66. package/dest/entrypoints/client/lazy/utils.js +2 -2
  67. package/dest/entrypoints/server/index.d.ts +5 -2
  68. package/dest/entrypoints/server/index.d.ts.map +1 -1
  69. package/dest/entrypoints/server/index.js +3 -1
  70. package/dest/error_enriching.d.ts +5 -3
  71. package/dest/error_enriching.d.ts.map +1 -1
  72. package/dest/error_enriching.js +12 -10
  73. package/dest/hooks/execution_hooks.d.ts +15 -4
  74. package/dest/hooks/execution_hooks.d.ts.map +1 -1
  75. package/dest/hooks/index.d.ts +3 -2
  76. package/dest/hooks/index.d.ts.map +1 -1
  77. package/dest/hooks/index.js +1 -0
  78. package/dest/hooks/resolve_custom_request.d.ts +23 -0
  79. package/dest/hooks/resolve_custom_request.d.ts.map +1 -0
  80. package/dest/hooks/resolve_custom_request.js +3 -0
  81. package/dest/hooks/resolve_tagging_secret_strategy.d.ts +10 -1
  82. package/dest/hooks/resolve_tagging_secret_strategy.d.ts.map +1 -1
  83. package/dest/hooks/resolve_tagging_secret_strategy.js +3 -3
  84. package/dest/logs/log_service.d.ts +3 -2
  85. package/dest/logs/log_service.d.ts.map +1 -1
  86. package/dest/logs/log_service.js +33 -16
  87. package/dest/oracle_version.d.ts +2 -2
  88. package/dest/oracle_version.js +2 -2
  89. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts +1 -1
  90. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts.map +1 -1
  91. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.js +6 -2
  92. package/dest/private_kernel/private_kernel_execution_prover.d.ts +1 -1
  93. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
  94. package/dest/private_kernel/private_kernel_execution_prover.js +17 -36
  95. package/dest/private_kernel/private_kernel_oracle.d.ts +4 -2
  96. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
  97. package/dest/private_kernel/private_kernel_oracle.js +17 -5
  98. package/dest/pxe.d.ts +81 -46
  99. package/dest/pxe.d.ts.map +1 -1
  100. package/dest/pxe.js +135 -104
  101. package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts +1 -1
  102. package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts.map +1 -1
  103. package/dest/storage/backwards_compatibility_tests/schema_tests.js +31 -7
  104. package/dest/storage/contract_store/contract_store.d.ts +27 -24
  105. package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
  106. package/dest/storage/contract_store/contract_store.js +63 -74
  107. package/dest/storage/fact_store/fact_service.d.ts +6 -4
  108. package/dest/storage/fact_store/fact_service.d.ts.map +1 -1
  109. package/dest/storage/fact_store/fact_service.js +19 -4
  110. package/dest/storage/fact_store/fact_store.d.ts +1 -1
  111. package/dest/storage/fact_store/fact_store.js +1 -1
  112. package/dest/storage/fact_store/index.d.ts +2 -1
  113. package/dest/storage/fact_store/index.d.ts.map +1 -1
  114. package/dest/storage/fact_store/index.js +1 -0
  115. package/dest/storage/fact_store/origin_state.d.ts +57 -0
  116. package/dest/storage/fact_store/origin_state.d.ts.map +1 -0
  117. package/dest/storage/fact_store/origin_state.js +53 -0
  118. package/dest/storage/metadata.d.ts +2 -2
  119. package/dest/storage/metadata.d.ts.map +1 -1
  120. package/dest/storage/metadata.js +1 -1
  121. package/dest/storage/tagging_store/tagging_secret_sources_store.d.ts +17 -6
  122. package/dest/storage/tagging_store/tagging_secret_sources_store.d.ts.map +1 -1
  123. package/dest/storage/tagging_store/tagging_secret_sources_store.js +24 -11
  124. package/dest/tagging/constants.d.ts +2 -2
  125. package/dest/tagging/constants.d.ts.map +1 -1
  126. package/dest/tagging/constants.js +18 -9
  127. package/package.json +17 -17
  128. package/src/block_synchronizer/block_synchronizer.ts +9 -1
  129. package/src/contract/contract_class_service.ts +83 -0
  130. package/src/{contract_sync → contract}/contract_sync_service.ts +18 -37
  131. package/src/contract/helpers.ts +35 -0
  132. package/src/contract_function_simulator/anchored_contract_data.ts +74 -0
  133. package/src/contract_function_simulator/aztec_node_read_cache.ts +89 -0
  134. package/src/contract_function_simulator/contract_function_simulator.ts +56 -14
  135. package/src/contract_function_simulator/execution_note_cache.ts +7 -28
  136. package/src/contract_function_simulator/index.ts +7 -1
  137. package/src/contract_function_simulator/noir-structs/fact.ts +4 -4
  138. package/src/contract_function_simulator/noir-structs/fact_collection.ts +9 -4
  139. package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +6 -0
  140. package/src/contract_function_simulator/noir-structs/pending_tagged_log.ts +12 -0
  141. package/src/contract_function_simulator/noir-structs/provided_secret.ts +1 -1
  142. package/src/contract_function_simulator/noir-structs/resolved_tagging_strategy.ts +21 -0
  143. package/src/contract_function_simulator/oracle/acir_callback.ts +58 -12
  144. package/src/contract_function_simulator/oracle/legacy_oracle_registry.ts +147 -0
  145. package/src/contract_function_simulator/oracle/oracle_registry.ts +32 -7
  146. package/src/contract_function_simulator/oracle/oracle_type_mappings.ts +49 -32
  147. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +92 -41
  148. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +104 -59
  149. package/src/debug/pxe_debug_utils.ts +1 -1
  150. package/src/entrypoints/client/bundle/utils.ts +2 -2
  151. package/src/entrypoints/client/lazy/utils.ts +2 -2
  152. package/src/entrypoints/server/index.ts +5 -1
  153. package/src/error_enriching.ts +26 -10
  154. package/src/hooks/execution_hooks.ts +14 -3
  155. package/src/hooks/index.ts +2 -0
  156. package/src/hooks/resolve_custom_request.ts +24 -0
  157. package/src/hooks/resolve_tagging_secret_strategy.ts +14 -0
  158. package/src/logs/log_service.ts +31 -11
  159. package/src/oracle_version.ts +2 -2
  160. package/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +11 -1
  161. package/src/private_kernel/private_kernel_execution_prover.ts +22 -52
  162. package/src/private_kernel/private_kernel_oracle.ts +23 -4
  163. package/src/pxe.ts +209 -143
  164. package/src/storage/backwards_compatibility_tests/__snapshots__/AddressStore.json +6 -6
  165. package/src/storage/backwards_compatibility_tests/__snapshots__/ContractStore.json +1 -1
  166. package/src/storage/backwards_compatibility_tests/__snapshots__/KeyStore.json +12 -12
  167. package/src/storage/backwards_compatibility_tests/__snapshots__/RecipientTaggingStore.json +11 -3
  168. package/src/storage/backwards_compatibility_tests/__snapshots__/SenderTaggingStore.json +12 -4
  169. package/src/storage/backwards_compatibility_tests/__snapshots__/TaggingSecretSourcesStore.json +3 -3
  170. package/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json +1 -1
  171. package/src/storage/backwards_compatibility_tests/schema_tests.ts +38 -4
  172. package/src/storage/contract_store/contract_store.ts +85 -92
  173. package/src/storage/fact_store/fact_service.ts +29 -5
  174. package/src/storage/fact_store/fact_store.ts +1 -1
  175. package/src/storage/fact_store/index.ts +10 -0
  176. package/src/storage/fact_store/origin_state.ts +75 -0
  177. package/src/storage/metadata.ts +1 -1
  178. package/src/storage/tagging_store/tagging_secret_sources_store.ts +36 -15
  179. package/src/tagging/constants.ts +19 -9
  180. package/dest/contract_function_simulator/proxied_contract_data_source.d.ts +0 -6
  181. package/dest/contract_function_simulator/proxied_contract_data_source.d.ts.map +0 -1
  182. package/dest/contract_function_simulator/proxied_contract_data_source.js +0 -51
  183. package/dest/contract_sync/contract_sync_service.d.ts.map +0 -1
  184. package/dest/contract_sync/helpers.d.ts +0 -28
  185. package/dest/contract_sync/helpers.d.ts.map +0 -1
  186. package/dest/contract_sync/helpers.js +0 -48
  187. package/src/contract_function_simulator/proxied_contract_data_source.ts +0 -60
  188. package/src/contract_sync/helpers.ts +0 -79
@@ -0,0 +1,89 @@
1
+ import { Fr } from '@aztec/foundation/curves/bn254';
2
+ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
3
+ import type { BlockHash, BlockParameter } from '@aztec/stdlib/block';
4
+ import type { AztecNode } from '@aztec/stdlib/interfaces/server';
5
+ import type { TxHash } from '@aztec/stdlib/tx';
6
+
7
+ /**
8
+ * Per-execution cache for immutable Aztec node reads.
9
+ */
10
+ export class AztecNodeReadCache {
11
+ private readonly cache = new Map<string, Promise<unknown>>();
12
+
13
+ constructor(private readonly aztecNode: AztecNode) {}
14
+
15
+ /** Fetches a block without reissuing the same node request. */
16
+ public getBlock(block: BlockParameter) {
17
+ return this.#cachedRead(`block:${this.#keyPart(block)}`, () => this.aztecNode.getBlock(block));
18
+ }
19
+
20
+ /** Fetches a transaction receipt with its effect attached. */
21
+ public getTxReceiptWithEffect(txHash: TxHash) {
22
+ return this.#cachedRead(`tx-receipt-with-effect:${txHash.toString()}`, () =>
23
+ this.aztecNode.getTxReceipt(txHash, { includeTxEffect: true } as const),
24
+ );
25
+ }
26
+
27
+ /** Fetches an archive-tree witness for a block hash. */
28
+ public getBlockHashMembershipWitness(referenceBlock: BlockParameter, blockHash: BlockHash) {
29
+ return this.#cachedRead(
30
+ `block-hash-membership-witness:${this.#keyPart(referenceBlock)}:${blockHash.toString()}`,
31
+ () => this.aztecNode.getBlockHashMembershipWitness(referenceBlock, blockHash),
32
+ );
33
+ }
34
+
35
+ /** Fetches a public-data-tree witness for a leaf slot. */
36
+ public getPublicDataWitness(referenceBlock: BlockParameter, leafSlot: Fr) {
37
+ return this.#cachedRead(`public-data-witness:${this.#keyPart(referenceBlock)}:${leafSlot.toString()}`, () =>
38
+ this.aztecNode.getPublicDataWitness(referenceBlock, leafSlot),
39
+ );
40
+ }
41
+
42
+ /** Fetches public storage for a single slot. */
43
+ public getPublicStorageAt(referenceBlock: BlockParameter, contractAddress: AztecAddress, storageSlot: Fr) {
44
+ return this.#cachedRead(
45
+ `public-storage:${this.#keyPart(referenceBlock)}:${contractAddress.toString()}:${storageSlot.toString()}`,
46
+ () => this.aztecNode.getPublicStorageAt(referenceBlock, contractAddress, storageSlot),
47
+ );
48
+ }
49
+
50
+ /** Fetches a contiguous public storage range, reusing cached reads for overlapping slots. */
51
+ public getPublicStorageRange(
52
+ referenceBlock: BlockParameter,
53
+ contractAddress: AztecAddress,
54
+ startStorageSlot: Fr,
55
+ numberOfElements: number,
56
+ ) {
57
+ const slots = Array(numberOfElements)
58
+ .fill(0)
59
+ .map((_, i) => new Fr(startStorageSlot.value + BigInt(i)));
60
+
61
+ return Promise.all(slots.map(storageSlot => this.getPublicStorageAt(referenceBlock, contractAddress, storageSlot)));
62
+ }
63
+
64
+ #cachedRead<T>(key: string, fetch: () => Promise<T>): Promise<T> {
65
+ const cached = this.cache.get(key);
66
+ if (cached) {
67
+ return cached as Promise<T>;
68
+ }
69
+
70
+ const promise = fetch();
71
+ promise.catch(() => this.cache.delete(key));
72
+ this.cache.set(key, promise);
73
+ return promise;
74
+ }
75
+
76
+ #keyPart(value: unknown): string {
77
+ if (['string', 'number', 'bigint', 'boolean'].includes(typeof value)) {
78
+ return String(value);
79
+ }
80
+ if (value && typeof value === 'object') {
81
+ const toString = (value as { toString?: () => string }).toString;
82
+ if (toString && toString !== Object.prototype.toString) {
83
+ return toString.call(value);
84
+ }
85
+ return JSON.stringify(value, (_key, nested) => (typeof nested === 'bigint' ? nested.toString() : nested));
86
+ }
87
+ return String(value);
88
+ }
89
+ }
@@ -19,6 +19,7 @@ import {
19
19
  MAX_PRIVATE_LOGS_PER_TX,
20
20
  MAX_TX_LIFETIME,
21
21
  PRIVATE_TX_L2_GAS_OVERHEAD,
22
+ PUBLIC_DATA_WRITE_LENGTH,
22
23
  PUBLIC_TX_L2_GAS_OVERHEAD,
23
24
  TX_DA_GAS_OVERHEAD,
24
25
  } from '@aztec/constants';
@@ -80,6 +81,7 @@ import { MerkleTreeId } from '@aztec/stdlib/trees';
80
81
  import {
81
82
  BlockHeader,
82
83
  CallContext,
84
+ type ContractOverrides,
83
85
  HashedValues,
84
86
  type OffchainEffect,
85
87
  PrivateExecutionResult,
@@ -90,7 +92,8 @@ import {
90
92
  getFinalMinRevertibleSideEffectCounter,
91
93
  } from '@aztec/stdlib/tx';
92
94
 
93
- import type { ContractSyncService } from '../contract_sync/contract_sync_service.js';
95
+ import type { ContractClassService } from '../contract/contract_class_service.js';
96
+ import type { ContractSyncService } from '../contract/contract_sync_service.js';
94
97
  import type { ExecutionHooks } from '../hooks/index.js';
95
98
  import type { TxResolverService } from '../messages/tx_resolver_service.js';
96
99
  import type { AddressStore } from '../storage/address_store/address_store.js';
@@ -104,6 +107,7 @@ import type { PrivateEventStore } from '../storage/private_event_store/private_e
104
107
  import type { RecipientTaggingStore } from '../storage/tagging_store/recipient_tagging_store.js';
105
108
  import type { SenderTaggingStore } from '../storage/tagging_store/sender_tagging_store.js';
106
109
  import type { TaggingSecretSourcesStore } from '../storage/tagging_store/tagging_secret_sources_store.js';
110
+ import { AnchoredContractData } from './anchored_contract_data.js';
107
111
  import type { BenchmarkedNode } from './benchmarked_node.js';
108
112
  import { ExecutionNoteCache } from './execution_note_cache.js';
109
113
  import { ExecutionTaggingIndexCache } from './execution_tagging_index_cache.js';
@@ -131,6 +135,9 @@ export type ContractSimulatorRunOpts = {
131
135
  /** Args for ContractFunctionSimulator constructor. */
132
136
  export type ContractFunctionSimulatorArgs = {
133
137
  contractStore: ContractStore;
138
+ contractClassService: ContractClassService;
139
+ /** Per-simulation contract overrides. */
140
+ overrides?: ContractOverrides;
134
141
  noteStore: NoteStore;
135
142
  keyStore: KeyStore;
136
143
  addressStore: AddressStore;
@@ -154,6 +161,8 @@ export type ContractFunctionSimulatorArgs = {
154
161
  export class ContractFunctionSimulator {
155
162
  private readonly log: Logger;
156
163
  private readonly contractStore: ContractStore;
164
+ private readonly contractClassService: ContractClassService;
165
+ private readonly overrides: ContractOverrides | undefined;
157
166
  private readonly noteStore: NoteStore;
158
167
  private readonly keyStore: KeyStore;
159
168
  private readonly addressStore: AddressStore;
@@ -172,6 +181,8 @@ export class ContractFunctionSimulator {
172
181
 
173
182
  constructor(args: ContractFunctionSimulatorArgs) {
174
183
  this.contractStore = args.contractStore;
184
+ this.contractClassService = args.contractClassService;
185
+ this.overrides = args.overrides;
175
186
  this.noteStore = args.noteStore;
176
187
  this.keyStore = args.keyStore;
177
188
  this.addressStore = args.addressStore;
@@ -208,10 +219,23 @@ export class ContractFunctionSimulator {
208
219
 
209
220
  const contractAddress = request.origin;
210
221
 
211
- const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(
222
+ const anchoredContractData = new AnchoredContractData(
223
+ this.contractStore,
224
+ this.contractClassService,
225
+ anchorBlockHeader,
226
+ this.overrides,
227
+ );
228
+
229
+ const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(
212
230
  contractAddress,
213
231
  request.functionSelector,
214
232
  );
233
+ if (!entryPointArtifact) {
234
+ throw new Error(
235
+ `Cannot run function ${request.functionSelector} on ${contractAddress}: the contract is not registered. ` +
236
+ `Register it via wallet.registerContract(...).`,
237
+ );
238
+ }
215
239
 
216
240
  if (entryPointArtifact.functionType !== FunctionType.PRIVATE) {
217
241
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as private`);
@@ -239,6 +263,7 @@ export class ContractFunctionSimulator {
239
263
  const privateExecutionOracle = new PrivateExecutionOracle({
240
264
  argsHash: request.firstCallArgsHash,
241
265
  txContext: request.txContext,
266
+ txRequestSalt: request.salt,
242
267
  callContext,
243
268
  anchorBlockHeader,
244
269
  utilityExecutor: async (call, execScopes) => {
@@ -249,7 +274,7 @@ export class ContractFunctionSimulator {
249
274
  executionCache: HashedValuesCache.create(request.argsOfCalls),
250
275
  noteCache,
251
276
  taggingIndexCache,
252
- contractStore: this.contractStore,
277
+ anchoredContractData,
253
278
  noteStore: this.noteStore,
254
279
  keyStore: this.keyStore,
255
280
  addressStore: this.addressStore,
@@ -289,8 +314,7 @@ export class ContractFunctionSimulator {
289
314
  );
290
315
  const simulatorTeardownTimer = new Timer();
291
316
 
292
- noteCache.finish();
293
- const firstNullifierHint = noteCache.getNonceGenerator();
317
+ const firstNullifier = noteCache.getNonceGenerator();
294
318
 
295
319
  const publicCallRequests = collectNested([executionResult], r =>
296
320
  r.publicInputs.publicCallRequests
@@ -313,9 +337,9 @@ export class ContractFunctionSimulator {
313
337
  }
314
338
 
315
339
  // Not to be confused with a PrivateCallExecutionResult. This is a superset
316
- // of the PrivateCallExecutionResult, containing also firstNullifierHint
340
+ // of the PrivateCallExecutionResult, containing also firstNullifier
317
341
  // and publicFunctionsCalldata.
318
- return new PrivateExecutionResult(executionResult, firstNullifierHint, publicFunctionsCalldata);
342
+ return new PrivateExecutionResult(executionResult, firstNullifier, publicFunctionsCalldata);
319
343
  } catch (err) {
320
344
  throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
321
345
  }
@@ -333,7 +357,20 @@ export class ContractFunctionSimulator {
333
357
  scopes: AztecAddress[],
334
358
  jobId: string,
335
359
  ): Promise<{ result: Fr[]; offchainEffects: OffchainEffect[] }> {
336
- const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
360
+ const anchoredContractData = new AnchoredContractData(
361
+ this.contractStore,
362
+ this.contractClassService,
363
+ anchorBlockHeader,
364
+ this.overrides,
365
+ );
366
+
367
+ const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
368
+ if (!entryPointArtifact) {
369
+ throw new Error(
370
+ `Cannot run function ${call.selector} on ${call.to}: the contract is not registered. ` +
371
+ `Register it via wallet.registerContract(...).`,
372
+ );
373
+ }
337
374
 
338
375
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
339
376
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
@@ -353,7 +390,7 @@ export class ContractFunctionSimulator {
353
390
  authWitnesses: authwits,
354
391
  capsules: [],
355
392
  anchorBlockHeader,
356
- contractStore: this.contractStore,
393
+ anchoredContractData,
357
394
  noteStore: this.noteStore,
358
395
  keyStore: this.keyStore,
359
396
  addressStore: this.addressStore,
@@ -618,12 +655,12 @@ export async function generateSimulatedProvingResult(
618
655
  siloedNullifiers,
619
656
  minRevertibleSideEffectCounter,
620
657
  );
658
+ // The protocol nullifier is the nonce generator and the tx's first nullifier. It is injected by the
659
+ // init kernel (at counter 1, index 0) rather than emitted by any private call, so it is absent from
660
+ // the executed nullifiers above. Mirror the kernel here by prepending it as the first non-revertible
661
+ // nullifier.
621
662
  const nonceGenerator = privateExecutionResult.firstNullifier;
622
- if (nonRevertibleNullifiers.length === 0) {
623
- nonRevertibleNullifiers.push(nonceGenerator);
624
- } else if (!nonRevertibleNullifiers[0].equals(nonceGenerator)) {
625
- throw new Error('The first non revertible nullifier should be equal to the nonce generator. This is a bug!');
626
- }
663
+ nonRevertibleNullifiers.unshift(nonceGenerator);
627
664
 
628
665
  if (isPrivateOnlyTx) {
629
666
  // We must make the note hashes unique by using the
@@ -886,6 +923,11 @@ function meterGasUsed(data: PrivateToRollupAccumulatedData | PrivateToPublicAccu
886
923
  );
887
924
  meteredL2Gas += numContractClassLogs * L2_GAS_PER_CONTRACT_CLASS_LOG;
888
925
 
926
+ if (isPrivateOnlyTx) {
927
+ // The public data write that the private tx base rollup always performs to update the fee payer's balance.
928
+ meteredDAFields += PUBLIC_DATA_WRITE_LENGTH;
929
+ }
930
+
889
931
  const meteredDAGas = meteredDAFields * DA_GAS_PER_FIELD;
890
932
 
891
933
  if ((data as PrivateToPublicAccumulatedData).publicCallRequests) {
@@ -43,12 +43,6 @@ export class ExecutionNoteCache {
43
43
 
44
44
  private inRevertiblePhase = false;
45
45
 
46
- /**
47
- * Whether the protocol nullifier was used for nonce generation.
48
- * We don't need to use the protocol nullifier if a non-revertible nullifier is emitted.
49
- */
50
- private usedProtocolNullifierForNonces: boolean | undefined;
51
-
52
46
  constructor(private readonly protocolNullifier: Fr) {}
53
47
 
54
48
  /**
@@ -64,12 +58,9 @@ export class ExecutionNoteCache {
64
58
  this.inRevertiblePhase = true;
65
59
  this.minRevertibleSideEffectCounter = minRevertibleSideEffectCounter;
66
60
 
67
- const nullifiers = this.getEmittedNullifiers();
68
- // If there are no nullifiers emitted by private calls so far, we use the protocol nullifier as the nonce generator.
69
- // Note: There could still be nullifiers emitted after the counter is set, but those nullifiers are revertible, so
70
- // we don't want to use them as the nonce generator.
71
- this.usedProtocolNullifierForNonces = nullifiers.length === 0;
72
- const nonceGenerator = this.usedProtocolNullifierForNonces ? this.protocolNullifier : new Fr(nullifiers[0]);
61
+ // The protocol nullifier is always the tx's first nullifier (injected by the kernel init), so it is the
62
+ // nonce generator for every note hash.
63
+ const nonceGenerator = this.protocolNullifier;
73
64
 
74
65
  // The existing pending notes are all non-revertible.
75
66
  // They cannot be squashed by nullifiers emitted after minRevertibleSideEffectCounter is set.
@@ -102,14 +93,6 @@ export class ExecutionNoteCache {
102
93
  return sideEffectCounter >= this.minRevertibleSideEffectCounter;
103
94
  }
104
95
 
105
- public finish() {
106
- // If we never entered the revertible phase, and there are no nullifiers emitted, we need to use the protocol
107
- // nullifier as the nonce generator.
108
- if (!this.inRevertiblePhase) {
109
- this.usedProtocolNullifierForNonces = this.getEmittedNullifiers().length === 0;
110
- }
111
- }
112
-
113
96
  /**
114
97
  * Add a new note to cache.
115
98
  * @param note - New note created during execution.
@@ -223,19 +206,15 @@ export class ExecutionNoteCache {
223
206
  }
224
207
 
225
208
  /**
226
- * @returns All nullifiers emitted by private calls in this transaction. If the protocol nullifier was used as the
227
- * nonce generator, it is injected as the first nullifier.
209
+ * @returns All nullifiers of the transaction: the protocol nullifier (the kernel-injected first nullifier),
210
+ * followed by those emitted by private calls.
228
211
  */
229
212
  getAllNullifiers(): Fr[] {
230
- if (this.usedProtocolNullifierForNonces === undefined) {
231
- throw new Error('usedProtocolNullifierForNonces is not set yet. Call finish() to complete the transaction.');
232
- }
233
- const allNullifiers = this.getEmittedNullifiers();
234
- return [...(this.usedProtocolNullifierForNonces ? [this.protocolNullifier] : []), ...allNullifiers];
213
+ return [this.protocolNullifier, ...this.getEmittedNullifiers()];
235
214
  }
236
215
 
237
216
  getNonceGenerator(): Fr {
238
- return this.getAllNullifiers()[0];
217
+ return this.protocolNullifier;
239
218
  }
240
219
 
241
220
  #recordNullifier(contractAddress: AztecAddress, siloedNullifier: bigint) {
@@ -21,23 +21,27 @@ export {
21
21
  ETH_ADDRESS,
22
22
  EVENT_VALIDATION_REQUEST,
23
23
  FIELD,
24
+ FIXED_ARRAY,
24
25
  FUNCTION_SELECTOR,
25
26
  LOG_RETRIEVAL_REQUEST,
26
27
  LOG_RETRIEVAL_RESPONSE,
27
28
  MEMBERSHIP_WITNESS,
28
- MESSAGE_CONTEXT,
29
29
  NOTE_SELECTOR,
30
30
  NOTE_VALIDATION_REQUEST,
31
31
  OPTION,
32
32
  PENDING_TAGGED_LOG,
33
33
  POINT,
34
34
  PROVIDED_SECRET,
35
+ SLOT_NUMBER,
35
36
  STR,
37
+ STRUCT,
36
38
  U32,
39
+ tryFieldWidth,
37
40
  type InputSlot,
38
41
  type MaybePromise,
39
42
  type OutputSlot,
40
43
  type SlotShape,
44
+ type StructField,
41
45
  type TypeMapping,
42
46
  } from './oracle/oracle_type_mappings.js';
43
47
  export { ExecutionNoteCache } from './execution_note_cache.js';
@@ -53,6 +57,7 @@ export { TxResolverService } from '../messages/tx_resolver_service.js';
53
57
  export { UtilityExecutionOracle } from './oracle/utility_execution_oracle.js';
54
58
  export { PrivateExecutionOracle } from './oracle/private_execution_oracle.js';
55
59
  export { buildACIRCallback, UnavailableOracleError } from './oracle/acir_callback.js';
60
+ export { LEGACY_ORACLE_REGISTRY } from './oracle/legacy_oracle_registry.js';
56
61
  export { executePrivateFunction, extractPrivateCircuitPublicInputs } from './oracle/private_execution.js';
57
62
  export { generateSimulatedProvingResult } from './contract_function_simulator.js';
58
63
  export { packAsHintedNote } from './oracle/note_packing_utils.js';
@@ -66,6 +71,7 @@ export { EventValidationRequest } from './noir-structs/event_validation_request.
66
71
  export type { LogRetrievalRequest } from './noir-structs/log_retrieval_request.js';
67
72
  export type { LogRetrievalResponse } from './noir-structs/log_retrieval_response.js';
68
73
  export { NoteValidationRequest } from './noir-structs/note_validation_request.js';
74
+ export type { PendingTaggedLog } from './noir-structs/pending_tagged_log.js';
69
75
  export type { TxEffectData } from './noir-structs/tx_effect_data.js';
70
76
  export type { ProvidedSecret } from './noir-structs/provided_secret.js';
71
77
  export { ResolvedTx } from './noir-structs/resolved_tx.js';
@@ -1,13 +1,13 @@
1
1
  import type { Fr } from '@aztec/foundation/curves/bn254';
2
2
 
3
+ import type { RetractableFactOrigin } from '../../storage/fact_store/index.js';
3
4
  import type { EphemeralArray } from './ephemeral_array.js';
4
5
  import type { Option } from './option.js';
5
- import type { OriginBlock } from './origin_block.js';
6
6
 
7
7
  /**
8
8
  * A single fact returned within a fact collection by the fact store oracles.
9
9
  *
10
- * A TS version of the `Fact` struct in `facts/mod.nr`. `originBlock` is `Some` for a retractable fact (pruned on
11
- * reorg of that block) and `None` for a non-retractable one.
10
+ * A TS version of the `Fact` struct in `facts/mod.nr`. `originBlock` is `Some` for a retractable fact (carrying its
11
+ * origin block's current chain state) and `None` for a non-retractable one.
12
12
  */
13
- export type Fact = { factTypeId: Fr; payload: EphemeralArray<Fr>; originBlock: Option<OriginBlock> };
13
+ export type Fact = { factTypeId: Fr; payload: EphemeralArray<Fr>; originBlock: Option<RetractableFactOrigin> };
@@ -1,7 +1,8 @@
1
1
  import { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
3
3
 
4
- import type { Fact as FactFromStore, OriginBlock } from '../../storage/fact_store/index.js';
4
+ import type { FactWithOriginState, RetractableFactOrigin } from '../../storage/fact_store/index.js';
5
+ import { OriginBlockState } from '../../storage/fact_store/index.js';
5
6
  import type { EphemeralArrayService } from '../ephemeral_array_service.js';
6
7
  import { EphemeralArray } from './ephemeral_array.js';
7
8
  import type { Fact } from './fact.js';
@@ -27,7 +28,7 @@ export function toNoirFactCollection(
27
28
  scope: AztecAddress,
28
29
  factCollectionTypeId: Fr,
29
30
  factCollectionId: Fr,
30
- facts: FactFromStore[],
31
+ facts: FactWithOriginState[],
31
32
  ): FactCollection {
32
33
  return {
33
34
  contractAddress,
@@ -37,12 +38,16 @@ export function toNoirFactCollection(
37
38
  facts: EphemeralArray.fromValues(
38
39
  service,
39
40
  facts.map(
40
- (fact: FactFromStore): Fact => ({
41
+ (fact: FactWithOriginState): Fact => ({
41
42
  factTypeId: fact.factTypeId,
42
43
  payload: EphemeralArray.fromValues(service, fact.payload),
43
44
  originBlock: fact.originBlock
44
45
  ? Option.some(fact.originBlock)
45
- : Option.none<OriginBlock>({ blockNumber: 0, blockHash: Fr.ZERO }),
46
+ : Option.none<RetractableFactOrigin>({
47
+ blockNumber: 0,
48
+ blockHash: Fr.ZERO,
49
+ blockState: OriginBlockState.Pending,
50
+ }),
46
51
  }),
47
52
  ),
48
53
  ),
@@ -1,5 +1,8 @@
1
+ import type { BlockNumber } from '@aztec/foundation/branded-types';
1
2
  import type { Fr } from '@aztec/foundation/curves/bn254';
3
+ import type { BlockHash } from '@aztec/stdlib/block';
2
4
  import type { TxHash } from '@aztec/stdlib/tx';
5
+ import type { UInt64 } from '@aztec/stdlib/types';
3
6
 
4
7
  /**
5
8
  * Intermediate struct used to perform batch log retrieval by PXE. The `utilityBulkRetrieveLogs` oracle stores values of this
@@ -10,4 +13,7 @@ export type LogRetrievalResponse = {
10
13
  txHash: TxHash;
11
14
  uniqueNoteHashesInTx: Fr[];
12
15
  firstNullifierInTx: Fr;
16
+ blockNumber: BlockNumber;
17
+ blockTimestamp: UInt64;
18
+ blockHash: BlockHash;
13
19
  };
@@ -0,0 +1,12 @@
1
+ import type { Fr } from '@aztec/foundation/curves/bn254';
2
+
3
+ import type { ResolvedTx } from './resolved_tx.js';
4
+
5
+ /**
6
+ * Represents a pending tagged log as it is stored in the pending tagged log array to which the fetchTaggedLogs oracle
7
+ * inserts found private logs. A TS version of `pending_tagged_log.nr`.
8
+ */
9
+ export type PendingTaggedLog = {
10
+ log: Fr[];
11
+ context: ResolvedTx;
12
+ };
@@ -1,5 +1,5 @@
1
1
  import type { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import type { AppTaggingSecretKind } from '@aztec/stdlib/logs';
3
3
 
4
- /** A tagging secret an app supplies explicitly to `getPendingTaggedLogs` when PXE cannot derive it internally. */
4
+ /** A tagging secret an app supplies explicitly to `getPendingTaggedLogsV2` when PXE cannot derive it internally. */
5
5
  export type ProvidedSecret = { secret: Fr; mode: AppTaggingSecretKind };
@@ -3,6 +3,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
3
3
  // Keep in sync with aztec::messages::delivery::ResolvedTaggingStrategy
4
4
  const NON_INTERACTIVE_HANDSHAKE = 1;
5
5
  const UNCONSTRAINED_SECRET = 2;
6
+ const INTERACTIVE_HANDSHAKE = 3;
6
7
 
7
8
  /**
8
9
  * The tagging secret PXE hands to the contract after applying the wallet's {@link TaggingSecretStrategy} choice
@@ -13,6 +14,14 @@ export type ResolvedTaggingStrategy =
13
14
  /** A non-interactive handshake: the recipient re-derives the secret from the onchain handshake registry. */
14
15
  type: 'non-interactive-handshake';
15
16
  }
17
+ | {
18
+ /**
19
+ * An interactive handshake: the registry obtains the recipient's signed authorization through the custom
20
+ * request oracle, and the recipient learns the secret while signing. Nothing announcing the handshake is
21
+ * published onchain.
22
+ */
23
+ type: 'interactive-handshake';
24
+ }
16
25
  | {
17
26
  /**
18
27
  * An app-siloed, recipient-directional secret, ready to use. Only sound for unconstrained delivery.
@@ -29,6 +38,8 @@ export function resolvedTaggingStrategyToFields(resolved: ResolvedTaggingStrateg
29
38
  return [new Fr(NON_INTERACTIVE_HANDSHAKE), Fr.ZERO];
30
39
  case 'unconstrained-secret':
31
40
  return [new Fr(UNCONSTRAINED_SECRET), resolved.secret];
41
+ case 'interactive-handshake':
42
+ return [new Fr(INTERACTIVE_HANDSHAKE), Fr.ZERO];
32
43
  }
33
44
  }
34
45
 
@@ -36,10 +47,20 @@ export function resolvedTaggingStrategyToFields(resolved: ResolvedTaggingStrateg
36
47
  export function resolvedTaggingStrategyFromFields(kind: number, secret: Fr): ResolvedTaggingStrategy {
37
48
  switch (kind) {
38
49
  case NON_INTERACTIVE_HANDSHAKE:
50
+ assertAbsentSecret(kind, secret);
39
51
  return { type: 'non-interactive-handshake' };
52
+ case INTERACTIVE_HANDSHAKE:
53
+ assertAbsentSecret(kind, secret);
54
+ return { type: 'interactive-handshake' };
40
55
  case UNCONSTRAINED_SECRET:
41
56
  return { type: 'unconstrained-secret', secret };
42
57
  default:
43
58
  throw new Error(`Unrecognized resolved tagging strategy kind: ${kind}`);
44
59
  }
45
60
  }
61
+
62
+ function assertAbsentSecret(kind: number, secret: Fr): void {
63
+ if (!secret.isZero()) {
64
+ throw new Error(`Resolved tagging strategy ${kind} must not include a secret`);
65
+ }
66
+ }
@@ -2,7 +2,8 @@ import type { ACIRCallback, ACVMField } from '@aztec/simulator/client';
2
2
 
3
3
  import { ORACLE_VERSION_MAJOR, ORACLE_VERSION_MINOR } from '../../oracle_version.js';
4
4
  import type { IMiscOracle, IPrivateExecutionOracle, IUtilityExecutionOracle } from './interfaces.js';
5
- import { ORACLE_REGISTRY } from './oracle_registry.js';
5
+ import { LEGACY_ORACLE_REGISTRY, type LegacyOracleEntry } from './legacy_oracle_registry.js';
6
+ import { type NamedValue, ORACLE_REGISTRY, type OracleRegistryEntry, makeEntry } from './oracle_registry.js';
6
7
 
7
8
  export class UnavailableOracleError extends Error {
8
9
  constructor(oracleName: string) {
@@ -17,26 +18,71 @@ export class UnavailableOracleError extends Error {
17
18
  * `aztec_{scope}_{methodName}` convention to resolve the handler, and calling the method directly. Unknown oracle
18
19
  * names produce enhanced error messages based on the contract's oracle version.
19
20
  */
20
- export function buildACIRCallback(handler: OracleHandler): ACIRCallback {
21
+ export function buildACIRCallback(
22
+ handler: OracleHandler,
23
+ registries: {
24
+ real?: Record<string, OracleRegistryEntry>;
25
+ legacy?: Record<string, LegacyOracleEntry>;
26
+ } = {},
27
+ ): ACIRCallback {
28
+ const { real = ORACLE_REGISTRY, legacy: legacyRegistry = LEGACY_ORACLE_REGISTRY } = registries;
21
29
  const target = {} as ACIRCallback;
22
- for (const [oracleKey, entry] of Object.entries(ORACLE_REGISTRY)) {
23
- const match = oracleKey.match(/^aztec_(\w+?)_(.+)$/);
24
- if (!match) {
25
- throw new Error(`Oracle "${oracleKey}" does not follow the aztec_{scope}_{method} convention`);
26
- }
27
- const [, scope, methodName] = match;
30
+ for (const [oracleKey, entry] of Object.entries(real)) {
31
+ const { scope, methodName } = parseOracleName(oracleKey, 'Oracle');
28
32
  target[oracleKey] = async (...inputs: ACVMField[][]) => {
29
33
  assertHandlerSupportsScope(handler, scope);
30
34
  const named = entry.deserializeParams(inputs);
31
- const positional = named.map(p => p.value);
35
+ const positional = named.map((p: NamedValue) => p.value);
32
36
  const result = await (handler as any)[methodName](...positional);
33
37
  return entry.serializeReturn(result);
34
38
  };
35
39
  }
36
40
 
37
- return new Proxy(target, {
41
+ // Legacy oracle names: served for contracts compiled against a retired oracle version. Each reuses the current
42
+ // handler of its `modernOracle` and reshapes the wire (params and/or return) back to what the old bytecode expects.
43
+ for (const [legacyKey, legacy] of Object.entries(legacyRegistry)) {
44
+ const { scope } = parseOracleName(legacyKey, 'Legacy oracle');
45
+ if (legacyKey in target) {
46
+ throw new Error(`Legacy oracle "${legacyKey}" collides with a live oracle of the same name in the registry`);
47
+ }
48
+ const modernEntry = real[legacy.modernOracle];
49
+ const { methodName } = parseOracleName(legacy.modernOracle, 'Oracle');
50
+ // Override only the side whose wire changed; inherit the other from the modern entry.
51
+ const paramOverride = legacy.params;
52
+ const paramSource = paramOverride ? makeEntry({ params: [...paramOverride.legacyType] }) : modernEntry;
53
+ const returnOverride = legacy.returnType;
54
+ const returnSource = returnOverride ? makeEntry({ returnType: returnOverride.legacyType }) : modernEntry;
55
+ target[legacyKey] = async (...inputs: ACVMField[][]) => {
56
+ assertHandlerSupportsScope(handler, scope);
57
+ const legacyArgs = paramSource.deserializeParams(inputs).map(p => p.value);
58
+ const positional = paramOverride ? await paramOverride.mapping(legacyArgs) : legacyArgs;
59
+ const result = await (handler as any)[methodName](...positional);
60
+ return returnSource.serializeReturn(returnOverride ? returnOverride.mapping(result) : result);
61
+ };
62
+ }
63
+
64
+ return new Proxy(target, makeUnknownOracleTrap(handler));
65
+ }
66
+
67
+ /** Parses an `aztec_{scope}_{method}` oracle name into its parts, throwing if it doesn't follow the convention. */
68
+ function parseOracleName(key: string, label: string): { scope: string; methodName: string } {
69
+ const match = key.match(/^aztec_(\w+?)_(.+)$/);
70
+ if (!match) {
71
+ throw new Error(`${label} "${key}" does not follow the aztec_{scope}_{method} convention`);
72
+ }
73
+ return { scope: match[1], methodName: match[2] };
74
+ }
75
+
76
+ /**
77
+ * Proxy trap for the callback table: a known oracle name passes through; an unknown one throws a diagnostic keyed on
78
+ * the contract's oracle version (version unknown, contract newer than this environment, or a same-version mismatch).
79
+ */
80
+ function makeUnknownOracleTrap(handler: OracleHandler): ProxyHandler<ACIRCallback> {
81
+ return {
38
82
  get(obj, prop: string) {
39
- if (prop in obj) {
83
+ // Own-property check only: `in` would match inherited `Object.prototype` keys (e.g. `constructor`, `toString`)
84
+ // and return the built-in instead of falling through to the unknown-oracle diagnostic below.
85
+ if (Object.hasOwn(obj, prop)) {
40
86
  return (obj as Record<string, unknown>)[prop];
41
87
  }
42
88
 
@@ -76,7 +122,7 @@ export function buildACIRCallback(handler: OracleHandler): ACIRCallback {
76
122
  }
77
123
  };
78
124
  },
79
- });
125
+ };
80
126
  }
81
127
 
82
128
  type OracleHandler = IMiscOracle & (IUtilityExecutionOracle | IPrivateExecutionOracle);