@aztec/pxe 0.69.0-devnet → 0.69.1-devnet

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 (59) hide show
  1. package/dest/database/kv_pxe_database.d.ts +11 -7
  2. package/dest/database/kv_pxe_database.d.ts.map +1 -1
  3. package/dest/database/kv_pxe_database.js +36 -13
  4. package/dest/database/note_dao.d.ts +105 -0
  5. package/dest/database/note_dao.d.ts.map +1 -0
  6. package/dest/database/note_dao.js +123 -0
  7. package/dest/database/outgoing_note_dao.js +3 -3
  8. package/dest/database/pxe_database.d.ts +25 -9
  9. package/dest/database/pxe_database.d.ts.map +1 -1
  10. package/dest/database/pxe_database_test_suite.d.ts.map +1 -1
  11. package/dest/database/pxe_database_test_suite.js +68 -21
  12. package/dest/kernel_oracle/index.js +2 -2
  13. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.js +2 -2
  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 +32 -12
  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 +3 -3
  24. package/dest/note_decryption_utils/produce_note_daos.d.ts.map +1 -1
  25. package/dest/note_decryption_utils/produce_note_daos.js +6 -6
  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/pxe_service.d.ts +3 -2
  30. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  31. package/dest/pxe_service/pxe_service.js +34 -42
  32. package/dest/simulator_oracle/index.d.ts +18 -3
  33. package/dest/simulator_oracle/index.d.ts.map +1 -1
  34. package/dest/simulator_oracle/index.js +63 -37
  35. package/dest/utils/create_pxe_service.d.ts.map +1 -1
  36. package/dest/utils/create_pxe_service.js +3 -8
  37. package/package.json +14 -15
  38. package/src/database/kv_pxe_database.ts +46 -16
  39. package/src/database/{incoming_note_dao.ts → note_dao.ts} +65 -48
  40. package/src/database/outgoing_note_dao.ts +2 -2
  41. package/src/database/pxe_database.ts +27 -9
  42. package/src/database/pxe_database_test_suite.ts +86 -25
  43. package/src/kernel_oracle/index.ts +1 -1
  44. package/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts +1 -1
  45. package/src/kernel_prover/index.ts +0 -2
  46. package/src/kernel_prover/kernel_prover.ts +41 -11
  47. package/src/note_decryption_utils/brute_force_note_info.ts +1 -1
  48. package/src/note_decryption_utils/produce_note_daos.ts +8 -6
  49. package/src/note_decryption_utils/produce_note_daos_for_key.ts +2 -0
  50. package/src/pxe_service/pxe_service.ts +42 -63
  51. package/src/simulator_oracle/index.ts +54 -24
  52. package/src/utils/create_pxe_service.ts +2 -8
  53. package/dest/database/incoming_note_dao.d.ts +0 -86
  54. package/dest/database/incoming_note_dao.d.ts.map +0 -1
  55. package/dest/database/incoming_note_dao.js +0 -110
  56. package/dest/kernel_prover/test/test_circuit_prover.d.ts +0 -20
  57. package/dest/kernel_prover/test/test_circuit_prover.d.ts.map +0 -1
  58. package/dest/kernel_prover/test/test_circuit_prover.js +0 -75
  59. package/src/kernel_prover/test/test_circuit_prover.ts +0 -122
@@ -10,6 +10,7 @@ import {
10
10
  } from '@aztec/circuit-types';
11
11
  import {
12
12
  CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS,
13
+ ClientIvcProof,
13
14
  Fr,
14
15
  PROTOCOL_CONTRACT_TREE_HEIGHT,
15
16
  PrivateCallData,
@@ -32,7 +33,7 @@ import { createLogger } from '@aztec/foundation/log';
32
33
  import { assertLength } from '@aztec/foundation/serialize';
33
34
  import { pushTestData } from '@aztec/foundation/testing';
34
35
  import { Timer } from '@aztec/foundation/timer';
35
- import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/client';
36
+ import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks';
36
37
  import {
37
38
  getProtocolContractSiblingPath,
38
39
  isProtocolContract,
@@ -89,6 +90,12 @@ const NULL_PROVE_OUTPUT: PrivateKernelSimulateOutput<PrivateKernelCircuitPublicI
89
90
  bytecode: Buffer.from([]),
90
91
  };
91
92
 
93
+ export type ProvingConfig = {
94
+ simulate: boolean;
95
+ profile: boolean;
96
+ dryRun: boolean;
97
+ };
98
+
92
99
  /**
93
100
  * The KernelProver class is responsible for generating kernel proofs.
94
101
  * It takes a transaction request, its signature, and the simulation result as inputs, and outputs a proof
@@ -98,7 +105,11 @@ const NULL_PROVE_OUTPUT: PrivateKernelSimulateOutput<PrivateKernelCircuitPublicI
98
105
  export class KernelProver {
99
106
  private log = createLogger('pxe:kernel-prover');
100
107
 
101
- constructor(private oracle: ProvingDataOracle, private proofCreator: PrivateKernelProver) {}
108
+ constructor(
109
+ private oracle: ProvingDataOracle,
110
+ private proofCreator: PrivateKernelProver,
111
+ private fakeProofs = false,
112
+ ) {}
102
113
 
103
114
  /**
104
115
  * Generate a proof for a given transaction request and execution result.
@@ -116,9 +127,14 @@ export class KernelProver {
116
127
  async prove(
117
128
  txRequest: TxRequest,
118
129
  executionResult: PrivateExecutionResult,
119
- profile: boolean = false,
120
- dryRun: boolean = false,
130
+ { simulate, profile, dryRun }: ProvingConfig = { simulate: false, profile: false, dryRun: false },
121
131
  ): Promise<PrivateKernelSimulateOutput<PrivateKernelTailCircuitPublicInputs>> {
132
+ if (simulate && profile) {
133
+ throw new Error('Cannot simulate and profile at the same time');
134
+ }
135
+
136
+ simulate = simulate || this.fakeProofs;
137
+
122
138
  const timer = new Timer();
123
139
 
124
140
  const isPrivateOnlyTx = this.isPrivateOnly(executionResult);
@@ -156,7 +172,9 @@ export class KernelProver {
156
172
  );
157
173
  while (resetBuilder.needsReset()) {
158
174
  const privateInputs = await resetBuilder.build(this.oracle, noteHashLeafIndexMap);
159
- output = await this.proofCreator.simulateProofReset(privateInputs);
175
+ output = simulate
176
+ ? await this.proofCreator.simulateReset(privateInputs)
177
+ : await this.proofCreator.generateResetOutput(privateInputs);
160
178
  // TODO(#7368) consider refactoring this redundant bytecode pushing
161
179
  acirs.push(output.bytecode);
162
180
  witnessStack.push(output.outputWitness);
@@ -203,7 +221,9 @@ export class KernelProver {
203
221
 
204
222
  pushTestData('private-kernel-inputs-init', proofInput);
205
223
 
206
- output = await this.proofCreator.simulateProofInit(proofInput);
224
+ output = simulate
225
+ ? await this.proofCreator.simulateInit(proofInput)
226
+ : await this.proofCreator.generateInitOutput(proofInput);
207
227
 
208
228
  acirs.push(output.bytecode);
209
229
  witnessStack.push(output.outputWitness);
@@ -222,7 +242,9 @@ export class KernelProver {
222
242
 
223
243
  pushTestData('private-kernel-inputs-inner', proofInput);
224
244
 
225
- output = await this.proofCreator.simulateProofInner(proofInput);
245
+ output = simulate
246
+ ? await this.proofCreator.simulateInner(proofInput)
247
+ : await this.proofCreator.generateInnerOutput(proofInput);
226
248
 
227
249
  acirs.push(output.bytecode);
228
250
  witnessStack.push(output.outputWitness);
@@ -242,7 +264,9 @@ export class KernelProver {
242
264
  );
243
265
  while (resetBuilder.needsReset()) {
244
266
  const privateInputs = await resetBuilder.build(this.oracle, noteHashLeafIndexMap);
245
- output = await this.proofCreator.simulateProofReset(privateInputs);
267
+ output = simulate
268
+ ? await this.proofCreator.simulateReset(privateInputs)
269
+ : await this.proofCreator.generateResetOutput(privateInputs);
246
270
 
247
271
  acirs.push(output.bytecode);
248
272
  witnessStack.push(output.outputWitness);
@@ -275,7 +299,9 @@ export class KernelProver {
275
299
 
276
300
  pushTestData('private-kernel-inputs-ordering', privateInputs);
277
301
 
278
- const tailOutput = await this.proofCreator.simulateProofTail(privateInputs);
302
+ const tailOutput = simulate
303
+ ? await this.proofCreator.simulateTail(privateInputs)
304
+ : await this.proofCreator.generateTailOutput(privateInputs);
279
305
  if (tailOutput.publicInputs.forPublic) {
280
306
  const privateLogs = privateInputs.previousKernel.publicInputs.end.privateLogs;
281
307
  const nonRevertiblePrivateLogs = tailOutput.publicInputs.forPublic.nonRevertibleAccumulatedData.privateLogs;
@@ -290,12 +316,16 @@ export class KernelProver {
290
316
  tailOutput.profileResult = { gateCounts };
291
317
  }
292
318
 
293
- this.log.verbose(`Private kernel witness generation took ${timer.ms()}ms`);
319
+ if (!simulate) {
320
+ this.log.info(`Private kernel witness generation took ${timer.ms()}ms`);
321
+ }
294
322
 
295
323
  // TODO(#7368) how do we 'bincode' encode these inputs?
296
- if (!dryRun) {
324
+ if (!dryRun && !simulate) {
297
325
  const ivcProof = await this.proofCreator.createClientIvcProof(acirs, witnessStack);
298
326
  tailOutput.clientIvcProof = ivcProof;
327
+ } else {
328
+ tailOutput.clientIvcProof = ClientIvcProof.empty();
299
329
  }
300
330
 
301
331
  return tailOutput;
@@ -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)) {
@@ -3,7 +3,7 @@ import { type Fr } from '@aztec/foundation/fields';
3
3
  import { type Logger } from '@aztec/foundation/log';
4
4
  import { type AcirSimulator } from '@aztec/simulator/client';
5
5
 
6
- import { IncomingNoteDao } from '../database/incoming_note_dao.js';
6
+ import { NoteDao } from '../database/note_dao.js';
7
7
  import { type PxeDatabase } from '../database/pxe_database.js';
8
8
  import { produceNoteDaosForKey } from './produce_note_daos_for_key.js';
9
9
 
@@ -31,37 +31,39 @@ 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[],
37
38
  dataStartIndexForTx: number,
38
39
  excludedIndices: Set<number>,
39
40
  logger: Logger,
40
- ): Promise<{ incomingNote: IncomingNoteDao | undefined }> {
41
+ ): Promise<{ note: NoteDao | undefined }> {
41
42
  if (!addressPoint) {
42
43
  throw new Error('addressPoint is undefined. Cannot create note.');
43
44
  }
44
45
 
45
- let incomingNote: IncomingNoteDao | undefined;
46
+ let note: NoteDao | undefined;
46
47
 
47
48
  if (addressPoint) {
48
- incomingNote = await produceNoteDaosForKey(
49
+ note = await produceNoteDaosForKey(
49
50
  simulator,
50
51
  db,
51
52
  addressPoint,
52
53
  payload,
53
54
  txHash,
55
+ firstNullifier,
54
56
  l2BlockNumber,
55
57
  l2BlockHash,
56
58
  noteHashes,
57
59
  dataStartIndexForTx,
58
60
  excludedIndices,
59
61
  logger,
60
- IncomingNoteDao.fromPayloadAndNoteInfo,
62
+ NoteDao.fromPayloadAndNoteInfo,
61
63
  );
62
64
  }
63
65
 
64
66
  return {
65
- incomingNote,
67
+ note,
66
68
  };
67
69
  }
@@ -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,
@@ -7,11 +7,11 @@ import {
7
7
  type FunctionCall,
8
8
  type GetUnencryptedLogsResponse,
9
9
  type InBlock,
10
- type IncomingNotesFilter,
11
10
  L1EventPayload,
12
11
  type L2Block,
13
12
  type LogFilter,
14
13
  MerkleTreeId,
14
+ type NotesFilter,
15
15
  type PXE,
16
16
  type PXEInfo,
17
17
  type PrivateExecutionResult,
@@ -54,6 +54,7 @@ import {
54
54
  EventSelector,
55
55
  FunctionSelector,
56
56
  FunctionType,
57
+ decodeFunctionSignature,
57
58
  encodeArguments,
58
59
  } from '@aztec/foundation/abi';
59
60
  import { type AztecAddress } from '@aztec/foundation/aztec-address';
@@ -71,11 +72,10 @@ import { inspect } from 'util';
71
72
  import { type PXEServiceConfig } from '../config/index.js';
72
73
  import { getPackageInfo } from '../config/package_info.js';
73
74
  import { ContractDataOracle } from '../contract_data_oracle/index.js';
74
- import { IncomingNoteDao } from '../database/incoming_note_dao.js';
75
75
  import { type PxeDatabase } from '../database/index.js';
76
+ import { NoteDao } from '../database/note_dao.js';
76
77
  import { KernelOracle } from '../kernel_oracle/index.js';
77
- import { KernelProver } from '../kernel_prover/kernel_prover.js';
78
- import { TestPrivateKernelProver } from '../kernel_prover/test/test_circuit_prover.js';
78
+ import { KernelProver, type ProvingConfig } from '../kernel_prover/kernel_prover.js';
79
79
  import { getAcirSimulator } from '../simulator/index.js';
80
80
  import { Synchronizer } from '../synchronizer/index.js';
81
81
  import { enrichPublicSimulationError, enrichSimulationError } from './error_enriching.js';
@@ -89,6 +89,7 @@ export class PXEService implements PXE {
89
89
  private simulator: AcirSimulator;
90
90
  private log: Logger;
91
91
  private packageVersion: string;
92
+ private proverEnabled: boolean;
92
93
 
93
94
  constructor(
94
95
  private keyStore: KeyStore,
@@ -104,6 +105,7 @@ export class PXEService implements PXE {
104
105
  this.contractDataOracle = new ContractDataOracle(db);
105
106
  this.simulator = getAcirSimulator(db, node, keyStore, this.contractDataOracle);
106
107
  this.packageVersion = getPackageInfo().version;
108
+ this.proverEnabled = !!config.proverEnabled;
107
109
  }
108
110
 
109
111
  /**
@@ -237,14 +239,10 @@ export class PXEService implements PXE {
237
239
 
238
240
  await this.db.addContractArtifact(contractClassId, artifact);
239
241
 
240
- const functionNames: Record<string, string> = {};
241
- for (const fn of artifact.functions) {
242
- if (fn.functionType === FunctionType.PUBLIC) {
243
- functionNames[FunctionSelector.fromNameAndParameters(fn.name, fn.parameters).toString()] = fn.name;
244
- }
245
- }
246
-
247
- await this.node.registerContractFunctionNames(instance.address, functionNames);
242
+ const publicFunctionSignatures = artifact.functions
243
+ .filter(fn => fn.functionType === FunctionType.PUBLIC)
244
+ .map(fn => decodeFunctionSignature(fn.name, fn.parameters));
245
+ await this.node.registerContractFunctionSignatures(instance.address, publicFunctionSignatures);
248
246
 
249
247
  // TODO(#10007): Node should get public contract class from the registration event, not from PXE registration
250
248
  await this.node.addContractClass({ ...contractClass, privateFunctions: [], unconstrainedFunctions: [] });
@@ -273,8 +271,8 @@ export class PXEService implements PXE {
273
271
  return await this.node.getPublicStorageAt(contract, slot, 'latest');
274
272
  }
275
273
 
276
- public async getIncomingNotes(filter: IncomingNotesFilter): Promise<UniqueNote[]> {
277
- const noteDaos = await this.db.getIncomingNotes(filter);
274
+ public async getNotes(filter: NotesFilter): Promise<UniqueNote[]> {
275
+ const noteDaos = await this.db.getNotes(filter);
278
276
 
279
277
  const extendedNotes = noteDaos.map(async dao => {
280
278
  let owner = filter.owner;
@@ -343,19 +341,19 @@ export class PXEService implements PXE {
343
341
  }
344
342
 
345
343
  await this.db.addNote(
346
- new IncomingNoteDao(
344
+ new NoteDao(
347
345
  note.note,
348
346
  note.contractAddress,
349
347
  note.storageSlot,
350
- note.noteTypeId,
351
- note.txHash,
352
- l2BlockNumber,
353
- l2BlockHash,
354
348
  nonce,
355
349
  noteHash,
356
350
  siloedNullifier,
351
+ note.txHash,
352
+ l2BlockNumber,
353
+ l2BlockHash,
357
354
  index,
358
355
  owner.address.toAddressPoint(),
356
+ note.noteTypeId,
359
357
  ),
360
358
  scope,
361
359
  );
@@ -388,19 +386,19 @@ export class PXEService implements PXE {
388
386
  }
389
387
 
390
388
  await this.db.addNullifiedNote(
391
- new IncomingNoteDao(
389
+ new NoteDao(
392
390
  note.note,
393
391
  note.contractAddress,
394
392
  note.storageSlot,
395
- note.noteTypeId,
396
- note.txHash,
397
- l2BlockNumber,
398
- l2BlockHash,
399
393
  nonce,
400
394
  noteHash,
401
395
  Fr.ZERO, // We are not able to derive
396
+ note.txHash,
397
+ l2BlockNumber,
398
+ l2BlockHash,
402
399
  index,
403
400
  note.owner.toAddressPoint(),
401
+ note.noteTypeId,
404
402
  ),
405
403
  );
406
404
  }
@@ -456,20 +454,16 @@ export class PXEService implements PXE {
456
454
  return await this.node.getCurrentBaseFees();
457
455
  }
458
456
 
459
- async #simulateKernels(
460
- txRequest: TxExecutionRequest,
461
- privateExecutionResult: PrivateExecutionResult,
462
- ): Promise<PrivateKernelTailCircuitPublicInputs> {
463
- const result = await this.#prove(txRequest, new TestPrivateKernelProver(), privateExecutionResult);
464
- return result.publicInputs;
465
- }
466
-
467
457
  public async proveTx(
468
458
  txRequest: TxExecutionRequest,
469
459
  privateExecutionResult: PrivateExecutionResult,
470
460
  ): Promise<TxProvingResult> {
471
461
  try {
472
- const { publicInputs, clientIvcProof } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult);
462
+ const { publicInputs, clientIvcProof } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
463
+ simulate: false,
464
+ profile: false,
465
+ dryRun: false,
466
+ });
473
467
  return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof!);
474
468
  } catch (err: any) {
475
469
  throw this.contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult));
@@ -504,17 +498,11 @@ export class PXEService implements PXE {
504
498
  await this.synchronizer.sync();
505
499
  const privateExecutionResult = await this.#executePrivate(txRequest, msgSender, scopes);
506
500
 
507
- let publicInputs: PrivateKernelTailCircuitPublicInputs;
508
- let profileResult;
509
- if (profile) {
510
- ({ publicInputs, profileResult } = await this.#profileKernelProver(
511
- txRequest,
512
- this.proofCreator,
513
- privateExecutionResult,
514
- ));
515
- } else {
516
- publicInputs = await this.#simulateKernels(txRequest, privateExecutionResult);
517
- }
501
+ const { publicInputs, profileResult } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
502
+ simulate: !profile,
503
+ profile,
504
+ dryRun: true,
505
+ });
518
506
 
519
507
  const privateSimulationResult = new PrivateSimulationResult(privateExecutionResult, publicInputs);
520
508
  const simulatedTx = privateSimulationResult.toSimulatedTx();
@@ -529,8 +517,8 @@ export class PXEService implements PXE {
529
517
  }
530
518
  }
531
519
 
532
- this.log.info(`Simulation completed for ${simulatedTx.tryGetTxHash()} in ${timer.ms()}ms`, {
533
- txHash: simulatedTx.tryGetTxHash(),
520
+ this.log.info(`Simulation completed for ${simulatedTx.getTxHash()} in ${timer.ms()}ms`, {
521
+ txHash: simulatedTx.getTxHash(),
534
522
  ...txInfo,
535
523
  ...(profileResult ? { gateCounts: profileResult.gateCounts } : {}),
536
524
  ...(publicOutput
@@ -798,20 +786,6 @@ export class PXEService implements PXE {
798
786
  }
799
787
  }
800
788
 
801
- async #profileKernelProver(
802
- txExecutionRequest: TxExecutionRequest,
803
- proofCreator: PrivateKernelProver,
804
- privateExecutionResult: PrivateExecutionResult,
805
- ): Promise<PrivateKernelSimulateOutput<PrivateKernelTailCircuitPublicInputs>> {
806
- const block = privateExecutionResult.publicInputs.historicalHeader.globalVariables.blockNumber.toNumber();
807
- const kernelOracle = new KernelOracle(this.contractDataOracle, this.keyStore, this.node, block);
808
- const kernelProver = new KernelProver(kernelOracle, proofCreator);
809
-
810
- // Dry run the prover with profiler enabled
811
- const result = await kernelProver.prove(txExecutionRequest.toTxRequest(), privateExecutionResult, true, true);
812
- return result;
813
- }
814
-
815
789
  /**
816
790
  * Generate a kernel proof, and create a private kernel output.
817
791
  * The function takes in a transaction execution request, and the result of private execution
@@ -826,13 +800,18 @@ export class PXEService implements PXE {
826
800
  txExecutionRequest: TxExecutionRequest,
827
801
  proofCreator: PrivateKernelProver,
828
802
  privateExecutionResult: PrivateExecutionResult,
803
+ { simulate, profile, dryRun }: ProvingConfig,
829
804
  ): Promise<PrivateKernelSimulateOutput<PrivateKernelTailCircuitPublicInputs>> {
830
805
  // use the block the tx was simulated against
831
806
  const block = privateExecutionResult.publicInputs.historicalHeader.globalVariables.blockNumber.toNumber();
832
807
  const kernelOracle = new KernelOracle(this.contractDataOracle, this.keyStore, this.node, block);
833
- const kernelProver = new KernelProver(kernelOracle, proofCreator);
834
- this.log.debug(`Executing kernel prover...`);
835
- return await kernelProver.prove(txExecutionRequest.toTxRequest(), privateExecutionResult);
808
+ const kernelProver = new KernelProver(kernelOracle, proofCreator, !this.proverEnabled);
809
+ this.log.debug(`Executing kernel prover (simulate: ${simulate}, profile: ${profile}, dryRun: ${dryRun})...`);
810
+ return await kernelProver.prove(txExecutionRequest.toTxRequest(), privateExecutionResult, {
811
+ simulate,
812
+ profile,
813
+ dryRun,
814
+ });
836
815
  }
837
816
 
838
817
  public async isContractClassPubliclyRegistered(id: Fr): Promise<boolean> {
@@ -34,8 +34,8 @@ import { MessageLoadOracleInputs } from '@aztec/simulator/acvm';
34
34
  import { type AcirSimulator, type DBOracle } from '@aztec/simulator/client';
35
35
 
36
36
  import { type ContractDataOracle } from '../contract_data_oracle/index.js';
37
- import { type IncomingNoteDao } from '../database/incoming_note_dao.js';
38
37
  import { type PxeDatabase } from '../database/index.js';
38
+ import { type NoteDao } from '../database/note_dao.js';
39
39
  import { produceNoteDaos } from '../note_decryption_utils/produce_note_daos.js';
40
40
  import { getAcirSimulator } from '../simulator/index.js';
41
41
  import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndexesMap } from './tagging_utils.js';
@@ -92,7 +92,7 @@ export class SimulatorOracle implements DBOracle {
92
92
  }
93
93
 
94
94
  async getNotes(contractAddress: AztecAddress, storageSlot: Fr, status: NoteStatus, scopes?: AztecAddress[]) {
95
- const noteDaos = await this.db.getIncomingNotes({
95
+ const noteDaos = await this.db.getNotes({
96
96
  contractAddress,
97
97
  storageSlot,
98
98
  status,
@@ -163,7 +163,7 @@ export class SimulatorOracle implements DBOracle {
163
163
  * @returns - The index of the commitment. Undefined if it does not exist in the tree.
164
164
  */
165
165
  async getCommitmentIndex(commitment: Fr) {
166
- return await this.findLeafIndex('latest', MerkleTreeId.NOTE_HASH_TREE, commitment);
166
+ return await this.#findLeafIndex('latest', MerkleTreeId.NOTE_HASH_TREE, commitment);
167
167
  }
168
168
 
169
169
  // We need this in public as part of the EXISTS calls - but isn't used in private
@@ -172,19 +172,26 @@ export class SimulatorOracle implements DBOracle {
172
172
  }
173
173
 
174
174
  async getNullifierIndex(nullifier: Fr) {
175
- return await this.findLeafIndex('latest', MerkleTreeId.NULLIFIER_TREE, nullifier);
175
+ return await this.#findLeafIndex('latest', MerkleTreeId.NULLIFIER_TREE, nullifier);
176
176
  }
177
177
 
178
- public async findLeafIndex(
179
- blockNumber: L2BlockNumber,
180
- treeId: MerkleTreeId,
181
- leafValue: Fr,
182
- ): Promise<bigint | undefined> {
178
+ async #findLeafIndex(blockNumber: L2BlockNumber, treeId: MerkleTreeId, leafValue: Fr): Promise<bigint | undefined> {
183
179
  const [leafIndex] = await this.aztecNode.findLeavesIndexes(blockNumber, treeId, [leafValue]);
184
180
  return leafIndex;
185
181
  }
186
182
 
187
- public async getSiblingPath(blockNumber: number, treeId: MerkleTreeId, leafIndex: bigint): Promise<Fr[]> {
183
+ public async getMembershipWitness(blockNumber: number, treeId: MerkleTreeId, leafValue: Fr): Promise<Fr[]> {
184
+ const leafIndex = await this.#findLeafIndex(blockNumber, treeId, leafValue);
185
+ if (!leafIndex) {
186
+ throw new Error(`Leaf value: ${leafValue} not found in ${MerkleTreeId[treeId]}`);
187
+ }
188
+
189
+ const siblingPath = await this.#getSiblingPath(blockNumber, treeId, leafIndex);
190
+
191
+ return [new Fr(leafIndex), ...siblingPath];
192
+ }
193
+
194
+ async #getSiblingPath(blockNumber: number, treeId: MerkleTreeId, leafIndex: bigint): Promise<Fr[]> {
188
195
  switch (treeId) {
189
196
  case MerkleTreeId.NULLIFIER_TREE:
190
197
  return (await this.aztecNode.getNullifierSiblingPath(blockNumber, leafIndex)).toFields();
@@ -569,17 +576,17 @@ export class SimulatorOracle implements DBOracle {
569
576
  // Since we could have notes with the same index for different txs, we need
570
577
  // to keep track of them scoping by txHash
571
578
  const excludedIndices: Map<string, Set<number>> = new Map();
572
- const incomingNotes: IncomingNoteDao[] = [];
579
+ const notes: NoteDao[] = [];
573
580
 
574
581
  const txEffectsCache = new Map<string, InBlock<TxEffect> | undefined>();
575
582
 
576
583
  for (const scopedLog of scopedLogs) {
577
- const incomingNotePayload = scopedLog.isFromPublic
584
+ const notePayload = scopedLog.isFromPublic
578
585
  ? L1NotePayload.decryptAsIncomingFromPublic(scopedLog.logData, addressSecret)
579
586
  : L1NotePayload.decryptAsIncoming(PrivateLog.fromBuffer(scopedLog.logData), addressSecret);
580
587
 
581
- if (incomingNotePayload) {
582
- const payload = incomingNotePayload;
588
+ if (notePayload) {
589
+ const payload = notePayload;
583
590
 
584
591
  const txEffect =
585
592
  txEffectsCache.get(scopedLog.txHash.toString()) ?? (await this.aztecNode.getTxEffect(scopedLog.txHash));
@@ -594,15 +601,16 @@ export class SimulatorOracle implements DBOracle {
594
601
  if (!excludedIndices.has(scopedLog.txHash.toString())) {
595
602
  excludedIndices.set(scopedLog.txHash.toString(), new Set());
596
603
  }
597
- const { incomingNote } = await produceNoteDaos(
604
+ const { note } = await produceNoteDaos(
598
605
  // I don't like this at all, but we need a simulator to run `computeNoteHashAndOptionallyANullifier`. This generates
599
606
  // 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
607
  // mocking ESM exports, we have to pollute the method even more by providing a simulator parameter so tests can inject a fake one.
601
608
  simulator ?? getAcirSimulator(this.db, this.aztecNode, this.keyStore, this.contractDataOracle),
602
609
  this.db,
603
- incomingNotePayload ? recipient.toAddressPoint() : undefined,
610
+ notePayload ? recipient.toAddressPoint() : undefined,
604
611
  payload!,
605
612
  txEffect.data.txHash,
613
+ txEffect.data.nullifiers[0],
606
614
  txEffect.l2BlockNumber,
607
615
  txEffect.l2BlockHash,
608
616
  txEffect.data.noteHashes,
@@ -611,12 +619,12 @@ export class SimulatorOracle implements DBOracle {
611
619
  this.log,
612
620
  );
613
621
 
614
- if (incomingNote) {
615
- incomingNotes.push(incomingNote);
622
+ if (note) {
623
+ notes.push(note);
616
624
  }
617
625
  }
618
626
  }
619
- return { incomingNotes };
627
+ return { notes };
620
628
  }
621
629
 
622
630
  /**
@@ -629,10 +637,10 @@ export class SimulatorOracle implements DBOracle {
629
637
  recipient: AztecAddress,
630
638
  simulator?: AcirSimulator,
631
639
  ): Promise<void> {
632
- const { incomingNotes } = await this.#decryptTaggedLogs(logs, recipient, simulator);
633
- if (incomingNotes.length) {
634
- await this.db.addNotes(incomingNotes, recipient);
635
- incomingNotes.forEach(noteDao => {
640
+ const { notes } = await this.#decryptTaggedLogs(logs, recipient, simulator);
641
+ if (notes.length) {
642
+ await this.db.addNotes(notes, recipient);
643
+ notes.forEach(noteDao => {
636
644
  this.log.verbose(`Added incoming note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot}`, {
637
645
  contract: noteDao.contractAddress,
638
646
  slot: noteDao.storageSlot,
@@ -644,7 +652,7 @@ export class SimulatorOracle implements DBOracle {
644
652
 
645
653
  public async removeNullifiedNotes(contractAddress: AztecAddress) {
646
654
  for (const recipient of await this.keyStore.getAccounts()) {
647
- const currentNotesForRecipient = await this.db.getIncomingNotes({ contractAddress, owner: recipient });
655
+ const currentNotesForRecipient = await this.db.getNotes({ contractAddress, owner: recipient });
648
656
  const nullifiersToCheck = currentNotesForRecipient.map(note => note.siloedNullifier);
649
657
  const nullifierIndexes = await this.aztecNode.findNullifiersIndexesWithBlock('latest', nullifiersToCheck);
650
658
 
@@ -666,4 +674,26 @@ export class SimulatorOracle implements DBOracle {
666
674
  });
667
675
  }
668
676
  }
677
+
678
+ /**
679
+ * Used by contracts during execution to store arbitrary data in the local PXE database. The data is siloed/scoped
680
+ * to a specific `contract`.
681
+ * @param contract - An address of a contract that is requesting to store the data.
682
+ * @param key - A field element representing the key to store the data under.
683
+ * @param values - An array of field elements representing the data to store.
684
+ */
685
+ store(contract: AztecAddress, key: Fr, values: Fr[]): Promise<void> {
686
+ return this.db.store(contract, key, values);
687
+ }
688
+
689
+ /**
690
+ * Used by contracts during execution to load arbitrary data from the local PXE database. The data is siloed/scoped
691
+ * to a specific `contract`.
692
+ * @param contract - An address of a contract that is requesting to load the data.
693
+ * @param key - A field element representing the key under which to load the data..
694
+ * @returns An array of field elements representing the stored data or `null` if no data is stored under the key.
695
+ */
696
+ load(contract: AztecAddress, key: Fr): Promise<Fr[] | null> {
697
+ return this.db.load(contract, key);
698
+ }
669
699
  }
@@ -1,5 +1,5 @@
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';
@@ -9,7 +9,6 @@ import { L2TipsStore } from '@aztec/kv-store/stores';
9
9
 
10
10
  import { type PXEServiceConfig } from '../config/index.js';
11
11
  import { KVPxeDatabase } from '../database/kv_pxe_database.js';
12
- import { TestPrivateKernelProver } from '../kernel_prover/test/test_circuit_prover.js';
13
12
  import { PXEService } from '../pxe_service/pxe_service.js';
14
13
 
15
14
  /**
@@ -54,13 +53,8 @@ export async function createPXEService(
54
53
  }
55
54
 
56
55
  function createProver(config: PXEServiceConfig, logSuffix?: string) {
57
- if (!config.proverEnabled) {
58
- return new TestPrivateKernelProver();
59
- }
60
-
61
- // (@PhilWindle) Temporary validation until WASM is implemented
62
56
  if (!config.bbBinaryPath || !config.bbWorkingDirectory) {
63
- return new BBWasmPrivateKernelProver(16);
57
+ return new BBWASMBundlePrivateKernelProver(16);
64
58
  } else {
65
59
  const bbConfig = config as Required<Pick<PXEServiceConfig, 'bbBinaryPath' | 'bbWorkingDirectory'>> &
66
60
  PXEServiceConfig;