@aztec/pxe 0.87.5 → 0.87.7
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/config/package_info.js +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +37 -0
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -0
- package/dest/contract_function_simulator/contract_function_simulator.js +117 -0
- package/dest/contract_function_simulator/execution_data_provider.d.ts +301 -0
- package/dest/contract_function_simulator/execution_data_provider.d.ts.map +1 -0
- package/dest/contract_function_simulator/execution_data_provider.js +14 -0
- package/dest/contract_function_simulator/execution_note_cache.d.ts +93 -0
- package/dest/contract_function_simulator/execution_note_cache.d.ts.map +1 -0
- package/dest/contract_function_simulator/execution_note_cache.js +180 -0
- package/dest/contract_function_simulator/hashed_values_cache.d.ts +28 -0
- package/dest/contract_function_simulator/hashed_values_cache.d.ts.map +1 -0
- package/dest/contract_function_simulator/hashed_values_cache.js +36 -0
- package/dest/contract_function_simulator/index.d.ts +10 -0
- package/dest/contract_function_simulator/index.d.ts.map +1 -0
- package/dest/contract_function_simulator/index.js +8 -0
- package/dest/contract_function_simulator/oracle/index.d.ts +14 -0
- package/dest/contract_function_simulator/oracle/index.d.ts.map +1 -0
- package/dest/contract_function_simulator/oracle/index.js +2 -0
- package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts +19 -0
- package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts.map +1 -0
- package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.js +24 -0
- package/dest/contract_function_simulator/oracle/oracle.d.ts +53 -0
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -0
- package/dest/contract_function_simulator/oracle/oracle.js +317 -0
- package/dest/contract_function_simulator/oracle/private_execution.d.ts +24 -0
- package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -0
- package/dest/contract_function_simulator/oracle/private_execution.js +100 -0
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +187 -0
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -0
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +325 -0
- package/dest/contract_function_simulator/oracle/typed_oracle.d.ts +83 -0
- package/dest/contract_function_simulator/oracle/typed_oracle.d.ts.map +1 -0
- package/dest/contract_function_simulator/oracle/typed_oracle.js +138 -0
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +163 -0
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -0
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +257 -0
- package/dest/contract_function_simulator/pick_notes.d.ts +85 -0
- package/dest/contract_function_simulator/pick_notes.d.ts.map +1 -0
- package/dest/contract_function_simulator/pick_notes.js +51 -0
- package/dest/contract_function_simulator/proxied_node.d.ts +9 -0
- package/dest/contract_function_simulator/proxied_node.d.ts.map +1 -0
- package/dest/contract_function_simulator/proxied_node.js +27 -0
- package/dest/{pxe_oracle_interface → contract_function_simulator}/pxe_oracle_interface.d.ts +5 -4
- package/dest/contract_function_simulator/pxe_oracle_interface.d.ts.map +1 -0
- package/dest/{pxe_oracle_interface → contract_function_simulator}/pxe_oracle_interface.js +16 -15
- package/dest/contract_function_simulator/tagging_utils.d.ts.map +1 -0
- package/dest/entrypoints/client/bundle/index.d.ts +1 -1
- package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/index.js +1 -1
- package/dest/entrypoints/client/bundle/utils.d.ts +1 -1
- package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/utils.js +10 -4
- package/dest/entrypoints/client/lazy/index.d.ts +1 -1
- package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/index.js +1 -1
- package/dest/entrypoints/client/lazy/utils.d.ts +1 -1
- package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/utils.js +10 -4
- package/dest/entrypoints/{client/pxe_creation_options.d.ts → pxe_creation_options.d.ts} +4 -1
- package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -0
- package/dest/entrypoints/server/index.d.ts +1 -1
- package/dest/entrypoints/server/index.d.ts.map +1 -1
- package/dest/entrypoints/server/index.js +1 -1
- package/dest/entrypoints/server/utils.d.ts +6 -6
- package/dest/entrypoints/server/utils.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.js +26 -18
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.js +6 -5
- package/dest/pxe_service/pxe_service.d.ts +2 -2
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +58 -28
- package/dest/storage/note_data_provider/note_dao.d.ts +1 -1
- package/dest/storage/note_data_provider/note_dao.d.ts.map +1 -1
- package/package.json +17 -15
- package/src/config/package_info.ts +1 -1
- package/src/contract_function_simulator/contract_function_simulator.ts +193 -0
- package/src/contract_function_simulator/execution_data_provider.ts +391 -0
- package/src/contract_function_simulator/execution_note_cache.ts +217 -0
- package/src/contract_function_simulator/hashed_values_cache.ts +47 -0
- package/src/contract_function_simulator/index.ts +9 -0
- package/src/contract_function_simulator/oracle/index.ts +16 -0
- package/src/contract_function_simulator/oracle/message_load_oracle_inputs.ts +23 -0
- package/src/contract_function_simulator/oracle/oracle.ts +541 -0
- package/src/contract_function_simulator/oracle/private_execution.ts +171 -0
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +518 -0
- package/src/contract_function_simulator/oracle/typed_oracle.ts +273 -0
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +384 -0
- package/src/contract_function_simulator/pick_notes.ts +141 -0
- package/src/contract_function_simulator/proxied_node.ts +33 -0
- package/src/{pxe_oracle_interface → contract_function_simulator}/pxe_oracle_interface.ts +18 -21
- package/src/entrypoints/client/bundle/index.ts +1 -1
- package/src/entrypoints/client/bundle/utils.ts +24 -16
- package/src/entrypoints/client/lazy/index.ts +1 -1
- package/src/entrypoints/client/lazy/utils.ts +25 -12
- package/src/entrypoints/{client/pxe_creation_options.ts → pxe_creation_options.ts} +4 -1
- package/src/entrypoints/server/index.ts +1 -1
- package/src/entrypoints/server/utils.ts +44 -26
- package/src/private_kernel/private_kernel_execution_prover.ts +6 -4
- package/src/pxe_service/pxe_service.ts +86 -45
- package/src/storage/note_data_provider/note_dao.ts +2 -1
- package/dest/entrypoints/client/pxe_creation_options.d.ts.map +0 -1
- package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts.map +0 -1
- package/dest/pxe_oracle_interface/tagging_utils.d.ts.map +0 -1
- /package/dest/{pxe_oracle_interface → contract_function_simulator}/tagging_utils.d.ts +0 -0
- /package/dest/{pxe_oracle_interface → contract_function_simulator}/tagging_utils.js +0 -0
- /package/dest/entrypoints/{client/pxe_creation_options.js → pxe_creation_options.js} +0 -0
- /package/src/{pxe_oracle_interface → contract_function_simulator}/tagging_utils.ts +0 -0
|
@@ -5,7 +5,6 @@ import { Timer } from '@aztec/foundation/timer';
|
|
|
5
5
|
import { KeyStore } from '@aztec/key-store';
|
|
6
6
|
import { L2TipsKVStore } from '@aztec/kv-store/stores';
|
|
7
7
|
import { ProtocolContractAddress, protocolContractNames } from '@aztec/protocol-contracts';
|
|
8
|
-
import { AcirSimulator, readCurrentClassId } from '@aztec/simulator/client';
|
|
9
8
|
import { EventSelector, FunctionSelector, FunctionType, decodeFromAbi, decodeFunctionSignature, encodeArguments } from '@aztec/stdlib/abi';
|
|
10
9
|
import { computeContractAddressFromInstance, getContractClassFromArtifact } from '@aztec/stdlib/contract';
|
|
11
10
|
import { SimulationError } from '@aztec/stdlib/errors';
|
|
@@ -16,9 +15,12 @@ import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
|
16
15
|
import { PrivateSimulationResult, TxProfileResult, TxProvingResult, TxSimulationResult } from '@aztec/stdlib/tx';
|
|
17
16
|
import { inspect } from 'util';
|
|
18
17
|
import { getPackageInfo } from '../config/package_info.js';
|
|
18
|
+
import { ContractFunctionSimulator } from '../contract_function_simulator/contract_function_simulator.js';
|
|
19
|
+
import { readCurrentClassId } from '../contract_function_simulator/oracle/private_execution.js';
|
|
20
|
+
import { ProxiedNodeFactory } from '../contract_function_simulator/proxied_node.js';
|
|
21
|
+
import { PXEOracleInterface } from '../contract_function_simulator/pxe_oracle_interface.js';
|
|
19
22
|
import { PrivateKernelExecutionProver } from '../private_kernel/private_kernel_execution_prover.js';
|
|
20
23
|
import { PrivateKernelOracleImpl } from '../private_kernel/private_kernel_oracle_impl.js';
|
|
21
|
-
import { PXEOracleInterface } from '../pxe_oracle_interface/pxe_oracle_interface.js';
|
|
22
24
|
import { AddressDataProvider } from '../storage/address_data_provider/address_data_provider.js';
|
|
23
25
|
import { CapsuleDataProvider } from '../storage/capsule_data_provider/capsule_data_provider.js';
|
|
24
26
|
import { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
|
|
@@ -74,7 +76,7 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
74
76
|
* can be contacted.
|
|
75
77
|
*
|
|
76
78
|
* @returns A promise that resolves PXE service is ready to be used.
|
|
77
|
-
*/ static async create(node, store, proofCreator,
|
|
79
|
+
*/ static async create(node, store, proofCreator, simulator, protocolContractsProvider, config, loggerOrSuffix) {
|
|
78
80
|
const log = !loggerOrSuffix || typeof loggerOrSuffix === 'string' ? createLogger(loggerOrSuffix ? `pxe:service:${loggerOrSuffix}` : `pxe:service`) : loggerOrSuffix;
|
|
79
81
|
const packageVersion = getPackageInfo().version;
|
|
80
82
|
const proverEnabled = !!config.proverEnabled;
|
|
@@ -88,8 +90,6 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
88
90
|
const keyStore = new KeyStore(store);
|
|
89
91
|
const tipsStore = new L2TipsKVStore(store, 'pxe');
|
|
90
92
|
const synchronizer = new Synchronizer(node, syncDataProvider, noteDataProvider, taggingDataProvider, tipsStore, config, loggerOrSuffix);
|
|
91
|
-
const pxeOracleInterface = new PXEOracleInterface(node, keyStore, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, privateEventDataProvider, log);
|
|
92
|
-
const simulator = new AcirSimulator(pxeOracleInterface, simulationProvider);
|
|
93
93
|
const jobQueue = new SerialQueue();
|
|
94
94
|
const pxeService = new PXEService(node, synchronizer, keyStore, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, privateEventDataProvider, simulator, packageVersion, proverEnabled, proofCreator, protocolContractsProvider, log, jobQueue);
|
|
95
95
|
pxeService.jobQueue.start();
|
|
@@ -130,6 +130,10 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
130
130
|
return await getNonNullifiedL1ToL2MessageWitness(this.node, contractAddress, messageHash, secret);
|
|
131
131
|
}
|
|
132
132
|
// Internal methods
|
|
133
|
+
#getSimulatorForTx() {
|
|
134
|
+
const pxeOracleInterface = new PXEOracleInterface(ProxiedNodeFactory.create(this.node), this.keyStore, this.contractDataProvider, this.noteDataProvider, this.capsuleDataProvider, this.syncDataProvider, this.taggingDataProvider, this.addressDataProvider, this.privateEventDataProvider, this.log);
|
|
135
|
+
return new ContractFunctionSimulator(pxeOracleInterface, this.simulator);
|
|
136
|
+
}
|
|
133
137
|
#contextualizeError(err, ...context) {
|
|
134
138
|
let contextStr = '';
|
|
135
139
|
if (context.length > 0) {
|
|
@@ -194,10 +198,10 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
194
198
|
returnTypes: functionDao.returnTypes
|
|
195
199
|
};
|
|
196
200
|
}
|
|
197
|
-
async #executePrivate(txRequest, msgSender, scopes) {
|
|
201
|
+
async #executePrivate(contractFunctionSimulator, txRequest, msgSender, scopes) {
|
|
198
202
|
const { origin: contractAddress, functionSelector } = txRequest;
|
|
199
203
|
try {
|
|
200
|
-
const result = await
|
|
204
|
+
const result = await contractFunctionSimulator.run(txRequest, contractAddress, functionSelector, msgSender, scopes);
|
|
201
205
|
this.log.debug(`Private simulation completed for ${contractAddress.toString()}:${functionSelector}`);
|
|
202
206
|
return result;
|
|
203
207
|
} catch (err) {
|
|
@@ -209,14 +213,15 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
209
213
|
}
|
|
210
214
|
/**
|
|
211
215
|
* Simulate a utility function call on the given contract.
|
|
216
|
+
* @param contractFunctionSimulator - The simulator to use for the function call.
|
|
212
217
|
* @param call - The function call to execute.
|
|
213
218
|
* @param authWitnesses - Authentication witnesses required for the function call.
|
|
214
219
|
* @param scopes - Optional array of account addresses whose notes can be accessed in this call. Defaults to all
|
|
215
220
|
* accounts if not specified.
|
|
216
221
|
* @returns The simulation result containing the outputs of the utility function.
|
|
217
|
-
*/ async #simulateUtility(call, authWitnesses, scopes) {
|
|
222
|
+
*/ async #simulateUtility(contractFunctionSimulator, call, authWitnesses, scopes) {
|
|
218
223
|
try {
|
|
219
|
-
return
|
|
224
|
+
return contractFunctionSimulator.runUtility(call, authWitnesses ?? [], scopes);
|
|
220
225
|
} catch (err) {
|
|
221
226
|
if (err instanceof SimulationError) {
|
|
222
227
|
await enrichSimulationError(err, this.contractDataProvider, this.log);
|
|
@@ -447,11 +452,13 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
447
452
|
const totalTimer = new Timer();
|
|
448
453
|
try {
|
|
449
454
|
let syncTime;
|
|
455
|
+
let contractFunctionSimulator;
|
|
450
456
|
if (!privateExecutionResult) {
|
|
451
457
|
const syncTimer = new Timer();
|
|
452
458
|
await this.synchronizer.sync();
|
|
453
459
|
syncTime = syncTimer.ms();
|
|
454
|
-
|
|
460
|
+
contractFunctionSimulator = this.#getSimulatorForTx();
|
|
461
|
+
privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest);
|
|
455
462
|
}
|
|
456
463
|
const { publicInputs, clientIvcProof, executionSteps, timings: { proving } = {} } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
|
|
457
464
|
simulate: false,
|
|
@@ -459,9 +466,10 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
459
466
|
profileMode: 'none'
|
|
460
467
|
});
|
|
461
468
|
const totalTime = totalTimer.ms();
|
|
462
|
-
const perFunction = executionSteps.map(({ functionName, timings: { witgen } })=>({
|
|
469
|
+
const perFunction = executionSteps.map(({ functionName, timings: { witgen, oracles } })=>({
|
|
463
470
|
functionName,
|
|
464
|
-
time: witgen
|
|
471
|
+
time: witgen,
|
|
472
|
+
oracles
|
|
465
473
|
}));
|
|
466
474
|
const timings = {
|
|
467
475
|
total: totalTime,
|
|
@@ -473,7 +481,10 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
473
481
|
this.log.info(`Proving completed in ${totalTime}ms`, {
|
|
474
482
|
timings
|
|
475
483
|
});
|
|
476
|
-
return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof,
|
|
484
|
+
return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof, {
|
|
485
|
+
timings,
|
|
486
|
+
nodeRPCCalls: contractFunctionSimulator?.getStats().nodeRPCCalls
|
|
487
|
+
});
|
|
477
488
|
} catch (err) {
|
|
478
489
|
throw this.#contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult));
|
|
479
490
|
}
|
|
@@ -497,27 +508,36 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
497
508
|
const syncTimer = new Timer();
|
|
498
509
|
await this.synchronizer.sync();
|
|
499
510
|
const syncTime = syncTimer.ms();
|
|
500
|
-
const
|
|
511
|
+
const contractFunctionSimulator = this.#getSimulatorForTx();
|
|
512
|
+
const privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest, msgSender);
|
|
501
513
|
const { executionSteps, timings: { proving } = {} } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
|
|
502
514
|
simulate: skipProofGeneration,
|
|
503
515
|
skipFeeEnforcement: false,
|
|
504
516
|
profileMode
|
|
505
517
|
});
|
|
506
518
|
const totalTime = totalTimer.ms();
|
|
507
|
-
const perFunction = executionSteps.map(({ functionName, timings: { witgen } })=>
|
|
519
|
+
const perFunction = executionSteps.map(({ functionName, timings: { witgen, oracles } })=>{
|
|
520
|
+
return {
|
|
508
521
|
functionName,
|
|
509
|
-
time: witgen
|
|
510
|
-
|
|
522
|
+
time: witgen,
|
|
523
|
+
oracles
|
|
524
|
+
};
|
|
525
|
+
});
|
|
511
526
|
// Gate computation is time is not relevant for profiling, so we subtract it from the total time.
|
|
512
527
|
const gateCountComputationTime = executionSteps.reduce((acc, { timings })=>acc + (timings.gateCount ?? 0), 0) ?? 0;
|
|
528
|
+
const total = totalTime - gateCountComputationTime;
|
|
513
529
|
const timings = {
|
|
514
|
-
total
|
|
530
|
+
total,
|
|
515
531
|
sync: syncTime,
|
|
516
532
|
proving,
|
|
517
533
|
perFunction,
|
|
518
|
-
unaccounted:
|
|
534
|
+
unaccounted: total - ((syncTime ?? 0) + (proving ?? 0) + perFunction.reduce((acc, { time })=>acc + time, 0))
|
|
519
535
|
};
|
|
520
|
-
|
|
536
|
+
const simulatorStats = contractFunctionSimulator.getStats();
|
|
537
|
+
return new TxProfileResult(executionSteps, {
|
|
538
|
+
timings,
|
|
539
|
+
nodeRPCCalls: simulatorStats.nodeRPCCalls
|
|
540
|
+
});
|
|
521
541
|
} catch (err) {
|
|
522
542
|
throw this.#contextualizeError(err, inspect(txRequest), `profileMode=${profileMode}`, `msgSender=${msgSender?.toString() ?? 'undefined'}`);
|
|
523
543
|
}
|
|
@@ -544,7 +564,8 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
544
564
|
const syncTimer = new Timer();
|
|
545
565
|
await this.synchronizer.sync();
|
|
546
566
|
const syncTime = syncTimer.ms();
|
|
547
|
-
const
|
|
567
|
+
const contractFunctionSimulator = this.#getSimulatorForTx();
|
|
568
|
+
const privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest, msgSender, scopes);
|
|
548
569
|
const { publicInputs, executionSteps } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
|
|
549
570
|
simulate: true,
|
|
550
571
|
skipFeeEnforcement,
|
|
@@ -573,9 +594,10 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
573
594
|
}
|
|
574
595
|
const txHash = await simulatedTx.getTxHash();
|
|
575
596
|
const totalTime = totalTimer.ms();
|
|
576
|
-
const perFunction = executionSteps.map(({ functionName, timings: { witgen } })=>({
|
|
597
|
+
const perFunction = executionSteps.map(({ functionName, timings: { witgen, oracles } })=>({
|
|
577
598
|
functionName,
|
|
578
|
-
time: witgen
|
|
599
|
+
time: witgen,
|
|
600
|
+
oracles
|
|
579
601
|
}));
|
|
580
602
|
const timings = {
|
|
581
603
|
total: totalTime,
|
|
@@ -592,10 +614,13 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
592
614
|
gasUsed: publicOutput.gasUsed,
|
|
593
615
|
revertCode: publicOutput.txEffect.revertCode.getCode(),
|
|
594
616
|
revertReason: publicOutput.revertReason
|
|
595
|
-
} : {}
|
|
596
|
-
|
|
617
|
+
} : {}
|
|
618
|
+
});
|
|
619
|
+
const simulatorStats = contractFunctionSimulator.getStats();
|
|
620
|
+
return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput(privateSimulationResult, publicOutput, {
|
|
621
|
+
timings,
|
|
622
|
+
nodeRPCCalls: simulatorStats.nodeRPCCalls
|
|
597
623
|
});
|
|
598
|
-
return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput(privateSimulationResult, publicOutput, timings);
|
|
599
624
|
} catch (err) {
|
|
600
625
|
throw this.#contextualizeError(err, inspect(txRequest), `simulatePublic=${simulatePublic}`, `msgSender=${msgSender?.toString() ?? 'undefined'}`, `skipTxValidation=${skipTxValidation}`, `scopes=${scopes?.map((s)=>s.toString()).join(', ') ?? 'undefined'}`);
|
|
601
626
|
}
|
|
@@ -626,7 +651,8 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
626
651
|
// TODO - Should check if `from` has the permission to call the view function.
|
|
627
652
|
const functionCall = await this.#getFunctionCall(functionName, args, to);
|
|
628
653
|
const functionTimer = new Timer();
|
|
629
|
-
const
|
|
654
|
+
const contractFunctionSimulator = this.#getSimulatorForTx();
|
|
655
|
+
const executionResult = await this.#simulateUtility(contractFunctionSimulator, functionCall, authwits ?? [], scopes);
|
|
630
656
|
const functionTime = functionTimer.ms();
|
|
631
657
|
const totalTime = totalTimer.ms();
|
|
632
658
|
const perFunction = [
|
|
@@ -641,9 +667,13 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
641
667
|
perFunction,
|
|
642
668
|
unaccounted: totalTime - (syncTime + perFunction.reduce((acc, { time })=>acc + time, 0))
|
|
643
669
|
};
|
|
670
|
+
const simulationStats = contractFunctionSimulator.getStats();
|
|
644
671
|
return {
|
|
645
672
|
result: executionResult,
|
|
646
|
-
|
|
673
|
+
stats: {
|
|
674
|
+
timings,
|
|
675
|
+
nodeRPCCalls: simulationStats.nodeRPCCalls
|
|
676
|
+
}
|
|
647
677
|
};
|
|
648
678
|
} catch (err) {
|
|
649
679
|
const stringifiedArgs = args.map((arg)=>arg.toString()).join(', ');
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
2
|
import { BufferReader } from '@aztec/foundation/serialize';
|
|
3
|
-
import type { NoteData } from '@aztec/simulator/client';
|
|
4
3
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
4
|
import { Note } from '@aztec/stdlib/note';
|
|
6
5
|
import { TxHash } from '@aztec/stdlib/tx';
|
|
6
|
+
import type { NoteData } from '../../contract_function_simulator/oracle/typed_oracle.js';
|
|
7
7
|
/**
|
|
8
8
|
* A Note Data Access Object, representing a note that was committed to the note hash tree, holding all of the
|
|
9
9
|
* information required to use it during execution and manage its state.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"note_dao.d.ts","sourceRoot":"","sources":["../../../src/storage/note_data_provider/note_dao.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAS,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,YAAY,EAAqB,MAAM,6BAA6B,CAAC;AAC9E,OAAO,
|
|
1
|
+
{"version":3,"file":"note_dao.d.ts","sourceRoot":"","sources":["../../../src/storage/note_data_provider/note_dao.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAS,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,YAAY,EAAqB,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0DAA0D,CAAC;AAEzF;;;GAGG;AACH,qBAAa,OAAQ,YAAW,QAAQ;IAIpC,kFAAkF;IAC3E,IAAI,EAAE,IAAI;IACjB,8GAA8G;IACvG,eAAe,EAAE,YAAY;IACpC;;;SAGK;IACE,WAAW,EAAE,EAAE;IACtB,qFAAqF;IAC9E,KAAK,EAAE,EAAE;IAGhB;;;OAGG;IACI,QAAQ,EAAE,EAAE;IACnB;;;OAGG;IACI,eAAe,EAAE,EAAE;IAG1B;;OAEG;IACI,MAAM,EAAE,MAAM;IACrB;gBACY;IACL,aAAa,EAAE,MAAM;IAC5B;gBACY;IACL,WAAW,EAAE,MAAM;IAC1B,+EAA+E;IACxE,KAAK,EAAE,MAAM;IACpB;;;OAGG;IACI,SAAS,EAAE,YAAY;;IAzC9B,kFAAkF;IAC3E,IAAI,EAAE,IAAI;IACjB,8GAA8G;IACvG,eAAe,EAAE,YAAY;IACpC;;;SAGK;IACE,WAAW,EAAE,EAAE;IACtB,qFAAqF;IAC9E,KAAK,EAAE,EAAE;IAGhB;;;OAGG;IACI,QAAQ,EAAE,EAAE;IACnB;;;OAGG;IACI,eAAe,EAAE,EAAE;IAG1B;;OAEG;IACI,MAAM,EAAE,MAAM;IACrB;gBACY;IACL,aAAa,EAAE,MAAM;IAC5B;gBACY;IACL,WAAW,EAAE,MAAM;IAC1B,+EAA+E;IACxE,KAAK,EAAE,MAAM;IACpB;;;OAGG;IACI,SAAS,EAAE,YAAY;IAGhC,QAAQ,IAAI,MAAM;IAgBlB,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IA8B/C,QAAQ;IAIR,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM;IAK7B;;;OAGG;IACI,OAAO;WAMD,MAAM,CAAC,EAClB,IAAoB,EACpB,eAA2B,EAC3B,WAAyB,EACzB,KAAmB,EACnB,QAAsB,EACtB,eAA6B,EAC7B,MAAwB,EACxB,aAAgD,EAChD,WAAoC,EACpC,KAA8B,EAC9B,SAAqB,GACtB,GAAE,OAAO,CAAC,OAAO,CAAM;CAezB"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/pxe",
|
|
3
|
-
"version": "0.87.
|
|
3
|
+
"version": "0.87.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./server": "./dest/entrypoints/server/index.js",
|
|
7
7
|
"./client/lazy": "./dest/entrypoints/client/lazy/index.js",
|
|
8
8
|
"./client/bundle": "./dest/entrypoints/client/bundle/index.js",
|
|
9
|
+
"./simulator": "./dest/contract_function_simulator/index.js",
|
|
9
10
|
"./config": "./dest/config/index.js",
|
|
10
11
|
"./testing": "./dest/test/pxe_test_suite.js"
|
|
11
12
|
},
|
|
@@ -57,19 +58,19 @@
|
|
|
57
58
|
]
|
|
58
59
|
},
|
|
59
60
|
"dependencies": {
|
|
60
|
-
"@aztec/bb-prover": "0.87.
|
|
61
|
-
"@aztec/bb.js": "0.87.
|
|
62
|
-
"@aztec/builder": "0.87.
|
|
63
|
-
"@aztec/constants": "0.87.
|
|
64
|
-
"@aztec/ethereum": "0.87.
|
|
65
|
-
"@aztec/foundation": "0.87.
|
|
66
|
-
"@aztec/key-store": "0.87.
|
|
67
|
-
"@aztec/kv-store": "0.87.
|
|
68
|
-
"@aztec/noir-protocol-circuits-types": "0.87.
|
|
69
|
-
"@aztec/noir-types": "0.87.
|
|
70
|
-
"@aztec/protocol-contracts": "0.87.
|
|
71
|
-
"@aztec/simulator": "0.87.
|
|
72
|
-
"@aztec/stdlib": "0.87.
|
|
61
|
+
"@aztec/bb-prover": "0.87.7",
|
|
62
|
+
"@aztec/bb.js": "0.87.7",
|
|
63
|
+
"@aztec/builder": "0.87.7",
|
|
64
|
+
"@aztec/constants": "0.87.7",
|
|
65
|
+
"@aztec/ethereum": "0.87.7",
|
|
66
|
+
"@aztec/foundation": "0.87.7",
|
|
67
|
+
"@aztec/key-store": "0.87.7",
|
|
68
|
+
"@aztec/kv-store": "0.87.7",
|
|
69
|
+
"@aztec/noir-protocol-circuits-types": "0.87.7",
|
|
70
|
+
"@aztec/noir-types": "0.87.7",
|
|
71
|
+
"@aztec/protocol-contracts": "0.87.7",
|
|
72
|
+
"@aztec/simulator": "0.87.7",
|
|
73
|
+
"@aztec/stdlib": "0.87.7",
|
|
73
74
|
"koa": "^2.16.1",
|
|
74
75
|
"koa-router": "^12.0.0",
|
|
75
76
|
"lodash.omit": "^4.5.0",
|
|
@@ -78,7 +79,8 @@
|
|
|
78
79
|
"viem": "2.23.7"
|
|
79
80
|
},
|
|
80
81
|
"devDependencies": {
|
|
81
|
-
"@aztec/
|
|
82
|
+
"@aztec/merkle-tree": "0.87.7",
|
|
83
|
+
"@aztec/noir-test-contracts.js": "0.87.7",
|
|
82
84
|
"@jest/globals": "^29.5.0",
|
|
83
85
|
"@types/jest": "^29.5.0",
|
|
84
86
|
"@types/lodash.omit": "^4.5.7",
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
3
|
+
import { Timer } from '@aztec/foundation/timer';
|
|
4
|
+
import {
|
|
5
|
+
type CircuitSimulator,
|
|
6
|
+
ExecutionError,
|
|
7
|
+
createSimulationError,
|
|
8
|
+
extractCallStack,
|
|
9
|
+
resolveAssertionMessageFromError,
|
|
10
|
+
toACVMWitness,
|
|
11
|
+
witnessMapToFields,
|
|
12
|
+
} from '@aztec/simulator/client';
|
|
13
|
+
import type { AbiDecoded, FunctionCall } from '@aztec/stdlib/abi';
|
|
14
|
+
import { FunctionSelector, FunctionType, decodeFromAbi } from '@aztec/stdlib/abi';
|
|
15
|
+
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
16
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
17
|
+
import { CallContext, HashedValues, PrivateExecutionResult, TxExecutionRequest, collectNested } from '@aztec/stdlib/tx';
|
|
18
|
+
|
|
19
|
+
import type { ExecutionDataProvider } from './execution_data_provider.js';
|
|
20
|
+
import { ExecutionNoteCache } from './execution_note_cache.js';
|
|
21
|
+
import { HashedValuesCache } from './hashed_values_cache.js';
|
|
22
|
+
import { Oracle } from './oracle/oracle.js';
|
|
23
|
+
import { executePrivateFunction, verifyCurrentClassId } from './oracle/private_execution.js';
|
|
24
|
+
import { PrivateExecutionOracle } from './oracle/private_execution_oracle.js';
|
|
25
|
+
import { UtilityExecutionOracle } from './oracle/utility_execution_oracle.js';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The contract function simulator.
|
|
29
|
+
*/
|
|
30
|
+
export class ContractFunctionSimulator {
|
|
31
|
+
private log: Logger;
|
|
32
|
+
|
|
33
|
+
constructor(
|
|
34
|
+
private executionDataProvider: ExecutionDataProvider,
|
|
35
|
+
private simulator: CircuitSimulator,
|
|
36
|
+
) {
|
|
37
|
+
this.log = createLogger('simulator');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Runs a private function.
|
|
42
|
+
* @param request - The transaction request.
|
|
43
|
+
* @param entryPointArtifact - The artifact of the entry point function.
|
|
44
|
+
* @param contractAddress - The address of the contract (should match request.origin)
|
|
45
|
+
* @param msgSender - The address calling the function. This can be replaced to simulate a call from another contract or a specific account.
|
|
46
|
+
* @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all.
|
|
47
|
+
* @returns The result of the execution.
|
|
48
|
+
*/
|
|
49
|
+
public async run(
|
|
50
|
+
request: TxExecutionRequest,
|
|
51
|
+
contractAddress: AztecAddress,
|
|
52
|
+
selector: FunctionSelector,
|
|
53
|
+
msgSender = AztecAddress.fromField(Fr.MAX_FIELD_VALUE),
|
|
54
|
+
scopes?: AztecAddress[],
|
|
55
|
+
): Promise<PrivateExecutionResult> {
|
|
56
|
+
const simulatorSetupTimer = new Timer();
|
|
57
|
+
const header = await this.executionDataProvider.getBlockHeader();
|
|
58
|
+
|
|
59
|
+
await verifyCurrentClassId(contractAddress, this.executionDataProvider);
|
|
60
|
+
const entryPointArtifact = await this.executionDataProvider.getFunctionArtifact(contractAddress, selector);
|
|
61
|
+
|
|
62
|
+
if (entryPointArtifact.functionType !== FunctionType.PRIVATE) {
|
|
63
|
+
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as private`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (request.origin !== contractAddress) {
|
|
67
|
+
this.log.warn(
|
|
68
|
+
`Request origin does not match contract address in simulation. Request origin: ${request.origin}, contract address: ${contractAddress}`,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// reserve the first side effect for the tx hash (inserted by the private kernel)
|
|
73
|
+
const startSideEffectCounter = 1;
|
|
74
|
+
|
|
75
|
+
const callContext = new CallContext(
|
|
76
|
+
msgSender,
|
|
77
|
+
contractAddress,
|
|
78
|
+
await FunctionSelector.fromNameAndParameters(entryPointArtifact.name, entryPointArtifact.parameters),
|
|
79
|
+
entryPointArtifact.isStatic,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const txRequestHash = await request.toTxRequest().hash();
|
|
83
|
+
const noteCache = new ExecutionNoteCache(txRequestHash);
|
|
84
|
+
|
|
85
|
+
const context = new PrivateExecutionOracle(
|
|
86
|
+
request.firstCallArgsHash,
|
|
87
|
+
request.txContext,
|
|
88
|
+
callContext,
|
|
89
|
+
header,
|
|
90
|
+
request.authWitnesses,
|
|
91
|
+
request.capsules,
|
|
92
|
+
HashedValuesCache.create(request.argsOfCalls),
|
|
93
|
+
noteCache,
|
|
94
|
+
this.executionDataProvider,
|
|
95
|
+
this.simulator,
|
|
96
|
+
/*totalPublicArgsCount=*/ 0,
|
|
97
|
+
startSideEffectCounter,
|
|
98
|
+
undefined,
|
|
99
|
+
scopes,
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const setupTime = simulatorSetupTimer.ms();
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
const executionResult = await executePrivateFunction(
|
|
106
|
+
this.simulator,
|
|
107
|
+
context,
|
|
108
|
+
entryPointArtifact,
|
|
109
|
+
contractAddress,
|
|
110
|
+
request.functionSelector,
|
|
111
|
+
);
|
|
112
|
+
const simulatorTeardownTimer = new Timer();
|
|
113
|
+
const { usedTxRequestHashForNonces } = noteCache.finish();
|
|
114
|
+
const firstNullifierHint = usedTxRequestHashForNonces ? Fr.ZERO : noteCache.getAllNullifiers()[0];
|
|
115
|
+
|
|
116
|
+
const publicCallRequests = collectNested([executionResult], r => [
|
|
117
|
+
...r.publicInputs.publicCallRequests.map(r => r.inner),
|
|
118
|
+
r.publicInputs.publicTeardownCallRequest,
|
|
119
|
+
]).filter(r => !r.isEmpty());
|
|
120
|
+
const publicFunctionsCalldata = await Promise.all(
|
|
121
|
+
publicCallRequests.map(async r => {
|
|
122
|
+
const calldata = await context.loadFromExecutionCache(r.calldataHash);
|
|
123
|
+
return new HashedValues(calldata, r.calldataHash);
|
|
124
|
+
}),
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
const teardownTime = simulatorTeardownTimer.ms();
|
|
128
|
+
|
|
129
|
+
// Add simulator overhead to topmost call in the stack
|
|
130
|
+
if (executionResult.profileResult) {
|
|
131
|
+
executionResult.profileResult.timings.witgen += setupTime + teardownTime;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return new PrivateExecutionResult(executionResult, firstNullifierHint, publicFunctionsCalldata);
|
|
135
|
+
} catch (err) {
|
|
136
|
+
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// docs:start:execute_utility_function
|
|
141
|
+
/**
|
|
142
|
+
* Runs a utility function.
|
|
143
|
+
* @param call - The function call to execute.
|
|
144
|
+
* @param authwits - Authentication witnesses required for the function call.
|
|
145
|
+
* @param scopes - Optional array of account addresses whose notes can be accessed in this call. Defaults to all
|
|
146
|
+
* accounts if not specified.
|
|
147
|
+
* @returns A decoded ABI value containing the function's return data.
|
|
148
|
+
*/
|
|
149
|
+
public async runUtility(call: FunctionCall, authwits: AuthWitness[], scopes?: AztecAddress[]): Promise<AbiDecoded> {
|
|
150
|
+
await verifyCurrentClassId(call.to, this.executionDataProvider);
|
|
151
|
+
const entryPointArtifact = await this.executionDataProvider.getFunctionArtifact(call.to, call.selector);
|
|
152
|
+
|
|
153
|
+
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
154
|
+
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const oracle = new UtilityExecutionOracle(call.to, authwits, [], this.executionDataProvider, undefined, scopes);
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
this.log.verbose(`Executing utility function ${entryPointArtifact.name}`, {
|
|
161
|
+
contract: call.to,
|
|
162
|
+
selector: call.selector,
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const initialWitness = toACVMWitness(0, call.args);
|
|
166
|
+
const acirExecutionResult = await this.simulator
|
|
167
|
+
.executeUserCircuit(initialWitness, entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
168
|
+
.catch((err: Error) => {
|
|
169
|
+
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
170
|
+
throw new ExecutionError(
|
|
171
|
+
err.message,
|
|
172
|
+
{
|
|
173
|
+
contractAddress: call.to,
|
|
174
|
+
functionSelector: call.selector,
|
|
175
|
+
},
|
|
176
|
+
extractCallStack(err, entryPointArtifact.debug),
|
|
177
|
+
{ cause: err },
|
|
178
|
+
);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
const returnWitness = witnessMapToFields(acirExecutionResult.returnWitness);
|
|
182
|
+
this.log.verbose(`Utility simulation for ${call.to}.${call.selector} completed`);
|
|
183
|
+
return decodeFromAbi(entryPointArtifact.returnTypes, returnWitness);
|
|
184
|
+
} catch (err) {
|
|
185
|
+
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// docs:end:execute_utility_function
|
|
189
|
+
|
|
190
|
+
getStats() {
|
|
191
|
+
return this.executionDataProvider.getStats();
|
|
192
|
+
}
|
|
193
|
+
}
|