@aztec/pxe 0.86.0 → 0.87.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 (29) hide show
  1. package/dest/config/package_info.js +1 -1
  2. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
  3. package/dest/private_kernel/private_kernel_execution_prover.js +39 -8
  4. package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +1 -1
  5. package/dest/pxe_http/pxe_http_server.d.ts +0 -1
  6. package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
  7. package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts +0 -1
  8. package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts.map +1 -1
  9. package/dest/pxe_oracle_interface/pxe_oracle_interface.js +7 -19
  10. package/dest/pxe_service/error_enriching.d.ts.map +1 -1
  11. package/dest/pxe_service/error_enriching.js +17 -10
  12. package/dest/pxe_service/pxe_service.d.ts +5 -5
  13. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  14. package/dest/pxe_service/pxe_service.js +123 -36
  15. package/dest/storage/note_data_provider/note_dao.d.ts +0 -2
  16. package/dest/storage/note_data_provider/note_dao.d.ts.map +1 -1
  17. package/dest/storage/note_data_provider/note_data_provider.d.ts.map +1 -1
  18. package/dest/synchronizer/synchronizer.js +1 -1
  19. package/dest/test/pxe_test_suite.d.ts.map +1 -1
  20. package/package.json +18 -18
  21. package/src/config/package_info.ts +1 -1
  22. package/src/private_kernel/hints/build_private_kernel_reset_private_inputs.ts +2 -2
  23. package/src/private_kernel/private_kernel_execution_prover.ts +32 -4
  24. package/src/private_kernel/private_kernel_oracle_impl.ts +2 -3
  25. package/src/pxe_oracle_interface/pxe_oracle_interface.ts +8 -20
  26. package/src/pxe_service/error_enriching.ts +22 -12
  27. package/src/pxe_service/pxe_service.ts +185 -56
  28. package/src/storage/note_data_provider/note_data_provider.ts +22 -20
  29. package/src/synchronizer/synchronizer.ts +1 -1
@@ -48,6 +48,7 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
48
48
  protocolContractsProvider;
49
49
  log;
50
50
  jobQueue;
51
+ #nodeInfo;
51
52
  constructor(node, synchronizer, keyStore, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, privateEventDataProvider, simulator, packageVersion, proverEnabled, proofCreator, protocolContractsProvider, log, jobQueue){
52
53
  this.node = node;
53
54
  this.synchronizer = synchronizer;
@@ -443,21 +444,45 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
443
444
  // We disable proving concurrently mostly out of caution, since it accesses some of our stores. Proving is so
444
445
  // computationally demanding that it'd be rare for someone to try to do it concurrently regardless.
445
446
  return this.#putInJobQueue(async ()=>{
447
+ const totalTimer = new Timer();
446
448
  try {
447
- const { publicInputs, clientIvcProof } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
449
+ let syncTime;
450
+ if (!privateExecutionResult) {
451
+ const syncTimer = new Timer();
452
+ await this.synchronizer.sync();
453
+ syncTime = syncTimer.ms();
454
+ privateExecutionResult = await this.#executePrivate(txRequest);
455
+ }
456
+ const { publicInputs, clientIvcProof, executionSteps, timings: { proving } = {} } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
448
457
  simulate: false,
449
458
  skipFeeEnforcement: false,
450
459
  profileMode: 'none'
451
460
  });
452
- return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof);
461
+ const totalTime = totalTimer.ms();
462
+ const perFunction = executionSteps.map(({ functionName, timings: { witgen } })=>({
463
+ functionName,
464
+ time: witgen
465
+ }));
466
+ const timings = {
467
+ total: totalTime,
468
+ sync: syncTime,
469
+ proving,
470
+ perFunction,
471
+ unaccounted: totalTime - ((syncTime ?? 0) + (proving ?? 0) + perFunction.reduce((acc, { time })=>acc + time, 0))
472
+ };
473
+ this.log.info(`Proving completed in ${totalTime}ms`, {
474
+ timings
475
+ });
476
+ return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof, timings);
453
477
  } catch (err) {
454
478
  throw this.#contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult));
455
479
  }
456
480
  });
457
481
  }
458
- profileTx(txRequest, profileMode, msgSender) {
482
+ profileTx(txRequest, profileMode, skipProofGeneration = true, msgSender) {
459
483
  // We disable concurrent profiles for consistency with simulateTx.
460
484
  return this.#putInJobQueue(async ()=>{
485
+ const totalTimer = new Timer();
461
486
  try {
462
487
  const txInfo = {
463
488
  origin: txRequest.origin,
@@ -469,14 +494,30 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
469
494
  authWitnesses: txRequest.authWitnesses.map((w)=>w.requestHash)
470
495
  };
471
496
  this.log.info(`Profiling transaction execution request to ${txRequest.functionSelector} at ${txRequest.origin}`, txInfo);
497
+ const syncTimer = new Timer();
472
498
  await this.synchronizer.sync();
499
+ const syncTime = syncTimer.ms();
473
500
  const privateExecutionResult = await this.#executePrivate(txRequest, msgSender);
474
- const { executionSteps } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
475
- simulate: true,
501
+ const { executionSteps, timings: { proving } = {} } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
502
+ simulate: skipProofGeneration,
476
503
  skipFeeEnforcement: false,
477
504
  profileMode
478
505
  });
479
- return new TxProfileResult(executionSteps);
506
+ const totalTime = totalTimer.ms();
507
+ const perFunction = executionSteps.map(({ functionName, timings: { witgen } })=>({
508
+ functionName,
509
+ time: witgen
510
+ }));
511
+ // Gate computation is time is not relevant for profiling, so we subtract it from the total time.
512
+ const gateCountComputationTime = executionSteps.reduce((acc, { timings })=>acc + (timings.gateCount ?? 0), 0) ?? 0;
513
+ const timings = {
514
+ total: totalTime - gateCountComputationTime,
515
+ sync: syncTime,
516
+ proving,
517
+ perFunction,
518
+ unaccounted: totalTime - ((syncTime ?? 0) + (proving ?? 0) + perFunction.reduce((acc, { time })=>acc + time, 0) + gateCountComputationTime)
519
+ };
520
+ return new TxProfileResult(executionSteps, timings);
480
521
  } catch (err) {
481
522
  throw this.#contextualizeError(err, inspect(txRequest), `profileMode=${profileMode}`, `msgSender=${msgSender?.toString() ?? 'undefined'}`);
482
523
  }
@@ -489,6 +530,7 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
489
530
  // delete the same read value, or reading values that another simulation is currently modifying).
490
531
  return this.#putInJobQueue(async ()=>{
491
532
  try {
533
+ const totalTimer = new Timer();
492
534
  const txInfo = {
493
535
  origin: txRequest.origin,
494
536
  functionSelector: txRequest.functionSelector,
@@ -499,40 +541,61 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
499
541
  authWitnesses: txRequest.authWitnesses.map((w)=>w.requestHash)
500
542
  };
501
543
  this.log.info(`Simulating transaction execution request to ${txRequest.functionSelector} at ${txRequest.origin}`, txInfo);
502
- const timer = new Timer();
544
+ const syncTimer = new Timer();
503
545
  await this.synchronizer.sync();
546
+ const syncTime = syncTimer.ms();
504
547
  const privateExecutionResult = await this.#executePrivate(txRequest, msgSender, scopes);
505
- const { publicInputs } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
548
+ const { publicInputs, executionSteps } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
506
549
  simulate: true,
507
550
  skipFeeEnforcement,
508
551
  profileMode: 'none'
509
552
  });
510
553
  const privateSimulationResult = new PrivateSimulationResult(privateExecutionResult, publicInputs);
511
554
  const simulatedTx = privateSimulationResult.toSimulatedTx();
555
+ let publicSimulationTime;
512
556
  let publicOutput;
513
557
  if (simulatePublic && publicInputs.forPublic) {
558
+ const publicSimulationTimer = new Timer();
514
559
  publicOutput = await this.#simulatePublicCalls(simulatedTx, skipFeeEnforcement);
560
+ publicSimulationTime = publicSimulationTimer.ms();
515
561
  }
562
+ let validationTime;
516
563
  if (!skipTxValidation) {
564
+ const validationTimer = new Timer();
517
565
  const validationResult = await this.node.isValidTx(simulatedTx, {
518
566
  isSimulation: true,
519
567
  skipFeeEnforcement
520
568
  });
569
+ validationTime = validationTimer.ms();
521
570
  if (validationResult.result === 'invalid') {
522
571
  throw new Error('The simulated transaction is unable to be added to state and is invalid.');
523
572
  }
524
573
  }
525
574
  const txHash = await simulatedTx.getTxHash();
526
- this.log.info(`Simulation completed for ${txHash.toString()} in ${timer.ms()}ms`, {
575
+ const totalTime = totalTimer.ms();
576
+ const perFunction = executionSteps.map(({ functionName, timings: { witgen } })=>({
577
+ functionName,
578
+ time: witgen
579
+ }));
580
+ const timings = {
581
+ total: totalTime,
582
+ sync: syncTime,
583
+ publicSimulation: publicSimulationTime,
584
+ validation: validationTime,
585
+ perFunction,
586
+ unaccounted: totalTime - (syncTime + (publicSimulationTime ?? 0) + (validationTime ?? 0) + perFunction.reduce((acc, { time })=>acc + time, 0))
587
+ };
588
+ this.log.info(`Simulation completed for ${txHash.toString()} in ${totalTime}ms`, {
527
589
  txHash,
528
590
  ...txInfo,
529
591
  ...publicOutput ? {
530
592
  gasUsed: publicOutput.gasUsed,
531
593
  revertCode: publicOutput.txEffect.revertCode.getCode(),
532
594
  revertReason: publicOutput.revertReason
533
- } : {}
595
+ } : {},
596
+ timings
534
597
  });
535
- return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput(privateSimulationResult, publicOutput);
598
+ return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput(privateSimulationResult, publicOutput, timings);
536
599
  } catch (err) {
537
600
  throw this.#contextualizeError(err, inspect(txRequest), `simulatePublic=${simulatePublic}`, `msgSender=${msgSender?.toString() ?? 'undefined'}`, `skipTxValidation=${skipTxValidation}`, `scopes=${scopes?.map((s)=>s.toString()).join(', ') ?? 'undefined'}`);
538
601
  }
@@ -556,12 +619,32 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
556
619
  // delete the same read value, or reading values that another simulation is currently modifying).
557
620
  return this.#putInJobQueue(async ()=>{
558
621
  try {
622
+ const totalTimer = new Timer();
623
+ const syncTimer = new Timer();
559
624
  await this.synchronizer.sync();
625
+ const syncTime = syncTimer.ms();
560
626
  // TODO - Should check if `from` has the permission to call the view function.
561
627
  const functionCall = await this.#getFunctionCall(functionName, args, to);
628
+ const functionTimer = new Timer();
562
629
  const executionResult = await this.#simulateUtility(functionCall, authwits ?? [], scopes);
563
- // TODO - Return typed result based on the function artifact.
564
- return executionResult;
630
+ const functionTime = functionTimer.ms();
631
+ const totalTime = totalTimer.ms();
632
+ const perFunction = [
633
+ {
634
+ functionName,
635
+ time: functionTime
636
+ }
637
+ ];
638
+ const timings = {
639
+ total: totalTime,
640
+ sync: syncTime,
641
+ perFunction,
642
+ unaccounted: totalTime - (syncTime + perFunction.reduce((acc, { time })=>acc + time, 0))
643
+ };
644
+ return {
645
+ result: executionResult,
646
+ timings
647
+ };
565
648
  } catch (err) {
566
649
  const stringifiedArgs = args.map((arg)=>arg.toString()).join(', ');
567
650
  throw this.#contextualizeError(err, `simulateUtility ${to}:${functionName}(${stringifiedArgs})`, `scopes=${scopes?.map((s)=>s.toString()).join(', ') ?? 'undefined'}`);
@@ -569,23 +652,28 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
569
652
  });
570
653
  }
571
654
  async getNodeInfo() {
572
- const [nodeVersion, rollupVersion, chainId, enr, contractAddresses, protocolContractAddresses] = await Promise.all([
573
- this.node.getNodeVersion(),
574
- this.node.getVersion(),
575
- this.node.getChainId(),
576
- this.node.getEncodedEnr(),
577
- this.node.getL1ContractAddresses(),
578
- this.node.getProtocolContractAddresses()
579
- ]);
580
- const nodeInfo = {
581
- nodeVersion,
582
- l1ChainId: chainId,
583
- rollupVersion,
584
- enr,
585
- l1ContractAddresses: contractAddresses,
586
- protocolContractAddresses: protocolContractAddresses
587
- };
588
- return nodeInfo;
655
+ // This assumes we're connected to a single node, so we cache the info to avoid repeated calls.
656
+ // Load balancers and a myriad other configurations can break this assumption, so review this!
657
+ // Temporary mesure to avoid hammering full nodes with requests on testnet.
658
+ if (!this.#nodeInfo) {
659
+ const [nodeVersion, rollupVersion, chainId, enr, contractAddresses, protocolContractAddresses] = await Promise.all([
660
+ this.node.getNodeVersion(),
661
+ this.node.getVersion(),
662
+ this.node.getChainId(),
663
+ this.node.getEncodedEnr(),
664
+ this.node.getL1ContractAddresses(),
665
+ this.node.getProtocolContractAddresses()
666
+ ]);
667
+ this.#nodeInfo = {
668
+ nodeVersion,
669
+ l1ChainId: chainId,
670
+ rollupVersion,
671
+ enr,
672
+ l1ContractAddresses: contractAddresses,
673
+ protocolContractAddresses: protocolContractAddresses
674
+ };
675
+ }
676
+ return this.#nodeInfo;
589
677
  }
590
678
  getPXEInfo() {
591
679
  return Promise.resolve({
@@ -619,18 +707,17 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
619
707
  const decodedEvents = logs.map((log)=>{
620
708
  // +1 for the event selector
621
709
  const expectedLength = eventMetadataDef.fieldNames.length + 1;
622
- const logFields = log.log.log.slice(0, expectedLength);
710
+ if (log.log.emittedLength !== expectedLength) {
711
+ throw new Error(`Something is weird here, we have matching EventSelectors, but the actual payload has mismatched length. Expected ${expectedLength}. Got ${log.log.emittedLength}.`);
712
+ }
713
+ const logFields = log.log.getEmittedFields();
623
714
  // We are assuming here that event logs are the last 4 bytes of the event. This is not enshrined but is a function of aztec.nr raw log emission.
624
715
  if (!EventSelector.fromField(logFields[logFields.length - 1]).equals(eventMetadataDef.eventSelector)) {
625
716
  return undefined;
626
717
  }
627
- // If any of the remaining fields, are non-zero, the payload does match expected:
628
- if (log.log.log.slice(expectedLength + 1).find((f)=>!f.isZero())) {
629
- throw new Error('Something is weird here, we have matching EventSelectors, but the actual payload has mismatched length');
630
- }
631
718
  return decodeFromAbi([
632
719
  eventMetadataDef.abiType
633
- ], log.log.log);
720
+ ], log.log.fields);
634
721
  }).filter((log)=>log !== undefined);
635
722
  return decodedEvents;
636
723
  }
@@ -1,5 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
- /// <reference types="node" resolution-mode="require"/>
3
1
  import { Fr } from '@aztec/foundation/fields';
4
2
  import { BufferReader } from '@aztec/foundation/serialize';
5
3
  import type { NoteData } from '@aztec/simulator/client';
@@ -1 +1 @@
1
- {"version":3,"file":"note_dao.d.ts","sourceRoot":"","sources":["../../../src/storage/note_data_provider/note_dao.ts"],"names":[],"mappings":";;AACA,OAAO,EAAE,EAAE,EAAS,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,YAAY,EAAqB,MAAM,6BAA6B,CAAC;AAC9E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C;;;GAGG;AACH,qBAAa,OAAQ,YAAW,QAAQ;IAIpC,kFAAkF;IAC3E,IAAI,EAAE,IAAI;IACjB,8GAA8G;IACvG,eAAe,EAAE,YAAY;IACpC;;;SAGK;IACE,WAAW,EAAE,EAAE;IACtB,qFAAqF;IAC9E,KAAK,EAAE,EAAE;IAGhB;;;OAGG;IACI,QAAQ,EAAE,EAAE;IACnB;;;OAGG;IACI,eAAe,EAAE,EAAE;IAG1B;;OAEG;IACI,MAAM,EAAE,MAAM;IACrB;gBACY;IACL,aAAa,EAAE,MAAM;IAC5B;gBACY;IACL,WAAW,EAAE,MAAM;IAC1B,+EAA+E;IACxE,KAAK,EAAE,MAAM;IACpB;;;OAGG;IACI,SAAS,EAAE,YAAY;;IAzC9B,kFAAkF;IAC3E,IAAI,EAAE,IAAI;IACjB,8GAA8G;IACvG,eAAe,EAAE,YAAY;IACpC;;;SAGK;IACE,WAAW,EAAE,EAAE;IACtB,qFAAqF;IAC9E,KAAK,EAAE,EAAE;IAGhB;;;OAGG;IACI,QAAQ,EAAE,EAAE;IACnB;;;OAGG;IACI,eAAe,EAAE,EAAE;IAG1B;;OAEG;IACI,MAAM,EAAE,MAAM;IACrB;gBACY;IACL,aAAa,EAAE,MAAM;IAC5B;gBACY;IACL,WAAW,EAAE,MAAM;IAC1B,+EAA+E;IACxE,KAAK,EAAE,MAAM;IACpB;;;OAGG;IACI,SAAS,EAAE,YAAY;IAGhC,QAAQ,IAAI,MAAM;IAgBlB,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IA8B/C,QAAQ;IAIR,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM;IAK7B;;;OAGG;IACI,OAAO;WAMD,MAAM,CAAC,EAClB,IAAoB,EACpB,eAA2B,EAC3B,WAAyB,EACzB,KAAmB,EACnB,QAAsB,EACtB,eAA6B,EAC7B,MAAwB,EACxB,aAAgD,EAChD,WAAoC,EACpC,KAA8B,EAC9B,SAAqB,GACtB,GAAE,OAAO,CAAC,OAAO,CAAM;CAezB"}
1
+ {"version":3,"file":"note_dao.d.ts","sourceRoot":"","sources":["../../../src/storage/note_data_provider/note_dao.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAS,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,YAAY,EAAqB,MAAM,6BAA6B,CAAC;AAC9E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C;;;GAGG;AACH,qBAAa,OAAQ,YAAW,QAAQ;IAIpC,kFAAkF;IAC3E,IAAI,EAAE,IAAI;IACjB,8GAA8G;IACvG,eAAe,EAAE,YAAY;IACpC;;;SAGK;IACE,WAAW,EAAE,EAAE;IACtB,qFAAqF;IAC9E,KAAK,EAAE,EAAE;IAGhB;;;OAGG;IACI,QAAQ,EAAE,EAAE;IACnB;;;OAGG;IACI,eAAe,EAAE,EAAE;IAG1B;;OAEG;IACI,MAAM,EAAE,MAAM;IACrB;gBACY;IACL,aAAa,EAAE,MAAM;IAC5B;gBACY;IACL,WAAW,EAAE,MAAM;IAC1B,+EAA+E;IACxE,KAAK,EAAE,MAAM;IACpB;;;OAGG;IACI,SAAS,EAAE,YAAY;;IAzC9B,kFAAkF;IAC3E,IAAI,EAAE,IAAI;IACjB,8GAA8G;IACvG,eAAe,EAAE,YAAY;IACpC;;;SAGK;IACE,WAAW,EAAE,EAAE;IACtB,qFAAqF;IAC9E,KAAK,EAAE,EAAE;IAGhB;;;OAGG;IACI,QAAQ,EAAE,EAAE;IACnB;;;OAGG;IACI,eAAe,EAAE,EAAE;IAG1B;;OAEG;IACI,MAAM,EAAE,MAAM;IACrB;gBACY;IACL,aAAa,EAAE,MAAM;IAC5B;gBACY;IACL,WAAW,EAAE,MAAM;IAC1B,+EAA+E;IACxE,KAAK,EAAE,MAAM;IACpB;;;OAGG;IACI,SAAS,EAAE,YAAY;IAGhC,QAAQ,IAAI,MAAM;IAgBlB,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IA8B/C,QAAQ;IAIR,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM;IAK7B;;;OAGG;IACI,OAAO;WAMD,MAAM,CAAC,EAClB,IAAoB,EACpB,eAA2B,EAC3B,WAAyB,EACzB,KAAmB,EACnB,QAAsB,EACtB,eAA6B,EAC7B,MAAwB,EACxB,aAAgD,EAChD,WAAoC,EACpC,KAA8B,EAC9B,SAAqB,GACtB,GAAE,OAAO,CAAC,OAAO,CAAM;CAezB"}
@@ -1 +1 @@
1
- {"version":3,"file":"note_data_provider.d.ts","sourceRoot":"","sources":["../../../src/storage/note_data_provider/note_data_provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAqC,MAAM,iBAAiB,CAAC;AAC5F,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,qBAAa,gBAAiB,YAAW,YAAY;;IAsBnD,OAAO;WAsBa,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAWlE,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBtD,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,GAAE,YAAgC,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBjF,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB9C,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkD3F,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAgGvD,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IA2DtF,OAAO;CAGd"}
1
+ {"version":3,"file":"note_data_provider.d.ts","sourceRoot":"","sources":["../../../src/storage/note_data_provider/note_data_provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAqC,MAAM,iBAAiB,CAAC;AAC5F,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,qBAAa,gBAAiB,YAAW,YAAY;;IAsBnD,OAAO;WAsBa,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAWlE,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBtD,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,GAAE,YAAgC,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBjF,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB9C,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkD3F,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAkGvD,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IA2DtF,OAAO;CAGd"}
@@ -87,7 +87,7 @@ import { L2BlockStream } from '@aztec/stdlib/block';
87
87
  let currentHeader;
88
88
  try {
89
89
  currentHeader = await this.syncDataProvider.getBlockHeader();
90
- } catch (e) {
90
+ } catch {
91
91
  this.log.debug('Header is not set, requesting from the node');
92
92
  }
93
93
  if (!currentHeader) {
@@ -1 +1 @@
1
- {"version":3,"file":"pxe_test_suite.d.ts","sourceRoot":"","sources":["../../src/test/pxe_test_suite.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iCAAiC,CAAC;AAS3D,eAAO,MAAM,YAAY,aAAc,MAAM,YAAY,MAAM,QAAQ,GAAG,CAAC,SAmG1E,CAAC"}
1
+ {"version":3,"file":"pxe_test_suite.d.ts","sourceRoot":"","sources":["../../src/test/pxe_test_suite.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iCAAiC,CAAC;AAS3D,eAAO,MAAM,YAAY,GAAI,UAAU,MAAM,EAAE,UAAU,MAAM,OAAO,CAAC,GAAG,CAAC,SAmG1E,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/pxe",
3
- "version": "0.86.0",
3
+ "version": "0.87.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./server": "./dest/entrypoints/server/index.js",
@@ -57,19 +57,19 @@
57
57
  ]
58
58
  },
59
59
  "dependencies": {
60
- "@aztec/bb-prover": "0.86.0",
61
- "@aztec/bb.js": "0.86.0",
62
- "@aztec/builder": "0.86.0",
63
- "@aztec/constants": "0.86.0",
64
- "@aztec/ethereum": "0.86.0",
65
- "@aztec/foundation": "0.86.0",
66
- "@aztec/key-store": "0.86.0",
67
- "@aztec/kv-store": "0.86.0",
68
- "@aztec/noir-protocol-circuits-types": "0.86.0",
69
- "@aztec/noir-types": "0.86.0",
70
- "@aztec/protocol-contracts": "0.86.0",
71
- "@aztec/simulator": "0.86.0",
72
- "@aztec/stdlib": "0.86.0",
60
+ "@aztec/bb-prover": "0.87.0",
61
+ "@aztec/bb.js": "0.87.0",
62
+ "@aztec/builder": "0.87.0",
63
+ "@aztec/constants": "0.87.0",
64
+ "@aztec/ethereum": "0.87.0",
65
+ "@aztec/foundation": "0.87.0",
66
+ "@aztec/key-store": "0.87.0",
67
+ "@aztec/kv-store": "0.87.0",
68
+ "@aztec/noir-protocol-circuits-types": "0.87.0",
69
+ "@aztec/noir-types": "0.87.0",
70
+ "@aztec/protocol-contracts": "0.87.0",
71
+ "@aztec/simulator": "0.87.0",
72
+ "@aztec/stdlib": "0.87.0",
73
73
  "koa": "^2.16.1",
74
74
  "koa-router": "^12.0.0",
75
75
  "lodash.omit": "^4.5.0",
@@ -78,17 +78,17 @@
78
78
  "viem": "2.23.7"
79
79
  },
80
80
  "devDependencies": {
81
- "@aztec/noir-contracts.js": "0.86.0",
81
+ "@aztec/noir-test-contracts.js": "0.87.0",
82
82
  "@jest/globals": "^29.5.0",
83
83
  "@types/jest": "^29.5.0",
84
84
  "@types/lodash.omit": "^4.5.7",
85
85
  "@types/lodash.times": "^4.3.9",
86
- "@types/node": "^18.7.23",
86
+ "@types/node": "^22.15.17",
87
87
  "jest": "^29.5.0",
88
88
  "jest-mock-extended": "^3.0.3",
89
89
  "lodash.times": "^4.3.2",
90
90
  "ts-node": "^10.9.1",
91
- "typescript": "^5.0.4"
91
+ "typescript": "^5.3.3"
92
92
  },
93
93
  "files": [
94
94
  "dest",
@@ -97,6 +97,6 @@
97
97
  ],
98
98
  "types": "./dest/index.d.ts",
99
99
  "engines": {
100
- "node": ">=18"
100
+ "node": ">=20.10"
101
101
  }
102
102
  }
@@ -1,3 +1,3 @@
1
1
  export function getPackageInfo() {
2
- return { version: '0.85.0', name: '@aztec/pxe' };
2
+ return { version: '0.86.0', name: '@aztec/pxe' };
3
3
  }
@@ -419,8 +419,8 @@ export class PrivateKernelResetPrivateInputsBuilder {
419
419
  const overflownData = noteHashWillOverflow
420
420
  ? 'note hashes'
421
421
  : nullifierWillOverflow
422
- ? 'nullifiers'
423
- : 'private logs';
422
+ ? 'nullifiers'
423
+ : 'private logs';
424
424
  throw new Error(`Number of ${overflownData} exceeds the limit.`);
425
425
  }
426
426
  // Clearing the read requests might not be enough to squash the overflown data.
@@ -116,14 +116,18 @@ export class PrivateKernelExecutionProver {
116
116
  );
117
117
  while (resetBuilder.needsReset()) {
118
118
  const privateInputs = await resetBuilder.build(this.oracle, noteHashLeafIndexMap);
119
- output = simulate
120
- ? await this.proofCreator.simulateReset(privateInputs)
121
- : await this.proofCreator.generateResetOutput(privateInputs);
119
+ const witgenTimer = new Timer();
120
+ output = generateWitnesses
121
+ ? await this.proofCreator.generateResetOutput(privateInputs)
122
+ : await this.proofCreator.simulateReset(privateInputs);
122
123
  executionSteps.push({
123
124
  functionName: 'private_kernel_reset',
124
125
  bytecode: output.bytecode,
125
126
  witness: output.outputWitness,
126
127
  vk: output.verificationKey.keyAsBytes,
128
+ timings: {
129
+ witgen: witgenTimer.ms(),
130
+ },
127
131
  });
128
132
  resetBuilder = new PrivateKernelResetPrivateInputsBuilder(
129
133
  output,
@@ -148,6 +152,9 @@ export class PrivateKernelExecutionProver {
148
152
  bytecode: currentExecution.acir,
149
153
  witness: currentExecution.partialWitness,
150
154
  vk: currentExecution.vk,
155
+ timings: {
156
+ witgen: currentExecution.profileResult?.timings.witgen ?? 0,
157
+ },
151
158
  });
152
159
 
153
160
  const privateCallData = await this.createPrivateCallData(currentExecution);
@@ -167,6 +174,7 @@ export class PrivateKernelExecutionProver {
167
174
 
168
175
  pushTestData('private-kernel-inputs-init', proofInput);
169
176
 
177
+ const witgenTimer = new Timer();
170
178
  output = generateWitnesses
171
179
  ? await this.proofCreator.generateInitOutput(proofInput)
172
180
  : await this.proofCreator.simulateInit(proofInput);
@@ -176,6 +184,9 @@ export class PrivateKernelExecutionProver {
176
184
  bytecode: output.bytecode,
177
185
  witness: output.outputWitness,
178
186
  vk: output.verificationKey.keyAsBytes,
187
+ timings: {
188
+ witgen: witgenTimer.ms(),
189
+ },
179
190
  });
180
191
  } else {
181
192
  const previousVkMembershipWitness = await this.oracle.getVkMembershipWitness(
@@ -190,7 +201,7 @@ export class PrivateKernelExecutionProver {
190
201
  const proofInput = new PrivateKernelInnerCircuitPrivateInputs(previousKernelData, privateCallData);
191
202
 
192
203
  pushTestData('private-kernel-inputs-inner', proofInput);
193
-
204
+ const witgenTimer = new Timer();
194
205
  output = generateWitnesses
195
206
  ? await this.proofCreator.generateInnerOutput(proofInput)
196
207
  : await this.proofCreator.simulateInner(proofInput);
@@ -200,6 +211,9 @@ export class PrivateKernelExecutionProver {
200
211
  bytecode: output.bytecode,
201
212
  witness: output.outputWitness,
202
213
  vk: output.verificationKey.keyAsBytes,
214
+ timings: {
215
+ witgen: witgenTimer.ms(),
216
+ },
203
217
  });
204
218
  }
205
219
  firstIteration = false;
@@ -214,6 +228,7 @@ export class PrivateKernelExecutionProver {
214
228
  );
215
229
  while (resetBuilder.needsReset()) {
216
230
  const privateInputs = await resetBuilder.build(this.oracle, noteHashLeafIndexMap);
231
+ const witgenTimer = new Timer();
217
232
  output = generateWitnesses
218
233
  ? await this.proofCreator.generateResetOutput(privateInputs)
219
234
  : await this.proofCreator.simulateReset(privateInputs);
@@ -223,6 +238,9 @@ export class PrivateKernelExecutionProver {
223
238
  bytecode: output.bytecode,
224
239
  witness: output.outputWitness,
225
240
  vk: output.verificationKey.keyAsBytes,
241
+ timings: {
242
+ witgen: witgenTimer.ms(),
243
+ },
226
244
  });
227
245
 
228
246
  resetBuilder = new PrivateKernelResetPrivateInputsBuilder(
@@ -256,6 +274,7 @@ export class PrivateKernelExecutionProver {
256
274
 
257
275
  pushTestData('private-kernel-inputs-ordering', privateInputs);
258
276
 
277
+ const witgenTimer = new Timer();
259
278
  const tailOutput = generateWitnesses
260
279
  ? await this.proofCreator.generateTailOutput(privateInputs)
261
280
  : await this.proofCreator.simulateTail(privateInputs);
@@ -265,12 +284,17 @@ export class PrivateKernelExecutionProver {
265
284
  bytecode: tailOutput.bytecode,
266
285
  witness: tailOutput.outputWitness,
267
286
  vk: tailOutput.verificationKey.keyAsBytes,
287
+ timings: {
288
+ witgen: witgenTimer.ms(),
289
+ },
268
290
  });
269
291
 
270
292
  if (profileMode == 'gates' || profileMode == 'full') {
271
293
  for (const entry of executionSteps) {
294
+ const gateCountTimer = new Timer();
272
295
  const gateCount = await this.proofCreator.computeGateCountForCircuit(entry.bytecode, entry.functionName);
273
296
  entry.gateCount = gateCount;
297
+ entry.timings.gateCount = gateCountTimer.ms();
274
298
  }
275
299
  }
276
300
  if (profileMode === 'gates') {
@@ -287,8 +311,11 @@ export class PrivateKernelExecutionProver {
287
311
 
288
312
  let clientIvcProof: ClientIvcProof;
289
313
  // TODO(#7368) how do we 'bincode' encode these inputs?
314
+ let provingTime;
290
315
  if (!skipProofGeneration) {
316
+ const provingTimer = new Timer();
291
317
  clientIvcProof = await this.proofCreator.createClientIvcProof(executionSteps);
318
+ provingTime = provingTimer.ms();
292
319
  } else {
293
320
  clientIvcProof = ClientIvcProof.random();
294
321
  }
@@ -298,6 +325,7 @@ export class PrivateKernelExecutionProver {
298
325
  executionSteps,
299
326
  clientIvcProof,
300
327
  vk: tailOutput.verificationKey.keyAsBytes,
328
+ timings: provingTime ? { proving: provingTime } : undefined,
301
329
  };
302
330
  }
303
331
 
@@ -99,9 +99,8 @@ export class PrivateKernelOracleImpl implements PrivateKernelOracle {
99
99
  }
100
100
 
101
101
  public async getUpdatedClassIdHints(contractAddress: AztecAddress): Promise<UpdatedClassIdHints> {
102
- const { sharedMutableSlot, sharedMutableHashSlot } = await SharedMutableValuesWithHash.getContractUpdateSlots(
103
- contractAddress,
104
- );
102
+ const { sharedMutableSlot, sharedMutableHashSlot } =
103
+ await SharedMutableValuesWithHash.getContractUpdateSlots(contractAddress);
105
104
 
106
105
  const hashLeafSlot = await computePublicDataTreeLeafSlot(
107
106
  ProtocolContractAddress.ContractInstanceDeployer,
@@ -21,6 +21,7 @@ import {
21
21
  IndexedTaggingSecret,
22
22
  LogWithTxData,
23
23
  PendingTaggedLog,
24
+ PublicLog,
24
25
  TxScopedL2Log,
25
26
  deriveEcdhSharedSecret,
26
27
  } from '@aztec/stdlib/logs';
@@ -585,11 +586,11 @@ export class PXEOracleInterface implements ExecutionDataProvider {
585
586
  contractAddress: AztecAddress,
586
587
  capsuleArrayBaseSlot: Fr,
587
588
  recipient: AztecAddress,
588
- logs: TxScopedL2Log[],
589
+ privateLogs: TxScopedL2Log[],
589
590
  ) {
590
591
  // Build all pending tagged logs upfront with their tx effects
591
592
  const pendingTaggedLogs = await Promise.all(
592
- logs.map(async scopedLog => {
593
+ privateLogs.map(async scopedLog => {
593
594
  // TODO(#9789): get these effects along with the log
594
595
  const txEffect = await this.aztecNode.getTxEffect(scopedLog.txHash);
595
596
  if (!txEffect) {
@@ -597,7 +598,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
597
598
  }
598
599
 
599
600
  const pendingTaggedLog = new PendingTaggedLog(
600
- scopedLog.log.toFields(),
601
+ scopedLog.log.fields,
601
602
  scopedLog.txHash,
602
603
  txEffect.data.noteHashes,
603
604
  txEffect.data.nullifiers[0],
@@ -724,12 +725,11 @@ export class PXEOracleInterface implements ExecutionDataProvider {
724
725
  throw new Error(`Unexpected: failed to retrieve tx effects for tx ${scopedLog.txHash} which is known to exist`);
725
726
  }
726
727
 
727
- // Public logs always take up all available fields by padding with zeroes, and the length of the originally emitted
728
- // log is lost. Until this is improved, we simply remove all of the zero elements we find at the end.
729
- // TODO(#11636): use the actual log length.
730
- const trimmedLog = trimTrailingZeros(scopedLog.log.toFields());
728
+ const logContent = (scopedLog.isFromPublic ? [(scopedLog.log as PublicLog).contractAddress.toField()] : []).concat(
729
+ scopedLog.log.getEmittedFields(),
730
+ );
731
731
 
732
- return new LogWithTxData(trimmedLog, scopedLog.txHash, txEffect.data.noteHashes, txEffect.data.nullifiers[0]);
732
+ return new LogWithTxData(logContent, scopedLog.txHash, txEffect.data.noteHashes, txEffect.data.nullifiers[0]);
733
733
  }
734
734
 
735
735
  public async removeNullifiedNotes(contractAddress: AztecAddress) {
@@ -833,15 +833,3 @@ export class PXEOracleInterface implements ExecutionDataProvider {
833
833
  );
834
834
  }
835
835
  }
836
-
837
- // TODO(#11636): remove once we have the actual log length and we don't need to trim it anymore
838
- export function trimTrailingZeros(array: Fr[]): Fr[] {
839
- // Make a copy to avoid modifying the original one
840
- const toReturn = [...array];
841
-
842
- while (toReturn.length > 0 && toReturn[toReturn.length - 1].isZero()) {
843
- toReturn.pop();
844
- }
845
-
846
- return toReturn;
847
- }