@aztec/simulator 0.65.2 → 0.67.0
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/acvm/acvm.js +3 -3
- package/dest/acvm/oracle/oracle.d.ts +1 -4
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +3 -19
- package/dest/acvm/oracle/typed_oracle.d.ts +2 -7
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +3 -12
- package/dest/acvm/serialize.js +2 -2
- package/dest/avm/avm_context.d.ts +2 -2
- package/dest/avm/avm_context.d.ts.map +1 -1
- package/dest/avm/avm_context.js +3 -4
- package/dest/avm/avm_execution_environment.d.ts +4 -6
- package/dest/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/avm/avm_execution_environment.js +8 -13
- package/dest/avm/avm_memory_types.d.ts +2 -2
- package/dest/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/avm/avm_memory_types.js +7 -7
- package/dest/avm/avm_simulator.d.ts +3 -3
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/avm_simulator.js +26 -16
- package/dest/avm/avm_tree.d.ts +31 -14
- package/dest/avm/avm_tree.d.ts.map +1 -1
- package/dest/avm/avm_tree.js +34 -40
- package/dest/avm/errors.d.ts +3 -3
- package/dest/avm/errors.d.ts.map +1 -1
- package/dest/avm/errors.js +8 -15
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +4 -4
- package/dest/avm/journal/journal.d.ts +15 -4
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +121 -36
- package/dest/avm/opcodes/environment_getters.d.ts +10 -11
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +12 -15
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +4 -11
- package/dest/avm/opcodes/misc.d.ts.map +1 -1
- package/dest/avm/opcodes/misc.js +3 -3
- package/dest/client/client_execution_context.d.ts +6 -33
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +18 -54
- package/dest/client/db_oracle.d.ts +2 -2
- package/dest/client/db_oracle.d.ts.map +1 -1
- package/dest/client/execution_note_cache.d.ts +9 -1
- package/dest/client/execution_note_cache.d.ts.map +1 -1
- package/dest/client/execution_note_cache.js +10 -3
- package/dest/client/private_execution.d.ts.map +1 -1
- package/dest/client/private_execution.js +5 -7
- package/dest/client/simulator.d.ts.map +1 -1
- package/dest/client/simulator.js +4 -4
- package/dest/client/unconstrained_execution.d.ts.map +1 -1
- package/dest/client/unconstrained_execution.js +3 -3
- package/dest/client/view_data_oracle.d.ts +2 -2
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +5 -6
- package/dest/common/debug_fn_name.d.ts +2 -2
- package/dest/common/debug_fn_name.d.ts.map +1 -1
- package/dest/common/debug_fn_name.js +8 -14
- package/dest/providers/acvm_native.js +4 -4
- package/dest/providers/factory.d.ts +2 -2
- package/dest/providers/factory.d.ts.map +1 -1
- package/dest/providers/factory.js +4 -4
- package/dest/public/enqueued_call_side_effect_trace.d.ts +11 -23
- package/dest/public/enqueued_call_side_effect_trace.d.ts.map +1 -1
- package/dest/public/enqueued_call_side_effect_trace.js +51 -72
- package/dest/public/executor_metrics.d.ts.map +1 -1
- package/dest/public/executor_metrics.js +2 -5
- package/dest/public/fixtures/index.d.ts +25 -7
- package/dest/public/fixtures/index.d.ts.map +1 -1
- package/dest/public/fixtures/index.js +20 -17
- package/dest/public/index.d.ts +0 -1
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +1 -2
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +30 -16
- package/dest/public/public_processor.d.ts +7 -8
- package/dest/public/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor.js +37 -26
- package/dest/public/public_processor_metrics.d.ts +1 -1
- package/dest/public/public_processor_metrics.d.ts.map +1 -1
- package/dest/public/public_tx_context.d.ts +13 -14
- package/dest/public/public_tx_context.d.ts.map +1 -1
- package/dest/public/public_tx_context.js +63 -54
- package/dest/public/public_tx_simulator.d.ts +2 -2
- package/dest/public/public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator.js +43 -25
- package/dest/public/side_effect_trace_interface.d.ts +4 -17
- package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
- package/dest/public/transitional_adapters.d.ts +2 -6
- package/dest/public/transitional_adapters.d.ts.map +1 -1
- package/dest/public/transitional_adapters.js +29 -88
- package/package.json +16 -9
- package/src/acvm/acvm.ts +2 -2
- package/src/acvm/oracle/oracle.ts +2 -32
- package/src/acvm/oracle/typed_oracle.ts +3 -20
- package/src/acvm/serialize.ts +1 -1
- package/src/avm/avm_context.ts +2 -3
- package/src/avm/avm_execution_environment.ts +6 -31
- package/src/avm/avm_memory_types.ts +6 -6
- package/src/avm/avm_simulator.ts +28 -23
- package/src/avm/avm_tree.ts +67 -53
- package/src/avm/errors.ts +12 -14
- package/src/avm/fixtures/index.ts +2 -3
- package/src/avm/journal/journal.ts +206 -68
- package/src/avm/opcodes/environment_getters.ts +1 -4
- package/src/avm/opcodes/external_calls.ts +3 -19
- package/src/avm/opcodes/misc.ts +2 -2
- package/src/client/client_execution_context.ts +22 -68
- package/src/client/db_oracle.ts +2 -2
- package/src/client/execution_note_cache.ts +13 -3
- package/src/client/private_execution.ts +3 -7
- package/src/client/simulator.ts +4 -4
- package/src/client/unconstrained_execution.ts +2 -2
- package/src/client/view_data_oracle.ts +5 -6
- package/src/common/debug_fn_name.ts +7 -13
- package/src/providers/acvm_native.ts +3 -3
- package/src/providers/factory.ts +3 -3
- package/src/public/enqueued_call_side_effect_trace.ts +68 -90
- package/src/public/executor_metrics.ts +0 -4
- package/src/public/fixtures/index.ts +28 -17
- package/src/public/index.ts +0 -1
- package/src/public/public_db_sources.ts +32 -19
- package/src/public/public_processor.ts +52 -55
- package/src/public/public_processor_metrics.ts +1 -1
- package/src/public/public_tx_context.ts +89 -76
- package/src/public/public_tx_simulator.ts +58 -49
- package/src/public/side_effect_trace_interface.ts +8 -15
- package/src/public/transitional_adapters.ts +43 -215
- package/dest/public/dual_side_effect_trace.d.ts +0 -77
- package/dest/public/dual_side_effect_trace.d.ts.map +0 -1
- package/dest/public/dual_side_effect_trace.js +0 -119
- package/dest/public/side_effect_trace.d.ts +0 -96
- package/dest/public/side_effect_trace.d.ts.map +0 -1
- package/dest/public/side_effect_trace.js +0 -309
- package/src/public/dual_side_effect_trace.ts +0 -242
- package/src/public/side_effect_trace.ts +0 -536
package/src/avm/avm_tree.ts
CHANGED
|
@@ -17,7 +17,14 @@ import cloneDeep from 'lodash.clonedeep';
|
|
|
17
17
|
type PreimageWitness<T extends IndexedTreeLeafPreimage> = {
|
|
18
18
|
preimage: T;
|
|
19
19
|
index: bigint;
|
|
20
|
-
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The result of fetching a leaf from an indexed tree. Contains the preimage and wether the leaf was already present
|
|
24
|
+
* or it's a low leaf.
|
|
25
|
+
*/
|
|
26
|
+
type GetLeafResult<T extends IndexedTreeLeafPreimage> = PreimageWitness<T> & {
|
|
27
|
+
alreadyPresent: boolean;
|
|
21
28
|
};
|
|
22
29
|
|
|
23
30
|
/**
|
|
@@ -29,16 +36,30 @@ type LeafWitness<T extends IndexedTreeLeafPreimage> = PreimageWitness<T> & {
|
|
|
29
36
|
};
|
|
30
37
|
|
|
31
38
|
/**
|
|
32
|
-
* The result of an
|
|
39
|
+
* The result of an update in an indexed merkle tree (no new leaf inserted)
|
|
40
|
+
*/
|
|
41
|
+
type IndexedUpdateResult<T extends IndexedTreeLeafPreimage> = {
|
|
42
|
+
element: T;
|
|
43
|
+
lowWitness: LeafWitness<T>;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The result of an insertion in an indexed merkle tree.
|
|
33
48
|
* This will be used to hint the circuit
|
|
34
49
|
*/
|
|
35
|
-
export type
|
|
50
|
+
export type IndexedInsertResult<T extends IndexedTreeLeafPreimage> = IndexedUpdateResult<T> & {
|
|
36
51
|
leafIndex: bigint;
|
|
37
52
|
insertionPath: Fr[];
|
|
38
|
-
newOrElementToUpdate: { update: boolean; element: T };
|
|
39
|
-
lowWitness: LeafWitness<T>;
|
|
40
53
|
};
|
|
41
54
|
|
|
55
|
+
/**
|
|
56
|
+
* The result of an indexed upsert in an indexed merkle tree.
|
|
57
|
+
* This will be used to hint the circuit
|
|
58
|
+
*/
|
|
59
|
+
export type IndexedUpsertResult<T extends IndexedTreeLeafPreimage> =
|
|
60
|
+
| (IndexedUpdateResult<T> & { update: true })
|
|
61
|
+
| (IndexedInsertResult<T> & { update: false });
|
|
62
|
+
|
|
42
63
|
/****************************************************/
|
|
43
64
|
/****** The AvmEphemeralForest Class ****************/
|
|
44
65
|
/****************************************************/
|
|
@@ -144,7 +165,7 @@ export class AvmEphemeralForest {
|
|
|
144
165
|
* @param newValue - The value to be written or updated to
|
|
145
166
|
* @returns The insertion result which contains the insertion path, low leaf and the new leaf index
|
|
146
167
|
*/
|
|
147
|
-
async writePublicStorage(slot: Fr, newValue: Fr): Promise<
|
|
168
|
+
async writePublicStorage(slot: Fr, newValue: Fr): Promise<IndexedUpsertResult<PublicDataTreeLeafPreimage>> {
|
|
148
169
|
// This only works for the public data tree
|
|
149
170
|
const treeId = MerkleTreeId.PUBLIC_DATA_TREE;
|
|
150
171
|
const tree = this.treeMap.get(treeId)!;
|
|
@@ -152,12 +173,12 @@ export class AvmEphemeralForest {
|
|
|
152
173
|
typeof treeId,
|
|
153
174
|
PublicDataTreeLeafPreimage
|
|
154
175
|
>(treeId, slot);
|
|
155
|
-
const { preimage, index, update } = leafOrLowLeafInfo;
|
|
156
|
-
const siblingPath = await this.getSiblingPath(treeId,
|
|
176
|
+
const { preimage, index: lowLeafIndex, alreadyPresent: update } = leafOrLowLeafInfo;
|
|
177
|
+
const siblingPath = await this.getSiblingPath(treeId, lowLeafIndex);
|
|
157
178
|
|
|
158
179
|
if (pathAbsentInEphemeralTree) {
|
|
159
180
|
// Since we have never seen this before - we should insert it into our tree as it is about to be updated.
|
|
160
|
-
this.treeMap.get(treeId)!.insertSiblingPath(
|
|
181
|
+
this.treeMap.get(treeId)!.insertSiblingPath(lowLeafIndex, siblingPath);
|
|
161
182
|
}
|
|
162
183
|
|
|
163
184
|
if (update) {
|
|
@@ -165,29 +186,18 @@ export class AvmEphemeralForest {
|
|
|
165
186
|
const existingPublicDataSiblingPath = siblingPath;
|
|
166
187
|
updatedPreimage.value = newValue;
|
|
167
188
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const insertionIndex = tree.leafCount;
|
|
172
|
-
tree.updateLeaf(this.hashPreimage(updatedPreimage), index);
|
|
173
|
-
tree.appendLeaf(Fr.ZERO);
|
|
174
|
-
this.setIndexedUpdates(treeId, index, updatedPreimage);
|
|
175
|
-
this.setIndexedUpdates(treeId, insertionIndex, emptyLeaf);
|
|
176
|
-
const insertionPath = tree.getSiblingPath(insertionIndex)!;
|
|
177
|
-
|
|
178
|
-
// Even though we append an empty leaf into the tree as a part of update - it doesnt seem to impact future inserts...
|
|
179
|
-
this._updateSortedKeys(treeId, [updatedPreimage.slot], [index]);
|
|
189
|
+
tree.updateLeaf(this.hashPreimage(updatedPreimage), lowLeafIndex);
|
|
190
|
+
this.setIndexedUpdates(treeId, lowLeafIndex, updatedPreimage);
|
|
191
|
+
this._updateSortedKeys(treeId, [updatedPreimage.slot], [lowLeafIndex]);
|
|
180
192
|
|
|
181
193
|
return {
|
|
182
|
-
|
|
183
|
-
insertionPath,
|
|
184
|
-
newOrElementToUpdate: { update: true, element: updatedPreimage },
|
|
194
|
+
element: updatedPreimage,
|
|
185
195
|
lowWitness: {
|
|
186
196
|
preimage: preimage,
|
|
187
|
-
index:
|
|
188
|
-
update: true,
|
|
197
|
+
index: lowLeafIndex,
|
|
189
198
|
siblingPath: existingPublicDataSiblingPath,
|
|
190
199
|
},
|
|
200
|
+
update: true,
|
|
191
201
|
};
|
|
192
202
|
}
|
|
193
203
|
// We are writing to a new slot, so our preimage is a lowNullifier
|
|
@@ -202,22 +212,22 @@ export class AvmEphemeralForest {
|
|
|
202
212
|
new Fr(preimage.getNextKey()),
|
|
203
213
|
preimage.getNextIndex(),
|
|
204
214
|
);
|
|
205
|
-
const insertionPath = this.appendIndexedTree(treeId,
|
|
215
|
+
const insertionPath = this.appendIndexedTree(treeId, lowLeafIndex, updatedLowLeaf, newPublicDataLeaf);
|
|
206
216
|
|
|
207
217
|
// Even though the low leaf key is not updated, we still need to update the sorted keys in case we have
|
|
208
218
|
// not seen the low leaf before
|
|
209
|
-
this._updateSortedKeys(treeId, [newPublicDataLeaf.slot, updatedLowLeaf.slot], [insertionIndex,
|
|
219
|
+
this._updateSortedKeys(treeId, [newPublicDataLeaf.slot, updatedLowLeaf.slot], [insertionIndex, lowLeafIndex]);
|
|
210
220
|
|
|
211
221
|
return {
|
|
212
|
-
|
|
213
|
-
insertionPath: insertionPath,
|
|
214
|
-
newOrElementToUpdate: { update: false, element: newPublicDataLeaf },
|
|
222
|
+
element: newPublicDataLeaf,
|
|
215
223
|
lowWitness: {
|
|
216
224
|
preimage,
|
|
217
|
-
index:
|
|
218
|
-
update: false,
|
|
225
|
+
index: lowLeafIndex,
|
|
219
226
|
siblingPath,
|
|
220
227
|
},
|
|
228
|
+
update: false,
|
|
229
|
+
leafIndex: insertionIndex,
|
|
230
|
+
insertionPath: insertionPath,
|
|
221
231
|
};
|
|
222
232
|
}
|
|
223
233
|
|
|
@@ -247,14 +257,14 @@ export class AvmEphemeralForest {
|
|
|
247
257
|
* @param value - The nullifier to be appended
|
|
248
258
|
* @returns The insertion result which contains the insertion path, low leaf and the new leaf index
|
|
249
259
|
*/
|
|
250
|
-
async appendNullifier(nullifier: Fr): Promise<
|
|
260
|
+
async appendNullifier(nullifier: Fr): Promise<IndexedInsertResult<NullifierLeafPreimage>> {
|
|
251
261
|
const treeId = MerkleTreeId.NULLIFIER_TREE;
|
|
252
262
|
const tree = this.treeMap.get(treeId)!;
|
|
253
263
|
const [leafOrLowLeafInfo, pathAbsentInEphemeralTree] = await this._getLeafOrLowLeafInfo<
|
|
254
264
|
typeof treeId,
|
|
255
265
|
NullifierLeafPreimage
|
|
256
266
|
>(treeId, nullifier);
|
|
257
|
-
const { preimage, index,
|
|
267
|
+
const { preimage, index, alreadyPresent } = leafOrLowLeafInfo;
|
|
258
268
|
const siblingPath = await this.getSiblingPath(treeId, index);
|
|
259
269
|
|
|
260
270
|
if (pathAbsentInEphemeralTree) {
|
|
@@ -262,7 +272,7 @@ export class AvmEphemeralForest {
|
|
|
262
272
|
this.treeMap.get(treeId)!.insertSiblingPath(index, siblingPath);
|
|
263
273
|
}
|
|
264
274
|
|
|
265
|
-
assert(!
|
|
275
|
+
assert(!alreadyPresent, 'Nullifier already exists in the tree. Cannot update a nullifier!');
|
|
266
276
|
|
|
267
277
|
// We are writing a new entry
|
|
268
278
|
const insertionIndex = tree.leafCount;
|
|
@@ -282,15 +292,14 @@ export class AvmEphemeralForest {
|
|
|
282
292
|
);
|
|
283
293
|
|
|
284
294
|
return {
|
|
285
|
-
|
|
286
|
-
insertionPath: insertionPath,
|
|
287
|
-
newOrElementToUpdate: { update: false, element: newNullifierLeaf },
|
|
295
|
+
element: newNullifierLeaf,
|
|
288
296
|
lowWitness: {
|
|
289
297
|
preimage,
|
|
290
298
|
index,
|
|
291
|
-
update,
|
|
292
299
|
siblingPath,
|
|
293
300
|
},
|
|
301
|
+
leafIndex: insertionIndex,
|
|
302
|
+
insertionPath: insertionPath,
|
|
294
303
|
};
|
|
295
304
|
}
|
|
296
305
|
|
|
@@ -360,7 +369,7 @@ export class AvmEphemeralForest {
|
|
|
360
369
|
async getLeafOrLowLeafInfo<ID extends IndexedTreeId, T extends IndexedTreeLeafPreimage>(
|
|
361
370
|
treeId: ID,
|
|
362
371
|
key: Fr,
|
|
363
|
-
): Promise<
|
|
372
|
+
): Promise<GetLeafResult<T>> {
|
|
364
373
|
const [leafOrLowLeafInfo, _] = await this._getLeafOrLowLeafInfo<ID, T>(treeId, key);
|
|
365
374
|
return leafOrLowLeafInfo;
|
|
366
375
|
}
|
|
@@ -373,14 +382,14 @@ export class AvmEphemeralForest {
|
|
|
373
382
|
* @param key - The key for which we are look up the leaf or low leaf for.
|
|
374
383
|
* @param T - The type of the preimage (PublicData or Nullifier)
|
|
375
384
|
* @returns [
|
|
376
|
-
*
|
|
385
|
+
* getLeafResult - The leaf or low leaf info (preimage & leaf index),
|
|
377
386
|
* pathAbsentInEphemeralTree - whether its sibling path is absent in the ephemeral tree (useful during insertions)
|
|
378
387
|
* ]
|
|
379
388
|
*/
|
|
380
389
|
async _getLeafOrLowLeafInfo<ID extends IndexedTreeId, T extends IndexedTreeLeafPreimage>(
|
|
381
390
|
treeId: ID,
|
|
382
391
|
key: Fr,
|
|
383
|
-
): Promise<[
|
|
392
|
+
): Promise<[GetLeafResult<T>, /*pathAbsentInEphemeralTree=*/ boolean]> {
|
|
384
393
|
const bigIntKey = key.toBigInt();
|
|
385
394
|
// In this function, "min" refers to the leaf with the
|
|
386
395
|
// largest key <= the specified key in the indexedUpdates.
|
|
@@ -392,7 +401,7 @@ export class AvmEphemeralForest {
|
|
|
392
401
|
if (minIndexedLeafIndex === -1n) {
|
|
393
402
|
// No leaf is present in the indexed updates that is <= the key,
|
|
394
403
|
// so retrieve the leaf or low leaf from the underlying DB.
|
|
395
|
-
const leafOrLowLeafPreimage:
|
|
404
|
+
const leafOrLowLeafPreimage: GetLeafResult<T> = await this._getLeafOrLowLeafWitnessInExternalDb(
|
|
396
405
|
treeId,
|
|
397
406
|
bigIntKey,
|
|
398
407
|
);
|
|
@@ -402,7 +411,7 @@ export class AvmEphemeralForest {
|
|
|
402
411
|
const minPreimage: T = this.getIndexedUpdate(treeId, minIndexedLeafIndex);
|
|
403
412
|
if (minPreimage.getKey() === bigIntKey) {
|
|
404
413
|
// the index found is an exact match, no need to search further
|
|
405
|
-
const leafInfo = { preimage: minPreimage, index: minIndexedLeafIndex,
|
|
414
|
+
const leafInfo = { preimage: minPreimage, index: minIndexedLeafIndex, alreadyPresent: true };
|
|
406
415
|
return [leafInfo, /*pathAbsentInEphemeralTree=*/ false];
|
|
407
416
|
} else {
|
|
408
417
|
// We are starting with the leaf with largest key <= the specified key
|
|
@@ -453,7 +462,7 @@ export class AvmEphemeralForest {
|
|
|
453
462
|
private async _getLeafOrLowLeafWitnessInExternalDb<ID extends IndexedTreeId, T extends IndexedTreeLeafPreimage>(
|
|
454
463
|
treeId: ID,
|
|
455
464
|
key: bigint,
|
|
456
|
-
): Promise<
|
|
465
|
+
): Promise<GetLeafResult<T>> {
|
|
457
466
|
// "key" is siloed slot (leafSlot) or siloed nullifier
|
|
458
467
|
const previousValueIndex = await this.treeDb.getPreviousValueIndex(treeId, key);
|
|
459
468
|
assert(
|
|
@@ -468,7 +477,7 @@ export class AvmEphemeralForest {
|
|
|
468
477
|
`${MerkleTreeId[treeId]} low leaf preimage should never be undefined (even if target leaf does not exist)`,
|
|
469
478
|
);
|
|
470
479
|
|
|
471
|
-
return { preimage: leafPreimage as T, index: leafIndex,
|
|
480
|
+
return { preimage: leafPreimage as T, index: leafIndex, alreadyPresent };
|
|
472
481
|
}
|
|
473
482
|
|
|
474
483
|
/**
|
|
@@ -481,7 +490,7 @@ export class AvmEphemeralForest {
|
|
|
481
490
|
* @param minIndex - The index of the leaf with the largest key <= the specified key.
|
|
482
491
|
* @param T - The type of the preimage (PublicData or Nullifier)
|
|
483
492
|
* @returns [
|
|
484
|
-
*
|
|
493
|
+
* GetLeafResult | undefined - The leaf or low leaf info (preimage & leaf index),
|
|
485
494
|
* pathAbsentInEphemeralTree - whether its sibling path is absent in the ephemeral tree (useful during insertions)
|
|
486
495
|
* ]
|
|
487
496
|
*
|
|
@@ -497,10 +506,10 @@ export class AvmEphemeralForest {
|
|
|
497
506
|
key: bigint,
|
|
498
507
|
minPreimage: T,
|
|
499
508
|
minIndex: bigint,
|
|
500
|
-
): Promise<[
|
|
509
|
+
): Promise<[GetLeafResult<T> | undefined, /*pathAbsentInEphemeralTree=*/ boolean]> {
|
|
501
510
|
let found = false;
|
|
502
511
|
let curr = minPreimage as T;
|
|
503
|
-
let result:
|
|
512
|
+
let result: GetLeafResult<T> | undefined = undefined;
|
|
504
513
|
// Temp to avoid infinite loops - the limit is the number of leaves we may have to read
|
|
505
514
|
const LIMIT = 2n ** BigInt(getTreeHeight(treeId)) - 1n;
|
|
506
515
|
let counter = 0n;
|
|
@@ -511,11 +520,11 @@ export class AvmEphemeralForest {
|
|
|
511
520
|
if (curr.getKey() === bigIntKey) {
|
|
512
521
|
// We found an exact match - therefore this is an update
|
|
513
522
|
found = true;
|
|
514
|
-
result = { preimage: curr, index: lowPublicDataIndex,
|
|
523
|
+
result = { preimage: curr, index: lowPublicDataIndex, alreadyPresent: true };
|
|
515
524
|
} else if (curr.getKey() < bigIntKey && (curr.getNextIndex() === 0n || curr.getNextKey() > bigIntKey)) {
|
|
516
525
|
// We found it via sandwich or max condition, this is a low nullifier
|
|
517
526
|
found = true;
|
|
518
|
-
result = { preimage: curr, index: lowPublicDataIndex,
|
|
527
|
+
result = { preimage: curr, index: lowPublicDataIndex, alreadyPresent: false };
|
|
519
528
|
}
|
|
520
529
|
// Update the the values for the next iteration
|
|
521
530
|
else {
|
|
@@ -671,7 +680,12 @@ export class EphemeralAvmTree {
|
|
|
671
680
|
for (let i = 0; i < siblingPath.length; i++) {
|
|
672
681
|
// Flip(XOR) the last bit because we are inserting siblings of the leaf
|
|
673
682
|
const sibIndex = index ^ 1n;
|
|
674
|
-
this.
|
|
683
|
+
const node = this.getNode(sibIndex, this.depth - i);
|
|
684
|
+
// If we are inserting a sibling path and we already have a branch at that index in our
|
|
685
|
+
// ephemeral tree, we should not overwrite it
|
|
686
|
+
if (node === undefined || node.tag === TreeType.LEAF) {
|
|
687
|
+
this.updateLeaf(siblingPath[i], sibIndex, this.depth - i);
|
|
688
|
+
}
|
|
675
689
|
index >>= 1n;
|
|
676
690
|
}
|
|
677
691
|
}
|
package/src/avm/errors.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type FailingFunction, type NoirCallStack } from '@aztec/circuit-types';
|
|
2
|
-
import { type AztecAddress, Fr
|
|
2
|
+
import { type AztecAddress, type Fr } from '@aztec/circuits.js';
|
|
3
3
|
|
|
4
4
|
import { ExecutionError } from '../common/errors.js';
|
|
5
5
|
import { type AvmContext } from './avm_context.js';
|
|
@@ -138,16 +138,9 @@ export class AvmRevertReason extends ExecutionError {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
function createRevertReason(message: string, revertData: Fr[], context: AvmContext): AvmRevertReason {
|
|
142
|
-
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Properly fix this.
|
|
143
|
-
// If the function selector is the public dispatch selector, we need to extract the actual function selector from the calldata.
|
|
144
|
-
// We should remove this because the AVM (or public protocol) shouldn't be aware of the public dispatch calling convention.
|
|
145
|
-
let functionSelector = context.environment.functionSelector;
|
|
141
|
+
async function createRevertReason(message: string, revertData: Fr[], context: AvmContext): Promise<AvmRevertReason> {
|
|
146
142
|
// We drop the returnPc information.
|
|
147
143
|
const internalCallStack = context.machineState.internalCallStack.map(entry => entry.callPc);
|
|
148
|
-
if (functionSelector.toField().equals(new Fr(PUBLIC_DISPATCH_SELECTOR)) && context.environment.calldata.length > 0) {
|
|
149
|
-
functionSelector = FunctionSelector.fromField(context.environment.calldata[0]);
|
|
150
|
-
}
|
|
151
144
|
|
|
152
145
|
// If we are reverting due to the same error that we have been tracking, we use the nested error as the cause.
|
|
153
146
|
let nestedError = undefined;
|
|
@@ -160,11 +153,13 @@ function createRevertReason(message: string, revertData: Fr[], context: AvmConte
|
|
|
160
153
|
message = context.machineState.collectedRevertInfo.recursiveRevertReason.message;
|
|
161
154
|
}
|
|
162
155
|
|
|
156
|
+
const fnName = await context.persistableState.getPublicFunctionDebugName(context.environment);
|
|
157
|
+
|
|
163
158
|
return new AvmRevertReason(
|
|
164
159
|
message,
|
|
165
160
|
/*failingFunction=*/ {
|
|
166
161
|
contractAddress: context.environment.address,
|
|
167
|
-
|
|
162
|
+
functionName: fnName,
|
|
168
163
|
},
|
|
169
164
|
/*noirCallStack=*/ [...internalCallStack, context.machineState.pc].map(pc => `0.${pc}`),
|
|
170
165
|
/*options=*/ { cause: nestedError },
|
|
@@ -177,8 +172,11 @@ function createRevertReason(message: string, revertData: Fr[], context: AvmConte
|
|
|
177
172
|
* @param haltingError - the lower-level error causing the exceptional halt
|
|
178
173
|
* @param context - the context of the AVM execution used to extract the failingFunction and noirCallStack
|
|
179
174
|
*/
|
|
180
|
-
export function revertReasonFromExceptionalHalt(
|
|
181
|
-
|
|
175
|
+
export async function revertReasonFromExceptionalHalt(
|
|
176
|
+
haltingError: AvmExecutionError,
|
|
177
|
+
context: AvmContext,
|
|
178
|
+
): Promise<AvmRevertReason> {
|
|
179
|
+
return await createRevertReason(haltingError.message, [], context);
|
|
182
180
|
}
|
|
183
181
|
|
|
184
182
|
/**
|
|
@@ -187,6 +185,6 @@ export function revertReasonFromExceptionalHalt(haltingError: AvmExecutionError,
|
|
|
187
185
|
* @param revertData - output data of the explicit REVERT instruction
|
|
188
186
|
* @param context - the context of the AVM execution used to extract the failingFunction and noirCallStack
|
|
189
187
|
*/
|
|
190
|
-
export function revertReasonFromExplicitRevert(revertData: Fr[], context: AvmContext): AvmRevertReason {
|
|
191
|
-
return createRevertReason('Assertion failed: ', revertData, context);
|
|
188
|
+
export async function revertReasonFromExplicitRevert(revertData: Fr[], context: AvmContext): Promise<AvmRevertReason> {
|
|
189
|
+
return await createRevertReason('Assertion failed: ', revertData, context);
|
|
192
190
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isNoirCallStackUnresolved } from '@aztec/circuit-types';
|
|
2
|
-
import { GasFees, GlobalVariables,
|
|
2
|
+
import { GasFees, GlobalVariables, MAX_L2_GAS_PER_TX_PUBLIC_PORTION } from '@aztec/circuits.js';
|
|
3
3
|
import { type FunctionArtifact, FunctionSelector } from '@aztec/foundation/abi';
|
|
4
4
|
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
5
5
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
@@ -64,7 +64,6 @@ export function initExecutionEnvironment(overrides?: Partial<AvmExecutionEnviron
|
|
|
64
64
|
return new AvmExecutionEnvironment(
|
|
65
65
|
overrides?.address ?? AztecAddress.zero(),
|
|
66
66
|
overrides?.sender ?? AztecAddress.zero(),
|
|
67
|
-
overrides?.functionSelector ?? FunctionSelector.empty(),
|
|
68
67
|
overrides?.contractCallDepth ?? Fr.zero(),
|
|
69
68
|
overrides?.transactionFee ?? Fr.zero(),
|
|
70
69
|
overrides?.globals ?? GlobalVariables.empty(),
|
|
@@ -94,7 +93,7 @@ export function initGlobalVariables(overrides?: Partial<GlobalVariables>): Globa
|
|
|
94
93
|
*/
|
|
95
94
|
export function initMachineState(overrides?: Partial<AvmMachineState>): AvmMachineState {
|
|
96
95
|
return AvmMachineState.fromState({
|
|
97
|
-
l2GasLeft: overrides?.l2GasLeft ??
|
|
96
|
+
l2GasLeft: overrides?.l2GasLeft ?? MAX_L2_GAS_PER_TX_PUBLIC_PORTION,
|
|
98
97
|
daGasLeft: overrides?.daGasLeft ?? 1e8,
|
|
99
98
|
});
|
|
100
99
|
}
|