@aztec/pxe 0.69.1 → 0.70.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.
Files changed (61) hide show
  1. package/dest/database/kv_pxe_database.d.ts +4 -0
  2. package/dest/database/kv_pxe_database.d.ts.map +1 -1
  3. package/dest/database/kv_pxe_database.js +26 -3
  4. package/dest/database/note_dao.d.ts +1 -1
  5. package/dest/database/note_dao.d.ts.map +1 -1
  6. package/dest/database/pxe_database.d.ts +16 -0
  7. package/dest/database/pxe_database.d.ts.map +1 -1
  8. package/dest/database/pxe_database_test_suite.d.ts.map +1 -1
  9. package/dest/database/pxe_database_test_suite.js +48 -1
  10. package/dest/kernel_oracle/index.js +2 -2
  11. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts +2 -2
  12. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -1
  13. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.js +1 -1
  14. package/dest/kernel_prover/index.d.ts +0 -1
  15. package/dest/kernel_prover/index.d.ts.map +1 -1
  16. package/dest/kernel_prover/index.js +1 -2
  17. package/dest/kernel_prover/kernel_prover.d.ts +8 -2
  18. package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
  19. package/dest/kernel_prover/kernel_prover.js +42 -18
  20. package/dest/note_decryption_utils/brute_force_note_info.d.ts +1 -1
  21. package/dest/note_decryption_utils/brute_force_note_info.d.ts.map +1 -1
  22. package/dest/note_decryption_utils/brute_force_note_info.js +2 -3
  23. package/dest/note_decryption_utils/produce_note_daos.d.ts +1 -1
  24. package/dest/note_decryption_utils/produce_note_daos.d.ts.map +1 -1
  25. package/dest/note_decryption_utils/produce_note_daos.js +3 -3
  26. package/dest/note_decryption_utils/produce_note_daos_for_key.d.ts +1 -1
  27. package/dest/note_decryption_utils/produce_note_daos_for_key.d.ts.map +1 -1
  28. package/dest/note_decryption_utils/produce_note_daos_for_key.js +3 -3
  29. package/dest/pxe_service/error_enriching.js +1 -1
  30. package/dest/pxe_service/pxe_service.d.ts +5 -1
  31. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  32. package/dest/pxe_service/pxe_service.js +30 -31
  33. package/dest/simulator/index.d.ts +2 -2
  34. package/dest/simulator/index.d.ts.map +1 -1
  35. package/dest/simulator/index.js +4 -4
  36. package/dest/simulator_oracle/index.d.ts +21 -6
  37. package/dest/simulator_oracle/index.d.ts.map +1 -1
  38. package/dest/simulator_oracle/index.js +53 -25
  39. package/dest/utils/create_pxe_service.d.ts.map +1 -1
  40. package/dest/utils/create_pxe_service.js +9 -12
  41. package/package.json +14 -15
  42. package/src/database/kv_pxe_database.ts +30 -0
  43. package/src/database/note_dao.ts +1 -1
  44. package/src/database/pxe_database.ts +18 -0
  45. package/src/database/pxe_database_test_suite.ts +61 -0
  46. package/src/kernel_oracle/index.ts +1 -1
  47. package/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts +4 -4
  48. package/src/kernel_prover/index.ts +0 -2
  49. package/src/kernel_prover/kernel_prover.ts +58 -20
  50. package/src/note_decryption_utils/brute_force_note_info.ts +1 -1
  51. package/src/note_decryption_utils/produce_note_daos.ts +2 -0
  52. package/src/note_decryption_utils/produce_note_daos_for_key.ts +2 -0
  53. package/src/pxe_service/error_enriching.ts +1 -1
  54. package/src/pxe_service/pxe_service.ts +32 -44
  55. package/src/simulator/index.ts +4 -2
  56. package/src/simulator_oracle/index.ts +47 -11
  57. package/src/utils/create_pxe_service.ts +8 -13
  58. package/dest/kernel_prover/test/test_circuit_prover.d.ts +0 -20
  59. package/dest/kernel_prover/test/test_circuit_prover.d.ts.map +0 -1
  60. package/dest/kernel_prover/test/test_circuit_prover.js +0 -75
  61. package/src/kernel_prover/test/test_circuit_prover.ts +0 -122
@@ -1,4 +1,5 @@
1
1
  import {
2
+ type PrivateCallExecutionResult,
2
3
  type PrivateExecutionResult,
3
4
  type PrivateKernelProver,
4
5
  type PrivateKernelSimulateOutput,
@@ -10,6 +11,7 @@ import {
10
11
  } from '@aztec/circuit-types';
11
12
  import {
12
13
  CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS,
14
+ ClientIvcProof,
13
15
  Fr,
14
16
  PROTOCOL_CONTRACT_TREE_HEIGHT,
15
17
  PrivateCallData,
@@ -32,7 +34,7 @@ import { createLogger } from '@aztec/foundation/log';
32
34
  import { assertLength } from '@aztec/foundation/serialize';
33
35
  import { pushTestData } from '@aztec/foundation/testing';
34
36
  import { Timer } from '@aztec/foundation/timer';
35
- import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/client';
37
+ import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks';
36
38
  import {
37
39
  getProtocolContractSiblingPath,
38
40
  isProtocolContract,
@@ -89,6 +91,12 @@ const NULL_PROVE_OUTPUT: PrivateKernelSimulateOutput<PrivateKernelCircuitPublicI
89
91
  bytecode: Buffer.from([]),
90
92
  };
91
93
 
94
+ export type ProvingConfig = {
95
+ simulate: boolean;
96
+ profile: boolean;
97
+ dryRun: boolean;
98
+ };
99
+
92
100
  /**
93
101
  * The KernelProver class is responsible for generating kernel proofs.
94
102
  * It takes a transaction request, its signature, and the simulation result as inputs, and outputs a proof
@@ -98,7 +106,11 @@ const NULL_PROVE_OUTPUT: PrivateKernelSimulateOutput<PrivateKernelCircuitPublicI
98
106
  export class KernelProver {
99
107
  private log = createLogger('pxe:kernel-prover');
100
108
 
101
- constructor(private oracle: ProvingDataOracle, private proofCreator: PrivateKernelProver) {}
109
+ constructor(
110
+ private oracle: ProvingDataOracle,
111
+ private proofCreator: PrivateKernelProver,
112
+ private fakeProofs = false,
113
+ ) {}
102
114
 
103
115
  /**
104
116
  * Generate a proof for a given transaction request and execution result.
@@ -116,14 +128,19 @@ export class KernelProver {
116
128
  async prove(
117
129
  txRequest: TxRequest,
118
130
  executionResult: PrivateExecutionResult,
119
- profile: boolean = false,
120
- dryRun: boolean = false,
131
+ { simulate, profile, dryRun }: ProvingConfig = { simulate: false, profile: false, dryRun: false },
121
132
  ): Promise<PrivateKernelSimulateOutput<PrivateKernelTailCircuitPublicInputs>> {
133
+ if (simulate && profile) {
134
+ throw new Error('Cannot simulate and profile at the same time');
135
+ }
136
+
137
+ simulate = simulate || this.fakeProofs;
138
+
122
139
  const timer = new Timer();
123
140
 
124
141
  const isPrivateOnlyTx = this.isPrivateOnly(executionResult);
125
142
 
126
- const executionStack = [executionResult];
143
+ const executionStack = [executionResult.entrypoint];
127
144
  let firstIteration = true;
128
145
 
129
146
  let output = NULL_PROVE_OUTPUT;
@@ -156,7 +173,9 @@ export class KernelProver {
156
173
  );
157
174
  while (resetBuilder.needsReset()) {
158
175
  const privateInputs = await resetBuilder.build(this.oracle, noteHashLeafIndexMap);
159
- output = await this.proofCreator.simulateProofReset(privateInputs);
176
+ output = simulate
177
+ ? await this.proofCreator.simulateReset(privateInputs)
178
+ : await this.proofCreator.generateResetOutput(privateInputs);
160
179
  // TODO(#7368) consider refactoring this redundant bytecode pushing
161
180
  acirs.push(output.bytecode);
162
181
  witnessStack.push(output.outputWitness);
@@ -199,11 +218,17 @@ export class KernelProver {
199
218
  protocolContractTreeRoot,
200
219
  privateCallData,
201
220
  isPrivateOnlyTx,
221
+ executionResult.firstNullifier,
222
+ );
223
+ this.log.debug(
224
+ `Calling private kernel init with isPrivateOnly ${isPrivateOnlyTx} and firstNullifierHint ${proofInput.firstNullifierHint}`,
202
225
  );
203
226
 
204
227
  pushTestData('private-kernel-inputs-init', proofInput);
205
228
 
206
- output = await this.proofCreator.simulateProofInit(proofInput);
229
+ output = simulate
230
+ ? await this.proofCreator.simulateInit(proofInput)
231
+ : await this.proofCreator.generateInitOutput(proofInput);
207
232
 
208
233
  acirs.push(output.bytecode);
209
234
  witnessStack.push(output.outputWitness);
@@ -222,7 +247,9 @@ export class KernelProver {
222
247
 
223
248
  pushTestData('private-kernel-inputs-inner', proofInput);
224
249
 
225
- output = await this.proofCreator.simulateProofInner(proofInput);
250
+ output = simulate
251
+ ? await this.proofCreator.simulateInner(proofInput)
252
+ : await this.proofCreator.generateInnerOutput(proofInput);
226
253
 
227
254
  acirs.push(output.bytecode);
228
255
  witnessStack.push(output.outputWitness);
@@ -242,7 +269,9 @@ export class KernelProver {
242
269
  );
243
270
  while (resetBuilder.needsReset()) {
244
271
  const privateInputs = await resetBuilder.build(this.oracle, noteHashLeafIndexMap);
245
- output = await this.proofCreator.simulateProofReset(privateInputs);
272
+ output = simulate
273
+ ? await this.proofCreator.simulateReset(privateInputs)
274
+ : await this.proofCreator.generateResetOutput(privateInputs);
246
275
 
247
276
  acirs.push(output.bytecode);
248
277
  witnessStack.push(output.outputWitness);
@@ -275,7 +304,9 @@ export class KernelProver {
275
304
 
276
305
  pushTestData('private-kernel-inputs-ordering', privateInputs);
277
306
 
278
- const tailOutput = await this.proofCreator.simulateProofTail(privateInputs);
307
+ const tailOutput = simulate
308
+ ? await this.proofCreator.simulateTail(privateInputs)
309
+ : await this.proofCreator.generateTailOutput(privateInputs);
279
310
  if (tailOutput.publicInputs.forPublic) {
280
311
  const privateLogs = privateInputs.previousKernel.publicInputs.end.privateLogs;
281
312
  const nonRevertiblePrivateLogs = tailOutput.publicInputs.forPublic.nonRevertibleAccumulatedData.privateLogs;
@@ -290,18 +321,22 @@ export class KernelProver {
290
321
  tailOutput.profileResult = { gateCounts };
291
322
  }
292
323
 
293
- this.log.verbose(`Private kernel witness generation took ${timer.ms()}ms`);
324
+ if (!simulate) {
325
+ this.log.info(`Private kernel witness generation took ${timer.ms()}ms`);
326
+ }
294
327
 
295
328
  // TODO(#7368) how do we 'bincode' encode these inputs?
296
- if (!dryRun) {
329
+ if (!dryRun && !simulate) {
297
330
  const ivcProof = await this.proofCreator.createClientIvcProof(acirs, witnessStack);
298
331
  tailOutput.clientIvcProof = ivcProof;
332
+ } else {
333
+ tailOutput.clientIvcProof = ClientIvcProof.empty();
299
334
  }
300
335
 
301
336
  return tailOutput;
302
337
  }
303
338
 
304
- private async createPrivateCallData({ publicInputs, vk: vkAsBuffer }: PrivateExecutionResult) {
339
+ private async createPrivateCallData({ publicInputs, vk: vkAsBuffer }: PrivateCallExecutionResult) {
305
340
  const { contractAddress, functionSelector } = publicInputs.callContext;
306
341
 
307
342
  const vkAsFields = vkAsFieldsMegaHonk(vkAsBuffer);
@@ -339,12 +374,15 @@ export class KernelProver {
339
374
  }
340
375
 
341
376
  private isPrivateOnly(executionResult: PrivateExecutionResult): boolean {
342
- const makesPublicCalls =
343
- executionResult.enqueuedPublicFunctionCalls.some(enqueuedCall => !enqueuedCall.isEmpty()) ||
344
- !executionResult.publicTeardownFunctionCall.isEmpty();
345
- return (
346
- !makesPublicCalls &&
347
- executionResult.nestedExecutions.every(nestedExecution => this.isPrivateOnly(nestedExecution))
348
- );
377
+ const isPrivateOnlyRecursive = (callResult: PrivateCallExecutionResult): boolean => {
378
+ const makesPublicCalls =
379
+ callResult.enqueuedPublicFunctionCalls.some(enqueuedCall => !enqueuedCall.isEmpty()) ||
380
+ !callResult.publicTeardownFunctionCall.isEmpty();
381
+ return (
382
+ !makesPublicCalls &&
383
+ callResult.nestedExecutions.every(nestedExecution => isPrivateOnlyRecursive(nestedExecution))
384
+ );
385
+ };
386
+ return isPrivateOnlyRecursive(executionResult.entrypoint);
349
387
  }
350
388
  }
@@ -34,6 +34,7 @@ export async function bruteForceNoteInfo(
34
34
  simulator: AcirSimulator,
35
35
  uniqueNoteHashes: Fr[],
36
36
  txHash: TxHash,
37
+ firstNullifier: Fr,
37
38
  contractAddress: AztecAddress,
38
39
  storageSlot: Fr,
39
40
  noteTypeId: NoteSelector,
@@ -46,7 +47,6 @@ export async function bruteForceNoteInfo(
46
47
  let noteHash: Fr | undefined;
47
48
  let uniqueNoteHash: Fr | undefined;
48
49
  let innerNullifier: Fr | undefined;
49
- const firstNullifier = Fr.fromBuffer(txHash.toBuffer());
50
50
 
51
51
  for (; noteHashIndex < uniqueNoteHashes.length; ++noteHashIndex) {
52
52
  if (excludedIndices.has(noteHashIndex)) {
@@ -31,6 +31,7 @@ export async function produceNoteDaos(
31
31
  addressPoint: PublicKey | undefined,
32
32
  payload: L1NotePayload,
33
33
  txHash: TxHash,
34
+ firstNullifier: Fr,
34
35
  l2BlockNumber: number,
35
36
  l2BlockHash: string,
36
37
  noteHashes: Fr[],
@@ -51,6 +52,7 @@ export async function produceNoteDaos(
51
52
  addressPoint,
52
53
  payload,
53
54
  txHash,
55
+ firstNullifier,
54
56
  l2BlockNumber,
55
57
  l2BlockHash,
56
58
  noteHashes,
@@ -13,6 +13,7 @@ export async function produceNoteDaosForKey<T>(
13
13
  pkM: PublicKey,
14
14
  payload: L1NotePayload,
15
15
  txHash: TxHash,
16
+ firstNullifier: Fr,
16
17
  l2BlockNumber: number,
17
18
  l2BlockHash: string,
18
19
  noteHashes: Fr[],
@@ -39,6 +40,7 @@ export async function produceNoteDaosForKey<T>(
39
40
  simulator,
40
41
  noteHashes,
41
42
  txHash,
43
+ firstNullifier,
42
44
  payload.contractAddress,
43
45
  payload.storageSlot,
44
46
  payload.noteTypeId,
@@ -4,7 +4,7 @@ import { FunctionSelector } from '@aztec/foundation/abi';
4
4
  import { AztecAddress } from '@aztec/foundation/aztec-address';
5
5
  import { Fr } from '@aztec/foundation/fields';
6
6
  import { type Logger } from '@aztec/foundation/log';
7
- import { resolveAssertionMessageFromRevertData, resolveOpcodeLocations } from '@aztec/simulator/errors';
7
+ import { resolveAssertionMessageFromRevertData, resolveOpcodeLocations } from '@aztec/simulator/client';
8
8
 
9
9
  import { type ContractDataOracle, type PxeDatabase } from '../index.js';
10
10
 
@@ -65,7 +65,7 @@ import { type KeyStore } from '@aztec/key-store';
65
65
  import { type L2TipsStore } from '@aztec/kv-store/stores';
66
66
  import { ProtocolContractAddress, protocolContractNames } from '@aztec/protocol-contracts';
67
67
  import { getCanonicalProtocolContract } from '@aztec/protocol-contracts/bundle';
68
- import { type AcirSimulator } from '@aztec/simulator/client';
68
+ import { type AcirSimulator, type SimulationProvider } from '@aztec/simulator/client';
69
69
 
70
70
  import { inspect } from 'util';
71
71
 
@@ -75,8 +75,7 @@ import { ContractDataOracle } from '../contract_data_oracle/index.js';
75
75
  import { type PxeDatabase } from '../database/index.js';
76
76
  import { NoteDao } from '../database/note_dao.js';
77
77
  import { KernelOracle } from '../kernel_oracle/index.js';
78
- import { KernelProver } from '../kernel_prover/kernel_prover.js';
79
- import { TestPrivateKernelProver } from '../kernel_prover/test/test_circuit_prover.js';
78
+ import { KernelProver, type ProvingConfig } from '../kernel_prover/kernel_prover.js';
80
79
  import { getAcirSimulator } from '../simulator/index.js';
81
80
  import { Synchronizer } from '../synchronizer/index.js';
82
81
  import { enrichPublicSimulationError, enrichSimulationError } from './error_enriching.js';
@@ -90,6 +89,7 @@ export class PXEService implements PXE {
90
89
  private simulator: AcirSimulator;
91
90
  private log: Logger;
92
91
  private packageVersion: string;
92
+ private proverEnabled: boolean;
93
93
 
94
94
  constructor(
95
95
  private keyStore: KeyStore,
@@ -97,14 +97,16 @@ export class PXEService implements PXE {
97
97
  private db: PxeDatabase,
98
98
  tipsStore: L2TipsStore,
99
99
  private proofCreator: PrivateKernelProver,
100
+ private simulationProvider: SimulationProvider,
100
101
  config: PXEServiceConfig,
101
102
  logSuffix?: string,
102
103
  ) {
103
104
  this.log = createLogger(logSuffix ? `pxe:service:${logSuffix}` : `pxe:service`);
104
105
  this.synchronizer = new Synchronizer(node, db, tipsStore, config, logSuffix);
105
106
  this.contractDataOracle = new ContractDataOracle(db);
106
- this.simulator = getAcirSimulator(db, node, keyStore, this.contractDataOracle);
107
+ this.simulator = getAcirSimulator(db, node, keyStore, this.simulationProvider, this.contractDataOracle);
107
108
  this.packageVersion = getPackageInfo().version;
109
+ this.proverEnabled = !!config.proverEnabled;
108
110
  }
109
111
 
110
112
  /**
@@ -305,6 +307,10 @@ export class PXEService implements PXE {
305
307
  return await getNonNullifiedL1ToL2MessageWitness(this.node, contractAddress, messageHash, secret);
306
308
  }
307
309
 
310
+ public getL2ToL1MembershipWitness(blockNumber: number, l2Tol1Message: Fr): Promise<[bigint, SiblingPath<number>]> {
311
+ return this.node.getL2ToL1MessageMembershipWitness(blockNumber, l2Tol1Message);
312
+ }
313
+
308
314
  public async addNote(note: ExtendedNote, scope?: AztecAddress) {
309
315
  const owner = await this.db.getCompleteAddress(note.owner);
310
316
  if (!owner) {
@@ -453,20 +459,16 @@ export class PXEService implements PXE {
453
459
  return await this.node.getCurrentBaseFees();
454
460
  }
455
461
 
456
- async #simulateKernels(
457
- txRequest: TxExecutionRequest,
458
- privateExecutionResult: PrivateExecutionResult,
459
- ): Promise<PrivateKernelTailCircuitPublicInputs> {
460
- const result = await this.#prove(txRequest, new TestPrivateKernelProver(), privateExecutionResult);
461
- return result.publicInputs;
462
- }
463
-
464
462
  public async proveTx(
465
463
  txRequest: TxExecutionRequest,
466
464
  privateExecutionResult: PrivateExecutionResult,
467
465
  ): Promise<TxProvingResult> {
468
466
  try {
469
- const { publicInputs, clientIvcProof } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult);
467
+ const { publicInputs, clientIvcProof } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
468
+ simulate: false,
469
+ profile: false,
470
+ dryRun: false,
471
+ });
470
472
  return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof!);
471
473
  } catch (err: any) {
472
474
  throw this.contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult));
@@ -501,17 +503,11 @@ export class PXEService implements PXE {
501
503
  await this.synchronizer.sync();
502
504
  const privateExecutionResult = await this.#executePrivate(txRequest, msgSender, scopes);
503
505
 
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
- }
506
+ const { publicInputs, profileResult } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
507
+ simulate: !profile,
508
+ profile,
509
+ dryRun: true,
510
+ });
515
511
 
516
512
  const privateSimulationResult = new PrivateSimulationResult(privateExecutionResult, publicInputs);
517
513
  const simulatedTx = privateSimulationResult.toSimulatedTx();
@@ -526,8 +522,8 @@ export class PXEService implements PXE {
526
522
  }
527
523
  }
528
524
 
529
- this.log.info(`Simulation completed for ${simulatedTx.tryGetTxHash()} in ${timer.ms()}ms`, {
530
- txHash: simulatedTx.tryGetTxHash(),
525
+ this.log.info(`Simulation completed for ${simulatedTx.getTxHash()} in ${timer.ms()}ms`, {
526
+ txHash: simulatedTx.getTxHash(),
531
527
  ...txInfo,
532
528
  ...(profileResult ? { gateCounts: profileResult.gateCounts } : {}),
533
529
  ...(publicOutput
@@ -795,20 +791,6 @@ export class PXEService implements PXE {
795
791
  }
796
792
  }
797
793
 
798
- async #profileKernelProver(
799
- txExecutionRequest: TxExecutionRequest,
800
- proofCreator: PrivateKernelProver,
801
- privateExecutionResult: PrivateExecutionResult,
802
- ): Promise<PrivateKernelSimulateOutput<PrivateKernelTailCircuitPublicInputs>> {
803
- const block = privateExecutionResult.publicInputs.historicalHeader.globalVariables.blockNumber.toNumber();
804
- const kernelOracle = new KernelOracle(this.contractDataOracle, this.keyStore, this.node, block);
805
- const kernelProver = new KernelProver(kernelOracle, proofCreator);
806
-
807
- // Dry run the prover with profiler enabled
808
- const result = await kernelProver.prove(txExecutionRequest.toTxRequest(), privateExecutionResult, true, true);
809
- return result;
810
- }
811
-
812
794
  /**
813
795
  * Generate a kernel proof, and create a private kernel output.
814
796
  * The function takes in a transaction execution request, and the result of private execution
@@ -823,13 +805,19 @@ export class PXEService implements PXE {
823
805
  txExecutionRequest: TxExecutionRequest,
824
806
  proofCreator: PrivateKernelProver,
825
807
  privateExecutionResult: PrivateExecutionResult,
808
+ { simulate, profile, dryRun }: ProvingConfig,
826
809
  ): Promise<PrivateKernelSimulateOutput<PrivateKernelTailCircuitPublicInputs>> {
827
810
  // use the block the tx was simulated against
828
- const block = privateExecutionResult.publicInputs.historicalHeader.globalVariables.blockNumber.toNumber();
811
+ const block =
812
+ privateExecutionResult.entrypoint.publicInputs.historicalHeader.globalVariables.blockNumber.toNumber();
829
813
  const kernelOracle = new KernelOracle(this.contractDataOracle, this.keyStore, this.node, block);
830
- const kernelProver = new KernelProver(kernelOracle, proofCreator);
831
- this.log.debug(`Executing kernel prover...`);
832
- return await kernelProver.prove(txExecutionRequest.toTxRequest(), privateExecutionResult);
814
+ const kernelProver = new KernelProver(kernelOracle, proofCreator, !this.proverEnabled);
815
+ this.log.debug(`Executing kernel prover (simulate: ${simulate}, profile: ${profile}, dryRun: ${dryRun})...`);
816
+ return await kernelProver.prove(txExecutionRequest.toTxRequest(), privateExecutionResult, {
817
+ simulate,
818
+ profile,
819
+ dryRun,
820
+ });
833
821
  }
834
822
 
835
823
  public async isContractClassPubliclyRegistered(id: Fr): Promise<boolean> {
@@ -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/client';
3
+ import { AcirSimulator, type SimulationProvider } 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';
@@ -13,6 +13,7 @@ export function getAcirSimulator(
13
13
  db: PxeDatabase,
14
14
  aztecNode: AztecNode,
15
15
  keyStore: KeyStore,
16
+ simulationProvider: SimulationProvider,
16
17
  contractDataOracle?: ContractDataOracle,
17
18
  ) {
18
19
  const simulatorOracle = new SimulatorOracle(
@@ -20,6 +21,7 @@ export function getAcirSimulator(
20
21
  db,
21
22
  keyStore,
22
23
  aztecNode,
24
+ simulationProvider,
23
25
  );
24
- return new AcirSimulator(simulatorOracle, aztecNode);
26
+ return new AcirSimulator(simulatorOracle, aztecNode, simulationProvider);
25
27
  }
@@ -30,8 +30,12 @@ import { type FunctionArtifact, getFunctionArtifact } from '@aztec/foundation/ab
30
30
  import { poseidon2Hash } from '@aztec/foundation/crypto';
31
31
  import { createLogger } from '@aztec/foundation/log';
32
32
  import { type KeyStore } from '@aztec/key-store';
33
- import { MessageLoadOracleInputs } from '@aztec/simulator/acvm';
34
- import { type AcirSimulator, type DBOracle } from '@aztec/simulator/client';
33
+ import {
34
+ type AcirSimulator,
35
+ type DBOracle,
36
+ MessageLoadOracleInputs,
37
+ type SimulationProvider,
38
+ } from '@aztec/simulator/client';
35
39
 
36
40
  import { type ContractDataOracle } from '../contract_data_oracle/index.js';
37
41
  import { type PxeDatabase } from '../database/index.js';
@@ -49,6 +53,7 @@ export class SimulatorOracle implements DBOracle {
49
53
  private db: PxeDatabase,
50
54
  private keyStore: KeyStore,
51
55
  private aztecNode: AztecNode,
56
+ private simulationProvider: SimulationProvider,
52
57
  private log = createLogger('pxe:simulator_oracle'),
53
58
  ) {}
54
59
 
@@ -163,7 +168,7 @@ export class SimulatorOracle implements DBOracle {
163
168
  * @returns - The index of the commitment. Undefined if it does not exist in the tree.
164
169
  */
165
170
  async getCommitmentIndex(commitment: Fr) {
166
- return await this.findLeafIndex('latest', MerkleTreeId.NOTE_HASH_TREE, commitment);
171
+ return await this.#findLeafIndex('latest', MerkleTreeId.NOTE_HASH_TREE, commitment);
167
172
  }
168
173
 
169
174
  // We need this in public as part of the EXISTS calls - but isn't used in private
@@ -172,19 +177,26 @@ export class SimulatorOracle implements DBOracle {
172
177
  }
173
178
 
174
179
  async getNullifierIndex(nullifier: Fr) {
175
- return await this.findLeafIndex('latest', MerkleTreeId.NULLIFIER_TREE, nullifier);
180
+ return await this.#findLeafIndex('latest', MerkleTreeId.NULLIFIER_TREE, nullifier);
176
181
  }
177
182
 
178
- public async findLeafIndex(
179
- blockNumber: L2BlockNumber,
180
- treeId: MerkleTreeId,
181
- leafValue: Fr,
182
- ): Promise<bigint | undefined> {
183
+ async #findLeafIndex(blockNumber: L2BlockNumber, treeId: MerkleTreeId, leafValue: Fr): Promise<bigint | undefined> {
183
184
  const [leafIndex] = await this.aztecNode.findLeavesIndexes(blockNumber, treeId, [leafValue]);
184
185
  return leafIndex;
185
186
  }
186
187
 
187
- public async getSiblingPath(blockNumber: number, treeId: MerkleTreeId, leafIndex: bigint): Promise<Fr[]> {
188
+ public async getMembershipWitness(blockNumber: number, treeId: MerkleTreeId, leafValue: Fr): Promise<Fr[]> {
189
+ const leafIndex = await this.#findLeafIndex(blockNumber, treeId, leafValue);
190
+ if (!leafIndex) {
191
+ throw new Error(`Leaf value: ${leafValue} not found in ${MerkleTreeId[treeId]}`);
192
+ }
193
+
194
+ const siblingPath = await this.#getSiblingPath(blockNumber, treeId, leafIndex);
195
+
196
+ return [new Fr(leafIndex), ...siblingPath];
197
+ }
198
+
199
+ async #getSiblingPath(blockNumber: number, treeId: MerkleTreeId, leafIndex: bigint): Promise<Fr[]> {
188
200
  switch (treeId) {
189
201
  case MerkleTreeId.NULLIFIER_TREE:
190
202
  return (await this.aztecNode.getNullifierSiblingPath(blockNumber, leafIndex)).toFields();
@@ -598,11 +610,13 @@ export class SimulatorOracle implements DBOracle {
598
610
  // I don't like this at all, but we need a simulator to run `computeNoteHashAndOptionallyANullifier`. This generates
599
611
  // a chicken-and-egg problem due to this oracle requiring a simulator, which in turn requires this oracle. Furthermore, since jest doesn't allow
600
612
  // mocking ESM exports, we have to pollute the method even more by providing a simulator parameter so tests can inject a fake one.
601
- simulator ?? getAcirSimulator(this.db, this.aztecNode, this.keyStore, this.contractDataOracle),
613
+ simulator ??
614
+ getAcirSimulator(this.db, this.aztecNode, this.keyStore, this.simulationProvider, this.contractDataOracle),
602
615
  this.db,
603
616
  notePayload ? recipient.toAddressPoint() : undefined,
604
617
  payload!,
605
618
  txEffect.data.txHash,
619
+ txEffect.data.nullifiers[0],
606
620
  txEffect.l2BlockNumber,
607
621
  txEffect.l2BlockHash,
608
622
  txEffect.data.noteHashes,
@@ -666,4 +680,26 @@ export class SimulatorOracle implements DBOracle {
666
680
  });
667
681
  }
668
682
  }
683
+
684
+ /**
685
+ * Used by contracts during execution to store arbitrary data in the local PXE database. The data is siloed/scoped
686
+ * to a specific `contract`.
687
+ * @param contract - An address of a contract that is requesting to store the data.
688
+ * @param key - A field element representing the key to store the data under.
689
+ * @param values - An array of field elements representing the data to store.
690
+ */
691
+ store(contract: AztecAddress, key: Fr, values: Fr[]): Promise<void> {
692
+ return this.db.store(contract, key, values);
693
+ }
694
+
695
+ /**
696
+ * Used by contracts during execution to load arbitrary data from the local PXE database. The data is siloed/scoped
697
+ * to a specific `contract`.
698
+ * @param contract - An address of a contract that is requesting to load the data.
699
+ * @param key - A field element representing the key under which to load the data..
700
+ * @returns An array of field elements representing the stored data or `null` if no data is stored under the key.
701
+ */
702
+ load(contract: AztecAddress, key: Fr): Promise<Fr[] | null> {
703
+ return this.db.load(contract, key);
704
+ }
669
705
  }
@@ -1,15 +1,15 @@
1
1
  import { BBNativePrivateKernelProver } from '@aztec/bb-prover';
2
- import { BBWasmPrivateKernelProver } from '@aztec/bb-prover/wasm';
2
+ import { BBWASMBundlePrivateKernelProver } from '@aztec/bb-prover/wasm/bundle';
3
3
  import { type AztecNode, type PrivateKernelProver } from '@aztec/circuit-types';
4
4
  import { randomBytes } from '@aztec/foundation/crypto';
5
5
  import { createLogger } from '@aztec/foundation/log';
6
6
  import { KeyStore } from '@aztec/key-store';
7
7
  import { createStore } from '@aztec/kv-store/lmdb';
8
8
  import { L2TipsStore } from '@aztec/kv-store/stores';
9
+ import { type SimulationProvider, WASMSimulator } from '@aztec/simulator/client';
9
10
 
10
11
  import { type PXEServiceConfig } from '../config/index.js';
11
12
  import { KVPxeDatabase } from '../database/kv_pxe_database.js';
12
- import { TestPrivateKernelProver } from '../kernel_prover/test/test_circuit_prover.js';
13
13
  import { PXEService } from '../pxe_service/pxe_service.js';
14
14
 
15
15
  /**
@@ -46,25 +46,20 @@ export async function createPXEService(
46
46
 
47
47
  const db = await KVPxeDatabase.create(store);
48
48
  const tips = new L2TipsStore(store, 'pxe');
49
-
50
- const prover = proofCreator ?? (await createProver(config, logSuffix));
51
- const pxe = new PXEService(keyStore, aztecNode, db, tips, prover, config, logSuffix);
49
+ const simulationProvider = new WASMSimulator();
50
+ const prover = proofCreator ?? (await createProver(config, simulationProvider, logSuffix));
51
+ const pxe = new PXEService(keyStore, aztecNode, db, tips, prover, simulationProvider, config, logSuffix);
52
52
  await pxe.init();
53
53
  return pxe;
54
54
  }
55
55
 
56
- function createProver(config: PXEServiceConfig, logSuffix?: string) {
57
- if (!config.proverEnabled) {
58
- return new TestPrivateKernelProver();
59
- }
60
-
61
- // (@PhilWindle) Temporary validation until WASM is implemented
56
+ function createProver(config: PXEServiceConfig, simulationProvider: SimulationProvider, logSuffix?: string) {
62
57
  if (!config.bbBinaryPath || !config.bbWorkingDirectory) {
63
- return new BBWasmPrivateKernelProver(16);
58
+ return new BBWASMBundlePrivateKernelProver(simulationProvider, 16);
64
59
  } else {
65
60
  const bbConfig = config as Required<Pick<PXEServiceConfig, 'bbBinaryPath' | 'bbWorkingDirectory'>> &
66
61
  PXEServiceConfig;
67
62
  const log = createLogger('pxe:bb-native-prover' + (logSuffix ? `:${logSuffix}` : ''));
68
- return BBNativePrivateKernelProver.new({ bbSkipCleanup: false, ...bbConfig }, log);
63
+ return BBNativePrivateKernelProver.new({ bbSkipCleanup: false, ...bbConfig }, simulationProvider, log);
69
64
  }
70
65
  }
@@ -1,20 +0,0 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
- /// <reference types="node" resolution-mode="require"/>
3
- import { type PrivateKernelProver, type PrivateKernelSimulateOutput } from '@aztec/circuit-types';
4
- import { ClientIvcProof, type PrivateKernelCircuitPublicInputs, type PrivateKernelInitCircuitPrivateInputs, type PrivateKernelInnerCircuitPrivateInputs, type PrivateKernelResetCircuitPrivateInputs, type PrivateKernelTailCircuitPrivateInputs, type PrivateKernelTailCircuitPublicInputs } from '@aztec/circuits.js';
5
- import { type WitnessMap } from '@noir-lang/types';
6
- /**
7
- * Test Proof Creator executes circuit simulations and provides fake proofs.
8
- */
9
- export declare class TestPrivateKernelProver implements PrivateKernelProver {
10
- private log;
11
- constructor(log?: import("@aztec/foundation/log").Logger);
12
- createClientIvcProof(_acirs: Buffer[], _witnessStack: WitnessMap[]): Promise<ClientIvcProof>;
13
- simulateProofInit(privateInputs: PrivateKernelInitCircuitPrivateInputs): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>>;
14
- simulateProofInner(privateInputs: PrivateKernelInnerCircuitPrivateInputs): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>>;
15
- simulateProofReset(privateInputs: PrivateKernelResetCircuitPrivateInputs): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>>;
16
- simulateProofTail(privateInputs: PrivateKernelTailCircuitPrivateInputs): Promise<PrivateKernelSimulateOutput<PrivateKernelTailCircuitPublicInputs>>;
17
- computeGateCountForCircuit(_bytecode: Buffer, _circuitName: string): Promise<number>;
18
- private makeEmptyKernelSimulateOutput;
19
- }
20
- //# sourceMappingURL=test_circuit_prover.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"test_circuit_prover.d.ts","sourceRoot":"","sources":["../../../src/kernel_prover/test/test_circuit_prover.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AAElG,OAAO,EACL,cAAc,EACd,KAAK,gCAAgC,EACrC,KAAK,qCAAqC,EAC1C,KAAK,sCAAsC,EAC3C,KAAK,sCAAsC,EAC3C,KAAK,qCAAqC,EAC1C,KAAK,oCAAoC,EAC1C,MAAM,oBAAoB,CAAC;AAe5B,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB;IACrD,OAAO,CAAC,GAAG;gBAAH,GAAG,yCAAyC;IAEhE,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC;IAI/E,iBAAiB,CAC5B,aAAa,EAAE,qCAAqC,GACnD,OAAO,CAAC,2BAA2B,CAAC,gCAAgC,CAAC,CAAC;IAY5D,kBAAkB,CAC7B,aAAa,EAAE,sCAAsC,GACpD,OAAO,CAAC,2BAA2B,CAAC,gCAAgC,CAAC,CAAC;IAY5D,kBAAkB,CAC7B,aAAa,EAAE,sCAAsC,GACpD,OAAO,CAAC,2BAA2B,CAAC,gCAAgC,CAAC,CAAC;IAkB5D,iBAAiB,CAC5B,aAAa,EAAE,qCAAqC,GACnD,OAAO,CAAC,2BAA2B,CAAC,oCAAoC,CAAC,CAAC;IAkBtE,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK3F,OAAO,CAAC,6BAA6B;CAWtC"}