@aztec/simulator 0.76.1 → 0.76.3
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/oracle/oracle.d.ts +4 -5
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +9 -16
- package/dest/acvm/oracle/typed_oracle.d.ts +4 -5
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +9 -12
- package/dest/avm/avm_simulator.js +2 -2
- package/dest/avm/avm_tree.d.ts +1 -0
- package/dest/avm/avm_tree.d.ts.map +1 -1
- package/dest/avm/avm_tree.js +19 -7
- package/dest/avm/journal/journal.js +23 -23
- package/dest/client/db_oracle.d.ts +12 -15
- package/dest/client/db_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.d.ts +4 -10
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +9 -17
- package/dest/public/public_tx_context.js +3 -3
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +14 -14
- package/package.json +12 -12
- package/src/acvm/oracle/oracle.ts +9 -17
- package/src/acvm/oracle/typed_oracle.ts +8 -12
- package/src/avm/avm_simulator.ts +1 -1
- package/src/avm/avm_tree.ts +22 -6
- package/src/avm/journal/journal.ts +23 -23
- package/src/client/db_oracle.ts +12 -16
- package/src/client/view_data_oracle.ts +13 -17
- package/src/public/public_tx_context.ts +2 -2
- package/src/public/side_effect_trace.ts +13 -13
package/src/client/db_oracle.ts
CHANGED
|
@@ -64,13 +64,6 @@ export interface DBOracle extends CommitmentsDB {
|
|
|
64
64
|
*/
|
|
65
65
|
getAuthWitness(messageHash: Fr): Promise<Fr[]>;
|
|
66
66
|
|
|
67
|
-
/**
|
|
68
|
-
* Retrieve a capsule from the capsule dispenser.
|
|
69
|
-
* @returns A promise that resolves to an array of field elements representing the capsule.
|
|
70
|
-
* @remarks A capsule is a "blob" of data that is passed to the contract through an oracle.
|
|
71
|
-
*/
|
|
72
|
-
popCapsule(): Promise<Fr[]>;
|
|
73
|
-
|
|
74
67
|
/**
|
|
75
68
|
* Retrieve keys associated with a specific master public key and app address.
|
|
76
69
|
* @param pkMHash - The master public key hash.
|
|
@@ -263,32 +256,35 @@ export interface DBOracle extends CommitmentsDB {
|
|
|
263
256
|
removeNullifiedNotes(contractAddress: AztecAddress): Promise<void>;
|
|
264
257
|
|
|
265
258
|
/**
|
|
266
|
-
* Stores arbitrary information in a per-contract non-volatile database, which can later be retrieved with `
|
|
267
|
-
* * If data was already stored at this slot, it is
|
|
259
|
+
* Stores arbitrary information in a per-contract non-volatile database, which can later be retrieved with `loadCapsule`.
|
|
260
|
+
* * If data was already stored at this slot, it is overwritten.
|
|
268
261
|
* @param contractAddress - The contract address to scope the data under.
|
|
269
262
|
* @param slot - The slot in the database in which to store the value. Slots need not be contiguous.
|
|
270
|
-
* @param
|
|
263
|
+
* @param capsule - An array of field elements representing the capsule.
|
|
264
|
+
* @remarks A capsule is a "blob" of data that is passed to the contract through an oracle. It works similarly
|
|
265
|
+
* to public contract storage in that it's indexed by the contract address and storage slot but instead of the global
|
|
266
|
+
* network state it's backed by local PXE db.
|
|
271
267
|
*/
|
|
272
|
-
|
|
268
|
+
storeCapsule(contractAddress: AztecAddress, slot: Fr, capsule: Fr[]): Promise<void>;
|
|
273
269
|
|
|
274
270
|
/**
|
|
275
|
-
* Returns data previously stored via `
|
|
271
|
+
* Returns data previously stored via `storeCapsule` in the per-contract non-volatile database.
|
|
276
272
|
* @param contractAddress - The contract address under which the data is scoped.
|
|
277
273
|
* @param slot - The slot in the database to read.
|
|
278
274
|
* @returns The stored data or `null` if no data is stored under the slot.
|
|
279
275
|
*/
|
|
280
|
-
|
|
276
|
+
loadCapsule(contractAddress: AztecAddress, slot: Fr): Promise<Fr[] | null>;
|
|
281
277
|
|
|
282
278
|
/**
|
|
283
279
|
* Deletes data in the per-contract non-volatile database. Does nothing if no data was present.
|
|
284
280
|
* @param contractAddress - The contract address under which the data is scoped.
|
|
285
281
|
* @param slot - The slot in the database to delete.
|
|
286
282
|
*/
|
|
287
|
-
|
|
283
|
+
deleteCapsule(contractAddress: AztecAddress, slot: Fr): Promise<void>;
|
|
288
284
|
|
|
289
285
|
/**
|
|
290
286
|
* Copies a number of contiguous entries in the per-contract non-volatile database. This allows for efficient data
|
|
291
|
-
* structures by avoiding repeated calls to `
|
|
287
|
+
* structures by avoiding repeated calls to `loadCapsule` and `storeCapsule`.
|
|
292
288
|
* Supports overlapping source and destination regions (which will result in the overlapped source values being
|
|
293
289
|
* overwritten). All copied slots must exist in the database (i.e. have been stored and not deleted)
|
|
294
290
|
*
|
|
@@ -297,5 +293,5 @@ export interface DBOracle extends CommitmentsDB {
|
|
|
297
293
|
* @param dstSlot - The first slot to copy to.
|
|
298
294
|
* @param numEntries - The number of entries to copy.
|
|
299
295
|
*/
|
|
300
|
-
|
|
296
|
+
copyCapsule(contractAddress: AztecAddress, srcSlot: Fr, dstSlot: Fr, numEntries: number): Promise<void>;
|
|
301
297
|
}
|
|
@@ -162,15 +162,6 @@ export class ViewDataOracle extends TypedOracle {
|
|
|
162
162
|
);
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
/**
|
|
166
|
-
* Pops a capsule from the capsule dispenser
|
|
167
|
-
* @returns The capsule values
|
|
168
|
-
* @remarks A capsule is a "blob" of data that is passed to the contract through an oracle.
|
|
169
|
-
*/
|
|
170
|
-
public override popCapsule(): Promise<Fr[]> {
|
|
171
|
-
return this.db.popCapsule();
|
|
172
|
-
}
|
|
173
|
-
|
|
174
165
|
/**
|
|
175
166
|
* Gets some notes for a contract address and storage slot.
|
|
176
167
|
* Returns a flattened array containing filtered notes.
|
|
@@ -328,35 +319,40 @@ export class ViewDataOracle extends TypedOracle {
|
|
|
328
319
|
await this.db.deliverNote(contractAddress, storageSlot, nonce, content, noteHash, nullifier, txHash, recipient);
|
|
329
320
|
}
|
|
330
321
|
|
|
331
|
-
public override
|
|
322
|
+
public override storeCapsule(contractAddress: AztecAddress, slot: Fr, capsule: Fr[]): Promise<void> {
|
|
332
323
|
if (!contractAddress.equals(this.contractAddress)) {
|
|
333
324
|
// TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
|
|
334
325
|
throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
|
|
335
326
|
}
|
|
336
|
-
return this.db.
|
|
327
|
+
return this.db.storeCapsule(this.contractAddress, slot, capsule);
|
|
337
328
|
}
|
|
338
329
|
|
|
339
|
-
public override
|
|
330
|
+
public override loadCapsule(contractAddress: AztecAddress, slot: Fr): Promise<Fr[] | null> {
|
|
340
331
|
if (!contractAddress.equals(this.contractAddress)) {
|
|
341
332
|
// TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
|
|
342
333
|
throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
|
|
343
334
|
}
|
|
344
|
-
return this.db.
|
|
335
|
+
return this.db.loadCapsule(this.contractAddress, slot);
|
|
345
336
|
}
|
|
346
337
|
|
|
347
|
-
public override
|
|
338
|
+
public override deleteCapsule(contractAddress: AztecAddress, slot: Fr): Promise<void> {
|
|
348
339
|
if (!contractAddress.equals(this.contractAddress)) {
|
|
349
340
|
// TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
|
|
350
341
|
throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
|
|
351
342
|
}
|
|
352
|
-
return this.db.
|
|
343
|
+
return this.db.deleteCapsule(this.contractAddress, slot);
|
|
353
344
|
}
|
|
354
345
|
|
|
355
|
-
public override
|
|
346
|
+
public override copyCapsule(
|
|
347
|
+
contractAddress: AztecAddress,
|
|
348
|
+
srcSlot: Fr,
|
|
349
|
+
dstSlot: Fr,
|
|
350
|
+
numEntries: number,
|
|
351
|
+
): Promise<void> {
|
|
356
352
|
if (!contractAddress.equals(this.contractAddress)) {
|
|
357
353
|
// TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
|
|
358
354
|
throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
|
|
359
355
|
}
|
|
360
|
-
return this.db.
|
|
356
|
+
return this.db.copyCapsule(this.contractAddress, srcSlot, dstSlot, numEntries);
|
|
361
357
|
}
|
|
362
358
|
}
|
|
@@ -162,7 +162,7 @@ export class PublicTxContext {
|
|
|
162
162
|
* NOTE: this does not "halt" the entire transaction execution.
|
|
163
163
|
*/
|
|
164
164
|
revert(phase: TxExecutionPhase, revertReason: SimulationError | undefined = undefined, culprit = '') {
|
|
165
|
-
this.log.
|
|
165
|
+
this.log.warn(`${TxExecutionPhase[phase]} phase reverted! ${culprit} failed with reason: ${revertReason}`);
|
|
166
166
|
|
|
167
167
|
if (revertReason && !this.revertReason) {
|
|
168
168
|
// don't override revertReason
|
|
@@ -170,7 +170,7 @@ export class PublicTxContext {
|
|
|
170
170
|
this.revertReason = revertReason;
|
|
171
171
|
}
|
|
172
172
|
if (phase === TxExecutionPhase.SETUP) {
|
|
173
|
-
this.log.
|
|
173
|
+
this.log.warn(`Setup phase reverted! The transaction will be thrown out.`);
|
|
174
174
|
if (revertReason) {
|
|
175
175
|
throw revertReason;
|
|
176
176
|
} else {
|
|
@@ -127,7 +127,6 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
127
127
|
/** We need to track the set of class IDs used for bytecode retrieval to deduplicate and enforce limits. */
|
|
128
128
|
private gotBytecodeFromClassIds: UniqueClassIds = new UniqueClassIds(),
|
|
129
129
|
) {
|
|
130
|
-
this.log.debug(`Creating trace instance with startSideEffectCounter: ${startSideEffectCounter}`);
|
|
131
130
|
this.sideEffectCounter = startSideEffectCounter;
|
|
132
131
|
this.avmCircuitHints = AvmExecutionHints.empty();
|
|
133
132
|
}
|
|
@@ -215,7 +214,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
215
214
|
path: Fr[] = emptyPublicDataPath(),
|
|
216
215
|
) {
|
|
217
216
|
this.avmCircuitHints.publicDataReads.items.push(new AvmPublicDataReadTreeHint(leafPreimage, leafIndex, path));
|
|
218
|
-
this.log.
|
|
217
|
+
this.log.trace(
|
|
219
218
|
`Tracing storage read (address=${contractAddress}, slot=${slot}): value=${value} (counter=${this.sideEffectCounter})`,
|
|
220
219
|
);
|
|
221
220
|
this.incrementSideEffectCounter();
|
|
@@ -265,7 +264,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
265
264
|
new AvmPublicDataWriteTreeHint(readHint, newLeafPreimage, insertionPath),
|
|
266
265
|
);
|
|
267
266
|
|
|
268
|
-
this.log.
|
|
267
|
+
this.log.trace(
|
|
269
268
|
`Traced public data write (address=${contractAddress}, slot=${slot}): value=${value} (counter=${this.sideEffectCounter}, isProtocol:${protocolWrite})`,
|
|
270
269
|
);
|
|
271
270
|
this.incrementSideEffectCounter();
|
|
@@ -282,6 +281,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
282
281
|
// New Hinting
|
|
283
282
|
this.avmCircuitHints.noteHashReads.items.push(new AvmAppendTreeHint(leafIndex, noteHash, path));
|
|
284
283
|
// NOTE: counter does not increment for note hash checks (because it doesn't rely on pending note hashes)
|
|
284
|
+
this.log.trace(`Tracing note hash check (counter=${this.sideEffectCounter})`);
|
|
285
285
|
}
|
|
286
286
|
|
|
287
287
|
public traceNewNoteHash(noteHash: Fr, leafIndex: Fr = Fr.zero(), path: Fr[] = emptyNoteHashPath()) {
|
|
@@ -290,8 +290,8 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
290
290
|
}
|
|
291
291
|
|
|
292
292
|
this.noteHashes.push(new NoteHash(noteHash, this.sideEffectCounter));
|
|
293
|
-
this.log.debug(`NEW_NOTE_HASH cnt: ${this.sideEffectCounter}`);
|
|
294
293
|
this.avmCircuitHints.noteHashWrites.items.push(new AvmAppendTreeHint(leafIndex, noteHash, path));
|
|
294
|
+
this.log.trace(`Tracing new note hash (counter=${this.sideEffectCounter})`);
|
|
295
295
|
this.incrementSideEffectCounter();
|
|
296
296
|
}
|
|
297
297
|
|
|
@@ -305,7 +305,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
305
305
|
this.avmCircuitHints.nullifierReads.items.push(
|
|
306
306
|
new AvmNullifierReadTreeHint(lowLeafPreimage, lowLeafIndex, lowLeafPath),
|
|
307
307
|
);
|
|
308
|
-
this.log.
|
|
308
|
+
this.log.trace(`Tracing nullifier check (counter=${this.sideEffectCounter})`);
|
|
309
309
|
this.incrementSideEffectCounter();
|
|
310
310
|
}
|
|
311
311
|
|
|
@@ -324,7 +324,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
324
324
|
|
|
325
325
|
const lowLeafReadHint = new AvmNullifierReadTreeHint(lowLeafPreimage, lowLeafIndex, lowLeafPath);
|
|
326
326
|
this.avmCircuitHints.nullifierWrites.items.push(new AvmNullifierWriteTreeHint(lowLeafReadHint, insertionPath));
|
|
327
|
-
this.log.
|
|
327
|
+
this.log.trace(`Tracing new nullifier (counter=${this.sideEffectCounter})`);
|
|
328
328
|
this.incrementSideEffectCounter();
|
|
329
329
|
}
|
|
330
330
|
|
|
@@ -337,6 +337,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
337
337
|
path: Fr[] = emptyL1ToL2MessagePath(),
|
|
338
338
|
) {
|
|
339
339
|
this.avmCircuitHints.l1ToL2MessageReads.items.push(new AvmAppendTreeHint(msgLeafIndex, msgHash, path));
|
|
340
|
+
this.log.trace(`Tracing l1 to l2 message check (counter=${this.sideEffectCounter})`);
|
|
340
341
|
}
|
|
341
342
|
|
|
342
343
|
public traceNewL2ToL1Message(contractAddress: AztecAddress, recipient: Fr, content: Fr) {
|
|
@@ -348,7 +349,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
348
349
|
this.l2ToL1Messages.push(
|
|
349
350
|
new L2ToL1Message(recipientAddress, content, this.sideEffectCounter).scope(contractAddress),
|
|
350
351
|
);
|
|
351
|
-
this.log.
|
|
352
|
+
this.log.trace(`Tracing new l2 to l1 message (counter=${this.sideEffectCounter})`);
|
|
352
353
|
this.incrementSideEffectCounter();
|
|
353
354
|
}
|
|
354
355
|
|
|
@@ -362,7 +363,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
362
363
|
}
|
|
363
364
|
const publicLog = new PublicLog(contractAddress, padArrayEnd(log, Fr.ZERO, PUBLIC_LOG_DATA_SIZE_IN_FIELDS));
|
|
364
365
|
this.publicLogs.push(publicLog);
|
|
365
|
-
this.log.
|
|
366
|
+
this.log.trace(`Tracing new public log (counter=${this.sideEffectCounter})`);
|
|
366
367
|
this.incrementSideEffectCounter();
|
|
367
368
|
}
|
|
368
369
|
|
|
@@ -387,7 +388,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
387
388
|
membershipHint,
|
|
388
389
|
),
|
|
389
390
|
);
|
|
390
|
-
this.log.
|
|
391
|
+
this.log.trace(`Tracing contract instance retrieval (counter=${this.sideEffectCounter})`);
|
|
391
392
|
this.incrementSideEffectCounter();
|
|
392
393
|
}
|
|
393
394
|
|
|
@@ -432,7 +433,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
432
433
|
// Since the bytecode hints are keyed by class ID, we need to hint the instance separately
|
|
433
434
|
// since there might be multiple instances hinted for the same class ID.
|
|
434
435
|
this.avmCircuitHints.contractInstances.items.push(instance);
|
|
435
|
-
this.log.
|
|
436
|
+
this.log.trace(
|
|
436
437
|
`Tracing contract instance for bytecode retrieval: exists=${exists}, instance=${jsonStringify(contractInstance)}`,
|
|
437
438
|
);
|
|
438
439
|
|
|
@@ -447,7 +448,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
447
448
|
// To do so, the circuit needs to know the class ID in the
|
|
448
449
|
if (this.gotBytecodeFromClassIds.has(contractInstance.contractClassId.toString())) {
|
|
449
450
|
// this ensures there are no duplicates
|
|
450
|
-
this.log.
|
|
451
|
+
this.log.trace(
|
|
451
452
|
`Contract class id ${contractInstance.contractClassId.toString()} already exists in previous hints`,
|
|
452
453
|
);
|
|
453
454
|
return;
|
|
@@ -470,7 +471,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
470
471
|
);
|
|
471
472
|
}
|
|
472
473
|
|
|
473
|
-
this.log.
|
|
474
|
+
this.log.trace(`Tracing bytecode & contract class for bytecode retrieval: class=${jsonStringify(contractClass)}`);
|
|
474
475
|
this.avmCircuitHints.contractBytecodeHints.set(
|
|
475
476
|
contractInstance.contractClassId.toString(),
|
|
476
477
|
new AvmContractBytecodeHints(bytecode, instance, contractClass),
|
|
@@ -492,7 +493,6 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
492
493
|
/** Did the call revert? */
|
|
493
494
|
_reverted: boolean,
|
|
494
495
|
) {
|
|
495
|
-
this.log.debug(`Tracing enqueued call`);
|
|
496
496
|
// TODO(4805): check if some threshold is reached for max enqueued or nested calls (to unique contracts?)
|
|
497
497
|
this.enqueuedCalls.push(publicCallRequest);
|
|
498
498
|
this.avmCircuitHints.enqueuedCalls.items.push(new AvmEnqueuedCallHint(publicCallRequest.contractAddress, calldata));
|