@aztec/pxe 0.80.0 → 0.82.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/config/package_info.js +1 -1
- package/dest/entrypoints/server/utils.d.ts +15 -7
- package/dest/entrypoints/server/utils.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.js +17 -9
- package/dest/{kernel_prover → private_kernel}/hints/build_private_kernel_reset_private_inputs.d.ts +2 -2
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -0
- package/dest/private_kernel/hints/index.d.ts.map +1 -0
- package/dest/private_kernel/index.d.ts +3 -0
- package/dest/private_kernel/index.d.ts.map +1 -0
- package/dest/private_kernel/index.js +2 -0
- package/dest/{kernel_prover/kernel_prover.d.ts → private_kernel/private_kernel_execution_prover.d.ts} +13 -14
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -0
- package/dest/{kernel_prover/kernel_prover.js → private_kernel/private_kernel_execution_prover.js} +64 -64
- package/dest/{kernel_prover/proving_data_oracle.d.ts → private_kernel/private_kernel_oracle.d.ts} +17 -28
- package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -0
- package/dest/private_kernel/private_kernel_oracle.js +4 -0
- package/dest/{kernel_oracle/index.d.ts → private_kernel/private_kernel_oracle_impl.d.ts} +5 -5
- package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +1 -0
- package/dest/{kernel_oracle/index.js → private_kernel/private_kernel_oracle_impl.js} +2 -2
- package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts +14 -22
- package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts.map +1 -1
- package/dest/pxe_oracle_interface/pxe_oracle_interface.js +51 -107
- package/dest/pxe_service/pxe_service.d.ts +13 -27
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +213 -241
- package/dest/storage/contract_data_provider/contract_data_provider.d.ts +2 -2
- package/dest/storage/contract_data_provider/contract_data_provider.d.ts.map +1 -1
- package/dest/storage/contract_data_provider/contract_data_provider.js +6 -1
- package/dest/storage/contract_data_provider/private_functions_tree.d.ts +2 -2
- package/dest/storage/contract_data_provider/private_functions_tree.d.ts.map +1 -1
- package/dest/storage/index.d.ts +1 -2
- package/dest/storage/index.d.ts.map +1 -1
- package/dest/storage/index.js +1 -2
- package/dest/storage/metadata.d.ts +2 -0
- package/dest/storage/metadata.d.ts.map +1 -0
- package/dest/storage/metadata.js +1 -0
- package/dest/storage/note_data_provider/note_dao.d.ts +9 -13
- package/dest/storage/note_data_provider/note_dao.d.ts.map +1 -1
- package/dest/storage/note_data_provider/note_dao.js +11 -15
- package/dest/storage/note_data_provider/note_data_provider.d.ts +2 -2
- package/dest/storage/note_data_provider/note_data_provider.d.ts.map +1 -1
- package/dest/storage/note_data_provider/note_data_provider.js +18 -19
- package/dest/synchronizer/synchronizer.js +1 -1
- package/package.json +15 -15
- package/src/config/package_info.ts +1 -1
- package/src/entrypoints/server/utils.ts +25 -11
- package/src/{kernel_prover → private_kernel}/hints/build_private_kernel_reset_private_inputs.ts +4 -4
- package/src/private_kernel/index.ts +2 -0
- package/src/{kernel_prover/kernel_prover.ts → private_kernel/private_kernel_execution_prover.ts} +76 -71
- package/src/{kernel_prover/proving_data_oracle.ts → private_kernel/private_kernel_oracle.ts} +17 -29
- package/src/{kernel_oracle/index.ts → private_kernel/private_kernel_oracle_impl.ts} +6 -5
- package/src/pxe_oracle_interface/pxe_oracle_interface.ts +77 -153
- package/src/pxe_service/pxe_service.ts +289 -310
- package/src/storage/contract_data_provider/contract_data_provider.ts +11 -2
- package/src/storage/contract_data_provider/private_functions_tree.ts +2 -2
- package/src/storage/index.ts +1 -3
- package/src/storage/metadata.ts +1 -0
- package/src/storage/note_data_provider/note_dao.ts +9 -18
- package/src/storage/note_data_provider/note_data_provider.ts +22 -28
- package/src/synchronizer/synchronizer.ts +1 -1
- package/dest/kernel_oracle/index.d.ts.map +0 -1
- package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts.map +0 -1
- package/dest/kernel_prover/hints/index.d.ts.map +0 -1
- package/dest/kernel_prover/index.d.ts +0 -3
- package/dest/kernel_prover/index.d.ts.map +0 -1
- package/dest/kernel_prover/index.js +0 -2
- package/dest/kernel_prover/kernel_prover.d.ts.map +0 -1
- package/dest/kernel_prover/proving_data_oracle.d.ts.map +0 -1
- package/dest/kernel_prover/proving_data_oracle.js +0 -4
- package/dest/note_decryption_utils/add_public_values_to_payload.d.ts +0 -11
- package/dest/note_decryption_utils/add_public_values_to_payload.d.ts.map +0 -1
- package/dest/note_decryption_utils/add_public_values_to_payload.js +0 -47
- package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.d.ts +0 -11
- package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.d.ts.map +0 -1
- package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.js +0 -20
- package/dest/storage/auth_witness_data_provider/index.d.ts +0 -2
- package/dest/storage/auth_witness_data_provider/index.d.ts.map +0 -1
- package/dest/storage/auth_witness_data_provider/index.js +0 -1
- package/src/kernel_prover/index.ts +0 -2
- package/src/note_decryption_utils/add_public_values_to_payload.ts +0 -64
- package/src/storage/auth_witness_data_provider/auth_witness_data_provider.ts +0 -34
- package/src/storage/auth_witness_data_provider/index.ts +0 -1
- /package/dest/{kernel_prover → private_kernel}/hints/build_private_kernel_reset_private_inputs.js +0 -0
- /package/dest/{kernel_prover → private_kernel}/hints/index.d.ts +0 -0
- /package/dest/{kernel_prover → private_kernel}/hints/index.js +0 -0
- /package/src/{kernel_prover → private_kernel}/hints/index.ts +0 -0
|
@@ -32,8 +32,9 @@ import {
|
|
|
32
32
|
type ContractInstanceWithAddress,
|
|
33
33
|
type NodeInfo,
|
|
34
34
|
type PartialAddress,
|
|
35
|
+
computeContractAddressFromInstance,
|
|
36
|
+
getContractClassFromArtifact,
|
|
35
37
|
} from '@aztec/stdlib/contract';
|
|
36
|
-
import { computeContractAddressFromInstance, getContractClassFromArtifact } from '@aztec/stdlib/contract';
|
|
37
38
|
import { SimulationError } from '@aztec/stdlib/errors';
|
|
38
39
|
import { EventMetadata, L1EventPayload } from '@aztec/stdlib/event';
|
|
39
40
|
import type { GasFees } from '@aztec/stdlib/gas';
|
|
@@ -47,7 +48,7 @@ import type {
|
|
|
47
48
|
PXEInfo,
|
|
48
49
|
PrivateKernelProver,
|
|
49
50
|
} from '@aztec/stdlib/interfaces/client';
|
|
50
|
-
import {
|
|
51
|
+
import type { PrivateKernelExecutionProofOutput, PrivateKernelTailCircuitPublicInputs } from '@aztec/stdlib/kernel';
|
|
51
52
|
import { computeAddressSecret } from '@aztec/stdlib/keys';
|
|
52
53
|
import type { LogFilter } from '@aztec/stdlib/logs';
|
|
53
54
|
import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
|
|
@@ -56,11 +57,12 @@ import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
|
56
57
|
import {
|
|
57
58
|
PrivateExecutionResult,
|
|
58
59
|
PrivateSimulationResult,
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
PublicSimulationOutput,
|
|
61
|
+
Tx,
|
|
61
62
|
type TxEffect,
|
|
62
|
-
|
|
63
|
+
TxExecutionRequest,
|
|
63
64
|
type TxHash,
|
|
65
|
+
TxProfileResult,
|
|
64
66
|
TxProvingResult,
|
|
65
67
|
type TxReceipt,
|
|
66
68
|
TxSimulationResult,
|
|
@@ -70,11 +72,13 @@ import { inspect } from 'util';
|
|
|
70
72
|
|
|
71
73
|
import type { PXEServiceConfig } from '../config/index.js';
|
|
72
74
|
import { getPackageInfo } from '../config/package_info.js';
|
|
73
|
-
import {
|
|
74
|
-
|
|
75
|
+
import {
|
|
76
|
+
PrivateKernelExecutionProver,
|
|
77
|
+
type PrivateKernelExecutionProverConfig,
|
|
78
|
+
} from '../private_kernel/private_kernel_execution_prover.js';
|
|
79
|
+
import { PrivateKernelOracleImpl } from '../private_kernel/private_kernel_oracle_impl.js';
|
|
75
80
|
import { PXEOracleInterface } from '../pxe_oracle_interface/pxe_oracle_interface.js';
|
|
76
81
|
import { AddressDataProvider } from '../storage/address_data_provider/address_data_provider.js';
|
|
77
|
-
import { AuthWitnessDataProvider } from '../storage/auth_witness_data_provider/auth_witness_data_provider.js';
|
|
78
82
|
import { CapsuleDataProvider } from '../storage/capsule_data_provider/capsule_data_provider.js';
|
|
79
83
|
import { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
|
|
80
84
|
import { NoteDataProvider } from '../storage/note_data_provider/note_data_provider.js';
|
|
@@ -97,7 +101,6 @@ export class PXEService implements PXE {
|
|
|
97
101
|
private syncDataProvider: SyncDataProvider,
|
|
98
102
|
private taggingDataProvider: TaggingDataProvider,
|
|
99
103
|
private addressDataProvider: AddressDataProvider,
|
|
100
|
-
private authWitnessDataProvider: AuthWitnessDataProvider,
|
|
101
104
|
private simulator: AcirSimulator,
|
|
102
105
|
private packageVersion: string,
|
|
103
106
|
private proverEnabled: boolean,
|
|
@@ -131,7 +134,6 @@ export class PXEService implements PXE {
|
|
|
131
134
|
const packageVersion = getPackageInfo().version;
|
|
132
135
|
const proverEnabled = !!config.proverEnabled;
|
|
133
136
|
const addressDataProvider = new AddressDataProvider(store);
|
|
134
|
-
const authWitnessDataProvider = new AuthWitnessDataProvider(store);
|
|
135
137
|
const contractDataProvider = new ContractDataProvider(store);
|
|
136
138
|
const noteDataProvider = await NoteDataProvider.create(store);
|
|
137
139
|
const syncDataProvider = new SyncDataProvider(store);
|
|
@@ -158,7 +160,6 @@ export class PXEService implements PXE {
|
|
|
158
160
|
syncDataProvider,
|
|
159
161
|
taggingDataProvider,
|
|
160
162
|
addressDataProvider,
|
|
161
|
-
authWitnessDataProvider,
|
|
162
163
|
log,
|
|
163
164
|
);
|
|
164
165
|
const simulator = new AcirSimulator(pxeOracleInterface, simulationProvider);
|
|
@@ -174,7 +175,6 @@ export class PXEService implements PXE {
|
|
|
174
175
|
syncDataProvider,
|
|
175
176
|
taggingDataProvider,
|
|
176
177
|
addressDataProvider,
|
|
177
|
-
authWitnessDataProvider,
|
|
178
178
|
simulator,
|
|
179
179
|
packageVersion,
|
|
180
180
|
proverEnabled,
|
|
@@ -192,6 +192,68 @@ export class PXEService implements PXE {
|
|
|
192
192
|
return pxeService;
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
+
// Aztec node proxy methods
|
|
196
|
+
|
|
197
|
+
public isL1ToL2MessageSynced(l1ToL2Message: Fr): Promise<boolean> {
|
|
198
|
+
return this.node.isL1ToL2MessageSynced(l1ToL2Message);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
public getL2ToL1MembershipWitness(blockNumber: number, l2Tol1Message: Fr): Promise<[bigint, SiblingPath<number>]> {
|
|
202
|
+
return this.node.getL2ToL1MessageMembershipWitness(blockNumber, l2Tol1Message);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
public getTxReceipt(txHash: TxHash): Promise<TxReceipt> {
|
|
206
|
+
return this.node.getTxReceipt(txHash);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
public getTxEffect(txHash: TxHash): Promise<InBlock<TxEffect> | undefined> {
|
|
210
|
+
return this.node.getTxEffect(txHash);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
public getBlockNumber(): Promise<number> {
|
|
214
|
+
return this.node.getBlockNumber();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
public getProvenBlockNumber(): Promise<number> {
|
|
218
|
+
return this.node.getProvenBlockNumber();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
public getPublicLogs(filter: LogFilter): Promise<GetPublicLogsResponse> {
|
|
222
|
+
return this.node.getPublicLogs(filter);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
public getContractClassLogs(filter: LogFilter): Promise<GetContractClassLogsResponse> {
|
|
226
|
+
return this.node.getContractClassLogs(filter);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
public getPublicStorageAt(contract: AztecAddress, slot: Fr) {
|
|
230
|
+
return this.node.getPublicStorageAt('latest', contract, slot);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
public async getL1ToL2MembershipWitness(
|
|
234
|
+
contractAddress: AztecAddress,
|
|
235
|
+
messageHash: Fr,
|
|
236
|
+
secret: Fr,
|
|
237
|
+
): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>]> {
|
|
238
|
+
return await getNonNullifiedL1ToL2MessageWitness(this.node, contractAddress, messageHash, secret);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Internal methods
|
|
242
|
+
|
|
243
|
+
#contextualizeError(err: Error, ...context: string[]): Error {
|
|
244
|
+
let contextStr = '';
|
|
245
|
+
if (context.length > 0) {
|
|
246
|
+
contextStr = `\nContext:\n${context.join('\n')}`;
|
|
247
|
+
}
|
|
248
|
+
if (err instanceof SimulationError) {
|
|
249
|
+
err.setAztecContext(contextStr);
|
|
250
|
+
} else {
|
|
251
|
+
this.log.error(err.name, err);
|
|
252
|
+
this.log.debug(contextStr);
|
|
253
|
+
}
|
|
254
|
+
return err;
|
|
255
|
+
}
|
|
256
|
+
|
|
195
257
|
/**
|
|
196
258
|
* Enqueues a job for execution once no other jobs are running. Returns a promise that will resolve once the job is
|
|
197
259
|
* complete.
|
|
@@ -209,16 +271,164 @@ export class PXEService implements PXE {
|
|
|
209
271
|
return this.jobQueue.put(fn);
|
|
210
272
|
}
|
|
211
273
|
|
|
212
|
-
|
|
213
|
-
|
|
274
|
+
async #registerProtocolContracts() {
|
|
275
|
+
const registered: Record<string, string> = {};
|
|
276
|
+
for (const name of protocolContractNames) {
|
|
277
|
+
const { address, contractClass, instance, artifact } =
|
|
278
|
+
await this.protocolContractsProvider.getProtocolContractArtifact(name);
|
|
279
|
+
await this.contractDataProvider.addContractArtifact(contractClass.id, artifact);
|
|
280
|
+
await this.contractDataProvider.addContractInstance(instance);
|
|
281
|
+
registered[name] = address.toString();
|
|
282
|
+
}
|
|
283
|
+
this.log.verbose(`Registered protocol contracts in pxe`, registered);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
async #isContractClassPubliclyRegistered(id: Fr): Promise<boolean> {
|
|
287
|
+
return !!(await this.node.getContractClass(id));
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
async #isContractPubliclyDeployed(address: AztecAddress): Promise<boolean> {
|
|
291
|
+
return !!(await this.node.getContract(address));
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
async #isContractInitialized(address: AztecAddress): Promise<boolean> {
|
|
295
|
+
const initNullifier = await siloNullifier(address, address.toField());
|
|
296
|
+
return !!(await this.node.getNullifierMembershipWitness('latest', initNullifier));
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
async #getFunctionCall(functionName: string, args: any[], to: AztecAddress): Promise<FunctionCall> {
|
|
300
|
+
const contract = await this.contractDataProvider.getContract(to);
|
|
301
|
+
if (!contract) {
|
|
302
|
+
throw new Error(
|
|
303
|
+
`Unknown contract ${to}: add it to PXE Service by calling server.addContracts(...).\nSee docs for context: https://docs.aztec.network/developers/reference/debugging/aztecnr-errors#unknown-contract-0x0-add-it-to-pxe-by-calling-serveraddcontracts`,
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const functionDao = contract.functions.find(f => f.name === functionName);
|
|
308
|
+
if (!functionDao) {
|
|
309
|
+
throw new Error(`Unknown function ${functionName} in contract ${contract.name}.`);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return {
|
|
313
|
+
name: functionDao.name,
|
|
314
|
+
args: encodeArguments(functionDao, args),
|
|
315
|
+
selector: await FunctionSelector.fromNameAndParameters(functionDao.name, functionDao.parameters),
|
|
316
|
+
type: functionDao.functionType,
|
|
317
|
+
to,
|
|
318
|
+
isStatic: functionDao.isStatic,
|
|
319
|
+
returnTypes: functionDao.returnTypes,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
async #executePrivate(
|
|
324
|
+
txRequest: TxExecutionRequest,
|
|
325
|
+
msgSender?: AztecAddress,
|
|
326
|
+
scopes?: AztecAddress[],
|
|
327
|
+
): Promise<PrivateExecutionResult> {
|
|
328
|
+
const { origin: contractAddress, functionSelector } = txRequest;
|
|
329
|
+
|
|
330
|
+
try {
|
|
331
|
+
const result = await this.simulator.run(txRequest, contractAddress, functionSelector, msgSender, scopes);
|
|
332
|
+
this.log.debug(`Private simulation completed for ${contractAddress.toString()}:${functionSelector}`);
|
|
333
|
+
return result;
|
|
334
|
+
} catch (err) {
|
|
335
|
+
if (err instanceof SimulationError) {
|
|
336
|
+
await enrichSimulationError(err, this.contractDataProvider, this.log);
|
|
337
|
+
}
|
|
338
|
+
throw err;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Simulate an unconstrained transaction on the given contract, without considering constraints set by ACIR.
|
|
344
|
+
* The simulation parameters are fetched using ContractDataProvider and executed using AcirSimulator.
|
|
345
|
+
* Returns the simulation result containing the outputs of the unconstrained function.
|
|
346
|
+
*
|
|
347
|
+
* @param execRequest - The transaction request object containing the target contract and function data.
|
|
348
|
+
* @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all.
|
|
349
|
+
* @returns The simulation result containing the outputs of the unconstrained function.
|
|
350
|
+
*/
|
|
351
|
+
async #simulateUnconstrained(execRequest: FunctionCall, authWitnesses?: AuthWitness[], scopes?: AztecAddress[]) {
|
|
352
|
+
const { to: contractAddress, selector: functionSelector } = execRequest;
|
|
353
|
+
|
|
354
|
+
this.log.debug('Executing unconstrained simulator...');
|
|
355
|
+
try {
|
|
356
|
+
const result = await this.simulator.runUnconstrained(
|
|
357
|
+
execRequest,
|
|
358
|
+
contractAddress,
|
|
359
|
+
functionSelector,
|
|
360
|
+
authWitnesses ?? [],
|
|
361
|
+
scopes,
|
|
362
|
+
);
|
|
363
|
+
this.log.verbose(`Unconstrained simulation for ${contractAddress}.${functionSelector} completed`);
|
|
364
|
+
|
|
365
|
+
return result;
|
|
366
|
+
} catch (err) {
|
|
367
|
+
if (err instanceof SimulationError) {
|
|
368
|
+
await enrichSimulationError(err, this.contractDataProvider, this.log);
|
|
369
|
+
}
|
|
370
|
+
throw err;
|
|
371
|
+
}
|
|
214
372
|
}
|
|
215
373
|
|
|
374
|
+
/**
|
|
375
|
+
* Simulate the public part of a transaction.
|
|
376
|
+
* This allows to catch public execution errors before submitting the transaction.
|
|
377
|
+
* It can also be used for estimating gas in the future.
|
|
378
|
+
* @param tx - The transaction to be simulated.
|
|
379
|
+
*/
|
|
380
|
+
async #simulatePublicCalls(tx: Tx, skipFeeEnforcement: boolean) {
|
|
381
|
+
// Simulating public calls can throw if the TX fails in a phase that doesn't allow reverts (setup)
|
|
382
|
+
// Or return as reverted if it fails in a phase that allows reverts (app logic, teardown)
|
|
383
|
+
try {
|
|
384
|
+
const result = await this.node.simulatePublicCalls(tx, skipFeeEnforcement);
|
|
385
|
+
if (result.revertReason) {
|
|
386
|
+
throw result.revertReason;
|
|
387
|
+
}
|
|
388
|
+
return result;
|
|
389
|
+
} catch (err) {
|
|
390
|
+
if (err instanceof SimulationError) {
|
|
391
|
+
try {
|
|
392
|
+
await enrichPublicSimulationError(err, this.contractDataProvider, this.log);
|
|
393
|
+
} catch (enrichErr) {
|
|
394
|
+
this.log.error(`Failed to enrich public simulation error: ${enrichErr}`);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
throw err;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Generate a kernel proof, and create a private kernel output.
|
|
403
|
+
* The function takes in a transaction execution request, and the result of private execution
|
|
404
|
+
* and then generates a kernel proof.
|
|
405
|
+
*
|
|
406
|
+
* @param txExecutionRequest - The transaction request to be simulated and proved.
|
|
407
|
+
* @param proofCreator - The proof creator to use for proving the execution.
|
|
408
|
+
* @param privateExecutionResult - The result of the private execution
|
|
409
|
+
* @param config - The configuration for the kernel execution prover.
|
|
410
|
+
* @returns An object that contains the output of the kernel execution, including the ClientIvcProof if proving is enabled.
|
|
411
|
+
*/
|
|
412
|
+
async #prove(
|
|
413
|
+
txExecutionRequest: TxExecutionRequest,
|
|
414
|
+
proofCreator: PrivateKernelProver,
|
|
415
|
+
privateExecutionResult: PrivateExecutionResult,
|
|
416
|
+
config: PrivateKernelExecutionProverConfig,
|
|
417
|
+
): Promise<PrivateKernelExecutionProofOutput<PrivateKernelTailCircuitPublicInputs>> {
|
|
418
|
+
const block = privateExecutionResult.getSimulationBlockNumber();
|
|
419
|
+
const kernelOracle = new PrivateKernelOracleImpl(this.contractDataProvider, this.keyStore, this.node, block);
|
|
420
|
+
const kernelTraceProver = new PrivateKernelExecutionProver(kernelOracle, proofCreator, !this.proverEnabled);
|
|
421
|
+
this.log.debug(`Executing kernel trace prover (${JSON.stringify(config)})...`);
|
|
422
|
+
return await kernelTraceProver.proveWithKernels(txExecutionRequest.toTxRequest(), privateExecutionResult, config);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Public API
|
|
426
|
+
|
|
216
427
|
/** Returns an estimate of the db size in bytes. */
|
|
217
428
|
public async estimateDbSize() {
|
|
218
429
|
const treeRootsSize = Object.keys(MerkleTreeId).length * Fr.SIZE_IN_BYTES;
|
|
219
430
|
const dbSizes = await Promise.all([
|
|
220
431
|
this.addressDataProvider.getSize(),
|
|
221
|
-
this.authWitnessDataProvider.getSize(),
|
|
222
432
|
this.capsuleDataProvider.getSize(),
|
|
223
433
|
this.contractDataProvider.getSize(),
|
|
224
434
|
this.noteDataProvider.getSize(),
|
|
@@ -228,18 +438,6 @@ export class PXEService implements PXE {
|
|
|
228
438
|
return [...dbSizes, treeRootsSize].reduce((sum, size) => sum + size, 0);
|
|
229
439
|
}
|
|
230
440
|
|
|
231
|
-
public addAuthWitness(witness: AuthWitness) {
|
|
232
|
-
return this.authWitnessDataProvider.addAuthWitness(witness.requestHash, witness.witness);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
public getAuthWitness(messageHash: Fr): Promise<Fr[] | undefined> {
|
|
236
|
-
return this.authWitnessDataProvider.getAuthWitness(messageHash);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
public storeCapsule(contract: AztecAddress, storageSlot: Fr, capsule: Fr[]) {
|
|
240
|
-
return this.capsuleDataProvider.storeCapsule(contract, storageSlot, capsule);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
441
|
public getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
|
|
244
442
|
return this.contractDataProvider.getContractInstance(address);
|
|
245
443
|
}
|
|
@@ -319,9 +517,7 @@ export class PXEService implements PXE {
|
|
|
319
517
|
}
|
|
320
518
|
|
|
321
519
|
public getSenders(): Promise<AztecAddress[]> {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
return Promise.resolve(senders);
|
|
520
|
+
return this.taggingDataProvider.getSenderAddresses();
|
|
325
521
|
}
|
|
326
522
|
|
|
327
523
|
public async removeSender(address: AztecAddress): Promise<void> {
|
|
@@ -332,8 +528,6 @@ export class PXEService implements PXE {
|
|
|
332
528
|
} else {
|
|
333
529
|
this.log.info(`Sender:\n "${address.toString()}"\n not in address book.`);
|
|
334
530
|
}
|
|
335
|
-
|
|
336
|
-
return Promise.resolve();
|
|
337
531
|
}
|
|
338
532
|
|
|
339
533
|
public async getRegisteredAccounts(): Promise<CompleteAddress[]> {
|
|
@@ -375,9 +569,6 @@ export class PXEService implements PXE {
|
|
|
375
569
|
.filter(fn => fn.functionType === FunctionType.PUBLIC)
|
|
376
570
|
.map(fn => decodeFunctionSignature(fn.name, fn.parameters));
|
|
377
571
|
await this.node.registerContractFunctionSignatures(instance.address, publicFunctionSignatures);
|
|
378
|
-
|
|
379
|
-
// TODO(#10007): Node should get public contract class from the registration event, not from PXE registration
|
|
380
|
-
await this.node.addContractClass({ ...contractClass, privateFunctions: [], unconstrainedFunctions: [] });
|
|
381
572
|
} else {
|
|
382
573
|
// Otherwise, make sure there is an artifact already registered for that class id
|
|
383
574
|
artifact = await this.contractDataProvider.getContractArtifact(instance.currentContractClassId);
|
|
@@ -416,8 +607,6 @@ export class PXEService implements PXE {
|
|
|
416
607
|
.map(fn => decodeFunctionSignature(fn.name, fn.parameters));
|
|
417
608
|
await this.node.registerContractFunctionSignatures(contractAddress, publicFunctionSignatures);
|
|
418
609
|
|
|
419
|
-
// TODO(#10007): Node should get public contract class from the registration event, not from PXE registration
|
|
420
|
-
await this.node.addContractClass({ ...contractClass, privateFunctions: [], unconstrainedFunctions: [] });
|
|
421
610
|
currentInstance.currentContractClassId = contractClass.id;
|
|
422
611
|
await this.contractDataProvider.addContractInstance(currentInstance);
|
|
423
612
|
this.log.info(`Updated contract ${artifact.name} at ${contractAddress.toString()} to class ${contractClass.id}`);
|
|
@@ -428,51 +617,27 @@ export class PXEService implements PXE {
|
|
|
428
617
|
return this.contractDataProvider.getContractsAddresses();
|
|
429
618
|
}
|
|
430
619
|
|
|
431
|
-
public async getPublicStorageAt(contract: AztecAddress, slot: Fr) {
|
|
432
|
-
return await this.node.getPublicStorageAt('latest', contract, slot);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
620
|
public async getNotes(filter: NotesFilter): Promise<UniqueNote[]> {
|
|
436
621
|
const noteDaos = await this.noteDataProvider.getNotes(filter);
|
|
437
622
|
|
|
438
623
|
const extendedNotes = noteDaos.map(async dao => {
|
|
439
|
-
let
|
|
440
|
-
if (
|
|
624
|
+
let recipient = filter.recipient;
|
|
625
|
+
if (recipient === undefined) {
|
|
441
626
|
const completeAddresses = await this.addressDataProvider.getCompleteAddresses();
|
|
442
|
-
const completeAddressIndex = (
|
|
443
|
-
|
|
444
|
-
)
|
|
627
|
+
const completeAddressIndex = completeAddresses.findIndex(completeAddress =>
|
|
628
|
+
completeAddress.address.equals(dao.recipient),
|
|
629
|
+
);
|
|
445
630
|
const completeAddress = completeAddresses[completeAddressIndex];
|
|
446
631
|
if (completeAddress === undefined) {
|
|
447
|
-
throw new Error(`Cannot find complete address for
|
|
632
|
+
throw new Error(`Cannot find complete address for recipient ${dao.recipient.toString()}`);
|
|
448
633
|
}
|
|
449
|
-
|
|
634
|
+
recipient = completeAddress.address;
|
|
450
635
|
}
|
|
451
|
-
return new UniqueNote(
|
|
452
|
-
dao.note,
|
|
453
|
-
owner,
|
|
454
|
-
dao.contractAddress,
|
|
455
|
-
dao.storageSlot,
|
|
456
|
-
dao.noteTypeId,
|
|
457
|
-
dao.txHash,
|
|
458
|
-
dao.nonce,
|
|
459
|
-
);
|
|
636
|
+
return new UniqueNote(dao.note, recipient, dao.contractAddress, dao.storageSlot, dao.txHash, dao.nonce);
|
|
460
637
|
});
|
|
461
638
|
return Promise.all(extendedNotes);
|
|
462
639
|
}
|
|
463
640
|
|
|
464
|
-
public async getL1ToL2MembershipWitness(
|
|
465
|
-
contractAddress: AztecAddress,
|
|
466
|
-
messageHash: Fr,
|
|
467
|
-
secret: Fr,
|
|
468
|
-
): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>]> {
|
|
469
|
-
return await getNonNullifiedL1ToL2MessageWitness(this.node, contractAddress, messageHash, secret);
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
public getL2ToL1MembershipWitness(blockNumber: number, l2Tol1Message: Fr): Promise<[bigint, SiblingPath<number>]> {
|
|
473
|
-
return this.node.getL2ToL1MessageMembershipWitness(blockNumber, l2Tol1Message);
|
|
474
|
-
}
|
|
475
|
-
|
|
476
641
|
public async getBlock(blockNumber: number): Promise<L2Block | undefined> {
|
|
477
642
|
// If a negative block number is provided the current block number is fetched.
|
|
478
643
|
if (blockNumber < 0) {
|
|
@@ -500,12 +665,54 @@ export class PXEService implements PXE {
|
|
|
500
665
|
{
|
|
501
666
|
simulate: false,
|
|
502
667
|
skipFeeEnforcement: false,
|
|
503
|
-
|
|
668
|
+
profileMode: 'none',
|
|
504
669
|
},
|
|
505
670
|
);
|
|
506
671
|
return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof!);
|
|
507
672
|
} catch (err: any) {
|
|
508
|
-
throw this
|
|
673
|
+
throw this.#contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult));
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
public profileTx(
|
|
679
|
+
txRequest: TxExecutionRequest,
|
|
680
|
+
profileMode: 'full' | 'execution-steps' | 'gates',
|
|
681
|
+
msgSender?: AztecAddress,
|
|
682
|
+
): Promise<TxProfileResult> {
|
|
683
|
+
// We disable concurrent profiles for consistency with simulateTx.
|
|
684
|
+
return this.#putInJobQueue(async () => {
|
|
685
|
+
try {
|
|
686
|
+
const txInfo = {
|
|
687
|
+
origin: txRequest.origin,
|
|
688
|
+
functionSelector: txRequest.functionSelector,
|
|
689
|
+
simulatePublic: false,
|
|
690
|
+
msgSender,
|
|
691
|
+
chainId: txRequest.txContext.chainId,
|
|
692
|
+
version: txRequest.txContext.version,
|
|
693
|
+
authWitnesses: txRequest.authWitnesses.map(w => w.requestHash),
|
|
694
|
+
};
|
|
695
|
+
this.log.info(
|
|
696
|
+
`Profiling transaction execution request to ${txRequest.functionSelector} at ${txRequest.origin}`,
|
|
697
|
+
txInfo,
|
|
698
|
+
);
|
|
699
|
+
await this.synchronizer.sync();
|
|
700
|
+
const privateExecutionResult = await this.#executePrivate(txRequest, msgSender);
|
|
701
|
+
|
|
702
|
+
const { executionSteps } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
|
|
703
|
+
simulate: true,
|
|
704
|
+
skipFeeEnforcement: false,
|
|
705
|
+
profileMode,
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
return new TxProfileResult(executionSteps);
|
|
709
|
+
} catch (err: any) {
|
|
710
|
+
throw this.#contextualizeError(
|
|
711
|
+
err,
|
|
712
|
+
inspect(txRequest),
|
|
713
|
+
`profileMode=${profileMode}`,
|
|
714
|
+
`msgSender=${msgSender?.toString() ?? 'undefined'}`,
|
|
715
|
+
);
|
|
509
716
|
}
|
|
510
717
|
});
|
|
511
718
|
}
|
|
@@ -517,7 +724,6 @@ export class PXEService implements PXE {
|
|
|
517
724
|
msgSender: AztecAddress | undefined = undefined,
|
|
518
725
|
skipTxValidation: boolean = false,
|
|
519
726
|
skipFeeEnforcement: boolean = false,
|
|
520
|
-
profile: boolean = false,
|
|
521
727
|
scopes?: AztecAddress[],
|
|
522
728
|
): Promise<TxSimulationResult> {
|
|
523
729
|
// We disable concurrent simulations since those might execute oracles which read and write to the PXE stores (e.g.
|
|
@@ -542,16 +748,11 @@ export class PXEService implements PXE {
|
|
|
542
748
|
await this.synchronizer.sync();
|
|
543
749
|
const privateExecutionResult = await this.#executePrivate(txRequest, msgSender, scopes);
|
|
544
750
|
|
|
545
|
-
const { publicInputs
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
simulate: !profile,
|
|
551
|
-
skipFeeEnforcement,
|
|
552
|
-
profile,
|
|
553
|
-
},
|
|
554
|
-
);
|
|
751
|
+
const { publicInputs } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
|
|
752
|
+
simulate: true,
|
|
753
|
+
skipFeeEnforcement,
|
|
754
|
+
profileMode: 'none',
|
|
755
|
+
});
|
|
555
756
|
|
|
556
757
|
const privateSimulationResult = new PrivateSimulationResult(privateExecutionResult, publicInputs);
|
|
557
758
|
const simulatedTx = privateSimulationResult.toSimulatedTx();
|
|
@@ -571,7 +772,6 @@ export class PXEService implements PXE {
|
|
|
571
772
|
this.log.info(`Simulation completed for ${txHash.toString()} in ${timer.ms()}ms`, {
|
|
572
773
|
txHash,
|
|
573
774
|
...txInfo,
|
|
574
|
-
...(profileResult ? { gateCounts: profileResult.gateCounts } : {}),
|
|
575
775
|
...(publicOutput
|
|
576
776
|
? {
|
|
577
777
|
gasUsed: publicOutput.gasUsed,
|
|
@@ -581,19 +781,14 @@ export class PXEService implements PXE {
|
|
|
581
781
|
: {}),
|
|
582
782
|
});
|
|
583
783
|
|
|
584
|
-
return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput(
|
|
585
|
-
privateSimulationResult,
|
|
586
|
-
publicOutput,
|
|
587
|
-
profileResult,
|
|
588
|
-
);
|
|
784
|
+
return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput(privateSimulationResult, publicOutput);
|
|
589
785
|
} catch (err: any) {
|
|
590
|
-
throw this
|
|
786
|
+
throw this.#contextualizeError(
|
|
591
787
|
err,
|
|
592
788
|
inspect(txRequest),
|
|
593
789
|
`simulatePublic=${simulatePublic}`,
|
|
594
790
|
`msgSender=${msgSender?.toString() ?? 'undefined'}`,
|
|
595
791
|
`skipTxValidation=${skipTxValidation}`,
|
|
596
|
-
`profile=${profile}`,
|
|
597
792
|
`scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
|
|
598
793
|
);
|
|
599
794
|
}
|
|
@@ -607,7 +802,7 @@ export class PXEService implements PXE {
|
|
|
607
802
|
}
|
|
608
803
|
this.log.debug(`Sending transaction ${txHash}`);
|
|
609
804
|
await this.node.sendTx(tx).catch(err => {
|
|
610
|
-
throw this
|
|
805
|
+
throw this.#contextualizeError(err, inspect(tx));
|
|
611
806
|
});
|
|
612
807
|
this.log.info(`Sent transaction ${txHash}`);
|
|
613
808
|
return txHash;
|
|
@@ -617,6 +812,7 @@ export class PXEService implements PXE {
|
|
|
617
812
|
functionName: string,
|
|
618
813
|
args: any[],
|
|
619
814
|
to: AztecAddress,
|
|
815
|
+
authwits?: AuthWitness[],
|
|
620
816
|
_from?: AztecAddress,
|
|
621
817
|
scopes?: AztecAddress[],
|
|
622
818
|
): Promise<AbiDecoded> {
|
|
@@ -628,13 +824,13 @@ export class PXEService implements PXE {
|
|
|
628
824
|
await this.synchronizer.sync();
|
|
629
825
|
// TODO - Should check if `from` has the permission to call the view function.
|
|
630
826
|
const functionCall = await this.#getFunctionCall(functionName, args, to);
|
|
631
|
-
const executionResult = await this.#simulateUnconstrained(functionCall, scopes);
|
|
827
|
+
const executionResult = await this.#simulateUnconstrained(functionCall, authwits ?? [], scopes);
|
|
632
828
|
|
|
633
829
|
// TODO - Return typed result based on the function artifact.
|
|
634
830
|
return executionResult;
|
|
635
831
|
} catch (err: any) {
|
|
636
832
|
const stringifiedArgs = args.map(arg => arg.toString()).join(', ');
|
|
637
|
-
throw this
|
|
833
|
+
throw this.#contextualizeError(
|
|
638
834
|
err,
|
|
639
835
|
`simulateUnconstrained ${to}:${functionName}(${stringifiedArgs})`,
|
|
640
836
|
`scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
|
|
@@ -643,64 +839,6 @@ export class PXEService implements PXE {
|
|
|
643
839
|
});
|
|
644
840
|
}
|
|
645
841
|
|
|
646
|
-
public getTxReceipt(txHash: TxHash): Promise<TxReceipt> {
|
|
647
|
-
return this.node.getTxReceipt(txHash);
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
public getTxEffect(txHash: TxHash): Promise<InBlock<TxEffect> | undefined> {
|
|
651
|
-
return this.node.getTxEffect(txHash);
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
public async getBlockNumber(): Promise<number> {
|
|
655
|
-
return await this.node.getBlockNumber();
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
public async getProvenBlockNumber(): Promise<number> {
|
|
659
|
-
return await this.node.getProvenBlockNumber();
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
/**
|
|
663
|
-
* Gets public logs based on the provided filter.
|
|
664
|
-
* @param filter - The filter to apply to the logs.
|
|
665
|
-
* @returns The requested logs.
|
|
666
|
-
*/
|
|
667
|
-
public getPublicLogs(filter: LogFilter): Promise<GetPublicLogsResponse> {
|
|
668
|
-
return this.node.getPublicLogs(filter);
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
/**
|
|
672
|
-
* Gets contract class logs based on the provided filter.
|
|
673
|
-
* @param filter - The filter to apply to the logs.
|
|
674
|
-
* @returns The requested logs.
|
|
675
|
-
*/
|
|
676
|
-
public getContractClassLogs(filter: LogFilter): Promise<GetContractClassLogsResponse> {
|
|
677
|
-
return this.node.getContractClassLogs(filter);
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
async #getFunctionCall(functionName: string, args: any[], to: AztecAddress): Promise<FunctionCall> {
|
|
681
|
-
const contract = await this.contractDataProvider.getContract(to);
|
|
682
|
-
if (!contract) {
|
|
683
|
-
throw new Error(
|
|
684
|
-
`Unknown contract ${to}: add it to PXE Service by calling server.addContracts(...).\nSee docs for context: https://docs.aztec.network/developers/reference/debugging/aztecnr-errors#unknown-contract-0x0-add-it-to-pxe-by-calling-serveraddcontracts`,
|
|
685
|
-
);
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
const functionDao = contract.functions.find(f => f.name === functionName);
|
|
689
|
-
if (!functionDao) {
|
|
690
|
-
throw new Error(`Unknown function ${functionName} in contract ${contract.name}.`);
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
return {
|
|
694
|
-
name: functionDao.name,
|
|
695
|
-
args: encodeArguments(functionDao, args),
|
|
696
|
-
selector: await FunctionSelector.fromNameAndParameters(functionDao.name, functionDao.parameters),
|
|
697
|
-
type: functionDao.functionType,
|
|
698
|
-
to,
|
|
699
|
-
isStatic: functionDao.isStatic,
|
|
700
|
-
returnTypes: functionDao.returnTypes,
|
|
701
|
-
};
|
|
702
|
-
}
|
|
703
|
-
|
|
704
842
|
public async getNodeInfo(): Promise<NodeInfo> {
|
|
705
843
|
const [nodeVersion, protocolVersion, chainId, enr, contractAddresses, protocolContractAddresses] =
|
|
706
844
|
await Promise.all([
|
|
@@ -736,151 +874,6 @@ export class PXEService implements PXE {
|
|
|
736
874
|
});
|
|
737
875
|
}
|
|
738
876
|
|
|
739
|
-
async #registerProtocolContracts() {
|
|
740
|
-
const registered: Record<string, string> = {};
|
|
741
|
-
for (const name of protocolContractNames) {
|
|
742
|
-
const { address, contractClass, instance, artifact } =
|
|
743
|
-
await this.protocolContractsProvider.getProtocolContractArtifact(name);
|
|
744
|
-
await this.contractDataProvider.addContractArtifact(contractClass.id, artifact);
|
|
745
|
-
await this.contractDataProvider.addContractInstance(instance);
|
|
746
|
-
registered[name] = address.toString();
|
|
747
|
-
}
|
|
748
|
-
this.log.verbose(`Registered protocol contracts in pxe`, registered);
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
/**
|
|
752
|
-
* Retrieves the simulation parameters required to run an ACIR simulation.
|
|
753
|
-
* This includes the contract address, function artifact, and historical tree roots.
|
|
754
|
-
*
|
|
755
|
-
* @param execRequest - The transaction request object containing details of the contract call.
|
|
756
|
-
* @returns An object containing the contract address, function artifact, and historical tree roots.
|
|
757
|
-
*/
|
|
758
|
-
#getSimulationParameters(execRequest: FunctionCall | TxExecutionRequest) {
|
|
759
|
-
const contractAddress = (execRequest as FunctionCall).to ?? (execRequest as TxExecutionRequest).origin;
|
|
760
|
-
const functionSelector =
|
|
761
|
-
(execRequest as FunctionCall).selector ?? (execRequest as TxExecutionRequest).functionSelector;
|
|
762
|
-
|
|
763
|
-
return {
|
|
764
|
-
contractAddress,
|
|
765
|
-
functionSelector,
|
|
766
|
-
};
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
async #executePrivate(
|
|
770
|
-
txRequest: TxExecutionRequest,
|
|
771
|
-
msgSender?: AztecAddress,
|
|
772
|
-
scopes?: AztecAddress[],
|
|
773
|
-
): Promise<PrivateExecutionResult> {
|
|
774
|
-
// TODO - Pause syncing while simulating.
|
|
775
|
-
const { contractAddress, functionSelector } = this.#getSimulationParameters(txRequest);
|
|
776
|
-
|
|
777
|
-
try {
|
|
778
|
-
const result = await this.simulator.run(txRequest, contractAddress, functionSelector, msgSender, scopes);
|
|
779
|
-
this.log.debug(`Private simulation completed for ${contractAddress.toString()}:${functionSelector}`);
|
|
780
|
-
return result;
|
|
781
|
-
} catch (err) {
|
|
782
|
-
if (err instanceof SimulationError) {
|
|
783
|
-
await enrichSimulationError(err, this.contractDataProvider, this.log);
|
|
784
|
-
}
|
|
785
|
-
throw err;
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
/**
|
|
790
|
-
* Simulate an unconstrained transaction on the given contract, without considering constraints set by ACIR.
|
|
791
|
-
* The simulation parameters are fetched using ContractDataProvider and executed using AcirSimulator.
|
|
792
|
-
* Returns the simulation result containing the outputs of the unconstrained function.
|
|
793
|
-
*
|
|
794
|
-
* @param execRequest - The transaction request object containing the target contract and function data.
|
|
795
|
-
* @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all.
|
|
796
|
-
* @returns The simulation result containing the outputs of the unconstrained function.
|
|
797
|
-
*/
|
|
798
|
-
async #simulateUnconstrained(execRequest: FunctionCall, scopes?: AztecAddress[]) {
|
|
799
|
-
const { contractAddress, functionSelector } = this.#getSimulationParameters(execRequest);
|
|
800
|
-
|
|
801
|
-
this.log.debug('Executing unconstrained simulator...');
|
|
802
|
-
try {
|
|
803
|
-
const result = await this.simulator.runUnconstrained(execRequest, contractAddress, functionSelector, scopes);
|
|
804
|
-
this.log.verbose(`Unconstrained simulation for ${contractAddress}.${functionSelector} completed`);
|
|
805
|
-
|
|
806
|
-
return result;
|
|
807
|
-
} catch (err) {
|
|
808
|
-
if (err instanceof SimulationError) {
|
|
809
|
-
await enrichSimulationError(err, this.contractDataProvider, this.log);
|
|
810
|
-
}
|
|
811
|
-
throw err;
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
/**
|
|
816
|
-
* Simulate the public part of a transaction.
|
|
817
|
-
* This allows to catch public execution errors before submitting the transaction.
|
|
818
|
-
* It can also be used for estimating gas in the future.
|
|
819
|
-
* @param tx - The transaction to be simulated.
|
|
820
|
-
*/
|
|
821
|
-
async #simulatePublicCalls(tx: Tx, skipFeeEnforcement: boolean) {
|
|
822
|
-
// Simulating public calls can throw if the TX fails in a phase that doesn't allow reverts (setup)
|
|
823
|
-
// Or return as reverted if it fails in a phase that allows reverts (app logic, teardown)
|
|
824
|
-
try {
|
|
825
|
-
const result = await this.node.simulatePublicCalls(tx, skipFeeEnforcement);
|
|
826
|
-
if (result.revertReason) {
|
|
827
|
-
throw result.revertReason;
|
|
828
|
-
}
|
|
829
|
-
return result;
|
|
830
|
-
} catch (err) {
|
|
831
|
-
if (err instanceof SimulationError) {
|
|
832
|
-
try {
|
|
833
|
-
await enrichPublicSimulationError(err, this.contractDataProvider, this.log);
|
|
834
|
-
} catch (enrichErr) {
|
|
835
|
-
this.log.error(`Failed to enrich public simulation error: ${enrichErr}`);
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
throw err;
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
/**
|
|
843
|
-
* Generate a kernel proof, and create a private kernel output.
|
|
844
|
-
* The function takes in a transaction execution request, and the result of private execution
|
|
845
|
-
* and then generates a kernel proof.
|
|
846
|
-
*
|
|
847
|
-
* @param txExecutionRequest - The transaction request to be simulated and proved.
|
|
848
|
-
* @param proofCreator - The proof creator to use for proving the execution.
|
|
849
|
-
* @param privateExecutionResult - The result of the private execution
|
|
850
|
-
* @returns An object that contains the output of the kernel execution, including the ClientIvcProof if proving is enabled.
|
|
851
|
-
*/
|
|
852
|
-
async #prove(
|
|
853
|
-
txExecutionRequest: TxExecutionRequest,
|
|
854
|
-
proofCreator: PrivateKernelProver,
|
|
855
|
-
privateExecutionResult: PrivateExecutionResult,
|
|
856
|
-
{ simulate, skipFeeEnforcement, profile }: ProvingConfig,
|
|
857
|
-
): Promise<PrivateKernelSimulateOutput<PrivateKernelTailCircuitPublicInputs>> {
|
|
858
|
-
// use the block the tx was simulated against
|
|
859
|
-
const block =
|
|
860
|
-
privateExecutionResult.entrypoint.publicInputs.historicalHeader.globalVariables.blockNumber.toNumber();
|
|
861
|
-
const kernelOracle = new KernelOracle(this.contractDataProvider, this.keyStore, this.node, block);
|
|
862
|
-
const kernelProver = new KernelProver(kernelOracle, proofCreator, !this.proverEnabled);
|
|
863
|
-
this.log.debug(`Executing kernel prover (simulate: ${simulate}, profile: ${profile})...`);
|
|
864
|
-
return await kernelProver.prove(txExecutionRequest.toTxRequest(), privateExecutionResult, {
|
|
865
|
-
simulate,
|
|
866
|
-
skipFeeEnforcement,
|
|
867
|
-
profile,
|
|
868
|
-
});
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
async #isContractClassPubliclyRegistered(id: Fr): Promise<boolean> {
|
|
872
|
-
return !!(await this.node.getContractClass(id));
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
async #isContractPubliclyDeployed(address: AztecAddress): Promise<boolean> {
|
|
876
|
-
return !!(await this.node.getContract(address));
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
async #isContractInitialized(address: AztecAddress): Promise<boolean> {
|
|
880
|
-
const initNullifier = await siloNullifier(address, address.toField());
|
|
881
|
-
return !!(await this.node.getNullifierMembershipWitness('latest', initNullifier));
|
|
882
|
-
}
|
|
883
|
-
|
|
884
877
|
public async getPrivateEvents<T>(
|
|
885
878
|
eventMetadataDef: EventMetadataDefinition,
|
|
886
879
|
from: number,
|
|
@@ -985,18 +978,4 @@ export class PXEService implements PXE {
|
|
|
985
978
|
async resetNoteSyncData() {
|
|
986
979
|
return await this.taggingDataProvider.resetNoteSyncData();
|
|
987
980
|
}
|
|
988
|
-
|
|
989
|
-
private contextualizeError(err: Error, ...context: string[]): Error {
|
|
990
|
-
let contextStr = '';
|
|
991
|
-
if (context.length > 0) {
|
|
992
|
-
contextStr = `\nContext:\n${context.join('\n')}`;
|
|
993
|
-
}
|
|
994
|
-
if (err instanceof SimulationError) {
|
|
995
|
-
err.setAztecContext(contextStr);
|
|
996
|
-
} else {
|
|
997
|
-
this.log.error(err.name, err);
|
|
998
|
-
this.log.debug(contextStr);
|
|
999
|
-
}
|
|
1000
|
-
return err;
|
|
1001
|
-
}
|
|
1002
981
|
}
|