@aztec/txe 1.2.0 → 2.0.0-nightly.20250813
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.
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +34 -33
- package/dest/oracle/txe_oracle.d.ts +52 -81
- package/dest/oracle/txe_oracle.d.ts.map +1 -1
- package/dest/oracle/txe_oracle.js +167 -408
- package/dest/state_machine/archiver.d.ts +4 -2
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +8 -0
- package/dest/state_machine/dummy_p2p_client.d.ts +6 -3
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +8 -0
- package/dest/state_machine/mock_epoch_cache.d.ts +4 -2
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +7 -1
- package/dest/txe_constants.d.ts +0 -1
- package/dest/txe_constants.d.ts.map +1 -1
- package/dest/txe_constants.js +0 -2
- package/dest/txe_service/txe_service.d.ts +82 -90
- package/dest/txe_service/txe_service.d.ts.map +1 -1
- package/dest/txe_service/txe_service.js +305 -361
- package/dest/util/txe_public_contract_data_source.js +1 -1
- package/package.json +16 -16
- package/src/index.ts +42 -35
- package/src/oracle/txe_oracle.ts +192 -551
- package/src/state_machine/archiver.ts +10 -2
- package/src/state_machine/dummy_p2p_client.ts +29 -3
- package/src/state_machine/mock_epoch_cache.ts +10 -2
- package/src/txe_constants.ts +0 -2
- package/src/txe_service/txe_service.ts +353 -480
- package/src/util/txe_public_contract_data_source.ts +1 -1
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import { type ContractInstanceWithAddress, Fr, Point } from '@aztec/aztec.js';
|
|
2
|
-
import {
|
|
2
|
+
import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS } from '@aztec/constants';
|
|
3
3
|
import type { Logger } from '@aztec/foundation/log';
|
|
4
4
|
import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
|
|
5
5
|
import type { ProtocolContract } from '@aztec/protocol-contracts';
|
|
6
|
-
import {
|
|
7
|
-
import type { TypedOracle } from '@aztec/pxe/simulator';
|
|
6
|
+
import { packAsRetrievedNote } from '@aztec/pxe/simulator';
|
|
8
7
|
import { type ContractArtifact, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
9
|
-
import { PublicDataWrite } from '@aztec/stdlib/avm';
|
|
10
8
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
11
9
|
import { computePartialAddress } from '@aztec/stdlib/contract';
|
|
12
|
-
import { SimulationError } from '@aztec/stdlib/errors';
|
|
13
|
-
import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
|
|
14
10
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
15
11
|
|
|
16
12
|
import { TXE } from '../oracle/txe_oracle.js';
|
|
@@ -29,14 +25,21 @@ import {
|
|
|
29
25
|
toForeignCallResult,
|
|
30
26
|
toSingle,
|
|
31
27
|
} from '../util/encoding.js';
|
|
32
|
-
|
|
28
|
+
|
|
29
|
+
enum TXEContext {
|
|
30
|
+
TOP_LEVEL,
|
|
31
|
+
PRIVATE,
|
|
32
|
+
PUBLIC,
|
|
33
|
+
UTILITY,
|
|
34
|
+
}
|
|
33
35
|
|
|
34
36
|
export class TXEService {
|
|
35
|
-
|
|
37
|
+
context = TXEContext.TOP_LEVEL;
|
|
38
|
+
contextChecksEnabled = false;
|
|
36
39
|
|
|
37
40
|
constructor(
|
|
38
41
|
private logger: Logger,
|
|
39
|
-
private
|
|
42
|
+
private txe: TXE,
|
|
40
43
|
) {}
|
|
41
44
|
|
|
42
45
|
static async init(logger: Logger, protocolContracts: ProtocolContract[]) {
|
|
@@ -44,67 +47,119 @@ export class TXEService {
|
|
|
44
47
|
const store = await openTmpStore('test');
|
|
45
48
|
const txe = await TXE.create(logger, store, protocolContracts);
|
|
46
49
|
const service = new TXEService(logger, txe);
|
|
47
|
-
await service.
|
|
50
|
+
await service.txeAdvanceBlocksBy(toSingle(new Fr(1n)));
|
|
48
51
|
return service;
|
|
49
52
|
}
|
|
50
53
|
|
|
54
|
+
// TXE Context manipulation
|
|
55
|
+
|
|
56
|
+
// Temporary workaround - once all tests migrate to calling the new flow, in which this oracle is called at the
|
|
57
|
+
// beginning of a txe test, we'll make the context check be mandatory
|
|
58
|
+
txeEnableContextChecks() {
|
|
59
|
+
this.contextChecksEnabled = true;
|
|
60
|
+
return toForeignCallResult([]);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
txeSetTopLevelTXEContext() {
|
|
64
|
+
if (this.contextChecksEnabled) {
|
|
65
|
+
if (this.context == TXEContext.TOP_LEVEL) {
|
|
66
|
+
throw new Error(`Call to txeSetTopLevelTXEContext while in context ${TXEContext[this.context]}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.context = TXEContext.TOP_LEVEL;
|
|
71
|
+
return toForeignCallResult([]);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
txeSetPrivateTXEContext() {
|
|
75
|
+
if (this.contextChecksEnabled) {
|
|
76
|
+
if (this.context != TXEContext.TOP_LEVEL) {
|
|
77
|
+
throw new Error(`Call to txeSetPrivateTXEContext while in context ${TXEContext[this.context]}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
this.context = TXEContext.PRIVATE;
|
|
82
|
+
return toForeignCallResult([]);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
txeSetPublicTXEContext() {
|
|
86
|
+
if (this.contextChecksEnabled) {
|
|
87
|
+
if (this.context != TXEContext.TOP_LEVEL) {
|
|
88
|
+
throw new Error(`Call to txeSetPublicTXEContext while in context ${TXEContext[this.context]}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
this.context = TXEContext.PUBLIC;
|
|
93
|
+
return toForeignCallResult([]);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
txeSetUtilityTXEContext() {
|
|
97
|
+
if (this.contextChecksEnabled) {
|
|
98
|
+
if (this.context != TXEContext.TOP_LEVEL) {
|
|
99
|
+
throw new Error(`Call to txeSetUtilityTXEContext while in context ${TXEContext[this.context]}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
this.context = TXEContext.UTILITY;
|
|
104
|
+
return toForeignCallResult([]);
|
|
105
|
+
}
|
|
106
|
+
|
|
51
107
|
// Cheatcodes
|
|
52
108
|
|
|
53
|
-
async
|
|
54
|
-
blockNumberIsSome: ForeignCallSingle,
|
|
55
|
-
blockNumberValue: ForeignCallSingle,
|
|
56
|
-
timestampIsSome: ForeignCallSingle,
|
|
57
|
-
timestampValue: ForeignCallSingle,
|
|
58
|
-
) {
|
|
109
|
+
async txeGetPrivateContextInputs(blockNumberIsSome: ForeignCallSingle, blockNumberValue: ForeignCallSingle) {
|
|
59
110
|
const blockNumber = fromSingle(blockNumberIsSome).toBool() ? fromSingle(blockNumberValue).toNumber() : null;
|
|
60
|
-
const timestamp = fromSingle(timestampIsSome).toBool() ? fromSingle(timestampValue).toBigInt() : null;
|
|
61
111
|
|
|
62
|
-
const inputs = await
|
|
112
|
+
const inputs = await this.txe.txeGetPrivateContextInputs(blockNumber);
|
|
113
|
+
|
|
114
|
+
this.logger.info(
|
|
115
|
+
`Created private context for block ${inputs.historicalHeader.globalVariables.blockNumber} (requested ${blockNumber})`,
|
|
116
|
+
);
|
|
117
|
+
|
|
63
118
|
return toForeignCallResult(inputs.toFields().map(toSingle));
|
|
64
119
|
}
|
|
65
120
|
|
|
66
|
-
async
|
|
121
|
+
async txeAdvanceBlocksBy(blocks: ForeignCallSingle) {
|
|
67
122
|
const nBlocks = fromSingle(blocks).toNumber();
|
|
68
123
|
this.logger.debug(`time traveling ${nBlocks} blocks`);
|
|
69
124
|
|
|
70
125
|
for (let i = 0; i < nBlocks; i++) {
|
|
71
|
-
const blockNumber = await this.
|
|
72
|
-
await
|
|
73
|
-
|
|
126
|
+
const blockNumber = await this.txe.utilityGetBlockNumber();
|
|
127
|
+
await this.txe.commitState();
|
|
128
|
+
this.txe.setBlockNumber(blockNumber + 1);
|
|
74
129
|
}
|
|
75
130
|
return toForeignCallResult([]);
|
|
76
131
|
}
|
|
77
132
|
|
|
78
|
-
|
|
133
|
+
txeAdvanceTimestampBy(duration: ForeignCallSingle) {
|
|
79
134
|
const durationBigInt = fromSingle(duration).toBigInt();
|
|
80
135
|
this.logger.debug(`time traveling ${durationBigInt} seconds`);
|
|
81
|
-
|
|
136
|
+
this.txe.txeAdvanceTimestampBy(durationBigInt);
|
|
82
137
|
return toForeignCallResult([]);
|
|
83
138
|
}
|
|
84
139
|
|
|
85
|
-
|
|
140
|
+
txeSetContractAddress(address: ForeignCallSingle) {
|
|
86
141
|
const typedAddress = addressFromSingle(address);
|
|
87
|
-
|
|
142
|
+
this.txe.txeSetContractAddress(typedAddress);
|
|
88
143
|
return toForeignCallResult([]);
|
|
89
144
|
}
|
|
90
145
|
|
|
91
|
-
async
|
|
92
|
-
const keys = await (this.typedOracle as TXE).deriveKeys(fromSingle(secret));
|
|
93
|
-
return toForeignCallResult(keys.publicKeys.toFields().map(toSingle));
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
async deploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: ForeignCallSingle) {
|
|
146
|
+
async txeDeploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: ForeignCallSingle) {
|
|
97
147
|
// Emit deployment nullifier
|
|
98
|
-
await
|
|
99
|
-
AztecAddress.fromNumber(
|
|
148
|
+
await this.txe.noteCache.nullifierCreated(
|
|
149
|
+
AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
|
|
100
150
|
instance.address.toField(),
|
|
101
151
|
);
|
|
102
152
|
|
|
153
|
+
// Make sure the deployment nullifier gets included in a tx in a block
|
|
154
|
+
const blockNumber = await this.txe.utilityGetBlockNumber();
|
|
155
|
+
await this.txe.commitState();
|
|
156
|
+
this.txe.setBlockNumber(blockNumber + 1);
|
|
157
|
+
|
|
103
158
|
if (!fromSingle(secret).equals(Fr.ZERO)) {
|
|
104
|
-
await this.
|
|
159
|
+
await this.txeAddAccount(artifact, instance, secret);
|
|
105
160
|
} else {
|
|
106
|
-
await
|
|
107
|
-
await
|
|
161
|
+
await this.txe.addContractInstance(instance);
|
|
162
|
+
await this.txe.addContractArtifact(instance.currentContractClassId, artifact);
|
|
108
163
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
109
164
|
}
|
|
110
165
|
|
|
@@ -119,36 +174,14 @@ export class TXEService {
|
|
|
119
174
|
]);
|
|
120
175
|
}
|
|
121
176
|
|
|
122
|
-
async
|
|
123
|
-
|
|
124
|
-
startStorageSlot: ForeignCallSingle,
|
|
125
|
-
values: ForeignCallArray,
|
|
126
|
-
) {
|
|
127
|
-
const startStorageSlotFr = fromSingle(startStorageSlot);
|
|
128
|
-
const valuesFr = fromArray(values);
|
|
129
|
-
const contractAddressFr = addressFromSingle(contractAddress);
|
|
130
|
-
|
|
131
|
-
const publicDataWrites = await Promise.all(
|
|
132
|
-
valuesFr.map(async (value, i) => {
|
|
133
|
-
const storageSlot = startStorageSlotFr.add(new Fr(i));
|
|
134
|
-
this.logger.debug(`Oracle storage write: slot=${storageSlot.toString()} value=${value}`);
|
|
135
|
-
return new PublicDataWrite(await computePublicDataTreeLeafSlot(contractAddressFr, storageSlot), value);
|
|
136
|
-
}),
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
await (this.typedOracle as TXE).addPublicDataWrites(publicDataWrites);
|
|
140
|
-
|
|
141
|
-
return toForeignCallResult([toArray(publicDataWrites.map(write => write.value))]);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
async createAccount(secret: ForeignCallSingle) {
|
|
145
|
-
const keyStore = (this.typedOracle as TXE).getKeyStore();
|
|
177
|
+
async txeCreateAccount(secret: ForeignCallSingle) {
|
|
178
|
+
const keyStore = this.txe.getKeyStore();
|
|
146
179
|
const secretFr = fromSingle(secret);
|
|
147
180
|
// This is a footgun !
|
|
148
181
|
const completeAddress = await keyStore.addAccount(secretFr, secretFr);
|
|
149
|
-
const accountDataProvider =
|
|
182
|
+
const accountDataProvider = this.txe.getAccountDataProvider();
|
|
150
183
|
await accountDataProvider.setAccount(completeAddress.address, completeAddress);
|
|
151
|
-
const addressDataProvider =
|
|
184
|
+
const addressDataProvider = this.txe.getAddressDataProvider();
|
|
152
185
|
await addressDataProvider.addCompleteAddress(completeAddress);
|
|
153
186
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
154
187
|
return toForeignCallResult([
|
|
@@ -157,16 +190,16 @@ export class TXEService {
|
|
|
157
190
|
]);
|
|
158
191
|
}
|
|
159
192
|
|
|
160
|
-
async
|
|
193
|
+
async txeAddAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: ForeignCallSingle) {
|
|
161
194
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
162
|
-
await
|
|
163
|
-
await
|
|
195
|
+
await this.txe.addContractInstance(instance);
|
|
196
|
+
await this.txe.addContractArtifact(instance.currentContractClassId, artifact);
|
|
164
197
|
|
|
165
|
-
const keyStore =
|
|
198
|
+
const keyStore = this.txe.getKeyStore();
|
|
166
199
|
const completeAddress = await keyStore.addAccount(fromSingle(secret), await computePartialAddress(instance));
|
|
167
|
-
const accountDataProvider =
|
|
200
|
+
const accountDataProvider = this.txe.getAccountDataProvider();
|
|
168
201
|
await accountDataProvider.setAccount(completeAddress.address, completeAddress);
|
|
169
|
-
const addressDataProvider =
|
|
202
|
+
const addressDataProvider = this.txe.getAddressDataProvider();
|
|
170
203
|
await addressDataProvider.addCompleteAddress(completeAddress);
|
|
171
204
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
172
205
|
return toForeignCallResult([
|
|
@@ -175,142 +208,105 @@ export class TXEService {
|
|
|
175
208
|
]);
|
|
176
209
|
}
|
|
177
210
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
return toForeignCallResult([toSingle(new Fr(counter))]);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
async addAuthWitness(address: ForeignCallSingle, messageHash: ForeignCallSingle) {
|
|
184
|
-
await (this.typedOracle as TXE).addAuthWitness(addressFromSingle(address), fromSingle(messageHash));
|
|
185
|
-
return toForeignCallResult([]);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
async assertPublicCallFails(
|
|
189
|
-
address: ForeignCallSingle,
|
|
190
|
-
functionSelector: ForeignCallSingle,
|
|
191
|
-
_length: ForeignCallSingle,
|
|
192
|
-
args: ForeignCallArray,
|
|
193
|
-
) {
|
|
194
|
-
const parsedAddress = addressFromSingle(address);
|
|
195
|
-
const parsedSelector = fromSingle(functionSelector);
|
|
196
|
-
const extendedArgs = [parsedSelector, ...fromArray(args)];
|
|
197
|
-
const result = await (this.typedOracle as TXE).avmOpcodeCall(parsedAddress, extendedArgs, false);
|
|
198
|
-
if (result.revertCode.isOK()) {
|
|
199
|
-
throw new ExpectedFailureError('Public call did not revert');
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return toForeignCallResult([]);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
async assertPrivateCallFails(
|
|
206
|
-
targetContractAddress: ForeignCallSingle,
|
|
207
|
-
functionSelector: ForeignCallSingle,
|
|
208
|
-
argsHash: ForeignCallSingle,
|
|
209
|
-
sideEffectCounter: ForeignCallSingle,
|
|
210
|
-
isStaticCall: ForeignCallSingle,
|
|
211
|
-
) {
|
|
212
|
-
try {
|
|
213
|
-
await this.typedOracle.callPrivateFunction(
|
|
214
|
-
addressFromSingle(targetContractAddress),
|
|
215
|
-
FunctionSelector.fromField(fromSingle(functionSelector)),
|
|
216
|
-
fromSingle(argsHash),
|
|
217
|
-
fromSingle(sideEffectCounter).toNumber(),
|
|
218
|
-
fromSingle(isStaticCall).toBool(),
|
|
219
|
-
);
|
|
220
|
-
throw new ExpectedFailureError('Private call did not fail');
|
|
221
|
-
} catch (e) {
|
|
222
|
-
if (e instanceof ExpectedFailureError) {
|
|
223
|
-
throw e;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
211
|
+
async txeAddAuthWitness(address: ForeignCallSingle, messageHash: ForeignCallSingle) {
|
|
212
|
+
await this.txe.txeAddAuthWitness(addressFromSingle(address), fromSingle(messageHash));
|
|
226
213
|
return toForeignCallResult([]);
|
|
227
214
|
}
|
|
228
215
|
|
|
229
216
|
// PXE oracles
|
|
230
217
|
|
|
231
|
-
|
|
232
|
-
if (
|
|
218
|
+
utilityGetRandomField() {
|
|
219
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
233
220
|
throw new Error(
|
|
234
221
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
235
222
|
);
|
|
236
223
|
}
|
|
237
224
|
|
|
238
|
-
return toForeignCallResult([toSingle(this.
|
|
225
|
+
return toForeignCallResult([toSingle(this.txe.utilityGetRandomField())]);
|
|
239
226
|
}
|
|
240
227
|
|
|
241
|
-
async
|
|
242
|
-
if (
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
228
|
+
async utilityGetContractAddress() {
|
|
229
|
+
if (
|
|
230
|
+
this.contextChecksEnabled &&
|
|
231
|
+
this.context != TXEContext.TOP_LEVEL &&
|
|
232
|
+
this.context != TXEContext.UTILITY &&
|
|
233
|
+
this.context != TXEContext.PRIVATE
|
|
234
|
+
) {
|
|
235
|
+
throw new Error(`Attempted to call utilityGetContractAddress while in context ${TXEContext[this.context]}`);
|
|
246
236
|
}
|
|
247
237
|
|
|
248
|
-
const contractAddress = await this.
|
|
238
|
+
const contractAddress = await this.txe.utilityGetContractAddress();
|
|
249
239
|
return toForeignCallResult([toSingle(contractAddress.toField())]);
|
|
250
240
|
}
|
|
251
241
|
|
|
252
|
-
async
|
|
253
|
-
if (
|
|
254
|
-
throw new Error(
|
|
255
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
256
|
-
);
|
|
242
|
+
async utilityGetBlockNumber() {
|
|
243
|
+
if (this.contextChecksEnabled && this.context != TXEContext.TOP_LEVEL && this.context != TXEContext.UTILITY) {
|
|
244
|
+
throw new Error(`Attempted to call utilityGetBlockNumber while in context ${TXEContext[this.context]}`);
|
|
257
245
|
}
|
|
258
246
|
|
|
259
|
-
const blockNumber = await this.
|
|
247
|
+
const blockNumber = await this.txe.utilityGetBlockNumber();
|
|
260
248
|
return toForeignCallResult([toSingle(new Fr(blockNumber))]);
|
|
261
249
|
}
|
|
262
250
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
251
|
+
// seems to be used to mean the timestamp of the last mined block in txe (but that's not what is done here)
|
|
252
|
+
async utilityGetTimestamp() {
|
|
253
|
+
if (this.contextChecksEnabled && this.context != TXEContext.TOP_LEVEL && this.context != TXEContext.UTILITY) {
|
|
254
|
+
throw new Error(`Attempted to call utilityGetTimestamp while in context ${TXEContext[this.context]}`);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const timestamp = await this.txe.utilityGetTimestamp();
|
|
258
|
+
return toForeignCallResult([toSingle(new Fr(timestamp))]);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
async txeGetLastBlockTimestamp() {
|
|
262
|
+
if (this.contextChecksEnabled && this.context != TXEContext.TOP_LEVEL) {
|
|
263
|
+
throw new Error(`Attempted to call txeGetLastBlockTimestamp while in context ${TXEContext[this.context]}`);
|
|
268
264
|
}
|
|
269
265
|
|
|
270
|
-
const timestamp = await this.
|
|
266
|
+
const timestamp = await this.txe.txeGetLastBlockTimestamp();
|
|
271
267
|
return toForeignCallResult([toSingle(new Fr(timestamp))]);
|
|
272
268
|
}
|
|
273
269
|
|
|
274
270
|
// Since the argument is a slice, noir automatically adds a length field to oracle call.
|
|
275
|
-
|
|
276
|
-
if (
|
|
271
|
+
privateStoreInExecutionCache(_length: ForeignCallSingle, values: ForeignCallArray, hash: ForeignCallSingle) {
|
|
272
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
277
273
|
throw new Error(
|
|
278
274
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
279
275
|
);
|
|
280
276
|
}
|
|
281
277
|
|
|
282
|
-
this.
|
|
278
|
+
this.txe.privateStoreInExecutionCache(fromArray(values), fromSingle(hash));
|
|
283
279
|
return toForeignCallResult([]);
|
|
284
280
|
}
|
|
285
281
|
|
|
286
|
-
async
|
|
287
|
-
if (
|
|
282
|
+
async privateLoadFromExecutionCache(hash: ForeignCallSingle) {
|
|
283
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
288
284
|
throw new Error(
|
|
289
285
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
290
286
|
);
|
|
291
287
|
}
|
|
292
288
|
|
|
293
|
-
const returns = await this.
|
|
289
|
+
const returns = await this.txe.privateLoadFromExecutionCache(fromSingle(hash));
|
|
294
290
|
return toForeignCallResult([toArray(returns)]);
|
|
295
291
|
}
|
|
296
292
|
|
|
297
293
|
// Since the argument is a slice, noir automatically adds a length field to oracle call.
|
|
298
|
-
|
|
294
|
+
utilityDebugLog(message: ForeignCallArray, _length: ForeignCallSingle, fields: ForeignCallArray) {
|
|
299
295
|
const messageStr = fromArray(message)
|
|
300
296
|
.map(field => String.fromCharCode(field.toNumber()))
|
|
301
297
|
.join('');
|
|
302
298
|
const fieldsFr = fromArray(fields);
|
|
303
|
-
this.
|
|
299
|
+
this.txe.utilityDebugLog(messageStr, fieldsFr);
|
|
304
300
|
return toForeignCallResult([]);
|
|
305
301
|
}
|
|
306
302
|
|
|
307
|
-
async
|
|
303
|
+
async utilityStorageRead(
|
|
308
304
|
contractAddress: ForeignCallSingle,
|
|
309
305
|
startStorageSlot: ForeignCallSingle,
|
|
310
306
|
blockNumber: ForeignCallSingle,
|
|
311
307
|
numberOfElements: ForeignCallSingle,
|
|
312
308
|
) {
|
|
313
|
-
const values = await this.
|
|
309
|
+
const values = await this.txe.utilityStorageRead(
|
|
314
310
|
addressFromSingle(contractAddress),
|
|
315
311
|
fromSingle(startStorageSlot),
|
|
316
312
|
fromSingle(blockNumber).toNumber(),
|
|
@@ -319,13 +315,8 @@ export class TXEService {
|
|
|
319
315
|
return toForeignCallResult([toArray(values)]);
|
|
320
316
|
}
|
|
321
317
|
|
|
322
|
-
async
|
|
323
|
-
|
|
324
|
-
return toForeignCallResult([toArray(newValues)]);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
async getPublicDataWitness(blockNumber: ForeignCallSingle, leafSlot: ForeignCallSingle) {
|
|
328
|
-
if (!this.oraclesEnabled) {
|
|
318
|
+
async utilityGetPublicDataWitness(blockNumber: ForeignCallSingle, leafSlot: ForeignCallSingle) {
|
|
319
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
329
320
|
throw new Error(
|
|
330
321
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
331
322
|
);
|
|
@@ -334,14 +325,14 @@ export class TXEService {
|
|
|
334
325
|
const parsedBlockNumber = fromSingle(blockNumber).toNumber();
|
|
335
326
|
const parsedLeafSlot = fromSingle(leafSlot);
|
|
336
327
|
|
|
337
|
-
const witness = await this.
|
|
328
|
+
const witness = await this.txe.utilityGetPublicDataWitness(parsedBlockNumber, parsedLeafSlot);
|
|
338
329
|
if (!witness) {
|
|
339
330
|
throw new Error(`Public data witness not found for slot ${parsedLeafSlot} at block ${parsedBlockNumber}.`);
|
|
340
331
|
}
|
|
341
332
|
return toForeignCallResult(witness.toNoirRepresentation());
|
|
342
333
|
}
|
|
343
334
|
|
|
344
|
-
async
|
|
335
|
+
async utilityGetNotes(
|
|
345
336
|
storageSlot: ForeignCallSingle,
|
|
346
337
|
numSelects: ForeignCallSingle,
|
|
347
338
|
selectByIndexes: ForeignCallArray,
|
|
@@ -359,13 +350,13 @@ export class TXEService {
|
|
|
359
350
|
maxNotes: ForeignCallSingle,
|
|
360
351
|
packedRetrievedNoteLength: ForeignCallSingle,
|
|
361
352
|
) {
|
|
362
|
-
if (
|
|
353
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
363
354
|
throw new Error(
|
|
364
355
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
365
356
|
);
|
|
366
357
|
}
|
|
367
358
|
|
|
368
|
-
const noteDatas = await this.
|
|
359
|
+
const noteDatas = await this.txe.utilityGetNotes(
|
|
369
360
|
fromSingle(storageSlot),
|
|
370
361
|
fromSingle(numSelects).toNumber(),
|
|
371
362
|
fromArray(selectByIndexes).map(fr => fr.toNumber()),
|
|
@@ -389,17 +380,7 @@ export class TXEService {
|
|
|
389
380
|
}
|
|
390
381
|
}
|
|
391
382
|
|
|
392
|
-
|
|
393
|
-
// array is structured as [contract_address, note_nonce, nonzero_note_hash_counter, ...packed_note].
|
|
394
|
-
|
|
395
|
-
const returnDataAsArrayOfArrays = noteDatas.map(({ contractAddress, noteNonce, index, note }) => {
|
|
396
|
-
// If index is undefined, the note is transient which implies that the nonzero_note_hash_counter has to be true
|
|
397
|
-
const noteIsTransient = index === undefined;
|
|
398
|
-
const nonzeroNoteHashCounter = noteIsTransient ? true : false;
|
|
399
|
-
// If you change the array on the next line you have to change the `unpack_retrieved_note` function in
|
|
400
|
-
// `aztec/src/note/retrieved_note.nr`
|
|
401
|
-
return [contractAddress, noteNonce, nonzeroNoteHashCounter, ...note.items];
|
|
402
|
-
});
|
|
383
|
+
const returnDataAsArrayOfArrays = noteDatas.map(packAsRetrievedNote);
|
|
403
384
|
|
|
404
385
|
// Now we convert each sub-array to an array of ForeignCallSingles
|
|
405
386
|
const returnDataAsArrayOfForeignCallSingleArrays = returnDataAsArrayOfArrays.map(subArray =>
|
|
@@ -416,20 +397,20 @@ export class TXEService {
|
|
|
416
397
|
);
|
|
417
398
|
}
|
|
418
399
|
|
|
419
|
-
|
|
400
|
+
privateNotifyCreatedNote(
|
|
420
401
|
storageSlot: ForeignCallSingle,
|
|
421
402
|
noteTypeId: ForeignCallSingle,
|
|
422
403
|
note: ForeignCallArray,
|
|
423
404
|
noteHash: ForeignCallSingle,
|
|
424
405
|
counter: ForeignCallSingle,
|
|
425
406
|
) {
|
|
426
|
-
if (
|
|
407
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
427
408
|
throw new Error(
|
|
428
409
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
429
410
|
);
|
|
430
411
|
}
|
|
431
412
|
|
|
432
|
-
this.
|
|
413
|
+
this.txe.privateNotifyCreatedNote(
|
|
433
414
|
fromSingle(storageSlot),
|
|
434
415
|
NoteSelector.fromField(fromSingle(noteTypeId)),
|
|
435
416
|
fromArray(note),
|
|
@@ -439,18 +420,18 @@ export class TXEService {
|
|
|
439
420
|
return toForeignCallResult([]);
|
|
440
421
|
}
|
|
441
422
|
|
|
442
|
-
async
|
|
423
|
+
async privateNotifyNullifiedNote(
|
|
443
424
|
innerNullifier: ForeignCallSingle,
|
|
444
425
|
noteHash: ForeignCallSingle,
|
|
445
426
|
counter: ForeignCallSingle,
|
|
446
427
|
) {
|
|
447
|
-
if (
|
|
428
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
448
429
|
throw new Error(
|
|
449
430
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
450
431
|
);
|
|
451
432
|
}
|
|
452
433
|
|
|
453
|
-
await this.
|
|
434
|
+
await this.txe.privateNotifyNullifiedNote(
|
|
454
435
|
fromSingle(innerNullifier),
|
|
455
436
|
fromSingle(noteHash),
|
|
456
437
|
fromSingle(counter).toNumber(),
|
|
@@ -458,36 +439,36 @@ export class TXEService {
|
|
|
458
439
|
return toForeignCallResult([]);
|
|
459
440
|
}
|
|
460
441
|
|
|
461
|
-
async
|
|
462
|
-
if (
|
|
442
|
+
async privateNotifyCreatedNullifier(innerNullifier: ForeignCallSingle) {
|
|
443
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
463
444
|
throw new Error(
|
|
464
445
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
465
446
|
);
|
|
466
447
|
}
|
|
467
448
|
|
|
468
|
-
await this.
|
|
449
|
+
await this.txe.privateNotifyCreatedNullifier(fromSingle(innerNullifier));
|
|
469
450
|
return toForeignCallResult([]);
|
|
470
451
|
}
|
|
471
452
|
|
|
472
|
-
async
|
|
473
|
-
if (
|
|
453
|
+
async utilityCheckNullifierExists(innerNullifier: ForeignCallSingle) {
|
|
454
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
474
455
|
throw new Error(
|
|
475
456
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
476
457
|
);
|
|
477
458
|
}
|
|
478
459
|
|
|
479
|
-
const exists = await this.
|
|
460
|
+
const exists = await this.txe.utilityCheckNullifierExists(fromSingle(innerNullifier));
|
|
480
461
|
return toForeignCallResult([toSingle(new Fr(exists))]);
|
|
481
462
|
}
|
|
482
463
|
|
|
483
|
-
async
|
|
484
|
-
if (
|
|
464
|
+
async utilityGetContractInstance(address: ForeignCallSingle) {
|
|
465
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
485
466
|
throw new Error(
|
|
486
467
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
487
468
|
);
|
|
488
469
|
}
|
|
489
470
|
|
|
490
|
-
const instance = await this.
|
|
471
|
+
const instance = await this.txe.utilityGetContractInstance(addressFromSingle(address));
|
|
491
472
|
return toForeignCallResult(
|
|
492
473
|
[
|
|
493
474
|
instance.salt,
|
|
@@ -499,173 +480,133 @@ export class TXEService {
|
|
|
499
480
|
);
|
|
500
481
|
}
|
|
501
482
|
|
|
502
|
-
async
|
|
503
|
-
if (
|
|
483
|
+
async utilityGetPublicKeysAndPartialAddress(address: ForeignCallSingle) {
|
|
484
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
504
485
|
throw new Error(
|
|
505
486
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
506
487
|
);
|
|
507
488
|
}
|
|
508
489
|
|
|
509
490
|
const parsedAddress = addressFromSingle(address);
|
|
510
|
-
const { publicKeys, partialAddress } = await this.
|
|
491
|
+
const { publicKeys, partialAddress } = await this.txe.utilityGetCompleteAddress(parsedAddress);
|
|
511
492
|
return toForeignCallResult([toArray([...publicKeys.toFields(), partialAddress])]);
|
|
512
493
|
}
|
|
513
494
|
|
|
514
|
-
async
|
|
515
|
-
if (
|
|
495
|
+
async utilityGetKeyValidationRequest(pkMHash: ForeignCallSingle) {
|
|
496
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
516
497
|
throw new Error(
|
|
517
498
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
518
499
|
);
|
|
519
500
|
}
|
|
520
501
|
|
|
521
|
-
const keyValidationRequest = await this.
|
|
502
|
+
const keyValidationRequest = await this.txe.utilityGetKeyValidationRequest(fromSingle(pkMHash));
|
|
522
503
|
return toForeignCallResult(keyValidationRequest.toFields().map(toSingle));
|
|
523
504
|
}
|
|
524
505
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
506
|
+
privateCallPrivateFunction(
|
|
507
|
+
_targetContractAddress: ForeignCallSingle,
|
|
508
|
+
_functionSelector: ForeignCallSingle,
|
|
509
|
+
_argsHash: ForeignCallSingle,
|
|
510
|
+
_sideEffectCounter: ForeignCallSingle,
|
|
511
|
+
_isStaticCall: ForeignCallSingle,
|
|
531
512
|
) {
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
535
|
-
);
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
const result = await this.typedOracle.callPrivateFunction(
|
|
539
|
-
addressFromSingle(targetContractAddress),
|
|
540
|
-
FunctionSelector.fromField(fromSingle(functionSelector)),
|
|
541
|
-
fromSingle(argsHash),
|
|
542
|
-
fromSingle(sideEffectCounter).toNumber(),
|
|
543
|
-
fromSingle(isStaticCall).toBool(),
|
|
513
|
+
throw new Error(
|
|
514
|
+
'Contract calls are forbidden inside a `TestEnvironment::private_context`, use `private_call` instead',
|
|
544
515
|
);
|
|
545
|
-
return toForeignCallResult([toArray([result.endSideEffectCounter, result.returnsHash])]);
|
|
546
516
|
}
|
|
547
517
|
|
|
548
|
-
async
|
|
549
|
-
if (
|
|
518
|
+
async utilityGetNullifierMembershipWitness(blockNumber: ForeignCallSingle, nullifier: ForeignCallSingle) {
|
|
519
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
550
520
|
throw new Error(
|
|
551
521
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
552
522
|
);
|
|
553
523
|
}
|
|
554
524
|
|
|
555
525
|
const parsedBlockNumber = fromSingle(blockNumber).toNumber();
|
|
556
|
-
const witness = await this.
|
|
526
|
+
const witness = await this.txe.utilityGetNullifierMembershipWitness(parsedBlockNumber, fromSingle(nullifier));
|
|
557
527
|
if (!witness) {
|
|
558
528
|
throw new Error(`Nullifier membership witness not found at block ${parsedBlockNumber}.`);
|
|
559
529
|
}
|
|
560
530
|
return toForeignCallResult(witness.toNoirRepresentation());
|
|
561
531
|
}
|
|
562
532
|
|
|
563
|
-
async
|
|
564
|
-
if (
|
|
533
|
+
async utilityGetAuthWitness(messageHash: ForeignCallSingle) {
|
|
534
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
565
535
|
throw new Error(
|
|
566
536
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
567
537
|
);
|
|
568
538
|
}
|
|
569
539
|
|
|
570
540
|
const parsedMessageHash = fromSingle(messageHash);
|
|
571
|
-
const authWitness = await this.
|
|
541
|
+
const authWitness = await this.txe.utilityGetAuthWitness(parsedMessageHash);
|
|
572
542
|
if (!authWitness) {
|
|
573
543
|
throw new Error(`Auth witness not found for message hash ${parsedMessageHash}.`);
|
|
574
544
|
}
|
|
575
545
|
return toForeignCallResult([toArray(authWitness)]);
|
|
576
546
|
}
|
|
577
547
|
|
|
578
|
-
public
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
548
|
+
public privateNotifyEnqueuedPublicFunctionCall(
|
|
549
|
+
_targetContractAddress: ForeignCallSingle,
|
|
550
|
+
_calldataHash: ForeignCallSingle,
|
|
551
|
+
_sideEffectCounter: ForeignCallSingle,
|
|
552
|
+
_isStaticCall: ForeignCallSingle,
|
|
583
553
|
) {
|
|
584
|
-
|
|
585
|
-
throw new Error(
|
|
586
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
587
|
-
);
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
await this.typedOracle.notifyEnqueuedPublicFunctionCall(
|
|
591
|
-
addressFromSingle(targetContractAddress),
|
|
592
|
-
fromSingle(calldataHash),
|
|
593
|
-
fromSingle(sideEffectCounter).toNumber(),
|
|
594
|
-
fromSingle(isStaticCall).toBool(),
|
|
595
|
-
);
|
|
596
|
-
return toForeignCallResult([]);
|
|
554
|
+
throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
|
|
597
555
|
}
|
|
598
556
|
|
|
599
|
-
public
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
557
|
+
public privateNotifySetPublicTeardownFunctionCall(
|
|
558
|
+
_targetContractAddress: ForeignCallSingle,
|
|
559
|
+
_calldataHash: ForeignCallSingle,
|
|
560
|
+
_sideEffectCounter: ForeignCallSingle,
|
|
561
|
+
_isStaticCall: ForeignCallSingle,
|
|
604
562
|
) {
|
|
605
|
-
|
|
606
|
-
throw new Error(
|
|
607
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
608
|
-
);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
await this.typedOracle.notifySetPublicTeardownFunctionCall(
|
|
612
|
-
addressFromSingle(targetContractAddress),
|
|
613
|
-
fromSingle(calldataHash),
|
|
614
|
-
fromSingle(sideEffectCounter).toNumber(),
|
|
615
|
-
fromSingle(isStaticCall).toBool(),
|
|
616
|
-
);
|
|
617
|
-
return toForeignCallResult([]);
|
|
563
|
+
throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
|
|
618
564
|
}
|
|
619
565
|
|
|
620
|
-
public
|
|
621
|
-
|
|
622
|
-
throw new Error(
|
|
623
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
624
|
-
);
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
await this.typedOracle.notifySetMinRevertibleSideEffectCounter(
|
|
628
|
-
fromSingle(minRevertibleSideEffectCounter).toNumber(),
|
|
629
|
-
);
|
|
630
|
-
return toForeignCallResult([]);
|
|
566
|
+
public privateNotifySetMinRevertibleSideEffectCounter(_minRevertibleSideEffectCounter: ForeignCallSingle) {
|
|
567
|
+
throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
|
|
631
568
|
}
|
|
632
569
|
|
|
633
|
-
async
|
|
634
|
-
if (
|
|
570
|
+
async utilityGetChainId() {
|
|
571
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
635
572
|
throw new Error(
|
|
636
573
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
637
574
|
);
|
|
638
575
|
}
|
|
639
576
|
|
|
640
|
-
return toForeignCallResult([toSingle(await this.
|
|
577
|
+
return toForeignCallResult([toSingle(await this.txe.utilityGetChainId())]);
|
|
641
578
|
}
|
|
642
579
|
|
|
643
|
-
async
|
|
644
|
-
if (
|
|
580
|
+
async utilityGetVersion() {
|
|
581
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
645
582
|
throw new Error(
|
|
646
583
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
647
584
|
);
|
|
648
585
|
}
|
|
649
586
|
|
|
650
|
-
return toForeignCallResult([toSingle(await this.
|
|
587
|
+
return toForeignCallResult([toSingle(await this.txe.utilityGetVersion())]);
|
|
651
588
|
}
|
|
652
589
|
|
|
653
|
-
async
|
|
654
|
-
if (
|
|
590
|
+
async utilityGetBlockHeader(blockNumber: ForeignCallSingle) {
|
|
591
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
655
592
|
throw new Error(
|
|
656
593
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
657
594
|
);
|
|
658
595
|
}
|
|
659
596
|
|
|
660
|
-
const header = await this.
|
|
597
|
+
const header = await this.txe.utilityGetBlockHeader(fromSingle(blockNumber).toNumber());
|
|
661
598
|
if (!header) {
|
|
662
599
|
throw new Error(`Block header not found for block ${blockNumber}.`);
|
|
663
600
|
}
|
|
664
601
|
return toForeignCallResult(header.toFields().map(toSingle));
|
|
665
602
|
}
|
|
666
603
|
|
|
667
|
-
async
|
|
668
|
-
|
|
604
|
+
async utilityGetMembershipWitness(
|
|
605
|
+
blockNumber: ForeignCallSingle,
|
|
606
|
+
treeId: ForeignCallSingle,
|
|
607
|
+
leafValue: ForeignCallSingle,
|
|
608
|
+
) {
|
|
609
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
669
610
|
throw new Error(
|
|
670
611
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
671
612
|
);
|
|
@@ -674,7 +615,7 @@ export class TXEService {
|
|
|
674
615
|
const parsedBlockNumber = fromSingle(blockNumber).toNumber();
|
|
675
616
|
const parsedTreeId = fromSingle(treeId).toNumber();
|
|
676
617
|
const parsedLeafValue = fromSingle(leafValue);
|
|
677
|
-
const witness = await this.
|
|
618
|
+
const witness = await this.txe.utilityGetMembershipWitness(parsedBlockNumber, parsedTreeId, parsedLeafValue);
|
|
678
619
|
if (!witness) {
|
|
679
620
|
throw new Error(
|
|
680
621
|
`Membership witness in tree ${MerkleTreeId[parsedTreeId]} not found for value ${parsedLeafValue} at block ${parsedBlockNumber}.`,
|
|
@@ -683,8 +624,8 @@ export class TXEService {
|
|
|
683
624
|
return toForeignCallResult([toSingle(witness[0]), toArray(witness.slice(1))]);
|
|
684
625
|
}
|
|
685
626
|
|
|
686
|
-
async
|
|
687
|
-
if (
|
|
627
|
+
async utilityGetLowNullifierMembershipWitness(blockNumber: ForeignCallSingle, nullifier: ForeignCallSingle) {
|
|
628
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
688
629
|
throw new Error(
|
|
689
630
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
690
631
|
);
|
|
@@ -692,50 +633,50 @@ export class TXEService {
|
|
|
692
633
|
|
|
693
634
|
const parsedBlockNumber = fromSingle(blockNumber).toNumber();
|
|
694
635
|
|
|
695
|
-
const witness = await this.
|
|
636
|
+
const witness = await this.txe.utilityGetLowNullifierMembershipWitness(parsedBlockNumber, fromSingle(nullifier));
|
|
696
637
|
if (!witness) {
|
|
697
638
|
throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${parsedBlockNumber}.`);
|
|
698
639
|
}
|
|
699
640
|
return toForeignCallResult(witness.toNoirRepresentation());
|
|
700
641
|
}
|
|
701
642
|
|
|
702
|
-
async
|
|
703
|
-
if (
|
|
643
|
+
async utilityGetIndexedTaggingSecretAsSender(sender: ForeignCallSingle, recipient: ForeignCallSingle) {
|
|
644
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
704
645
|
throw new Error(
|
|
705
646
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
706
647
|
);
|
|
707
648
|
}
|
|
708
649
|
|
|
709
|
-
const secret = await this.
|
|
650
|
+
const secret = await this.txe.utilityGetIndexedTaggingSecretAsSender(
|
|
710
651
|
AztecAddress.fromField(fromSingle(sender)),
|
|
711
652
|
AztecAddress.fromField(fromSingle(recipient)),
|
|
712
653
|
);
|
|
713
654
|
return toForeignCallResult(secret.toFields().map(toSingle));
|
|
714
655
|
}
|
|
715
656
|
|
|
716
|
-
async
|
|
717
|
-
if (
|
|
657
|
+
async utilityFetchTaggedLogs(pendingTaggedLogArrayBaseSlot: ForeignCallSingle) {
|
|
658
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
718
659
|
throw new Error(
|
|
719
660
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
720
661
|
);
|
|
721
662
|
}
|
|
722
663
|
|
|
723
|
-
await this.
|
|
664
|
+
await this.txe.utilityFetchTaggedLogs(fromSingle(pendingTaggedLogArrayBaseSlot));
|
|
724
665
|
return toForeignCallResult([]);
|
|
725
666
|
}
|
|
726
667
|
|
|
727
|
-
public async
|
|
668
|
+
public async utilityValidateEnqueuedNotesAndEvents(
|
|
728
669
|
contractAddress: ForeignCallSingle,
|
|
729
670
|
noteValidationRequestsArrayBaseSlot: ForeignCallSingle,
|
|
730
671
|
eventValidationRequestsArrayBaseSlot: ForeignCallSingle,
|
|
731
672
|
) {
|
|
732
|
-
if (
|
|
673
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
733
674
|
throw new Error(
|
|
734
675
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
735
676
|
);
|
|
736
677
|
}
|
|
737
678
|
|
|
738
|
-
await this.
|
|
679
|
+
await this.txe.utilityValidateEnqueuedNotesAndEvents(
|
|
739
680
|
AztecAddress.fromField(fromSingle(contractAddress)),
|
|
740
681
|
fromSingle(noteValidationRequestsArrayBaseSlot),
|
|
741
682
|
fromSingle(eventValidationRequestsArrayBaseSlot),
|
|
@@ -744,18 +685,18 @@ export class TXEService {
|
|
|
744
685
|
return toForeignCallResult([]);
|
|
745
686
|
}
|
|
746
687
|
|
|
747
|
-
public async
|
|
688
|
+
public async utilityBulkRetrieveLogs(
|
|
748
689
|
contractAddress: ForeignCallSingle,
|
|
749
690
|
logRetrievalRequestsArrayBaseSlot: ForeignCallSingle,
|
|
750
691
|
logRetrievalResponsesArrayBaseSlot: ForeignCallSingle,
|
|
751
692
|
) {
|
|
752
|
-
if (
|
|
693
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
753
694
|
throw new Error(
|
|
754
695
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
755
696
|
);
|
|
756
697
|
}
|
|
757
698
|
|
|
758
|
-
await this.
|
|
699
|
+
await this.txe.utilityBulkRetrieveLogs(
|
|
759
700
|
AztecAddress.fromField(fromSingle(contractAddress)),
|
|
760
701
|
fromSingle(logRetrievalRequestsArrayBaseSlot),
|
|
761
702
|
fromSingle(logRetrievalResponsesArrayBaseSlot),
|
|
@@ -764,14 +705,14 @@ export class TXEService {
|
|
|
764
705
|
return toForeignCallResult([]);
|
|
765
706
|
}
|
|
766
707
|
|
|
767
|
-
async
|
|
768
|
-
if (
|
|
708
|
+
async utilityStoreCapsule(contractAddress: ForeignCallSingle, slot: ForeignCallSingle, capsule: ForeignCallArray) {
|
|
709
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
769
710
|
throw new Error(
|
|
770
711
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
771
712
|
);
|
|
772
713
|
}
|
|
773
714
|
|
|
774
|
-
await this.
|
|
715
|
+
await this.txe.utilityStoreCapsule(
|
|
775
716
|
AztecAddress.fromField(fromSingle(contractAddress)),
|
|
776
717
|
fromSingle(slot),
|
|
777
718
|
fromArray(capsule),
|
|
@@ -779,14 +720,14 @@ export class TXEService {
|
|
|
779
720
|
return toForeignCallResult([]);
|
|
780
721
|
}
|
|
781
722
|
|
|
782
|
-
async
|
|
783
|
-
if (
|
|
723
|
+
async utilityLoadCapsule(contractAddress: ForeignCallSingle, slot: ForeignCallSingle, tSize: ForeignCallSingle) {
|
|
724
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
784
725
|
throw new Error(
|
|
785
726
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
786
727
|
);
|
|
787
728
|
}
|
|
788
729
|
|
|
789
|
-
const values = await this.
|
|
730
|
+
const values = await this.txe.utilityLoadCapsule(
|
|
790
731
|
AztecAddress.fromField(fromSingle(contractAddress)),
|
|
791
732
|
fromSingle(slot),
|
|
792
733
|
);
|
|
@@ -801,30 +742,30 @@ export class TXEService {
|
|
|
801
742
|
}
|
|
802
743
|
}
|
|
803
744
|
|
|
804
|
-
async
|
|
805
|
-
if (
|
|
745
|
+
async utilityDeleteCapsule(contractAddress: ForeignCallSingle, slot: ForeignCallSingle) {
|
|
746
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
806
747
|
throw new Error(
|
|
807
748
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
808
749
|
);
|
|
809
750
|
}
|
|
810
751
|
|
|
811
|
-
await this.
|
|
752
|
+
await this.txe.utilityDeleteCapsule(AztecAddress.fromField(fromSingle(contractAddress)), fromSingle(slot));
|
|
812
753
|
return toForeignCallResult([]);
|
|
813
754
|
}
|
|
814
755
|
|
|
815
|
-
async
|
|
756
|
+
async utilityCopyCapsule(
|
|
816
757
|
contractAddress: ForeignCallSingle,
|
|
817
758
|
srcSlot: ForeignCallSingle,
|
|
818
759
|
dstSlot: ForeignCallSingle,
|
|
819
760
|
numEntries: ForeignCallSingle,
|
|
820
761
|
) {
|
|
821
|
-
if (
|
|
762
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
822
763
|
throw new Error(
|
|
823
764
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
824
765
|
);
|
|
825
766
|
}
|
|
826
767
|
|
|
827
|
-
await this.
|
|
768
|
+
await this.txe.utilityCopyCapsule(
|
|
828
769
|
AztecAddress.fromField(fromSingle(contractAddress)),
|
|
829
770
|
fromSingle(srcSlot),
|
|
830
771
|
fromSingle(dstSlot),
|
|
@@ -838,13 +779,13 @@ export class TXEService {
|
|
|
838
779
|
// 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
|
|
839
780
|
// to implement this function here. Isn't there a way to programmatically identify that this is missing, given the
|
|
840
781
|
// existence of a txe_oracle method?
|
|
841
|
-
async
|
|
782
|
+
async utilityAes128Decrypt(
|
|
842
783
|
ciphertextBVecStorage: ForeignCallArray,
|
|
843
784
|
ciphertextLength: ForeignCallSingle,
|
|
844
785
|
iv: ForeignCallArray,
|
|
845
786
|
symKey: ForeignCallArray,
|
|
846
787
|
) {
|
|
847
|
-
if (
|
|
788
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
848
789
|
throw new Error(
|
|
849
790
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
850
791
|
);
|
|
@@ -854,24 +795,24 @@ export class TXEService {
|
|
|
854
795
|
const ivBuffer = fromUintArray(iv, 8);
|
|
855
796
|
const symKeyBuffer = fromUintArray(symKey, 8);
|
|
856
797
|
|
|
857
|
-
const plaintextBuffer = await this.
|
|
798
|
+
const plaintextBuffer = await this.txe.utilityAes128Decrypt(ciphertext, ivBuffer, symKeyBuffer);
|
|
858
799
|
|
|
859
800
|
return toForeignCallResult(arrayToBoundedVec(bufferToU8Array(plaintextBuffer), ciphertextBVecStorage.length));
|
|
860
801
|
}
|
|
861
802
|
|
|
862
|
-
async
|
|
803
|
+
async utilityGetSharedSecret(
|
|
863
804
|
address: ForeignCallSingle,
|
|
864
805
|
ephPKField0: ForeignCallSingle,
|
|
865
806
|
ephPKField1: ForeignCallSingle,
|
|
866
807
|
ephPKField2: ForeignCallSingle,
|
|
867
808
|
) {
|
|
868
|
-
if (
|
|
809
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
869
810
|
throw new Error(
|
|
870
811
|
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
871
812
|
);
|
|
872
813
|
}
|
|
873
814
|
|
|
874
|
-
const secret = await this.
|
|
815
|
+
const secret = await this.txe.utilityGetSharedSecret(
|
|
875
816
|
AztecAddress.fromField(fromSingle(address)),
|
|
876
817
|
Point.fromFields([fromSingle(ephPKField0), fromSingle(ephPKField1), fromSingle(ephPKField2)]),
|
|
877
818
|
);
|
|
@@ -879,24 +820,15 @@ export class TXEService {
|
|
|
879
820
|
}
|
|
880
821
|
|
|
881
822
|
emitOffchainEffect(_data: ForeignCallArray) {
|
|
882
|
-
|
|
883
|
-
throw new Error(
|
|
884
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
885
|
-
);
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
// Offchain effects are currently discarded in the TXE tests.
|
|
889
|
-
// TODO: Expose this to the tests.
|
|
890
|
-
|
|
891
|
-
return toForeignCallResult([]);
|
|
823
|
+
throw new Error('Offchain effects are not yet supported in the TestEnvironment');
|
|
892
824
|
}
|
|
893
825
|
|
|
894
826
|
// AVM opcodes
|
|
895
827
|
|
|
896
828
|
avmOpcodeEmitUnencryptedLog(_message: ForeignCallArray) {
|
|
897
|
-
if (
|
|
829
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
898
830
|
throw new Error(
|
|
899
|
-
|
|
831
|
+
`Attempted to call the avmOpcodeEmitUnencryptedLog oracle while in context ${TXEContext[this.context]}`,
|
|
900
832
|
);
|
|
901
833
|
}
|
|
902
834
|
|
|
@@ -905,35 +837,33 @@ export class TXEService {
|
|
|
905
837
|
}
|
|
906
838
|
|
|
907
839
|
async avmOpcodeStorageRead(slot: ForeignCallSingle) {
|
|
908
|
-
if (
|
|
909
|
-
throw new Error(
|
|
910
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
911
|
-
);
|
|
840
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
841
|
+
throw new Error(`Attempted to call the avmOpcodeStorageRead oracle while in context ${TXEContext[this.context]}`);
|
|
912
842
|
}
|
|
913
843
|
|
|
914
|
-
const value = (await
|
|
844
|
+
const value = (await this.txe.avmOpcodeStorageRead(fromSingle(slot))).value;
|
|
915
845
|
return toForeignCallResult([toSingle(new Fr(value))]);
|
|
916
846
|
}
|
|
917
847
|
|
|
918
848
|
async avmOpcodeStorageWrite(slot: ForeignCallSingle, value: ForeignCallSingle) {
|
|
919
|
-
if (
|
|
849
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
920
850
|
throw new Error(
|
|
921
|
-
|
|
851
|
+
`Attempted to call the avmOpcodeStorageWrite oracle while in context ${TXEContext[this.context]}`,
|
|
922
852
|
);
|
|
923
853
|
}
|
|
924
854
|
|
|
925
|
-
await this.
|
|
855
|
+
await this.txe.storageWrite(fromSingle(slot), [fromSingle(value)]);
|
|
926
856
|
return toForeignCallResult([]);
|
|
927
857
|
}
|
|
928
858
|
|
|
929
859
|
async avmOpcodeGetContractInstanceDeployer(address: ForeignCallSingle) {
|
|
930
|
-
if (
|
|
860
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
931
861
|
throw new Error(
|
|
932
|
-
|
|
862
|
+
`Attempted to call the avmOpcodeGetContractInstanceDeployer oracle while in context ${TXEContext[this.context]}`,
|
|
933
863
|
);
|
|
934
864
|
}
|
|
935
865
|
|
|
936
|
-
const instance = await this.
|
|
866
|
+
const instance = await this.txe.utilityGetContractInstance(addressFromSingle(address));
|
|
937
867
|
return toForeignCallResult([
|
|
938
868
|
toSingle(instance.deployer),
|
|
939
869
|
// AVM requires an extra boolean indicating the instance was found
|
|
@@ -942,13 +872,13 @@ export class TXEService {
|
|
|
942
872
|
}
|
|
943
873
|
|
|
944
874
|
async avmOpcodeGetContractInstanceClassId(address: ForeignCallSingle) {
|
|
945
|
-
if (
|
|
875
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
946
876
|
throw new Error(
|
|
947
|
-
|
|
877
|
+
`Attempted to call the avmOpcodeGetContractInstanceClassId oracle while in context ${TXEContext[this.context]}`,
|
|
948
878
|
);
|
|
949
879
|
}
|
|
950
880
|
|
|
951
|
-
const instance = await this.
|
|
881
|
+
const instance = await this.txe.utilityGetContractInstance(addressFromSingle(address));
|
|
952
882
|
return toForeignCallResult([
|
|
953
883
|
toSingle(instance.currentContractClassId),
|
|
954
884
|
// AVM requires an extra boolean indicating the instance was found
|
|
@@ -957,13 +887,13 @@ export class TXEService {
|
|
|
957
887
|
}
|
|
958
888
|
|
|
959
889
|
async avmOpcodeGetContractInstanceInitializationHash(address: ForeignCallSingle) {
|
|
960
|
-
if (
|
|
890
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
961
891
|
throw new Error(
|
|
962
|
-
|
|
892
|
+
`Attempted to call the avmOpcodeGetContractInstanceInitializationHash oracle while in context ${TXEContext[this.context]}`,
|
|
963
893
|
);
|
|
964
894
|
}
|
|
965
895
|
|
|
966
|
-
const instance = await this.
|
|
896
|
+
const instance = await this.txe.utilityGetContractInstance(addressFromSingle(address));
|
|
967
897
|
return toForeignCallResult([
|
|
968
898
|
toSingle(instance.initializationHash),
|
|
969
899
|
// AVM requires an extra boolean indicating the instance was found
|
|
@@ -972,46 +902,44 @@ export class TXEService {
|
|
|
972
902
|
}
|
|
973
903
|
|
|
974
904
|
avmOpcodeSender() {
|
|
975
|
-
if (
|
|
976
|
-
throw new Error(
|
|
977
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
978
|
-
);
|
|
905
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
906
|
+
throw new Error(`Attempted to call the avmOpcodeSender oracle while in context ${TXEContext[this.context]}`);
|
|
979
907
|
}
|
|
980
908
|
|
|
981
|
-
const sender =
|
|
909
|
+
const sender = this.txe.getMsgSender();
|
|
982
910
|
return toForeignCallResult([toSingle(sender)]);
|
|
983
911
|
}
|
|
984
912
|
|
|
985
913
|
async avmOpcodeEmitNullifier(nullifier: ForeignCallSingle) {
|
|
986
|
-
if (
|
|
914
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
987
915
|
throw new Error(
|
|
988
|
-
|
|
916
|
+
`Attempted to call the avmOpcodeEmitNullifier oracle while in context ${TXEContext[this.context]}`,
|
|
989
917
|
);
|
|
990
918
|
}
|
|
991
919
|
|
|
992
|
-
await
|
|
920
|
+
await this.txe.avmOpcodeEmitNullifier(fromSingle(nullifier));
|
|
993
921
|
return toForeignCallResult([]);
|
|
994
922
|
}
|
|
995
923
|
|
|
996
924
|
async avmOpcodeEmitNoteHash(noteHash: ForeignCallSingle) {
|
|
997
|
-
if (
|
|
925
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
998
926
|
throw new Error(
|
|
999
|
-
|
|
927
|
+
`Attempted to call the avmOpcodeEmitNoteHash oracle while in context ${TXEContext[this.context]}`,
|
|
1000
928
|
);
|
|
1001
929
|
}
|
|
1002
930
|
|
|
1003
|
-
await
|
|
931
|
+
await this.txe.avmOpcodeEmitNoteHash(fromSingle(noteHash));
|
|
1004
932
|
return toForeignCallResult([]);
|
|
1005
933
|
}
|
|
1006
934
|
|
|
1007
935
|
async avmOpcodeNullifierExists(innerNullifier: ForeignCallSingle, targetAddress: ForeignCallSingle) {
|
|
1008
|
-
if (
|
|
936
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
1009
937
|
throw new Error(
|
|
1010
|
-
|
|
938
|
+
`Attempted to call the avmOpcodeNullifierExists oracle while in context ${TXEContext[this.context]}`,
|
|
1011
939
|
);
|
|
1012
940
|
}
|
|
1013
941
|
|
|
1014
|
-
const exists = await
|
|
942
|
+
const exists = await this.txe.avmOpcodeNullifierExists(
|
|
1015
943
|
fromSingle(innerNullifier),
|
|
1016
944
|
AztecAddress.fromField(fromSingle(targetAddress)),
|
|
1017
945
|
);
|
|
@@ -1019,181 +947,105 @@ export class TXEService {
|
|
|
1019
947
|
}
|
|
1020
948
|
|
|
1021
949
|
async avmOpcodeAddress() {
|
|
1022
|
-
if (
|
|
1023
|
-
throw new Error(
|
|
1024
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
1025
|
-
);
|
|
950
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
951
|
+
throw new Error(`Attempted to call the avmOpcodeAddress oracle while in context ${TXEContext[this.context]}`);
|
|
1026
952
|
}
|
|
1027
953
|
|
|
1028
|
-
const contractAddress = await this.
|
|
954
|
+
const contractAddress = await this.txe.utilityGetContractAddress();
|
|
1029
955
|
return toForeignCallResult([toSingle(contractAddress.toField())]);
|
|
1030
956
|
}
|
|
1031
957
|
|
|
1032
958
|
async avmOpcodeBlockNumber() {
|
|
1033
|
-
if (
|
|
1034
|
-
throw new Error(
|
|
1035
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
1036
|
-
);
|
|
959
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
960
|
+
throw new Error(`Attempted to call the avmOpcodeBlockNumber oracle while in context ${TXEContext[this.context]}`);
|
|
1037
961
|
}
|
|
1038
962
|
|
|
1039
|
-
const blockNumber = await this.
|
|
963
|
+
const blockNumber = await this.txe.utilityGetBlockNumber();
|
|
1040
964
|
return toForeignCallResult([toSingle(new Fr(blockNumber))]);
|
|
1041
965
|
}
|
|
1042
966
|
|
|
1043
967
|
async avmOpcodeTimestamp() {
|
|
1044
|
-
if (
|
|
1045
|
-
throw new Error(
|
|
1046
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
1047
|
-
);
|
|
968
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
969
|
+
throw new Error(`Attempted to call the avmOpcodeTimestamp oracle while in context ${TXEContext[this.context]}`);
|
|
1048
970
|
}
|
|
1049
971
|
|
|
1050
|
-
const timestamp = await this.
|
|
972
|
+
const timestamp = await this.txe.utilityGetTimestamp();
|
|
1051
973
|
return toForeignCallResult([toSingle(new Fr(timestamp))]);
|
|
1052
974
|
}
|
|
1053
975
|
|
|
1054
976
|
avmOpcodeIsStaticCall() {
|
|
1055
|
-
if (
|
|
977
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
1056
978
|
throw new Error(
|
|
1057
|
-
|
|
979
|
+
`Attempted to call the avmOpcodeIsStaticCall oracle while in context ${TXEContext[this.context]}`,
|
|
1058
980
|
);
|
|
1059
981
|
}
|
|
1060
982
|
|
|
1061
|
-
|
|
983
|
+
// TestEnvironment::public_context is always static
|
|
984
|
+
const isStaticCall = true;
|
|
1062
985
|
return toForeignCallResult([toSingle(new Fr(isStaticCall ? 1 : 0))]);
|
|
1063
986
|
}
|
|
1064
987
|
|
|
1065
988
|
async avmOpcodeChainId() {
|
|
1066
|
-
if (
|
|
1067
|
-
throw new Error(
|
|
1068
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
1069
|
-
);
|
|
989
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
990
|
+
throw new Error(`Attempted to call the avmOpcodeChainId oracle while in context ${TXEContext[this.context]}`);
|
|
1070
991
|
}
|
|
1071
992
|
|
|
1072
|
-
const chainId = await
|
|
993
|
+
const chainId = await this.txe.utilityGetChainId();
|
|
1073
994
|
return toForeignCallResult([toSingle(chainId)]);
|
|
1074
995
|
}
|
|
1075
996
|
|
|
1076
997
|
async avmOpcodeVersion() {
|
|
1077
|
-
if (
|
|
1078
|
-
throw new Error(
|
|
1079
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
1080
|
-
);
|
|
998
|
+
if (this.contextChecksEnabled && this.context != TXEContext.PUBLIC) {
|
|
999
|
+
throw new Error(`Attempted to call the avmOpcodeVersion oracle while in context ${TXEContext[this.context]}`);
|
|
1081
1000
|
}
|
|
1082
1001
|
|
|
1083
|
-
const version = await
|
|
1002
|
+
const version = await this.txe.utilityGetVersion();
|
|
1084
1003
|
return toForeignCallResult([toSingle(version)]);
|
|
1085
1004
|
}
|
|
1086
1005
|
|
|
1087
1006
|
avmOpcodeReturndataSize() {
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
);
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
const size = (this.typedOracle as TXE).avmOpcodeReturndataSize();
|
|
1095
|
-
return toForeignCallResult([toSingle(new Fr(size))]);
|
|
1007
|
+
throw new Error(
|
|
1008
|
+
'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
|
|
1009
|
+
);
|
|
1096
1010
|
}
|
|
1097
1011
|
|
|
1098
|
-
avmOpcodeReturndataCopy(
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
1102
|
-
);
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
const returndata = (this.typedOracle as TXE).avmOpcodeReturndataCopy(
|
|
1106
|
-
fromSingle(rdOffset).toNumber(),
|
|
1107
|
-
fromSingle(copySize).toNumber(),
|
|
1012
|
+
avmOpcodeReturndataCopy(_rdOffset: ForeignCallSingle, _copySize: ForeignCallSingle) {
|
|
1013
|
+
throw new Error(
|
|
1014
|
+
'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
|
|
1108
1015
|
);
|
|
1109
|
-
// This is a slice, so we need to return the length as well.
|
|
1110
|
-
return toForeignCallResult([toSingle(new Fr(returndata.length)), toArray(returndata)]);
|
|
1111
1016
|
}
|
|
1112
1017
|
|
|
1113
|
-
|
|
1018
|
+
avmOpcodeCall(
|
|
1114
1019
|
_l2Gas: ForeignCallSingle,
|
|
1115
1020
|
_daGas: ForeignCallSingle,
|
|
1116
|
-
|
|
1021
|
+
_address: ForeignCallSingle,
|
|
1117
1022
|
_length: ForeignCallSingle,
|
|
1118
|
-
|
|
1023
|
+
_args: ForeignCallArray,
|
|
1119
1024
|
) {
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
1123
|
-
);
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1126
|
-
const result = await (this.typedOracle as TXE).avmOpcodeCall(
|
|
1127
|
-
addressFromSingle(address),
|
|
1128
|
-
fromArray(args),
|
|
1129
|
-
/* isStaticCall */ false,
|
|
1025
|
+
throw new Error(
|
|
1026
|
+
'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
|
|
1130
1027
|
);
|
|
1131
|
-
|
|
1132
|
-
// Poor man's revert handling
|
|
1133
|
-
if (!result.revertCode.isOK()) {
|
|
1134
|
-
if (result.revertReason && result.revertReason instanceof SimulationError) {
|
|
1135
|
-
await enrichPublicSimulationError(
|
|
1136
|
-
result.revertReason,
|
|
1137
|
-
(this.typedOracle as TXE).getContractDataProvider(),
|
|
1138
|
-
this.logger,
|
|
1139
|
-
);
|
|
1140
|
-
throw new Error(result.revertReason.message);
|
|
1141
|
-
} else {
|
|
1142
|
-
throw new Error(`Public function call reverted: ${result.revertReason}`);
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
return toForeignCallResult([]);
|
|
1147
1028
|
}
|
|
1148
1029
|
|
|
1149
|
-
|
|
1030
|
+
avmOpcodeStaticCall(
|
|
1150
1031
|
_l2Gas: ForeignCallSingle,
|
|
1151
1032
|
_daGas: ForeignCallSingle,
|
|
1152
|
-
|
|
1033
|
+
_address: ForeignCallSingle,
|
|
1153
1034
|
_length: ForeignCallSingle,
|
|
1154
|
-
|
|
1035
|
+
_args: ForeignCallArray,
|
|
1155
1036
|
) {
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
1159
|
-
);
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
const result = await (this.typedOracle as TXE).avmOpcodeCall(
|
|
1163
|
-
addressFromSingle(address),
|
|
1164
|
-
fromArray(args),
|
|
1165
|
-
/* isStaticCall */ true,
|
|
1037
|
+
throw new Error(
|
|
1038
|
+
'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
|
|
1166
1039
|
);
|
|
1167
|
-
|
|
1168
|
-
// Poor man's revert handling
|
|
1169
|
-
if (!result.revertCode.isOK()) {
|
|
1170
|
-
if (result.revertReason && result.revertReason instanceof SimulationError) {
|
|
1171
|
-
await enrichPublicSimulationError(
|
|
1172
|
-
result.revertReason,
|
|
1173
|
-
(this.typedOracle as TXE).getContractDataProvider(),
|
|
1174
|
-
this.logger,
|
|
1175
|
-
);
|
|
1176
|
-
throw new Error(result.revertReason.message);
|
|
1177
|
-
} else {
|
|
1178
|
-
throw new Error(`Public function call reverted: ${result.revertReason}`);
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
|
|
1182
|
-
return toForeignCallResult([]);
|
|
1183
1040
|
}
|
|
1184
1041
|
|
|
1185
1042
|
avmOpcodeSuccessCopy() {
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
);
|
|
1190
|
-
}
|
|
1191
|
-
|
|
1192
|
-
const success = (this.typedOracle as TXE).avmOpcodeSuccessCopy();
|
|
1193
|
-
return toForeignCallResult([toSingle(new Fr(success))]);
|
|
1043
|
+
throw new Error(
|
|
1044
|
+
'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
|
|
1045
|
+
);
|
|
1194
1046
|
}
|
|
1195
1047
|
|
|
1196
|
-
async
|
|
1048
|
+
async txePrivateCallNewFlow(
|
|
1197
1049
|
from: ForeignCallSingle,
|
|
1198
1050
|
targetContractAddress: ForeignCallSingle,
|
|
1199
1051
|
functionSelector: ForeignCallSingle,
|
|
@@ -1202,7 +1054,7 @@ export class TXEService {
|
|
|
1202
1054
|
argsHash: ForeignCallSingle,
|
|
1203
1055
|
isStaticCall: ForeignCallSingle,
|
|
1204
1056
|
) {
|
|
1205
|
-
const result = await
|
|
1057
|
+
const result = await this.txe.txePrivateCallNewFlow(
|
|
1206
1058
|
addressFromSingle(from),
|
|
1207
1059
|
addressFromSingle(targetContractAddress),
|
|
1208
1060
|
FunctionSelector.fromField(fromSingle(functionSelector)),
|
|
@@ -1211,15 +1063,7 @@ export class TXEService {
|
|
|
1211
1063
|
fromSingle(isStaticCall).toBool(),
|
|
1212
1064
|
);
|
|
1213
1065
|
|
|
1214
|
-
return toForeignCallResult([toArray([result.endSideEffectCounter, result.returnsHash, result.txHash])]);
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
|
-
disableOracles() {
|
|
1218
|
-
this.oraclesEnabled = false;
|
|
1219
|
-
}
|
|
1220
|
-
|
|
1221
|
-
enableOracles() {
|
|
1222
|
-
this.oraclesEnabled = true;
|
|
1066
|
+
return toForeignCallResult([toArray([result.endSideEffectCounter, result.returnsHash, result.txHash.hash])]);
|
|
1223
1067
|
}
|
|
1224
1068
|
|
|
1225
1069
|
async simulateUtilityFunction(
|
|
@@ -1227,7 +1071,7 @@ export class TXEService {
|
|
|
1227
1071
|
functionSelector: ForeignCallSingle,
|
|
1228
1072
|
argsHash: ForeignCallSingle,
|
|
1229
1073
|
) {
|
|
1230
|
-
const result = await
|
|
1074
|
+
const result = await this.txe.simulateUtilityFunction(
|
|
1231
1075
|
addressFromSingle(targetContractAddress),
|
|
1232
1076
|
FunctionSelector.fromField(fromSingle(functionSelector)),
|
|
1233
1077
|
fromSingle(argsHash),
|
|
@@ -1236,20 +1080,49 @@ export class TXEService {
|
|
|
1236
1080
|
return toForeignCallResult([toSingle(result)]);
|
|
1237
1081
|
}
|
|
1238
1082
|
|
|
1239
|
-
async
|
|
1083
|
+
async txePublicCallNewFlow(
|
|
1240
1084
|
from: ForeignCallSingle,
|
|
1241
1085
|
address: ForeignCallSingle,
|
|
1242
1086
|
_length: ForeignCallSingle,
|
|
1243
1087
|
calldata: ForeignCallArray,
|
|
1244
1088
|
isStaticCall: ForeignCallSingle,
|
|
1245
1089
|
) {
|
|
1246
|
-
const result = await
|
|
1090
|
+
const result = await this.txe.txePublicCallNewFlow(
|
|
1247
1091
|
addressFromSingle(from),
|
|
1248
1092
|
addressFromSingle(address),
|
|
1249
1093
|
fromArray(calldata),
|
|
1250
1094
|
fromSingle(isStaticCall).toBool(),
|
|
1251
1095
|
);
|
|
1252
1096
|
|
|
1253
|
-
return toForeignCallResult([toArray([result.returnsHash, result.txHash])]);
|
|
1097
|
+
return toForeignCallResult([toArray([result.returnsHash, result.txHash.hash])]);
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
async privateGetSenderForTags() {
|
|
1101
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
1102
|
+
throw new Error(
|
|
1103
|
+
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
1104
|
+
);
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
const sender = await this.txe.privateGetSenderForTags();
|
|
1108
|
+
// Return a Noir Option struct with `some` and `value` fields
|
|
1109
|
+
if (sender === undefined) {
|
|
1110
|
+
// No sender found, return Option with some=0 and value=0
|
|
1111
|
+
return toForeignCallResult([toSingle(0), toSingle(0)]);
|
|
1112
|
+
} else {
|
|
1113
|
+
// Sender found, return Option with some=1 and value=sender address
|
|
1114
|
+
return toForeignCallResult([toSingle(1), toSingle(sender)]);
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
async privateSetSenderForTags(senderForTags: ForeignCallSingle) {
|
|
1119
|
+
if (this.contextChecksEnabled && this.context == TXEContext.TOP_LEVEL) {
|
|
1120
|
+
throw new Error(
|
|
1121
|
+
'Oracle access from the root of a TXe test are not enabled. Please use env._ to interact with the oracles.',
|
|
1122
|
+
);
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
await this.txe.privateSetSenderForTags(AztecAddress.fromField(fromSingle(senderForTags)));
|
|
1126
|
+
return toForeignCallResult([]);
|
|
1254
1127
|
}
|
|
1255
1128
|
}
|