@aztec/simulator 0.85.0 → 0.86.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/private/providers/acvm_native.d.ts +1 -1
- package/dest/private/providers/acvm_native.d.ts.map +1 -1
- package/dest/private/providers/acvm_native.js +4 -3
- package/dest/private/providers/acvm_wasm.d.ts +2 -1
- package/dest/private/providers/acvm_wasm.d.ts.map +1 -1
- package/dest/private/providers/acvm_wasm.js +6 -1
- package/dest/private/providers/acvm_wasm_with_blobs.d.ts +2 -1
- package/dest/private/providers/acvm_wasm_with_blobs.d.ts.map +1 -1
- package/dest/private/providers/acvm_wasm_with_blobs.js +6 -1
- package/dest/private/providers/circuit_recording/simulation_provider_recorder_wrapper.d.ts +2 -1
- package/dest/private/providers/circuit_recording/simulation_provider_recorder_wrapper.d.ts.map +1 -1
- package/dest/private/providers/simulation_provider.d.ts +2 -1
- package/dest/private/providers/simulation_provider.d.ts.map +1 -1
- package/dest/public/avm/avm_context.d.ts +2 -2
- package/dest/public/avm/avm_context.d.ts.map +1 -1
- package/dest/public/avm/avm_simulator.d.ts +2 -1
- package/dest/public/avm/avm_simulator.d.ts.map +1 -1
- package/dest/public/avm/avm_simulator.js +2 -1
- package/dest/public/avm/avm_simulator_interface.d.ts +11 -0
- package/dest/public/avm/avm_simulator_interface.d.ts.map +1 -0
- package/dest/public/avm/avm_simulator_interface.js +3 -0
- package/dest/public/avm/errors.d.ts +1 -16
- package/dest/public/avm/errors.d.ts.map +1 -1
- package/dest/public/avm/errors.js +0 -37
- package/dest/public/avm/fixtures/avm_simulation_tester.d.ts +1 -1
- package/dest/public/avm/fixtures/avm_simulation_tester.d.ts.map +1 -1
- package/dest/public/avm/fixtures/avm_simulation_tester.js +1 -1
- package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts +1 -1
- package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts.map +1 -1
- package/dest/public/avm/fixtures/index.d.ts +2 -85
- package/dest/public/avm/fixtures/index.d.ts.map +1 -1
- package/dest/public/avm/fixtures/index.js +2 -174
- package/dest/public/avm/fixtures/initializers.d.ts +42 -0
- package/dest/public/avm/fixtures/initializers.d.ts.map +1 -0
- package/dest/public/avm/fixtures/initializers.js +42 -0
- package/dest/public/avm/fixtures/utils.d.ts +46 -0
- package/dest/public/avm/fixtures/utils.d.ts.map +1 -0
- package/dest/public/avm/fixtures/utils.js +136 -0
- package/dest/public/avm/index.d.ts +0 -1
- package/dest/public/avm/index.d.ts.map +1 -1
- package/dest/public/avm/index.js +0 -1
- package/dest/public/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/public/avm/opcodes/accrued_substate.js +1 -1
- package/dest/public/avm/opcodes/external_calls.d.ts +3 -2
- package/dest/public/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/public/avm/opcodes/external_calls.js +14 -9
- package/dest/public/avm/opcodes/instruction.d.ts +5 -5
- package/dest/public/avm/opcodes/instruction.d.ts.map +1 -1
- package/dest/public/avm/opcodes/instruction.js +6 -6
- package/dest/public/avm/revert_reason.d.ts +18 -0
- package/dest/public/avm/revert_reason.d.ts.map +1 -0
- package/dest/public/avm/revert_reason.js +38 -0
- package/dest/public/avm/serialization/bytecode_serialization.d.ts +2 -4
- package/dest/public/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/public/avm/serialization/bytecode_serialization.js +70 -69
- package/dest/{common → public}/debug_fn_name.d.ts +1 -1
- package/dest/{common → public}/debug_fn_name.d.ts.map +1 -1
- package/dest/public/fixtures/index.d.ts +1 -0
- package/dest/public/fixtures/index.d.ts.map +1 -1
- package/dest/public/fixtures/index.js +1 -0
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts +1 -1
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
- package/dest/public/fixtures/public_tx_simulation_tester.js +3 -4
- package/dest/public/fixtures/simple_contract_data_source.d.ts.map +1 -0
- package/dest/public/{avm/fixtures → fixtures}/simple_contract_data_source.js +1 -1
- package/dest/public/hinting_db_sources.d.ts +15 -5
- package/dest/public/hinting_db_sources.d.ts.map +1 -1
- package/dest/public/hinting_db_sources.js +65 -27
- package/dest/public/index.d.ts +2 -6
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +2 -6
- package/dest/public/public_db_sources.d.ts +19 -52
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +96 -107
- package/dest/public/public_processor/public_processor.d.ts +6 -6
- package/dest/public/public_processor/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor.js +24 -26
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts +3 -2
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.js +2 -2
- package/dest/public/public_tx_simulator/public_tx_context.d.ts +3 -4
- package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_context.js +11 -21
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +5 -4
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_simulator.js +21 -10
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts +3 -2
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.js +2 -2
- package/dest/public/side_effect_trace.d.ts +1 -3
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +3 -2
- package/dest/public/state_manager/state_manager.d.ts +6 -4
- package/dest/public/state_manager/state_manager.d.ts.map +1 -1
- package/dest/public/state_manager/state_manager.js +20 -41
- package/package.json +14 -16
- package/src/private/providers/acvm_native.ts +5 -4
- package/src/private/providers/acvm_wasm.ts +5 -2
- package/src/private/providers/acvm_wasm_with_blobs.ts +5 -3
- package/src/private/providers/circuit_recording/simulation_provider_recorder_wrapper.ts +3 -2
- package/src/private/providers/simulation_provider.ts +2 -1
- package/src/public/avm/avm_context.ts +2 -2
- package/src/public/avm/avm_simulator.ts +4 -8
- package/src/public/avm/avm_simulator_interface.ts +8 -0
- package/src/public/avm/errors.ts +1 -53
- package/src/public/avm/fixtures/avm_simulation_tester.ts +1 -1
- package/src/public/avm/fixtures/base_avm_simulation_tester.ts +1 -1
- package/src/public/avm/fixtures/index.ts +2 -308
- package/src/public/avm/fixtures/initializers.ts +101 -0
- package/src/public/avm/fixtures/utils.ts +213 -0
- package/src/public/avm/index.ts +0 -1
- package/src/public/avm/opcodes/accrued_substate.ts +1 -5
- package/src/public/avm/opcodes/external_calls.ts +17 -11
- package/src/public/avm/opcodes/instruction.ts +9 -8
- package/src/public/avm/revert_reason.ts +55 -0
- package/src/public/avm/serialization/bytecode_serialization.ts +72 -74
- package/src/{common → public}/debug_fn_name.ts +1 -1
- package/src/public/fixtures/index.ts +1 -0
- package/src/public/fixtures/public_tx_simulation_tester.ts +3 -5
- package/src/public/{avm/fixtures → fixtures}/simple_contract_data_source.ts +1 -1
- package/src/public/hinting_db_sources.ts +104 -39
- package/src/public/index.ts +2 -6
- package/src/public/public_db_sources.ts +111 -164
- package/src/public/public_processor/public_processor.ts +27 -29
- package/src/public/public_tx_simulator/measured_public_tx_simulator.ts +4 -3
- package/src/public/public_tx_simulator/public_tx_context.ts +10 -47
- package/src/public/public_tx_simulator/public_tx_simulator.ts +25 -10
- package/src/public/public_tx_simulator/telemetry_public_tx_simulator.ts +4 -3
- package/src/public/side_effect_trace.ts +2 -4
- package/src/public/state_manager/state_manager.ts +24 -50
- package/dest/public/avm/fixtures/simple_contract_data_source.d.ts.map +0 -1
- /package/dest/{common → public}/debug_fn_name.js +0 -0
- /package/dest/public/{avm/fixtures → fixtures}/simple_contract_data_source.d.ts +0 -0
|
@@ -2,7 +2,6 @@ import { NULLIFIER_SUBTREE_HEIGHT, PUBLIC_DATA_SUBTREE_HEIGHT } from '@aztec/con
|
|
|
2
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { Timer } from '@aztec/foundation/timer';
|
|
5
|
-
import type { IndexedTreeLeafPreimage, SiblingPath } from '@aztec/foundation/trees';
|
|
6
5
|
import { ContractClassRegisteredEvent } from '@aztec/protocol-contracts/class-registerer';
|
|
7
6
|
import { ContractInstanceDeployedEvent } from '@aztec/protocol-contracts/instance-deployer';
|
|
8
7
|
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
@@ -15,18 +14,17 @@ import {
|
|
|
15
14
|
computePublicBytecodeCommitment,
|
|
16
15
|
} from '@aztec/stdlib/contract';
|
|
17
16
|
import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
|
|
18
|
-
import type {
|
|
19
|
-
BatchInsertionResult,
|
|
20
|
-
IndexedTreeId,
|
|
21
|
-
MerkleTreeLeafType,
|
|
22
|
-
MerkleTreeWriteOperations,
|
|
23
|
-
SequentialInsertionResult,
|
|
24
|
-
TreeInfo,
|
|
25
|
-
} from '@aztec/stdlib/interfaces/server';
|
|
17
|
+
import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
|
|
26
18
|
import { ContractClassLog, PrivateLog } from '@aztec/stdlib/logs';
|
|
27
19
|
import type { PublicDBAccessStats } from '@aztec/stdlib/stats';
|
|
28
|
-
import {
|
|
29
|
-
|
|
20
|
+
import {
|
|
21
|
+
MerkleTreeId,
|
|
22
|
+
NullifierLeaf,
|
|
23
|
+
PublicDataTreeLeaf,
|
|
24
|
+
type PublicDataTreeLeafPreimage,
|
|
25
|
+
getTreeName,
|
|
26
|
+
} from '@aztec/stdlib/trees';
|
|
27
|
+
import { TreeSnapshots, type Tx } from '@aztec/stdlib/tx';
|
|
30
28
|
|
|
31
29
|
import type { PublicContractsDBInterface, PublicStateDBInterface } from './db_interfaces.js';
|
|
32
30
|
import { TxContractCache } from './tx_contract_cache.js';
|
|
@@ -276,172 +274,69 @@ export class PublicContractsDB implements PublicContractsDBInterface {
|
|
|
276
274
|
}
|
|
277
275
|
|
|
278
276
|
/**
|
|
279
|
-
*
|
|
277
|
+
* A high-level class that provides access to the merkle trees.
|
|
280
278
|
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
|
|
285
|
-
class
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return this.operations.getTreeInfo(treeId);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
getStateReference(): Promise<StateReference> {
|
|
293
|
-
return this.operations.getStateReference();
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
getInitialHeader(): BlockHeader {
|
|
297
|
-
return this.operations.getInitialHeader();
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
getSiblingPath<N extends number>(treeId: MerkleTreeId, index: bigint): Promise<SiblingPath<N>> {
|
|
301
|
-
return this.operations.getSiblingPath(treeId, index);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
getPreviousValueIndex<ID extends IndexedTreeId>(
|
|
305
|
-
treeId: ID,
|
|
306
|
-
value: bigint,
|
|
307
|
-
): Promise<
|
|
308
|
-
| {
|
|
309
|
-
index: bigint;
|
|
310
|
-
alreadyPresent: boolean;
|
|
311
|
-
}
|
|
312
|
-
| undefined
|
|
313
|
-
> {
|
|
314
|
-
return this.operations.getPreviousValueIndex(treeId, value);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
getLeafPreimage<ID extends IndexedTreeId>(treeId: ID, index: bigint): Promise<IndexedTreeLeafPreimage | undefined> {
|
|
318
|
-
return this.operations.getLeafPreimage(treeId, index);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
findLeafIndices<ID extends MerkleTreeId>(
|
|
322
|
-
treeId: ID,
|
|
323
|
-
values: MerkleTreeLeafType<ID>[],
|
|
324
|
-
): Promise<(bigint | undefined)[]> {
|
|
325
|
-
return this.operations.findLeafIndices(treeId, values);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
findLeafIndicesAfter<ID extends MerkleTreeId>(
|
|
329
|
-
treeId: ID,
|
|
330
|
-
values: MerkleTreeLeafType<ID>[],
|
|
331
|
-
startIndex: bigint,
|
|
332
|
-
): Promise<(bigint | undefined)[]> {
|
|
333
|
-
return this.operations.findLeafIndicesAfter(treeId, values, startIndex);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
getLeafValue<ID extends MerkleTreeId>(
|
|
337
|
-
treeId: ID,
|
|
338
|
-
index: bigint,
|
|
339
|
-
): Promise<MerkleTreeLeafType<typeof treeId> | undefined> {
|
|
340
|
-
return this.operations.getLeafValue(treeId, index);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
getBlockNumbersForLeafIndices<ID extends MerkleTreeId>(
|
|
344
|
-
treeId: ID,
|
|
345
|
-
leafIndices: bigint[],
|
|
346
|
-
): Promise<(bigint | undefined)[]> {
|
|
347
|
-
return this.operations.getBlockNumbersForLeafIndices(treeId, leafIndices);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
createCheckpoint(): Promise<void> {
|
|
351
|
-
return this.operations.createCheckpoint();
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
commitCheckpoint(): Promise<void> {
|
|
355
|
-
return this.operations.commitCheckpoint();
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
revertCheckpoint(): Promise<void> {
|
|
359
|
-
return this.operations.revertCheckpoint();
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
appendLeaves<ID extends MerkleTreeId>(treeId: ID, leaves: MerkleTreeLeafType<ID>[]): Promise<void> {
|
|
363
|
-
return this.operations.appendLeaves(treeId, leaves);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
updateArchive(header: BlockHeader): Promise<void> {
|
|
367
|
-
return this.operations.updateArchive(header);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
batchInsert<TreeHeight extends number, SubtreeSiblingPathHeight extends number, ID extends IndexedTreeId>(
|
|
371
|
-
treeId: ID,
|
|
372
|
-
leaves: Buffer[],
|
|
373
|
-
subtreeHeight: number,
|
|
374
|
-
): Promise<BatchInsertionResult<TreeHeight, SubtreeSiblingPathHeight>> {
|
|
375
|
-
return this.operations.batchInsert(treeId, leaves, subtreeHeight);
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
sequentialInsert<TreeHeight extends number, ID extends IndexedTreeId>(
|
|
379
|
-
treeId: ID,
|
|
380
|
-
leaves: Buffer[],
|
|
381
|
-
): Promise<SequentialInsertionResult<TreeHeight>> {
|
|
382
|
-
return this.operations.sequentialInsert(treeId, leaves);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
close(): Promise<void> {
|
|
386
|
-
return this.operations.close();
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* A class that provides access to the merkle trees, and other helper methods.
|
|
279
|
+
* This class is just a helper wrapper around a merkle db. Anything that you can do with it
|
|
280
|
+
* can also be done directly with the merkle db. This class should NOT be exposed or used
|
|
281
|
+
* outside of `simulator/src/public`.
|
|
282
|
+
*
|
|
283
|
+
* NOTE: This class is currently written in such a way that it would generate the
|
|
284
|
+
* necessary hints if used with a hinting merkle db. This is a bit of a leak of concepts.
|
|
285
|
+
* Eventually we can have everything depend on a config/factory at the TxSimulator level
|
|
286
|
+
* to decide whether to use hints or not (same with tracing, etc).
|
|
392
287
|
*/
|
|
393
|
-
export class PublicTreesDB
|
|
288
|
+
export class PublicTreesDB implements PublicStateDBInterface {
|
|
394
289
|
private logger = createLogger('simulator:public-trees-db');
|
|
395
290
|
|
|
396
|
-
constructor(db: MerkleTreeWriteOperations) {
|
|
397
|
-
super(db);
|
|
398
|
-
}
|
|
291
|
+
constructor(private readonly db: MerkleTreeWriteOperations) {}
|
|
399
292
|
|
|
400
|
-
/**
|
|
401
|
-
* Reads a value from public storage, returning zero if none.
|
|
402
|
-
* @param contract - Owner of the storage.
|
|
403
|
-
* @param slot - Slot to read in the contract storage.
|
|
404
|
-
* @returns The current value in the storage slot.
|
|
405
|
-
*/
|
|
406
293
|
public async storageRead(contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
294
|
+
const timer = new Timer();
|
|
407
295
|
const leafSlot = (await computePublicDataTreeLeafSlot(contract, slot)).toBigInt();
|
|
408
296
|
|
|
409
|
-
const lowLeafResult = await this.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
|
|
297
|
+
const lowLeafResult = await this.db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
|
|
410
298
|
if (!lowLeafResult) {
|
|
411
299
|
throw new Error('Low leaf not found');
|
|
412
300
|
}
|
|
413
301
|
|
|
414
|
-
// TODO
|
|
415
|
-
await this.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index);
|
|
302
|
+
// TODO: We need this for the hints. See class comment for more details.
|
|
303
|
+
await this.db.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index);
|
|
416
304
|
// Unconditionally fetching the preimage for the hints. Move it to the hinting layer?
|
|
417
|
-
const preimage = (await this.getLeafPreimage(
|
|
305
|
+
const preimage = (await this.db.getLeafPreimage(
|
|
418
306
|
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
419
307
|
lowLeafResult.index,
|
|
420
308
|
)) as PublicDataTreeLeafPreimage;
|
|
421
309
|
|
|
422
|
-
|
|
310
|
+
const result = lowLeafResult.alreadyPresent ? preimage.leaf.value : Fr.ZERO;
|
|
311
|
+
this.logger.debug(`Storage read (contract=${contract}, slot=${slot}, value=${result})`, {
|
|
312
|
+
eventName: 'public-db-access',
|
|
313
|
+
duration: timer.ms(),
|
|
314
|
+
operation: 'storage-read',
|
|
315
|
+
} satisfies PublicDBAccessStats);
|
|
316
|
+
|
|
317
|
+
return result;
|
|
423
318
|
}
|
|
424
319
|
|
|
425
|
-
/**
|
|
426
|
-
* Records a write to public storage.
|
|
427
|
-
* @param contract - Owner of the storage.
|
|
428
|
-
* @param slot - Slot to read in the contract storage.
|
|
429
|
-
* @param newValue - The new value to store.
|
|
430
|
-
* @returns The slot of the written leaf in the public data tree.
|
|
431
|
-
*/
|
|
432
320
|
public async storageWrite(contract: AztecAddress, slot: Fr, newValue: Fr): Promise<void> {
|
|
321
|
+
const timer = new Timer();
|
|
433
322
|
const leafSlot = await computePublicDataTreeLeafSlot(contract, slot);
|
|
434
323
|
const publicDataWrite = new PublicDataWrite(leafSlot, newValue);
|
|
435
|
-
await this.sequentialInsert(MerkleTreeId.PUBLIC_DATA_TREE, [publicDataWrite.toBuffer()]);
|
|
324
|
+
await this.db.sequentialInsert(MerkleTreeId.PUBLIC_DATA_TREE, [publicDataWrite.toBuffer()]);
|
|
325
|
+
|
|
326
|
+
this.logger.debug(`Storage write (contract=${contract}, slot=${slot}, value=${newValue})`, {
|
|
327
|
+
eventName: 'public-db-access',
|
|
328
|
+
duration: timer.ms(),
|
|
329
|
+
operation: 'storage-write',
|
|
330
|
+
} satisfies PublicDBAccessStats);
|
|
436
331
|
}
|
|
437
332
|
|
|
438
333
|
public async getL1ToL2LeafValue(leafIndex: bigint): Promise<Fr | undefined> {
|
|
439
334
|
const timer = new Timer();
|
|
440
|
-
const leafValue = await this.getLeafValue(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, leafIndex);
|
|
441
|
-
// TODO
|
|
442
|
-
await this.getSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, leafIndex);
|
|
335
|
+
const leafValue = await this.db.getLeafValue(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, leafIndex);
|
|
336
|
+
// TODO: We need this for the hints. See class comment for more details.
|
|
337
|
+
await this.db.getSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, leafIndex);
|
|
443
338
|
|
|
444
|
-
this.logger.debug(`
|
|
339
|
+
this.logger.debug(`Fetched L1 to L2 message leaf value (leafIndex=${leafIndex}, value=${leafValue})`, {
|
|
445
340
|
eventName: 'public-db-access',
|
|
446
341
|
duration: timer.ms(),
|
|
447
342
|
operation: 'get-l1-to-l2-message-leaf-value',
|
|
@@ -451,11 +346,11 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt
|
|
|
451
346
|
|
|
452
347
|
public async getNoteHash(leafIndex: bigint): Promise<Fr | undefined> {
|
|
453
348
|
const timer = new Timer();
|
|
454
|
-
const leafValue = await this.getLeafValue(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
|
|
455
|
-
// TODO
|
|
456
|
-
await this.getSiblingPath(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
|
|
349
|
+
const leafValue = await this.db.getLeafValue(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
|
|
350
|
+
// TODO: We need this for the hints. See class comment for more details.
|
|
351
|
+
await this.db.getSiblingPath(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
|
|
457
352
|
|
|
458
|
-
this.logger.debug(`
|
|
353
|
+
this.logger.debug(`Fetched note hash leaf value (leafIndex=${leafIndex}, value=${leafValue})`, {
|
|
459
354
|
eventName: 'public-db-access',
|
|
460
355
|
duration: timer.ms(),
|
|
461
356
|
operation: 'get-note-hash',
|
|
@@ -463,19 +358,30 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt
|
|
|
463
358
|
return leafValue;
|
|
464
359
|
}
|
|
465
360
|
|
|
361
|
+
public async writeNoteHash(noteHash: Fr): Promise<void> {
|
|
362
|
+
const timer = new Timer();
|
|
363
|
+
await this.db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, [noteHash]);
|
|
364
|
+
|
|
365
|
+
this.logger.debug(`Wrote note hash (noteHash=${noteHash})`, {
|
|
366
|
+
eventName: 'public-db-access',
|
|
367
|
+
duration: timer.ms(),
|
|
368
|
+
operation: 'write-note-hash',
|
|
369
|
+
} satisfies PublicDBAccessStats);
|
|
370
|
+
}
|
|
371
|
+
|
|
466
372
|
public async checkNullifierExists(nullifier: Fr): Promise<boolean> {
|
|
467
373
|
const timer = new Timer();
|
|
468
|
-
const lowLeafResult = await this.getPreviousValueIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBigInt());
|
|
374
|
+
const lowLeafResult = await this.db.getPreviousValueIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBigInt());
|
|
469
375
|
if (!lowLeafResult) {
|
|
470
376
|
throw new Error('Low leaf not found');
|
|
471
377
|
}
|
|
472
|
-
// TODO
|
|
473
|
-
await this.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, lowLeafResult.index);
|
|
474
|
-
// TODO
|
|
475
|
-
await this.getLeafPreimage(MerkleTreeId.NULLIFIER_TREE, lowLeafResult.index);
|
|
378
|
+
// TODO: We need this for the hints. See class comment for more details.
|
|
379
|
+
await this.db.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, lowLeafResult.index);
|
|
380
|
+
// TODO: We need this for the hints. See class comment for more details.
|
|
381
|
+
await this.db.getLeafPreimage(MerkleTreeId.NULLIFIER_TREE, lowLeafResult.index);
|
|
476
382
|
const exists = lowLeafResult.alreadyPresent;
|
|
477
383
|
|
|
478
|
-
this.logger.debug(`
|
|
384
|
+
this.logger.debug(`Checked nullifier exists (nullifier=${nullifier}, exists=${exists})`, {
|
|
479
385
|
eventName: 'public-db-access',
|
|
480
386
|
duration: timer.ms(),
|
|
481
387
|
operation: 'check-nullifier-exists',
|
|
@@ -483,30 +389,71 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt
|
|
|
483
389
|
return exists;
|
|
484
390
|
}
|
|
485
391
|
|
|
392
|
+
public async writeNullifier(siloedNullifier: Fr): Promise<void> {
|
|
393
|
+
const timer = new Timer();
|
|
394
|
+
await this.db.sequentialInsert(MerkleTreeId.NULLIFIER_TREE, [siloedNullifier.toBuffer()]);
|
|
395
|
+
|
|
396
|
+
this.logger.debug(`Wrote nullifier (nullifier=${siloedNullifier})`, {
|
|
397
|
+
eventName: 'public-db-access',
|
|
398
|
+
duration: timer.ms(),
|
|
399
|
+
operation: 'write-nullifier',
|
|
400
|
+
} satisfies PublicDBAccessStats);
|
|
401
|
+
}
|
|
402
|
+
|
|
486
403
|
public async padTree(treeId: MerkleTreeId, leavesToInsert: number): Promise<void> {
|
|
404
|
+
const timer = new Timer();
|
|
405
|
+
|
|
487
406
|
switch (treeId) {
|
|
488
407
|
// Indexed trees.
|
|
489
408
|
case MerkleTreeId.NULLIFIER_TREE:
|
|
490
|
-
await this.batchInsert(
|
|
409
|
+
await this.db.batchInsert(
|
|
491
410
|
treeId,
|
|
492
411
|
Array(leavesToInsert).fill(NullifierLeaf.empty().toBuffer()),
|
|
493
412
|
NULLIFIER_SUBTREE_HEIGHT,
|
|
494
413
|
);
|
|
495
414
|
break;
|
|
496
415
|
case MerkleTreeId.PUBLIC_DATA_TREE:
|
|
497
|
-
await this.batchInsert(
|
|
416
|
+
await this.db.batchInsert(
|
|
498
417
|
treeId,
|
|
499
418
|
Array(leavesToInsert).fill(PublicDataTreeLeaf.empty().toBuffer()),
|
|
500
419
|
PUBLIC_DATA_SUBTREE_HEIGHT,
|
|
501
420
|
);
|
|
502
421
|
break;
|
|
503
|
-
//
|
|
422
|
+
// Append-only trees.
|
|
504
423
|
case MerkleTreeId.L1_TO_L2_MESSAGE_TREE:
|
|
505
424
|
case MerkleTreeId.NOTE_HASH_TREE:
|
|
506
|
-
await this.appendLeaves(treeId, Array(leavesToInsert).fill(Fr.ZERO));
|
|
425
|
+
await this.db.appendLeaves(treeId, Array(leavesToInsert).fill(Fr.ZERO));
|
|
507
426
|
break;
|
|
508
427
|
default:
|
|
509
428
|
throw new Error(`Padding not supported for tree ${treeId}`);
|
|
510
429
|
}
|
|
430
|
+
|
|
431
|
+
this.logger.debug(`Padded tree (tree=${getTreeName(treeId)}, leavesToInsert=${leavesToInsert})`, {
|
|
432
|
+
eventName: 'public-db-access',
|
|
433
|
+
duration: timer.ms(),
|
|
434
|
+
operation: 'pad-tree',
|
|
435
|
+
} satisfies PublicDBAccessStats);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
public async createCheckpoint(): Promise<void> {
|
|
439
|
+
await this.db.createCheckpoint();
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
public async commitCheckpoint(): Promise<void> {
|
|
443
|
+
await this.db.commitCheckpoint();
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
public async revertCheckpoint(): Promise<void> {
|
|
447
|
+
await this.db.revertCheckpoint();
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
public async getTreeSnapshots(): Promise<TreeSnapshots> {
|
|
451
|
+
const stateReference = await this.db.getStateReference();
|
|
452
|
+
return new TreeSnapshots(
|
|
453
|
+
stateReference.l1ToL2MessageTree,
|
|
454
|
+
stateReference.partial.noteHashTree,
|
|
455
|
+
stateReference.partial.nullifierTree,
|
|
456
|
+
stateReference.partial.publicDataTree,
|
|
457
|
+
);
|
|
511
458
|
}
|
|
512
459
|
}
|
|
@@ -44,7 +44,7 @@ export class PublicProcessorFactory {
|
|
|
44
44
|
constructor(
|
|
45
45
|
private contractDataSource: ContractDataSource,
|
|
46
46
|
private dateProvider: DateProvider,
|
|
47
|
-
|
|
47
|
+
protected telemetryClient: TelemetryClient = getTelemetryClient(),
|
|
48
48
|
) {}
|
|
49
49
|
|
|
50
50
|
/**
|
|
@@ -59,10 +59,9 @@ export class PublicProcessorFactory {
|
|
|
59
59
|
globalVariables: GlobalVariables,
|
|
60
60
|
skipFeeEnforcement: boolean,
|
|
61
61
|
): PublicProcessor {
|
|
62
|
-
const treesDB = new PublicTreesDB(merkleTree);
|
|
63
62
|
const contractsDB = new PublicContractsDB(this.contractDataSource);
|
|
64
63
|
const publicTxSimulator = this.createPublicTxSimulator(
|
|
65
|
-
|
|
64
|
+
merkleTree,
|
|
66
65
|
contractsDB,
|
|
67
66
|
globalVariables,
|
|
68
67
|
/*doMerkleOperations=*/ true,
|
|
@@ -71,7 +70,7 @@ export class PublicProcessorFactory {
|
|
|
71
70
|
|
|
72
71
|
return new PublicProcessor(
|
|
73
72
|
globalVariables,
|
|
74
|
-
|
|
73
|
+
merkleTree,
|
|
75
74
|
contractsDB,
|
|
76
75
|
publicTxSimulator,
|
|
77
76
|
this.dateProvider,
|
|
@@ -80,14 +79,14 @@ export class PublicProcessorFactory {
|
|
|
80
79
|
}
|
|
81
80
|
|
|
82
81
|
protected createPublicTxSimulator(
|
|
83
|
-
|
|
82
|
+
merkleTree: MerkleTreeWriteOperations,
|
|
84
83
|
contractsDB: PublicContractsDB,
|
|
85
84
|
globalVariables: GlobalVariables,
|
|
86
85
|
doMerkleOperations: boolean,
|
|
87
86
|
skipFeeEnforcement: boolean,
|
|
88
87
|
): PublicTxSimulator {
|
|
89
88
|
return new TelemetryPublicTxSimulator(
|
|
90
|
-
|
|
89
|
+
merkleTree,
|
|
91
90
|
contractsDB,
|
|
92
91
|
globalVariables,
|
|
93
92
|
doMerkleOperations,
|
|
@@ -110,9 +109,10 @@ class PublicProcessorTimeoutError extends Error {
|
|
|
110
109
|
*/
|
|
111
110
|
export class PublicProcessor implements Traceable {
|
|
112
111
|
private metrics: PublicProcessorMetrics;
|
|
112
|
+
|
|
113
113
|
constructor(
|
|
114
114
|
protected globalVariables: GlobalVariables,
|
|
115
|
-
|
|
115
|
+
private merkleTree: MerkleTreeWriteOperations,
|
|
116
116
|
protected contractsDB: PublicContractsDB,
|
|
117
117
|
protected publicTxSimulator: PublicTxSimulator,
|
|
118
118
|
private dateProvider: DateProvider,
|
|
@@ -221,7 +221,7 @@ export class PublicProcessor implements Traceable {
|
|
|
221
221
|
// We checkpoint the transaction here, then within the try/catch we
|
|
222
222
|
// 1. Revert the checkpoint if the tx fails or needs to be discarded for any reason
|
|
223
223
|
// 2. Commit the transaction in the finally block. Note that by using the ForkCheckpoint lifecycle only the first commit/revert takes effect
|
|
224
|
-
const checkpoint = await ForkCheckpoint.new(this.
|
|
224
|
+
const checkpoint = await ForkCheckpoint.new(this.merkleTree);
|
|
225
225
|
|
|
226
226
|
try {
|
|
227
227
|
const [processedTx, returnValues] = await this.processTx(tx, deadline);
|
|
@@ -240,16 +240,8 @@ export class PublicProcessor implements Traceable {
|
|
|
240
240
|
continue;
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
// When there are public calls, the PublicTxSimulator & AVM handle tree insertions.
|
|
246
|
-
await this.doTreeInsertionsForPrivateOnlyTx(processedTx);
|
|
247
|
-
// Add any contracts registered/deployed in this private-only tx to the block-level cache
|
|
248
|
-
// (add to tx-level cache and then commit to block-level cache)
|
|
249
|
-
await this.contractsDB.addNewContracts(tx);
|
|
250
|
-
this.contractsDB.commitContractsForTx();
|
|
251
|
-
}
|
|
252
|
-
|
|
243
|
+
// FIXME(fcarreiro): it's ugly to have to notify the validator of nullifiers.
|
|
244
|
+
// I'd rather pass the validators the processedTx as well and let them deal with it.
|
|
253
245
|
nullifierCache?.addNullifiers(processedTx.txEffect.nullifiers.map(n => n.toBuffer()));
|
|
254
246
|
result.push(processedTx);
|
|
255
247
|
returns = returns.concat(returnValues);
|
|
@@ -332,12 +324,12 @@ export class PublicProcessor implements Traceable {
|
|
|
332
324
|
// b) always had a txHandler with the same db passed to it as this.db, which updated the db in buildBaseRollupHints in this loop
|
|
333
325
|
// To see how this ^ happens, move back to one shared db in test_context and run orchestrator_multi_public_functions.test.ts
|
|
334
326
|
// The below is taken from buildBaseRollupHints:
|
|
335
|
-
await this.
|
|
327
|
+
await this.merkleTree.appendLeaves(
|
|
336
328
|
MerkleTreeId.NOTE_HASH_TREE,
|
|
337
329
|
padArrayEnd(processedTx.txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX),
|
|
338
330
|
);
|
|
339
331
|
try {
|
|
340
|
-
await this.
|
|
332
|
+
await this.merkleTree.batchInsert(
|
|
341
333
|
MerkleTreeId.NULLIFIER_TREE,
|
|
342
334
|
padArrayEnd(processedTx.txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX).map(n => n.toBuffer()),
|
|
343
335
|
NULLIFIER_SUBTREE_HEIGHT,
|
|
@@ -352,11 +344,6 @@ export class PublicProcessor implements Traceable {
|
|
|
352
344
|
}
|
|
353
345
|
}
|
|
354
346
|
|
|
355
|
-
// The only public data write should be for fee payment
|
|
356
|
-
await this.treesDB.sequentialInsert(
|
|
357
|
-
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
358
|
-
processedTx.txEffect.publicDataWrites.map(x => x.toBuffer()),
|
|
359
|
-
);
|
|
360
347
|
const treeInsertionEnd = process.hrtime.bigint();
|
|
361
348
|
this.metrics.recordTreeInsertions(Number(treeInsertionEnd - treeInsertionStart) / 1_000);
|
|
362
349
|
}
|
|
@@ -398,14 +385,16 @@ export class PublicProcessor implements Traceable {
|
|
|
398
385
|
* This is used in private only txs, since for txs with public calls
|
|
399
386
|
* the avm handles the fee payment itself.
|
|
400
387
|
*/
|
|
401
|
-
private async
|
|
388
|
+
private async performFeePaymentPublicDataWrite(txFee: Fr, feePayer: AztecAddress): Promise<PublicDataWrite> {
|
|
402
389
|
const feeJuiceAddress = ProtocolContractAddress.FeeJuice;
|
|
403
390
|
const balanceSlot = await computeFeePayerBalanceStorageSlot(feePayer);
|
|
404
391
|
const leafSlot = await computeFeePayerBalanceLeafSlot(feePayer);
|
|
392
|
+
// This high-level db is used as a convenient helper. It could be done with the merkleTree directly.
|
|
393
|
+
const treesDB = new PublicTreesDB(this.merkleTree);
|
|
405
394
|
|
|
406
395
|
this.log.debug(`Deducting ${txFee.toBigInt()} balance in Fee Juice for ${feePayer}`);
|
|
407
396
|
|
|
408
|
-
const balance = await
|
|
397
|
+
const balance = await treesDB.storageRead(feeJuiceAddress, balanceSlot);
|
|
409
398
|
|
|
410
399
|
if (balance.lt(txFee)) {
|
|
411
400
|
throw new Error(
|
|
@@ -414,7 +403,7 @@ export class PublicProcessor implements Traceable {
|
|
|
414
403
|
}
|
|
415
404
|
|
|
416
405
|
const updatedBalance = balance.sub(txFee);
|
|
417
|
-
await
|
|
406
|
+
await treesDB.storageWrite(feeJuiceAddress, balanceSlot, updatedBalance);
|
|
418
407
|
|
|
419
408
|
return new PublicDataWrite(leafSlot, updatedBalance);
|
|
420
409
|
}
|
|
@@ -426,7 +415,7 @@ export class PublicProcessor implements Traceable {
|
|
|
426
415
|
const gasFees = this.globalVariables.gasFees;
|
|
427
416
|
const transactionFee = tx.data.gasUsed.computeFee(gasFees);
|
|
428
417
|
|
|
429
|
-
const feePaymentPublicDataWrite = await this.
|
|
418
|
+
const feePaymentPublicDataWrite = await this.performFeePaymentPublicDataWrite(transactionFee, tx.data.feePayer);
|
|
430
419
|
|
|
431
420
|
const processedTx = await makeProcessedTxFromPrivateOnlyTx(
|
|
432
421
|
tx,
|
|
@@ -445,6 +434,15 @@ export class PublicProcessor implements Traceable {
|
|
|
445
434
|
.filter(log => ContractClassRegisteredEvent.isContractClassRegisteredEvent(log))
|
|
446
435
|
.map(log => ContractClassRegisteredEvent.fromLog(log)),
|
|
447
436
|
);
|
|
437
|
+
|
|
438
|
+
// Fee payment insertion has already been done. Do the rest.
|
|
439
|
+
await this.doTreeInsertionsForPrivateOnlyTx(processedTx);
|
|
440
|
+
|
|
441
|
+
// Add any contracts registered/deployed in this private-only tx to the block-level cache
|
|
442
|
+
// (add to tx-level cache and then commit to block-level cache)
|
|
443
|
+
await this.contractsDB.addNewContracts(tx);
|
|
444
|
+
this.contractsDB.commitContractsForTx();
|
|
445
|
+
|
|
448
446
|
return [processedTx, undefined];
|
|
449
447
|
}
|
|
450
448
|
|
|
@@ -2,11 +2,12 @@ import type { Fr } from '@aztec/foundation/fields';
|
|
|
2
2
|
import { Timer } from '@aztec/foundation/timer';
|
|
3
3
|
import type { Gas } from '@aztec/stdlib/gas';
|
|
4
4
|
import type { AvmSimulationStats } from '@aztec/stdlib/stats';
|
|
5
|
+
import type { MerkleTreeWriteOperations } from '@aztec/stdlib/trees';
|
|
5
6
|
import { type GlobalVariables, PublicCallRequestWithCalldata, Tx, TxExecutionPhase } from '@aztec/stdlib/tx';
|
|
6
7
|
|
|
7
8
|
import type { AvmFinalizedCallResult } from '../avm/avm_contract_call_result.js';
|
|
8
9
|
import type { ExecutorMetricsInterface } from '../executor_metrics_interface.js';
|
|
9
|
-
import type { PublicContractsDB
|
|
10
|
+
import type { PublicContractsDB } from '../public_db_sources.js';
|
|
10
11
|
import type { PublicPersistableStateManager } from '../state_manager/state_manager.js';
|
|
11
12
|
import { PublicTxContext } from './public_tx_context.js';
|
|
12
13
|
import { type ProcessedPhase, type PublicTxResult, PublicTxSimulator } from './public_tx_simulator.js';
|
|
@@ -16,14 +17,14 @@ import { type ProcessedPhase, type PublicTxResult, PublicTxSimulator } from './p
|
|
|
16
17
|
*/
|
|
17
18
|
export class MeasuredPublicTxSimulator extends PublicTxSimulator {
|
|
18
19
|
constructor(
|
|
19
|
-
|
|
20
|
+
merkleTree: MerkleTreeWriteOperations,
|
|
20
21
|
contractsDB: PublicContractsDB,
|
|
21
22
|
globalVariables: GlobalVariables,
|
|
22
23
|
doMerkleOperations: boolean = false,
|
|
23
24
|
skipFeeEnforcement: boolean = false,
|
|
24
25
|
protected readonly metrics: ExecutorMetricsInterface,
|
|
25
26
|
) {
|
|
26
|
-
super(
|
|
27
|
+
super(merkleTree, contractsDB, globalVariables, doMerkleOperations, skipFeeEnforcement);
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
public override async simulate(tx: Tx, txLabel: string = 'unlabeledTx'): Promise<PublicTxResult> {
|