@aztec/txe 0.0.1-commit.fffb133c → 0.0.1-dev

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