@aztec/pxe 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/bin/index.js +5 -6
- package/dest/config/index.d.ts +0 -9
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +1 -17
- package/dest/config/package_info.d.ts +5 -0
- package/dest/config/package_info.d.ts.map +1 -0
- package/dest/config/package_info.js +4 -0
- package/dest/contract_data_oracle/index.js +2 -2
- package/dest/database/incoming_note_dao.d.ts +1 -1
- package/dest/database/incoming_note_dao.d.ts.map +1 -1
- package/dest/database/incoming_note_dao.js +2 -2
- package/dest/database/kv_pxe_database.d.ts +10 -13
- package/dest/database/kv_pxe_database.d.ts.map +1 -1
- package/dest/database/kv_pxe_database.js +153 -230
- package/dest/database/outgoing_note_dao.js +2 -2
- package/dest/database/pxe_database.d.ts +7 -25
- package/dest/database/pxe_database.d.ts.map +1 -1
- package/dest/database/pxe_database_test_suite.d.ts.map +1 -1
- package/dest/database/pxe_database_test_suite.js +18 -59
- package/dest/index.d.ts +2 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +3 -1
- package/dest/kernel_oracle/index.d.ts.map +1 -1
- package/dest/kernel_oracle/index.js +3 -3
- package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts +1 -1
- package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -1
- package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.js +13 -15
- package/dest/kernel_prover/index.d.ts +1 -0
- package/dest/kernel_prover/index.d.ts.map +1 -1
- package/dest/kernel_prover/index.js +2 -1
- package/dest/kernel_prover/kernel_prover.d.ts +1 -0
- package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
- package/dest/kernel_prover/kernel_prover.js +38 -4
- package/dest/kernel_prover/test/test_circuit_prover.d.ts.map +1 -1
- package/dest/kernel_prover/test/test_circuit_prover.js +4 -4
- package/dest/note_decryption_utils/add_public_values_to_payload.js +2 -2
- package/dest/note_decryption_utils/brute_force_note_info.d.ts +3 -3
- package/dest/note_decryption_utils/brute_force_note_info.d.ts.map +1 -1
- package/dest/note_decryption_utils/brute_force_note_info.js +8 -8
- package/dest/note_decryption_utils/produce_note_daos.d.ts +3 -6
- package/dest/note_decryption_utils/produce_note_daos.d.ts.map +1 -1
- package/dest/note_decryption_utils/produce_note_daos.js +5 -19
- package/dest/note_decryption_utils/produce_note_daos_for_key.d.ts +1 -1
- package/dest/note_decryption_utils/produce_note_daos_for_key.d.ts.map +1 -1
- package/dest/pxe_service/error_enriching.d.ts +3 -3
- package/dest/pxe_service/error_enriching.d.ts.map +1 -1
- package/dest/pxe_service/error_enriching.js +10 -10
- package/dest/pxe_service/index.d.ts +0 -1
- package/dest/pxe_service/index.d.ts.map +1 -1
- package/dest/pxe_service/index.js +1 -2
- package/dest/pxe_service/pxe_service.d.ts +4 -16
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +86 -101
- package/dest/pxe_service/test/pxe_test_suite.d.ts.map +1 -1
- package/dest/pxe_service/test/pxe_test_suite.js +1 -3
- package/dest/simulator/index.d.ts +1 -1
- package/dest/simulator/index.d.ts.map +1 -1
- package/dest/simulator/index.js +2 -2
- package/dest/simulator_oracle/index.d.ts +7 -6
- package/dest/simulator_oracle/index.d.ts.map +1 -1
- package/dest/simulator_oracle/index.js +65 -44
- package/dest/synchronizer/synchronizer.d.ts +10 -40
- package/dest/synchronizer/synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/synchronizer.js +35 -69
- package/dest/{pxe_service → utils}/create_pxe_service.d.ts +1 -1
- package/dest/utils/create_pxe_service.d.ts.map +1 -0
- package/dest/utils/create_pxe_service.js +49 -0
- package/package.json +31 -19
- package/src/bin/index.ts +4 -5
- package/src/config/index.ts +0 -21
- package/src/config/package_info.ts +3 -0
- package/src/contract_data_oracle/index.ts +1 -1
- package/src/database/incoming_note_dao.ts +2 -2
- package/src/database/kv_pxe_database.ts +212 -309
- package/src/database/outgoing_note_dao.ts +1 -1
- package/src/database/pxe_database.ts +7 -28
- package/src/database/pxe_database_test_suite.ts +20 -75
- package/src/index.ts +2 -0
- package/src/kernel_oracle/index.ts +2 -2
- package/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts +14 -16
- package/src/kernel_prover/index.ts +2 -0
- package/src/kernel_prover/kernel_prover.ts +61 -2
- package/src/kernel_prover/test/test_circuit_prover.ts +5 -3
- package/src/note_decryption_utils/add_public_values_to_payload.ts +1 -1
- package/src/note_decryption_utils/brute_force_note_info.ts +9 -9
- package/src/note_decryption_utils/produce_note_daos.ts +5 -48
- package/src/note_decryption_utils/produce_note_daos_for_key.ts +1 -1
- package/src/pxe_service/error_enriching.ts +14 -12
- package/src/pxe_service/index.ts +0 -1
- package/src/pxe_service/pxe_service.ts +137 -160
- package/src/pxe_service/test/pxe_test_suite.ts +0 -3
- package/src/simulator/index.ts +1 -1
- package/src/simulator_oracle/index.ts +71 -75
- package/src/synchronizer/synchronizer.ts +37 -77
- package/src/{pxe_service → utils}/create_pxe_service.ts +10 -10
- package/dest/pxe_service/create_pxe_service.d.ts.map +0 -1
- package/dest/pxe_service/create_pxe_service.js +0 -49
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
type L2Block,
|
|
13
13
|
type LogFilter,
|
|
14
14
|
MerkleTreeId,
|
|
15
|
-
type OutgoingNotesFilter,
|
|
16
15
|
type PXE,
|
|
17
16
|
type PXEInfo,
|
|
18
17
|
type PrivateExecutionResult,
|
|
@@ -56,8 +55,7 @@ import {
|
|
|
56
55
|
encodeArguments,
|
|
57
56
|
} from '@aztec/foundation/abi';
|
|
58
57
|
import { Fr, type Point } from '@aztec/foundation/fields';
|
|
59
|
-
import { type
|
|
60
|
-
import { SerialQueue } from '@aztec/foundation/queue';
|
|
58
|
+
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
61
59
|
import { type KeyStore } from '@aztec/key-store';
|
|
62
60
|
import { type L2TipsStore } from '@aztec/kv-store/stores';
|
|
63
61
|
import {
|
|
@@ -65,9 +63,12 @@ import {
|
|
|
65
63
|
getCanonicalProtocolContract,
|
|
66
64
|
protocolContractNames,
|
|
67
65
|
} from '@aztec/protocol-contracts';
|
|
68
|
-
import { type AcirSimulator } from '@aztec/simulator';
|
|
66
|
+
import { type AcirSimulator } from '@aztec/simulator/client';
|
|
69
67
|
|
|
70
|
-
import {
|
|
68
|
+
import { inspect } from 'util';
|
|
69
|
+
|
|
70
|
+
import { type PXEServiceConfig } from '../config/index.js';
|
|
71
|
+
import { getPackageInfo } from '../config/package_info.js';
|
|
71
72
|
import { ContractDataOracle } from '../contract_data_oracle/index.js';
|
|
72
73
|
import { IncomingNoteDao } from '../database/incoming_note_dao.js';
|
|
73
74
|
import { type PxeDatabase } from '../database/index.js';
|
|
@@ -85,11 +86,8 @@ export class PXEService implements PXE {
|
|
|
85
86
|
private synchronizer: Synchronizer;
|
|
86
87
|
private contractDataOracle: ContractDataOracle;
|
|
87
88
|
private simulator: AcirSimulator;
|
|
88
|
-
private log:
|
|
89
|
+
private log: Logger;
|
|
89
90
|
private packageVersion: string;
|
|
90
|
-
// serialize synchronizer and calls to proveTx.
|
|
91
|
-
// ensures that state is not changed while simulating
|
|
92
|
-
private jobQueue = new SerialQueue();
|
|
93
91
|
|
|
94
92
|
constructor(
|
|
95
93
|
private keyStore: KeyStore,
|
|
@@ -100,13 +98,11 @@ export class PXEService implements PXE {
|
|
|
100
98
|
config: PXEServiceConfig,
|
|
101
99
|
logSuffix?: string,
|
|
102
100
|
) {
|
|
103
|
-
this.log =
|
|
101
|
+
this.log = createLogger(logSuffix ? `pxe:service:${logSuffix}` : `pxe:service`);
|
|
104
102
|
this.synchronizer = new Synchronizer(node, db, tipsStore, config, logSuffix);
|
|
105
103
|
this.contractDataOracle = new ContractDataOracle(db);
|
|
106
104
|
this.simulator = getAcirSimulator(db, node, keyStore, this.contractDataOracle);
|
|
107
105
|
this.packageVersion = getPackageInfo().version;
|
|
108
|
-
|
|
109
|
-
this.jobQueue.start();
|
|
110
106
|
}
|
|
111
107
|
|
|
112
108
|
/**
|
|
@@ -114,25 +110,14 @@ export class PXEService implements PXE {
|
|
|
114
110
|
*
|
|
115
111
|
* @returns A promise that resolves when the server has started successfully.
|
|
116
112
|
*/
|
|
117
|
-
public async
|
|
118
|
-
await this.synchronizer.start();
|
|
113
|
+
public async init() {
|
|
119
114
|
await this.#registerProtocolContracts();
|
|
120
115
|
const info = await this.getNodeInfo();
|
|
121
116
|
this.log.info(`Started PXE connected to chain ${info.l1ChainId} version ${info.protocolVersion}`);
|
|
122
117
|
}
|
|
123
118
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
* This function ensures that all ongoing tasks are completed before stopping the server.
|
|
127
|
-
* It is useful for gracefully shutting down the server during maintenance or restarts.
|
|
128
|
-
*
|
|
129
|
-
* @returns A Promise resolving once the server has been stopped successfully.
|
|
130
|
-
*/
|
|
131
|
-
public async stop() {
|
|
132
|
-
await this.jobQueue.cancel();
|
|
133
|
-
this.log.info('Cancelled Job Queue');
|
|
134
|
-
await this.synchronizer.stop();
|
|
135
|
-
this.log.info('Stopped Synchronizer');
|
|
119
|
+
isL1ToL2MessageSynced(l1ToL2Message: Fr): Promise<boolean> {
|
|
120
|
+
return this.node.isL1ToL2MessageSynced(l1ToL2Message);
|
|
136
121
|
}
|
|
137
122
|
|
|
138
123
|
/** Returns an estimate of the db size in bytes. */
|
|
@@ -314,33 +299,6 @@ export class PXEService implements PXE {
|
|
|
314
299
|
return Promise.all(extendedNotes);
|
|
315
300
|
}
|
|
316
301
|
|
|
317
|
-
public async getOutgoingNotes(filter: OutgoingNotesFilter): Promise<UniqueNote[]> {
|
|
318
|
-
const noteDaos = await this.db.getOutgoingNotes(filter);
|
|
319
|
-
|
|
320
|
-
const extendedNotes = noteDaos.map(async dao => {
|
|
321
|
-
let owner = filter.owner;
|
|
322
|
-
if (owner === undefined) {
|
|
323
|
-
const completeAddresses = (await this.db.getCompleteAddresses()).find(address =>
|
|
324
|
-
address.publicKeys.masterOutgoingViewingPublicKey.equals(dao.ovpkM),
|
|
325
|
-
);
|
|
326
|
-
if (completeAddresses === undefined) {
|
|
327
|
-
throw new Error(`Cannot find complete address for OvpkM ${dao.ovpkM.toString()}`);
|
|
328
|
-
}
|
|
329
|
-
owner = completeAddresses.address;
|
|
330
|
-
}
|
|
331
|
-
return new UniqueNote(
|
|
332
|
-
dao.note,
|
|
333
|
-
owner,
|
|
334
|
-
dao.contractAddress,
|
|
335
|
-
dao.storageSlot,
|
|
336
|
-
dao.noteTypeId,
|
|
337
|
-
dao.txHash,
|
|
338
|
-
dao.nonce,
|
|
339
|
-
);
|
|
340
|
-
});
|
|
341
|
-
return Promise.all(extendedNotes);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
302
|
public async getL1ToL2MembershipWitness(
|
|
345
303
|
contractAddress: AztecAddress,
|
|
346
304
|
messageHash: Fr,
|
|
@@ -361,7 +319,7 @@ export class PXEService implements PXE {
|
|
|
361
319
|
}
|
|
362
320
|
|
|
363
321
|
for (const nonce of nonces) {
|
|
364
|
-
const { noteHash,
|
|
322
|
+
const { noteHash, uniqueNoteHash, innerNullifier } = await this.simulator.computeNoteHashAndOptionallyANullifier(
|
|
365
323
|
note.contractAddress,
|
|
366
324
|
nonce,
|
|
367
325
|
note.storageSlot,
|
|
@@ -370,7 +328,7 @@ export class PXEService implements PXE {
|
|
|
370
328
|
note.note,
|
|
371
329
|
);
|
|
372
330
|
|
|
373
|
-
const [index] = await this.node.findLeavesIndexes('latest', MerkleTreeId.NOTE_HASH_TREE, [
|
|
331
|
+
const [index] = await this.node.findLeavesIndexes('latest', MerkleTreeId.NOTE_HASH_TREE, [uniqueNoteHash]);
|
|
374
332
|
if (index === undefined) {
|
|
375
333
|
throw new Error('Note does not exist.');
|
|
376
334
|
}
|
|
@@ -410,7 +368,7 @@ export class PXEService implements PXE {
|
|
|
410
368
|
}
|
|
411
369
|
|
|
412
370
|
for (const nonce of nonces) {
|
|
413
|
-
const { noteHash,
|
|
371
|
+
const { noteHash, uniqueNoteHash, innerNullifier } = await this.simulator.computeNoteHashAndOptionallyANullifier(
|
|
414
372
|
note.contractAddress,
|
|
415
373
|
nonce,
|
|
416
374
|
note.storageSlot,
|
|
@@ -423,7 +381,7 @@ export class PXEService implements PXE {
|
|
|
423
381
|
throw new Error('Unexpectedly received non-zero nullifier.');
|
|
424
382
|
}
|
|
425
383
|
|
|
426
|
-
const [index] = await this.node.findLeavesIndexes('latest', MerkleTreeId.NOTE_HASH_TREE, [
|
|
384
|
+
const [index] = await this.node.findLeavesIndexes('latest', MerkleTreeId.NOTE_HASH_TREE, [uniqueNoteHash]);
|
|
427
385
|
if (index === undefined) {
|
|
428
386
|
throw new Error('Note does not exist.');
|
|
429
387
|
}
|
|
@@ -469,7 +427,7 @@ export class PXEService implements PXE {
|
|
|
469
427
|
}
|
|
470
428
|
|
|
471
429
|
const nonce = computeNoteHashNonce(firstNullifier, i);
|
|
472
|
-
const {
|
|
430
|
+
const { uniqueNoteHash } = await this.simulator.computeNoteHashAndOptionallyANullifier(
|
|
473
431
|
note.contractAddress,
|
|
474
432
|
nonce,
|
|
475
433
|
note.storageSlot,
|
|
@@ -477,7 +435,7 @@ export class PXEService implements PXE {
|
|
|
477
435
|
false,
|
|
478
436
|
note.note,
|
|
479
437
|
);
|
|
480
|
-
if (hash.equals(
|
|
438
|
+
if (hash.equals(uniqueNoteHash)) {
|
|
481
439
|
nonces.push(nonce);
|
|
482
440
|
}
|
|
483
441
|
}
|
|
@@ -505,23 +463,16 @@ export class PXEService implements PXE {
|
|
|
505
463
|
return result.publicInputs;
|
|
506
464
|
}
|
|
507
465
|
|
|
508
|
-
public proveTx(
|
|
466
|
+
public async proveTx(
|
|
509
467
|
txRequest: TxExecutionRequest,
|
|
510
468
|
privateExecutionResult: PrivateExecutionResult,
|
|
511
469
|
): Promise<TxProvingResult> {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
);
|
|
519
|
-
return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof!);
|
|
520
|
-
})
|
|
521
|
-
.catch(err => {
|
|
522
|
-
this.log.error(err);
|
|
523
|
-
throw err;
|
|
524
|
-
});
|
|
470
|
+
try {
|
|
471
|
+
const { publicInputs, clientIvcProof } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult);
|
|
472
|
+
return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof!);
|
|
473
|
+
} catch (err: any) {
|
|
474
|
+
throw this.contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult));
|
|
475
|
+
}
|
|
525
476
|
}
|
|
526
477
|
|
|
527
478
|
// TODO(#7456) Prevent msgSender being defined here for the first call
|
|
@@ -533,52 +484,77 @@ export class PXEService implements PXE {
|
|
|
533
484
|
profile: boolean = false,
|
|
534
485
|
scopes?: AztecAddress[],
|
|
535
486
|
): Promise<TxSimulationResult> {
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
487
|
+
try {
|
|
488
|
+
const txInfo = {
|
|
489
|
+
origin: txRequest.origin,
|
|
490
|
+
functionSelector: txRequest.functionSelector,
|
|
491
|
+
simulatePublic,
|
|
492
|
+
msgSender,
|
|
493
|
+
chainId: txRequest.txContext.chainId,
|
|
494
|
+
version: txRequest.txContext.version,
|
|
495
|
+
authWitnesses: txRequest.authWitnesses.map(w => w.requestHash),
|
|
496
|
+
};
|
|
497
|
+
this.log.verbose(
|
|
498
|
+
`Simulating transaction execution request to ${txRequest.functionSelector} at ${txRequest.origin}`,
|
|
499
|
+
txInfo,
|
|
500
|
+
);
|
|
501
|
+
await this.synchronizer.sync();
|
|
502
|
+
const privateExecutionResult = await this.#executePrivate(txRequest, msgSender, scopes);
|
|
551
503
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
504
|
+
let publicInputs: PrivateKernelTailCircuitPublicInputs;
|
|
505
|
+
let profileResult;
|
|
506
|
+
if (profile) {
|
|
507
|
+
({ publicInputs, profileResult } = await this.#profileKernelProver(
|
|
508
|
+
txRequest,
|
|
509
|
+
this.proofCreator,
|
|
510
|
+
privateExecutionResult,
|
|
511
|
+
));
|
|
512
|
+
} else {
|
|
513
|
+
publicInputs = await this.#simulateKernels(txRequest, privateExecutionResult);
|
|
514
|
+
}
|
|
558
515
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
516
|
+
const privateSimulationResult = new PrivateSimulationResult(privateExecutionResult, publicInputs);
|
|
517
|
+
const simulatedTx = privateSimulationResult.toSimulatedTx();
|
|
518
|
+
let publicOutput: PublicSimulationOutput | undefined;
|
|
519
|
+
if (simulatePublic) {
|
|
520
|
+
publicOutput = await this.#simulatePublicCalls(simulatedTx);
|
|
521
|
+
}
|
|
564
522
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
// If we log, the `getTxHash` function will throw.
|
|
569
|
-
if (!msgSender) {
|
|
570
|
-
this.log.info(`Executed local simulation for ${simulatedTx.getTxHash()}`);
|
|
523
|
+
if (!skipTxValidation) {
|
|
524
|
+
if (!(await this.node.isValidTx(simulatedTx, true))) {
|
|
525
|
+
throw new Error('The simulated transaction is unable to be added to state and is invalid.');
|
|
571
526
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
this.log.info(`Simulation completed for ${simulatedTx.tryGetTxHash()}`, {
|
|
530
|
+
txHash: simulatedTx.tryGetTxHash(),
|
|
531
|
+
...txInfo,
|
|
532
|
+
...(profileResult ? { gateCounts: profileResult.gateCounts } : {}),
|
|
533
|
+
...(publicOutput
|
|
534
|
+
? {
|
|
535
|
+
gasUsed: publicOutput.gasUsed,
|
|
536
|
+
revertCode: publicOutput.txEffect.revertCode.getCode(),
|
|
537
|
+
revertReason: publicOutput.revertReason,
|
|
538
|
+
}
|
|
539
|
+
: {}),
|
|
581
540
|
});
|
|
541
|
+
|
|
542
|
+
return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput(
|
|
543
|
+
privateSimulationResult,
|
|
544
|
+
publicOutput,
|
|
545
|
+
profileResult,
|
|
546
|
+
);
|
|
547
|
+
} catch (err: any) {
|
|
548
|
+
throw this.contextualizeError(
|
|
549
|
+
err,
|
|
550
|
+
inspect(txRequest),
|
|
551
|
+
`simulatePublic=${simulatePublic}`,
|
|
552
|
+
`msgSender=${msgSender?.toString() ?? 'undefined'}`,
|
|
553
|
+
`skipTxValidation=${skipTxValidation}`,
|
|
554
|
+
`profile=${profile}`,
|
|
555
|
+
`scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
|
|
556
|
+
);
|
|
557
|
+
}
|
|
582
558
|
}
|
|
583
559
|
|
|
584
560
|
public async sendTx(tx: Tx): Promise<TxHash> {
|
|
@@ -586,10 +562,9 @@ export class PXEService implements PXE {
|
|
|
586
562
|
if (await this.node.getTxEffect(txHash)) {
|
|
587
563
|
throw new Error(`A settled tx with equal hash ${txHash.toString()} exists.`);
|
|
588
564
|
}
|
|
589
|
-
this.log.
|
|
565
|
+
this.log.debug(`Sending transaction ${txHash}`);
|
|
590
566
|
await this.node.sendTx(tx).catch(err => {
|
|
591
|
-
this.
|
|
592
|
-
throw err;
|
|
567
|
+
throw this.contextualizeError(err, inspect(tx));
|
|
593
568
|
});
|
|
594
569
|
this.log.info(`Sent transaction ${txHash}`);
|
|
595
570
|
return txHash;
|
|
@@ -602,20 +577,22 @@ export class PXEService implements PXE {
|
|
|
602
577
|
_from?: AztecAddress,
|
|
603
578
|
scopes?: AztecAddress[],
|
|
604
579
|
): Promise<AbiDecoded> {
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
.
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
580
|
+
try {
|
|
581
|
+
await this.synchronizer.sync();
|
|
582
|
+
// TODO - Should check if `from` has the permission to call the view function.
|
|
583
|
+
const functionCall = await this.#getFunctionCall(functionName, args, to);
|
|
584
|
+
const executionResult = await this.#simulateUnconstrained(functionCall, scopes);
|
|
585
|
+
|
|
586
|
+
// TODO - Return typed result based on the function artifact.
|
|
587
|
+
return executionResult;
|
|
588
|
+
} catch (err: any) {
|
|
589
|
+
const stringifiedArgs = args.map(arg => arg.toString()).join(', ');
|
|
590
|
+
throw this.contextualizeError(
|
|
591
|
+
err,
|
|
592
|
+
`simulateUnconstrained ${to}:${functionName}(${stringifiedArgs})`,
|
|
593
|
+
`scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
|
|
594
|
+
);
|
|
595
|
+
}
|
|
619
596
|
}
|
|
620
597
|
|
|
621
598
|
public getTxReceipt(txHash: TxHash): Promise<TxReceipt> {
|
|
@@ -712,12 +689,14 @@ export class PXEService implements PXE {
|
|
|
712
689
|
}
|
|
713
690
|
|
|
714
691
|
async #registerProtocolContracts() {
|
|
692
|
+
const registered: Record<string, string> = {};
|
|
715
693
|
for (const name of protocolContractNames) {
|
|
716
694
|
const { address, contractClass, instance, artifact } = getCanonicalProtocolContract(name);
|
|
717
695
|
await this.db.addContractArtifact(contractClass.id, artifact);
|
|
718
696
|
await this.db.addContractInstance(instance);
|
|
719
|
-
|
|
697
|
+
registered[name] = address.toString();
|
|
720
698
|
}
|
|
699
|
+
this.log.verbose(`Registered protocol contracts in pxe`, registered);
|
|
721
700
|
}
|
|
722
701
|
|
|
723
702
|
/**
|
|
@@ -749,13 +728,11 @@ export class PXEService implements PXE {
|
|
|
749
728
|
scopes?: AztecAddress[],
|
|
750
729
|
): Promise<PrivateExecutionResult> {
|
|
751
730
|
// TODO - Pause syncing while simulating.
|
|
752
|
-
|
|
753
731
|
const { contractAddress, functionArtifact } = await this.#getSimulationParameters(txRequest);
|
|
754
732
|
|
|
755
|
-
this.log.debug('Executing simulator...');
|
|
756
733
|
try {
|
|
757
734
|
const result = await this.simulator.run(txRequest, functionArtifact, contractAddress, msgSender, scopes);
|
|
758
|
-
this.log.
|
|
735
|
+
this.log.debug(`Private simulation completed for ${contractAddress.toString()}:${functionArtifact.name}`);
|
|
759
736
|
return result;
|
|
760
737
|
} catch (err) {
|
|
761
738
|
if (err instanceof SimulationError) {
|
|
@@ -833,19 +810,14 @@ export class PXEService implements PXE {
|
|
|
833
810
|
}
|
|
834
811
|
|
|
835
812
|
/**
|
|
836
|
-
*
|
|
837
|
-
* The function takes in a transaction request,
|
|
838
|
-
*
|
|
839
|
-
* transaction object with the generated proof and public inputs. If a new contract address is provided,
|
|
840
|
-
* the function will also include the new contract's public functions in the transaction object.
|
|
813
|
+
* Generate a kernel proof, and create a private kernel output.
|
|
814
|
+
* The function takes in a transaction execution request, and the result of private execution
|
|
815
|
+
* and then generates a kernel proof.
|
|
841
816
|
*
|
|
842
817
|
* @param txExecutionRequest - The transaction request to be simulated and proved.
|
|
843
818
|
* @param proofCreator - The proof creator to use for proving the execution.
|
|
844
|
-
* @param
|
|
845
|
-
* @
|
|
846
|
-
* @returns An object that contains:
|
|
847
|
-
* A private transaction object containing the proof, public inputs, and encrypted logs.
|
|
848
|
-
* The return values of the private execution
|
|
819
|
+
* @param privateExecutionResult - The result of the private execution
|
|
820
|
+
* @returns An object that contains the output of the kernel execution, including the ClientIvcProof if proving is enabled.
|
|
849
821
|
*/
|
|
850
822
|
async #prove(
|
|
851
823
|
txExecutionRequest: TxExecutionRequest,
|
|
@@ -860,14 +832,6 @@ export class PXEService implements PXE {
|
|
|
860
832
|
return await kernelProver.prove(txExecutionRequest.toTxRequest(), privateExecutionResult);
|
|
861
833
|
}
|
|
862
834
|
|
|
863
|
-
public async isGlobalStateSynchronized() {
|
|
864
|
-
return await this.synchronizer.isGlobalStateSynchronized();
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
public getSyncStatus() {
|
|
868
|
-
return Promise.resolve(this.synchronizer.getSyncStatus());
|
|
869
|
-
}
|
|
870
|
-
|
|
871
835
|
public async isContractClassPubliclyRegistered(id: Fr): Promise<boolean> {
|
|
872
836
|
return !!(await this.node.getContractClass(id));
|
|
873
837
|
}
|
|
@@ -896,13 +860,11 @@ export class PXEService implements PXE {
|
|
|
896
860
|
const blocks = await this.node.getBlocks(from, limit);
|
|
897
861
|
|
|
898
862
|
const txEffects = blocks.flatMap(block => block.body.txEffects);
|
|
899
|
-
const
|
|
900
|
-
|
|
901
|
-
const encryptedLogs = encryptedTxLogs.flatMap(encryptedTxLog => encryptedTxLog.unrollLogs());
|
|
863
|
+
const privateLogs = txEffects.flatMap(txEffect => txEffect.privateLogs);
|
|
902
864
|
|
|
903
865
|
const vsks = await Promise.all(
|
|
904
866
|
vpks.map(async vpk => {
|
|
905
|
-
const [keyPrefix, account] = this.keyStore.getKeyPrefixAndAccount(vpk);
|
|
867
|
+
const [keyPrefix, account] = await this.keyStore.getKeyPrefixAndAccount(vpk);
|
|
906
868
|
let secretKey = await this.keyStore.getMasterSecretKey(vpk);
|
|
907
869
|
if (keyPrefix === 'iv') {
|
|
908
870
|
const registeredAccount = await this.getRegisteredAccount(account);
|
|
@@ -919,10 +881,11 @@ export class PXEService implements PXE {
|
|
|
919
881
|
}),
|
|
920
882
|
);
|
|
921
883
|
|
|
922
|
-
const visibleEvents =
|
|
884
|
+
const visibleEvents = privateLogs.flatMap(log => {
|
|
923
885
|
for (const sk of vsks) {
|
|
924
|
-
|
|
925
|
-
|
|
886
|
+
// TODO: Verify that the first field of the log is the tag siloed with contract address.
|
|
887
|
+
// Or use tags to query logs, like we do with notes.
|
|
888
|
+
const decryptedEvent = L1EventPayload.decryptAsIncoming(log, sk);
|
|
926
889
|
if (decryptedEvent !== undefined) {
|
|
927
890
|
return [decryptedEvent];
|
|
928
891
|
}
|
|
@@ -987,4 +950,18 @@ export class PXEService implements PXE {
|
|
|
987
950
|
async resetNoteSyncData() {
|
|
988
951
|
return await this.db.resetNoteSyncData();
|
|
989
952
|
}
|
|
953
|
+
|
|
954
|
+
private contextualizeError(err: Error, ...context: string[]): Error {
|
|
955
|
+
let contextStr = '';
|
|
956
|
+
if (context.length > 0) {
|
|
957
|
+
contextStr = `\nContext:\n${context.join('\n')}`;
|
|
958
|
+
}
|
|
959
|
+
if (err instanceof SimulationError) {
|
|
960
|
+
err.setAztecContext(contextStr);
|
|
961
|
+
} else {
|
|
962
|
+
this.log.error(err.name, err);
|
|
963
|
+
this.log.debug(contextStr);
|
|
964
|
+
}
|
|
965
|
+
return err;
|
|
966
|
+
}
|
|
990
967
|
}
|
|
@@ -115,8 +115,5 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise<PXE>) =>
|
|
|
115
115
|
expect(typeof nodeInfo.l1ChainId).toEqual('number');
|
|
116
116
|
expect(nodeInfo.l1ContractAddresses.rollupAddress.toString()).toMatch(/0x[a-fA-F0-9]+/);
|
|
117
117
|
});
|
|
118
|
-
|
|
119
|
-
// Note: Not testing `isGlobalStateSynchronized`, `isAccountStateSynchronized` and `getSyncStatus` as these methods
|
|
120
|
-
// only call synchronizer.
|
|
121
118
|
});
|
|
122
119
|
};
|
package/src/simulator/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type AztecNode } from '@aztec/circuit-types';
|
|
2
2
|
import { type KeyStore } from '@aztec/key-store';
|
|
3
|
-
import { AcirSimulator } from '@aztec/simulator';
|
|
3
|
+
import { AcirSimulator } from '@aztec/simulator/client';
|
|
4
4
|
|
|
5
5
|
import { ContractDataOracle } from '../contract_data_oracle/index.js';
|
|
6
6
|
import { type PxeDatabase } from '../database/pxe_database.js';
|