@aztec/txe 0.76.4 → 0.77.0-testnet-ignition.21
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.js +3 -5
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +106 -106
- package/dest/node/txe_node.d.ts +19 -6
- package/dest/node/txe_node.d.ts.map +1 -1
- package/dest/node/txe_node.js +303 -334
- package/dest/oracle/txe_oracle.d.ts +25 -16
- package/dest/oracle/txe_oracle.d.ts.map +1 -1
- package/dest/oracle/txe_oracle.js +249 -143
- package/dest/txe_service/txe_service.d.ts +3 -3
- package/dest/txe_service/txe_service.d.ts.map +1 -1
- package/dest/txe_service/txe_service.js +205 -105
- package/dest/util/encoding.d.ts +39 -25
- package/dest/util/encoding.d.ts.map +1 -1
- package/dest/util/encoding.js +45 -11
- package/dest/util/expected_failure_error.js +1 -2
- package/dest/util/txe_database.d.ts +3 -2
- package/dest/util/txe_database.d.ts.map +1 -1
- package/dest/util/txe_database.js +6 -10
- package/dest/util/txe_public_contract_data_source.d.ts +5 -3
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
- package/dest/util/txe_public_contract_data_source.js +25 -13
- package/dest/util/txe_world_state_db.d.ts +6 -8
- package/dest/util/txe_world_state_db.d.ts.map +1 -1
- package/dest/util/txe_world_state_db.js +10 -23
- package/package.json +14 -15
- package/src/index.ts +2 -2
- package/src/node/txe_node.ts +64 -42
- package/src/oracle/txe_oracle.ts +101 -86
- package/src/txe_service/txe_service.ts +25 -28
- package/src/util/encoding.ts +32 -5
- package/src/util/txe_database.ts +3 -2
- package/src/util/txe_public_contract_data_source.ts +8 -9
- package/src/util/txe_world_state_db.ts +9 -26
|
@@ -1,27 +1,62 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { AuthWitness, Body, L2Block, MerkleTreeId, Note, NullifierMembershipWitness, PublicDataWitness, PublicExecutionRequest, SimulationError, TxEffect, TxHash, } from '@aztec/circuit-types';
|
|
4
|
-
import { AppendOnlyTreeSnapshot, BlockHeader, CallContext, Gas, GasFees, GlobalVariables, IndexedTaggingSecret, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, NULLIFIER_SUBTREE_HEIGHT, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, PRIVATE_CONTEXT_INPUTS_LENGTH, PUBLIC_DISPATCH_SELECTOR, PrivateContextInputs, PublicDataTreeLeaf, PublicDataWrite, computeTaggingSecretPoint, deriveKeys, } from '@aztec/circuits.js';
|
|
5
|
-
import { Schnorr } from '@aztec/circuits.js/barretenberg';
|
|
6
|
-
import { computeNoteHashNonce, computePublicDataTreeLeafSlot, computeUniqueNoteHash, siloNoteHash, siloNullifier, } from '@aztec/circuits.js/hash';
|
|
7
|
-
import { makeAppendOnlyTreeSnapshot, makeContentCommitment, makeGlobalVariables, makeHeader, } from '@aztec/circuits.js/testing';
|
|
8
|
-
import { FunctionSelector, countArgumentsSize, } from '@aztec/foundation/abi';
|
|
9
|
-
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
1
|
+
import { Body, L2Block, Note } from '@aztec/aztec.js';
|
|
2
|
+
import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, NULLIFIER_SUBTREE_HEIGHT, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, PRIVATE_CONTEXT_INPUTS_LENGTH, PUBLIC_DISPATCH_SELECTOR } from '@aztec/constants';
|
|
10
3
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
11
|
-
import { poseidon2Hash } from '@aztec/foundation/crypto';
|
|
4
|
+
import { Schnorr, poseidon2Hash } from '@aztec/foundation/crypto';
|
|
12
5
|
import { Fr } from '@aztec/foundation/fields';
|
|
13
6
|
import { applyStringFormatting, createDebugOnlyLogger } from '@aztec/foundation/log';
|
|
14
7
|
import { Timer } from '@aztec/foundation/timer';
|
|
15
8
|
import { ContractDataOracle, SimulatorOracle, enrichPublicSimulationError } from '@aztec/pxe';
|
|
16
|
-
import { ExecutionNoteCache, Oracle, ViewDataOracle, WASMSimulator, extractCallStack, extractPrivateCircuitPublicInputs, pickNotes, toACVMWitness, witnessMapToFields
|
|
9
|
+
import { ExecutionNoteCache, Oracle, ViewDataOracle, WASMSimulator, extractCallStack, extractPrivateCircuitPublicInputs, pickNotes, toACVMWitness, witnessMapToFields } from '@aztec/simulator/client';
|
|
17
10
|
import { createTxForPublicCalls } from '@aztec/simulator/public/fixtures';
|
|
18
|
-
import { ExecutionError, PublicTxSimulator, createSimulationError, resolveAssertionMessageFromError
|
|
11
|
+
import { ExecutionError, PublicTxSimulator, createSimulationError, resolveAssertionMessageFromError } from '@aztec/simulator/server';
|
|
12
|
+
import { FunctionSelector, countArgumentsSize } from '@aztec/stdlib/abi';
|
|
13
|
+
import { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
14
|
+
import { PublicDataWrite } from '@aztec/stdlib/avm';
|
|
15
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
16
|
+
import { SimulationError } from '@aztec/stdlib/errors';
|
|
17
|
+
import { Gas, GasFees } from '@aztec/stdlib/gas';
|
|
18
|
+
import { computeNoteHashNonce, computePublicDataTreeLeafSlot, computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
|
|
19
|
+
import { PrivateContextInputs } from '@aztec/stdlib/kernel';
|
|
20
|
+
import { computeTaggingSecretPoint, deriveKeys } from '@aztec/stdlib/keys';
|
|
21
|
+
import { IndexedTaggingSecret } from '@aztec/stdlib/logs';
|
|
22
|
+
import { makeAppendOnlyTreeSnapshot, makeContentCommitment, makeGlobalVariables, makeHeader } from '@aztec/stdlib/testing';
|
|
23
|
+
import { AppendOnlyTreeSnapshot, MerkleTreeId, NullifierMembershipWitness, PublicDataTreeLeaf, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
24
|
+
import { BlockHeader, CallContext, GlobalVariables, PublicExecutionRequest, TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
25
|
+
import { ForkCheckpoint } from '@aztec/world-state/native';
|
|
19
26
|
import { TXENode } from '../node/txe_node.js';
|
|
20
27
|
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
21
28
|
import { TXEWorldStateDB } from '../util/txe_world_state_db.js';
|
|
22
29
|
export class TXE {
|
|
23
|
-
|
|
24
|
-
|
|
30
|
+
logger;
|
|
31
|
+
executionCache;
|
|
32
|
+
keyStore;
|
|
33
|
+
txeDatabase;
|
|
34
|
+
contractAddress;
|
|
35
|
+
nativeWorldStateService;
|
|
36
|
+
baseFork;
|
|
37
|
+
blockNumber;
|
|
38
|
+
sideEffectCounter;
|
|
39
|
+
msgSender;
|
|
40
|
+
functionSelector;
|
|
41
|
+
isStaticCall;
|
|
42
|
+
// Return/revert data of the latest nested call.
|
|
43
|
+
nestedCallReturndata;
|
|
44
|
+
contractDataOracle;
|
|
45
|
+
simulatorOracle;
|
|
46
|
+
viewDataOracle;
|
|
47
|
+
publicDataWrites;
|
|
48
|
+
uniqueNoteHashesFromPublic;
|
|
49
|
+
siloedNullifiersFromPublic;
|
|
50
|
+
privateLogs;
|
|
51
|
+
publicLogs;
|
|
52
|
+
committedBlocks;
|
|
53
|
+
VERSION;
|
|
54
|
+
CHAIN_ID;
|
|
55
|
+
node;
|
|
56
|
+
simulationProvider;
|
|
57
|
+
noteCache;
|
|
58
|
+
debug;
|
|
59
|
+
constructor(logger, executionCache, keyStore, txeDatabase, contractAddress, nativeWorldStateService, baseFork){
|
|
25
60
|
this.logger = logger;
|
|
26
61
|
this.executionCache = executionCache;
|
|
27
62
|
this.keyStore = keyStore;
|
|
@@ -33,7 +68,6 @@ export class TXE {
|
|
|
33
68
|
this.sideEffectCounter = 0;
|
|
34
69
|
this.functionSelector = FunctionSelector.fromField(new Fr(0));
|
|
35
70
|
this.isStaticCall = false;
|
|
36
|
-
// Return/revert data of the latest nested call.
|
|
37
71
|
this.nestedCallReturndata = [];
|
|
38
72
|
this.publicDataWrites = [];
|
|
39
73
|
this.uniqueNoteHashesFromPublic = [];
|
|
@@ -50,8 +84,7 @@ export class TXE {
|
|
|
50
84
|
// Default msg_sender (for entrypoints) is now Fr.max_value rather than 0 addr (see #7190 & #7404)
|
|
51
85
|
this.msgSender = AztecAddress.fromField(Fr.MAX_FIELD_VALUE);
|
|
52
86
|
this.simulatorOracle = new SimulatorOracle(this.contractDataOracle, txeDatabase, keyStore, this.node, this.simulationProvider);
|
|
53
|
-
this.viewDataOracle = new ViewDataOracle(this.contractAddress, []
|
|
54
|
-
this.node);
|
|
87
|
+
this.viewDataOracle = new ViewDataOracle(this.contractAddress, [], [], this.simulatorOracle, this.node);
|
|
55
88
|
this.debug = createDebugOnlyLogger('aztec:kv-pxe-database');
|
|
56
89
|
}
|
|
57
90
|
static async create(logger, executionCache, keyStore, txeDatabase, nativeWorldStateService, baseFork) {
|
|
@@ -65,10 +98,10 @@ export class TXE {
|
|
|
65
98
|
return this.baseFork;
|
|
66
99
|
}
|
|
67
100
|
getChainId() {
|
|
68
|
-
return Promise.resolve(this.node.getChainId().then(id
|
|
101
|
+
return Promise.resolve(this.node.getChainId().then((id)=>new Fr(id)));
|
|
69
102
|
}
|
|
70
103
|
getVersion() {
|
|
71
|
-
return Promise.resolve(this.node.getVersion().then(v
|
|
104
|
+
return Promise.resolve(this.node.getVersion().then((v)=>new Fr(v)));
|
|
72
105
|
}
|
|
73
106
|
getMsgSender() {
|
|
74
107
|
return this.msgSender;
|
|
@@ -113,8 +146,7 @@ export class TXE {
|
|
|
113
146
|
async getPrivateContextInputs(blockNumber, sideEffectsCounter = this.sideEffectCounter, isStaticCall = false) {
|
|
114
147
|
if (blockNumber > this.blockNumber) {
|
|
115
148
|
throw new Error(`Tried to request private context inputs for ${blockNumber}, which is greater than our current block number of ${this.blockNumber}`);
|
|
116
|
-
}
|
|
117
|
-
else if (blockNumber === this.blockNumber) {
|
|
149
|
+
} else if (blockNumber === this.blockNumber) {
|
|
118
150
|
this.logger.debug(`Tried to request private context inputs for ${blockNumber}, equal to current block of ${this.blockNumber}. Clamping to current block - 1.`);
|
|
119
151
|
blockNumber = this.blockNumber - 1;
|
|
120
152
|
}
|
|
@@ -139,18 +171,20 @@ export class TXE {
|
|
|
139
171
|
const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
|
|
140
172
|
const schnorr = new Schnorr();
|
|
141
173
|
const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
|
|
142
|
-
const authWitness = new AuthWitness(messageHash, [
|
|
174
|
+
const authWitness = new AuthWitness(messageHash, [
|
|
175
|
+
...signature.toBuffer()
|
|
176
|
+
]);
|
|
143
177
|
return this.txeDatabase.addAuthWitness(authWitness.requestHash, authWitness.witness);
|
|
144
178
|
}
|
|
145
179
|
async addPublicDataWrites(writes) {
|
|
146
180
|
this.publicDataWrites.push(...writes);
|
|
147
|
-
await this.baseFork.sequentialInsert(MerkleTreeId.PUBLIC_DATA_TREE, writes.map(w
|
|
181
|
+
await this.baseFork.sequentialInsert(MerkleTreeId.PUBLIC_DATA_TREE, writes.map((w)=>new PublicDataTreeLeaf(w.leafSlot, w.value).toBuffer()));
|
|
148
182
|
}
|
|
149
183
|
async checkNullifiersNotInTree(contractAddress, nullifiers) {
|
|
150
|
-
const siloedNullifiers = await Promise.all(nullifiers.map(nullifier
|
|
184
|
+
const siloedNullifiers = await Promise.all(nullifiers.map((nullifier)=>siloNullifier(contractAddress, nullifier)));
|
|
151
185
|
const db = this.baseFork;
|
|
152
|
-
const nullifierIndexesInTree = await db.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, siloedNullifiers.map(n
|
|
153
|
-
if (nullifierIndexesInTree.some(index
|
|
186
|
+
const nullifierIndexesInTree = await db.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, siloedNullifiers.map((n)=>n.toBuffer()));
|
|
187
|
+
if (nullifierIndexesInTree.some((index)=>index !== undefined)) {
|
|
154
188
|
throw new Error(`Rejecting tx for emitting duplicate nullifiers`);
|
|
155
189
|
}
|
|
156
190
|
}
|
|
@@ -161,20 +195,22 @@ export class TXE {
|
|
|
161
195
|
this.uniqueNoteHashesFromPublic.push(...siloedNoteHashes);
|
|
162
196
|
}
|
|
163
197
|
async addPrivateLogs(contractAddress, privateLogs) {
|
|
164
|
-
for (const privateLog of privateLogs)
|
|
165
|
-
privateLog.fields[0] = await poseidon2Hash([
|
|
198
|
+
for (const privateLog of privateLogs){
|
|
199
|
+
privateLog.fields[0] = await poseidon2Hash([
|
|
200
|
+
contractAddress,
|
|
201
|
+
privateLog.fields[0]
|
|
202
|
+
]);
|
|
166
203
|
}
|
|
167
204
|
this.privateLogs.push(...privateLogs);
|
|
168
205
|
}
|
|
169
206
|
addPublicLogs(logs) {
|
|
170
|
-
logs.forEach(log
|
|
207
|
+
logs.forEach((log)=>{
|
|
171
208
|
try {
|
|
172
209
|
// The first elt stores lengths => tag is in fields[1]
|
|
173
210
|
const tag = log.log[1];
|
|
174
211
|
this.logger.verbose(`Found tagged public log with tag ${tag.toString()} in block ${this.blockNumber}`);
|
|
175
212
|
this.publicLogs.push(log);
|
|
176
|
-
}
|
|
177
|
-
catch (err) {
|
|
213
|
+
} catch (err) {
|
|
178
214
|
this.logger.warn(`Failed to add tagged log to store: ${err}`);
|
|
179
215
|
}
|
|
180
216
|
});
|
|
@@ -213,12 +249,17 @@ export class TXE {
|
|
|
213
249
|
}
|
|
214
250
|
async getMembershipWitness(blockNumber, treeId, leafValue) {
|
|
215
251
|
const snap = this.nativeWorldStateService.getSnapshot(blockNumber);
|
|
216
|
-
const index = (await snap.findLeafIndices(treeId, [
|
|
252
|
+
const index = (await snap.findLeafIndices(treeId, [
|
|
253
|
+
leafValue.toBuffer()
|
|
254
|
+
]))[0];
|
|
217
255
|
if (index === undefined) {
|
|
218
256
|
throw new Error(`Leaf value: ${leafValue} not found in ${MerkleTreeId[treeId]} at block ${blockNumber}`);
|
|
219
257
|
}
|
|
220
258
|
const siblingPath = await snap.getSiblingPath(treeId, index);
|
|
221
|
-
return [
|
|
259
|
+
return [
|
|
260
|
+
new Fr(index),
|
|
261
|
+
...siblingPath.toFields()
|
|
262
|
+
];
|
|
222
263
|
}
|
|
223
264
|
async getSiblingPath(blockNumber, treeId, leafIndex) {
|
|
224
265
|
const snap = this.nativeWorldStateService.getSnapshot(blockNumber);
|
|
@@ -227,13 +268,18 @@ export class TXE {
|
|
|
227
268
|
}
|
|
228
269
|
async getNullifierMembershipWitness(blockNumber, nullifier) {
|
|
229
270
|
const snap = this.nativeWorldStateService.getSnapshot(blockNumber);
|
|
230
|
-
const [index] = await snap.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [
|
|
271
|
+
const [index] = await snap.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [
|
|
272
|
+
nullifier.toBuffer()
|
|
273
|
+
]);
|
|
231
274
|
if (!index) {
|
|
232
275
|
return undefined;
|
|
233
276
|
}
|
|
234
277
|
const leafPreimagePromise = snap.getLeafPreimage(MerkleTreeId.NULLIFIER_TREE, index);
|
|
235
278
|
const siblingPathPromise = snap.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, BigInt(index));
|
|
236
|
-
const [leafPreimage, siblingPath] = await Promise.all([
|
|
279
|
+
const [leafPreimage, siblingPath] = await Promise.all([
|
|
280
|
+
leafPreimagePromise,
|
|
281
|
+
siblingPathPromise
|
|
282
|
+
]);
|
|
237
283
|
if (!leafPreimage) {
|
|
238
284
|
return undefined;
|
|
239
285
|
}
|
|
@@ -244,9 +290,8 @@ export class TXE {
|
|
|
244
290
|
const lowLeafResult = await snap.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
245
291
|
if (!lowLeafResult) {
|
|
246
292
|
return undefined;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const preimage = (await snap.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index));
|
|
293
|
+
} else {
|
|
294
|
+
const preimage = await snap.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index);
|
|
250
295
|
const path = await snap.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index);
|
|
251
296
|
return new PublicDataWitness(lowLeafResult.index, preimage, path);
|
|
252
297
|
}
|
|
@@ -261,7 +306,7 @@ export class TXE {
|
|
|
261
306
|
if (alreadyPresent) {
|
|
262
307
|
this.logger.warn(`Nullifier ${nullifier.toBigInt()} already exists in the tree`);
|
|
263
308
|
}
|
|
264
|
-
const preimageData =
|
|
309
|
+
const preimageData = await snap.getLeafPreimage(MerkleTreeId.NULLIFIER_TREE, index);
|
|
265
310
|
const siblingPath = await snap.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, BigInt(index));
|
|
266
311
|
return new NullifierMembershipWitness(BigInt(index), preimageData, siblingPath);
|
|
267
312
|
}
|
|
@@ -289,23 +334,32 @@ export class TXE {
|
|
|
289
334
|
const pendingNotes = this.noteCache.getNotes(this.contractAddress, storageSlot);
|
|
290
335
|
const pendingNullifiers = this.noteCache.getNullifiers(this.contractAddress);
|
|
291
336
|
const dbNotes = await this.simulatorOracle.getNotes(this.contractAddress, storageSlot, status);
|
|
292
|
-
const dbNotesFiltered = dbNotes.filter(n
|
|
293
|
-
const notes = pickNotes([
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
337
|
+
const dbNotesFiltered = dbNotes.filter((n)=>!pendingNullifiers.has(n.siloedNullifier.value));
|
|
338
|
+
const notes = pickNotes([
|
|
339
|
+
...dbNotesFiltered,
|
|
340
|
+
...pendingNotes
|
|
341
|
+
], {
|
|
342
|
+
selects: selectByIndexes.slice(0, numSelects).map((index, i)=>({
|
|
343
|
+
selector: {
|
|
344
|
+
index,
|
|
345
|
+
offset: selectByOffsets[i],
|
|
346
|
+
length: selectByLengths[i]
|
|
347
|
+
},
|
|
348
|
+
value: selectValues[i],
|
|
349
|
+
comparator: selectComparators[i]
|
|
350
|
+
})),
|
|
351
|
+
sorts: sortByIndexes.map((index, i)=>({
|
|
352
|
+
selector: {
|
|
353
|
+
index,
|
|
354
|
+
offset: sortByOffsets[i],
|
|
355
|
+
length: sortByLengths[i]
|
|
356
|
+
},
|
|
357
|
+
order: sortOrder[i]
|
|
358
|
+
})),
|
|
303
359
|
limit,
|
|
304
|
-
offset
|
|
360
|
+
offset
|
|
305
361
|
});
|
|
306
|
-
this.logger.debug(`Returning ${notes.length} notes for ${this.contractAddress} at ${storageSlot}: ${notes
|
|
307
|
-
.map(n => `${n.nonce.toString()}:[${n.note.items.map(i => i.toString()).join(',')}]`)
|
|
308
|
-
.join(', ')}`);
|
|
362
|
+
this.logger.debug(`Returning ${notes.length} notes for ${this.contractAddress} at ${storageSlot}: ${notes.map((n)=>`${n.nonce.toString()}:[${n.note.items.map((i)=>i.toString()).join(',')}]`).join(', ')}`);
|
|
309
363
|
return notes;
|
|
310
364
|
}
|
|
311
365
|
notifyCreatedNote(storageSlot, _noteTypeId, noteItems, noteHash, counter) {
|
|
@@ -313,27 +367,33 @@ export class TXE {
|
|
|
313
367
|
this.noteCache.addNewNote({
|
|
314
368
|
contractAddress: this.contractAddress,
|
|
315
369
|
storageSlot,
|
|
316
|
-
nonce: Fr.ZERO,
|
|
370
|
+
nonce: Fr.ZERO,
|
|
317
371
|
note,
|
|
318
|
-
siloedNullifier: undefined,
|
|
319
|
-
noteHash
|
|
372
|
+
siloedNullifier: undefined,
|
|
373
|
+
noteHash
|
|
320
374
|
}, counter);
|
|
321
375
|
this.sideEffectCounter = counter + 1;
|
|
322
376
|
return Promise.resolve();
|
|
323
377
|
}
|
|
324
378
|
async notifyNullifiedNote(innerNullifier, noteHash, counter) {
|
|
325
|
-
await this.checkNullifiersNotInTree(this.contractAddress, [
|
|
379
|
+
await this.checkNullifiersNotInTree(this.contractAddress, [
|
|
380
|
+
innerNullifier
|
|
381
|
+
]);
|
|
326
382
|
await this.noteCache.nullifyNote(this.contractAddress, innerNullifier, noteHash);
|
|
327
383
|
this.sideEffectCounter = counter + 1;
|
|
328
384
|
}
|
|
329
385
|
async notifyCreatedNullifier(innerNullifier) {
|
|
330
|
-
await this.checkNullifiersNotInTree(this.contractAddress, [
|
|
386
|
+
await this.checkNullifiersNotInTree(this.contractAddress, [
|
|
387
|
+
innerNullifier
|
|
388
|
+
]);
|
|
331
389
|
await this.noteCache.nullifierCreated(this.contractAddress, innerNullifier);
|
|
332
390
|
}
|
|
333
391
|
async checkNullifierExists(innerNullifier) {
|
|
334
392
|
const snap = this.nativeWorldStateService.getSnapshot(this.blockNumber - 1);
|
|
335
393
|
const nullifier = await siloNullifier(this.contractAddress, innerNullifier);
|
|
336
|
-
const [index] = await snap.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [
|
|
394
|
+
const [index] = await snap.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [
|
|
395
|
+
nullifier.toBuffer()
|
|
396
|
+
]);
|
|
337
397
|
return index !== undefined;
|
|
338
398
|
}
|
|
339
399
|
getL1ToL2MembershipWitness(_contractAddress, _messageHash, _secret) {
|
|
@@ -343,18 +403,17 @@ export class TXE {
|
|
|
343
403
|
let db;
|
|
344
404
|
if (blockNumber === this.blockNumber) {
|
|
345
405
|
db = this.baseFork;
|
|
346
|
-
}
|
|
347
|
-
else {
|
|
406
|
+
} else {
|
|
348
407
|
db = this.nativeWorldStateService.getSnapshot(blockNumber);
|
|
349
408
|
}
|
|
350
409
|
const values = [];
|
|
351
|
-
for
|
|
410
|
+
for(let i = 0n; i < numberOfElements; i++){
|
|
352
411
|
const storageSlot = startStorageSlot.add(new Fr(i));
|
|
353
412
|
const leafSlot = (await computePublicDataTreeLeafSlot(contractAddress, storageSlot)).toBigInt();
|
|
354
413
|
const lowLeafResult = await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
|
|
355
414
|
let value = Fr.ZERO;
|
|
356
415
|
if (lowLeafResult && lowLeafResult.alreadyPresent) {
|
|
357
|
-
const preimage =
|
|
416
|
+
const preimage = await db.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index);
|
|
358
417
|
value = preimage.value;
|
|
359
418
|
}
|
|
360
419
|
this.logger.debug(`Oracle storage read: slot=${storageSlot.toString()} value=${value}`);
|
|
@@ -363,51 +422,58 @@ export class TXE {
|
|
|
363
422
|
return values;
|
|
364
423
|
}
|
|
365
424
|
async storageWrite(startStorageSlot, values) {
|
|
366
|
-
const publicDataWrites = await Promise.all(values.map(async (value, i)
|
|
425
|
+
const publicDataWrites = await Promise.all(values.map(async (value, i)=>{
|
|
367
426
|
const storageSlot = startStorageSlot.add(new Fr(i));
|
|
368
427
|
this.logger.debug(`Oracle storage write: slot=${storageSlot.toString()} value=${value}`);
|
|
369
428
|
return new PublicDataWrite(await computePublicDataTreeLeafSlot(this.contractAddress, storageSlot), value);
|
|
370
429
|
}));
|
|
371
430
|
await this.addPublicDataWrites(publicDataWrites);
|
|
372
|
-
return publicDataWrites.map(write
|
|
431
|
+
return publicDataWrites.map((write)=>write.value);
|
|
373
432
|
}
|
|
374
433
|
async commitState() {
|
|
375
434
|
const blockNumber = await this.getBlockNumber();
|
|
376
435
|
const { usedTxRequestHashForNonces } = this.noteCache.finish();
|
|
377
436
|
if (this.committedBlocks.has(blockNumber)) {
|
|
378
437
|
throw new Error('Already committed state');
|
|
379
|
-
}
|
|
380
|
-
else {
|
|
438
|
+
} else {
|
|
381
439
|
this.committedBlocks.add(blockNumber);
|
|
382
440
|
}
|
|
383
441
|
const fork = this.baseFork;
|
|
384
442
|
const txEffect = TxEffect.empty();
|
|
385
443
|
const nonceGenerator = usedTxRequestHashForNonces ? this.getTxRequestHash() : this.noteCache.getAllNullifiers()[0];
|
|
386
444
|
let i = 0;
|
|
387
|
-
const uniqueNoteHashesFromPrivate = await Promise.all(this.noteCache
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
445
|
+
const uniqueNoteHashesFromPrivate = await Promise.all(this.noteCache.getAllNotes().map(async (pendingNote)=>computeUniqueNoteHash(await computeNoteHashNonce(nonceGenerator, i++), await siloNoteHash(pendingNote.note.contractAddress, pendingNote.noteHashForConsumption))));
|
|
446
|
+
txEffect.noteHashes = [
|
|
447
|
+
...uniqueNoteHashesFromPrivate,
|
|
448
|
+
...this.uniqueNoteHashesFromPublic
|
|
449
|
+
];
|
|
450
|
+
txEffect.nullifiers = [
|
|
451
|
+
...this.siloedNullifiersFromPublic,
|
|
452
|
+
...this.noteCache.getAllNullifiers()
|
|
453
|
+
];
|
|
392
454
|
if (usedTxRequestHashForNonces) {
|
|
393
455
|
txEffect.nullifiers.unshift(this.getTxRequestHash());
|
|
394
456
|
}
|
|
395
457
|
txEffect.publicDataWrites = this.publicDataWrites;
|
|
396
|
-
const body = new Body([
|
|
458
|
+
const body = new Body([
|
|
459
|
+
txEffect
|
|
460
|
+
]);
|
|
397
461
|
const l2Block = new L2Block(makeAppendOnlyTreeSnapshot(blockNumber + 1), makeHeader(0, blockNumber, blockNumber), body);
|
|
398
462
|
const paddedTxEffects = l2Block.body.txEffects;
|
|
399
463
|
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
400
464
|
{
|
|
401
|
-
const noteHashesPadded = paddedTxEffects.flatMap(txEffect
|
|
465
|
+
const noteHashesPadded = paddedTxEffects.flatMap((txEffect)=>padArrayEnd(txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX));
|
|
402
466
|
await fork.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashesPadded);
|
|
403
467
|
await fork.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
404
468
|
}
|
|
405
469
|
{
|
|
406
|
-
for (const txEffect of paddedTxEffects)
|
|
470
|
+
for (const txEffect of paddedTxEffects){
|
|
407
471
|
// We do not need to add public data writes because we apply them as we go. We use the sequentialInsert because
|
|
408
472
|
// the batchInsert was not working when updating a previously updated slot.
|
|
473
|
+
// FIXME: public data writes, note hashes, nullifiers, messages should all be handled in the same way.
|
|
474
|
+
// They are all relevant to subsequent enqueued calls and txs.
|
|
409
475
|
const nullifiersPadded = padArrayEnd(txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX);
|
|
410
|
-
await fork.batchInsert(MerkleTreeId.NULLIFIER_TREE, nullifiersPadded.map(nullifier
|
|
476
|
+
await fork.batchInsert(MerkleTreeId.NULLIFIER_TREE, nullifiersPadded.map((nullifier)=>nullifier.toBuffer()), NULLIFIER_SUBTREE_HEIGHT);
|
|
411
477
|
}
|
|
412
478
|
}
|
|
413
479
|
await this.node.setTxEffect(blockNumber, new TxHash(new Fr(blockNumber)), txEffect);
|
|
@@ -420,6 +486,11 @@ export class TXE {
|
|
|
420
486
|
header.globalVariables.blockNumber = new Fr(blockNumber);
|
|
421
487
|
l2Block.header = header;
|
|
422
488
|
await fork.updateArchive(l2Block.header);
|
|
489
|
+
// We've built a block with all of our state changes in a "fork".
|
|
490
|
+
// Now emulate a "sync" to this block, by letting cpp reapply the block's
|
|
491
|
+
// changes to the underlying unforked world state and comparing the results
|
|
492
|
+
// against the block's state reference (which is this state reference here in the fork).
|
|
493
|
+
// This essentially commits the state updates to the unforked state and sanity checks the roots.
|
|
423
494
|
await this.nativeWorldStateService.handleL2BlockAndMessages(l2Block, l1ToL2Messages);
|
|
424
495
|
this.publicDataWrites = [];
|
|
425
496
|
this.privateLogs = [];
|
|
@@ -449,14 +520,14 @@ export class TXE {
|
|
|
449
520
|
const initialWitness = await this.getInitialWitness(artifact, argsHash, sideEffectCounter, isStaticCall);
|
|
450
521
|
const acvmCallback = new Oracle(this);
|
|
451
522
|
const timer = new Timer();
|
|
452
|
-
const acirExecutionResult = await this.simulationProvider
|
|
453
|
-
.executeUserCircuit(acir, initialWitness, acvmCallback)
|
|
454
|
-
.catch((err) => {
|
|
523
|
+
const acirExecutionResult = await this.simulationProvider.executeUserCircuit(acir, initialWitness, acvmCallback).catch((err)=>{
|
|
455
524
|
err.message = resolveAssertionMessageFromError(err, artifact);
|
|
456
525
|
const execError = new ExecutionError(err.message, {
|
|
457
526
|
contractAddress: targetContractAddress,
|
|
458
|
-
functionSelector
|
|
459
|
-
}, extractCallStack(err, artifact.debug), {
|
|
527
|
+
functionSelector
|
|
528
|
+
}, extractCallStack(err, artifact.debug), {
|
|
529
|
+
cause: err
|
|
530
|
+
});
|
|
460
531
|
this.logger.debug(`Error executing private function ${targetContractAddress}:${functionSelector}`);
|
|
461
532
|
throw createSimulationError(execError);
|
|
462
533
|
});
|
|
@@ -469,16 +540,19 @@ export class TXE {
|
|
|
469
540
|
eventName: 'circuit-witness-generation',
|
|
470
541
|
inputSize: initialWitnessSize,
|
|
471
542
|
outputSize: publicInputs.toBuffer().length,
|
|
472
|
-
appCircuitName: 'noname'
|
|
543
|
+
appCircuitName: 'noname'
|
|
473
544
|
});
|
|
474
545
|
// Apply side effects
|
|
475
546
|
const endSideEffectCounter = publicInputs.endSideEffectCounter;
|
|
476
547
|
this.sideEffectCounter = endSideEffectCounter.toNumber() + 1;
|
|
477
|
-
await this.addPrivateLogs(targetContractAddress, publicInputs.privateLogs.filter(privateLog
|
|
548
|
+
await this.addPrivateLogs(targetContractAddress, publicInputs.privateLogs.filter((privateLog)=>!privateLog.isEmpty()).map((privateLog)=>privateLog.log));
|
|
478
549
|
this.setContractAddress(currentContractAddress);
|
|
479
550
|
this.setMsgSender(currentMessageSender);
|
|
480
551
|
this.setFunctionSelector(currentFunctionSelector);
|
|
481
|
-
return {
|
|
552
|
+
return {
|
|
553
|
+
endSideEffectCounter,
|
|
554
|
+
returnsHash: publicInputs.returnsHash
|
|
555
|
+
};
|
|
482
556
|
}
|
|
483
557
|
async getInitialWitness(abi, argsHash, sideEffectCounter, isStaticCall) {
|
|
484
558
|
const argumentsSize = countArgumentsSize(abi);
|
|
@@ -491,7 +565,10 @@ export class TXE {
|
|
|
491
565
|
if (privateContextInputsAsFields.length !== PRIVATE_CONTEXT_INPUTS_LENGTH) {
|
|
492
566
|
throw new Error('Invalid private context inputs size');
|
|
493
567
|
}
|
|
494
|
-
const fields = [
|
|
568
|
+
const fields = [
|
|
569
|
+
...privateContextInputsAsFields,
|
|
570
|
+
...args
|
|
571
|
+
];
|
|
495
572
|
return toACVMWitness(0, fields);
|
|
496
573
|
}
|
|
497
574
|
async getDebugFunctionName(address, selector) {
|
|
@@ -499,15 +576,15 @@ export class TXE {
|
|
|
499
576
|
if (!instance) {
|
|
500
577
|
return undefined;
|
|
501
578
|
}
|
|
502
|
-
const artifact = await this.contractDataOracle.getContractArtifact(instance.
|
|
579
|
+
const artifact = await this.contractDataOracle.getContractArtifact(instance.currentContractClassId);
|
|
503
580
|
if (!artifact) {
|
|
504
581
|
return undefined;
|
|
505
582
|
}
|
|
506
|
-
const functionSelectorsAndNames = await Promise.all(artifact.functions.map(async (f)
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
const functionSelectorAndName = functionSelectorsAndNames.find(f
|
|
583
|
+
const functionSelectorsAndNames = await Promise.all(artifact.functions.map(async (f)=>({
|
|
584
|
+
name: f.name,
|
|
585
|
+
selector: await FunctionSelector.fromNameAndParameters(f.name, f.parameters)
|
|
586
|
+
})));
|
|
587
|
+
const functionSelectorAndName = functionSelectorsAndNames.find((f)=>f.selector.equals(selector));
|
|
511
588
|
if (!functionSelectorAndName) {
|
|
512
589
|
return undefined;
|
|
513
590
|
}
|
|
@@ -521,23 +598,35 @@ export class TXE {
|
|
|
521
598
|
globalVariables.version = new Fr(await this.node.getVersion());
|
|
522
599
|
globalVariables.blockNumber = new Fr(this.blockNumber);
|
|
523
600
|
globalVariables.gasFees = new GasFees(1, 1);
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
601
|
+
let result;
|
|
602
|
+
// Checkpoint here so that we can revert merkle ops after simulation.
|
|
603
|
+
// See note at revert below.
|
|
604
|
+
const checkpoint = await ForkCheckpoint.new(db);
|
|
605
|
+
try {
|
|
606
|
+
const simulator = new PublicTxSimulator(db, new TXEWorldStateDB(db, new TXEPublicContractDataSource(this), this), globalVariables, /*doMerkleOperations=*/ true);
|
|
607
|
+
const { usedTxRequestHashForNonces } = this.noteCache.finish();
|
|
608
|
+
const firstNullifier = usedTxRequestHashForNonces ? this.getTxRequestHash() : this.noteCache.getAllNullifiers()[0];
|
|
609
|
+
// When setting up a teardown call, we tell it that
|
|
610
|
+
// private execution used Gas(1, 1) so it can compute a tx fee.
|
|
611
|
+
const gasUsedByPrivate = isTeardown ? new Gas(1, 1) : Gas.empty();
|
|
612
|
+
const tx = await createTxForPublicCalls(firstNullifier, /*setupExecutionRequests=*/ [], /*appExecutionRequests=*/ isTeardown ? [] : [
|
|
613
|
+
executionRequest
|
|
614
|
+
], /*teardownExecutionRequests=*/ isTeardown ? executionRequest : undefined, /*feePayer=*/ AztecAddress.zero(), gasUsedByPrivate);
|
|
615
|
+
result = await simulator.simulate(tx);
|
|
616
|
+
} finally{
|
|
617
|
+
// NOTE: Don't accept any merkle updates from the AVM since this was just 1 enqueued call
|
|
618
|
+
// and the TXE will re-apply all txEffects after entire execution (all enqueued calls)
|
|
619
|
+
// complete.
|
|
620
|
+
await checkpoint.revert();
|
|
621
|
+
// If an error is thrown during the above simulation, this revert is the last
|
|
622
|
+
// thing executed and we skip the postprocessing below.
|
|
623
|
+
}
|
|
624
|
+
const noteHashes = result.avmProvingRequest.inputs.publicInputs.accumulatedData.noteHashes.filter((s)=>!s.isEmpty());
|
|
625
|
+
const publicDataWrites = result.avmProvingRequest.inputs.publicInputs.accumulatedData.publicDataWrites.filter((s)=>!s.isEmpty());
|
|
626
|
+
// For now, public data writes are the only merkle operations that are readable by later enqueued calls in the TXE.
|
|
538
627
|
await this.addPublicDataWrites(publicDataWrites);
|
|
539
628
|
this.addUniqueNoteHashesFromPublic(noteHashes);
|
|
540
|
-
this.addPublicLogs(result.avmProvingRequest.inputs.publicInputs.accumulatedData.publicLogs.filter(log
|
|
629
|
+
this.addPublicLogs(result.avmProvingRequest.inputs.publicInputs.accumulatedData.publicLogs.filter((log)=>!log.contractAddress.equals(AztecAddress.ZERO)));
|
|
541
630
|
return Promise.resolve(result);
|
|
542
631
|
}
|
|
543
632
|
async enqueuePublicFunctionCall(targetContractAddress, functionSelector, argsHash, _sideEffectCounter, isStaticCall, isTeardown = false) {
|
|
@@ -548,9 +637,11 @@ export class TXE {
|
|
|
548
637
|
this.setMsgSender(this.contractAddress);
|
|
549
638
|
this.setContractAddress(targetContractAddress);
|
|
550
639
|
this.setFunctionSelector(functionSelector);
|
|
551
|
-
const callContext = new CallContext(
|
|
552
|
-
|
|
553
|
-
|
|
640
|
+
const callContext = new CallContext(/* msgSender */ currentContractAddress, targetContractAddress, FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)), isStaticCall);
|
|
641
|
+
const args = [
|
|
642
|
+
this.functionSelector.toField(),
|
|
643
|
+
...this.executionCache.getPreimage(argsHash)
|
|
644
|
+
];
|
|
554
645
|
const newArgsHash = await this.executionCache.store(args);
|
|
555
646
|
const executionResult = await this.executePublicFunction(args, callContext, isTeardown);
|
|
556
647
|
// Poor man's revert handling
|
|
@@ -558,8 +649,7 @@ export class TXE {
|
|
|
558
649
|
if (executionResult.revertReason && executionResult.revertReason instanceof SimulationError) {
|
|
559
650
|
await enrichPublicSimulationError(executionResult.revertReason, this.contractDataOracle, this.txeDatabase, this.logger);
|
|
560
651
|
throw new Error(executionResult.revertReason.message);
|
|
561
|
-
}
|
|
562
|
-
else {
|
|
652
|
+
} else {
|
|
563
653
|
throw new Error(`Enqueued public function call reverted: ${executionResult.revertReason}`);
|
|
564
654
|
}
|
|
565
655
|
}
|
|
@@ -567,7 +657,7 @@ export class TXE {
|
|
|
567
657
|
const sideEffects = executionResult.avmProvingRequest.inputs.publicInputs.accumulatedData;
|
|
568
658
|
const { usedTxRequestHashForNonces } = this.noteCache.finish();
|
|
569
659
|
const firstNullifier = usedTxRequestHashForNonces ? this.getTxRequestHash() : this.noteCache.getAllNullifiers()[0];
|
|
570
|
-
const nullifiers = sideEffects.nullifiers.filter(s
|
|
660
|
+
const nullifiers = sideEffects.nullifiers.filter((s)=>!s.isEmpty()).filter((s)=>!s.equals(firstNullifier));
|
|
571
661
|
// For some reason we cannot move this up to 'executePublicFunction'. It gives us an error of trying to modify the same nullifier twice.
|
|
572
662
|
this.addSiloedNullifiersFromPublic(nullifiers);
|
|
573
663
|
this.setContractAddress(currentContractAddress);
|
|
@@ -578,28 +668,47 @@ export class TXE {
|
|
|
578
668
|
async setPublicTeardownFunctionCall(targetContractAddress, functionSelector, argsHash, sideEffectCounter, isStaticCall) {
|
|
579
669
|
// Definitely not right, in that the teardown should always be last.
|
|
580
670
|
// But useful for executing flows.
|
|
581
|
-
return await this.enqueuePublicFunctionCall(targetContractAddress, functionSelector, argsHash, sideEffectCounter, isStaticCall,
|
|
582
|
-
/*isTeardown=*/ true);
|
|
671
|
+
return await this.enqueuePublicFunctionCall(targetContractAddress, functionSelector, argsHash, sideEffectCounter, isStaticCall, /*isTeardown=*/ true);
|
|
583
672
|
}
|
|
584
673
|
async notifySetMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter) {
|
|
585
674
|
await this.noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
586
675
|
}
|
|
587
676
|
debugLog(message, fields) {
|
|
588
|
-
this.logger.verbose(`${applyStringFormatting(message, fields)}`, {
|
|
677
|
+
this.logger.verbose(`${applyStringFormatting(message, fields)}`, {
|
|
678
|
+
module: `${this.logger.module}:debug_log`
|
|
679
|
+
});
|
|
589
680
|
}
|
|
590
681
|
async incrementAppTaggingSecretIndexAsSender(sender, recipient) {
|
|
591
|
-
const appSecret = await
|
|
592
|
-
const [index] = await this.txeDatabase.getTaggingSecretsIndexesAsSender([
|
|
593
|
-
|
|
682
|
+
const appSecret = await this.#calculateAppTaggingSecret(this.contractAddress, sender, recipient);
|
|
683
|
+
const [index] = await this.txeDatabase.getTaggingSecretsIndexesAsSender([
|
|
684
|
+
appSecret
|
|
685
|
+
]);
|
|
686
|
+
await this.txeDatabase.setTaggingSecretsIndexesAsSender([
|
|
687
|
+
new IndexedTaggingSecret(appSecret, index + 1)
|
|
688
|
+
]);
|
|
594
689
|
}
|
|
595
690
|
async getIndexedTaggingSecretAsSender(sender, recipient) {
|
|
596
|
-
const secret = await
|
|
597
|
-
const [index] = await this.txeDatabase.getTaggingSecretsIndexesAsSender([
|
|
691
|
+
const secret = await this.#calculateAppTaggingSecret(this.contractAddress, sender, recipient);
|
|
692
|
+
const [index] = await this.txeDatabase.getTaggingSecretsIndexesAsSender([
|
|
693
|
+
secret
|
|
694
|
+
]);
|
|
598
695
|
return new IndexedTaggingSecret(secret, index);
|
|
599
696
|
}
|
|
697
|
+
async #calculateAppTaggingSecret(contractAddress, sender, recipient) {
|
|
698
|
+
const senderCompleteAddress = await this.getCompleteAddress(sender);
|
|
699
|
+
const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
|
|
700
|
+
const secretPoint = await computeTaggingSecretPoint(senderCompleteAddress, senderIvsk, recipient);
|
|
701
|
+
// Silo the secret to the app so it can't be used to track other app's notes
|
|
702
|
+
const appSecret = poseidon2Hash([
|
|
703
|
+
secretPoint.x,
|
|
704
|
+
secretPoint.y,
|
|
705
|
+
contractAddress
|
|
706
|
+
]);
|
|
707
|
+
return appSecret;
|
|
708
|
+
}
|
|
600
709
|
async syncNotes() {
|
|
601
710
|
const taggedLogsByRecipient = await this.simulatorOracle.syncTaggedLogs(this.contractAddress, await this.getBlockNumber(), undefined);
|
|
602
|
-
for (const [recipient, taggedLogs] of taggedLogsByRecipient.entries())
|
|
711
|
+
for (const [recipient, taggedLogs] of taggedLogsByRecipient.entries()){
|
|
603
712
|
await this.simulatorOracle.processTaggedLogs(taggedLogs, AztecAddress.fromString(recipient));
|
|
604
713
|
}
|
|
605
714
|
await this.simulatorOracle.removeNullifiedNotes(this.contractAddress);
|
|
@@ -608,6 +717,9 @@ export class TXE {
|
|
|
608
717
|
deliverNote(_contractAddress, _storageSlot, _nonce, _content, _noteHash, _nullifier, _txHash, _recipient) {
|
|
609
718
|
throw new Error('deliverNote');
|
|
610
719
|
}
|
|
720
|
+
async getLogByTag(tag) {
|
|
721
|
+
return await this.simulatorOracle.getLogByTag(tag);
|
|
722
|
+
}
|
|
611
723
|
// AVM oracles
|
|
612
724
|
async avmOpcodeCall(targetContractAddress, args, isStaticCall) {
|
|
613
725
|
// Store and modify env
|
|
@@ -615,21 +727,18 @@ export class TXE {
|
|
|
615
727
|
const currentMessageSender = this.msgSender;
|
|
616
728
|
this.setMsgSender(this.contractAddress);
|
|
617
729
|
this.setContractAddress(targetContractAddress);
|
|
618
|
-
const callContext = new CallContext(
|
|
619
|
-
/* msgSender */ currentContractAddress, targetContractAddress, FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)), isStaticCall);
|
|
730
|
+
const callContext = new CallContext(/* msgSender */ currentContractAddress, targetContractAddress, FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)), isStaticCall);
|
|
620
731
|
const executionResult = await this.executePublicFunction(args, callContext);
|
|
621
732
|
// Save return/revert data for later.
|
|
622
733
|
this.nestedCallReturndata = executionResult.processedPhases[0].returnValues[0].values;
|
|
623
734
|
// Apply side effects
|
|
624
735
|
if (executionResult.revertCode.isOK()) {
|
|
625
736
|
const sideEffects = executionResult.avmProvingRequest.inputs.publicInputs.accumulatedData;
|
|
626
|
-
const publicDataWrites = sideEffects.publicDataWrites.filter(s
|
|
627
|
-
const noteHashes = sideEffects.noteHashes.filter(s
|
|
737
|
+
const publicDataWrites = sideEffects.publicDataWrites.filter((s)=>!s.isEmpty());
|
|
738
|
+
const noteHashes = sideEffects.noteHashes.filter((s)=>!s.isEmpty());
|
|
628
739
|
const { usedTxRequestHashForNonces } = this.noteCache.finish();
|
|
629
|
-
const firstNullifier = usedTxRequestHashForNonces
|
|
630
|
-
|
|
631
|
-
: this.noteCache.getAllNullifiers()[0];
|
|
632
|
-
const nullifiers = sideEffects.nullifiers.filter(s => !s.isEmpty()).filter(s => !s.equals(firstNullifier));
|
|
740
|
+
const firstNullifier = usedTxRequestHashForNonces ? this.getTxRequestHash() : this.noteCache.getAllNullifiers()[0];
|
|
741
|
+
const nullifiers = sideEffects.nullifiers.filter((s)=>!s.isEmpty()).filter((s)=>!s.equals(firstNullifier));
|
|
633
742
|
await this.addPublicDataWrites(publicDataWrites);
|
|
634
743
|
this.addUniqueNoteHashesFromPublic(noteHashes);
|
|
635
744
|
this.addSiloedNullifiersFromPublic(nullifiers);
|
|
@@ -647,18 +756,24 @@ export class TXE {
|
|
|
647
756
|
async avmOpcodeNullifierExists(innerNullifier, targetAddress) {
|
|
648
757
|
const nullifier = await siloNullifier(targetAddress, innerNullifier);
|
|
649
758
|
const db = this.baseFork;
|
|
650
|
-
const index = (await db.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [
|
|
759
|
+
const index = (await db.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [
|
|
760
|
+
nullifier.toBuffer()
|
|
761
|
+
]))[0];
|
|
651
762
|
return index !== undefined;
|
|
652
763
|
}
|
|
653
764
|
async avmOpcodeEmitNullifier(nullifier) {
|
|
654
765
|
const siloedNullifier = await siloNullifier(this.contractAddress, nullifier);
|
|
655
|
-
this.addSiloedNullifiersFromPublic([
|
|
766
|
+
this.addSiloedNullifiersFromPublic([
|
|
767
|
+
siloedNullifier
|
|
768
|
+
]);
|
|
656
769
|
return Promise.resolve();
|
|
657
770
|
}
|
|
658
771
|
// Doesn't this need to get hashed w/ the nonce ?
|
|
659
772
|
async avmOpcodeEmitNoteHash(noteHash) {
|
|
660
773
|
const siloedNoteHash = await siloNoteHash(this.contractAddress, noteHash);
|
|
661
|
-
this.addUniqueNoteHashesFromPublic([
|
|
774
|
+
this.addUniqueNoteHashesFromPublic([
|
|
775
|
+
siloedNoteHash
|
|
776
|
+
]);
|
|
662
777
|
return Promise.resolve();
|
|
663
778
|
}
|
|
664
779
|
async avmOpcodeStorageRead(slot) {
|
|
@@ -667,7 +782,7 @@ export class TXE {
|
|
|
667
782
|
if (!lowLeafResult || !lowLeafResult.alreadyPresent) {
|
|
668
783
|
return Fr.ZERO;
|
|
669
784
|
}
|
|
670
|
-
const preimage =
|
|
785
|
+
const preimage = await this.baseFork.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index);
|
|
671
786
|
return preimage.value;
|
|
672
787
|
}
|
|
673
788
|
storeCapsule(contractAddress, slot, capsule) {
|
|
@@ -702,12 +817,3 @@ export class TXE {
|
|
|
702
817
|
return this.viewDataOracle.aes128Decrypt(ciphertext, iv, symKey);
|
|
703
818
|
}
|
|
704
819
|
}
|
|
705
|
-
_TXE_instances = new WeakSet(), _TXE_calculateAppTaggingSecret = async function _TXE_calculateAppTaggingSecret(contractAddress, sender, recipient) {
|
|
706
|
-
const senderCompleteAddress = await this.getCompleteAddress(sender);
|
|
707
|
-
const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
|
|
708
|
-
const secretPoint = await computeTaggingSecretPoint(senderCompleteAddress, senderIvsk, recipient);
|
|
709
|
-
// Silo the secret to the app so it can't be used to track other app's notes
|
|
710
|
-
const appSecret = poseidon2Hash([secretPoint.x, secretPoint.y, contractAddress]);
|
|
711
|
-
return appSecret;
|
|
712
|
-
};
|
|
713
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhlX29yYWNsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcmFjbGUvdHhlX29yYWNsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE9BQU8sRUFDTCxXQUFXLEVBQ1gsSUFBSSxFQUNKLE9BQU8sRUFDUCxZQUFZLEVBR1osSUFBSSxFQUVKLDBCQUEwQixFQUMxQixpQkFBaUIsRUFDakIsc0JBQXNCLEVBQ3RCLGVBQWUsRUFDZixRQUFRLEVBQ1IsTUFBTSxHQUVQLE1BQU0sc0JBQXNCLENBQUM7QUFFOUIsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixXQUFXLEVBQ1gsV0FBVyxFQUdYLEdBQUcsRUFDSCxPQUFPLEVBQ1AsZUFBZSxFQUNmLG9CQUFvQixFQUdwQixzQkFBc0IsRUFDdEIscUJBQXFCLEVBQ3JCLHdCQUF3QixFQUV4QixtQ0FBbUMsRUFFbkMsNkJBQTZCLEVBRTdCLHdCQUF3QixFQUN4QixvQkFBb0IsRUFFcEIsa0JBQWtCLEVBRWxCLGVBQWUsRUFFZix5QkFBeUIsRUFDekIsVUFBVSxHQUNYLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzFELE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsNkJBQTZCLEVBQzdCLHFCQUFxQixFQUNyQixZQUFZLEVBQ1osYUFBYSxHQUNkLE1BQU0seUJBQXlCLENBQUM7QUFDakMsT0FBTyxFQUNMLDBCQUEwQixFQUMxQixxQkFBcUIsRUFDckIsbUJBQW1CLEVBQ25CLFVBQVUsR0FDWCxNQUFNLDRCQUE0QixDQUFDO0FBQ3BDLE9BQU8sRUFHTCxnQkFBZ0IsRUFFaEIsa0JBQWtCLEdBQ25CLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQy9ELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsYUFB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
|