@aztec/txe 0.0.1-commit.7b97ef96e → 0.0.1-commit.7cbc774

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 (126) 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 -1
  23. package/dest/constants.d.ts.map +1 -1
  24. package/dest/constants.js +5 -0
  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 +160 -119
  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 +27 -12
  40. package/dest/oracle/txe_oracle_top_level_context.d.ts +38 -22
  41. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  42. package/dest/oracle/txe_oracle_top_level_context.js +141 -72
  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 +139 -83
  50. package/dest/rpc_translator.d.ts.map +1 -1
  51. package/dest/rpc_translator.js +574 -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 +4 -4
  55. package/dest/state_machine/archiver.d.ts.map +1 -1
  56. package/dest/state_machine/archiver.js +22 -20
  57. package/dest/state_machine/dummy_p2p_client.d.ts +14 -8
  58. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  59. package/dest/state_machine/dummy_p2p_client.js +17 -5
  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 +7 -3
  64. package/dest/state_machine/index.d.ts.map +1 -1
  65. package/dest/state_machine/index.js +23 -5
  66. package/dest/state_machine/mock_epoch_cache.d.ts +18 -3
  67. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  68. package/dest/state_machine/mock_epoch_cache.js +35 -2
  69. package/dest/state_machine/synchronizer.d.ts +5 -5
  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 +69 -6
  76. package/dest/txe_session.d.ts.map +1 -1
  77. package/dest/txe_session.js +170 -35
  78. package/dest/utils/encoding.d.ts +191 -0
  79. package/dest/utils/encoding.d.ts.map +1 -0
  80. package/dest/{util → utils}/encoding.js +7 -2
  81. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  82. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  83. package/dest/{util → utils}/txe_account_store.d.ts +1 -1
  84. package/dest/utils/txe_account_store.d.ts.map +1 -0
  85. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  86. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  87. package/dest/{util → utils}/txe_public_contract_data_source.js +1 -3
  88. package/dest/worker.bundle.js +3 -0
  89. package/dest/worker.bundle.js.map +7 -0
  90. package/dest/worker.d.ts +2 -0
  91. package/dest/worker.d.ts.map +1 -0
  92. package/dest/worker.js +92 -0
  93. package/package.json +37 -21
  94. package/src/bin/check_txe_oracle_version.ts +37 -0
  95. package/src/bin/index.ts +11 -2
  96. package/src/constants.ts +6 -0
  97. package/src/dispatcher_pool.ts +316 -0
  98. package/src/index.ts +178 -126
  99. package/src/msgpackr_fr_extension.ts +23 -0
  100. package/src/oracle/interfaces.ts +48 -34
  101. package/src/oracle/txe_oracle_public_context.ts +42 -12
  102. package/src/oracle/txe_oracle_top_level_context.ts +176 -83
  103. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  104. package/src/rpc_server.ts +87 -0
  105. package/src/rpc_translator.ts +654 -319
  106. package/src/state_machine/archiver.ts +33 -18
  107. package/src/state_machine/dummy_p2p_client.ts +32 -12
  108. package/src/state_machine/global_variable_builder.ts +18 -3
  109. package/src/state_machine/index.ts +25 -6
  110. package/src/state_machine/mock_epoch_cache.ts +46 -3
  111. package/src/state_machine/synchronizer.ts +5 -5
  112. package/src/txe_oracle_version.ts +17 -0
  113. package/src/txe_session.ts +269 -37
  114. package/src/{util → utils}/encoding.ts +8 -2
  115. package/src/{util → utils}/txe_public_contract_data_source.ts +0 -2
  116. package/src/worker.ts +98 -0
  117. package/dest/util/encoding.d.ts +0 -720
  118. package/dest/util/encoding.d.ts.map +0 -1
  119. package/dest/util/expected_failure_error.d.ts.map +0 -1
  120. package/dest/util/txe_account_store.d.ts.map +0 -1
  121. package/dest/util/txe_public_contract_data_source.d.ts +0 -20
  122. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  123. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  124. /package/dest/{util → utils}/txe_account_store.js +0 -0
  125. /package/src/{util → utils}/expected_failure_error.ts +0 -0
  126. /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,
17
+ Option,
9
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 { BlockHash } from '@aztec/stdlib/block';
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
- async utilityLog(
441
+ // eslint-disable-next-line camelcase
442
+ async aztec_utl_log(
332
443
  foreignLevel: ForeignCallSingle,
333
444
  foreignMessage: ForeignCallArray,
334
445
  _foreignLength: ForeignCallSingle,
@@ -340,23 +451,24 @@ export class RPCTranslator {
340
451
  .join('');
341
452
  const fields = fromArray(foreignFields);
342
453
 
343
- await this.handlerAsMisc().utilityLog(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(
349
461
  foreignBlockHash: ForeignCallSingle,
350
462
  foreignContractAddress: ForeignCallSingle,
351
463
  foreignStartStorageSlot: ForeignCallSingle,
352
464
  foreignNumberOfElements: ForeignCallSingle,
353
465
  ) {
354
- const blockHash = new BlockHash(fromSingle(foreignBlockHash));
466
+ const blockHash = blockHashFromSingle(foreignBlockHash);
355
467
  const contractAddress = addressFromSingle(foreignContractAddress);
356
468
  const startStorageSlot = fromSingle(foreignStartStorageSlot);
357
469
  const numberOfElements = fromSingle(foreignNumberOfElements).toNumber();
358
470
 
359
- const values = await this.handlerAsUtility().utilityStorageRead(
471
+ const values = await this.handlerAsUtility().getFromPublicStorage(
360
472
  blockHash,
361
473
  contractAddress,
362
474
  startStorageSlot,
@@ -366,19 +478,17 @@ export class RPCTranslator {
366
478
  return toForeignCallResult([toArray(values)]);
367
479
  }
368
480
 
369
- async utilityGetPublicDataWitness(foreignBlockHash: ForeignCallSingle, foreignLeafSlot: ForeignCallSingle) {
370
- const blockHash = new BlockHash(fromSingle(foreignBlockHash));
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(blockHash, leafSlot);
374
-
375
- if (!witness) {
376
- throw new Error(`Public data witness not found for slot ${leafSlot} at block ${blockHash.toString()}.`);
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,
@@ -400,8 +510,8 @@ export class RPCTranslator {
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());
@@ -419,7 +529,7 @@ export class RPCTranslator {
419
529
  const maxNotes = fromSingle(foreignMaxNotes).toNumber();
420
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,9 +545,11 @@ 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 =>
552
+ const returnDataAsArrayOfArrays = Array.from(noteVec.data).map(noteData =>
441
553
  packAsHintedNote({
442
554
  contractAddress: noteData.contractAddress,
443
555
  owner: noteData.owner,
@@ -449,18 +561,17 @@ export class RPCTranslator {
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
569
  arrayOfArraysToBoundedVecOfArrays(returnDataAsArrayOfForeignCallSingleArrays, maxNotes, packedHintedNoteLength),
460
570
  );
461
571
  }
462
572
 
463
- privateNotifyCreatedNote(
573
+ // eslint-disable-next-line camelcase
574
+ aztec_prv_notifyCreatedNote(
464
575
  foreignOwner: ForeignCallSingle,
465
576
  foreignStorageSlot: ForeignCallSingle,
466
577
  foreignRandomness: ForeignCallSingle,
@@ -477,20 +588,13 @@ export class RPCTranslator {
477
588
  const noteHash = fromSingle(foreignNoteHash);
478
589
  const counter = fromSingle(foreignCounter).toNumber();
479
590
 
480
- this.handlerAsPrivate().privateNotifyCreatedNote(
481
- owner,
482
- storageSlot,
483
- randomness,
484
- noteTypeId,
485
- note,
486
- noteHash,
487
- counter,
488
- );
591
+ this.handlerAsPrivate().notifyCreatedNote(owner, storageSlot, randomness, noteTypeId, note, noteHash, counter);
489
592
 
490
593
  return toForeignCallResult([]);
491
594
  }
492
595
 
493
- async privateNotifyNullifiedNote(
596
+ // eslint-disable-next-line camelcase
597
+ async aztec_prv_notifyNullifiedNote(
494
598
  foreignInnerNullifier: ForeignCallSingle,
495
599
  foreignNoteHash: ForeignCallSingle,
496
600
  foreignCounter: ForeignCallSingle,
@@ -499,40 +603,47 @@ export class RPCTranslator {
499
603
  const noteHash = fromSingle(foreignNoteHash);
500
604
  const counter = fromSingle(foreignCounter).toNumber();
501
605
 
502
- await this.handlerAsPrivate().privateNotifyNullifiedNote(innerNullifier, noteHash, counter);
606
+ await this.handlerAsPrivate().notifyNullifiedNote(innerNullifier, noteHash, counter);
503
607
 
504
608
  return toForeignCallResult([]);
505
609
  }
506
610
 
507
- async privateNotifyCreatedNullifier(foreignInnerNullifier: ForeignCallSingle) {
611
+ // eslint-disable-next-line camelcase
612
+ async aztec_prv_notifyCreatedNullifier(foreignInnerNullifier: ForeignCallSingle) {
508
613
  const innerNullifier = fromSingle(foreignInnerNullifier);
509
614
 
510
- await this.handlerAsPrivate().privateNotifyCreatedNullifier(innerNullifier);
615
+ await this.handlerAsPrivate().notifyCreatedNullifier(innerNullifier);
511
616
 
512
617
  return toForeignCallResult([]);
513
618
  }
514
619
 
515
- async privateIsNullifierPending(foreignInnerNullifier: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
620
+ // eslint-disable-next-line camelcase
621
+ async aztec_prv_isNullifierPending(
622
+ foreignInnerNullifier: ForeignCallSingle,
623
+ foreignContractAddress: ForeignCallSingle,
624
+ ) {
516
625
  const innerNullifier = fromSingle(foreignInnerNullifier);
517
626
  const contractAddress = addressFromSingle(foreignContractAddress);
518
627
 
519
- const isPending = await this.handlerAsPrivate().privateIsNullifierPending(innerNullifier, contractAddress);
628
+ const isPending = await this.handlerAsPrivate().isNullifierPending(innerNullifier, contractAddress);
520
629
 
521
630
  return toForeignCallResult([toSingle(new Fr(isPending))]);
522
631
  }
523
632
 
524
- async utilityCheckNullifierExists(foreignInnerNullifier: ForeignCallSingle) {
633
+ // eslint-disable-next-line camelcase
634
+ async aztec_utl_doesNullifierExist(foreignInnerNullifier: ForeignCallSingle) {
525
635
  const innerNullifier = fromSingle(foreignInnerNullifier);
526
636
 
527
- const exists = await this.handlerAsUtility().utilityCheckNullifierExists(innerNullifier);
637
+ const exists = await this.handlerAsUtility().doesNullifierExist(innerNullifier);
528
638
 
529
639
  return toForeignCallResult([toSingle(new Fr(exists))]);
530
640
  }
531
641
 
532
- async utilityGetContractInstance(foreignAddress: ForeignCallSingle) {
642
+ // eslint-disable-next-line camelcase
643
+ async aztec_utl_getContractInstance(foreignAddress: ForeignCallSingle) {
533
644
  const address = addressFromSingle(foreignAddress);
534
645
 
535
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
646
+ const instance = await this.handlerAsUtility().getContractInstance(address);
536
647
 
537
648
  return toForeignCallResult(
538
649
  [
@@ -540,342 +651,451 @@ export class RPCTranslator {
540
651
  instance.deployer.toField(),
541
652
  instance.currentContractClassId,
542
653
  instance.initializationHash,
654
+ instance.immutablesHash,
543
655
  ...instance.publicKeys.toFields(),
544
656
  ].map(toSingle),
545
657
  );
546
658
  }
547
659
 
548
- async utilityTryGetPublicKeysAndPartialAddress(foreignAddress: ForeignCallSingle) {
660
+ // eslint-disable-next-line camelcase
661
+ async aztec_utl_getPublicKeysAndPartialAddress(foreignAddress: ForeignCallSingle) {
549
662
  const address = addressFromSingle(foreignAddress);
550
663
 
551
- const result = await this.handlerAsUtility().utilityTryGetPublicKeysAndPartialAddress(address);
664
+ const result = await this.handlerAsUtility().getPublicKeysAndPartialAddress(address);
552
665
 
553
666
  // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
554
667
  // with two fields: `some` (a boolean) and `value` (a field array in this case).
555
- if (result === undefined) {
668
+ if (!result.isSome()) {
556
669
  // No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size.
557
- return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(13).fill(new Fr(0)))]);
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)))]);
558
672
  } else {
559
- // Data was found so we set `some` to 1 and return it along with `value`.
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;
560
678
  return toForeignCallResult([
561
679
  toSingle(new Fr(1)),
562
- toArray([...result.publicKeys.toFields(), result.partialAddress]),
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
+ ]),
563
690
  ]);
564
691
  }
565
692
  }
566
693
 
567
- async utilityGetKeyValidationRequest(foreignPkMHash: ForeignCallSingle) {
694
+ // eslint-disable-next-line camelcase
695
+ async aztec_utl_getKeyValidationRequest(foreignPkMHash: ForeignCallSingle) {
568
696
  const pkMHash = fromSingle(foreignPkMHash);
569
697
 
570
- const keyValidationRequest = await this.handlerAsUtility().utilityGetKeyValidationRequest(pkMHash);
698
+ const keyValidationRequest = await this.handlerAsUtility().getKeyValidationRequest(pkMHash);
571
699
 
572
700
  return toForeignCallResult(keyValidationRequest.toFields().map(toSingle));
573
701
  }
574
702
 
575
- privateCallPrivateFunction(
576
- _foreignTargetContractAddress: ForeignCallSingle,
577
- _foreignFunctionSelector: ForeignCallSingle,
578
- _foreignArgsHash: ForeignCallSingle,
579
- _foreignSideEffectCounter: ForeignCallSingle,
580
- _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,
581
710
  ) {
582
- throw new Error(
583
- '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,
584
723
  );
724
+ return toForeignCallResult([[endSideEffectCounter, returnsHash].map(toSingle)]);
585
725
  }
586
726
 
587
- async utilityGetNullifierMembershipWitness(foreignBlockHash: ForeignCallSingle, foreignNullifier: ForeignCallSingle) {
588
- const blockHash = new BlockHash(fromSingle(foreignBlockHash));
727
+ // eslint-disable-next-line camelcase
728
+ async aztec_utl_getNullifierMembershipWitness(
729
+ foreignBlockHash: ForeignCallSingle,
730
+ foreignNullifier: ForeignCallSingle,
731
+ ) {
732
+ const blockHash = blockHashFromSingle(foreignBlockHash);
589
733
  const nullifier = fromSingle(foreignNullifier);
590
734
 
591
- const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockHash, nullifier);
592
-
593
- if (!witness) {
594
- throw new Error(`Nullifier membership witness not found at block ${blockHash}.`);
595
- }
735
+ const witness = await this.handlerAsUtility().getNullifierMembershipWitness(blockHash, nullifier);
596
736
  return toForeignCallResult(witness.toNoirRepresentation());
597
737
  }
598
738
 
599
- async utilityGetAuthWitness(foreignMessageHash: ForeignCallSingle) {
739
+ // eslint-disable-next-line camelcase
740
+ async aztec_utl_getAuthWitness(foreignMessageHash: ForeignCallSingle) {
600
741
  const messageHash = fromSingle(foreignMessageHash);
601
742
 
602
- const authWitness = await this.handlerAsUtility().utilityGetAuthWitness(messageHash);
603
-
604
- if (!authWitness) {
605
- throw new Error(`Auth witness not found for message hash ${messageHash}.`);
606
- }
743
+ const authWitness = await this.handlerAsUtility().getAuthWitness(messageHash);
607
744
  return toForeignCallResult([toArray(authWitness)]);
608
745
  }
609
746
 
610
- public privateNotifyEnqueuedPublicFunctionCall(
611
- _foreignTargetContractAddress: ForeignCallSingle,
612
- _foreignCalldataHash: ForeignCallSingle,
613
- _foreignSideEffectCounter: ForeignCallSingle,
614
- _foreignIsStaticCall: ForeignCallSingle,
615
- ) {
616
- throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
617
- }
618
-
619
- public privateNotifySetPublicTeardownFunctionCall(
620
- _foreignTargetContractAddress: ForeignCallSingle,
621
- _foreignCalldataHash: ForeignCallSingle,
622
- _foreignSideEffectCounter: ForeignCallSingle,
623
- _foreignIsStaticCall: ForeignCallSingle,
624
- ) {
625
- 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([]);
626
752
  }
627
753
 
628
- public privateNotifySetMinRevertibleSideEffectCounter(_foreignMinRevertibleSideEffectCounter: ForeignCallSingle) {
629
- 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([]);
630
759
  }
631
760
 
632
- public async privateIsSideEffectCounterRevertible(foreignSideEffectCounter: ForeignCallSingle) {
761
+ // eslint-disable-next-line camelcase
762
+ public async aztec_prv_isExecutionInRevertiblePhase(foreignSideEffectCounter: ForeignCallSingle) {
633
763
  const sideEffectCounter = fromSingle(foreignSideEffectCounter).toNumber();
634
- const isRevertible = await this.handlerAsPrivate().privateIsSideEffectCounterRevertible(sideEffectCounter);
764
+ const isRevertible = await this.handlerAsPrivate().isExecutionInRevertiblePhase(sideEffectCounter);
635
765
  return toForeignCallResult([toSingle(new Fr(isRevertible))]);
636
766
  }
637
767
 
638
- utilityGetUtilityContext() {
639
- const context = this.handlerAsUtility().utilityGetUtilityContext();
768
+ // eslint-disable-next-line camelcase
769
+ aztec_utl_getUtilityContext() {
770
+ const context = this.handlerAsUtility().getUtilityContext();
640
771
 
641
772
  return toForeignCallResult(context.toNoirRepresentation());
642
773
  }
643
774
 
644
- async utilityGetBlockHeader(foreignBlockNumber: ForeignCallSingle) {
775
+ // eslint-disable-next-line camelcase
776
+ async aztec_utl_getBlockHeader(foreignBlockNumber: ForeignCallSingle) {
645
777
  const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
646
778
 
647
- const header = await this.handlerAsUtility().utilityGetBlockHeader(blockNumber);
648
-
649
- if (!header) {
650
- throw new Error(`Block header not found for block ${blockNumber}.`);
651
- }
779
+ const header = await this.handlerAsUtility().getBlockHeader(blockNumber);
652
780
  return toForeignCallResult(header.toFields().map(toSingle));
653
781
  }
654
782
 
655
- async utilityGetNoteHashMembershipWitness(
783
+ // eslint-disable-next-line camelcase
784
+ async aztec_utl_getNoteHashMembershipWitness(
656
785
  foreignAnchorBlockHash: ForeignCallSingle,
657
786
  foreignNoteHash: ForeignCallSingle,
658
787
  ) {
659
- const blockHash = new BlockHash(fromSingle(foreignAnchorBlockHash));
788
+ const blockHash = blockHashFromSingle(foreignAnchorBlockHash);
660
789
  const noteHash = fromSingle(foreignNoteHash);
661
790
 
662
- const witness = await this.handlerAsUtility().utilityGetNoteHashMembershipWitness(blockHash, noteHash);
663
-
664
- if (!witness) {
665
- throw new Error(`Note hash ${noteHash} not found in the note hash tree at block ${blockHash.toString()}.`);
666
- }
791
+ const witness = await this.handlerAsUtility().getNoteHashMembershipWitness(blockHash, noteHash);
667
792
  return toForeignCallResult(witness.toNoirRepresentation());
668
793
  }
669
794
 
670
- async utilityGetBlockHashMembershipWitness(
795
+ // eslint-disable-next-line camelcase
796
+ async aztec_utl_getBlockHashMembershipWitness(
671
797
  foreignAnchorBlockHash: ForeignCallSingle,
672
798
  foreignBlockHash: ForeignCallSingle,
673
799
  ) {
674
- const anchorBlockHash = new BlockHash(fromSingle(foreignAnchorBlockHash));
675
- const blockHash = new BlockHash(fromSingle(foreignBlockHash));
800
+ const anchorBlockHash = blockHashFromSingle(foreignAnchorBlockHash);
801
+ const blockHash = blockHashFromSingle(foreignBlockHash);
676
802
 
677
- const witness = await this.handlerAsUtility().utilityGetBlockHashMembershipWitness(anchorBlockHash, blockHash);
678
-
679
- if (!witness) {
680
- throw new Error(
681
- `Block hash ${blockHash.toString()} not found in the archive tree at anchor block ${anchorBlockHash.toString()}.`,
682
- );
683
- }
684
- return toForeignCallResult(witness.toNoirRepresentation());
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()]);
685
806
  }
686
807
 
687
- async utilityGetLowNullifierMembershipWitness(
808
+ // eslint-disable-next-line camelcase
809
+ async aztec_utl_getLowNullifierMembershipWitness(
688
810
  foreignBlockHash: ForeignCallSingle,
689
811
  foreignNullifier: ForeignCallSingle,
690
812
  ) {
691
- const blockHash = new BlockHash(fromSingle(foreignBlockHash));
813
+ const blockHash = blockHashFromSingle(foreignBlockHash);
692
814
  const nullifier = fromSingle(foreignNullifier);
693
815
 
694
- const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockHash, nullifier);
695
-
696
- if (!witness) {
697
- throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${blockHash}.`);
698
- }
816
+ const witness = await this.handlerAsUtility().getLowNullifierMembershipWitness(blockHash, nullifier);
699
817
  return toForeignCallResult(witness.toNoirRepresentation());
700
818
  }
701
819
 
702
- async utilityFetchTaggedLogs(foreignPendingTaggedLogArrayBaseSlot: ForeignCallSingle) {
703
- const pendingTaggedLogArrayBaseSlot = fromSingle(foreignPendingTaggedLogArrayBaseSlot);
704
-
705
- await this.handlerAsUtility().utilityFetchTaggedLogs(pendingTaggedLogArrayBaseSlot);
706
-
707
- 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)]);
708
825
  }
709
826
 
710
- public async utilityValidateAndStoreEnqueuedNotesAndEvents(
711
- foreignContractAddress: ForeignCallSingle,
827
+ // eslint-disable-next-line camelcase
828
+ public async aztec_utl_validateAndStoreEnqueuedNotesAndEvents(
712
829
  foreignNoteValidationRequestsArrayBaseSlot: ForeignCallSingle,
713
830
  foreignEventValidationRequestsArrayBaseSlot: ForeignCallSingle,
831
+ foreignScope: ForeignCallSingle,
714
832
  ) {
715
- const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
716
833
  const noteValidationRequestsArrayBaseSlot = fromSingle(foreignNoteValidationRequestsArrayBaseSlot);
717
834
  const eventValidationRequestsArrayBaseSlot = fromSingle(foreignEventValidationRequestsArrayBaseSlot);
835
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
718
836
 
719
- await this.handlerAsUtility().utilityValidateAndStoreEnqueuedNotesAndEvents(
720
- contractAddress,
837
+ await this.handlerAsUtility().validateAndStoreEnqueuedNotesAndEvents(
721
838
  noteValidationRequestsArrayBaseSlot,
722
839
  eventValidationRequestsArrayBaseSlot,
840
+ scope,
723
841
  );
724
842
 
725
843
  return toForeignCallResult([]);
726
844
  }
727
845
 
728
- public async utilityBulkRetrieveLogs(
729
- foreignContractAddress: ForeignCallSingle,
730
- foreignLogRetrievalRequestsArrayBaseSlot: ForeignCallSingle,
731
- foreignLogRetrievalResponsesArrayBaseSlot: ForeignCallSingle,
732
- ) {
733
- const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
734
- const logRetrievalRequestsArrayBaseSlot = fromSingle(foreignLogRetrievalRequestsArrayBaseSlot);
735
- const logRetrievalResponsesArrayBaseSlot = fromSingle(foreignLogRetrievalResponsesArrayBaseSlot);
736
-
737
- await this.handlerAsUtility().utilityBulkRetrieveLogs(
738
- contractAddress,
739
- logRetrievalRequestsArrayBaseSlot,
740
- logRetrievalResponsesArrayBaseSlot,
741
- );
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
+ }
742
852
 
743
- 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)]);
744
858
  }
745
859
 
746
- async utilityStoreCapsule(
860
+ // eslint-disable-next-line camelcase
861
+ aztec_utl_setCapsule(
747
862
  foreignContractAddress: ForeignCallSingle,
748
863
  foreignSlot: ForeignCallSingle,
749
864
  foreignCapsule: ForeignCallArray,
865
+ foreignScope: ForeignCallSingle,
750
866
  ) {
751
867
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
752
868
  const slot = fromSingle(foreignSlot);
753
869
  const capsule = fromArray(foreignCapsule);
870
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
754
871
 
755
- await this.handlerAsUtility().utilityStoreCapsule(contractAddress, slot, capsule);
872
+ this.handlerAsUtility().setCapsule(contractAddress, slot, capsule, scope);
756
873
 
757
874
  return toForeignCallResult([]);
758
875
  }
759
876
 
760
- async utilityLoadCapsule(
877
+ // eslint-disable-next-line camelcase
878
+ async aztec_utl_getCapsule(
761
879
  foreignContractAddress: ForeignCallSingle,
762
880
  foreignSlot: ForeignCallSingle,
763
881
  foreignTSize: ForeignCallSingle,
882
+ foreignScope: ForeignCallSingle,
764
883
  ) {
765
884
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
766
885
  const slot = fromSingle(foreignSlot);
767
886
  const tSize = fromSingle(foreignTSize).toNumber();
887
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
768
888
 
769
- const values = await this.handlerAsUtility().utilityLoadCapsule(contractAddress, slot);
889
+ const opt = await this.handlerAsUtility().getCapsule(contractAddress, slot, tSize, scope);
770
890
 
771
891
  // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
772
892
  // with two fields: `some` (a boolean) and `value` (a field array in this case).
773
- 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 {
774
897
  // No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size.
775
898
  return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(tSize).fill(new Fr(0)))]);
776
- } else {
777
- // Data was found so we set `some` to 1 and return it along with `value`.
778
- return toForeignCallResult([toSingle(new Fr(1)), toArray(values)]);
779
899
  }
780
900
  }
781
901
 
782
- 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
+ ) {
783
908
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
784
909
  const slot = fromSingle(foreignSlot);
910
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
785
911
 
786
- await this.handlerAsUtility().utilityDeleteCapsule(contractAddress, slot);
912
+ this.handlerAsUtility().deleteCapsule(contractAddress, slot, scope);
787
913
 
788
914
  return toForeignCallResult([]);
789
915
  }
790
916
 
791
- async utilityCopyCapsule(
917
+ // eslint-disable-next-line camelcase
918
+ async aztec_utl_copyCapsule(
792
919
  foreignContractAddress: ForeignCallSingle,
793
920
  foreignSrcSlot: ForeignCallSingle,
794
921
  foreignDstSlot: ForeignCallSingle,
795
922
  foreignNumEntries: ForeignCallSingle,
923
+ foreignScope: ForeignCallSingle,
796
924
  ) {
797
925
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
798
926
  const srcSlot = fromSingle(foreignSrcSlot);
799
927
  const dstSlot = fromSingle(foreignDstSlot);
800
928
  const numEntries = fromSingle(foreignNumEntries).toNumber();
929
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
801
930
 
802
- await this.handlerAsUtility().utilityCopyCapsule(contractAddress, srcSlot, dstSlot, numEntries);
931
+ await this.handlerAsUtility().copyCapsule(contractAddress, srcSlot, dstSlot, numEntries, scope);
803
932
 
804
933
  return toForeignCallResult([]);
805
934
  }
806
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
+
807
994
  // TODO: I forgot to add a corresponding function here, when I introduced an oracle method to txe_oracle.ts.
808
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
809
996
  // to implement this function here. Isn't there a way to programmatically identify that this is missing, given the
810
997
  // existence of a txe_oracle method?
811
- async utilityAes128Decrypt(
998
+ // eslint-disable-next-line camelcase
999
+ async aztec_utl_decryptAes128(
812
1000
  foreignCiphertextBVecStorage: ForeignCallArray,
813
1001
  foreignCiphertextLength: ForeignCallSingle,
814
1002
  foreignIv: ForeignCallArray,
815
1003
  foreignSymKey: ForeignCallArray,
816
1004
  ) {
817
- 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 });
818
1008
  const iv = fromUintArray(foreignIv, 8);
819
1009
  const symKey = fromUintArray(foreignSymKey, 8);
820
1010
 
821
- const plaintextBuffer = await this.handlerAsUtility().utilityAes128Decrypt(ciphertext, iv, symKey);
822
-
823
- return toForeignCallResult(
824
- arrayToBoundedVec(bufferToU8Array(plaintextBuffer), foreignCiphertextBVecStorage.length),
825
- );
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
+ }
826
1020
  }
827
1021
 
828
- async utilityGetSharedSecret(
1022
+ // eslint-disable-next-line camelcase
1023
+ async aztec_utl_getSharedSecrets(
829
1024
  foreignAddress: ForeignCallSingle,
830
- foreignEphPKField0: ForeignCallSingle,
831
- foreignEphPKField1: ForeignCallSingle,
832
- foreignEphPKField2: ForeignCallSingle,
1025
+ foreignEphPksSlot: ForeignCallSingle,
1026
+ foreignContractAddress: ForeignCallSingle,
833
1027
  ) {
834
1028
  const address = AztecAddress.fromField(fromSingle(foreignAddress));
835
- const ephPK = Point.fromFields([
836
- fromSingle(foreignEphPKField0),
837
- fromSingle(foreignEphPKField1),
838
- fromSingle(foreignEphPKField2),
839
- ]);
1029
+ const ephPksSlot = fromSingle(foreignEphPksSlot);
1030
+ const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
1031
+
1032
+ const responseSlot = await this.handlerAsUtility().getSharedSecrets(address, ephPksSlot, contractAddress);
1033
+
1034
+ return toForeignCallResult([toSingle(responseSlot)]);
1035
+ }
1036
+
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
+ });
840
1050
 
841
- const secret = await this.handlerAsUtility().utilityGetSharedSecret(address, ephPK);
1051
+ this.handlerAsUtility().setContractSyncCacheInvalid(contractAddress, scopes);
842
1052
 
843
- return toForeignCallResult(secret.toFields().map(toSingle));
1053
+ return Promise.resolve(toForeignCallResult([]));
844
1054
  }
845
1055
 
846
- emitOffchainEffect(_foreignData: ForeignCallArray) {
847
- throw new Error('Offchain effects are not yet supported in the TestEnvironment');
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([]));
848
1064
  }
849
1065
 
850
1066
  // AVM opcodes
851
1067
 
852
- avmOpcodeEmitPublicLog(_foreignMessage: ForeignCallArray) {
1068
+ // eslint-disable-next-line camelcase
1069
+ aztec_avm_emitPublicLog(_foreignMessage: ForeignCallArray) {
853
1070
  // TODO(#8811): Implement
854
1071
  return toForeignCallResult([]);
855
1072
  }
856
1073
 
857
- async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
1074
+ // eslint-disable-next-line camelcase
1075
+ async aztec_avm_storageRead(foreignSlot: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
858
1076
  const slot = fromSingle(foreignSlot);
859
1077
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
860
1078
 
861
- const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot, contractAddress)).value;
1079
+ const value = (await this.handlerAsAvm().storageRead(slot, contractAddress)).value;
862
1080
 
863
1081
  return toForeignCallResult([toSingle(new Fr(value))]);
864
1082
  }
865
1083
 
866
- async avmOpcodeStorageWrite(foreignSlot: ForeignCallSingle, foreignValue: ForeignCallSingle) {
1084
+ // eslint-disable-next-line camelcase
1085
+ async aztec_avm_storageWrite(foreignSlot: ForeignCallSingle, foreignValue: ForeignCallSingle) {
867
1086
  const slot = fromSingle(foreignSlot);
868
1087
  const value = fromSingle(foreignValue);
869
1088
 
870
- await this.handlerAsAvm().avmOpcodeStorageWrite(slot, value);
1089
+ await this.handlerAsAvm().storageWrite(slot, value);
871
1090
 
872
1091
  return toForeignCallResult([]);
873
1092
  }
874
1093
 
875
- async avmOpcodeGetContractInstanceDeployer(foreignAddress: ForeignCallSingle) {
1094
+ // eslint-disable-next-line camelcase
1095
+ async aztec_avm_getContractInstanceDeployer(foreignAddress: ForeignCallSingle) {
876
1096
  const address = addressFromSingle(foreignAddress);
877
1097
 
878
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
1098
+ const instance = await this.handlerAsUtility().getContractInstance(address);
879
1099
 
880
1100
  return toForeignCallResult([
881
1101
  toSingle(instance.deployer),
@@ -884,10 +1104,11 @@ export class RPCTranslator {
884
1104
  ]);
885
1105
  }
886
1106
 
887
- async avmOpcodeGetContractInstanceClassId(foreignAddress: ForeignCallSingle) {
1107
+ // eslint-disable-next-line camelcase
1108
+ async aztec_avm_getContractInstanceClassId(foreignAddress: ForeignCallSingle) {
888
1109
  const address = addressFromSingle(foreignAddress);
889
1110
 
890
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
1111
+ const instance = await this.handlerAsUtility().getContractInstance(address);
891
1112
 
892
1113
  return toForeignCallResult([
893
1114
  toSingle(instance.currentContractClassId),
@@ -896,10 +1117,11 @@ export class RPCTranslator {
896
1117
  ]);
897
1118
  }
898
1119
 
899
- async avmOpcodeGetContractInstanceInitializationHash(foreignAddress: ForeignCallSingle) {
1120
+ // eslint-disable-next-line camelcase
1121
+ async aztec_avm_getContractInstanceInitializationHash(foreignAddress: ForeignCallSingle) {
900
1122
  const address = addressFromSingle(foreignAddress);
901
1123
 
902
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
1124
+ const instance = await this.handlerAsUtility().getContractInstance(address);
903
1125
 
904
1126
  return toForeignCallResult([
905
1127
  toSingle(instance.initializationHash),
@@ -908,202 +1130,315 @@ export class RPCTranslator {
908
1130
  ]);
909
1131
  }
910
1132
 
911
- async avmOpcodeSender() {
912
- 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();
913
1149
 
914
1150
  return toForeignCallResult([toSingle(sender)]);
915
1151
  }
916
1152
 
917
- async avmOpcodeEmitNullifier(foreignNullifier: ForeignCallSingle) {
1153
+ // eslint-disable-next-line camelcase
1154
+ async aztec_avm_emitNullifier(foreignNullifier: ForeignCallSingle) {
918
1155
  const nullifier = fromSingle(foreignNullifier);
919
1156
 
920
- await this.handlerAsAvm().avmOpcodeEmitNullifier(nullifier);
1157
+ await this.handlerAsAvm().emitNullifier(nullifier);
921
1158
 
922
1159
  return toForeignCallResult([]);
923
1160
  }
924
1161
 
925
- async avmOpcodeEmitNoteHash(foreignNoteHash: ForeignCallSingle) {
1162
+ // eslint-disable-next-line camelcase
1163
+ async aztec_avm_emitNoteHash(foreignNoteHash: ForeignCallSingle) {
926
1164
  const noteHash = fromSingle(foreignNoteHash);
927
1165
 
928
- await this.handlerAsAvm().avmOpcodeEmitNoteHash(noteHash);
1166
+ await this.handlerAsAvm().emitNoteHash(noteHash);
929
1167
 
930
1168
  return toForeignCallResult([]);
931
1169
  }
932
1170
 
933
- async avmOpcodeNullifierExists(foreignSiloedNullifier: ForeignCallSingle) {
1171
+ // eslint-disable-next-line camelcase
1172
+ async aztec_avm_nullifierExists(foreignSiloedNullifier: ForeignCallSingle) {
934
1173
  const siloedNullifier = fromSingle(foreignSiloedNullifier);
935
1174
 
936
- const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(siloedNullifier);
1175
+ const exists = await this.handlerAsAvm().nullifierExists(siloedNullifier);
937
1176
 
938
1177
  return toForeignCallResult([toSingle(new Fr(exists))]);
939
1178
  }
940
1179
 
941
- async avmOpcodeAddress() {
942
- const contractAddress = await this.handlerAsAvm().avmOpcodeAddress();
1180
+ // eslint-disable-next-line camelcase
1181
+ async aztec_avm_address() {
1182
+ const contractAddress = await this.handlerAsAvm().address();
943
1183
 
944
1184
  return toForeignCallResult([toSingle(contractAddress.toField())]);
945
1185
  }
946
1186
 
947
- async avmOpcodeBlockNumber() {
948
- const blockNumber = await this.handlerAsAvm().avmOpcodeBlockNumber();
1187
+ // eslint-disable-next-line camelcase
1188
+ async aztec_avm_blockNumber() {
1189
+ const blockNumber = await this.handlerAsAvm().blockNumber();
949
1190
 
950
1191
  return toForeignCallResult([toSingle(new Fr(blockNumber))]);
951
1192
  }
952
1193
 
953
- async avmOpcodeTimestamp() {
954
- const timestamp = await this.handlerAsAvm().avmOpcodeTimestamp();
1194
+ // eslint-disable-next-line camelcase
1195
+ async aztec_avm_timestamp() {
1196
+ const timestamp = await this.handlerAsAvm().timestamp();
955
1197
 
956
1198
  return toForeignCallResult([toSingle(new Fr(timestamp))]);
957
1199
  }
958
1200
 
959
- async avmOpcodeIsStaticCall() {
960
- const isStaticCall = await this.handlerAsAvm().avmOpcodeIsStaticCall();
1201
+ // eslint-disable-next-line camelcase
1202
+ async aztec_avm_isStaticCall() {
1203
+ const isStaticCall = await this.handlerAsAvm().isStaticCall();
961
1204
 
962
1205
  return toForeignCallResult([toSingle(new Fr(isStaticCall ? 1 : 0))]);
963
1206
  }
964
1207
 
965
- async avmOpcodeChainId() {
966
- const chainId = await this.handlerAsAvm().avmOpcodeChainId();
1208
+ // eslint-disable-next-line camelcase
1209
+ async aztec_avm_chainId() {
1210
+ const chainId = await this.handlerAsAvm().chainId();
967
1211
 
968
1212
  return toForeignCallResult([toSingle(chainId)]);
969
1213
  }
970
1214
 
971
- async avmOpcodeVersion() {
972
- const version = await this.handlerAsAvm().avmOpcodeVersion();
1215
+ // eslint-disable-next-line camelcase
1216
+ async aztec_avm_version() {
1217
+ const version = await this.handlerAsAvm().version();
973
1218
 
974
1219
  return toForeignCallResult([toSingle(version)]);
975
1220
  }
976
1221
 
977
- avmOpcodeReturndataSize() {
978
- throw new Error(
979
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
980
- );
1222
+ // eslint-disable-next-line camelcase
1223
+ async aztec_avm_returndataSize() {
1224
+ const result = await this.handlerAsAvm().returndataSize();
1225
+ return toForeignCallResult([toSingle(result)]);
981
1226
  }
982
1227
 
983
- avmOpcodeReturndataCopy(_foreignRdOffset: ForeignCallSingle, _foreignCopySize: ForeignCallSingle) {
984
- throw new Error(
985
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
986
- );
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)]);
987
1234
  }
988
1235
 
989
- avmOpcodeCall(
990
- _foreignL2Gas: ForeignCallSingle,
991
- _foreignDaGas: ForeignCallSingle,
992
- _foreignAddress: ForeignCallSingle,
993
- _foreignLength: ForeignCallSingle,
994
- _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,
995
1243
  ) {
996
- throw new Error(
997
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
998
- );
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)]);
999
1251
  }
1000
1252
 
1001
- avmOpcodeStaticCall(
1002
- _foreignL2Gas: ForeignCallSingle,
1003
- _foreignDaGas: ForeignCallSingle,
1004
- _foreignAddress: ForeignCallSingle,
1005
- _foreignLength: ForeignCallSingle,
1006
- _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,
1007
1260
  ) {
1008
- throw new Error(
1009
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
1010
- );
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)]);
1011
1268
  }
1012
1269
 
1013
- avmOpcodeSuccessCopy() {
1014
- throw new Error(
1015
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
1016
- );
1270
+ // eslint-disable-next-line camelcase
1271
+ async aztec_avm_successCopy() {
1272
+ const result = await this.handlerAsAvm().successCopy();
1273
+ return toForeignCallResult([toSingle(result)]);
1017
1274
  }
1018
1275
 
1019
- async txePrivateCallNewFlow(
1020
- 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,
1021
1281
  foreignTargetContractAddress: ForeignCallSingle,
1022
1282
  foreignFunctionSelector: ForeignCallSingle,
1023
1283
  foreignArgs: ForeignCallArray,
1024
1284
  foreignArgsHash: ForeignCallSingle,
1025
1285
  foreignIsStaticCall: ForeignCallSingle,
1286
+ foreignAdditionalScopes: ForeignCallArray,
1287
+ foreignAuthorizedUtilityCallTargets: ForeignCallArray,
1288
+ foreignGasSettings: ForeignCallArray,
1026
1289
  ) {
1027
- const from = addressFromSingle(foreignFrom);
1290
+ const from = fromSingle(foreignFromIsSome).toBool() ? addressFromSingle(foreignFromValue) : undefined;
1028
1291
  const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
1029
1292
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
1030
1293
  const args = fromArray(foreignArgs);
1031
1294
  const argsHash = fromSingle(foreignArgsHash);
1032
1295
  const isStaticCall = fromSingle(foreignIsStaticCall).toBool();
1033
-
1034
- const returnValues = await this.handlerAsTxe().txePrivateCallNewFlow(
1035
- from,
1036
- targetContractAddress,
1037
- functionSelector,
1038
- args,
1039
- argsHash,
1040
- isStaticCall,
1296
+ const additionalScopes = fromArray(foreignAdditionalScopes).map(field => AztecAddress.fromField(field));
1297
+ const authorizedUtilityCallTargets = fromArray(foreignAuthorizedUtilityCallTargets).map(field =>
1298
+ AztecAddress.fromField(field),
1041
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
+ });
1042
1336
 
1043
1337
  return toForeignCallResult([toArray(returnValues)]);
1044
1338
  }
1045
1339
 
1046
- async txeExecuteUtilityFunction(
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(
1047
1343
  foreignTargetContractAddress: ForeignCallSingle,
1048
1344
  foreignFunctionSelector: ForeignCallSingle,
1049
1345
  foreignArgs: ForeignCallArray,
1346
+ foreignAuthorizedUtilityCallTargets: ForeignCallArray,
1050
1347
  ) {
1051
1348
  const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
1052
1349
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
1053
1350
  const args = fromArray(foreignArgs);
1054
-
1055
- const returnValues = await this.handlerAsTxe().txeExecuteUtilityFunction(
1056
- targetContractAddress,
1057
- functionSelector,
1058
- args,
1351
+ const authorizedUtilityCallTargets = fromArray(foreignAuthorizedUtilityCallTargets).map(field =>
1352
+ AztecAddress.fromField(field),
1059
1353
  );
1060
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
+
1061
1370
  return toForeignCallResult([toArray(returnValues)]);
1062
1371
  }
1063
1372
 
1064
- async txePublicCallNewFlow(
1065
- 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,
1066
1378
  foreignAddress: ForeignCallSingle,
1067
1379
  foreignCalldata: ForeignCallArray,
1068
1380
  foreignIsStaticCall: ForeignCallSingle,
1381
+ foreignGasSettings: ForeignCallArray,
1069
1382
  ) {
1070
- const from = addressFromSingle(foreignFrom);
1383
+ const from = fromSingle(foreignFromIsSome).toBool() ? addressFromSingle(foreignFromValue) : undefined;
1071
1384
  const address = addressFromSingle(foreignAddress);
1072
1385
  const calldata = fromArray(foreignCalldata);
1073
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
+ );
1074
1397
 
1075
- const returnValues = await this.handlerAsTxe().txePublicCallNewFlow(from, address, calldata, isStaticCall);
1398
+ // TODO(F-335): Avoid doing the following call here.
1399
+ await this.stateHandler.cycleJob();
1400
+
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
+ });
1076
1408
 
1077
1409
  return toForeignCallResult([toArray(returnValues)]);
1078
1410
  }
1079
1411
 
1080
- async privateGetSenderForTags() {
1081
- const sender = await this.handlerAsPrivate().privateGetSenderForTags();
1412
+ // eslint-disable-next-line camelcase
1413
+ async aztec_prv_getSenderForTags() {
1414
+ const senderOpt = await this.handlerAsPrivate().getSenderForTags();
1082
1415
 
1083
1416
  // Return a Noir Option struct with `some` and `value` fields
1084
- 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 {
1085
1421
  // No sender found, return Option with some=0 and value=0
1086
1422
  return toForeignCallResult([toSingle(0), toSingle(0)]);
1087
- } else {
1088
- // Sender found, return Option with some=1 and value=sender address
1089
- return toForeignCallResult([toSingle(1), toSingle(sender)]);
1090
1423
  }
1091
1424
  }
1092
1425
 
1093
- async privateSetSenderForTags(foreignSenderForTags: ForeignCallSingle) {
1094
- 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));
1095
1430
 
1096
- await this.handlerAsPrivate().privateSetSenderForTags(senderForTags);
1431
+ const nextAppTag = await this.handlerAsPrivate().getNextAppTagAsSender(sender, recipient);
1097
1432
 
1098
- return toForeignCallResult([]);
1433
+ return toForeignCallResult([toSingle(nextAppTag.value)]);
1099
1434
  }
1100
1435
 
1101
- async privateGetNextAppTagAsSender(foreignSender: ForeignCallSingle, foreignRecipient: ForeignCallSingle) {
1102
- const sender = AztecAddress.fromField(fromSingle(foreignSender));
1103
- const recipient = AztecAddress.fromField(fromSingle(foreignRecipient));
1436
+ // eslint-disable-next-line camelcase
1437
+ async aztec_prv_getNextConstrainedTaggingIndex(foreignAppSiloedSecret: ForeignCallSingle) {
1438
+ const appSiloedSecret = fromSingle(foreignAppSiloedSecret);
1104
1439
 
1105
- const nextAppTag = await this.handlerAsPrivate().privateGetNextAppTagAsSender(sender, recipient);
1440
+ const index = await this.handlerAsPrivate().getNextConstrainedTaggingIndex(appSiloedSecret);
1106
1441
 
1107
- return toForeignCallResult([toSingle(nextAppTag.value)]);
1442
+ return toForeignCallResult([toSingle(new Fr(index))]);
1108
1443
  }
1109
1444
  }