@aztec/txe 0.0.1-commit.96bb3f7 → 0.0.1-commit.993d240

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 (138) hide show
  1. package/dest/ContractClassRegistry-KKNT527R.js +3 -0
  2. package/dest/ContractClassRegistry-KKNT527R.js.map +7 -0
  3. package/dest/ContractInstanceRegistry-GSKBNL3Q.js +3 -0
  4. package/dest/ContractInstanceRegistry-GSKBNL3Q.js.map +7 -0
  5. package/dest/FeeJuice-GUJ5O6GB.js +3 -0
  6. package/dest/FeeJuice-GUJ5O6GB.js.map +7 -0
  7. package/dest/MultiCallEntrypoint-ZQPCKVKL.js +3 -0
  8. package/dest/MultiCallEntrypoint-ZQPCKVKL.js.map +7 -0
  9. package/dest/SchnorrAccount-QIXE5DXA.js +3 -0
  10. package/dest/SchnorrAccount-QIXE5DXA.js.map +7 -0
  11. package/dest/bin/check_txe_oracle_version.d.ts +2 -0
  12. package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
  13. package/dest/bin/check_txe_oracle_version.js +32 -0
  14. package/dest/bin/index.js +3 -30
  15. package/dest/bin/index.js.map +7 -0
  16. package/dest/chunk-BJVAAXNA.js +3 -0
  17. package/dest/chunk-BJVAAXNA.js.map +7 -0
  18. package/dest/chunk-DF6RMOC6.js +304 -0
  19. package/dest/chunk-DF6RMOC6.js.map +7 -0
  20. package/dest/chunk-PPJTNNUG.js +265 -0
  21. package/dest/chunk-PPJTNNUG.js.map +7 -0
  22. package/dest/constants.d.ts +3 -2
  23. package/dest/constants.d.ts.map +1 -1
  24. package/dest/constants.js +5 -1
  25. package/dest/dispatcher_pool.d.ts +67 -0
  26. package/dest/dispatcher_pool.d.ts.map +1 -0
  27. package/dest/dispatcher_pool.js +284 -0
  28. package/dest/index.d.ts +188 -7
  29. package/dest/index.d.ts.map +1 -1
  30. package/dest/index.js +148 -75
  31. package/dest/metafile.json +38147 -0
  32. package/dest/msgpackr_fr_extension.d.ts +2 -0
  33. package/dest/msgpackr_fr_extension.d.ts.map +1 -0
  34. package/dest/msgpackr_fr_extension.js +21 -0
  35. package/dest/oracle/interfaces.d.ts +40 -28
  36. package/dest/oracle/interfaces.d.ts.map +1 -1
  37. package/dest/oracle/txe_oracle_public_context.d.ts +18 -13
  38. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  39. package/dest/oracle/txe_oracle_public_context.js +31 -16
  40. package/dest/oracle/txe_oracle_top_level_context.d.ts +39 -23
  41. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  42. package/dest/oracle/txe_oracle_top_level_context.js +225 -89
  43. package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
  44. package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
  45. package/dest/oracle/txe_private_execution_oracle.js +15 -0
  46. package/dest/rpc_server.d.ts +14 -0
  47. package/dest/rpc_server.d.ts.map +1 -0
  48. package/dest/rpc_server.js +78 -0
  49. package/dest/rpc_translator.d.ts +144 -82
  50. package/dest/rpc_translator.d.ts.map +1 -1
  51. package/dest/rpc_translator.js +599 -238
  52. package/dest/server.bundle.js +3 -0
  53. package/dest/server.bundle.js.map +7 -0
  54. package/dest/state_machine/archiver.d.ts +20 -69
  55. package/dest/state_machine/archiver.d.ts.map +1 -1
  56. package/dest/state_machine/archiver.js +47 -187
  57. package/dest/state_machine/dummy_p2p_client.d.ts +26 -16
  58. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  59. package/dest/state_machine/dummy_p2p_client.js +44 -20
  60. package/dest/state_machine/global_variable_builder.d.ts +9 -4
  61. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  62. package/dest/state_machine/global_variable_builder.js +9 -3
  63. package/dest/state_machine/index.d.ts +10 -6
  64. package/dest/state_machine/index.d.ts.map +1 -1
  65. package/dest/state_machine/index.js +55 -14
  66. package/dest/state_machine/mock_epoch_cache.d.ts +25 -8
  67. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  68. package/dest/state_machine/mock_epoch_cache.js +46 -9
  69. package/dest/state_machine/synchronizer.d.ts +6 -6
  70. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  71. package/dest/state_machine/synchronizer.js +4 -4
  72. package/dest/txe_oracle_version.d.ts +17 -0
  73. package/dest/txe_oracle_version.d.ts.map +1 -0
  74. package/dest/txe_oracle_version.js +14 -0
  75. package/dest/txe_session.d.ts +73 -10
  76. package/dest/txe_session.d.ts.map +1 -1
  77. package/dest/txe_session.js +242 -39
  78. package/dest/utils/block_creation.d.ts +4 -4
  79. package/dest/utils/block_creation.d.ts.map +1 -1
  80. package/dest/utils/block_creation.js +18 -4
  81. package/dest/utils/encoding.d.ts +191 -0
  82. package/dest/utils/encoding.d.ts.map +1 -0
  83. package/dest/{util → utils}/encoding.js +7 -2
  84. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  85. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  86. package/dest/utils/tx_effect_creation.d.ts +2 -3
  87. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  88. package/dest/utils/tx_effect_creation.js +3 -6
  89. package/dest/{util → utils}/txe_account_store.d.ts +1 -1
  90. package/dest/utils/txe_account_store.d.ts.map +1 -0
  91. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  92. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  93. package/dest/{util → utils}/txe_public_contract_data_source.js +6 -25
  94. package/dest/worker.bundle.js +3 -0
  95. package/dest/worker.bundle.js.map +7 -0
  96. package/dest/worker.d.ts +2 -0
  97. package/dest/worker.d.ts.map +1 -0
  98. package/dest/worker.js +92 -0
  99. package/package.json +38 -22
  100. package/src/bin/check_txe_oracle_version.ts +37 -0
  101. package/src/bin/index.ts +11 -2
  102. package/src/constants.ts +6 -1
  103. package/src/dispatcher_pool.ts +316 -0
  104. package/src/index.ts +166 -80
  105. package/src/msgpackr_fr_extension.ts +23 -0
  106. package/src/oracle/interfaces.ts +48 -34
  107. package/src/oracle/txe_oracle_public_context.ts +46 -18
  108. package/src/oracle/txe_oracle_top_level_context.ts +282 -151
  109. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  110. package/src/rpc_server.ts +87 -0
  111. package/src/rpc_translator.ts +687 -326
  112. package/src/state_machine/archiver.ts +53 -235
  113. package/src/state_machine/dummy_p2p_client.ts +70 -32
  114. package/src/state_machine/global_variable_builder.ts +18 -3
  115. package/src/state_machine/index.ts +72 -15
  116. package/src/state_machine/mock_epoch_cache.ts +57 -14
  117. package/src/state_machine/synchronizer.ts +6 -6
  118. package/src/txe_oracle_version.ts +17 -0
  119. package/src/txe_session.ts +352 -104
  120. package/src/utils/block_creation.ts +19 -16
  121. package/src/{util → utils}/encoding.ts +8 -2
  122. package/src/utils/tx_effect_creation.ts +3 -11
  123. package/src/{util → utils}/txe_public_contract_data_source.ts +10 -38
  124. package/src/worker.ts +98 -0
  125. package/dest/util/encoding.d.ts +0 -720
  126. package/dest/util/encoding.d.ts.map +0 -1
  127. package/dest/util/expected_failure_error.d.ts.map +0 -1
  128. package/dest/util/txe_account_store.d.ts.map +0 -1
  129. package/dest/util/txe_contract_store.d.ts +0 -12
  130. package/dest/util/txe_contract_store.d.ts.map +0 -1
  131. package/dest/util/txe_contract_store.js +0 -22
  132. package/dest/util/txe_public_contract_data_source.d.ts +0 -21
  133. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  134. package/src/util/txe_contract_store.ts +0 -36
  135. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  136. /package/dest/{util → utils}/txe_account_store.js +0 -0
  137. /package/src/{util → utils}/expected_failure_error.ts +0 -0
  138. /package/src/{util → utils}/txe_account_store.ts +0 -0
@@ -1,17 +1,27 @@
1
1
  import type { ContractInstanceWithAddress } from '@aztec/aztec.js/contracts';
2
- import { Fr, Point } from '@aztec/aztec.js/fields';
3
- import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX } from '@aztec/constants';
2
+ import { Fr } from '@aztec/aztec.js/fields';
3
+ import {
4
+ ARCHIVE_HEIGHT,
5
+ MAX_NOTE_HASHES_PER_TX,
6
+ MAX_NULLIFIERS_PER_TX,
7
+ MAX_PRIVATE_LOGS_PER_TX,
8
+ PRIVATE_LOG_SIZE_IN_FIELDS,
9
+ } from '@aztec/constants';
4
10
  import { BlockNumber } from '@aztec/foundation/branded-types';
11
+ import { MembershipWitness } from '@aztec/foundation/trees';
5
12
  import {
13
+ BoundedVec,
6
14
  type IMiscOracle,
7
15
  type IPrivateExecutionOracle,
8
16
  type IUtilityExecutionOracle,
9
- packAsRetrievedNote,
17
+ Option,
18
+ packAsHintedNote,
10
19
  } from '@aztec/pxe/simulator';
11
20
  import { type ContractArtifact, EventSelector, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
12
21
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
13
- import { MerkleTreeId } from '@aztec/stdlib/trees';
22
+ import { GasSettings } from '@aztec/stdlib/gas';
14
23
 
24
+ import { MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY, MAX_OFFCHAIN_EFFECT_LEN } from './constants.js';
15
25
  import type { IAvmExecutionOracle, ITxeExecutionOracle } from './oracle/interfaces.js';
16
26
  import type { TXESessionStateHandler } from './txe_session.js';
17
27
  import {
@@ -20,6 +30,7 @@ import {
20
30
  addressFromSingle,
21
31
  arrayOfArraysToBoundedVecOfArrays,
22
32
  arrayToBoundedVec,
33
+ blockHashFromSingle,
23
34
  bufferToU8Array,
24
35
  fromArray,
25
36
  fromSingle,
@@ -28,9 +39,9 @@ import {
28
39
  toArray,
29
40
  toForeignCallResult,
30
41
  toSingle,
31
- } from './util/encoding.js';
42
+ } from './utils/encoding.js';
32
43
 
33
- const MAX_EVENT_LEN = 12; // This is MAX_MESSAGE_CONTENT_LEN - PRIVATE_EVENT_RESERVED_FIELDS
44
+ const MAX_EVENT_LEN = 10; // This is MAX_MESSAGE_CONTENT_LEN - PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN
34
45
  const MAX_PRIVATE_EVENTS_PER_TXE_QUERY = 5;
35
46
 
36
47
  export class UnavailableOracleError extends Error {
@@ -102,19 +113,32 @@ export class RPCTranslator {
102
113
  return this.oracleHandler;
103
114
  }
104
115
 
116
+ // eslint-disable-next-line camelcase
117
+ aztec_txe_assertCompatibleOracleVersion(foreignMajor: ForeignCallSingle, foreignMinor: ForeignCallSingle) {
118
+ const major = fromSingle(foreignMajor).toNumber();
119
+ const minor = fromSingle(foreignMinor).toNumber();
120
+
121
+ this.stateHandler.setTxeOracleVersion(major, minor);
122
+
123
+ return toForeignCallResult([]);
124
+ }
125
+
105
126
  // TXE session state transition functions - these get handled by the state handler
106
127
 
107
- async txeSetTopLevelTXEContext() {
128
+ // eslint-disable-next-line camelcase
129
+ async aztec_txe_setTopLevelTXEContext() {
108
130
  await this.stateHandler.enterTopLevelState();
109
131
 
110
132
  return toForeignCallResult([]);
111
133
  }
112
134
 
113
- async txeSetPrivateTXEContext(
135
+ // eslint-disable-next-line camelcase
136
+ async aztec_txe_setPrivateTXEContext(
114
137
  foreignContractAddressIsSome: ForeignCallSingle,
115
138
  foreignContractAddressValue: ForeignCallSingle,
116
139
  foreignAnchorBlockNumberIsSome: ForeignCallSingle,
117
140
  foreignAnchorBlockNumberValue: ForeignCallSingle,
141
+ foreignGasSettings: ForeignCallArray,
118
142
  ) {
119
143
  const contractAddress = fromSingle(foreignContractAddressIsSome).toBool()
120
144
  ? AztecAddress.fromField(fromSingle(foreignContractAddressValue))
@@ -124,12 +148,19 @@ export class RPCTranslator {
124
148
  ? BlockNumber(fromSingle(foreignAnchorBlockNumberValue).toNumber())
125
149
  : undefined;
126
150
 
127
- const privateContextInputs = await this.stateHandler.enterPrivateState(contractAddress, anchorBlockNumber);
151
+ const gasSettings = GasSettings.fromFields(fromArray(foreignGasSettings));
152
+
153
+ const privateContextInputs = await this.stateHandler.enterPrivateState(
154
+ contractAddress,
155
+ anchorBlockNumber,
156
+ gasSettings,
157
+ );
128
158
 
129
159
  return toForeignCallResult(privateContextInputs.toFields().map(toSingle));
130
160
  }
131
161
 
132
- async txeSetPublicTXEContext(
162
+ // eslint-disable-next-line camelcase
163
+ async aztec_txe_setPublicTXEContext(
133
164
  foreignContractAddressIsSome: ForeignCallSingle,
134
165
  foreignContractAddressValue: ForeignCallSingle,
135
166
  ) {
@@ -142,7 +173,8 @@ export class RPCTranslator {
142
173
  return toForeignCallResult([]);
143
174
  }
144
175
 
145
- async txeSetUtilityTXEContext(
176
+ // eslint-disable-next-line camelcase
177
+ async aztec_txe_setUtilityTXEContext(
146
178
  foreignContractAddressIsSome: ForeignCallSingle,
147
179
  foreignContractAddressValue: ForeignCallSingle,
148
180
  ) {
@@ -159,44 +191,54 @@ export class RPCTranslator {
159
191
 
160
192
  // TXE-specific oracles
161
193
 
162
- txeGetDefaultAddress() {
163
- const defaultAddress = this.handlerAsTxe().txeGetDefaultAddress();
194
+ // eslint-disable-next-line camelcase
195
+ aztec_txe_getDefaultAddress() {
196
+ const defaultAddress = this.handlerAsTxe().getDefaultAddress();
164
197
 
165
198
  return toForeignCallResult([toSingle(defaultAddress)]);
166
199
  }
167
200
 
168
- async txeGetNextBlockNumber() {
169
- const nextBlockNumber = await this.handlerAsTxe().txeGetNextBlockNumber();
201
+ // eslint-disable-next-line camelcase
202
+ async aztec_txe_getNextBlockNumber() {
203
+ const nextBlockNumber = await this.handlerAsTxe().getNextBlockNumber();
170
204
 
171
205
  return toForeignCallResult([toSingle(nextBlockNumber)]);
172
206
  }
173
207
 
174
- async txeGetNextBlockTimestamp() {
175
- const nextBlockTimestamp = await this.handlerAsTxe().txeGetNextBlockTimestamp();
208
+ // eslint-disable-next-line camelcase
209
+ async aztec_txe_getNextBlockTimestamp() {
210
+ const nextBlockTimestamp = await this.handlerAsTxe().getNextBlockTimestamp();
176
211
 
177
212
  return toForeignCallResult([toSingle(nextBlockTimestamp)]);
178
213
  }
179
214
 
180
- async txeAdvanceBlocksBy(foreignBlocks: ForeignCallSingle) {
215
+ // eslint-disable-next-line camelcase
216
+ async aztec_txe_advanceBlocksBy(foreignBlocks: ForeignCallSingle) {
181
217
  const blocks = fromSingle(foreignBlocks).toNumber();
182
218
 
183
- await this.handlerAsTxe().txeAdvanceBlocksBy(blocks);
219
+ await this.handlerAsTxe().advanceBlocksBy(blocks);
184
220
 
185
221
  return toForeignCallResult([]);
186
222
  }
187
223
 
188
- txeAdvanceTimestampBy(foreignDuration: ForeignCallSingle) {
224
+ // eslint-disable-next-line camelcase
225
+ aztec_txe_advanceTimestampBy(foreignDuration: ForeignCallSingle) {
189
226
  const duration = fromSingle(foreignDuration).toBigInt();
190
227
 
191
- this.handlerAsTxe().txeAdvanceTimestampBy(duration);
228
+ this.handlerAsTxe().advanceTimestampBy(duration);
192
229
 
193
230
  return toForeignCallResult([]);
194
231
  }
195
232
 
196
- async txeDeploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, foreignSecret: ForeignCallSingle) {
233
+ // eslint-disable-next-line camelcase
234
+ async aztec_txe_deploy(
235
+ artifact: ContractArtifact,
236
+ instance: ContractInstanceWithAddress,
237
+ foreignSecret: ForeignCallSingle,
238
+ ) {
197
239
  const secret = fromSingle(foreignSecret);
198
240
 
199
- await this.handlerAsTxe().txeDeploy(artifact, instance, secret);
241
+ await this.handlerAsTxe().deploy(artifact, instance, secret);
200
242
 
201
243
  return toForeignCallResult([
202
244
  toArray([
@@ -204,15 +246,17 @@ export class RPCTranslator {
204
246
  instance.deployer.toField(),
205
247
  instance.currentContractClassId,
206
248
  instance.initializationHash,
249
+ instance.immutablesHash,
207
250
  ...instance.publicKeys.toFields(),
208
251
  ]),
209
252
  ]);
210
253
  }
211
254
 
212
- async txeCreateAccount(foreignSecret: ForeignCallSingle) {
255
+ // eslint-disable-next-line camelcase
256
+ async aztec_txe_createAccount(foreignSecret: ForeignCallSingle) {
213
257
  const secret = fromSingle(foreignSecret);
214
258
 
215
- const completeAddress = await this.handlerAsTxe().txeCreateAccount(secret);
259
+ const completeAddress = await this.handlerAsTxe().createAccount(secret);
216
260
 
217
261
  return toForeignCallResult([
218
262
  toSingle(completeAddress.address),
@@ -220,14 +264,15 @@ export class RPCTranslator {
220
264
  ]);
221
265
  }
222
266
 
223
- async txeAddAccount(
267
+ // eslint-disable-next-line camelcase
268
+ async aztec_txe_addAccount(
224
269
  artifact: ContractArtifact,
225
270
  instance: ContractInstanceWithAddress,
226
271
  foreignSecret: ForeignCallSingle,
227
272
  ) {
228
273
  const secret = fromSingle(foreignSecret);
229
274
 
230
- const completeAddress = await this.handlerAsTxe().txeAddAccount(artifact, instance, secret);
275
+ const completeAddress = await this.handlerAsTxe().addAccount(artifact, instance, secret);
231
276
 
232
277
  return toForeignCallResult([
233
278
  toSingle(completeAddress.address),
@@ -235,48 +280,104 @@ export class RPCTranslator {
235
280
  ]);
236
281
  }
237
282
 
238
- async txeAddAuthWitness(foreignAddress: ForeignCallSingle, foreignMessageHash: ForeignCallSingle) {
283
+ // eslint-disable-next-line camelcase
284
+ async aztec_txe_addAuthWitness(foreignAddress: ForeignCallSingle, foreignMessageHash: ForeignCallSingle) {
239
285
  const address = addressFromSingle(foreignAddress);
240
286
  const messageHash = fromSingle(foreignMessageHash);
241
287
 
242
- await this.handlerAsTxe().txeAddAuthWitness(address, messageHash);
288
+ await this.handlerAsTxe().addAuthWitness(address, messageHash);
243
289
 
244
290
  return toForeignCallResult([]);
245
291
  }
246
292
 
247
293
  // PXE oracles
248
294
 
249
- utilityAssertCompatibleOracleVersion(foreignVersion: ForeignCallSingle) {
250
- const version = fromSingle(foreignVersion).toNumber();
295
+ // eslint-disable-next-line camelcase
296
+ aztec_utl_assertCompatibleOracleVersion(foreignMajor: ForeignCallSingle, foreignMinor: ForeignCallSingle) {
297
+ const major = fromSingle(foreignMajor).toNumber();
298
+ const minor = fromSingle(foreignMinor).toNumber();
251
299
 
252
- this.handlerAsMisc().utilityAssertCompatibleOracleVersion(version);
300
+ this.handlerAsMisc().assertCompatibleOracleVersion(major, minor);
253
301
 
254
302
  return toForeignCallResult([]);
255
303
  }
256
304
 
257
- utilityGetRandomField() {
258
- const randomField = this.handlerAsMisc().utilityGetRandomField();
305
+ // eslint-disable-next-line camelcase
306
+ aztec_utl_getRandomField() {
307
+ const randomField = this.handlerAsMisc().getRandomField();
259
308
 
260
309
  return toForeignCallResult([toSingle(randomField)]);
261
310
  }
262
311
 
263
- async txeGetLastBlockTimestamp() {
264
- const timestamp = await this.handlerAsTxe().txeGetLastBlockTimestamp();
312
+ // eslint-disable-next-line camelcase
313
+ async aztec_txe_getLastBlockTimestamp() {
314
+ const timestamp = await this.handlerAsTxe().getLastBlockTimestamp();
265
315
 
266
316
  return toForeignCallResult([toSingle(new Fr(timestamp))]);
267
317
  }
268
318
 
269
- async txeGetLastTxEffects() {
270
- const { txHash, noteHashes, nullifiers } = await this.handlerAsTxe().txeGetLastTxEffects();
319
+ // eslint-disable-next-line camelcase
320
+ async aztec_txe_getLastTxEffects() {
321
+ const { txHash, noteHashes, nullifiers, privateLogs } = await this.handlerAsTxe().getLastTxEffects();
322
+
323
+ // Same workaround as `aztec_txe_getPrivateEvents`: Noir cannot yet return nested structs with arrays, so we return
324
+ // a flat multidimensional array plus per-log lengths and the total count, and reassemble into a
325
+ // `BoundedVec<BoundedVec<T>>` on the Noir side. Each log contributes only its emitted fields. The rest
326
+ // is zero-padded to `PRIVATE_LOG_SIZE_IN_FIELDS`.
327
+ const emittedLogs = privateLogs.map(log => log.getEmittedFields());
328
+
329
+ const rawLogStorage = emittedLogs
330
+ .map(fields => fields.concat(Array(PRIVATE_LOG_SIZE_IN_FIELDS - fields.length).fill(new Fr(0))))
331
+ .concat(
332
+ Array(MAX_PRIVATE_LOGS_PER_TX - emittedLogs.length).fill(Array(PRIVATE_LOG_SIZE_IN_FIELDS).fill(new Fr(0))),
333
+ )
334
+ .flat();
335
+
336
+ const logLengths = emittedLogs
337
+ .map(fields => new Fr(fields.length))
338
+ .concat(Array(MAX_PRIVATE_LOGS_PER_TX - emittedLogs.length).fill(new Fr(0)));
339
+
340
+ const logCount = new Fr(emittedLogs.length);
271
341
 
272
342
  return toForeignCallResult([
273
343
  toSingle(txHash.hash),
274
344
  ...arrayToBoundedVec(toArray(noteHashes), MAX_NOTE_HASHES_PER_TX),
275
345
  ...arrayToBoundedVec(toArray(nullifiers), MAX_NULLIFIERS_PER_TX),
346
+ toArray(rawLogStorage),
347
+ toArray(logLengths),
348
+ toSingle(logCount),
276
349
  ]);
277
350
  }
278
351
 
279
- async txeGetPrivateEvents(
352
+ // eslint-disable-next-line camelcase
353
+ aztec_txe_getLastCallOffchainEffects() {
354
+ const { effects } = this.stateHandler.getLastCallOffchainEffects();
355
+
356
+ const rawArrayStorage = effects
357
+ .map(e => e.concat(Array(MAX_OFFCHAIN_EFFECT_LEN - e.length).fill(new Fr(0))))
358
+ .concat(
359
+ Array(MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY - effects.length).fill(Array(MAX_OFFCHAIN_EFFECT_LEN).fill(new Fr(0))),
360
+ )
361
+ .flat();
362
+
363
+ const effectLengths = effects
364
+ .map(e => new Fr(e.length))
365
+ .concat(Array(MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY - effects.length).fill(new Fr(0)));
366
+
367
+ const count = new Fr(effects.length);
368
+
369
+ return toForeignCallResult([toArray(rawArrayStorage), toArray(effectLengths), toSingle(count)]);
370
+ }
371
+
372
+ // eslint-disable-next-line camelcase
373
+ aztec_txe_getLastCallContext() {
374
+ const { txHash, anchorBlockTimestamp } = this.stateHandler.getLastCallContext();
375
+ const isSome = txHash.isZero() ? 0 : 1;
376
+ return toForeignCallResult([toSingle(isSome), toSingle(txHash), toSingle(new Fr(anchorBlockTimestamp))]);
377
+ }
378
+
379
+ // eslint-disable-next-line camelcase
380
+ async aztec_txe_getPrivateEvents(
280
381
  foreignSelector: ForeignCallSingle,
281
382
  foreignContractAddress: ForeignCallSingle,
282
383
  foreignScope: ForeignCallSingle,
@@ -285,7 +386,14 @@ export class RPCTranslator {
285
386
  const contractAddress = addressFromSingle(foreignContractAddress);
286
387
  const scope = addressFromSingle(foreignScope);
287
388
 
288
- const events = await this.handlerAsTxe().txeGetPrivateEvents(selector, contractAddress, scope);
389
+ // TODO(F-335): Avoid doing the following 2 calls here.
390
+ {
391
+ await this.handlerAsTxe().syncContractNonOracleMethod(contractAddress, scope, this.stateHandler.getCurrentJob());
392
+ // We cycle job to commit the stores after the contract sync.
393
+ await this.stateHandler.cycleJob();
394
+ }
395
+
396
+ const events = await this.handlerAsTxe().getPrivateEvents(selector, contractAddress, scope);
289
397
 
290
398
  if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
291
399
  throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
@@ -309,26 +417,29 @@ export class RPCTranslator {
309
417
  return toForeignCallResult([toArray(rawArrayStorage), toArray(eventLengths), toSingle(queryLength)]);
310
418
  }
311
419
 
312
- privateStoreInExecutionCache(foreignValues: ForeignCallArray, foreignHash: ForeignCallSingle) {
420
+ // eslint-disable-next-line camelcase
421
+ aztec_prv_setHashPreimage(foreignValues: ForeignCallArray, foreignHash: ForeignCallSingle) {
313
422
  const values = fromArray(foreignValues);
314
423
  const hash = fromSingle(foreignHash);
315
424
 
316
- this.handlerAsPrivate().privateStoreInExecutionCache(values, hash);
425
+ this.handlerAsPrivate().setHashPreimage(values, hash);
317
426
 
318
427
  return toForeignCallResult([]);
319
428
  }
320
429
 
321
- async privateLoadFromExecutionCache(foreignHash: ForeignCallSingle) {
430
+ // eslint-disable-next-line camelcase
431
+ async aztec_prv_getHashPreimage(foreignHash: ForeignCallSingle) {
322
432
  const hash = fromSingle(foreignHash);
323
433
 
324
- const returns = await this.handlerAsPrivate().privateLoadFromExecutionCache(hash);
434
+ const returns = await this.handlerAsPrivate().getHashPreimage(hash);
325
435
 
326
436
  return toForeignCallResult([toArray(returns)]);
327
437
  }
328
438
 
329
439
  // When the argument is a slice, noir automatically adds a length field to oracle call.
330
440
  // When the argument is an array, we add the field length manually to the signature.
331
- utilityDebugLog(
441
+ // eslint-disable-next-line camelcase
442
+ async aztec_utl_log(
332
443
  foreignLevel: ForeignCallSingle,
333
444
  foreignMessage: ForeignCallArray,
334
445
  _foreignLength: ForeignCallSingle,
@@ -340,45 +451,44 @@ export class RPCTranslator {
340
451
  .join('');
341
452
  const fields = fromArray(foreignFields);
342
453
 
343
- this.handlerAsMisc().utilityDebugLog(level, message, fields);
454
+ await this.handlerAsMisc().log(level, message, fields);
344
455
 
345
456
  return toForeignCallResult([]);
346
457
  }
347
458
 
348
- async utilityStorageRead(
459
+ // eslint-disable-next-line camelcase
460
+ async aztec_utl_getFromPublicStorage(
461
+ foreignBlockHash: ForeignCallSingle,
349
462
  foreignContractAddress: ForeignCallSingle,
350
463
  foreignStartStorageSlot: ForeignCallSingle,
351
- foreignBlockNumber: ForeignCallSingle,
352
464
  foreignNumberOfElements: ForeignCallSingle,
353
465
  ) {
466
+ const blockHash = blockHashFromSingle(foreignBlockHash);
354
467
  const contractAddress = addressFromSingle(foreignContractAddress);
355
468
  const startStorageSlot = fromSingle(foreignStartStorageSlot);
356
- const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
357
469
  const numberOfElements = fromSingle(foreignNumberOfElements).toNumber();
358
470
 
359
- const values = await this.handlerAsUtility().utilityStorageRead(
471
+ const values = await this.handlerAsUtility().getFromPublicStorage(
472
+ blockHash,
360
473
  contractAddress,
361
474
  startStorageSlot,
362
- blockNumber,
363
475
  numberOfElements,
364
476
  );
365
477
 
366
478
  return toForeignCallResult([toArray(values)]);
367
479
  }
368
480
 
369
- async utilityGetPublicDataWitness(foreignBlockNumber: ForeignCallSingle, foreignLeafSlot: ForeignCallSingle) {
370
- const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
481
+ // eslint-disable-next-line camelcase
482
+ async aztec_utl_getPublicDataWitness(foreignBlockHash: ForeignCallSingle, foreignLeafSlot: ForeignCallSingle) {
483
+ const blockHash = blockHashFromSingle(foreignBlockHash);
371
484
  const leafSlot = fromSingle(foreignLeafSlot);
372
485
 
373
- const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(blockNumber, leafSlot);
374
-
375
- if (!witness) {
376
- throw new Error(`Public data witness not found for slot ${leafSlot} at block ${blockNumber}.`);
377
- }
486
+ const witness = await this.handlerAsUtility().getPublicDataWitness(blockHash, leafSlot);
378
487
  return toForeignCallResult(witness.toNoirRepresentation());
379
488
  }
380
489
 
381
- async utilityGetNotes(
490
+ // eslint-disable-next-line camelcase
491
+ async aztec_utl_getNotes(
382
492
  foreignOwnerIsSome: ForeignCallSingle,
383
493
  foreignOwnerValue: ForeignCallSingle,
384
494
  foreignStorageSlot: ForeignCallSingle,
@@ -396,12 +506,12 @@ export class RPCTranslator {
396
506
  foreignOffset: ForeignCallSingle,
397
507
  foreignStatus: ForeignCallSingle,
398
508
  foreignMaxNotes: ForeignCallSingle,
399
- foreignPackedRetrievedNoteLength: ForeignCallSingle,
509
+ foreignPackedHintedNoteLength: ForeignCallSingle,
400
510
  ) {
401
511
  // Parse Option<AztecAddress>: ownerIsSome is 0 for None, 1 for Some
402
512
  const owner = fromSingle(foreignOwnerIsSome).toBool()
403
- ? AztecAddress.fromField(fromSingle(foreignOwnerValue))
404
- : undefined;
513
+ ? Option.some(AztecAddress.fromField(fromSingle(foreignOwnerValue)))
514
+ : Option.none(AztecAddress.ZERO);
405
515
  const storageSlot = fromSingle(foreignStorageSlot);
406
516
  const numSelects = fromSingle(foreignNumSelects).toNumber();
407
517
  const selectByIndexes = fromArray(foreignSelectByIndexes).map(fr => fr.toNumber());
@@ -417,9 +527,9 @@ export class RPCTranslator {
417
527
  const offset = fromSingle(foreignOffset).toNumber();
418
528
  const status = fromSingle(foreignStatus).toNumber();
419
529
  const maxNotes = fromSingle(foreignMaxNotes).toNumber();
420
- const packedRetrievedNoteLength = fromSingle(foreignPackedRetrievedNoteLength).toNumber();
530
+ const packedHintedNoteLength = fromSingle(foreignPackedHintedNoteLength).toNumber();
421
531
 
422
- const noteDatas = await this.handlerAsUtility().utilityGetNotes(
532
+ const noteVec = await this.handlerAsUtility().getNotes(
423
533
  owner,
424
534
  storageSlot,
425
535
  numSelects,
@@ -435,36 +545,33 @@ export class RPCTranslator {
435
545
  limit,
436
546
  offset,
437
547
  status,
548
+ maxNotes,
549
+ packedHintedNoteLength,
438
550
  );
439
551
 
440
- const returnDataAsArrayOfArrays = noteDatas.map(noteData =>
441
- packAsRetrievedNote({
552
+ const returnDataAsArrayOfArrays = Array.from(noteVec.data).map(noteData =>
553
+ packAsHintedNote({
442
554
  contractAddress: noteData.contractAddress,
443
555
  owner: noteData.owner,
444
556
  randomness: noteData.randomness,
445
557
  storageSlot: noteData.storageSlot,
446
558
  noteNonce: noteData.noteNonce,
447
- index: noteData.index,
559
+ isPending: noteData.isPending,
448
560
  note: noteData.note,
449
561
  }),
450
562
  );
451
563
 
452
- // Now we convert each sub-array to an array of ForeignCallSingles
453
564
  const returnDataAsArrayOfForeignCallSingleArrays = returnDataAsArrayOfArrays.map(subArray =>
454
565
  subArray.map(toSingle),
455
566
  );
456
567
 
457
- // At last we convert the array of arrays to a bounded vec of arrays
458
568
  return toForeignCallResult(
459
- arrayOfArraysToBoundedVecOfArrays(
460
- returnDataAsArrayOfForeignCallSingleArrays,
461
- maxNotes,
462
- packedRetrievedNoteLength,
463
- ),
569
+ arrayOfArraysToBoundedVecOfArrays(returnDataAsArrayOfForeignCallSingleArrays, maxNotes, packedHintedNoteLength),
464
570
  );
465
571
  }
466
572
 
467
- privateNotifyCreatedNote(
573
+ // eslint-disable-next-line camelcase
574
+ aztec_prv_notifyCreatedNote(
468
575
  foreignOwner: ForeignCallSingle,
469
576
  foreignStorageSlot: ForeignCallSingle,
470
577
  foreignRandomness: ForeignCallSingle,
@@ -481,20 +588,13 @@ export class RPCTranslator {
481
588
  const noteHash = fromSingle(foreignNoteHash);
482
589
  const counter = fromSingle(foreignCounter).toNumber();
483
590
 
484
- this.handlerAsPrivate().privateNotifyCreatedNote(
485
- owner,
486
- storageSlot,
487
- randomness,
488
- noteTypeId,
489
- note,
490
- noteHash,
491
- counter,
492
- );
591
+ this.handlerAsPrivate().notifyCreatedNote(owner, storageSlot, randomness, noteTypeId, note, noteHash, counter);
493
592
 
494
593
  return toForeignCallResult([]);
495
594
  }
496
595
 
497
- async privateNotifyNullifiedNote(
596
+ // eslint-disable-next-line camelcase
597
+ async aztec_prv_notifyNullifiedNote(
498
598
  foreignInnerNullifier: ForeignCallSingle,
499
599
  foreignNoteHash: ForeignCallSingle,
500
600
  foreignCounter: ForeignCallSingle,
@@ -503,31 +603,47 @@ export class RPCTranslator {
503
603
  const noteHash = fromSingle(foreignNoteHash);
504
604
  const counter = fromSingle(foreignCounter).toNumber();
505
605
 
506
- await this.handlerAsPrivate().privateNotifyNullifiedNote(innerNullifier, noteHash, counter);
606
+ await this.handlerAsPrivate().notifyNullifiedNote(innerNullifier, noteHash, counter);
507
607
 
508
608
  return toForeignCallResult([]);
509
609
  }
510
610
 
511
- async privateNotifyCreatedNullifier(foreignInnerNullifier: ForeignCallSingle) {
611
+ // eslint-disable-next-line camelcase
612
+ async aztec_prv_notifyCreatedNullifier(foreignInnerNullifier: ForeignCallSingle) {
512
613
  const innerNullifier = fromSingle(foreignInnerNullifier);
513
614
 
514
- await this.handlerAsPrivate().privateNotifyCreatedNullifier(innerNullifier);
615
+ await this.handlerAsPrivate().notifyCreatedNullifier(innerNullifier);
515
616
 
516
617
  return toForeignCallResult([]);
517
618
  }
518
619
 
519
- async utilityCheckNullifierExists(foreignInnerNullifier: ForeignCallSingle) {
620
+ // eslint-disable-next-line camelcase
621
+ async aztec_prv_isNullifierPending(
622
+ foreignInnerNullifier: ForeignCallSingle,
623
+ foreignContractAddress: ForeignCallSingle,
624
+ ) {
625
+ const innerNullifier = fromSingle(foreignInnerNullifier);
626
+ const contractAddress = addressFromSingle(foreignContractAddress);
627
+
628
+ const isPending = await this.handlerAsPrivate().isNullifierPending(innerNullifier, contractAddress);
629
+
630
+ return toForeignCallResult([toSingle(new Fr(isPending))]);
631
+ }
632
+
633
+ // eslint-disable-next-line camelcase
634
+ async aztec_utl_doesNullifierExist(foreignInnerNullifier: ForeignCallSingle) {
520
635
  const innerNullifier = fromSingle(foreignInnerNullifier);
521
636
 
522
- const exists = await this.handlerAsUtility().utilityCheckNullifierExists(innerNullifier);
637
+ const exists = await this.handlerAsUtility().doesNullifierExist(innerNullifier);
523
638
 
524
639
  return toForeignCallResult([toSingle(new Fr(exists))]);
525
640
  }
526
641
 
527
- async utilityGetContractInstance(foreignAddress: ForeignCallSingle) {
642
+ // eslint-disable-next-line camelcase
643
+ async aztec_utl_getContractInstance(foreignAddress: ForeignCallSingle) {
528
644
  const address = addressFromSingle(foreignAddress);
529
645
 
530
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
646
+ const instance = await this.handlerAsUtility().getContractInstance(address);
531
647
 
532
648
  return toForeignCallResult(
533
649
  [
@@ -535,320 +651,451 @@ export class RPCTranslator {
535
651
  instance.deployer.toField(),
536
652
  instance.currentContractClassId,
537
653
  instance.initializationHash,
654
+ instance.immutablesHash,
538
655
  ...instance.publicKeys.toFields(),
539
656
  ].map(toSingle),
540
657
  );
541
658
  }
542
659
 
543
- async utilityGetPublicKeysAndPartialAddress(foreignAddress: ForeignCallSingle) {
660
+ // eslint-disable-next-line camelcase
661
+ async aztec_utl_getPublicKeysAndPartialAddress(foreignAddress: ForeignCallSingle) {
544
662
  const address = addressFromSingle(foreignAddress);
545
663
 
546
- const { publicKeys, partialAddress } = await this.handlerAsUtility().utilityGetPublicKeysAndPartialAddress(address);
664
+ const result = await this.handlerAsUtility().getPublicKeysAndPartialAddress(address);
547
665
 
548
- return toForeignCallResult([toArray([...publicKeys.toFields(), partialAddress])]);
666
+ // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
667
+ // with two fields: `some` (a boolean) and `value` (a field array in this case).
668
+ if (!result.isSome()) {
669
+ // No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size.
670
+ // Wire shape: [npk_m_hash, ivpk_m.x, ivpk_m.y, ovpk_m_hash, tpk_m_hash, mspk_m_hash, fbpk_m_hash, partial_address] = 8 fields.
671
+ return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(8).fill(new Fr(0)))]);
672
+ } else {
673
+ // The Noir side hand-decodes a `[Field; 8]` here (see aztec-nr/aztec/src/oracle/keys.nr), so we
674
+ // emit the 7-field PublicKeys shape + partial_address explicitly
675
+ // rather than going through `publicKeys.toFields()` (which is the struct-flattened 8-field
676
+ // wire for oracle returns that decode via struct shape).
677
+ const { publicKeys, partialAddress } = result.value;
678
+ return toForeignCallResult([
679
+ toSingle(new Fr(1)),
680
+ toArray([
681
+ publicKeys.npkMHash,
682
+ publicKeys.ivpkM.x,
683
+ publicKeys.ivpkM.y,
684
+ publicKeys.ovpkMHash,
685
+ publicKeys.tpkMHash,
686
+ publicKeys.mspkMHash,
687
+ publicKeys.fbpkMHash,
688
+ partialAddress,
689
+ ]),
690
+ ]);
691
+ }
549
692
  }
550
693
 
551
- async utilityGetKeyValidationRequest(foreignPkMHash: ForeignCallSingle) {
694
+ // eslint-disable-next-line camelcase
695
+ async aztec_utl_getKeyValidationRequest(foreignPkMHash: ForeignCallSingle) {
552
696
  const pkMHash = fromSingle(foreignPkMHash);
553
697
 
554
- const keyValidationRequest = await this.handlerAsUtility().utilityGetKeyValidationRequest(pkMHash);
698
+ const keyValidationRequest = await this.handlerAsUtility().getKeyValidationRequest(pkMHash);
555
699
 
556
700
  return toForeignCallResult(keyValidationRequest.toFields().map(toSingle));
557
701
  }
558
702
 
559
- privateCallPrivateFunction(
560
- _foreignTargetContractAddress: ForeignCallSingle,
561
- _foreignFunctionSelector: ForeignCallSingle,
562
- _foreignArgsHash: ForeignCallSingle,
563
- _foreignSideEffectCounter: ForeignCallSingle,
564
- _foreignIsStaticCall: ForeignCallSingle,
703
+ // eslint-disable-next-line camelcase
704
+ async aztec_prv_callPrivateFunction(
705
+ foreignTargetContractAddress: ForeignCallSingle,
706
+ foreignFunctionSelector: ForeignCallSingle,
707
+ foreignArgsHash: ForeignCallSingle,
708
+ foreignSideEffectCounter: ForeignCallSingle,
709
+ foreignIsStaticCall: ForeignCallSingle,
565
710
  ) {
566
- throw new Error(
567
- 'Contract calls are forbidden inside a `TestEnvironment::private_context`, use `private_call` instead',
711
+ const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
712
+ const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
713
+ const argsHash = fromSingle(foreignArgsHash);
714
+ const sideEffectCounter = fromSingle(foreignSideEffectCounter).toNumber();
715
+ const isStaticCall = fromSingle(foreignIsStaticCall).toBool();
716
+
717
+ const { endSideEffectCounter, returnsHash } = await this.handlerAsPrivate().callPrivateFunction(
718
+ targetContractAddress,
719
+ functionSelector,
720
+ argsHash,
721
+ sideEffectCounter,
722
+ isStaticCall,
568
723
  );
724
+ return toForeignCallResult([[endSideEffectCounter, returnsHash].map(toSingle)]);
569
725
  }
570
726
 
571
- async utilityGetNullifierMembershipWitness(
572
- foreignBlockNumber: ForeignCallSingle,
727
+ // eslint-disable-next-line camelcase
728
+ async aztec_utl_getNullifierMembershipWitness(
729
+ foreignBlockHash: ForeignCallSingle,
573
730
  foreignNullifier: ForeignCallSingle,
574
731
  ) {
575
- const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
732
+ const blockHash = blockHashFromSingle(foreignBlockHash);
576
733
  const nullifier = fromSingle(foreignNullifier);
577
734
 
578
- const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockNumber, nullifier);
579
-
580
- if (!witness) {
581
- throw new Error(`Nullifier membership witness not found at block ${blockNumber}.`);
582
- }
735
+ const witness = await this.handlerAsUtility().getNullifierMembershipWitness(blockHash, nullifier);
583
736
  return toForeignCallResult(witness.toNoirRepresentation());
584
737
  }
585
738
 
586
- async utilityGetAuthWitness(foreignMessageHash: ForeignCallSingle) {
739
+ // eslint-disable-next-line camelcase
740
+ async aztec_utl_getAuthWitness(foreignMessageHash: ForeignCallSingle) {
587
741
  const messageHash = fromSingle(foreignMessageHash);
588
742
 
589
- const authWitness = await this.handlerAsUtility().utilityGetAuthWitness(messageHash);
590
-
591
- if (!authWitness) {
592
- throw new Error(`Auth witness not found for message hash ${messageHash}.`);
593
- }
743
+ const authWitness = await this.handlerAsUtility().getAuthWitness(messageHash);
594
744
  return toForeignCallResult([toArray(authWitness)]);
595
745
  }
596
746
 
597
- public privateNotifyEnqueuedPublicFunctionCall(
598
- _foreignTargetContractAddress: ForeignCallSingle,
599
- _foreignCalldataHash: ForeignCallSingle,
600
- _foreignSideEffectCounter: ForeignCallSingle,
601
- _foreignIsStaticCall: ForeignCallSingle,
602
- ) {
603
- throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
604
- }
605
-
606
- public privateNotifySetPublicTeardownFunctionCall(
607
- _foreignTargetContractAddress: ForeignCallSingle,
608
- _foreignCalldataHash: ForeignCallSingle,
609
- _foreignSideEffectCounter: ForeignCallSingle,
610
- _foreignIsStaticCall: ForeignCallSingle,
611
- ) {
612
- throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
747
+ // eslint-disable-next-line camelcase
748
+ public async aztec_prv_assertValidPublicCalldata(foreignCalldataHash: ForeignCallSingle) {
749
+ const calldataHash = fromSingle(foreignCalldataHash);
750
+ await this.handlerAsPrivate().assertValidPublicCalldata(calldataHash);
751
+ return toForeignCallResult([]);
613
752
  }
614
753
 
615
- public privateNotifySetMinRevertibleSideEffectCounter(_foreignMinRevertibleSideEffectCounter: ForeignCallSingle) {
616
- throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
754
+ // eslint-disable-next-line camelcase
755
+ public async aztec_prv_notifyRevertiblePhaseStart(foreignMinRevertibleSideEffectCounter: ForeignCallSingle) {
756
+ const minRevertibleSideEffectCounter = fromSingle(foreignMinRevertibleSideEffectCounter).toNumber();
757
+ await this.handlerAsPrivate().notifyRevertiblePhaseStart(minRevertibleSideEffectCounter);
758
+ return toForeignCallResult([]);
617
759
  }
618
760
 
619
- public async privateIsSideEffectCounterRevertible(foreignSideEffectCounter: ForeignCallSingle) {
761
+ // eslint-disable-next-line camelcase
762
+ public async aztec_prv_isExecutionInRevertiblePhase(foreignSideEffectCounter: ForeignCallSingle) {
620
763
  const sideEffectCounter = fromSingle(foreignSideEffectCounter).toNumber();
621
- const isRevertible = await this.handlerAsPrivate().privateIsSideEffectCounterRevertible(sideEffectCounter);
764
+ const isRevertible = await this.handlerAsPrivate().isExecutionInRevertiblePhase(sideEffectCounter);
622
765
  return toForeignCallResult([toSingle(new Fr(isRevertible))]);
623
766
  }
624
767
 
625
- utilityGetUtilityContext() {
626
- const context = this.handlerAsUtility().utilityGetUtilityContext();
768
+ // eslint-disable-next-line camelcase
769
+ aztec_utl_getUtilityContext() {
770
+ const context = this.handlerAsUtility().getUtilityContext();
627
771
 
628
772
  return toForeignCallResult(context.toNoirRepresentation());
629
773
  }
630
774
 
631
- async utilityGetBlockHeader(foreignBlockNumber: ForeignCallSingle) {
775
+ // eslint-disable-next-line camelcase
776
+ async aztec_utl_getBlockHeader(foreignBlockNumber: ForeignCallSingle) {
632
777
  const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
633
778
 
634
- const header = await this.handlerAsUtility().utilityGetBlockHeader(blockNumber);
635
-
636
- if (!header) {
637
- throw new Error(`Block header not found for block ${blockNumber}.`);
638
- }
779
+ const header = await this.handlerAsUtility().getBlockHeader(blockNumber);
639
780
  return toForeignCallResult(header.toFields().map(toSingle));
640
781
  }
641
782
 
642
- async utilityGetMembershipWitness(
643
- foreignBlockNumber: ForeignCallSingle,
644
- foreignTreeId: ForeignCallSingle,
645
- foreignLeafValue: ForeignCallSingle,
783
+ // eslint-disable-next-line camelcase
784
+ async aztec_utl_getNoteHashMembershipWitness(
785
+ foreignAnchorBlockHash: ForeignCallSingle,
786
+ foreignNoteHash: ForeignCallSingle,
646
787
  ) {
647
- const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
648
- const treeId = fromSingle(foreignTreeId).toNumber();
649
- const leafValue = fromSingle(foreignLeafValue);
788
+ const blockHash = blockHashFromSingle(foreignAnchorBlockHash);
789
+ const noteHash = fromSingle(foreignNoteHash);
650
790
 
651
- const witness = await this.handlerAsUtility().utilityGetMembershipWitness(blockNumber, treeId, leafValue);
791
+ const witness = await this.handlerAsUtility().getNoteHashMembershipWitness(blockHash, noteHash);
792
+ return toForeignCallResult(witness.toNoirRepresentation());
793
+ }
652
794
 
653
- if (!witness) {
654
- throw new Error(
655
- `Membership witness in tree ${MerkleTreeId[treeId]} not found for value ${leafValue} at block ${blockNumber}.`,
656
- );
657
- }
658
- return toForeignCallResult([toSingle(witness[0]), toArray(witness.slice(1))]);
795
+ // eslint-disable-next-line camelcase
796
+ async aztec_utl_getBlockHashMembershipWitness(
797
+ foreignAnchorBlockHash: ForeignCallSingle,
798
+ foreignBlockHash: ForeignCallSingle,
799
+ ) {
800
+ const anchorBlockHash = blockHashFromSingle(foreignAnchorBlockHash);
801
+ const blockHash = blockHashFromSingle(foreignBlockHash);
802
+
803
+ const witnessOpt = await this.handlerAsUtility().getBlockHashMembershipWitness(anchorBlockHash, blockHash);
804
+ const effective = witnessOpt.value ?? MembershipWitness.empty(ARCHIVE_HEIGHT);
805
+ return toForeignCallResult([toSingle(new Fr(witnessOpt.isSome() ? 1 : 0)), ...effective.toNoirRepresentation()]);
659
806
  }
660
807
 
661
- async utilityGetLowNullifierMembershipWitness(
662
- foreignBlockNumber: ForeignCallSingle,
808
+ // eslint-disable-next-line camelcase
809
+ async aztec_utl_getLowNullifierMembershipWitness(
810
+ foreignBlockHash: ForeignCallSingle,
663
811
  foreignNullifier: ForeignCallSingle,
664
812
  ) {
665
- const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
813
+ const blockHash = blockHashFromSingle(foreignBlockHash);
666
814
  const nullifier = fromSingle(foreignNullifier);
667
815
 
668
- const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockNumber, nullifier);
669
-
670
- if (!witness) {
671
- throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${blockNumber}.`);
672
- }
816
+ const witness = await this.handlerAsUtility().getLowNullifierMembershipWitness(blockHash, nullifier);
673
817
  return toForeignCallResult(witness.toNoirRepresentation());
674
818
  }
675
819
 
676
- async utilityFetchTaggedLogs(foreignPendingTaggedLogArrayBaseSlot: ForeignCallSingle) {
677
- const pendingTaggedLogArrayBaseSlot = fromSingle(foreignPendingTaggedLogArrayBaseSlot);
678
-
679
- await this.handlerAsUtility().utilityFetchTaggedLogs(pendingTaggedLogArrayBaseSlot);
680
-
681
- return toForeignCallResult([]);
820
+ // eslint-disable-next-line camelcase
821
+ async aztec_utl_getPendingTaggedLogs(foreignScope: ForeignCallSingle) {
822
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
823
+ const slot = await this.handlerAsUtility().getPendingTaggedLogs(scope);
824
+ return toForeignCallResult([toSingle(slot)]);
682
825
  }
683
826
 
684
- public async utilityValidateEnqueuedNotesAndEvents(
685
- foreignContractAddress: ForeignCallSingle,
827
+ // eslint-disable-next-line camelcase
828
+ public async aztec_utl_validateAndStoreEnqueuedNotesAndEvents(
686
829
  foreignNoteValidationRequestsArrayBaseSlot: ForeignCallSingle,
687
830
  foreignEventValidationRequestsArrayBaseSlot: ForeignCallSingle,
831
+ foreignScope: ForeignCallSingle,
688
832
  ) {
689
- const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
690
833
  const noteValidationRequestsArrayBaseSlot = fromSingle(foreignNoteValidationRequestsArrayBaseSlot);
691
834
  const eventValidationRequestsArrayBaseSlot = fromSingle(foreignEventValidationRequestsArrayBaseSlot);
835
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
692
836
 
693
- await this.handlerAsUtility().utilityValidateEnqueuedNotesAndEvents(
694
- contractAddress,
837
+ await this.handlerAsUtility().validateAndStoreEnqueuedNotesAndEvents(
695
838
  noteValidationRequestsArrayBaseSlot,
696
839
  eventValidationRequestsArrayBaseSlot,
840
+ scope,
697
841
  );
698
842
 
699
843
  return toForeignCallResult([]);
700
844
  }
701
845
 
702
- public async utilityBulkRetrieveLogs(
703
- foreignContractAddress: ForeignCallSingle,
704
- foreignLogRetrievalRequestsArrayBaseSlot: ForeignCallSingle,
705
- foreignLogRetrievalResponsesArrayBaseSlot: ForeignCallSingle,
706
- ) {
707
- const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
708
- const logRetrievalRequestsArrayBaseSlot = fromSingle(foreignLogRetrievalRequestsArrayBaseSlot);
709
- const logRetrievalResponsesArrayBaseSlot = fromSingle(foreignLogRetrievalResponsesArrayBaseSlot);
710
-
711
- await this.handlerAsUtility().utilityBulkRetrieveLogs(
712
- contractAddress,
713
- logRetrievalRequestsArrayBaseSlot,
714
- logRetrievalResponsesArrayBaseSlot,
715
- );
846
+ // eslint-disable-next-line camelcase
847
+ async aztec_utl_getLogsByTag(foreignRequestArrayBaseSlot: ForeignCallSingle) {
848
+ const requestArrayBaseSlot = fromSingle(foreignRequestArrayBaseSlot);
849
+ const responseSlot = await this.handlerAsUtility().getLogsByTag(requestArrayBaseSlot);
850
+ return toForeignCallResult([toSingle(responseSlot)]);
851
+ }
716
852
 
717
- return toForeignCallResult([]);
853
+ // eslint-disable-next-line camelcase
854
+ async aztec_utl_getMessageContextsByTxHash(foreignRequestArrayBaseSlot: ForeignCallSingle) {
855
+ const requestArrayBaseSlot = fromSingle(foreignRequestArrayBaseSlot);
856
+ const responseSlot = await this.handlerAsUtility().getMessageContextsByTxHash(requestArrayBaseSlot);
857
+ return toForeignCallResult([toSingle(responseSlot)]);
718
858
  }
719
859
 
720
- async utilityStoreCapsule(
860
+ // eslint-disable-next-line camelcase
861
+ aztec_utl_setCapsule(
721
862
  foreignContractAddress: ForeignCallSingle,
722
863
  foreignSlot: ForeignCallSingle,
723
864
  foreignCapsule: ForeignCallArray,
865
+ foreignScope: ForeignCallSingle,
724
866
  ) {
725
867
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
726
868
  const slot = fromSingle(foreignSlot);
727
869
  const capsule = fromArray(foreignCapsule);
870
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
728
871
 
729
- await this.handlerAsUtility().utilityStoreCapsule(contractAddress, slot, capsule);
872
+ this.handlerAsUtility().setCapsule(contractAddress, slot, capsule, scope);
730
873
 
731
874
  return toForeignCallResult([]);
732
875
  }
733
876
 
734
- async utilityLoadCapsule(
877
+ // eslint-disable-next-line camelcase
878
+ async aztec_utl_getCapsule(
735
879
  foreignContractAddress: ForeignCallSingle,
736
880
  foreignSlot: ForeignCallSingle,
737
881
  foreignTSize: ForeignCallSingle,
882
+ foreignScope: ForeignCallSingle,
738
883
  ) {
739
884
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
740
885
  const slot = fromSingle(foreignSlot);
741
886
  const tSize = fromSingle(foreignTSize).toNumber();
887
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
742
888
 
743
- const values = await this.handlerAsUtility().utilityLoadCapsule(contractAddress, slot);
889
+ const opt = await this.handlerAsUtility().getCapsule(contractAddress, slot, tSize, scope);
744
890
 
745
891
  // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
746
892
  // with two fields: `some` (a boolean) and `value` (a field array in this case).
747
- if (values === null) {
893
+ if (opt.isSome()) {
894
+ // Data was found so we set `some` to 1 and return it along with `value`.
895
+ return toForeignCallResult([toSingle(new Fr(1)), toArray(Array.from(opt.value))]);
896
+ } else {
748
897
  // No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size.
749
898
  return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(tSize).fill(new Fr(0)))]);
750
- } else {
751
- // Data was found so we set `some` to 1 and return it along with `value`.
752
- return toForeignCallResult([toSingle(new Fr(1)), toArray(values)]);
753
899
  }
754
900
  }
755
901
 
756
- async utilityDeleteCapsule(foreignContractAddress: ForeignCallSingle, foreignSlot: ForeignCallSingle) {
902
+ // eslint-disable-next-line camelcase
903
+ aztec_utl_deleteCapsule(
904
+ foreignContractAddress: ForeignCallSingle,
905
+ foreignSlot: ForeignCallSingle,
906
+ foreignScope: ForeignCallSingle,
907
+ ) {
757
908
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
758
909
  const slot = fromSingle(foreignSlot);
910
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
759
911
 
760
- await this.handlerAsUtility().utilityDeleteCapsule(contractAddress, slot);
912
+ this.handlerAsUtility().deleteCapsule(contractAddress, slot, scope);
761
913
 
762
914
  return toForeignCallResult([]);
763
915
  }
764
916
 
765
- async utilityCopyCapsule(
917
+ // eslint-disable-next-line camelcase
918
+ async aztec_utl_copyCapsule(
766
919
  foreignContractAddress: ForeignCallSingle,
767
920
  foreignSrcSlot: ForeignCallSingle,
768
921
  foreignDstSlot: ForeignCallSingle,
769
922
  foreignNumEntries: ForeignCallSingle,
923
+ foreignScope: ForeignCallSingle,
770
924
  ) {
771
925
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
772
926
  const srcSlot = fromSingle(foreignSrcSlot);
773
927
  const dstSlot = fromSingle(foreignDstSlot);
774
928
  const numEntries = fromSingle(foreignNumEntries).toNumber();
929
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
775
930
 
776
- await this.handlerAsUtility().utilityCopyCapsule(contractAddress, srcSlot, dstSlot, numEntries);
931
+ await this.handlerAsUtility().copyCapsule(contractAddress, srcSlot, dstSlot, numEntries, scope);
777
932
 
778
933
  return toForeignCallResult([]);
779
934
  }
780
935
 
936
+ // eslint-disable-next-line camelcase
937
+ aztec_utl_pushEphemeral(foreignSlot: ForeignCallSingle, foreignElements: ForeignCallArray) {
938
+ const slot = fromSingle(foreignSlot);
939
+ const elements = fromArray(foreignElements);
940
+ const newLen = this.handlerAsUtility().pushEphemeral(slot, elements);
941
+ return toForeignCallResult([toSingle(new Fr(newLen))]);
942
+ }
943
+
944
+ // eslint-disable-next-line camelcase
945
+ aztec_utl_popEphemeral(foreignSlot: ForeignCallSingle) {
946
+ const slot = fromSingle(foreignSlot);
947
+ const element = this.handlerAsUtility().popEphemeral(slot);
948
+ return toForeignCallResult([toArray(element)]);
949
+ }
950
+
951
+ // eslint-disable-next-line camelcase
952
+ aztec_utl_getEphemeral(foreignSlot: ForeignCallSingle, foreignIndex: ForeignCallSingle) {
953
+ const slot = fromSingle(foreignSlot);
954
+ const index = fromSingle(foreignIndex).toNumber();
955
+ const element = this.handlerAsUtility().getEphemeral(slot, index);
956
+ return toForeignCallResult([toArray(element)]);
957
+ }
958
+
959
+ // eslint-disable-next-line camelcase
960
+ aztec_utl_setEphemeral(
961
+ foreignSlot: ForeignCallSingle,
962
+ foreignIndex: ForeignCallSingle,
963
+ foreignElements: ForeignCallArray,
964
+ ) {
965
+ const slot = fromSingle(foreignSlot);
966
+ const index = fromSingle(foreignIndex).toNumber();
967
+ const elements = fromArray(foreignElements);
968
+ this.handlerAsUtility().setEphemeral(slot, index, elements);
969
+ return toForeignCallResult([]);
970
+ }
971
+
972
+ // eslint-disable-next-line camelcase
973
+ aztec_utl_getEphemeralLen(foreignSlot: ForeignCallSingle) {
974
+ const slot = fromSingle(foreignSlot);
975
+ const len = this.handlerAsUtility().getEphemeralLen(slot);
976
+ return toForeignCallResult([toSingle(new Fr(len))]);
977
+ }
978
+
979
+ // eslint-disable-next-line camelcase
980
+ aztec_utl_removeEphemeral(foreignSlot: ForeignCallSingle, foreignIndex: ForeignCallSingle) {
981
+ const slot = fromSingle(foreignSlot);
982
+ const index = fromSingle(foreignIndex).toNumber();
983
+ this.handlerAsUtility().removeEphemeral(slot, index);
984
+ return toForeignCallResult([]);
985
+ }
986
+
987
+ // eslint-disable-next-line camelcase
988
+ aztec_utl_clearEphemeral(foreignSlot: ForeignCallSingle) {
989
+ const slot = fromSingle(foreignSlot);
990
+ this.handlerAsUtility().clearEphemeral(slot);
991
+ return toForeignCallResult([]);
992
+ }
993
+
781
994
  // TODO: I forgot to add a corresponding function here, when I introduced an oracle method to txe_oracle.ts.
782
995
  // The compiler didn't throw an error, so it took me a while to learn of the existence of this file, and that I need
783
996
  // to implement this function here. Isn't there a way to programmatically identify that this is missing, given the
784
997
  // existence of a txe_oracle method?
785
- async utilityAes128Decrypt(
998
+ // eslint-disable-next-line camelcase
999
+ async aztec_utl_decryptAes128(
786
1000
  foreignCiphertextBVecStorage: ForeignCallArray,
787
1001
  foreignCiphertextLength: ForeignCallSingle,
788
1002
  foreignIv: ForeignCallArray,
789
1003
  foreignSymKey: ForeignCallArray,
790
1004
  ) {
791
- const ciphertext = fromUintBoundedVec(foreignCiphertextBVecStorage, foreignCiphertextLength, 8);
1005
+ const capacity = foreignCiphertextBVecStorage.length;
1006
+ const ciphertextBuf = fromUintBoundedVec(foreignCiphertextBVecStorage, foreignCiphertextLength, 8);
1007
+ const ciphertext = BoundedVec.from<number>({ data: [...ciphertextBuf], maxLength: capacity });
792
1008
  const iv = fromUintArray(foreignIv, 8);
793
1009
  const symKey = fromUintArray(foreignSymKey, 8);
794
1010
 
795
- const plaintextBuffer = await this.handlerAsUtility().utilityAes128Decrypt(ciphertext, iv, symKey);
796
-
797
- return toForeignCallResult(
798
- arrayToBoundedVec(bufferToU8Array(plaintextBuffer), foreignCiphertextBVecStorage.length),
799
- );
1011
+ // Noir Option<BoundedVec> is encoded as [is_some: Field, storage: Field[], length: Field].
1012
+ const plaintextOpt = await this.handlerAsUtility().decryptAes128(ciphertext, iv, symKey);
1013
+ if (plaintextOpt.isSome()) {
1014
+ const [storage, length] = arrayToBoundedVec(bufferToU8Array(Buffer.from(plaintextOpt.value.data)), capacity);
1015
+ return toForeignCallResult([toSingle(new Fr(1)), storage, length]);
1016
+ } else {
1017
+ const zeroStorage = toArray(Array(capacity).fill(new Fr(0)));
1018
+ return toForeignCallResult([toSingle(new Fr(0)), zeroStorage, toSingle(new Fr(0))]);
1019
+ }
800
1020
  }
801
1021
 
802
- async utilityGetSharedSecret(
1022
+ // eslint-disable-next-line camelcase
1023
+ async aztec_utl_getSharedSecrets(
803
1024
  foreignAddress: ForeignCallSingle,
804
- foreignEphPKField0: ForeignCallSingle,
805
- foreignEphPKField1: ForeignCallSingle,
806
- foreignEphPKField2: ForeignCallSingle,
1025
+ foreignEphPksSlot: ForeignCallSingle,
1026
+ foreignContractAddress: ForeignCallSingle,
807
1027
  ) {
808
1028
  const address = AztecAddress.fromField(fromSingle(foreignAddress));
809
- const ephPK = Point.fromFields([
810
- fromSingle(foreignEphPKField0),
811
- fromSingle(foreignEphPKField1),
812
- fromSingle(foreignEphPKField2),
813
- ]);
1029
+ const ephPksSlot = fromSingle(foreignEphPksSlot);
1030
+ const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
814
1031
 
815
- const secret = await this.handlerAsUtility().utilityGetSharedSecret(address, ephPK);
1032
+ const responseSlot = await this.handlerAsUtility().getSharedSecrets(address, ephPksSlot, contractAddress);
816
1033
 
817
- return toForeignCallResult(secret.toFields().map(toSingle));
1034
+ return toForeignCallResult([toSingle(responseSlot)]);
818
1035
  }
819
1036
 
820
- emitOffchainEffect(_foreignData: ForeignCallArray) {
821
- throw new Error('Offchain effects are not yet supported in the TestEnvironment');
1037
+ // eslint-disable-next-line camelcase
1038
+ aztec_utl_setContractSyncCacheInvalid(
1039
+ foreignContractAddress: ForeignCallSingle,
1040
+ foreignScopes: ForeignCallArray,
1041
+ foreignScopeCount: ForeignCallSingle,
1042
+ ) {
1043
+ const contractAddress = addressFromSingle(foreignContractAddress);
1044
+ const allFields = fromArray(foreignScopes);
1045
+ const count = fromSingle(foreignScopeCount).toNumber();
1046
+ const scopes = BoundedVec.from({
1047
+ data: allFields.slice(0, count).map(f => new AztecAddress(f)),
1048
+ maxLength: allFields.length,
1049
+ });
1050
+
1051
+ this.handlerAsUtility().setContractSyncCacheInvalid(contractAddress, scopes);
1052
+
1053
+ return Promise.resolve(toForeignCallResult([]));
1054
+ }
1055
+
1056
+ // eslint-disable-next-line camelcase
1057
+ aztec_utl_emitOffchainEffect(foreignData: ForeignCallArray) {
1058
+ // Record the raw payload against the currently-executing top-level call. The Noir side
1059
+ // (via `env.offchain_messages()`) is responsible for decoding the protocol-reserved prefix
1060
+ // (`OFFCHAIN_MESSAGE_IDENTIFIER`, recipient) and turning each payload into an `OffchainMessage` struct suitable
1061
+ // for `offchain_receive`.
1062
+ this.stateHandler.recordOffchainEffect(fromArray(foreignData));
1063
+ return Promise.resolve(toForeignCallResult([]));
822
1064
  }
823
1065
 
824
1066
  // AVM opcodes
825
1067
 
826
- avmOpcodeEmitUnencryptedLog(_foreignMessage: ForeignCallArray) {
1068
+ // eslint-disable-next-line camelcase
1069
+ aztec_avm_emitPublicLog(_foreignMessage: ForeignCallArray) {
827
1070
  // TODO(#8811): Implement
828
1071
  return toForeignCallResult([]);
829
1072
  }
830
1073
 
831
- async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle) {
1074
+ // eslint-disable-next-line camelcase
1075
+ async aztec_avm_storageRead(foreignSlot: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
832
1076
  const slot = fromSingle(foreignSlot);
1077
+ const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
833
1078
 
834
- const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot)).value;
1079
+ const value = (await this.handlerAsAvm().storageRead(slot, contractAddress)).value;
835
1080
 
836
1081
  return toForeignCallResult([toSingle(new Fr(value))]);
837
1082
  }
838
1083
 
839
- async avmOpcodeStorageWrite(foreignSlot: ForeignCallSingle, foreignValue: ForeignCallSingle) {
1084
+ // eslint-disable-next-line camelcase
1085
+ async aztec_avm_storageWrite(foreignSlot: ForeignCallSingle, foreignValue: ForeignCallSingle) {
840
1086
  const slot = fromSingle(foreignSlot);
841
1087
  const value = fromSingle(foreignValue);
842
1088
 
843
- await this.handlerAsAvm().avmOpcodeStorageWrite(slot, value);
1089
+ await this.handlerAsAvm().storageWrite(slot, value);
844
1090
 
845
1091
  return toForeignCallResult([]);
846
1092
  }
847
1093
 
848
- async avmOpcodeGetContractInstanceDeployer(foreignAddress: ForeignCallSingle) {
1094
+ // eslint-disable-next-line camelcase
1095
+ async aztec_avm_getContractInstanceDeployer(foreignAddress: ForeignCallSingle) {
849
1096
  const address = addressFromSingle(foreignAddress);
850
1097
 
851
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
1098
+ const instance = await this.handlerAsUtility().getContractInstance(address);
852
1099
 
853
1100
  return toForeignCallResult([
854
1101
  toSingle(instance.deployer),
@@ -857,10 +1104,11 @@ export class RPCTranslator {
857
1104
  ]);
858
1105
  }
859
1106
 
860
- async avmOpcodeGetContractInstanceClassId(foreignAddress: ForeignCallSingle) {
1107
+ // eslint-disable-next-line camelcase
1108
+ async aztec_avm_getContractInstanceClassId(foreignAddress: ForeignCallSingle) {
861
1109
  const address = addressFromSingle(foreignAddress);
862
1110
 
863
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
1111
+ const instance = await this.handlerAsUtility().getContractInstance(address);
864
1112
 
865
1113
  return toForeignCallResult([
866
1114
  toSingle(instance.currentContractClassId),
@@ -869,10 +1117,11 @@ export class RPCTranslator {
869
1117
  ]);
870
1118
  }
871
1119
 
872
- async avmOpcodeGetContractInstanceInitializationHash(foreignAddress: ForeignCallSingle) {
1120
+ // eslint-disable-next-line camelcase
1121
+ async aztec_avm_getContractInstanceInitializationHash(foreignAddress: ForeignCallSingle) {
873
1122
  const address = addressFromSingle(foreignAddress);
874
1123
 
875
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
1124
+ const instance = await this.handlerAsUtility().getContractInstance(address);
876
1125
 
877
1126
  return toForeignCallResult([
878
1127
  toSingle(instance.initializationHash),
@@ -881,203 +1130,315 @@ export class RPCTranslator {
881
1130
  ]);
882
1131
  }
883
1132
 
884
- async avmOpcodeSender() {
885
- const sender = await this.handlerAsAvm().avmOpcodeSender();
1133
+ // eslint-disable-next-line camelcase
1134
+ async aztec_avm_getContractInstanceImmutablesHash(foreignAddress: ForeignCallSingle) {
1135
+ const address = addressFromSingle(foreignAddress);
1136
+
1137
+ const instance = await this.handlerAsUtility().getContractInstance(address);
1138
+
1139
+ return toForeignCallResult([
1140
+ toSingle(instance.immutablesHash),
1141
+ // AVM requires an extra boolean indicating the instance was found
1142
+ toSingle(new Fr(1)),
1143
+ ]);
1144
+ }
1145
+
1146
+ // eslint-disable-next-line camelcase
1147
+ async aztec_avm_sender() {
1148
+ const sender = await this.handlerAsAvm().sender();
886
1149
 
887
1150
  return toForeignCallResult([toSingle(sender)]);
888
1151
  }
889
1152
 
890
- async avmOpcodeEmitNullifier(foreignNullifier: ForeignCallSingle) {
1153
+ // eslint-disable-next-line camelcase
1154
+ async aztec_avm_emitNullifier(foreignNullifier: ForeignCallSingle) {
891
1155
  const nullifier = fromSingle(foreignNullifier);
892
1156
 
893
- await this.handlerAsAvm().avmOpcodeEmitNullifier(nullifier);
1157
+ await this.handlerAsAvm().emitNullifier(nullifier);
894
1158
 
895
1159
  return toForeignCallResult([]);
896
1160
  }
897
1161
 
898
- async avmOpcodeEmitNoteHash(foreignNoteHash: ForeignCallSingle) {
1162
+ // eslint-disable-next-line camelcase
1163
+ async aztec_avm_emitNoteHash(foreignNoteHash: ForeignCallSingle) {
899
1164
  const noteHash = fromSingle(foreignNoteHash);
900
1165
 
901
- await this.handlerAsAvm().avmOpcodeEmitNoteHash(noteHash);
1166
+ await this.handlerAsAvm().emitNoteHash(noteHash);
902
1167
 
903
1168
  return toForeignCallResult([]);
904
1169
  }
905
1170
 
906
- async avmOpcodeNullifierExists(foreignInnerNullifier: ForeignCallSingle, foreignTargetAddress: ForeignCallSingle) {
907
- const innerNullifier = fromSingle(foreignInnerNullifier);
908
- const targetAddress = AztecAddress.fromField(fromSingle(foreignTargetAddress));
1171
+ // eslint-disable-next-line camelcase
1172
+ async aztec_avm_nullifierExists(foreignSiloedNullifier: ForeignCallSingle) {
1173
+ const siloedNullifier = fromSingle(foreignSiloedNullifier);
909
1174
 
910
- const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(innerNullifier, targetAddress);
1175
+ const exists = await this.handlerAsAvm().nullifierExists(siloedNullifier);
911
1176
 
912
1177
  return toForeignCallResult([toSingle(new Fr(exists))]);
913
1178
  }
914
1179
 
915
- async avmOpcodeAddress() {
916
- const contractAddress = await this.handlerAsAvm().avmOpcodeAddress();
1180
+ // eslint-disable-next-line camelcase
1181
+ async aztec_avm_address() {
1182
+ const contractAddress = await this.handlerAsAvm().address();
917
1183
 
918
1184
  return toForeignCallResult([toSingle(contractAddress.toField())]);
919
1185
  }
920
1186
 
921
- async avmOpcodeBlockNumber() {
922
- const blockNumber = await this.handlerAsAvm().avmOpcodeBlockNumber();
1187
+ // eslint-disable-next-line camelcase
1188
+ async aztec_avm_blockNumber() {
1189
+ const blockNumber = await this.handlerAsAvm().blockNumber();
923
1190
 
924
1191
  return toForeignCallResult([toSingle(new Fr(blockNumber))]);
925
1192
  }
926
1193
 
927
- async avmOpcodeTimestamp() {
928
- const timestamp = await this.handlerAsAvm().avmOpcodeTimestamp();
1194
+ // eslint-disable-next-line camelcase
1195
+ async aztec_avm_timestamp() {
1196
+ const timestamp = await this.handlerAsAvm().timestamp();
929
1197
 
930
1198
  return toForeignCallResult([toSingle(new Fr(timestamp))]);
931
1199
  }
932
1200
 
933
- async avmOpcodeIsStaticCall() {
934
- const isStaticCall = await this.handlerAsAvm().avmOpcodeIsStaticCall();
1201
+ // eslint-disable-next-line camelcase
1202
+ async aztec_avm_isStaticCall() {
1203
+ const isStaticCall = await this.handlerAsAvm().isStaticCall();
935
1204
 
936
1205
  return toForeignCallResult([toSingle(new Fr(isStaticCall ? 1 : 0))]);
937
1206
  }
938
1207
 
939
- async avmOpcodeChainId() {
940
- const chainId = await this.handlerAsAvm().avmOpcodeChainId();
1208
+ // eslint-disable-next-line camelcase
1209
+ async aztec_avm_chainId() {
1210
+ const chainId = await this.handlerAsAvm().chainId();
941
1211
 
942
1212
  return toForeignCallResult([toSingle(chainId)]);
943
1213
  }
944
1214
 
945
- async avmOpcodeVersion() {
946
- const version = await this.handlerAsAvm().avmOpcodeVersion();
1215
+ // eslint-disable-next-line camelcase
1216
+ async aztec_avm_version() {
1217
+ const version = await this.handlerAsAvm().version();
947
1218
 
948
1219
  return toForeignCallResult([toSingle(version)]);
949
1220
  }
950
1221
 
951
- avmOpcodeReturndataSize() {
952
- throw new Error(
953
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
954
- );
1222
+ // eslint-disable-next-line camelcase
1223
+ async aztec_avm_returndataSize() {
1224
+ const result = await this.handlerAsAvm().returndataSize();
1225
+ return toForeignCallResult([toSingle(result)]);
955
1226
  }
956
1227
 
957
- avmOpcodeReturndataCopy(_foreignRdOffset: ForeignCallSingle, _foreignCopySize: ForeignCallSingle) {
958
- throw new Error(
959
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
960
- );
1228
+ // eslint-disable-next-line camelcase
1229
+ async aztec_avm_returndataCopy(foreignRdOffset: ForeignCallSingle, foreignCopySize: ForeignCallSingle) {
1230
+ const rdOffset = fromSingle(foreignRdOffset).toNumber();
1231
+ const copySize = fromSingle(foreignCopySize).toNumber();
1232
+ const result = await this.handlerAsAvm().returndataCopy(rdOffset, copySize);
1233
+ return toForeignCallResult([toArray(result)]);
961
1234
  }
962
1235
 
963
- avmOpcodeCall(
964
- _foreignL2Gas: ForeignCallSingle,
965
- _foreignDaGas: ForeignCallSingle,
966
- _foreignAddress: ForeignCallSingle,
967
- _foreignLength: ForeignCallSingle,
968
- _foreignArgs: ForeignCallArray,
1236
+ // eslint-disable-next-line camelcase
1237
+ async aztec_avm_call(
1238
+ foreignL2Gas: ForeignCallSingle,
1239
+ foreignDaGas: ForeignCallSingle,
1240
+ foreignAddress: ForeignCallSingle,
1241
+ foreignLength: ForeignCallSingle,
1242
+ foreignArgs: ForeignCallArray,
969
1243
  ) {
970
- throw new Error(
971
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
972
- );
1244
+ const l2Gas = fromSingle(foreignL2Gas).toNumber();
1245
+ const daGas = fromSingle(foreignDaGas).toNumber();
1246
+ const address = addressFromSingle(foreignAddress);
1247
+ const argsLength = fromSingle(foreignLength).toNumber();
1248
+ const args = fromArray(foreignArgs);
1249
+ const result = await this.handlerAsAvm().call(l2Gas, daGas, address, argsLength, args);
1250
+ return toForeignCallResult([toArray(result)]);
973
1251
  }
974
1252
 
975
- avmOpcodeStaticCall(
976
- _foreignL2Gas: ForeignCallSingle,
977
- _foreignDaGas: ForeignCallSingle,
978
- _foreignAddress: ForeignCallSingle,
979
- _foreignLength: ForeignCallSingle,
980
- _foreignArgs: ForeignCallArray,
1253
+ // eslint-disable-next-line camelcase
1254
+ async aztec_avm_staticCall(
1255
+ foreignL2Gas: ForeignCallSingle,
1256
+ foreignDaGas: ForeignCallSingle,
1257
+ foreignAddress: ForeignCallSingle,
1258
+ foreignLength: ForeignCallSingle,
1259
+ foreignArgs: ForeignCallArray,
981
1260
  ) {
982
- throw new Error(
983
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
984
- );
1261
+ const l2Gas = fromSingle(foreignL2Gas).toNumber();
1262
+ const daGas = fromSingle(foreignDaGas).toNumber();
1263
+ const address = addressFromSingle(foreignAddress);
1264
+ const argsLength = fromSingle(foreignLength).toNumber();
1265
+ const args = fromArray(foreignArgs);
1266
+ const result = await this.handlerAsAvm().staticCall(l2Gas, daGas, address, argsLength, args);
1267
+ return toForeignCallResult([toArray(result)]);
985
1268
  }
986
1269
 
987
- avmOpcodeSuccessCopy() {
988
- throw new Error(
989
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
990
- );
1270
+ // eslint-disable-next-line camelcase
1271
+ async aztec_avm_successCopy() {
1272
+ const result = await this.handlerAsAvm().successCopy();
1273
+ return toForeignCallResult([toSingle(result)]);
991
1274
  }
992
1275
 
993
- async txePrivateCallNewFlow(
994
- foreignFrom: ForeignCallSingle,
1276
+ // TODO(F-674): Move orchestration logic into the handler so the transport layer is pure serialize→delegate→deserialize.
1277
+ // eslint-disable-next-line camelcase
1278
+ async aztec_txe_privateCallNewFlow(
1279
+ foreignFromIsSome: ForeignCallSingle,
1280
+ foreignFromValue: ForeignCallSingle,
995
1281
  foreignTargetContractAddress: ForeignCallSingle,
996
1282
  foreignFunctionSelector: ForeignCallSingle,
997
1283
  foreignArgs: ForeignCallArray,
998
1284
  foreignArgsHash: ForeignCallSingle,
999
1285
  foreignIsStaticCall: ForeignCallSingle,
1286
+ foreignAdditionalScopes: ForeignCallArray,
1287
+ foreignAuthorizedUtilityCallTargets: ForeignCallArray,
1288
+ foreignGasSettings: ForeignCallArray,
1000
1289
  ) {
1001
- const from = addressFromSingle(foreignFrom);
1290
+ const from = fromSingle(foreignFromIsSome).toBool() ? addressFromSingle(foreignFromValue) : undefined;
1002
1291
  const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
1003
1292
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
1004
1293
  const args = fromArray(foreignArgs);
1005
1294
  const argsHash = fromSingle(foreignArgsHash);
1006
1295
  const isStaticCall = fromSingle(foreignIsStaticCall).toBool();
1007
-
1008
- const returnValues = await this.handlerAsTxe().txePrivateCallNewFlow(
1009
- from,
1010
- targetContractAddress,
1011
- functionSelector,
1012
- args,
1013
- argsHash,
1014
- isStaticCall,
1296
+ const additionalScopes = fromArray(foreignAdditionalScopes).map(field => AztecAddress.fromField(field));
1297
+ const authorizedUtilityCallTargets = fromArray(foreignAuthorizedUtilityCallTargets).map(field =>
1298
+ AztecAddress.fromField(field),
1015
1299
  );
1300
+ const gasSettings = GasSettings.fromFields(fromArray(foreignGasSettings));
1301
+
1302
+ const returnValues = await this.stateHandler.withTopLevelCallTracking(async () => {
1303
+ const { returnValues, offchainEffects } = await this.handlerAsTxe().privateCallNewFlow(
1304
+ from,
1305
+ targetContractAddress,
1306
+ functionSelector,
1307
+ args,
1308
+ argsHash,
1309
+ isStaticCall,
1310
+ additionalScopes,
1311
+ this.stateHandler.getCurrentJob(),
1312
+ authorizedUtilityCallTargets,
1313
+ gasSettings,
1314
+ );
1315
+
1316
+ // Private execution collects offchain effects inside PXE's PrivateExecutionOracle rather than
1317
+ // round-tripping them through `aztec_utl_emitOffchainEffect`, so the session buffer is empty
1318
+ // at this point. Drain the effects from the execution tree into the session buffer so the
1319
+ // next `env.offchain_messages()` call in the test sees them.
1320
+ for (const data of offchainEffects) {
1321
+ this.stateHandler.recordOffchainEffect(data);
1322
+ }
1323
+
1324
+ // TODO(F-335): Avoid doing the following call here.
1325
+ await this.stateHandler.cycleJob();
1326
+
1327
+ if (isStaticCall) {
1328
+ // Static calls revert their checkpoint and mine no block, so there is no tx hash to tag
1329
+ // offchain effects with. Querying `getLastTxEffects()` here would return an unrelated
1330
+ // predecessor tx.
1331
+ return { result: returnValues };
1332
+ }
1333
+ const { txHash } = await this.handlerAsTxe().getLastTxEffects();
1334
+ return { result: returnValues, txHash: txHash.hash };
1335
+ });
1016
1336
 
1017
1337
  return toForeignCallResult([toArray(returnValues)]);
1018
1338
  }
1019
1339
 
1020
- async txeSimulateUtilityFunction(
1340
+ // TODO(F-674): Move orchestration logic into the handler so the transport layer is pure serialize→delegate→deserialize.
1341
+ // eslint-disable-next-line camelcase
1342
+ async aztec_txe_executeUtilityFunction(
1021
1343
  foreignTargetContractAddress: ForeignCallSingle,
1022
1344
  foreignFunctionSelector: ForeignCallSingle,
1023
1345
  foreignArgs: ForeignCallArray,
1346
+ foreignAuthorizedUtilityCallTargets: ForeignCallArray,
1024
1347
  ) {
1025
1348
  const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
1026
1349
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
1027
1350
  const args = fromArray(foreignArgs);
1028
-
1029
- const returnValues = await this.handlerAsTxe().txeSimulateUtilityFunction(
1030
- targetContractAddress,
1031
- functionSelector,
1032
- args,
1351
+ const authorizedUtilityCallTargets = fromArray(foreignAuthorizedUtilityCallTargets).map(field =>
1352
+ AztecAddress.fromField(field),
1033
1353
  );
1034
1354
 
1355
+ const returnValues = await this.stateHandler.withTopLevelCallTracking(async () => {
1356
+ const returnValues = await this.handlerAsTxe().executeUtilityFunction(
1357
+ targetContractAddress,
1358
+ functionSelector,
1359
+ args,
1360
+ this.stateHandler.getCurrentJob(),
1361
+ authorizedUtilityCallTargets,
1362
+ );
1363
+
1364
+ // TODO(F-335): Avoid doing the following call here.
1365
+ await this.stateHandler.cycleJob();
1366
+
1367
+ return { result: returnValues };
1368
+ });
1369
+
1035
1370
  return toForeignCallResult([toArray(returnValues)]);
1036
1371
  }
1037
1372
 
1038
- async txePublicCallNewFlow(
1039
- foreignFrom: ForeignCallSingle,
1373
+ // TODO(F-674): Move orchestration logic into the handler so the transport layer is pure serialize→delegate→deserialize.
1374
+ // eslint-disable-next-line camelcase
1375
+ async aztec_txe_publicCallNewFlow(
1376
+ foreignFromIsSome: ForeignCallSingle,
1377
+ foreignFromValue: ForeignCallSingle,
1040
1378
  foreignAddress: ForeignCallSingle,
1041
1379
  foreignCalldata: ForeignCallArray,
1042
1380
  foreignIsStaticCall: ForeignCallSingle,
1381
+ foreignGasSettings: ForeignCallArray,
1043
1382
  ) {
1044
- const from = addressFromSingle(foreignFrom);
1383
+ const from = fromSingle(foreignFromIsSome).toBool() ? addressFromSingle(foreignFromValue) : undefined;
1045
1384
  const address = addressFromSingle(foreignAddress);
1046
1385
  const calldata = fromArray(foreignCalldata);
1047
1386
  const isStaticCall = fromSingle(foreignIsStaticCall).toBool();
1387
+ const gasSettings = GasSettings.fromFields(fromArray(foreignGasSettings));
1388
+
1389
+ const returnValues = await this.stateHandler.withTopLevelCallTracking(async () => {
1390
+ const returnValues = await this.handlerAsTxe().publicCallNewFlow(
1391
+ from,
1392
+ address,
1393
+ calldata,
1394
+ isStaticCall,
1395
+ gasSettings,
1396
+ );
1397
+
1398
+ // TODO(F-335): Avoid doing the following call here.
1399
+ await this.stateHandler.cycleJob();
1048
1400
 
1049
- const returnValues = await this.handlerAsTxe().txePublicCallNewFlow(from, address, calldata, isStaticCall);
1401
+ if (isStaticCall) {
1402
+ // See equivalent branch in `aztec_txe_privateCallNewFlow`.
1403
+ return { result: returnValues };
1404
+ }
1405
+ const { txHash } = await this.handlerAsTxe().getLastTxEffects();
1406
+ return { result: returnValues, txHash: txHash.hash };
1407
+ });
1050
1408
 
1051
1409
  return toForeignCallResult([toArray(returnValues)]);
1052
1410
  }
1053
1411
 
1054
- async privateGetSenderForTags() {
1055
- const sender = await this.handlerAsPrivate().privateGetSenderForTags();
1412
+ // eslint-disable-next-line camelcase
1413
+ async aztec_prv_getSenderForTags() {
1414
+ const senderOpt = await this.handlerAsPrivate().getSenderForTags();
1056
1415
 
1057
1416
  // Return a Noir Option struct with `some` and `value` fields
1058
- if (sender === undefined) {
1417
+ if (senderOpt.isSome()) {
1418
+ // Sender found, return Option with some=1 and value=sender address
1419
+ return toForeignCallResult([toSingle(1), toSingle(senderOpt.value)]);
1420
+ } else {
1059
1421
  // No sender found, return Option with some=0 and value=0
1060
1422
  return toForeignCallResult([toSingle(0), toSingle(0)]);
1061
- } else {
1062
- // Sender found, return Option with some=1 and value=sender address
1063
- return toForeignCallResult([toSingle(1), toSingle(sender)]);
1064
1423
  }
1065
1424
  }
1066
1425
 
1067
- async privateSetSenderForTags(foreignSenderForTags: ForeignCallSingle) {
1068
- const senderForTags = AztecAddress.fromField(fromSingle(foreignSenderForTags));
1426
+ // eslint-disable-next-line camelcase
1427
+ async aztec_prv_getNextAppTagAsSender(foreignSender: ForeignCallSingle, foreignRecipient: ForeignCallSingle) {
1428
+ const sender = AztecAddress.fromField(fromSingle(foreignSender));
1429
+ const recipient = AztecAddress.fromField(fromSingle(foreignRecipient));
1069
1430
 
1070
- await this.handlerAsPrivate().privateSetSenderForTags(senderForTags);
1431
+ const nextAppTag = await this.handlerAsPrivate().getNextAppTagAsSender(sender, recipient);
1071
1432
 
1072
- return toForeignCallResult([]);
1433
+ return toForeignCallResult([toSingle(nextAppTag.value)]);
1073
1434
  }
1074
1435
 
1075
- async privateGetNextAppTagAsSender(foreignSender: ForeignCallSingle, foreignRecipient: ForeignCallSingle) {
1076
- const sender = AztecAddress.fromField(fromSingle(foreignSender));
1077
- const recipient = AztecAddress.fromField(fromSingle(foreignRecipient));
1436
+ // eslint-disable-next-line camelcase
1437
+ async aztec_prv_getNextConstrainedTaggingIndex(foreignAppSiloedSecret: ForeignCallSingle) {
1438
+ const appSiloedSecret = fromSingle(foreignAppSiloedSecret);
1078
1439
 
1079
- const nextAppTag = await this.handlerAsPrivate().privateGetNextAppTagAsSender(sender, recipient);
1440
+ const index = await this.handlerAsPrivate().getNextConstrainedTaggingIndex(appSiloedSecret);
1080
1441
 
1081
- return toForeignCallResult([toSingle(nextAppTag.value)]);
1442
+ return toForeignCallResult([toSingle(new Fr(index))]);
1082
1443
  }
1083
1444
  }