@aztec/txe 0.0.1-commit.86469d5 → 0.0.1-commit.8655d4a

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 (134) 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 +148 -75
  31. package/dest/metafile.json +38147 -0
  32. package/dest/msgpackr_fr_extension.d.ts +2 -0
  33. package/dest/msgpackr_fr_extension.d.ts.map +1 -0
  34. package/dest/msgpackr_fr_extension.js +21 -0
  35. package/dest/oracle/interfaces.d.ts +40 -28
  36. package/dest/oracle/interfaces.d.ts.map +1 -1
  37. package/dest/oracle/txe_oracle_public_context.d.ts +18 -13
  38. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  39. package/dest/oracle/txe_oracle_public_context.js +27 -12
  40. package/dest/oracle/txe_oracle_top_level_context.d.ts +39 -24
  41. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  42. package/dest/oracle/txe_oracle_top_level_context.js +205 -78
  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 +140 -84
  50. package/dest/rpc_translator.d.ts.map +1 -1
  51. package/dest/rpc_translator.js +587 -239
  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 +24 -20
  57. package/dest/state_machine/dummy_p2p_client.d.ts +26 -16
  58. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  59. package/dest/state_machine/dummy_p2p_client.js +44 -20
  60. package/dest/state_machine/global_variable_builder.d.ts +9 -4
  61. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  62. package/dest/state_machine/global_variable_builder.js +9 -3
  63. package/dest/state_machine/index.d.ts +10 -6
  64. package/dest/state_machine/index.d.ts.map +1 -1
  65. package/dest/state_machine/index.js +35 -12
  66. package/dest/state_machine/mock_epoch_cache.d.ts +20 -3
  67. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  68. package/dest/state_machine/mock_epoch_cache.js +39 -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 +71 -10
  76. package/dest/txe_session.d.ts.map +1 -1
  77. package/dest/txe_session.js +227 -40
  78. package/dest/utils/block_creation.d.ts +1 -1
  79. package/dest/utils/block_creation.d.ts.map +1 -1
  80. package/dest/utils/block_creation.js +3 -1
  81. package/dest/utils/encoding.d.ts +191 -0
  82. package/dest/utils/encoding.d.ts.map +1 -0
  83. package/dest/{util → utils}/encoding.js +7 -2
  84. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  85. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  86. package/dest/{util → utils}/txe_account_store.d.ts +1 -1
  87. package/dest/utils/txe_account_store.d.ts.map +1 -0
  88. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  89. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  90. package/dest/{util → utils}/txe_public_contract_data_source.js +6 -25
  91. package/dest/worker.bundle.js +3 -0
  92. package/dest/worker.bundle.js.map +7 -0
  93. package/dest/worker.d.ts +2 -0
  94. package/dest/worker.d.ts.map +1 -0
  95. package/dest/worker.js +92 -0
  96. package/package.json +37 -21
  97. package/src/bin/check_txe_oracle_version.ts +37 -0
  98. package/src/bin/index.ts +11 -2
  99. package/src/constants.ts +6 -0
  100. package/src/dispatcher_pool.ts +316 -0
  101. package/src/index.ts +166 -80
  102. package/src/msgpackr_fr_extension.ts +23 -0
  103. package/src/oracle/interfaces.ts +48 -34
  104. package/src/oracle/txe_oracle_public_context.ts +42 -12
  105. package/src/oracle/txe_oracle_top_level_context.ts +231 -144
  106. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  107. package/src/rpc_server.ts +87 -0
  108. package/src/rpc_translator.ts +662 -316
  109. package/src/state_machine/archiver.ts +35 -18
  110. package/src/state_machine/dummy_p2p_client.ts +70 -32
  111. package/src/state_machine/global_variable_builder.ts +18 -3
  112. package/src/state_machine/index.ts +48 -13
  113. package/src/state_machine/mock_epoch_cache.ts +51 -3
  114. package/src/state_machine/synchronizer.ts +5 -5
  115. package/src/txe_oracle_version.ts +17 -0
  116. package/src/txe_session.ts +324 -90
  117. package/src/utils/block_creation.ts +3 -1
  118. package/src/{util → utils}/encoding.ts +8 -2
  119. package/src/{util → utils}/txe_public_contract_data_source.ts +10 -38
  120. package/src/worker.ts +98 -0
  121. package/dest/util/encoding.d.ts +0 -720
  122. package/dest/util/encoding.d.ts.map +0 -1
  123. package/dest/util/expected_failure_error.d.ts.map +0 -1
  124. package/dest/util/txe_account_store.d.ts.map +0 -1
  125. package/dest/util/txe_contract_store.d.ts +0 -12
  126. package/dest/util/txe_contract_store.d.ts.map +0 -1
  127. package/dest/util/txe_contract_store.js +0 -22
  128. package/dest/util/txe_public_contract_data_source.d.ts +0 -21
  129. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  130. package/src/util/txe_contract_store.ts +0 -36
  131. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  132. /package/dest/{util → utils}/txe_account_store.js +0 -0
  133. /package/src/{util → utils}/expected_failure_error.ts +0 -0
  134. /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
- utilityDebugLog(
441
+ // eslint-disable-next-line camelcase
442
+ async aztec_utl_log(
332
443
  foreignLevel: ForeignCallSingle,
333
444
  foreignMessage: ForeignCallArray,
334
445
  _foreignLength: ForeignCallSingle,
@@ -340,23 +451,24 @@ export class RPCTranslator {
340
451
  .join('');
341
452
  const fields = fromArray(foreignFields);
342
453
 
343
- this.handlerAsMisc().utilityDebugLog(level, message, fields);
454
+ await this.handlerAsMisc().log(level, message, fields);
344
455
 
345
456
  return toForeignCallResult([]);
346
457
  }
347
458
 
348
- async utilityStorageRead(
459
+ // eslint-disable-next-line camelcase
460
+ async aztec_utl_getFromPublicStorage(
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,256 +651,343 @@ 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 utilityGetPublicKeysAndPartialAddress(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 { publicKeys, partialAddress } = await this.handlerAsUtility().utilityGetPublicKeysAndPartialAddress(address);
664
+ const result = await this.handlerAsUtility().getPublicKeysAndPartialAddress(address);
552
665
 
553
- return toForeignCallResult([toArray([...publicKeys.toFields(), partialAddress])]);
666
+ // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
667
+ // with two fields: `some` (a boolean) and `value` (a field array in this case).
668
+ if (!result.isSome()) {
669
+ // No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size.
670
+ // Wire shape: [npk_m_hash, ivpk_m.x, ivpk_m.y, ovpk_m_hash, tpk_m_hash, mspk_m_hash, fbpk_m_hash, partial_address] = 8 fields.
671
+ return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(8).fill(new Fr(0)))]);
672
+ } else {
673
+ // The Noir side hand-decodes a `[Field; 8]` here (see aztec-nr/aztec/src/oracle/keys.nr), so we
674
+ // emit the 7-field PublicKeys shape + partial_address explicitly
675
+ // rather than going through `publicKeys.toFields()` (which is the struct-flattened 8-field
676
+ // wire for oracle returns that decode via struct shape).
677
+ const { publicKeys, partialAddress } = result.value;
678
+ return toForeignCallResult([
679
+ toSingle(new Fr(1)),
680
+ toArray([
681
+ publicKeys.npkMHash,
682
+ publicKeys.ivpkM.x,
683
+ publicKeys.ivpkM.y,
684
+ publicKeys.ovpkMHash,
685
+ publicKeys.tpkMHash,
686
+ publicKeys.mspkMHash,
687
+ publicKeys.fbpkMHash,
688
+ partialAddress,
689
+ ]),
690
+ ]);
691
+ }
554
692
  }
555
693
 
556
- async utilityGetKeyValidationRequest(foreignPkMHash: ForeignCallSingle) {
694
+ // eslint-disable-next-line camelcase
695
+ async aztec_utl_getKeyValidationRequest(foreignPkMHash: ForeignCallSingle) {
557
696
  const pkMHash = fromSingle(foreignPkMHash);
558
697
 
559
- const keyValidationRequest = await this.handlerAsUtility().utilityGetKeyValidationRequest(pkMHash);
698
+ const keyValidationRequest = await this.handlerAsUtility().getKeyValidationRequest(pkMHash);
560
699
 
561
700
  return toForeignCallResult(keyValidationRequest.toFields().map(toSingle));
562
701
  }
563
702
 
564
- privateCallPrivateFunction(
565
- _foreignTargetContractAddress: ForeignCallSingle,
566
- _foreignFunctionSelector: ForeignCallSingle,
567
- _foreignArgsHash: ForeignCallSingle,
568
- _foreignSideEffectCounter: ForeignCallSingle,
569
- _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,
570
710
  ) {
571
- throw new Error(
572
- '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,
573
723
  );
724
+ return toForeignCallResult([[endSideEffectCounter, returnsHash].map(toSingle)]);
574
725
  }
575
726
 
576
- async utilityGetNullifierMembershipWitness(foreignBlockHash: ForeignCallSingle, foreignNullifier: ForeignCallSingle) {
577
- 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);
578
733
  const nullifier = fromSingle(foreignNullifier);
579
734
 
580
- const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockHash, nullifier);
581
-
582
- if (!witness) {
583
- throw new Error(`Nullifier membership witness not found at block ${blockHash}.`);
584
- }
735
+ const witness = await this.handlerAsUtility().getNullifierMembershipWitness(blockHash, nullifier);
585
736
  return toForeignCallResult(witness.toNoirRepresentation());
586
737
  }
587
738
 
588
- async utilityGetAuthWitness(foreignMessageHash: ForeignCallSingle) {
739
+ // eslint-disable-next-line camelcase
740
+ async aztec_utl_getAuthWitness(foreignMessageHash: ForeignCallSingle) {
589
741
  const messageHash = fromSingle(foreignMessageHash);
590
742
 
591
- const authWitness = await this.handlerAsUtility().utilityGetAuthWitness(messageHash);
592
-
593
- if (!authWitness) {
594
- throw new Error(`Auth witness not found for message hash ${messageHash}.`);
595
- }
743
+ const authWitness = await this.handlerAsUtility().getAuthWitness(messageHash);
596
744
  return toForeignCallResult([toArray(authWitness)]);
597
745
  }
598
746
 
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
- ) {
614
- 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([]);
615
752
  }
616
753
 
617
- public privateNotifySetMinRevertibleSideEffectCounter(_foreignMinRevertibleSideEffectCounter: ForeignCallSingle) {
618
- 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([]);
619
759
  }
620
760
 
621
- public async privateIsSideEffectCounterRevertible(foreignSideEffectCounter: ForeignCallSingle) {
761
+ // eslint-disable-next-line camelcase
762
+ public async aztec_prv_isExecutionInRevertiblePhase(foreignSideEffectCounter: ForeignCallSingle) {
622
763
  const sideEffectCounter = fromSingle(foreignSideEffectCounter).toNumber();
623
- const isRevertible = await this.handlerAsPrivate().privateIsSideEffectCounterRevertible(sideEffectCounter);
764
+ const isRevertible = await this.handlerAsPrivate().isExecutionInRevertiblePhase(sideEffectCounter);
624
765
  return toForeignCallResult([toSingle(new Fr(isRevertible))]);
625
766
  }
626
767
 
627
- utilityGetUtilityContext() {
628
- const context = this.handlerAsUtility().utilityGetUtilityContext();
768
+ // eslint-disable-next-line camelcase
769
+ aztec_utl_getUtilityContext() {
770
+ const context = this.handlerAsUtility().getUtilityContext();
629
771
 
630
772
  return toForeignCallResult(context.toNoirRepresentation());
631
773
  }
632
774
 
633
- async utilityGetBlockHeader(foreignBlockNumber: ForeignCallSingle) {
775
+ // eslint-disable-next-line camelcase
776
+ async aztec_utl_getBlockHeader(foreignBlockNumber: ForeignCallSingle) {
634
777
  const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
635
778
 
636
- const header = await this.handlerAsUtility().utilityGetBlockHeader(blockNumber);
637
-
638
- if (!header) {
639
- throw new Error(`Block header not found for block ${blockNumber}.`);
640
- }
779
+ const header = await this.handlerAsUtility().getBlockHeader(blockNumber);
641
780
  return toForeignCallResult(header.toFields().map(toSingle));
642
781
  }
643
782
 
644
- async utilityGetNoteHashMembershipWitness(
783
+ // eslint-disable-next-line camelcase
784
+ async aztec_utl_getNoteHashMembershipWitness(
645
785
  foreignAnchorBlockHash: ForeignCallSingle,
646
786
  foreignNoteHash: ForeignCallSingle,
647
787
  ) {
648
- const blockHash = new BlockHash(fromSingle(foreignAnchorBlockHash));
788
+ const blockHash = blockHashFromSingle(foreignAnchorBlockHash);
649
789
  const noteHash = fromSingle(foreignNoteHash);
650
790
 
651
- const witness = await this.handlerAsUtility().utilityGetNoteHashMembershipWitness(blockHash, noteHash);
652
-
653
- if (!witness) {
654
- throw new Error(`Note hash ${noteHash} not found in the note hash tree at block ${blockHash.toString()}.`);
655
- }
791
+ const witness = await this.handlerAsUtility().getNoteHashMembershipWitness(blockHash, noteHash);
656
792
  return toForeignCallResult(witness.toNoirRepresentation());
657
793
  }
658
794
 
659
- async utilityGetBlockHashMembershipWitness(
795
+ // eslint-disable-next-line camelcase
796
+ async aztec_utl_getBlockHashMembershipWitness(
660
797
  foreignAnchorBlockHash: ForeignCallSingle,
661
798
  foreignBlockHash: ForeignCallSingle,
662
799
  ) {
663
- const anchorBlockHash = new BlockHash(fromSingle(foreignAnchorBlockHash));
664
- const blockHash = new BlockHash(fromSingle(foreignBlockHash));
800
+ const anchorBlockHash = blockHashFromSingle(foreignAnchorBlockHash);
801
+ const blockHash = blockHashFromSingle(foreignBlockHash);
665
802
 
666
- const witness = await this.handlerAsUtility().utilityGetBlockHashMembershipWitness(anchorBlockHash, blockHash);
667
-
668
- if (!witness) {
669
- throw new Error(
670
- `Block hash ${blockHash.toString()} not found in the archive tree at anchor block ${anchorBlockHash.toString()}.`,
671
- );
672
- }
673
- 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()]);
674
806
  }
675
807
 
676
- async utilityGetLowNullifierMembershipWitness(
808
+ // eslint-disable-next-line camelcase
809
+ async aztec_utl_getLowNullifierMembershipWitness(
677
810
  foreignBlockHash: ForeignCallSingle,
678
811
  foreignNullifier: ForeignCallSingle,
679
812
  ) {
680
- const blockHash = new BlockHash(fromSingle(foreignBlockHash));
813
+ const blockHash = blockHashFromSingle(foreignBlockHash);
681
814
  const nullifier = fromSingle(foreignNullifier);
682
815
 
683
- const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockHash, nullifier);
684
-
685
- if (!witness) {
686
- throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${blockHash}.`);
687
- }
816
+ const witness = await this.handlerAsUtility().getLowNullifierMembershipWitness(blockHash, nullifier);
688
817
  return toForeignCallResult(witness.toNoirRepresentation());
689
818
  }
690
819
 
691
- async utilityFetchTaggedLogs(foreignPendingTaggedLogArrayBaseSlot: ForeignCallSingle) {
692
- const pendingTaggedLogArrayBaseSlot = fromSingle(foreignPendingTaggedLogArrayBaseSlot);
693
-
694
- await this.handlerAsUtility().utilityFetchTaggedLogs(pendingTaggedLogArrayBaseSlot);
695
-
696
- 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)]);
697
825
  }
698
826
 
699
- public async utilityValidateAndStoreEnqueuedNotesAndEvents(
700
- foreignContractAddress: ForeignCallSingle,
827
+ // eslint-disable-next-line camelcase
828
+ public async aztec_utl_validateAndStoreEnqueuedNotesAndEvents(
701
829
  foreignNoteValidationRequestsArrayBaseSlot: ForeignCallSingle,
702
830
  foreignEventValidationRequestsArrayBaseSlot: ForeignCallSingle,
831
+ foreignScope: ForeignCallSingle,
703
832
  ) {
704
- const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
705
833
  const noteValidationRequestsArrayBaseSlot = fromSingle(foreignNoteValidationRequestsArrayBaseSlot);
706
834
  const eventValidationRequestsArrayBaseSlot = fromSingle(foreignEventValidationRequestsArrayBaseSlot);
835
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
707
836
 
708
- await this.handlerAsUtility().utilityValidateAndStoreEnqueuedNotesAndEvents(
709
- contractAddress,
837
+ await this.handlerAsUtility().validateAndStoreEnqueuedNotesAndEvents(
710
838
  noteValidationRequestsArrayBaseSlot,
711
839
  eventValidationRequestsArrayBaseSlot,
840
+ scope,
712
841
  );
713
842
 
714
843
  return toForeignCallResult([]);
715
844
  }
716
845
 
717
- public async utilityBulkRetrieveLogs(
718
- foreignContractAddress: ForeignCallSingle,
719
- foreignLogRetrievalRequestsArrayBaseSlot: ForeignCallSingle,
720
- foreignLogRetrievalResponsesArrayBaseSlot: ForeignCallSingle,
721
- ) {
722
- const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
723
- const logRetrievalRequestsArrayBaseSlot = fromSingle(foreignLogRetrievalRequestsArrayBaseSlot);
724
- const logRetrievalResponsesArrayBaseSlot = fromSingle(foreignLogRetrievalResponsesArrayBaseSlot);
725
-
726
- await this.handlerAsUtility().utilityBulkRetrieveLogs(
727
- contractAddress,
728
- logRetrievalRequestsArrayBaseSlot,
729
- logRetrievalResponsesArrayBaseSlot,
730
- );
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
+ }
731
852
 
732
- 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)]);
733
858
  }
734
859
 
735
- async utilityStoreCapsule(
860
+ // eslint-disable-next-line camelcase
861
+ aztec_utl_setCapsule(
736
862
  foreignContractAddress: ForeignCallSingle,
737
863
  foreignSlot: ForeignCallSingle,
738
864
  foreignCapsule: ForeignCallArray,
865
+ foreignScope: ForeignCallSingle,
739
866
  ) {
740
867
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
741
868
  const slot = fromSingle(foreignSlot);
742
869
  const capsule = fromArray(foreignCapsule);
870
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
743
871
 
744
- await this.handlerAsUtility().utilityStoreCapsule(contractAddress, slot, capsule);
872
+ this.handlerAsUtility().setCapsule(contractAddress, slot, capsule, scope);
745
873
 
746
874
  return toForeignCallResult([]);
747
875
  }
748
876
 
749
- async utilityLoadCapsule(
877
+ // eslint-disable-next-line camelcase
878
+ async aztec_utl_getCapsule(
750
879
  foreignContractAddress: ForeignCallSingle,
751
880
  foreignSlot: ForeignCallSingle,
752
881
  foreignTSize: ForeignCallSingle,
882
+ foreignScope: ForeignCallSingle,
753
883
  ) {
754
884
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
755
885
  const slot = fromSingle(foreignSlot);
756
886
  const tSize = fromSingle(foreignTSize).toNumber();
887
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
757
888
 
758
- const values = await this.handlerAsUtility().utilityLoadCapsule(contractAddress, slot);
889
+ const opt = await this.handlerAsUtility().getCapsule(contractAddress, slot, tSize, scope);
759
890
 
760
891
  // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
761
892
  // with two fields: `some` (a boolean) and `value` (a field array in this case).
762
- 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 {
763
897
  // No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size.
764
898
  return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(tSize).fill(new Fr(0)))]);
765
- } else {
766
- // Data was found so we set `some` to 1 and return it along with `value`.
767
- return toForeignCallResult([toSingle(new Fr(1)), toArray(values)]);
768
899
  }
769
900
  }
770
901
 
771
- 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
+ ) {
772
908
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
773
909
  const slot = fromSingle(foreignSlot);
910
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
774
911
 
775
- await this.handlerAsUtility().utilityDeleteCapsule(contractAddress, slot);
912
+ this.handlerAsUtility().deleteCapsule(contractAddress, slot, scope);
776
913
 
777
914
  return toForeignCallResult([]);
778
915
  }
779
916
 
780
- async utilityCopyCapsule(
917
+ // eslint-disable-next-line camelcase
918
+ async aztec_utl_copyCapsule(
781
919
  foreignContractAddress: ForeignCallSingle,
782
920
  foreignSrcSlot: ForeignCallSingle,
783
921
  foreignDstSlot: ForeignCallSingle,
784
922
  foreignNumEntries: ForeignCallSingle,
923
+ foreignScope: ForeignCallSingle,
785
924
  ) {
786
925
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
787
926
  const srcSlot = fromSingle(foreignSrcSlot);
788
927
  const dstSlot = fromSingle(foreignDstSlot);
789
928
  const numEntries = fromSingle(foreignNumEntries).toNumber();
929
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
930
+
931
+ await this.handlerAsUtility().copyCapsule(contractAddress, srcSlot, dstSlot, numEntries, scope);
932
+
933
+ return toForeignCallResult([]);
934
+ }
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
+ }
790
971
 
791
- await this.handlerAsUtility().utilityCopyCapsule(contractAddress, srcSlot, dstSlot, numEntries);
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
+ }
792
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);
793
991
  return toForeignCallResult([]);
794
992
  }
795
993
 
@@ -797,74 +995,107 @@ export class RPCTranslator {
797
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
798
996
  // to implement this function here. Isn't there a way to programmatically identify that this is missing, given the
799
997
  // existence of a txe_oracle method?
800
- async utilityAes128Decrypt(
998
+ // eslint-disable-next-line camelcase
999
+ async aztec_utl_decryptAes128(
801
1000
  foreignCiphertextBVecStorage: ForeignCallArray,
802
1001
  foreignCiphertextLength: ForeignCallSingle,
803
1002
  foreignIv: ForeignCallArray,
804
1003
  foreignSymKey: ForeignCallArray,
805
1004
  ) {
806
- 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 });
807
1008
  const iv = fromUintArray(foreignIv, 8);
808
1009
  const symKey = fromUintArray(foreignSymKey, 8);
809
1010
 
810
- const plaintextBuffer = await this.handlerAsUtility().utilityAes128Decrypt(ciphertext, iv, symKey);
811
-
812
- return toForeignCallResult(
813
- arrayToBoundedVec(bufferToU8Array(plaintextBuffer), foreignCiphertextBVecStorage.length),
814
- );
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
+ }
815
1020
  }
816
1021
 
817
- async utilityGetSharedSecret(
1022
+ // eslint-disable-next-line camelcase
1023
+ async aztec_utl_getSharedSecrets(
818
1024
  foreignAddress: ForeignCallSingle,
819
- foreignEphPKField0: ForeignCallSingle,
820
- foreignEphPKField1: ForeignCallSingle,
821
- foreignEphPKField2: ForeignCallSingle,
1025
+ foreignEphPksSlot: ForeignCallSingle,
1026
+ foreignContractAddress: ForeignCallSingle,
822
1027
  ) {
823
1028
  const address = AztecAddress.fromField(fromSingle(foreignAddress));
824
- const ephPK = Point.fromFields([
825
- fromSingle(foreignEphPKField0),
826
- fromSingle(foreignEphPKField1),
827
- fromSingle(foreignEphPKField2),
828
- ]);
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
+ }
829
1036
 
830
- const secret = await this.handlerAsUtility().utilityGetSharedSecret(address, ephPK);
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
+ });
831
1050
 
832
- return toForeignCallResult(secret.toFields().map(toSingle));
1051
+ this.handlerAsUtility().setContractSyncCacheInvalid(contractAddress, scopes);
1052
+
1053
+ return Promise.resolve(toForeignCallResult([]));
833
1054
  }
834
1055
 
835
- emitOffchainEffect(_foreignData: ForeignCallArray) {
836
- 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([]));
837
1064
  }
838
1065
 
839
1066
  // AVM opcodes
840
1067
 
841
- avmOpcodeEmitUnencryptedLog(_foreignMessage: ForeignCallArray) {
1068
+ // eslint-disable-next-line camelcase
1069
+ aztec_avm_emitPublicLog(_foreignMessage: ForeignCallArray) {
842
1070
  // TODO(#8811): Implement
843
1071
  return toForeignCallResult([]);
844
1072
  }
845
1073
 
846
- async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
1074
+ // eslint-disable-next-line camelcase
1075
+ async aztec_avm_storageRead(foreignSlot: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
847
1076
  const slot = fromSingle(foreignSlot);
848
1077
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
849
1078
 
850
- const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot, contractAddress)).value;
1079
+ const value = (await this.handlerAsAvm().storageRead(slot, contractAddress)).value;
851
1080
 
852
1081
  return toForeignCallResult([toSingle(new Fr(value))]);
853
1082
  }
854
1083
 
855
- async avmOpcodeStorageWrite(foreignSlot: ForeignCallSingle, foreignValue: ForeignCallSingle) {
1084
+ // eslint-disable-next-line camelcase
1085
+ async aztec_avm_storageWrite(foreignSlot: ForeignCallSingle, foreignValue: ForeignCallSingle) {
856
1086
  const slot = fromSingle(foreignSlot);
857
1087
  const value = fromSingle(foreignValue);
858
1088
 
859
- await this.handlerAsAvm().avmOpcodeStorageWrite(slot, value);
1089
+ await this.handlerAsAvm().storageWrite(slot, value);
860
1090
 
861
1091
  return toForeignCallResult([]);
862
1092
  }
863
1093
 
864
- async avmOpcodeGetContractInstanceDeployer(foreignAddress: ForeignCallSingle) {
1094
+ // eslint-disable-next-line camelcase
1095
+ async aztec_avm_getContractInstanceDeployer(foreignAddress: ForeignCallSingle) {
865
1096
  const address = addressFromSingle(foreignAddress);
866
1097
 
867
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
1098
+ const instance = await this.handlerAsUtility().getContractInstance(address);
868
1099
 
869
1100
  return toForeignCallResult([
870
1101
  toSingle(instance.deployer),
@@ -873,10 +1104,11 @@ export class RPCTranslator {
873
1104
  ]);
874
1105
  }
875
1106
 
876
- async avmOpcodeGetContractInstanceClassId(foreignAddress: ForeignCallSingle) {
1107
+ // eslint-disable-next-line camelcase
1108
+ async aztec_avm_getContractInstanceClassId(foreignAddress: ForeignCallSingle) {
877
1109
  const address = addressFromSingle(foreignAddress);
878
1110
 
879
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
1111
+ const instance = await this.handlerAsUtility().getContractInstance(address);
880
1112
 
881
1113
  return toForeignCallResult([
882
1114
  toSingle(instance.currentContractClassId),
@@ -885,10 +1117,11 @@ export class RPCTranslator {
885
1117
  ]);
886
1118
  }
887
1119
 
888
- async avmOpcodeGetContractInstanceInitializationHash(foreignAddress: ForeignCallSingle) {
1120
+ // eslint-disable-next-line camelcase
1121
+ async aztec_avm_getContractInstanceInitializationHash(foreignAddress: ForeignCallSingle) {
889
1122
  const address = addressFromSingle(foreignAddress);
890
1123
 
891
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
1124
+ const instance = await this.handlerAsUtility().getContractInstance(address);
892
1125
 
893
1126
  return toForeignCallResult([
894
1127
  toSingle(instance.initializationHash),
@@ -897,202 +1130,315 @@ export class RPCTranslator {
897
1130
  ]);
898
1131
  }
899
1132
 
900
- async avmOpcodeSender() {
901
- 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();
902
1149
 
903
1150
  return toForeignCallResult([toSingle(sender)]);
904
1151
  }
905
1152
 
906
- async avmOpcodeEmitNullifier(foreignNullifier: ForeignCallSingle) {
1153
+ // eslint-disable-next-line camelcase
1154
+ async aztec_avm_emitNullifier(foreignNullifier: ForeignCallSingle) {
907
1155
  const nullifier = fromSingle(foreignNullifier);
908
1156
 
909
- await this.handlerAsAvm().avmOpcodeEmitNullifier(nullifier);
1157
+ await this.handlerAsAvm().emitNullifier(nullifier);
910
1158
 
911
1159
  return toForeignCallResult([]);
912
1160
  }
913
1161
 
914
- async avmOpcodeEmitNoteHash(foreignNoteHash: ForeignCallSingle) {
1162
+ // eslint-disable-next-line camelcase
1163
+ async aztec_avm_emitNoteHash(foreignNoteHash: ForeignCallSingle) {
915
1164
  const noteHash = fromSingle(foreignNoteHash);
916
1165
 
917
- await this.handlerAsAvm().avmOpcodeEmitNoteHash(noteHash);
1166
+ await this.handlerAsAvm().emitNoteHash(noteHash);
918
1167
 
919
1168
  return toForeignCallResult([]);
920
1169
  }
921
1170
 
922
- async avmOpcodeNullifierExists(foreignSiloedNullifier: ForeignCallSingle) {
1171
+ // eslint-disable-next-line camelcase
1172
+ async aztec_avm_nullifierExists(foreignSiloedNullifier: ForeignCallSingle) {
923
1173
  const siloedNullifier = fromSingle(foreignSiloedNullifier);
924
1174
 
925
- const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(siloedNullifier);
1175
+ const exists = await this.handlerAsAvm().nullifierExists(siloedNullifier);
926
1176
 
927
1177
  return toForeignCallResult([toSingle(new Fr(exists))]);
928
1178
  }
929
1179
 
930
- async avmOpcodeAddress() {
931
- const contractAddress = await this.handlerAsAvm().avmOpcodeAddress();
1180
+ // eslint-disable-next-line camelcase
1181
+ async aztec_avm_address() {
1182
+ const contractAddress = await this.handlerAsAvm().address();
932
1183
 
933
1184
  return toForeignCallResult([toSingle(contractAddress.toField())]);
934
1185
  }
935
1186
 
936
- async avmOpcodeBlockNumber() {
937
- const blockNumber = await this.handlerAsAvm().avmOpcodeBlockNumber();
1187
+ // eslint-disable-next-line camelcase
1188
+ async aztec_avm_blockNumber() {
1189
+ const blockNumber = await this.handlerAsAvm().blockNumber();
938
1190
 
939
1191
  return toForeignCallResult([toSingle(new Fr(blockNumber))]);
940
1192
  }
941
1193
 
942
- async avmOpcodeTimestamp() {
943
- const timestamp = await this.handlerAsAvm().avmOpcodeTimestamp();
1194
+ // eslint-disable-next-line camelcase
1195
+ async aztec_avm_timestamp() {
1196
+ const timestamp = await this.handlerAsAvm().timestamp();
944
1197
 
945
1198
  return toForeignCallResult([toSingle(new Fr(timestamp))]);
946
1199
  }
947
1200
 
948
- async avmOpcodeIsStaticCall() {
949
- const isStaticCall = await this.handlerAsAvm().avmOpcodeIsStaticCall();
1201
+ // eslint-disable-next-line camelcase
1202
+ async aztec_avm_isStaticCall() {
1203
+ const isStaticCall = await this.handlerAsAvm().isStaticCall();
950
1204
 
951
1205
  return toForeignCallResult([toSingle(new Fr(isStaticCall ? 1 : 0))]);
952
1206
  }
953
1207
 
954
- async avmOpcodeChainId() {
955
- const chainId = await this.handlerAsAvm().avmOpcodeChainId();
1208
+ // eslint-disable-next-line camelcase
1209
+ async aztec_avm_chainId() {
1210
+ const chainId = await this.handlerAsAvm().chainId();
956
1211
 
957
1212
  return toForeignCallResult([toSingle(chainId)]);
958
1213
  }
959
1214
 
960
- async avmOpcodeVersion() {
961
- const version = await this.handlerAsAvm().avmOpcodeVersion();
1215
+ // eslint-disable-next-line camelcase
1216
+ async aztec_avm_version() {
1217
+ const version = await this.handlerAsAvm().version();
962
1218
 
963
1219
  return toForeignCallResult([toSingle(version)]);
964
1220
  }
965
1221
 
966
- avmOpcodeReturndataSize() {
967
- throw new Error(
968
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
969
- );
1222
+ // eslint-disable-next-line camelcase
1223
+ async aztec_avm_returndataSize() {
1224
+ const result = await this.handlerAsAvm().returndataSize();
1225
+ return toForeignCallResult([toSingle(result)]);
970
1226
  }
971
1227
 
972
- avmOpcodeReturndataCopy(_foreignRdOffset: ForeignCallSingle, _foreignCopySize: ForeignCallSingle) {
973
- throw new Error(
974
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
975
- );
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)]);
976
1234
  }
977
1235
 
978
- avmOpcodeCall(
979
- _foreignL2Gas: ForeignCallSingle,
980
- _foreignDaGas: ForeignCallSingle,
981
- _foreignAddress: ForeignCallSingle,
982
- _foreignLength: ForeignCallSingle,
983
- _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,
984
1243
  ) {
985
- throw new Error(
986
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
987
- );
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)]);
988
1251
  }
989
1252
 
990
- avmOpcodeStaticCall(
991
- _foreignL2Gas: ForeignCallSingle,
992
- _foreignDaGas: ForeignCallSingle,
993
- _foreignAddress: ForeignCallSingle,
994
- _foreignLength: ForeignCallSingle,
995
- _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,
996
1260
  ) {
997
- throw new Error(
998
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
999
- );
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)]);
1000
1268
  }
1001
1269
 
1002
- avmOpcodeSuccessCopy() {
1003
- throw new Error(
1004
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
1005
- );
1270
+ // eslint-disable-next-line camelcase
1271
+ async aztec_avm_successCopy() {
1272
+ const result = await this.handlerAsAvm().successCopy();
1273
+ return toForeignCallResult([toSingle(result)]);
1006
1274
  }
1007
1275
 
1008
- async txePrivateCallNewFlow(
1009
- 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,
1010
1281
  foreignTargetContractAddress: ForeignCallSingle,
1011
1282
  foreignFunctionSelector: ForeignCallSingle,
1012
1283
  foreignArgs: ForeignCallArray,
1013
1284
  foreignArgsHash: ForeignCallSingle,
1014
1285
  foreignIsStaticCall: ForeignCallSingle,
1286
+ foreignAdditionalScopes: ForeignCallArray,
1287
+ foreignAuthorizedUtilityCallTargets: ForeignCallArray,
1288
+ foreignGasSettings: ForeignCallArray,
1015
1289
  ) {
1016
- const from = addressFromSingle(foreignFrom);
1290
+ const from = fromSingle(foreignFromIsSome).toBool() ? addressFromSingle(foreignFromValue) : undefined;
1017
1291
  const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
1018
1292
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
1019
1293
  const args = fromArray(foreignArgs);
1020
1294
  const argsHash = fromSingle(foreignArgsHash);
1021
1295
  const isStaticCall = fromSingle(foreignIsStaticCall).toBool();
1022
-
1023
- const returnValues = await this.handlerAsTxe().txePrivateCallNewFlow(
1024
- from,
1025
- targetContractAddress,
1026
- functionSelector,
1027
- args,
1028
- argsHash,
1029
- isStaticCall,
1296
+ const additionalScopes = fromArray(foreignAdditionalScopes).map(field => AztecAddress.fromField(field));
1297
+ const authorizedUtilityCallTargets = fromArray(foreignAuthorizedUtilityCallTargets).map(field =>
1298
+ AztecAddress.fromField(field),
1030
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
+ });
1031
1336
 
1032
1337
  return toForeignCallResult([toArray(returnValues)]);
1033
1338
  }
1034
1339
 
1035
- async txeSimulateUtilityFunction(
1340
+ // TODO(F-674): Move orchestration logic into the handler so the transport layer is pure serialize→delegate→deserialize.
1341
+ // eslint-disable-next-line camelcase
1342
+ async aztec_txe_executeUtilityFunction(
1036
1343
  foreignTargetContractAddress: ForeignCallSingle,
1037
1344
  foreignFunctionSelector: ForeignCallSingle,
1038
1345
  foreignArgs: ForeignCallArray,
1346
+ foreignAuthorizedUtilityCallTargets: ForeignCallArray,
1039
1347
  ) {
1040
1348
  const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
1041
1349
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
1042
1350
  const args = fromArray(foreignArgs);
1043
-
1044
- const returnValues = await this.handlerAsTxe().txeSimulateUtilityFunction(
1045
- targetContractAddress,
1046
- functionSelector,
1047
- args,
1351
+ const authorizedUtilityCallTargets = fromArray(foreignAuthorizedUtilityCallTargets).map(field =>
1352
+ AztecAddress.fromField(field),
1048
1353
  );
1049
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
+
1050
1370
  return toForeignCallResult([toArray(returnValues)]);
1051
1371
  }
1052
1372
 
1053
- async txePublicCallNewFlow(
1054
- 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,
1055
1378
  foreignAddress: ForeignCallSingle,
1056
1379
  foreignCalldata: ForeignCallArray,
1057
1380
  foreignIsStaticCall: ForeignCallSingle,
1381
+ foreignGasSettings: ForeignCallArray,
1058
1382
  ) {
1059
- const from = addressFromSingle(foreignFrom);
1383
+ const from = fromSingle(foreignFromIsSome).toBool() ? addressFromSingle(foreignFromValue) : undefined;
1060
1384
  const address = addressFromSingle(foreignAddress);
1061
1385
  const calldata = fromArray(foreignCalldata);
1062
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
+ );
1063
1397
 
1064
- 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
+ });
1065
1408
 
1066
1409
  return toForeignCallResult([toArray(returnValues)]);
1067
1410
  }
1068
1411
 
1069
- async privateGetSenderForTags() {
1070
- const sender = await this.handlerAsPrivate().privateGetSenderForTags();
1412
+ // eslint-disable-next-line camelcase
1413
+ async aztec_prv_getSenderForTags() {
1414
+ const senderOpt = await this.handlerAsPrivate().getSenderForTags();
1071
1415
 
1072
1416
  // Return a Noir Option struct with `some` and `value` fields
1073
- 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 {
1074
1421
  // No sender found, return Option with some=0 and value=0
1075
1422
  return toForeignCallResult([toSingle(0), toSingle(0)]);
1076
- } else {
1077
- // Sender found, return Option with some=1 and value=sender address
1078
- return toForeignCallResult([toSingle(1), toSingle(sender)]);
1079
1423
  }
1080
1424
  }
1081
1425
 
1082
- async privateSetSenderForTags(foreignSenderForTags: ForeignCallSingle) {
1083
- 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));
1084
1430
 
1085
- await this.handlerAsPrivate().privateSetSenderForTags(senderForTags);
1431
+ const nextAppTag = await this.handlerAsPrivate().getNextAppTagAsSender(sender, recipient);
1086
1432
 
1087
- return toForeignCallResult([]);
1433
+ return toForeignCallResult([toSingle(nextAppTag.value)]);
1088
1434
  }
1089
1435
 
1090
- async privateGetNextAppTagAsSender(foreignSender: ForeignCallSingle, foreignRecipient: ForeignCallSingle) {
1091
- const sender = AztecAddress.fromField(fromSingle(foreignSender));
1092
- const recipient = AztecAddress.fromField(fromSingle(foreignRecipient));
1436
+ // eslint-disable-next-line camelcase
1437
+ async aztec_prv_getNextConstrainedTaggingIndex(foreignAppSiloedSecret: ForeignCallSingle) {
1438
+ const appSiloedSecret = fromSingle(foreignAppSiloedSecret);
1093
1439
 
1094
- const nextAppTag = await this.handlerAsPrivate().privateGetNextAppTagAsSender(sender, recipient);
1440
+ const index = await this.handlerAsPrivate().getNextConstrainedTaggingIndex(appSiloedSecret);
1095
1441
 
1096
- return toForeignCallResult([toSingle(nextAppTag.value)]);
1442
+ return toForeignCallResult([toSingle(new Fr(index))]);
1097
1443
  }
1098
1444
  }