@aztec/txe 0.46.5 → 0.46.6
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/bin/index.d.ts +3 -0
- package/dest/bin/index.d.ts.map +1 -0
- package/dest/bin/index.js +20 -0
- package/dest/index.d.ts +9 -0
- package/dest/index.d.ts.map +1 -0
- package/dest/index.js +37 -0
- package/dest/oracle/txe_oracle.d.ts +108 -0
- package/dest/oracle/txe_oracle.d.ts.map +1 -0
- package/dest/oracle/txe_oracle.js +527 -0
- package/dest/txe_service/txe_service.d.ts +196 -0
- package/dest/txe_service/txe_service.d.ts.map +1 -0
- package/dest/txe_service/txe_service.js +440 -0
- package/dest/util/encoding.d.ts +14 -0
- package/dest/util/encoding.d.ts.map +1 -0
- package/dest/util/encoding.js +17 -0
- package/dest/util/expected_failure_error.d.ts +4 -0
- package/dest/util/expected_failure_error.d.ts.map +1 -0
- package/dest/util/expected_failure_error.js +6 -0
- package/dest/util/txe_database.d.ts +10 -0
- package/dest/util/txe_database.d.ts.map +1 -0
- package/dest/util/txe_database.js +23 -0
- package/dest/util/txe_public_contract_data_source.d.ts +16 -0
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -0
- package/dest/util/txe_public_contract_data_source.js +48 -0
- package/dest/util/txe_public_state_db.d.ts +14 -0
- package/dest/util/txe_public_state_db.d.ts.map +1 -0
- package/dest/util/txe_public_state_db.js +37 -0
- package/package.json +13 -13
- package/src/bin/index.ts +10 -67
- package/src/index.ts +55 -0
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
import { AuthWitness, L1NotePayload, MerkleTreeId, Note, NullifierMembershipWitness, PublicDataWitness, PublicDataWrite, TaggedLog, } from '@aztec/circuit-types';
|
|
2
|
+
import { CallContext, FunctionData, Gas, GlobalVariables, Header, NULLIFIER_SUBTREE_HEIGHT, PUBLIC_DATA_SUBTREE_HEIGHT, PrivateCallStackItem, PrivateCircuitPublicInputs, PrivateContextInputs, PublicCallRequest, PublicDataTreeLeaf, TxContext, computeContractClassId, deriveKeys, getContractClassFromArtifact, } from '@aztec/circuits.js';
|
|
3
|
+
import { Aes128, Schnorr } from '@aztec/circuits.js/barretenberg';
|
|
4
|
+
import { computePublicDataTreeLeafSlot, siloNoteHash, siloNullifier } from '@aztec/circuits.js/hash';
|
|
5
|
+
import { FunctionSelector, countArgumentsSize, } from '@aztec/foundation/abi';
|
|
6
|
+
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
7
|
+
import { Fr, GrumpkinScalar } from '@aztec/foundation/fields';
|
|
8
|
+
import { applyStringFormatting } from '@aztec/foundation/log';
|
|
9
|
+
import { Timer } from '@aztec/foundation/timer';
|
|
10
|
+
import { ContractDataOracle } from '@aztec/pxe';
|
|
11
|
+
import { ContractsDataSourcePublicDB, ExecutionError, Oracle, PublicExecutor, WorldStateDB, acvm, createSimulationError, extractCallStack, pickNotes, toACVMWitness, witnessMapToFields, } from '@aztec/simulator';
|
|
12
|
+
import { MerkleTreeSnapshotOperationsFacade } from '@aztec/world-state';
|
|
13
|
+
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
14
|
+
import { TXEPublicStateDB } from '../util/txe_public_state_db.js';
|
|
15
|
+
export class TXE {
|
|
16
|
+
constructor(logger, trees, packedValuesCache, noteCache, keyStore, txeDatabase) {
|
|
17
|
+
this.logger = logger;
|
|
18
|
+
this.trees = trees;
|
|
19
|
+
this.packedValuesCache = packedValuesCache;
|
|
20
|
+
this.noteCache = noteCache;
|
|
21
|
+
this.keyStore = keyStore;
|
|
22
|
+
this.txeDatabase = txeDatabase;
|
|
23
|
+
this.blockNumber = 0;
|
|
24
|
+
this.sideEffectsCounter = 0;
|
|
25
|
+
this.functionSelector = FunctionSelector.fromField(new Fr(0));
|
|
26
|
+
this.version = Fr.ONE;
|
|
27
|
+
this.chainId = Fr.ONE;
|
|
28
|
+
this.contractDataOracle = new ContractDataOracle(txeDatabase);
|
|
29
|
+
this.contractAddress = AztecAddress.random();
|
|
30
|
+
this.msgSender = AztecAddress.fromField(new Fr(0));
|
|
31
|
+
}
|
|
32
|
+
// Utils
|
|
33
|
+
getChainId() {
|
|
34
|
+
return Promise.resolve(this.chainId);
|
|
35
|
+
}
|
|
36
|
+
getVersion() {
|
|
37
|
+
return Promise.resolve(this.version);
|
|
38
|
+
}
|
|
39
|
+
getMsgSender() {
|
|
40
|
+
return this.msgSender;
|
|
41
|
+
}
|
|
42
|
+
getFunctionSelector() {
|
|
43
|
+
return this.functionSelector;
|
|
44
|
+
}
|
|
45
|
+
setMsgSender(msgSender) {
|
|
46
|
+
this.msgSender = msgSender;
|
|
47
|
+
}
|
|
48
|
+
setFunctionSelector(functionSelector) {
|
|
49
|
+
this.functionSelector = functionSelector;
|
|
50
|
+
}
|
|
51
|
+
getSideEffectsCounter() {
|
|
52
|
+
return this.sideEffectsCounter;
|
|
53
|
+
}
|
|
54
|
+
setSideEffectsCounter(sideEffectsCounter) {
|
|
55
|
+
this.sideEffectsCounter = sideEffectsCounter;
|
|
56
|
+
}
|
|
57
|
+
setContractAddress(contractAddress) {
|
|
58
|
+
this.contractAddress = contractAddress;
|
|
59
|
+
}
|
|
60
|
+
setBlockNumber(blockNumber) {
|
|
61
|
+
this.blockNumber = blockNumber;
|
|
62
|
+
}
|
|
63
|
+
getTrees() {
|
|
64
|
+
return this.trees;
|
|
65
|
+
}
|
|
66
|
+
getContractDataOracle() {
|
|
67
|
+
return this.contractDataOracle;
|
|
68
|
+
}
|
|
69
|
+
getTXEDatabase() {
|
|
70
|
+
return this.txeDatabase;
|
|
71
|
+
}
|
|
72
|
+
getKeyStore() {
|
|
73
|
+
return this.keyStore;
|
|
74
|
+
}
|
|
75
|
+
async addContractInstance(contractInstance) {
|
|
76
|
+
await this.txeDatabase.addContractInstance(contractInstance);
|
|
77
|
+
}
|
|
78
|
+
async addContractArtifact(artifact) {
|
|
79
|
+
const contractClass = getContractClassFromArtifact(artifact);
|
|
80
|
+
await this.txeDatabase.addContractArtifact(computeContractClassId(contractClass), artifact);
|
|
81
|
+
}
|
|
82
|
+
async getPrivateContextInputs(blockNumber, sideEffectsCounter = this.sideEffectsCounter, isStaticCall = false, isDelegateCall = false) {
|
|
83
|
+
const trees = this.getTrees();
|
|
84
|
+
const stateReference = await trees.getStateReference(false);
|
|
85
|
+
const inputs = PrivateContextInputs.empty();
|
|
86
|
+
inputs.historicalHeader.globalVariables.blockNumber = new Fr(blockNumber);
|
|
87
|
+
inputs.historicalHeader.state = stateReference;
|
|
88
|
+
inputs.callContext.msgSender = this.msgSender;
|
|
89
|
+
inputs.callContext.storageContractAddress = this.contractAddress;
|
|
90
|
+
inputs.callContext.isStaticCall = isStaticCall;
|
|
91
|
+
inputs.callContext.isDelegateCall = isDelegateCall;
|
|
92
|
+
inputs.startSideEffectCounter = sideEffectsCounter;
|
|
93
|
+
inputs.callContext.functionSelector = this.functionSelector;
|
|
94
|
+
return inputs;
|
|
95
|
+
}
|
|
96
|
+
getPublicContextInputs() {
|
|
97
|
+
const inputs = {
|
|
98
|
+
argsHash: new Fr(0),
|
|
99
|
+
isStaticCall: false,
|
|
100
|
+
toFields: function () {
|
|
101
|
+
return [this.argsHash, new Fr(this.isStaticCall)];
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
return inputs;
|
|
105
|
+
}
|
|
106
|
+
async avmOpcodeNullifierExists(innerNullifier, targetAddress) {
|
|
107
|
+
const nullifier = siloNullifier(targetAddress, innerNullifier);
|
|
108
|
+
const db = this.trees.asLatest();
|
|
109
|
+
const index = await db.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer());
|
|
110
|
+
return index !== undefined;
|
|
111
|
+
}
|
|
112
|
+
async avmOpcodeEmitNullifier(nullifier) {
|
|
113
|
+
const db = this.trees.asLatest();
|
|
114
|
+
const siloedNullifier = siloNullifier(this.contractAddress, nullifier);
|
|
115
|
+
await db.batchInsert(MerkleTreeId.NULLIFIER_TREE, [siloedNullifier.toBuffer()], NULLIFIER_SUBTREE_HEIGHT);
|
|
116
|
+
return Promise.resolve();
|
|
117
|
+
}
|
|
118
|
+
async avmOpcodeEmitNoteHash(innerNoteHash) {
|
|
119
|
+
const db = this.trees.asLatest();
|
|
120
|
+
const noteHash = siloNoteHash(this.contractAddress, innerNoteHash);
|
|
121
|
+
await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, [noteHash]);
|
|
122
|
+
return Promise.resolve();
|
|
123
|
+
}
|
|
124
|
+
deriveKeys(secret) {
|
|
125
|
+
return deriveKeys(secret);
|
|
126
|
+
}
|
|
127
|
+
async addAuthWitness(address, messageHash) {
|
|
128
|
+
const account = this.txeDatabase.getAccount(address);
|
|
129
|
+
const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
|
|
130
|
+
const schnorr = new Schnorr();
|
|
131
|
+
const signature = schnorr.constructSignature(messageHash.toBuffer(), privateKey).toBuffer();
|
|
132
|
+
const authWitness = new AuthWitness(messageHash, [...signature]);
|
|
133
|
+
return this.txeDatabase.addAuthWitness(authWitness.requestHash, authWitness.witness);
|
|
134
|
+
}
|
|
135
|
+
async addNullifiers(contractAddress, nullifiers) {
|
|
136
|
+
const db = this.trees.asLatest();
|
|
137
|
+
const siloedNullifiers = nullifiers.map(nullifier => siloNullifier(contractAddress, nullifier).toBuffer());
|
|
138
|
+
await db.batchInsert(MerkleTreeId.NULLIFIER_TREE, siloedNullifiers, NULLIFIER_SUBTREE_HEIGHT);
|
|
139
|
+
}
|
|
140
|
+
async addNoteHashes(contractAddress, innerNoteHashes) {
|
|
141
|
+
const db = this.trees.asLatest();
|
|
142
|
+
const siloedNoteHashes = innerNoteHashes.map(innerNoteHash => siloNoteHash(contractAddress, innerNoteHash));
|
|
143
|
+
await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, siloedNoteHashes);
|
|
144
|
+
}
|
|
145
|
+
// TypedOracle
|
|
146
|
+
getBlockNumber() {
|
|
147
|
+
return Promise.resolve(this.blockNumber);
|
|
148
|
+
}
|
|
149
|
+
getContractAddress() {
|
|
150
|
+
return Promise.resolve(this.contractAddress);
|
|
151
|
+
}
|
|
152
|
+
getRandomField() {
|
|
153
|
+
return Fr.random();
|
|
154
|
+
}
|
|
155
|
+
packArgumentsArray(args) {
|
|
156
|
+
return Promise.resolve(this.packedValuesCache.pack(args));
|
|
157
|
+
}
|
|
158
|
+
packReturns(returns) {
|
|
159
|
+
return Promise.resolve(this.packedValuesCache.pack(returns));
|
|
160
|
+
}
|
|
161
|
+
unpackReturns(returnsHash) {
|
|
162
|
+
return Promise.resolve(this.packedValuesCache.unpack(returnsHash));
|
|
163
|
+
}
|
|
164
|
+
getKeyValidationRequest(pkMHash) {
|
|
165
|
+
return this.keyStore.getKeyValidationRequest(pkMHash, this.contractAddress);
|
|
166
|
+
}
|
|
167
|
+
async getContractInstance(address) {
|
|
168
|
+
const contractInstance = await this.contractDataOracle.getContractInstance(address);
|
|
169
|
+
if (!contractInstance) {
|
|
170
|
+
throw new Error(`Contract instance not found for address ${address}`);
|
|
171
|
+
}
|
|
172
|
+
return contractInstance;
|
|
173
|
+
}
|
|
174
|
+
getMembershipWitness(_blockNumber, _treeId, _leafValue) {
|
|
175
|
+
throw new Error('Method not implemented.');
|
|
176
|
+
}
|
|
177
|
+
async getSiblingPath(blockNumber, treeId, leafIndex) {
|
|
178
|
+
const committedDb = new MerkleTreeSnapshotOperationsFacade(this.trees, blockNumber);
|
|
179
|
+
const result = await committedDb.getSiblingPath(treeId, leafIndex.toBigInt());
|
|
180
|
+
return result.toFields();
|
|
181
|
+
}
|
|
182
|
+
async getNullifierMembershipWitness(blockNumber, nullifier) {
|
|
183
|
+
const committedDb = new MerkleTreeSnapshotOperationsFacade(this.trees, blockNumber);
|
|
184
|
+
const index = await committedDb.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer());
|
|
185
|
+
if (!index) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
const leafPreimagePromise = committedDb.getLeafPreimage(MerkleTreeId.NULLIFIER_TREE, index);
|
|
189
|
+
const siblingPathPromise = committedDb.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, BigInt(index));
|
|
190
|
+
const [leafPreimage, siblingPath] = await Promise.all([leafPreimagePromise, siblingPathPromise]);
|
|
191
|
+
if (!leafPreimage) {
|
|
192
|
+
return undefined;
|
|
193
|
+
}
|
|
194
|
+
return new NullifierMembershipWitness(BigInt(index), leafPreimage, siblingPath);
|
|
195
|
+
}
|
|
196
|
+
async getPublicDataTreeWitness(blockNumber, leafSlot) {
|
|
197
|
+
const committedDb = new MerkleTreeSnapshotOperationsFacade(this.trees, blockNumber);
|
|
198
|
+
const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
199
|
+
if (!lowLeafResult) {
|
|
200
|
+
return undefined;
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
const preimage = (await committedDb.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index));
|
|
204
|
+
const path = await committedDb.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index);
|
|
205
|
+
return new PublicDataWitness(lowLeafResult.index, preimage, path);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
getLowNullifierMembershipWitness(_blockNumber, _nullifier) {
|
|
209
|
+
throw new Error('Method not implemented.');
|
|
210
|
+
}
|
|
211
|
+
getHeader(_blockNumber) {
|
|
212
|
+
throw new Error('Method not implemented.');
|
|
213
|
+
}
|
|
214
|
+
getCompleteAddress(account) {
|
|
215
|
+
return Promise.resolve(this.txeDatabase.getAccount(account));
|
|
216
|
+
}
|
|
217
|
+
getAuthWitness(messageHash) {
|
|
218
|
+
return this.txeDatabase.getAuthWitness(messageHash);
|
|
219
|
+
}
|
|
220
|
+
popCapsule() {
|
|
221
|
+
throw new Error('Method not implemented.');
|
|
222
|
+
}
|
|
223
|
+
getNotes(storageSlot, numSelects, selectByIndexes, selectByOffsets, selectByLengths, selectValues, selectComparators, sortByIndexes, sortByOffsets, sortByLengths, sortOrder, limit, offset, _status) {
|
|
224
|
+
// Nullified pending notes are already removed from the list.
|
|
225
|
+
const pendingNotes = this.noteCache.getNotes(this.contractAddress, storageSlot);
|
|
226
|
+
const notes = pickNotes(pendingNotes, {
|
|
227
|
+
selects: selectByIndexes.slice(0, numSelects).map((index, i) => ({
|
|
228
|
+
selector: { index, offset: selectByOffsets[i], length: selectByLengths[i] },
|
|
229
|
+
value: selectValues[i],
|
|
230
|
+
comparator: selectComparators[i],
|
|
231
|
+
})),
|
|
232
|
+
sorts: sortByIndexes.map((index, i) => ({
|
|
233
|
+
selector: { index, offset: sortByOffsets[i], length: sortByLengths[i] },
|
|
234
|
+
order: sortOrder[i],
|
|
235
|
+
})),
|
|
236
|
+
limit,
|
|
237
|
+
offset,
|
|
238
|
+
});
|
|
239
|
+
this.logger.debug(`Returning ${notes.length} notes for ${this.contractAddress} at ${storageSlot}: ${notes
|
|
240
|
+
.map(n => `${n.nonce.toString()}:[${n.note.items.map(i => i.toString()).join(',')}]`)
|
|
241
|
+
.join(', ')}`);
|
|
242
|
+
return Promise.resolve(notes);
|
|
243
|
+
}
|
|
244
|
+
notifyCreatedNote(storageSlot, noteTypeId, noteItems, innerNoteHash, counter) {
|
|
245
|
+
const note = new Note(noteItems);
|
|
246
|
+
this.noteCache.addNewNote({
|
|
247
|
+
contractAddress: this.contractAddress,
|
|
248
|
+
storageSlot,
|
|
249
|
+
nonce: Fr.ZERO, // Nonce cannot be known during private execution.
|
|
250
|
+
note,
|
|
251
|
+
siloedNullifier: undefined, // Siloed nullifier cannot be known for newly created note.
|
|
252
|
+
innerNoteHash,
|
|
253
|
+
}, counter);
|
|
254
|
+
return Promise.resolve();
|
|
255
|
+
}
|
|
256
|
+
notifyNullifiedNote(innerNullifier, innerNoteHash, _counter) {
|
|
257
|
+
this.noteCache.nullifyNote(this.contractAddress, innerNullifier, innerNoteHash);
|
|
258
|
+
return Promise.resolve();
|
|
259
|
+
}
|
|
260
|
+
async checkNullifierExists(innerNullifier) {
|
|
261
|
+
const nullifier = siloNullifier(this.contractAddress, innerNullifier);
|
|
262
|
+
const db = this.trees.asLatest();
|
|
263
|
+
const index = await db.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer());
|
|
264
|
+
return index !== undefined;
|
|
265
|
+
}
|
|
266
|
+
getL1ToL2MembershipWitness(_contractAddress, _messageHash, _secret) {
|
|
267
|
+
throw new Error('Method not implemented.');
|
|
268
|
+
}
|
|
269
|
+
async avmOpcodeStorageRead(slot, length) {
|
|
270
|
+
const db = this.trees.asLatest();
|
|
271
|
+
const result = [];
|
|
272
|
+
for (let i = 0; i < length.toNumber(); i++) {
|
|
273
|
+
const leafSlot = computePublicDataTreeLeafSlot(this.contractAddress, slot.add(new Fr(i))).toBigInt();
|
|
274
|
+
const lowLeafResult = await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
|
|
275
|
+
if (!lowLeafResult || !lowLeafResult.alreadyPresent) {
|
|
276
|
+
result.push(Fr.ZERO);
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
const preimage = (await db.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index));
|
|
280
|
+
result.push(preimage.value);
|
|
281
|
+
}
|
|
282
|
+
return result;
|
|
283
|
+
}
|
|
284
|
+
async storageRead(contractAddress, startStorageSlot, blockNumber, numberOfElements) {
|
|
285
|
+
const db = blockNumber === (await this.getBlockNumber())
|
|
286
|
+
? this.trees.asLatest()
|
|
287
|
+
: new MerkleTreeSnapshotOperationsFacade(this.trees, blockNumber);
|
|
288
|
+
const values = [];
|
|
289
|
+
for (let i = 0n; i < numberOfElements; i++) {
|
|
290
|
+
const storageSlot = startStorageSlot.add(new Fr(i));
|
|
291
|
+
const leafSlot = computePublicDataTreeLeafSlot(contractAddress, storageSlot).toBigInt();
|
|
292
|
+
const lowLeafResult = await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
|
|
293
|
+
let value = Fr.ZERO;
|
|
294
|
+
if (lowLeafResult && lowLeafResult.alreadyPresent) {
|
|
295
|
+
const preimage = (await db.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index));
|
|
296
|
+
value = preimage.value;
|
|
297
|
+
}
|
|
298
|
+
this.logger.debug(`Oracle storage read: slot=${storageSlot.toString()} value=${value}`);
|
|
299
|
+
values.push(value);
|
|
300
|
+
}
|
|
301
|
+
return values;
|
|
302
|
+
}
|
|
303
|
+
async storageWrite(startStorageSlot, values) {
|
|
304
|
+
const db = this.trees.asLatest();
|
|
305
|
+
const publicDataWrites = values.map((value, i) => {
|
|
306
|
+
const storageSlot = startStorageSlot.add(new Fr(i));
|
|
307
|
+
this.logger.debug(`Oracle storage write: slot=${storageSlot.toString()} value=${value}`);
|
|
308
|
+
return new PublicDataWrite(computePublicDataTreeLeafSlot(this.contractAddress, storageSlot), value);
|
|
309
|
+
});
|
|
310
|
+
await db.batchInsert(MerkleTreeId.PUBLIC_DATA_TREE, publicDataWrites.map(write => new PublicDataTreeLeaf(write.leafIndex, write.newValue).toBuffer()), PUBLIC_DATA_SUBTREE_HEIGHT);
|
|
311
|
+
return publicDataWrites.map(write => write.newValue);
|
|
312
|
+
}
|
|
313
|
+
emitEncryptedLog(_contractAddress, _randomness, _encryptedNote, _counter) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
emitEncryptedNoteLog(_noteHashCounter, _encryptedNote, _counter) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
computeEncryptedNoteLog(contractAddress, storageSlot, noteTypeId, ovKeys, ivpkM, preimage) {
|
|
320
|
+
const note = new Note(preimage);
|
|
321
|
+
const l1NotePayload = new L1NotePayload(note, contractAddress, storageSlot, noteTypeId);
|
|
322
|
+
const taggedNote = new TaggedLog(l1NotePayload);
|
|
323
|
+
const ephSk = GrumpkinScalar.random();
|
|
324
|
+
const recipient = AztecAddress.random();
|
|
325
|
+
return taggedNote.encrypt(ephSk, recipient, ivpkM, ovKeys);
|
|
326
|
+
}
|
|
327
|
+
emitUnencryptedLog(_log, _counter) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
emitContractClassUnencryptedLog(_log, _counter) {
|
|
331
|
+
throw new Error('Method not implemented.');
|
|
332
|
+
}
|
|
333
|
+
async callPrivateFunction(targetContractAddress, functionSelector, argsHash, sideEffectCounter, isStaticCall, isDelegateCall) {
|
|
334
|
+
this.logger.verbose(`Executing external function ${targetContractAddress}:${functionSelector}(${await this.getDebugFunctionName(targetContractAddress, functionSelector)}) isStaticCall=${isStaticCall} isDelegateCall=${isDelegateCall}`);
|
|
335
|
+
// Store and modify env
|
|
336
|
+
const currentContractAddress = AztecAddress.fromField(this.contractAddress);
|
|
337
|
+
const currentMessageSender = AztecAddress.fromField(this.msgSender);
|
|
338
|
+
const currentFunctionSelector = FunctionSelector.fromField(this.functionSelector.toField());
|
|
339
|
+
this.setMsgSender(this.contractAddress);
|
|
340
|
+
this.setContractAddress(targetContractAddress);
|
|
341
|
+
this.setFunctionSelector(functionSelector);
|
|
342
|
+
const artifact = await this.contractDataOracle.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
343
|
+
const acir = artifact.bytecode;
|
|
344
|
+
const initialWitness = await this.getInitialWitness(artifact, argsHash, sideEffectCounter, isStaticCall, isDelegateCall);
|
|
345
|
+
const acvmCallback = new Oracle(this);
|
|
346
|
+
const timer = new Timer();
|
|
347
|
+
try {
|
|
348
|
+
const acirExecutionResult = await acvm(acir, initialWitness, acvmCallback).catch((err) => {
|
|
349
|
+
const execError = new ExecutionError(err.message, {
|
|
350
|
+
contractAddress: targetContractAddress,
|
|
351
|
+
functionSelector,
|
|
352
|
+
}, extractCallStack(err, artifact.debug), { cause: err });
|
|
353
|
+
this.logger.debug(`Error executing private function ${targetContractAddress}:${functionSelector}`);
|
|
354
|
+
throw createSimulationError(execError);
|
|
355
|
+
});
|
|
356
|
+
const duration = timer.ms();
|
|
357
|
+
const returnWitness = witnessMapToFields(acirExecutionResult.returnWitness);
|
|
358
|
+
const publicInputs = PrivateCircuitPublicInputs.fromFields(returnWitness);
|
|
359
|
+
const initialWitnessSize = witnessMapToFields(initialWitness).length * Fr.SIZE_IN_BYTES;
|
|
360
|
+
this.logger.debug(`Ran external function ${targetContractAddress.toString()}:${functionSelector}`, {
|
|
361
|
+
circuitName: 'app-circuit',
|
|
362
|
+
duration,
|
|
363
|
+
eventName: 'circuit-witness-generation',
|
|
364
|
+
inputSize: initialWitnessSize,
|
|
365
|
+
outputSize: publicInputs.toBuffer().length,
|
|
366
|
+
appCircuitName: 'noname',
|
|
367
|
+
});
|
|
368
|
+
const callStackItem = new PrivateCallStackItem(targetContractAddress, new FunctionData(functionSelector, true), publicInputs);
|
|
369
|
+
// Apply side effects
|
|
370
|
+
this.sideEffectsCounter = publicInputs.endSideEffectCounter.toNumber();
|
|
371
|
+
await this.addNullifiers(targetContractAddress, publicInputs.nullifiers.filter(nullifier => !nullifier.isEmpty()).map(nullifier => nullifier.value));
|
|
372
|
+
await this.addNoteHashes(targetContractAddress, publicInputs.noteHashes.filter(noteHash => !noteHash.isEmpty()).map(noteHash => noteHash.value));
|
|
373
|
+
return callStackItem;
|
|
374
|
+
}
|
|
375
|
+
finally {
|
|
376
|
+
this.setContractAddress(currentContractAddress);
|
|
377
|
+
this.setMsgSender(currentMessageSender);
|
|
378
|
+
this.setFunctionSelector(currentFunctionSelector);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
async getInitialWitness(abi, argsHash, sideEffectCounter, isStaticCall, isDelegateCall) {
|
|
382
|
+
const argumentsSize = countArgumentsSize(abi);
|
|
383
|
+
const args = this.packedValuesCache.unpack(argsHash);
|
|
384
|
+
if (args.length !== argumentsSize) {
|
|
385
|
+
throw new Error('Invalid arguments size');
|
|
386
|
+
}
|
|
387
|
+
const privateContextInputs = await this.getPrivateContextInputs(this.blockNumber - 1, sideEffectCounter, isStaticCall, isDelegateCall);
|
|
388
|
+
const fields = [...privateContextInputs.toFields(), ...args];
|
|
389
|
+
return toACVMWitness(0, fields);
|
|
390
|
+
}
|
|
391
|
+
async getDebugFunctionName(address, selector) {
|
|
392
|
+
const instance = await this.contractDataOracle.getContractInstance(address);
|
|
393
|
+
if (!instance) {
|
|
394
|
+
return undefined;
|
|
395
|
+
}
|
|
396
|
+
const artifact = await this.contractDataOracle.getContractArtifact(instance.contractClassId);
|
|
397
|
+
if (!artifact) {
|
|
398
|
+
return undefined;
|
|
399
|
+
}
|
|
400
|
+
const f = artifact.functions.find(f => FunctionSelector.fromNameAndParameters(f.name, f.parameters).equals(selector));
|
|
401
|
+
if (!f) {
|
|
402
|
+
return undefined;
|
|
403
|
+
}
|
|
404
|
+
return `${artifact.name}:${f.name}`;
|
|
405
|
+
}
|
|
406
|
+
async executePublicFunction(targetContractAddress, functionSelector, args, callContext) {
|
|
407
|
+
const header = Header.empty();
|
|
408
|
+
header.state = await this.trees.getStateReference(true);
|
|
409
|
+
header.globalVariables.blockNumber = new Fr(await this.getBlockNumber());
|
|
410
|
+
header.state.partial.nullifierTree.root = Fr.fromBuffer((await this.trees.getTreeInfo(MerkleTreeId.NULLIFIER_TREE, true)).root);
|
|
411
|
+
header.state.partial.noteHashTree.root = Fr.fromBuffer((await this.trees.getTreeInfo(MerkleTreeId.NOTE_HASH_TREE, true)).root);
|
|
412
|
+
header.state.partial.publicDataTree.root = Fr.fromBuffer((await this.trees.getTreeInfo(MerkleTreeId.PUBLIC_DATA_TREE, true)).root);
|
|
413
|
+
header.state.l1ToL2MessageTree.root = Fr.fromBuffer((await this.trees.getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, true)).root);
|
|
414
|
+
const executor = new PublicExecutor(new TXEPublicStateDB(this), new ContractsDataSourcePublicDB(new TXEPublicContractDataSource(this)), new WorldStateDB(this.trees.asLatest()), header);
|
|
415
|
+
const execution = {
|
|
416
|
+
contractAddress: targetContractAddress,
|
|
417
|
+
functionSelector,
|
|
418
|
+
args,
|
|
419
|
+
callContext,
|
|
420
|
+
};
|
|
421
|
+
return executor.simulate(execution, GlobalVariables.empty(), Gas.test(), TxContext.empty(),
|
|
422
|
+
/* pendingNullifiers */ [],
|
|
423
|
+
/* transactionFee */ Fr.ONE);
|
|
424
|
+
}
|
|
425
|
+
async avmOpcodeCall(targetContractAddress, functionSelector, args, isStaticCall, isDelegateCall) {
|
|
426
|
+
// Store and modify env
|
|
427
|
+
const currentContractAddress = AztecAddress.fromField(this.contractAddress);
|
|
428
|
+
const currentMessageSender = AztecAddress.fromField(this.msgSender);
|
|
429
|
+
const currentFunctionSelector = FunctionSelector.fromField(this.functionSelector.toField());
|
|
430
|
+
this.setMsgSender(this.contractAddress);
|
|
431
|
+
this.setContractAddress(targetContractAddress);
|
|
432
|
+
this.setFunctionSelector(functionSelector);
|
|
433
|
+
const callContext = CallContext.empty();
|
|
434
|
+
callContext.msgSender = this.msgSender;
|
|
435
|
+
callContext.functionSelector = this.functionSelector;
|
|
436
|
+
callContext.storageContractAddress = targetContractAddress;
|
|
437
|
+
callContext.isStaticCall = isStaticCall;
|
|
438
|
+
callContext.isDelegateCall = isDelegateCall;
|
|
439
|
+
const executionResult = await this.executePublicFunction(targetContractAddress, functionSelector, args, callContext);
|
|
440
|
+
// Apply side effects
|
|
441
|
+
if (!executionResult.reverted) {
|
|
442
|
+
this.sideEffectsCounter += executionResult.endSideEffectCounter.toNumber();
|
|
443
|
+
}
|
|
444
|
+
this.setContractAddress(currentContractAddress);
|
|
445
|
+
this.setMsgSender(currentMessageSender);
|
|
446
|
+
this.setFunctionSelector(currentFunctionSelector);
|
|
447
|
+
return executionResult;
|
|
448
|
+
}
|
|
449
|
+
async callPublicFunction(targetContractAddress, functionSelector, argsHash, sideEffectCounter, isStaticCall, isDelegateCall) {
|
|
450
|
+
// Store and modify env
|
|
451
|
+
const currentContractAddress = AztecAddress.fromField(this.contractAddress);
|
|
452
|
+
const currentMessageSender = AztecAddress.fromField(this.msgSender);
|
|
453
|
+
const currentFunctionSelector = FunctionSelector.fromField(this.functionSelector.toField());
|
|
454
|
+
this.setMsgSender(this.contractAddress);
|
|
455
|
+
this.setContractAddress(targetContractAddress);
|
|
456
|
+
this.setFunctionSelector(functionSelector);
|
|
457
|
+
const callContext = CallContext.empty();
|
|
458
|
+
callContext.msgSender = this.msgSender;
|
|
459
|
+
callContext.functionSelector = this.functionSelector;
|
|
460
|
+
callContext.storageContractAddress = targetContractAddress;
|
|
461
|
+
callContext.isStaticCall = isStaticCall;
|
|
462
|
+
callContext.isDelegateCall = isDelegateCall;
|
|
463
|
+
const args = this.packedValuesCache.unpack(argsHash);
|
|
464
|
+
const executionResult = await this.executePublicFunction(targetContractAddress, functionSelector, args, callContext);
|
|
465
|
+
// Apply side effects
|
|
466
|
+
this.sideEffectsCounter = executionResult.endSideEffectCounter.toNumber();
|
|
467
|
+
this.setContractAddress(currentContractAddress);
|
|
468
|
+
this.setMsgSender(currentMessageSender);
|
|
469
|
+
this.setFunctionSelector(currentFunctionSelector);
|
|
470
|
+
return executionResult.returnValues;
|
|
471
|
+
}
|
|
472
|
+
async enqueuePublicFunctionCall(targetContractAddress, functionSelector, argsHash, sideEffectCounter, isStaticCall, isDelegateCall) {
|
|
473
|
+
// Store and modify env
|
|
474
|
+
const currentContractAddress = AztecAddress.fromField(this.contractAddress);
|
|
475
|
+
const currentMessageSender = AztecAddress.fromField(this.msgSender);
|
|
476
|
+
const currentFunctionSelector = FunctionSelector.fromField(this.functionSelector.toField());
|
|
477
|
+
this.setMsgSender(this.contractAddress);
|
|
478
|
+
this.setContractAddress(targetContractAddress);
|
|
479
|
+
this.setFunctionSelector(functionSelector);
|
|
480
|
+
const callContext = CallContext.empty();
|
|
481
|
+
callContext.msgSender = this.msgSender;
|
|
482
|
+
callContext.functionSelector = this.functionSelector;
|
|
483
|
+
callContext.storageContractAddress = targetContractAddress;
|
|
484
|
+
callContext.isStaticCall = isStaticCall;
|
|
485
|
+
callContext.isDelegateCall = isDelegateCall;
|
|
486
|
+
const args = this.packedValuesCache.unpack(argsHash);
|
|
487
|
+
const executionResult = await this.executePublicFunction(targetContractAddress, functionSelector, args, callContext);
|
|
488
|
+
// Apply side effects
|
|
489
|
+
this.sideEffectsCounter += executionResult.endSideEffectCounter.toNumber();
|
|
490
|
+
this.setContractAddress(currentContractAddress);
|
|
491
|
+
this.setMsgSender(currentMessageSender);
|
|
492
|
+
this.setFunctionSelector(currentFunctionSelector);
|
|
493
|
+
const parentCallContext = CallContext.empty();
|
|
494
|
+
parentCallContext.msgSender = currentMessageSender;
|
|
495
|
+
parentCallContext.functionSelector = currentFunctionSelector;
|
|
496
|
+
parentCallContext.storageContractAddress = currentContractAddress;
|
|
497
|
+
parentCallContext.isStaticCall = isStaticCall;
|
|
498
|
+
parentCallContext.isDelegateCall = isDelegateCall;
|
|
499
|
+
return PublicCallRequest.from({
|
|
500
|
+
parentCallContext,
|
|
501
|
+
contractAddress: targetContractAddress,
|
|
502
|
+
functionSelector,
|
|
503
|
+
callContext,
|
|
504
|
+
sideEffectCounter,
|
|
505
|
+
args,
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
setPublicTeardownFunctionCall(targetContractAddress, functionSelector, argsHash, sideEffectCounter, isStaticCall, isDelegateCall) {
|
|
509
|
+
// Definitely not right, in that the teardown should always be last.
|
|
510
|
+
// But useful for executing flows.
|
|
511
|
+
return this.enqueuePublicFunctionCall(targetContractAddress, functionSelector, argsHash, sideEffectCounter, isStaticCall, isDelegateCall);
|
|
512
|
+
}
|
|
513
|
+
aes128Encrypt(input, initializationVector, key) {
|
|
514
|
+
const aes128 = new Aes128();
|
|
515
|
+
return aes128.encryptBufferCBC(input, initializationVector, key);
|
|
516
|
+
}
|
|
517
|
+
debugLog(message, fields) {
|
|
518
|
+
this.logger.verbose(`debug_log ${applyStringFormatting(message, fields)}`);
|
|
519
|
+
}
|
|
520
|
+
emitEncryptedEventLog(_contractAddress, _randomness, _encryptedEvent, _counter) {
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
computeEncryptedEventLog(_contractAddress, _randomness, _eventTypeId, _ovKeys, _ivpkM, _preimage) {
|
|
524
|
+
throw new Error('Method not implemented.');
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhlX29yYWNsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcmFjbGUvdHhlX29yYWNsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsV0FBVyxFQUNYLGFBQWEsRUFDYixZQUFZLEVBQ1osSUFBSSxFQUVKLDBCQUEwQixFQUMxQixpQkFBaUIsRUFDakIsZUFBZSxFQUNmLFNBQVMsR0FFVixNQUFNLHNCQUFzQixDQUFDO0FBRTlCLE9BQU8sRUFDTCxXQUFXLEVBQ1gsWUFBWSxFQUNaLEdBQUcsRUFDSCxlQUFlLEVBQ2YsTUFBTSxFQUVOLHdCQUF3QixFQUd4QiwwQkFBMEIsRUFFMUIsb0JBQW9CLEVBQ3BCLDBCQUEwQixFQUMxQixvQkFBb0IsRUFDcEIsaUJBQWlCLEVBQ2pCLGtCQUFrQixFQUVsQixTQUFTLEVBQ1Qsc0JBQXNCLEVBQ3RCLFVBQVUsRUFDViw0QkFBNEIsR0FDN0IsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDckcsT0FBTyxFQUdMLGdCQUFnQixFQUVoQixrQkFBa0IsR0FDbkIsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDL0QsT0FBTyxFQUFFLEVBQUUsRUFBRSxjQUFjLEVBQWMsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRSxPQUFPLEVBQWUscUJBQXFCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMzRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFaEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ2hELE9BQU8sRUFDTCwyQkFBMkIsRUFDM0IsY0FBYyxFQUlk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
|