@aztec/txe 1.2.1 → 2.0.0-nightly.20250814

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.
@@ -1,74 +1,122 @@
1
1
  import { Fr, Point } from '@aztec/aztec.js';
2
- import { DEPLOYER_CONTRACT_ADDRESS } from '@aztec/constants';
2
+ import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS } from '@aztec/constants';
3
3
  import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
4
- import { enrichPublicSimulationError } from '@aztec/pxe/server';
4
+ import { packAsRetrievedNote } from '@aztec/pxe/simulator';
5
5
  import { FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
6
- import { PublicDataWrite } from '@aztec/stdlib/avm';
7
6
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
8
7
  import { computePartialAddress } from '@aztec/stdlib/contract';
9
- import { SimulationError } from '@aztec/stdlib/errors';
10
- import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
11
8
  import { MerkleTreeId } from '@aztec/stdlib/trees';
12
9
  import { TXE } from '../oracle/txe_oracle.js';
13
10
  import { addressFromSingle, arrayOfArraysToBoundedVecOfArrays, arrayToBoundedVec, bufferToU8Array, fromArray, fromSingle, fromUintArray, fromUintBoundedVec, toArray, toForeignCallResult, toSingle } from '../util/encoding.js';
14
- import { ExpectedFailureError } from '../util/expected_failure_error.js';
11
+ var TXEContext = /*#__PURE__*/ function(TXEContext) {
12
+ TXEContext[TXEContext["TOP_LEVEL"] = 0] = "TOP_LEVEL";
13
+ TXEContext[TXEContext["PRIVATE"] = 1] = "PRIVATE";
14
+ TXEContext[TXEContext["PUBLIC"] = 2] = "PUBLIC";
15
+ TXEContext[TXEContext["UTILITY"] = 3] = "UTILITY";
16
+ return TXEContext;
17
+ }(TXEContext || {});
15
18
  export class TXEService {
16
19
  logger;
17
- typedOracle;
18
- oraclesEnabled;
19
- constructor(logger, typedOracle){
20
+ txe;
21
+ context;
22
+ contextChecksEnabled;
23
+ constructor(logger, txe){
20
24
  this.logger = logger;
21
- this.typedOracle = typedOracle;
22
- this.oraclesEnabled = true;
25
+ this.txe = txe;
26
+ this.context = 0;
27
+ this.contextChecksEnabled = false;
23
28
  }
24
29
  static async init(logger, protocolContracts) {
25
30
  logger.debug(`TXE service initialized`);
26
31
  const store = await openTmpStore('test');
27
32
  const txe = await TXE.create(logger, store, protocolContracts);
28
33
  const service = new TXEService(logger, txe);
29
- await service.advanceBlocksBy(toSingle(new Fr(1n)));
34
+ await service.txeAdvanceBlocksBy(toSingle(new Fr(1n)));
30
35
  return service;
31
36
  }
37
+ // TXE Context manipulation
38
+ // Temporary workaround - once all tests migrate to calling the new flow, in which this oracle is called at the
39
+ // beginning of a txe test, we'll make the context check be mandatory
40
+ txeEnableContextChecks() {
41
+ this.contextChecksEnabled = true;
42
+ return toForeignCallResult([]);
43
+ }
44
+ txeSetTopLevelTXEContext() {
45
+ if (this.contextChecksEnabled) {
46
+ if (this.context == 0) {
47
+ throw new Error(`Call to txeSetTopLevelTXEContext while in context ${TXEContext[this.context]}`);
48
+ }
49
+ }
50
+ this.context = 0;
51
+ return toForeignCallResult([]);
52
+ }
53
+ txeSetPrivateTXEContext() {
54
+ if (this.contextChecksEnabled) {
55
+ if (this.context != 0) {
56
+ throw new Error(`Call to txeSetPrivateTXEContext while in context ${TXEContext[this.context]}`);
57
+ }
58
+ }
59
+ this.context = 1;
60
+ return toForeignCallResult([]);
61
+ }
62
+ txeSetPublicTXEContext() {
63
+ if (this.contextChecksEnabled) {
64
+ if (this.context != 0) {
65
+ throw new Error(`Call to txeSetPublicTXEContext while in context ${TXEContext[this.context]}`);
66
+ }
67
+ }
68
+ this.context = 2;
69
+ return toForeignCallResult([]);
70
+ }
71
+ txeSetUtilityTXEContext() {
72
+ if (this.contextChecksEnabled) {
73
+ if (this.context != 0) {
74
+ throw new Error(`Call to txeSetUtilityTXEContext while in context ${TXEContext[this.context]}`);
75
+ }
76
+ }
77
+ this.context = 3;
78
+ return toForeignCallResult([]);
79
+ }
32
80
  // Cheatcodes
33
- async getPrivateContextInputs(blockNumberIsSome, blockNumberValue, timestampIsSome, timestampValue) {
81
+ async txeGetPrivateContextInputs(blockNumberIsSome, blockNumberValue) {
34
82
  const blockNumber = fromSingle(blockNumberIsSome).toBool() ? fromSingle(blockNumberValue).toNumber() : null;
35
- const timestamp = fromSingle(timestampIsSome).toBool() ? fromSingle(timestampValue).toBigInt() : null;
36
- const inputs = await this.typedOracle.getPrivateContextInputs(blockNumber, timestamp);
83
+ const inputs = await this.txe.txeGetPrivateContextInputs(blockNumber);
84
+ this.logger.info(`Created private context for block ${inputs.historicalHeader.globalVariables.blockNumber} (requested ${blockNumber})`);
37
85
  return toForeignCallResult(inputs.toFields().map(toSingle));
38
86
  }
39
- async advanceBlocksBy(blocks) {
87
+ async txeAdvanceBlocksBy(blocks) {
40
88
  const nBlocks = fromSingle(blocks).toNumber();
41
89
  this.logger.debug(`time traveling ${nBlocks} blocks`);
42
90
  for(let i = 0; i < nBlocks; i++){
43
- const blockNumber = await this.typedOracle.getBlockNumber();
44
- await this.typedOracle.commitState();
45
- this.typedOracle.setBlockNumber(blockNumber + 1);
91
+ const blockNumber = await this.txe.utilityGetBlockNumber();
92
+ await this.txe.commitState();
93
+ this.txe.setBlockNumber(blockNumber + 1);
46
94
  }
47
95
  return toForeignCallResult([]);
48
96
  }
49
- advanceTimestampBy(duration) {
97
+ txeAdvanceTimestampBy(duration) {
50
98
  const durationBigInt = fromSingle(duration).toBigInt();
51
99
  this.logger.debug(`time traveling ${durationBigInt} seconds`);
52
- this.typedOracle.advanceTimestampBy(durationBigInt);
100
+ this.txe.txeAdvanceTimestampBy(durationBigInt);
53
101
  return toForeignCallResult([]);
54
102
  }
55
- setContractAddress(address) {
103
+ txeSetContractAddress(address) {
56
104
  const typedAddress = addressFromSingle(address);
57
- this.typedOracle.setContractAddress(typedAddress);
105
+ this.txe.txeSetContractAddress(typedAddress);
58
106
  return toForeignCallResult([]);
59
107
  }
60
- async deriveKeys(secret) {
61
- const keys = await this.typedOracle.deriveKeys(fromSingle(secret));
62
- return toForeignCallResult(keys.publicKeys.toFields().map(toSingle));
63
- }
64
- async deploy(artifact, instance, secret) {
108
+ async txeDeploy(artifact, instance, secret) {
65
109
  // Emit deployment nullifier
66
- await this.typedOracle.noteCache.nullifierCreated(AztecAddress.fromNumber(DEPLOYER_CONTRACT_ADDRESS), instance.address.toField());
110
+ await this.txe.noteCache.nullifierCreated(AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), instance.address.toField());
111
+ // Make sure the deployment nullifier gets included in a tx in a block
112
+ const blockNumber = await this.txe.utilityGetBlockNumber();
113
+ await this.txe.commitState();
114
+ this.txe.setBlockNumber(blockNumber + 1);
67
115
  if (!fromSingle(secret).equals(Fr.ZERO)) {
68
- await this.addAccount(artifact, instance, secret);
116
+ await this.txeAddAccount(artifact, instance, secret);
69
117
  } else {
70
- await this.typedOracle.addContractInstance(instance);
71
- await this.typedOracle.addContractArtifact(instance.currentContractClassId, artifact);
118
+ await this.txe.addContractInstance(instance);
119
+ await this.txe.addContractArtifact(instance.currentContractClassId, artifact);
72
120
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
73
121
  }
74
122
  return toForeignCallResult([
@@ -81,28 +129,14 @@ export class TXEService {
81
129
  ])
82
130
  ]);
83
131
  }
84
- async directStorageWrite(contractAddress, startStorageSlot, values) {
85
- const startStorageSlotFr = fromSingle(startStorageSlot);
86
- const valuesFr = fromArray(values);
87
- const contractAddressFr = addressFromSingle(contractAddress);
88
- const publicDataWrites = await Promise.all(valuesFr.map(async (value, i)=>{
89
- const storageSlot = startStorageSlotFr.add(new Fr(i));
90
- this.logger.debug(`Oracle storage write: slot=${storageSlot.toString()} value=${value}`);
91
- return new PublicDataWrite(await computePublicDataTreeLeafSlot(contractAddressFr, storageSlot), value);
92
- }));
93
- await this.typedOracle.addPublicDataWrites(publicDataWrites);
94
- return toForeignCallResult([
95
- toArray(publicDataWrites.map((write)=>write.value))
96
- ]);
97
- }
98
- async createAccount(secret) {
99
- const keyStore = this.typedOracle.getKeyStore();
132
+ async txeCreateAccount(secret) {
133
+ const keyStore = this.txe.getKeyStore();
100
134
  const secretFr = fromSingle(secret);
101
135
  // This is a footgun !
102
136
  const completeAddress = await keyStore.addAccount(secretFr, secretFr);
103
- const accountDataProvider = this.typedOracle.getAccountDataProvider();
137
+ const accountDataProvider = this.txe.getAccountDataProvider();
104
138
  await accountDataProvider.setAccount(completeAddress.address, completeAddress);
105
- const addressDataProvider = this.typedOracle.getAddressDataProvider();
139
+ const addressDataProvider = this.txe.getAddressDataProvider();
106
140
  await addressDataProvider.addCompleteAddress(completeAddress);
107
141
  this.logger.debug(`Created account ${completeAddress.address}`);
108
142
  return toForeignCallResult([
@@ -110,15 +144,15 @@ export class TXEService {
110
144
  ...completeAddress.publicKeys.toFields().map(toSingle)
111
145
  ]);
112
146
  }
113
- async addAccount(artifact, instance, secret) {
147
+ async txeAddAccount(artifact, instance, secret) {
114
148
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
115
- await this.typedOracle.addContractInstance(instance);
116
- await this.typedOracle.addContractArtifact(instance.currentContractClassId, artifact);
117
- const keyStore = this.typedOracle.getKeyStore();
149
+ await this.txe.addContractInstance(instance);
150
+ await this.txe.addContractArtifact(instance.currentContractClassId, artifact);
151
+ const keyStore = this.txe.getKeyStore();
118
152
  const completeAddress = await keyStore.addAccount(fromSingle(secret), await computePartialAddress(instance));
119
- const accountDataProvider = this.typedOracle.getAccountDataProvider();
153
+ const accountDataProvider = this.txe.getAccountDataProvider();
120
154
  await accountDataProvider.setAccount(completeAddress.address, completeAddress);
121
- const addressDataProvider = this.typedOracle.getAddressDataProvider();
155
+ const addressDataProvider = this.txe.getAddressDataProvider();
122
156
  await addressDataProvider.addCompleteAddress(completeAddress);
123
157
  this.logger.debug(`Created account ${completeAddress.address}`);
124
158
  return toForeignCallResult([
@@ -126,190 +160,150 @@ export class TXEService {
126
160
  ...completeAddress.publicKeys.toFields().map(toSingle)
127
161
  ]);
128
162
  }
129
- getSideEffectsCounter() {
130
- const counter = this.typedOracle.getSideEffectsCounter();
131
- return toForeignCallResult([
132
- toSingle(new Fr(counter))
133
- ]);
134
- }
135
- async addAuthWitness(address, messageHash) {
136
- await this.typedOracle.addAuthWitness(addressFromSingle(address), fromSingle(messageHash));
137
- return toForeignCallResult([]);
138
- }
139
- async assertPublicCallFails(address, functionSelector, _length, args) {
140
- const parsedAddress = addressFromSingle(address);
141
- const parsedSelector = fromSingle(functionSelector);
142
- const extendedArgs = [
143
- parsedSelector,
144
- ...fromArray(args)
145
- ];
146
- const result = await this.typedOracle.avmOpcodeCall(parsedAddress, extendedArgs, false);
147
- if (result.revertCode.isOK()) {
148
- throw new ExpectedFailureError('Public call did not revert');
149
- }
150
- return toForeignCallResult([]);
151
- }
152
- async assertPrivateCallFails(targetContractAddress, functionSelector, argsHash, sideEffectCounter, isStaticCall) {
153
- try {
154
- await this.typedOracle.callPrivateFunction(addressFromSingle(targetContractAddress), FunctionSelector.fromField(fromSingle(functionSelector)), fromSingle(argsHash), fromSingle(sideEffectCounter).toNumber(), fromSingle(isStaticCall).toBool());
155
- throw new ExpectedFailureError('Private call did not fail');
156
- } catch (e) {
157
- if (e instanceof ExpectedFailureError) {
158
- throw e;
159
- }
160
- }
163
+ async txeAddAuthWitness(address, messageHash) {
164
+ await this.txe.txeAddAuthWitness(addressFromSingle(address), fromSingle(messageHash));
161
165
  return toForeignCallResult([]);
162
166
  }
163
167
  // PXE oracles
164
- getRandomField() {
165
- if (!this.oraclesEnabled) {
168
+ utilityGetRandomField() {
169
+ if (this.contextChecksEnabled && this.context == 0) {
166
170
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
167
171
  }
168
172
  return toForeignCallResult([
169
- toSingle(this.typedOracle.getRandomField())
173
+ toSingle(this.txe.utilityGetRandomField())
170
174
  ]);
171
175
  }
172
- async getContractAddress() {
173
- if (!this.oraclesEnabled) {
174
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
176
+ async utilityGetContractAddress() {
177
+ if (this.contextChecksEnabled && this.context != 0 && this.context != 3 && this.context != 1) {
178
+ throw new Error(`Attempted to call utilityGetContractAddress while in context ${TXEContext[this.context]}`);
175
179
  }
176
- const contractAddress = await this.typedOracle.getContractAddress();
180
+ const contractAddress = await this.txe.utilityGetContractAddress();
177
181
  return toForeignCallResult([
178
182
  toSingle(contractAddress.toField())
179
183
  ]);
180
184
  }
181
- async getBlockNumber() {
182
- if (!this.oraclesEnabled) {
183
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
185
+ async utilityGetBlockNumber() {
186
+ if (this.contextChecksEnabled && this.context != 0 && this.context != 3) {
187
+ throw new Error(`Attempted to call utilityGetBlockNumber while in context ${TXEContext[this.context]}`);
184
188
  }
185
- const blockNumber = await this.typedOracle.getBlockNumber();
189
+ const blockNumber = await this.txe.utilityGetBlockNumber();
186
190
  return toForeignCallResult([
187
191
  toSingle(new Fr(blockNumber))
188
192
  ]);
189
193
  }
190
- async getTimestamp() {
191
- if (!this.oraclesEnabled) {
192
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
194
+ // seems to be used to mean the timestamp of the last mined block in txe (but that's not what is done here)
195
+ async utilityGetTimestamp() {
196
+ if (this.contextChecksEnabled && this.context != 0 && this.context != 3) {
197
+ throw new Error(`Attempted to call utilityGetTimestamp while in context ${TXEContext[this.context]}`);
193
198
  }
194
- const timestamp = await this.typedOracle.getTimestamp();
199
+ const timestamp = await this.txe.utilityGetTimestamp();
200
+ return toForeignCallResult([
201
+ toSingle(new Fr(timestamp))
202
+ ]);
203
+ }
204
+ async txeGetLastBlockTimestamp() {
205
+ if (this.contextChecksEnabled && this.context != 0) {
206
+ throw new Error(`Attempted to call txeGetLastBlockTimestamp while in context ${TXEContext[this.context]}`);
207
+ }
208
+ const timestamp = await this.txe.txeGetLastBlockTimestamp();
195
209
  return toForeignCallResult([
196
210
  toSingle(new Fr(timestamp))
197
211
  ]);
198
212
  }
199
213
  // Since the argument is a slice, noir automatically adds a length field to oracle call.
200
- storeInExecutionCache(_length, values, hash) {
201
- if (!this.oraclesEnabled) {
214
+ privateStoreInExecutionCache(_length, values, hash) {
215
+ if (this.contextChecksEnabled && this.context == 0) {
202
216
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
203
217
  }
204
- this.typedOracle.storeInExecutionCache(fromArray(values), fromSingle(hash));
218
+ this.txe.privateStoreInExecutionCache(fromArray(values), fromSingle(hash));
205
219
  return toForeignCallResult([]);
206
220
  }
207
- async loadFromExecutionCache(hash) {
208
- if (!this.oraclesEnabled) {
221
+ async privateLoadFromExecutionCache(hash) {
222
+ if (this.contextChecksEnabled && this.context == 0) {
209
223
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
210
224
  }
211
- const returns = await this.typedOracle.loadFromExecutionCache(fromSingle(hash));
225
+ const returns = await this.txe.privateLoadFromExecutionCache(fromSingle(hash));
212
226
  return toForeignCallResult([
213
227
  toArray(returns)
214
228
  ]);
215
229
  }
216
230
  // Since the argument is a slice, noir automatically adds a length field to oracle call.
217
- debugLog(message, _length, fields) {
231
+ utilityDebugLog(message, _length, fields) {
218
232
  const messageStr = fromArray(message).map((field)=>String.fromCharCode(field.toNumber())).join('');
219
233
  const fieldsFr = fromArray(fields);
220
- this.typedOracle.debugLog(messageStr, fieldsFr);
234
+ this.txe.utilityDebugLog(messageStr, fieldsFr);
221
235
  return toForeignCallResult([]);
222
236
  }
223
- async storageRead(contractAddress, startStorageSlot, blockNumber, numberOfElements) {
224
- const values = await this.typedOracle.storageRead(addressFromSingle(contractAddress), fromSingle(startStorageSlot), fromSingle(blockNumber).toNumber(), fromSingle(numberOfElements).toNumber());
237
+ async utilityStorageRead(contractAddress, startStorageSlot, blockNumber, numberOfElements) {
238
+ const values = await this.txe.utilityStorageRead(addressFromSingle(contractAddress), fromSingle(startStorageSlot), fromSingle(blockNumber).toNumber(), fromSingle(numberOfElements).toNumber());
225
239
  return toForeignCallResult([
226
240
  toArray(values)
227
241
  ]);
228
242
  }
229
- async storageWrite(startStorageSlot, values) {
230
- const newValues = await this.typedOracle.storageWrite(fromSingle(startStorageSlot), fromArray(values));
231
- return toForeignCallResult([
232
- toArray(newValues)
233
- ]);
234
- }
235
- async getPublicDataWitness(blockNumber, leafSlot) {
236
- if (!this.oraclesEnabled) {
243
+ async utilityGetPublicDataWitness(blockNumber, leafSlot) {
244
+ if (this.contextChecksEnabled && this.context == 0) {
237
245
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
238
246
  }
239
247
  const parsedBlockNumber = fromSingle(blockNumber).toNumber();
240
248
  const parsedLeafSlot = fromSingle(leafSlot);
241
- const witness = await this.typedOracle.getPublicDataWitness(parsedBlockNumber, parsedLeafSlot);
249
+ const witness = await this.txe.utilityGetPublicDataWitness(parsedBlockNumber, parsedLeafSlot);
242
250
  if (!witness) {
243
251
  throw new Error(`Public data witness not found for slot ${parsedLeafSlot} at block ${parsedBlockNumber}.`);
244
252
  }
245
253
  return toForeignCallResult(witness.toNoirRepresentation());
246
254
  }
247
- async getNotes(storageSlot, numSelects, selectByIndexes, selectByOffsets, selectByLengths, selectValues, selectComparators, sortByIndexes, sortByOffsets, sortByLengths, sortOrder, limit, offset, status, maxNotes, packedRetrievedNoteLength) {
248
- if (!this.oraclesEnabled) {
255
+ async utilityGetNotes(storageSlot, numSelects, selectByIndexes, selectByOffsets, selectByLengths, selectValues, selectComparators, sortByIndexes, sortByOffsets, sortByLengths, sortOrder, limit, offset, status, maxNotes, packedRetrievedNoteLength) {
256
+ if (this.contextChecksEnabled && this.context == 0) {
249
257
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
250
258
  }
251
- const noteDatas = await this.typedOracle.getNotes(fromSingle(storageSlot), fromSingle(numSelects).toNumber(), fromArray(selectByIndexes).map((fr)=>fr.toNumber()), fromArray(selectByOffsets).map((fr)=>fr.toNumber()), fromArray(selectByLengths).map((fr)=>fr.toNumber()), fromArray(selectValues), fromArray(selectComparators).map((fr)=>fr.toNumber()), fromArray(sortByIndexes).map((fr)=>fr.toNumber()), fromArray(sortByOffsets).map((fr)=>fr.toNumber()), fromArray(sortByLengths).map((fr)=>fr.toNumber()), fromArray(sortOrder).map((fr)=>fr.toNumber()), fromSingle(limit).toNumber(), fromSingle(offset).toNumber(), fromSingle(status).toNumber());
259
+ const noteDatas = await this.txe.utilityGetNotes(fromSingle(storageSlot), fromSingle(numSelects).toNumber(), fromArray(selectByIndexes).map((fr)=>fr.toNumber()), fromArray(selectByOffsets).map((fr)=>fr.toNumber()), fromArray(selectByLengths).map((fr)=>fr.toNumber()), fromArray(selectValues), fromArray(selectComparators).map((fr)=>fr.toNumber()), fromArray(sortByIndexes).map((fr)=>fr.toNumber()), fromArray(sortByOffsets).map((fr)=>fr.toNumber()), fromArray(sortByLengths).map((fr)=>fr.toNumber()), fromArray(sortOrder).map((fr)=>fr.toNumber()), fromSingle(limit).toNumber(), fromSingle(offset).toNumber(), fromSingle(status).toNumber());
252
260
  if (noteDatas.length > 0) {
253
261
  const noteLength = noteDatas[0].note.items.length;
254
262
  if (!noteDatas.every(({ note })=>noteLength === note.items.length)) {
255
263
  throw new Error('Notes should all be the same length.');
256
264
  }
257
265
  }
258
- // The expected return type is a BoundedVec<[Field; packedRetrievedNoteLength], maxNotes> where each
259
- // array is structured as [contract_address, note_nonce, nonzero_note_hash_counter, ...packed_note].
260
- const returnDataAsArrayOfArrays = noteDatas.map(({ contractAddress, noteNonce, index, note })=>{
261
- // If index is undefined, the note is transient which implies that the nonzero_note_hash_counter has to be true
262
- const noteIsTransient = index === undefined;
263
- const nonzeroNoteHashCounter = noteIsTransient ? true : false;
264
- // If you change the array on the next line you have to change the `unpack_retrieved_note` function in
265
- // `aztec/src/note/retrieved_note.nr`
266
- return [
267
- contractAddress,
268
- noteNonce,
269
- nonzeroNoteHashCounter,
270
- ...note.items
271
- ];
272
- });
266
+ const returnDataAsArrayOfArrays = noteDatas.map(packAsRetrievedNote);
273
267
  // Now we convert each sub-array to an array of ForeignCallSingles
274
268
  const returnDataAsArrayOfForeignCallSingleArrays = returnDataAsArrayOfArrays.map((subArray)=>subArray.map(toSingle));
275
269
  // At last we convert the array of arrays to a bounded vec of arrays
276
270
  return toForeignCallResult(arrayOfArraysToBoundedVecOfArrays(returnDataAsArrayOfForeignCallSingleArrays, fromSingle(maxNotes).toNumber(), fromSingle(packedRetrievedNoteLength).toNumber()));
277
271
  }
278
- notifyCreatedNote(storageSlot, noteTypeId, note, noteHash, counter) {
279
- if (!this.oraclesEnabled) {
272
+ privateNotifyCreatedNote(storageSlot, noteTypeId, note, noteHash, counter) {
273
+ if (this.contextChecksEnabled && this.context == 0) {
280
274
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
281
275
  }
282
- this.typedOracle.notifyCreatedNote(fromSingle(storageSlot), NoteSelector.fromField(fromSingle(noteTypeId)), fromArray(note), fromSingle(noteHash), fromSingle(counter).toNumber());
276
+ this.txe.privateNotifyCreatedNote(fromSingle(storageSlot), NoteSelector.fromField(fromSingle(noteTypeId)), fromArray(note), fromSingle(noteHash), fromSingle(counter).toNumber());
283
277
  return toForeignCallResult([]);
284
278
  }
285
- async notifyNullifiedNote(innerNullifier, noteHash, counter) {
286
- if (!this.oraclesEnabled) {
279
+ async privateNotifyNullifiedNote(innerNullifier, noteHash, counter) {
280
+ if (this.contextChecksEnabled && this.context == 0) {
287
281
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
288
282
  }
289
- await this.typedOracle.notifyNullifiedNote(fromSingle(innerNullifier), fromSingle(noteHash), fromSingle(counter).toNumber());
283
+ await this.txe.privateNotifyNullifiedNote(fromSingle(innerNullifier), fromSingle(noteHash), fromSingle(counter).toNumber());
290
284
  return toForeignCallResult([]);
291
285
  }
292
- async notifyCreatedNullifier(innerNullifier) {
293
- if (!this.oraclesEnabled) {
286
+ async privateNotifyCreatedNullifier(innerNullifier) {
287
+ if (this.contextChecksEnabled && this.context == 0) {
294
288
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
295
289
  }
296
- await this.typedOracle.notifyCreatedNullifier(fromSingle(innerNullifier));
290
+ await this.txe.privateNotifyCreatedNullifier(fromSingle(innerNullifier));
297
291
  return toForeignCallResult([]);
298
292
  }
299
- async checkNullifierExists(innerNullifier) {
300
- if (!this.oraclesEnabled) {
293
+ async utilityCheckNullifierExists(innerNullifier) {
294
+ if (this.contextChecksEnabled && this.context == 0) {
301
295
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
302
296
  }
303
- const exists = await this.typedOracle.checkNullifierExists(fromSingle(innerNullifier));
297
+ const exists = await this.txe.utilityCheckNullifierExists(fromSingle(innerNullifier));
304
298
  return toForeignCallResult([
305
299
  toSingle(new Fr(exists))
306
300
  ]);
307
301
  }
308
- async getContractInstance(address) {
309
- if (!this.oraclesEnabled) {
302
+ async utilityGetContractInstance(address) {
303
+ if (this.contextChecksEnabled && this.context == 0) {
310
304
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
311
305
  }
312
- const instance = await this.typedOracle.getContractInstance(addressFromSingle(address));
306
+ const instance = await this.txe.utilityGetContractInstance(addressFromSingle(address));
313
307
  return toForeignCallResult([
314
308
  instance.salt,
315
309
  instance.deployer.toField(),
@@ -318,12 +312,12 @@ export class TXEService {
318
312
  ...instance.publicKeys.toFields()
319
313
  ].map(toSingle));
320
314
  }
321
- async getPublicKeysAndPartialAddress(address) {
322
- if (!this.oraclesEnabled) {
315
+ async utilityGetPublicKeysAndPartialAddress(address) {
316
+ if (this.contextChecksEnabled && this.context == 0) {
323
317
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
324
318
  }
325
319
  const parsedAddress = addressFromSingle(address);
326
- const { publicKeys, partialAddress } = await this.typedOracle.getCompleteAddress(parsedAddress);
320
+ const { publicKeys, partialAddress } = await this.txe.utilityGetCompleteAddress(parsedAddress);
327
321
  return toForeignCallResult([
328
322
  toArray([
329
323
  ...publicKeys.toFields(),
@@ -331,42 +325,33 @@ export class TXEService {
331
325
  ])
332
326
  ]);
333
327
  }
334
- async getKeyValidationRequest(pkMHash) {
335
- if (!this.oraclesEnabled) {
328
+ async utilityGetKeyValidationRequest(pkMHash) {
329
+ if (this.contextChecksEnabled && this.context == 0) {
336
330
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
337
331
  }
338
- const keyValidationRequest = await this.typedOracle.getKeyValidationRequest(fromSingle(pkMHash));
332
+ const keyValidationRequest = await this.txe.utilityGetKeyValidationRequest(fromSingle(pkMHash));
339
333
  return toForeignCallResult(keyValidationRequest.toFields().map(toSingle));
340
334
  }
341
- async callPrivateFunction(targetContractAddress, functionSelector, argsHash, sideEffectCounter, isStaticCall) {
342
- if (!this.oraclesEnabled) {
343
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
344
- }
345
- const result = await this.typedOracle.callPrivateFunction(addressFromSingle(targetContractAddress), FunctionSelector.fromField(fromSingle(functionSelector)), fromSingle(argsHash), fromSingle(sideEffectCounter).toNumber(), fromSingle(isStaticCall).toBool());
346
- return toForeignCallResult([
347
- toArray([
348
- result.endSideEffectCounter,
349
- result.returnsHash
350
- ])
351
- ]);
335
+ privateCallPrivateFunction(_targetContractAddress, _functionSelector, _argsHash, _sideEffectCounter, _isStaticCall) {
336
+ throw new Error('Contract calls are forbidden inside a `TestEnvironment::private_context`, use `private_call` instead');
352
337
  }
353
- async getNullifierMembershipWitness(blockNumber, nullifier) {
354
- if (!this.oraclesEnabled) {
338
+ async utilityGetNullifierMembershipWitness(blockNumber, nullifier) {
339
+ if (this.contextChecksEnabled && this.context == 0) {
355
340
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
356
341
  }
357
342
  const parsedBlockNumber = fromSingle(blockNumber).toNumber();
358
- const witness = await this.typedOracle.getNullifierMembershipWitness(parsedBlockNumber, fromSingle(nullifier));
343
+ const witness = await this.txe.utilityGetNullifierMembershipWitness(parsedBlockNumber, fromSingle(nullifier));
359
344
  if (!witness) {
360
345
  throw new Error(`Nullifier membership witness not found at block ${parsedBlockNumber}.`);
361
346
  }
362
347
  return toForeignCallResult(witness.toNoirRepresentation());
363
348
  }
364
- async getAuthWitness(messageHash) {
365
- if (!this.oraclesEnabled) {
349
+ async utilityGetAuthWitness(messageHash) {
350
+ if (this.contextChecksEnabled && this.context == 0) {
366
351
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
367
352
  }
368
353
  const parsedMessageHash = fromSingle(messageHash);
369
- const authWitness = await this.typedOracle.getAuthWitness(parsedMessageHash);
354
+ const authWitness = await this.txe.utilityGetAuthWitness(parsedMessageHash);
370
355
  if (!authWitness) {
371
356
  throw new Error(`Auth witness not found for message hash ${parsedMessageHash}.`);
372
357
  }
@@ -374,61 +359,49 @@ export class TXEService {
374
359
  toArray(authWitness)
375
360
  ]);
376
361
  }
377
- async notifyEnqueuedPublicFunctionCall(targetContractAddress, calldataHash, sideEffectCounter, isStaticCall) {
378
- if (!this.oraclesEnabled) {
379
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
380
- }
381
- await this.typedOracle.notifyEnqueuedPublicFunctionCall(addressFromSingle(targetContractAddress), fromSingle(calldataHash), fromSingle(sideEffectCounter).toNumber(), fromSingle(isStaticCall).toBool());
382
- return toForeignCallResult([]);
362
+ privateNotifyEnqueuedPublicFunctionCall(_targetContractAddress, _calldataHash, _sideEffectCounter, _isStaticCall) {
363
+ throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
383
364
  }
384
- async notifySetPublicTeardownFunctionCall(targetContractAddress, calldataHash, sideEffectCounter, isStaticCall) {
385
- if (!this.oraclesEnabled) {
386
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
387
- }
388
- await this.typedOracle.notifySetPublicTeardownFunctionCall(addressFromSingle(targetContractAddress), fromSingle(calldataHash), fromSingle(sideEffectCounter).toNumber(), fromSingle(isStaticCall).toBool());
389
- return toForeignCallResult([]);
365
+ privateNotifySetPublicTeardownFunctionCall(_targetContractAddress, _calldataHash, _sideEffectCounter, _isStaticCall) {
366
+ throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
390
367
  }
391
- async notifySetMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter) {
392
- if (!this.oraclesEnabled) {
393
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
394
- }
395
- await this.typedOracle.notifySetMinRevertibleSideEffectCounter(fromSingle(minRevertibleSideEffectCounter).toNumber());
396
- return toForeignCallResult([]);
368
+ privateNotifySetMinRevertibleSideEffectCounter(_minRevertibleSideEffectCounter) {
369
+ throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
397
370
  }
398
- async getChainId() {
399
- if (!this.oraclesEnabled) {
371
+ async utilityGetChainId() {
372
+ if (this.contextChecksEnabled && this.context == 0) {
400
373
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
401
374
  }
402
375
  return toForeignCallResult([
403
- toSingle(await this.typedOracle.getChainId())
376
+ toSingle(await this.txe.utilityGetChainId())
404
377
  ]);
405
378
  }
406
- async getVersion() {
407
- if (!this.oraclesEnabled) {
379
+ async utilityGetVersion() {
380
+ if (this.contextChecksEnabled && this.context == 0) {
408
381
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
409
382
  }
410
383
  return toForeignCallResult([
411
- toSingle(await this.typedOracle.getVersion())
384
+ toSingle(await this.txe.utilityGetVersion())
412
385
  ]);
413
386
  }
414
- async getBlockHeader(blockNumber) {
415
- if (!this.oraclesEnabled) {
387
+ async utilityGetBlockHeader(blockNumber) {
388
+ if (this.contextChecksEnabled && this.context == 0) {
416
389
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
417
390
  }
418
- const header = await this.typedOracle.getBlockHeader(fromSingle(blockNumber).toNumber());
391
+ const header = await this.txe.utilityGetBlockHeader(fromSingle(blockNumber).toNumber());
419
392
  if (!header) {
420
393
  throw new Error(`Block header not found for block ${blockNumber}.`);
421
394
  }
422
395
  return toForeignCallResult(header.toFields().map(toSingle));
423
396
  }
424
- async getMembershipWitness(blockNumber, treeId, leafValue) {
425
- if (!this.oraclesEnabled) {
397
+ async utilityGetMembershipWitness(blockNumber, treeId, leafValue) {
398
+ if (this.contextChecksEnabled && this.context == 0) {
426
399
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
427
400
  }
428
401
  const parsedBlockNumber = fromSingle(blockNumber).toNumber();
429
402
  const parsedTreeId = fromSingle(treeId).toNumber();
430
403
  const parsedLeafValue = fromSingle(leafValue);
431
- const witness = await this.typedOracle.getMembershipWitness(parsedBlockNumber, parsedTreeId, parsedLeafValue);
404
+ const witness = await this.txe.utilityGetMembershipWitness(parsedBlockNumber, parsedTreeId, parsedLeafValue);
432
405
  if (!witness) {
433
406
  throw new Error(`Membership witness in tree ${MerkleTreeId[parsedTreeId]} not found for value ${parsedLeafValue} at block ${parsedBlockNumber}.`);
434
407
  }
@@ -437,57 +410,57 @@ export class TXEService {
437
410
  toArray(witness.slice(1))
438
411
  ]);
439
412
  }
440
- async getLowNullifierMembershipWitness(blockNumber, nullifier) {
441
- if (!this.oraclesEnabled) {
413
+ async utilityGetLowNullifierMembershipWitness(blockNumber, nullifier) {
414
+ if (this.contextChecksEnabled && this.context == 0) {
442
415
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
443
416
  }
444
417
  const parsedBlockNumber = fromSingle(blockNumber).toNumber();
445
- const witness = await this.typedOracle.getLowNullifierMembershipWitness(parsedBlockNumber, fromSingle(nullifier));
418
+ const witness = await this.txe.utilityGetLowNullifierMembershipWitness(parsedBlockNumber, fromSingle(nullifier));
446
419
  if (!witness) {
447
420
  throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${parsedBlockNumber}.`);
448
421
  }
449
422
  return toForeignCallResult(witness.toNoirRepresentation());
450
423
  }
451
- async getIndexedTaggingSecretAsSender(sender, recipient) {
452
- if (!this.oraclesEnabled) {
424
+ async utilityGetIndexedTaggingSecretAsSender(sender, recipient) {
425
+ if (this.contextChecksEnabled && this.context == 0) {
453
426
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
454
427
  }
455
- const secret = await this.typedOracle.getIndexedTaggingSecretAsSender(AztecAddress.fromField(fromSingle(sender)), AztecAddress.fromField(fromSingle(recipient)));
428
+ const secret = await this.txe.utilityGetIndexedTaggingSecretAsSender(AztecAddress.fromField(fromSingle(sender)), AztecAddress.fromField(fromSingle(recipient)));
456
429
  return toForeignCallResult(secret.toFields().map(toSingle));
457
430
  }
458
- async fetchTaggedLogs(pendingTaggedLogArrayBaseSlot) {
459
- if (!this.oraclesEnabled) {
431
+ async utilityFetchTaggedLogs(pendingTaggedLogArrayBaseSlot) {
432
+ if (this.contextChecksEnabled && this.context == 0) {
460
433
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
461
434
  }
462
- await this.typedOracle.fetchTaggedLogs(fromSingle(pendingTaggedLogArrayBaseSlot));
435
+ await this.txe.utilityFetchTaggedLogs(fromSingle(pendingTaggedLogArrayBaseSlot));
463
436
  return toForeignCallResult([]);
464
437
  }
465
- async validateEnqueuedNotesAndEvents(contractAddress, noteValidationRequestsArrayBaseSlot, eventValidationRequestsArrayBaseSlot) {
466
- if (!this.oraclesEnabled) {
438
+ async utilityValidateEnqueuedNotesAndEvents(contractAddress, noteValidationRequestsArrayBaseSlot, eventValidationRequestsArrayBaseSlot) {
439
+ if (this.contextChecksEnabled && this.context == 0) {
467
440
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
468
441
  }
469
- await this.typedOracle.validateEnqueuedNotesAndEvents(AztecAddress.fromField(fromSingle(contractAddress)), fromSingle(noteValidationRequestsArrayBaseSlot), fromSingle(eventValidationRequestsArrayBaseSlot));
442
+ await this.txe.utilityValidateEnqueuedNotesAndEvents(AztecAddress.fromField(fromSingle(contractAddress)), fromSingle(noteValidationRequestsArrayBaseSlot), fromSingle(eventValidationRequestsArrayBaseSlot));
470
443
  return toForeignCallResult([]);
471
444
  }
472
- async bulkRetrieveLogs(contractAddress, logRetrievalRequestsArrayBaseSlot, logRetrievalResponsesArrayBaseSlot) {
473
- if (!this.oraclesEnabled) {
445
+ async utilityBulkRetrieveLogs(contractAddress, logRetrievalRequestsArrayBaseSlot, logRetrievalResponsesArrayBaseSlot) {
446
+ if (this.contextChecksEnabled && this.context == 0) {
474
447
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
475
448
  }
476
- await this.typedOracle.bulkRetrieveLogs(AztecAddress.fromField(fromSingle(contractAddress)), fromSingle(logRetrievalRequestsArrayBaseSlot), fromSingle(logRetrievalResponsesArrayBaseSlot));
449
+ await this.txe.utilityBulkRetrieveLogs(AztecAddress.fromField(fromSingle(contractAddress)), fromSingle(logRetrievalRequestsArrayBaseSlot), fromSingle(logRetrievalResponsesArrayBaseSlot));
477
450
  return toForeignCallResult([]);
478
451
  }
479
- async storeCapsule(contractAddress, slot, capsule) {
480
- if (!this.oraclesEnabled) {
452
+ async utilityStoreCapsule(contractAddress, slot, capsule) {
453
+ if (this.contextChecksEnabled && this.context == 0) {
481
454
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
482
455
  }
483
- await this.typedOracle.storeCapsule(AztecAddress.fromField(fromSingle(contractAddress)), fromSingle(slot), fromArray(capsule));
456
+ await this.txe.utilityStoreCapsule(AztecAddress.fromField(fromSingle(contractAddress)), fromSingle(slot), fromArray(capsule));
484
457
  return toForeignCallResult([]);
485
458
  }
486
- async loadCapsule(contractAddress, slot, tSize) {
487
- if (!this.oraclesEnabled) {
459
+ async utilityLoadCapsule(contractAddress, slot, tSize) {
460
+ if (this.contextChecksEnabled && this.context == 0) {
488
461
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
489
462
  }
490
- const values = await this.typedOracle.loadCapsule(AztecAddress.fromField(fromSingle(contractAddress)), fromSingle(slot));
463
+ const values = await this.txe.utilityLoadCapsule(AztecAddress.fromField(fromSingle(contractAddress)), fromSingle(slot));
491
464
  // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
492
465
  // with two fields: `some` (a boolean) and `value` (a field array in this case).
493
466
  if (values === null) {
@@ -504,39 +477,39 @@ export class TXEService {
504
477
  ]);
505
478
  }
506
479
  }
507
- async deleteCapsule(contractAddress, slot) {
508
- if (!this.oraclesEnabled) {
480
+ async utilityDeleteCapsule(contractAddress, slot) {
481
+ if (this.contextChecksEnabled && this.context == 0) {
509
482
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
510
483
  }
511
- await this.typedOracle.deleteCapsule(AztecAddress.fromField(fromSingle(contractAddress)), fromSingle(slot));
484
+ await this.txe.utilityDeleteCapsule(AztecAddress.fromField(fromSingle(contractAddress)), fromSingle(slot));
512
485
  return toForeignCallResult([]);
513
486
  }
514
- async copyCapsule(contractAddress, srcSlot, dstSlot, numEntries) {
515
- if (!this.oraclesEnabled) {
487
+ async utilityCopyCapsule(contractAddress, srcSlot, dstSlot, numEntries) {
488
+ if (this.contextChecksEnabled && this.context == 0) {
516
489
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
517
490
  }
518
- await this.typedOracle.copyCapsule(AztecAddress.fromField(fromSingle(contractAddress)), fromSingle(srcSlot), fromSingle(dstSlot), fromSingle(numEntries).toNumber());
491
+ await this.txe.utilityCopyCapsule(AztecAddress.fromField(fromSingle(contractAddress)), fromSingle(srcSlot), fromSingle(dstSlot), fromSingle(numEntries).toNumber());
519
492
  return toForeignCallResult([]);
520
493
  }
521
494
  // TODO: I forgot to add a corresponding function here, when I introduced an oracle method to txe_oracle.ts.
522
495
  // 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
523
496
  // to implement this function here. Isn't there a way to programmatically identify that this is missing, given the
524
497
  // existence of a txe_oracle method?
525
- async aes128Decrypt(ciphertextBVecStorage, ciphertextLength, iv, symKey) {
526
- if (!this.oraclesEnabled) {
498
+ async utilityAes128Decrypt(ciphertextBVecStorage, ciphertextLength, iv, symKey) {
499
+ if (this.contextChecksEnabled && this.context == 0) {
527
500
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
528
501
  }
529
502
  const ciphertext = fromUintBoundedVec(ciphertextBVecStorage, ciphertextLength, 8);
530
503
  const ivBuffer = fromUintArray(iv, 8);
531
504
  const symKeyBuffer = fromUintArray(symKey, 8);
532
- const plaintextBuffer = await this.typedOracle.aes128Decrypt(ciphertext, ivBuffer, symKeyBuffer);
505
+ const plaintextBuffer = await this.txe.utilityAes128Decrypt(ciphertext, ivBuffer, symKeyBuffer);
533
506
  return toForeignCallResult(arrayToBoundedVec(bufferToU8Array(plaintextBuffer), ciphertextBVecStorage.length));
534
507
  }
535
- async getSharedSecret(address, ephPKField0, ephPKField1, ephPKField2) {
536
- if (!this.oraclesEnabled) {
508
+ async utilityGetSharedSecret(address, ephPKField0, ephPKField1, ephPKField2) {
509
+ if (this.contextChecksEnabled && this.context == 0) {
537
510
  throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
538
511
  }
539
- const secret = await this.typedOracle.getSharedSecret(AztecAddress.fromField(fromSingle(address)), Point.fromFields([
512
+ const secret = await this.txe.utilityGetSharedSecret(AztecAddress.fromField(fromSingle(address)), Point.fromFields([
540
513
  fromSingle(ephPKField0),
541
514
  fromSingle(ephPKField1),
542
515
  fromSingle(ephPKField2)
@@ -544,44 +517,39 @@ export class TXEService {
544
517
  return toForeignCallResult(secret.toFields().map(toSingle));
545
518
  }
546
519
  emitOffchainEffect(_data) {
547
- if (!this.oraclesEnabled) {
548
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
549
- }
550
- // Offchain effects are currently discarded in the TXE tests.
551
- // TODO: Expose this to the tests.
552
- return toForeignCallResult([]);
520
+ throw new Error('Offchain effects are not yet supported in the TestEnvironment');
553
521
  }
554
522
  // AVM opcodes
555
523
  avmOpcodeEmitUnencryptedLog(_message) {
556
- if (!this.oraclesEnabled) {
557
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
524
+ if (this.contextChecksEnabled && this.context != 2) {
525
+ throw new Error(`Attempted to call the avmOpcodeEmitUnencryptedLog oracle while in context ${TXEContext[this.context]}`);
558
526
  }
559
527
  // TODO(#8811): Implement
560
528
  return toForeignCallResult([]);
561
529
  }
562
530
  async avmOpcodeStorageRead(slot) {
563
- if (!this.oraclesEnabled) {
564
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
531
+ if (this.contextChecksEnabled && this.context != 2) {
532
+ throw new Error(`Attempted to call the avmOpcodeStorageRead oracle while in context ${TXEContext[this.context]}`);
565
533
  }
566
- const value = (await this.typedOracle.avmOpcodeStorageRead(fromSingle(slot))).value;
534
+ const value = (await this.txe.avmOpcodeStorageRead(fromSingle(slot))).value;
567
535
  return toForeignCallResult([
568
536
  toSingle(new Fr(value))
569
537
  ]);
570
538
  }
571
539
  async avmOpcodeStorageWrite(slot, value) {
572
- if (!this.oraclesEnabled) {
573
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
540
+ if (this.contextChecksEnabled && this.context != 2) {
541
+ throw new Error(`Attempted to call the avmOpcodeStorageWrite oracle while in context ${TXEContext[this.context]}`);
574
542
  }
575
- await this.typedOracle.storageWrite(fromSingle(slot), [
543
+ await this.txe.storageWrite(fromSingle(slot), [
576
544
  fromSingle(value)
577
545
  ]);
578
546
  return toForeignCallResult([]);
579
547
  }
580
548
  async avmOpcodeGetContractInstanceDeployer(address) {
581
- if (!this.oraclesEnabled) {
582
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
549
+ if (this.contextChecksEnabled && this.context != 2) {
550
+ throw new Error(`Attempted to call the avmOpcodeGetContractInstanceDeployer oracle while in context ${TXEContext[this.context]}`);
583
551
  }
584
- const instance = await this.typedOracle.getContractInstance(addressFromSingle(address));
552
+ const instance = await this.txe.utilityGetContractInstance(addressFromSingle(address));
585
553
  return toForeignCallResult([
586
554
  toSingle(instance.deployer),
587
555
  // AVM requires an extra boolean indicating the instance was found
@@ -589,10 +557,10 @@ export class TXEService {
589
557
  ]);
590
558
  }
591
559
  async avmOpcodeGetContractInstanceClassId(address) {
592
- if (!this.oraclesEnabled) {
593
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
560
+ if (this.contextChecksEnabled && this.context != 2) {
561
+ throw new Error(`Attempted to call the avmOpcodeGetContractInstanceClassId oracle while in context ${TXEContext[this.context]}`);
594
562
  }
595
- const instance = await this.typedOracle.getContractInstance(addressFromSingle(address));
563
+ const instance = await this.txe.utilityGetContractInstance(addressFromSingle(address));
596
564
  return toForeignCallResult([
597
565
  toSingle(instance.currentContractClassId),
598
566
  // AVM requires an extra boolean indicating the instance was found
@@ -600,10 +568,10 @@ export class TXEService {
600
568
  ]);
601
569
  }
602
570
  async avmOpcodeGetContractInstanceInitializationHash(address) {
603
- if (!this.oraclesEnabled) {
604
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
571
+ if (this.contextChecksEnabled && this.context != 2) {
572
+ throw new Error(`Attempted to call the avmOpcodeGetContractInstanceInitializationHash oracle while in context ${TXEContext[this.context]}`);
605
573
  }
606
- const instance = await this.typedOracle.getContractInstance(addressFromSingle(address));
574
+ const instance = await this.txe.utilityGetContractInstance(addressFromSingle(address));
607
575
  return toForeignCallResult([
608
576
  toSingle(instance.initializationHash),
609
577
  // AVM requires an extra boolean indicating the instance was found
@@ -611,181 +579,157 @@ export class TXEService {
611
579
  ]);
612
580
  }
613
581
  avmOpcodeSender() {
614
- if (!this.oraclesEnabled) {
615
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
582
+ if (this.contextChecksEnabled && this.context != 2) {
583
+ throw new Error(`Attempted to call the avmOpcodeSender oracle while in context ${TXEContext[this.context]}`);
616
584
  }
617
- const sender = this.typedOracle.getMsgSender();
585
+ const sender = this.txe.getMsgSender();
618
586
  return toForeignCallResult([
619
587
  toSingle(sender)
620
588
  ]);
621
589
  }
622
590
  async avmOpcodeEmitNullifier(nullifier) {
623
- if (!this.oraclesEnabled) {
624
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
591
+ if (this.contextChecksEnabled && this.context != 2) {
592
+ throw new Error(`Attempted to call the avmOpcodeEmitNullifier oracle while in context ${TXEContext[this.context]}`);
625
593
  }
626
- await this.typedOracle.avmOpcodeEmitNullifier(fromSingle(nullifier));
594
+ await this.txe.avmOpcodeEmitNullifier(fromSingle(nullifier));
627
595
  return toForeignCallResult([]);
628
596
  }
629
597
  async avmOpcodeEmitNoteHash(noteHash) {
630
- if (!this.oraclesEnabled) {
631
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
598
+ if (this.contextChecksEnabled && this.context != 2) {
599
+ throw new Error(`Attempted to call the avmOpcodeEmitNoteHash oracle while in context ${TXEContext[this.context]}`);
632
600
  }
633
- await this.typedOracle.avmOpcodeEmitNoteHash(fromSingle(noteHash));
601
+ await this.txe.avmOpcodeEmitNoteHash(fromSingle(noteHash));
634
602
  return toForeignCallResult([]);
635
603
  }
636
604
  async avmOpcodeNullifierExists(innerNullifier, targetAddress) {
637
- if (!this.oraclesEnabled) {
638
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
605
+ if (this.contextChecksEnabled && this.context != 2) {
606
+ throw new Error(`Attempted to call the avmOpcodeNullifierExists oracle while in context ${TXEContext[this.context]}`);
639
607
  }
640
- const exists = await this.typedOracle.avmOpcodeNullifierExists(fromSingle(innerNullifier), AztecAddress.fromField(fromSingle(targetAddress)));
608
+ const exists = await this.txe.avmOpcodeNullifierExists(fromSingle(innerNullifier), AztecAddress.fromField(fromSingle(targetAddress)));
641
609
  return toForeignCallResult([
642
610
  toSingle(new Fr(exists))
643
611
  ]);
644
612
  }
645
613
  async avmOpcodeAddress() {
646
- if (!this.oraclesEnabled) {
647
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
614
+ if (this.contextChecksEnabled && this.context != 2) {
615
+ throw new Error(`Attempted to call the avmOpcodeAddress oracle while in context ${TXEContext[this.context]}`);
648
616
  }
649
- const contractAddress = await this.typedOracle.getContractAddress();
617
+ const contractAddress = await this.txe.utilityGetContractAddress();
650
618
  return toForeignCallResult([
651
619
  toSingle(contractAddress.toField())
652
620
  ]);
653
621
  }
654
622
  async avmOpcodeBlockNumber() {
655
- if (!this.oraclesEnabled) {
656
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
623
+ if (this.contextChecksEnabled && this.context != 2) {
624
+ throw new Error(`Attempted to call the avmOpcodeBlockNumber oracle while in context ${TXEContext[this.context]}`);
657
625
  }
658
- const blockNumber = await this.typedOracle.getBlockNumber();
626
+ const blockNumber = await this.txe.utilityGetBlockNumber();
659
627
  return toForeignCallResult([
660
628
  toSingle(new Fr(blockNumber))
661
629
  ]);
662
630
  }
663
631
  async avmOpcodeTimestamp() {
664
- if (!this.oraclesEnabled) {
665
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
632
+ if (this.contextChecksEnabled && this.context != 2) {
633
+ throw new Error(`Attempted to call the avmOpcodeTimestamp oracle while in context ${TXEContext[this.context]}`);
666
634
  }
667
- const timestamp = await this.typedOracle.getTimestamp();
635
+ const timestamp = await this.txe.utilityGetTimestamp();
668
636
  return toForeignCallResult([
669
637
  toSingle(new Fr(timestamp))
670
638
  ]);
671
639
  }
672
640
  avmOpcodeIsStaticCall() {
673
- if (!this.oraclesEnabled) {
674
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
641
+ if (this.contextChecksEnabled && this.context != 2) {
642
+ throw new Error(`Attempted to call the avmOpcodeIsStaticCall oracle while in context ${TXEContext[this.context]}`);
675
643
  }
676
- const isStaticCall = this.typedOracle.getIsStaticCall();
644
+ // TestEnvironment::public_context is always static
645
+ const isStaticCall = true;
677
646
  return toForeignCallResult([
678
647
  toSingle(new Fr(isStaticCall ? 1 : 0))
679
648
  ]);
680
649
  }
681
650
  async avmOpcodeChainId() {
682
- if (!this.oraclesEnabled) {
683
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
651
+ if (this.contextChecksEnabled && this.context != 2) {
652
+ throw new Error(`Attempted to call the avmOpcodeChainId oracle while in context ${TXEContext[this.context]}`);
684
653
  }
685
- const chainId = await this.typedOracle.getChainId();
654
+ const chainId = await this.txe.utilityGetChainId();
686
655
  return toForeignCallResult([
687
656
  toSingle(chainId)
688
657
  ]);
689
658
  }
690
659
  async avmOpcodeVersion() {
691
- if (!this.oraclesEnabled) {
692
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
660
+ if (this.contextChecksEnabled && this.context != 2) {
661
+ throw new Error(`Attempted to call the avmOpcodeVersion oracle while in context ${TXEContext[this.context]}`);
693
662
  }
694
- const version = await this.typedOracle.getVersion();
663
+ const version = await this.txe.utilityGetVersion();
695
664
  return toForeignCallResult([
696
665
  toSingle(version)
697
666
  ]);
698
667
  }
699
668
  avmOpcodeReturndataSize() {
700
- if (!this.oraclesEnabled) {
701
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
702
- }
703
- const size = this.typedOracle.avmOpcodeReturndataSize();
704
- return toForeignCallResult([
705
- toSingle(new Fr(size))
706
- ]);
669
+ throw new Error('Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead');
707
670
  }
708
- avmOpcodeReturndataCopy(rdOffset, copySize) {
709
- if (!this.oraclesEnabled) {
710
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
711
- }
712
- const returndata = this.typedOracle.avmOpcodeReturndataCopy(fromSingle(rdOffset).toNumber(), fromSingle(copySize).toNumber());
713
- // This is a slice, so we need to return the length as well.
714
- return toForeignCallResult([
715
- toSingle(new Fr(returndata.length)),
716
- toArray(returndata)
717
- ]);
671
+ avmOpcodeReturndataCopy(_rdOffset, _copySize) {
672
+ throw new Error('Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead');
718
673
  }
719
- async avmOpcodeCall(_l2Gas, _daGas, address, _length, args) {
720
- if (!this.oraclesEnabled) {
721
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
722
- }
723
- const result = await this.typedOracle.avmOpcodeCall(addressFromSingle(address), fromArray(args), /* isStaticCall */ false);
724
- // Poor man's revert handling
725
- if (!result.revertCode.isOK()) {
726
- if (result.revertReason && result.revertReason instanceof SimulationError) {
727
- await enrichPublicSimulationError(result.revertReason, this.typedOracle.getContractDataProvider(), this.logger);
728
- throw new Error(result.revertReason.message);
729
- } else {
730
- throw new Error(`Public function call reverted: ${result.revertReason}`);
731
- }
732
- }
733
- return toForeignCallResult([]);
674
+ avmOpcodeCall(_l2Gas, _daGas, _address, _length, _args) {
675
+ throw new Error('Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead');
734
676
  }
735
- async avmOpcodeStaticCall(_l2Gas, _daGas, address, _length, args) {
736
- if (!this.oraclesEnabled) {
737
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
738
- }
739
- const result = await this.typedOracle.avmOpcodeCall(addressFromSingle(address), fromArray(args), /* isStaticCall */ true);
740
- // Poor man's revert handling
741
- if (!result.revertCode.isOK()) {
742
- if (result.revertReason && result.revertReason instanceof SimulationError) {
743
- await enrichPublicSimulationError(result.revertReason, this.typedOracle.getContractDataProvider(), this.logger);
744
- throw new Error(result.revertReason.message);
745
- } else {
746
- throw new Error(`Public function call reverted: ${result.revertReason}`);
747
- }
748
- }
749
- return toForeignCallResult([]);
677
+ avmOpcodeStaticCall(_l2Gas, _daGas, _address, _length, _args) {
678
+ throw new Error('Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead');
750
679
  }
751
680
  avmOpcodeSuccessCopy() {
752
- if (!this.oraclesEnabled) {
753
- throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
754
- }
755
- const success = this.typedOracle.avmOpcodeSuccessCopy();
756
- return toForeignCallResult([
757
- toSingle(new Fr(success))
758
- ]);
681
+ throw new Error('Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead');
759
682
  }
760
- async privateCallNewFlow(from, targetContractAddress, functionSelector, _argsLength, args, argsHash, isStaticCall) {
761
- const result = await this.typedOracle.privateCallNewFlow(addressFromSingle(from), addressFromSingle(targetContractAddress), FunctionSelector.fromField(fromSingle(functionSelector)), fromArray(args), fromSingle(argsHash), fromSingle(isStaticCall).toBool());
683
+ async txePrivateCallNewFlow(from, targetContractAddress, functionSelector, _argsLength, args, argsHash, isStaticCall) {
684
+ const result = await this.txe.txePrivateCallNewFlow(addressFromSingle(from), addressFromSingle(targetContractAddress), FunctionSelector.fromField(fromSingle(functionSelector)), fromArray(args), fromSingle(argsHash), fromSingle(isStaticCall).toBool());
762
685
  return toForeignCallResult([
763
686
  toArray([
764
687
  result.endSideEffectCounter,
765
688
  result.returnsHash,
766
- result.txHash
689
+ result.txHash.hash
767
690
  ])
768
691
  ]);
769
692
  }
770
- disableOracles() {
771
- this.oraclesEnabled = false;
772
- }
773
- enableOracles() {
774
- this.oraclesEnabled = true;
775
- }
776
693
  async simulateUtilityFunction(targetContractAddress, functionSelector, argsHash) {
777
- const result = await this.typedOracle.simulateUtilityFunction(addressFromSingle(targetContractAddress), FunctionSelector.fromField(fromSingle(functionSelector)), fromSingle(argsHash));
694
+ const result = await this.txe.simulateUtilityFunction(addressFromSingle(targetContractAddress), FunctionSelector.fromField(fromSingle(functionSelector)), fromSingle(argsHash));
778
695
  return toForeignCallResult([
779
696
  toSingle(result)
780
697
  ]);
781
698
  }
782
- async publicCallNewFlow(from, address, _length, calldata, isStaticCall) {
783
- const result = await this.typedOracle.publicCallNewFlow(addressFromSingle(from), addressFromSingle(address), fromArray(calldata), fromSingle(isStaticCall).toBool());
699
+ async txePublicCallNewFlow(from, address, _length, calldata, isStaticCall) {
700
+ const result = await this.txe.txePublicCallNewFlow(addressFromSingle(from), addressFromSingle(address), fromArray(calldata), fromSingle(isStaticCall).toBool());
784
701
  return toForeignCallResult([
785
702
  toArray([
786
703
  result.returnsHash,
787
- result.txHash
704
+ result.txHash.hash
788
705
  ])
789
706
  ]);
790
707
  }
708
+ async privateGetSenderForTags() {
709
+ if (this.contextChecksEnabled && this.context == 0) {
710
+ throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
711
+ }
712
+ const sender = await this.txe.privateGetSenderForTags();
713
+ // Return a Noir Option struct with `some` and `value` fields
714
+ if (sender === undefined) {
715
+ // No sender found, return Option with some=0 and value=0
716
+ return toForeignCallResult([
717
+ toSingle(0),
718
+ toSingle(0)
719
+ ]);
720
+ } else {
721
+ // Sender found, return Option with some=1 and value=sender address
722
+ return toForeignCallResult([
723
+ toSingle(1),
724
+ toSingle(sender)
725
+ ]);
726
+ }
727
+ }
728
+ async privateSetSenderForTags(senderForTags) {
729
+ if (this.contextChecksEnabled && this.context == 0) {
730
+ throw new Error('Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.');
731
+ }
732
+ await this.txe.privateSetSenderForTags(AztecAddress.fromField(fromSingle(senderForTags)));
733
+ return toForeignCallResult([]);
734
+ }
791
735
  }