@aztec/simulator 0.0.1-commit.c949de6bc → 0.0.1-commit.cbf2c2d5d

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 (38) hide show
  1. package/dest/private/circuit_recording/circuit_recorder.js +2 -2
  2. package/dest/public/contracts_db_checkpoint.d.ts +2 -2
  3. package/dest/public/contracts_db_checkpoint.d.ts.map +1 -1
  4. package/dest/public/contracts_db_checkpoint.js +1 -1
  5. package/dest/public/fixtures/public_tx_simulation_tester.d.ts +6 -5
  6. package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
  7. package/dest/public/fixtures/public_tx_simulation_tester.js +8 -8
  8. package/dest/public/fixtures/utils.d.ts +2 -2
  9. package/dest/public/fixtures/utils.d.ts.map +1 -1
  10. package/dest/public/fixtures/utils.js +2 -2
  11. package/dest/public/hinting_db_sources.d.ts +4 -4
  12. package/dest/public/hinting_db_sources.d.ts.map +1 -1
  13. package/dest/public/hinting_db_sources.js +6 -5
  14. package/dest/public/public_db_sources.d.ts +3 -3
  15. package/dest/public/public_db_sources.d.ts.map +1 -1
  16. package/dest/public/public_db_sources.js +10 -10
  17. package/dest/public/public_processor/guarded_merkle_tree.d.ts +4 -4
  18. package/dest/public/public_processor/guarded_merkle_tree.d.ts.map +1 -1
  19. package/dest/public/public_processor/guarded_merkle_tree.js +4 -4
  20. package/dest/public/public_processor/public_processor.d.ts +2 -2
  21. package/dest/public/public_processor/public_processor.d.ts.map +1 -1
  22. package/dest/public/public_processor/public_processor.js +37 -37
  23. package/dest/public/public_tx_simulator/contract_provider_for_cpp.d.ts +1 -1
  24. package/dest/public/public_tx_simulator/contract_provider_for_cpp.d.ts.map +1 -1
  25. package/dest/public/public_tx_simulator/contract_provider_for_cpp.js +2 -1
  26. package/dest/public/public_tx_simulator/public_tx_simulator.js +2 -2
  27. package/package.json +15 -16
  28. package/src/private/circuit_recording/circuit_recorder.ts +2 -2
  29. package/src/public/avm/opcodes/external_calls.ts +1 -1
  30. package/src/public/contracts_db_checkpoint.ts +1 -1
  31. package/src/public/fixtures/public_tx_simulation_tester.ts +17 -2
  32. package/src/public/fixtures/utils.ts +2 -1
  33. package/src/public/hinting_db_sources.ts +8 -6
  34. package/src/public/public_db_sources.ts +12 -14
  35. package/src/public/public_processor/guarded_merkle_tree.ts +5 -5
  36. package/src/public/public_processor/public_processor.ts +46 -42
  37. package/src/public/public_tx_simulator/contract_provider_for_cpp.ts +2 -1
  38. package/src/public/public_tx_simulator/public_tx_simulator.ts +2 -2
@@ -490,7 +490,7 @@ _dec = trackSpan('PublicProcessor.processTx', (tx)=>({
490
490
  * @param validator - Pre-process validator and nullifier cache to use for processing the txs.
491
491
  * @returns The list of processed txs with their circuit simulation outputs.
492
492
  */ async process(txs, limits = {}, validator = {}) {
493
- const { maxTransactions, maxBlockSize, deadline, maxBlockGas, maxBlobFields } = limits;
493
+ const { maxTransactions, deadline, maxBlockGas, maxBlobFields, isBuildingProposal } = limits;
494
494
  const { preprocessValidator, nullifierCache } = validator;
495
495
  const result = [];
496
496
  const usedTxs = [];
@@ -513,21 +513,23 @@ _dec = trackSpan('PublicProcessor.processTx', (tx)=>({
513
513
  this.log.warn(`Stopping tx processing due to timeout.`);
514
514
  break;
515
515
  }
516
- // Skip this tx if it'd exceed max block size
517
516
  const txHash = tx.getTxHash().toString();
518
- const preTxSizeInBytes = tx.getEstimatedPrivateTxEffectsSize();
519
- if (maxBlockSize !== undefined && totalSizeInBytes + preTxSizeInBytes > maxBlockSize) {
520
- this.log.warn(`Skipping processing of tx ${txHash} sized ${preTxSizeInBytes} bytes due to block size limit`, {
517
+ // Skip this tx if its estimated blob fields would exceed the limit.
518
+ // Only done during proposal building: during re-execution we must process the exact txs from the proposal.
519
+ const txBlobFields = tx.getPrivateTxEffectsSizeInFields();
520
+ if (isBuildingProposal && maxBlobFields !== undefined && totalBlobFields + txBlobFields > maxBlobFields) {
521
+ this.log.warn(`Skipping tx ${txHash} with ${txBlobFields} fields from private side effects due to blob fields limit`, {
521
522
  txHash,
522
- sizeInBytes: preTxSizeInBytes,
523
- totalSizeInBytes,
524
- maxBlockSize
523
+ txBlobFields,
524
+ totalBlobFields,
525
+ maxBlobFields
525
526
  });
526
527
  continue;
527
528
  }
528
- // Skip this tx if its gas limit would exceed the block gas limit
529
+ // Skip this tx if its gas limit would exceed the block gas limit (either da or l2).
530
+ // Only done during proposal building: during re-execution we must process the exact txs from the proposal.
529
531
  const txGasLimit = tx.data.constants.txContext.gasSettings.gasLimits;
530
- if (maxBlockGas !== undefined && totalBlockGas.add(txGasLimit).gtAny(maxBlockGas)) {
532
+ if (isBuildingProposal && maxBlockGas !== undefined && totalBlockGas.add(txGasLimit).gtAny(maxBlockGas)) {
531
533
  this.log.warn(`Skipping processing of tx ${txHash} due to block gas limit`, {
532
534
  txHash,
533
535
  txGasLimit,
@@ -574,21 +576,8 @@ _dec = trackSpan('PublicProcessor.processTx', (tx)=>({
574
576
  throw new Error(`Fake error after processing ${fakeThrowAfter} txs`);
575
577
  }
576
578
  const txBlobFields = processedTx.txEffect.getNumBlobFields();
577
- // If the actual size of this tx would exceed block size, skip it
578
579
  const txSize = txBlobFields * Fr.SIZE_IN_BYTES;
579
- if (maxBlockSize !== undefined && totalSizeInBytes + txSize > maxBlockSize) {
580
- this.log.debug(`Skipping processed tx ${txHash} sized ${txSize} due to max block size.`, {
581
- txHash,
582
- sizeInBytes: txSize,
583
- totalSizeInBytes,
584
- maxBlockSize
585
- });
586
- // Need to revert the checkpoint here and don't go any further
587
- await checkpoint.revert();
588
- this.contractsDB.revertCheckpoint();
589
- continue;
590
- }
591
- // If the actual blob fields of this tx would exceed the limit, skip it
580
+ // If the actual blob fields of this tx would exceed the limit, skip it.
592
581
  // Note: maxBlobFields already accounts for block end blob fields and previous blocks in checkpoint.
593
582
  if (maxBlobFields !== undefined && totalBlobFields + txBlobFields > maxBlobFields) {
594
583
  this.log.debug(`Skipping processed tx ${txHash} with ${txBlobFields} blob fields due to max blob fields limit.`, {
@@ -602,6 +591,20 @@ _dec = trackSpan('PublicProcessor.processTx', (tx)=>({
602
591
  this.contractsDB.revertCheckpoint();
603
592
  continue;
604
593
  }
594
+ // During re-execution, check if the actual gas used by this tx would push the block over the gas limit.
595
+ // Unlike the proposal-building check (which uses declared gas limits pessimistically before processing),
596
+ // this uses actual gas and stops processing when the limit is exceeded.
597
+ if (!isBuildingProposal && maxBlockGas !== undefined && totalBlockGas.add(processedTx.gasUsed.totalGas).gtAny(maxBlockGas)) {
598
+ this.log.warn(`Stopping re-execution since tx ${txHash} would push block gas over limit`, {
599
+ txHash,
600
+ txGas: processedTx.gasUsed.totalGas,
601
+ totalBlockGas,
602
+ maxBlockGas
603
+ });
604
+ await checkpoint.revert();
605
+ this.contractsDB.revertCheckpoint();
606
+ break;
607
+ }
605
608
  // FIXME(fcarreiro): it's ugly to have to notify the validator of nullifiers.
606
609
  // I'd rather pass the validators the processedTx as well and let them deal with it.
607
610
  nullifierCache?.addNullifiers(processedTx.txEffect.nullifiers.map((n)=>n.toBuffer()));
@@ -614,6 +617,8 @@ _dec = trackSpan('PublicProcessor.processTx', (tx)=>({
614
617
  totalBlockGas = totalBlockGas.add(processedTx.gasUsed.totalGas);
615
618
  totalSizeInBytes += txSize;
616
619
  totalBlobFields += txBlobFields;
620
+ // Commit the tx-level contracts checkpoint on success
621
+ this.contractsDB.commitCheckpoint();
617
622
  } catch (err) {
618
623
  if (err?.name === 'PublicProcessorTimeoutError') {
619
624
  this.log.warn(`Stopping tx processing due to timeout.`);
@@ -630,22 +635,19 @@ _dec = trackSpan('PublicProcessor.processTx', (tx)=>({
630
635
  // We now know there can't be any further access to world state. The fork is in a state where there is:
631
636
  // 1. At least one outstanding checkpoint that has not been committed (the one created before we processed the tx).
632
637
  // 2. Possible state updates on that checkpoint or any others created during execution.
633
- // First we revert a checkpoint as managed by the ForkCheckpoint. This will revert whatever is the current checkpoint
634
- // which may not be the one originally created by this object. But that is ok, we do this to fulfil the ForkCheckpoint
635
- // lifecycle expectations and ensure it doesn't attempt to commit later on.
636
- await checkpoint.revert();
637
- // Now we want to revert any/all remaining checkpoints, destroying any outstanding state updates.
638
- // This needs to be done directly on the underlying fork as the guarded fork has been stopped.
639
- await this.guardedMerkleTree.getUnderlyingFork().revertAllCheckpoints();
638
+ // Revert all checkpoints at or above this checkpoint's depth (inclusive), destroying any outstanding state
639
+ // updates from this tx and any nested checkpoints created during execution. This preserves any checkpoints
640
+ // created by callers below our depth.
641
+ await checkpoint.revertToCheckpoint();
640
642
  // Revert any contracts added to the DB for the tx.
641
643
  this.contractsDB.revertCheckpoint();
642
644
  // Ensure we're at the same state as when we started processing this tx.
643
645
  await this.checkWorldStateUnchanged(startStateReference, txHash, err);
644
646
  break;
645
647
  }
646
- // Roll back state to start of TX before proceeding to next TX
647
- await checkpoint.revert();
648
- await this.guardedMerkleTree.getUnderlyingFork().revertAllCheckpoints();
648
+ // Roll back state to start of TX before proceeding to next TX.
649
+ // Reverts all checkpoints at or above this checkpoint's depth, preserving any caller checkpoints below.
650
+ await checkpoint.revertToCheckpoint();
649
651
  this.contractsDB.revertCheckpoint();
650
652
  const errorMessage = err instanceof Error || err instanceof AssertionError ? err.message : 'Unknown error';
651
653
  this.log.warn(`Failed to process tx ${txHash.toString()}: ${errorMessage} ${err?.stack}`);
@@ -659,7 +661,6 @@ _dec = trackSpan('PublicProcessor.processTx', (tx)=>({
659
661
  } finally{
660
662
  // Base case is we always commit the checkpoint. Using the ForkCheckpoint means this has no effect if the tx was previously reverted
661
663
  await checkpoint.commit();
662
- this.contractsDB.commitCheckpointOkIfNone();
663
664
  }
664
665
  }
665
666
  const duration = timer.s();
@@ -677,7 +678,6 @@ _dec = trackSpan('PublicProcessor.processTx', (tx)=>({
677
678
  failed,
678
679
  usedTxs,
679
680
  returns,
680
- totalBlobFields,
681
681
  debugLogs
682
682
  ];
683
683
  }
@@ -788,7 +788,7 @@ _dec = trackSpan('PublicProcessor.processTx', (tx)=>({
788
788
  this.metrics.recordClassPublication(...tx.getContractClassLogs().filter((log)=>ContractClassPublishedEvent.isContractClassPublishedEvent(log)).map((log)=>ContractClassPublishedEvent.fromLog(log)));
789
789
  // Fee payment insertion has already been done. Do the rest.
790
790
  await this.doTreeInsertionsForPrivateOnlyTx(processedTx);
791
- await this.contractsDB.addNewContracts(tx);
791
+ this.contractsDB.addNewContracts(tx);
792
792
  return [
793
793
  processedTx,
794
794
  undefined,
@@ -16,4 +16,4 @@ export declare class ContractProviderForCpp implements ContractProvider {
16
16
  commitCheckpoint: () => Promise<void>;
17
17
  revertCheckpoint: () => Promise<void>;
18
18
  }
19
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3RfcHJvdmlkZXJfZm9yX2NwcC5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3B1YmxpYy9wdWJsaWNfdHhfc2ltdWxhdG9yL2NvbnRyYWN0X3Byb3ZpZGVyX2Zvcl9jcHAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFlLEtBQUssY0FBYyxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBQ3ZGLE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBS3RELE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXhELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFakUscUJBQWEsc0JBQXVCLFlBQVcsZ0JBQWdCO0lBSTNELE9BQU8sQ0FBQyxXQUFXO0lBQ25CLE9BQU8sQ0FBQyxlQUFlO0lBSnpCLE9BQU8sQ0FBQyxHQUFHLENBQVM7SUFFcEIsWUFDVSxXQUFXLEVBQUUsaUJBQWlCLEVBQzlCLGVBQWUsRUFBRSxlQUFlLEVBQ3hDLFFBQVEsQ0FBQyxFQUFFLGNBQWMsRUFHMUI7SUFFTSxtQkFBbUIsb0VBYXhCO0lBRUssZ0JBQWdCLG9FQWVyQjtJQUVLLFlBQVksMkVBV2pCO0lBRUsscUJBQXFCLG9FQWdCMUI7SUFFSyxvQkFBb0IscUVBc0J6QjtJQUVLLGdCQUFnQixzQkFHckI7SUFFSyxnQkFBZ0Isc0JBR3JCO0lBRUssZ0JBQWdCLHNCQUdyQjtDQUNIIn0=
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3RfcHJvdmlkZXJfZm9yX2NwcC5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3B1YmxpYy9wdWJsaWNfdHhfc2ltdWxhdG9yL2NvbnRyYWN0X3Byb3ZpZGVyX2Zvcl9jcHAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFlLEtBQUssY0FBYyxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBQ3ZGLE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBS3RELE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXhELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFakUscUJBQWEsc0JBQXVCLFlBQVcsZ0JBQWdCO0lBSTNELE9BQU8sQ0FBQyxXQUFXO0lBQ25CLE9BQU8sQ0FBQyxlQUFlO0lBSnpCLE9BQU8sQ0FBQyxHQUFHLENBQVM7SUFFcEIsWUFDVSxXQUFXLEVBQUUsaUJBQWlCLEVBQzlCLGVBQWUsRUFBRSxlQUFlLEVBQ3hDLFFBQVEsQ0FBQyxFQUFFLGNBQWMsRUFHMUI7SUFFTSxtQkFBbUIsb0VBYXhCO0lBRUssZ0JBQWdCLG9FQWVyQjtJQUdLLFlBQVksMkVBV2pCO0lBRUsscUJBQXFCLG9FQWdCMUI7SUFFSyxvQkFBb0IscUVBc0J6QjtJQUVLLGdCQUFnQixzQkFHckI7SUFFSyxnQkFBZ0Isc0JBR3JCO0lBRUssZ0JBQWdCLHNCQUdyQjtDQUNIIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"contract_provider_for_cpp.d.ts","sourceRoot":"","sources":["../../../src/public/public_tx_simulator/contract_provider_for_cpp.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,uBAAuB,CAAC;AACvF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAKtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,qBAAa,sBAAuB,YAAW,gBAAgB;IAI3D,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,eAAe;IAJzB,OAAO,CAAC,GAAG,CAAS;IAEpB,YACU,WAAW,EAAE,iBAAiB,EAC9B,eAAe,EAAE,eAAe,EACxC,QAAQ,CAAC,EAAE,cAAc,EAG1B;IAEM,mBAAmB,oEAaxB;IAEK,gBAAgB,oEAerB;IAEK,YAAY,2EAWjB;IAEK,qBAAqB,oEAgB1B;IAEK,oBAAoB,qEAsBzB;IAEK,gBAAgB,sBAGrB;IAEK,gBAAgB,sBAGrB;IAEK,gBAAgB,sBAGrB;CACH"}
1
+ {"version":3,"file":"contract_provider_for_cpp.d.ts","sourceRoot":"","sources":["../../../src/public/public_tx_simulator/contract_provider_for_cpp.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,uBAAuB,CAAC;AACvF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAKtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,qBAAa,sBAAuB,YAAW,gBAAgB;IAI3D,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,eAAe;IAJzB,OAAO,CAAC,GAAG,CAAS;IAEpB,YACU,WAAW,EAAE,iBAAiB,EAC9B,eAAe,EAAE,eAAe,EACxC,QAAQ,CAAC,EAAE,cAAc,EAG1B;IAEM,mBAAmB,oEAaxB;IAEK,gBAAgB,oEAerB;IAGK,YAAY,2EAWjB;IAEK,qBAAqB,oEAgB1B;IAEK,oBAAoB,qEAsBzB;IAEK,gBAAgB,sBAGrB;IAEK,gBAAgB,sBAGrB;IAEK,gBAAgB,sBAGrB;CACH"}
@@ -40,7 +40,7 @@ export class ContractProviderForCpp {
40
40
  const contractDeploymentData = ContractDeploymentData.fromPlainObject(rawData);
41
41
  // Add contracts to the contracts DB
42
42
  this.log.trace(`Calling contractsDB.addContracts`);
43
- await this.contractsDB.addContracts(contractDeploymentData);
43
+ this.contractsDB.addContracts(contractDeploymentData);
44
44
  };
45
45
  this.getBytecodeCommitment = async (classId)=>{
46
46
  this.log.trace(`Contract provider callback: getBytecodeCommitment(${classId})`);
@@ -89,6 +89,7 @@ export class ContractProviderForCpp {
89
89
  }
90
90
  getContractInstance;
91
91
  getContractClass;
92
+ // eslint-disable-next-line require-await
92
93
  addContracts;
93
94
  getBytecodeCommitment;
94
95
  getDebugFunctionName;
@@ -255,7 +255,7 @@ export class PublicTxSimulator {
255
255
  // However, things work as expected because later calls to getters on the hintingContractsDB
256
256
  // will pick up the new contracts and will generate the necessary hints.
257
257
  // So, a consumer of the hints will always see the new contracts.
258
- await this.contractsDB.addContracts(context.nonRevertibleContractDeploymentData);
258
+ this.contractsDB.addContracts(context.nonRevertibleContractDeploymentData);
259
259
  }
260
260
  /**
261
261
  * Insert the revertible accumulated data from private into the public state.
@@ -316,7 +316,7 @@ export class PublicTxSimulator {
316
316
  // However, things work as expected because later calls to getters on the hintingContractsDB
317
317
  // will pick up the new contracts and will generate the necessary hints.
318
318
  // So, a consumer of the hints will always see the new contracts.
319
- await this.contractsDB.addContracts(context.revertibleContractDeploymentData);
319
+ this.contractsDB.addContracts(context.revertibleContractDeploymentData);
320
320
  }
321
321
  async payFee(context) {
322
322
  const txFee = context.getTransactionFee(TxExecutionPhase.TEARDOWN);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/simulator",
3
- "version": "0.0.1-commit.c949de6bc",
3
+ "version": "0.0.1-commit.cbf2c2d5d",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./server": "./dest/server.js",
@@ -64,26 +64,25 @@
64
64
  ]
65
65
  },
66
66
  "dependencies": {
67
- "@aztec/constants": "0.0.1-commit.c949de6bc",
68
- "@aztec/foundation": "0.0.1-commit.c949de6bc",
69
- "@aztec/native": "0.0.1-commit.c949de6bc",
70
- "@aztec/noir-acvm_js": "0.0.1-commit.c949de6bc",
71
- "@aztec/noir-noirc_abi": "0.0.1-commit.c949de6bc",
72
- "@aztec/noir-protocol-circuits-types": "0.0.1-commit.c949de6bc",
73
- "@aztec/noir-types": "0.0.1-commit.c949de6bc",
74
- "@aztec/protocol-contracts": "0.0.1-commit.c949de6bc",
75
- "@aztec/stdlib": "0.0.1-commit.c949de6bc",
76
- "@aztec/telemetry-client": "0.0.1-commit.c949de6bc",
77
- "@aztec/world-state": "0.0.1-commit.c949de6bc",
67
+ "@aztec/constants": "0.0.1-commit.cbf2c2d5d",
68
+ "@aztec/foundation": "0.0.1-commit.cbf2c2d5d",
69
+ "@aztec/native": "0.0.1-commit.cbf2c2d5d",
70
+ "@aztec/noir-acvm_js": "0.0.1-commit.cbf2c2d5d",
71
+ "@aztec/noir-noirc_abi": "0.0.1-commit.cbf2c2d5d",
72
+ "@aztec/noir-protocol-circuits-types": "0.0.1-commit.cbf2c2d5d",
73
+ "@aztec/noir-types": "0.0.1-commit.cbf2c2d5d",
74
+ "@aztec/protocol-contracts": "0.0.1-commit.cbf2c2d5d",
75
+ "@aztec/stdlib": "0.0.1-commit.cbf2c2d5d",
76
+ "@aztec/telemetry-client": "0.0.1-commit.cbf2c2d5d",
77
+ "@aztec/world-state": "0.0.1-commit.cbf2c2d5d",
78
78
  "lodash.clonedeep": "^4.5.0",
79
79
  "lodash.merge": "^4.6.2",
80
80
  "tslib": "^2.4.0"
81
81
  },
82
82
  "devDependencies": {
83
- "@aztec/kv-store": "0.0.1-commit.c949de6bc",
84
- "@aztec/merkle-tree": "0.0.1-commit.c949de6bc",
85
- "@aztec/noir-contracts.js": "0.0.1-commit.c949de6bc",
86
- "@aztec/noir-test-contracts.js": "0.0.1-commit.c949de6bc",
83
+ "@aztec/kv-store": "0.0.1-commit.cbf2c2d5d",
84
+ "@aztec/noir-contracts.js": "0.0.1-commit.cbf2c2d5d",
85
+ "@aztec/noir-test-contracts.js": "0.0.1-commit.cbf2c2d5d",
87
86
  "@jest/globals": "^30.0.0",
88
87
  "@types/jest": "^30.0.0",
89
88
  "@types/lodash.clonedeep": "^4.5.7",
@@ -161,11 +161,11 @@ export class CircuitRecorder {
161
161
  throw new Error(`Oracle method ${name} not found when setting up recording callback`);
162
162
  }
163
163
 
164
- const isExternalCall = (name as keyof ACIRCallback) === 'privateCallPrivateFunction';
164
+ const isExternalCall = (name as keyof ACIRCallback) === 'aztec_prv_callPrivateFunction';
165
165
 
166
166
  recordingCallback[name as keyof ACIRCallback] = (...args: ForeignCallInput[]): ReturnType<typeof fn> => {
167
167
  const timer = new Timer();
168
- // If we're entering another circuit via `privateCallPrivateFunction`, we increase the stack depth and set the
168
+ // If we're entering another circuit via `aztec_prv_callPrivateFunction`, we increase the stack depth and set the
169
169
  // newCircuit variable to ensure we are creating a new recording object.
170
170
  if (isExternalCall) {
171
171
  this.stackDepth++;
@@ -14,8 +14,8 @@ abstract class ExternalCall extends Instruction {
14
14
  OperandType.UINT16, // L2 gas offset
15
15
  OperandType.UINT16, // DA gas offset
16
16
  OperandType.UINT16, // Address offset
17
- OperandType.UINT16, // Args offset
18
17
  OperandType.UINT16, // Args size offset
18
+ OperandType.UINT16, // Args offset
19
19
  ];
20
20
 
21
21
  constructor(
@@ -31,7 +31,7 @@ export class ContractsDbCheckpoint {
31
31
  return this.bytecodeCommitments.get(classId.toString());
32
32
  }
33
33
 
34
- public deepCopy(): ContractsDbCheckpoint {
34
+ public fork(): ContractsDbCheckpoint {
35
35
  const copy = new ContractsDbCheckpoint();
36
36
  this.instances.forEach((value, key) => copy.instances.set(key, value));
37
37
  this.classes.forEach((value, key) => copy.classes.set(key, value));
@@ -117,6 +117,7 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
117
117
  feePayer: AztecAddress = sender,
118
118
  /* need some unique first nullifier for note-nonce computations */
119
119
  privateInsertions: TestPrivateInsertions = { nonRevertible: { nullifiers: [new Fr(420000 + this.txCount)] } },
120
+ gasLimits?: Gas,
120
121
  ): Promise<Tx> {
121
122
  const setupCallRequests = await asyncMap(setupCalls, call =>
122
123
  this.#createPubicCallRequestForCall(call, call.sender ?? sender),
@@ -142,6 +143,7 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
142
143
  )
143
144
  : new Gas(TX_DA_GAS_OVERHEAD, PUBLIC_TX_L2_GAS_OVERHEAD),
144
145
  defaultGlobals(),
146
+ gasLimits,
145
147
  );
146
148
  }
147
149
 
@@ -154,8 +156,9 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
154
156
  /* need some unique first nullifier for note-nonce computations */
155
157
  privateInsertions?: TestPrivateInsertions,
156
158
  txLabel: string = 'unlabeledTx',
159
+ gasLimits?: Gas,
157
160
  ): Promise<PublicTxResult> {
158
- const tx = await this.createTx(sender, setupCalls, appCalls, teardownCall, feePayer, privateInsertions);
161
+ const tx = await this.createTx(sender, setupCalls, appCalls, teardownCall, feePayer, privateInsertions, gasLimits);
159
162
 
160
163
  await this.setFeePayerBalance(feePayer);
161
164
 
@@ -200,8 +203,18 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
200
203
  teardownCall?: TestEnqueuedCall,
201
204
  feePayer?: AztecAddress,
202
205
  privateInsertions?: TestPrivateInsertions,
206
+ gasLimits?: Gas,
203
207
  ): Promise<PublicTxResult> {
204
- return await this.simulateTx(sender, setupCalls, appCalls, teardownCall, feePayer, privateInsertions, txLabel);
208
+ return await this.simulateTx(
209
+ sender,
210
+ setupCalls,
211
+ appCalls,
212
+ teardownCall,
213
+ feePayer,
214
+ privateInsertions,
215
+ txLabel,
216
+ gasLimits,
217
+ );
205
218
  }
206
219
 
207
220
  /**
@@ -219,6 +232,7 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
219
232
  teardownCall?: TestEnqueuedCall,
220
233
  feePayer?: AztecAddress,
221
234
  privateInsertions?: TestPrivateInsertions,
235
+ gasLimits?: Gas,
222
236
  ): Promise<PublicTxResult> {
223
237
  return await this.simulateTxWithLabel(
224
238
  txLabel,
@@ -228,6 +242,7 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
228
242
  teardownCall,
229
243
  feePayer,
230
244
  privateInsertions,
245
+ gasLimits,
231
246
  );
232
247
  }
233
248
 
@@ -62,13 +62,14 @@ export async function createTxForPublicCalls(
62
62
  feePayer = AztecAddress.zero(),
63
63
  gasUsedByPrivate: Gas = Gas.empty(),
64
64
  globals: GlobalVariables = GlobalVariables.empty(),
65
+ gasLimits?: Gas,
65
66
  ): Promise<Tx> {
66
67
  assert(
67
68
  setupCallRequests.length > 0 || appCallRequests.length > 0 || teardownCallRequest !== undefined,
68
69
  "Can't create public tx with no enqueued calls",
69
70
  );
70
71
  // use max limits
71
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
72
+ gasLimits = gasLimits ?? new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
72
73
 
73
74
  const forPublic = PartialPrivateTailPublicInputsForPublic.empty();
74
75
 
@@ -410,12 +410,12 @@ export class HintingMerkleWriteOperations implements MerkleTreeWriteOperations {
410
410
  }
411
411
  }
412
412
 
413
- public async createCheckpoint(): Promise<void> {
413
+ public async createCheckpoint(): Promise<number> {
414
414
  const actionCounter = this.checkpointActionCounter++;
415
415
  const oldCheckpointId = this.getCurrentCheckpointId();
416
416
  const treesStateHash = await this.getTreesStateHash();
417
417
 
418
- await this.db.createCheckpoint();
418
+ const depth = await this.db.createCheckpoint();
419
419
  this.checkpointStack.push(this.nextCheckpointId++);
420
420
  const newCheckpointId = this.getCurrentCheckpointId();
421
421
 
@@ -424,14 +424,16 @@ export class HintingMerkleWriteOperations implements MerkleTreeWriteOperations {
424
424
  HintingMerkleWriteOperations.log.trace(
425
425
  `[createCheckpoint:${actionCounter}] Checkpoint evolved ${oldCheckpointId} -> ${newCheckpointId} at trees state ${treesStateHash}.`,
426
426
  );
427
+
428
+ return depth;
427
429
  }
428
430
 
429
- public commitAllCheckpoints(): Promise<void> {
430
- throw new Error('commitAllCheckpoints is not supported in HintingMerkleWriteOperations.');
431
+ public commitAllCheckpointsTo(_depth: number): Promise<void> {
432
+ throw new Error('commitAllCheckpointsTo is not supported in HintingMerkleWriteOperations.');
431
433
  }
432
434
 
433
- public revertAllCheckpoints(): Promise<void> {
434
- throw new Error('revertAllCheckpoints is not supported in HintingMerkleWriteOperations.');
435
+ public revertAllCheckpointsTo(_depth: number): Promise<void> {
436
+ throw new Error('revertAllCheckpointsTo is not supported in HintingMerkleWriteOperations.');
435
437
  }
436
438
 
437
439
  public async commitCheckpoint(): Promise<void> {
@@ -55,10 +55,10 @@ export class PublicContractsDB implements PublicContractsDBInterface {
55
55
  this.log = createLogger('simulator:contracts-data-source', bindings);
56
56
  }
57
57
 
58
- public async addContracts(contractDeploymentData: ContractDeploymentData): Promise<void> {
58
+ public addContracts(contractDeploymentData: ContractDeploymentData): void {
59
59
  const currentState = this.getCurrentState();
60
60
 
61
- await this.addContractClassesFromEvents(
61
+ this.addContractClassesFromEvents(
62
62
  ContractClassPublishedEvent.extractContractClassEvents(contractDeploymentData.getContractClassLogs()),
63
63
  currentState,
64
64
  );
@@ -69,10 +69,10 @@ export class PublicContractsDB implements PublicContractsDBInterface {
69
69
  );
70
70
  }
71
71
 
72
- public async addNewContracts(tx: Tx): Promise<void> {
72
+ public addNewContracts(tx: Tx): void {
73
73
  const contractDeploymentData = AllContractDeploymentData.fromTx(tx);
74
- await this.addContracts(contractDeploymentData.getNonRevertibleContractDeploymentData());
75
- await this.addContracts(contractDeploymentData.getRevertibleContractDeploymentData());
74
+ this.addContracts(contractDeploymentData.getNonRevertibleContractDeploymentData());
75
+ this.addContracts(contractDeploymentData.getRevertibleContractDeploymentData());
76
76
  }
77
77
 
78
78
  /**
@@ -81,7 +81,7 @@ export class PublicContractsDB implements PublicContractsDBInterface {
81
81
  */
82
82
  public createCheckpoint(): void {
83
83
  const currentState = this.getCurrentState();
84
- const newState = currentState.deepCopy();
84
+ const newState = currentState.fork();
85
85
  this.contractStateStack.push(newState);
86
86
  }
87
87
 
@@ -174,17 +174,15 @@ export class PublicContractsDB implements PublicContractsDBInterface {
174
174
  return await this.dataSource.getDebugFunctionName(address, selector);
175
175
  }
176
176
 
177
- private async addContractClassesFromEvents(
177
+ private addContractClassesFromEvents(
178
178
  contractClassEvents: ContractClassPublishedEvent[],
179
179
  state: ContractsDbCheckpoint,
180
180
  ) {
181
- await Promise.all(
182
- contractClassEvents.map(async (event: ContractClassPublishedEvent) => {
183
- this.log.debug(`Adding class ${event.contractClassId.toString()} to contract state`);
184
- const contractClass = await event.toContractClassPublic();
185
- state.addClass(event.contractClassId, contractClass);
186
- }),
187
- );
181
+ for (const event of contractClassEvents) {
182
+ this.log.debug(`Adding class ${event.contractClassId.toString()} to contract state`);
183
+ const contractClass = event.toContractClassPublic();
184
+ state.addClass(event.contractClassId, contractClass);
185
+ }
188
186
  }
189
187
 
190
188
  private addContractInstancesFromEvents(
@@ -134,7 +134,7 @@ export class GuardedMerkleTreeOperations implements MerkleTreeWriteOperations {
134
134
  ): Promise<(BlockNumber | undefined)[]> {
135
135
  return this.guardAndPush(() => this.target.getBlockNumbersForLeafIndices(treeId, leafIndices));
136
136
  }
137
- createCheckpoint(): Promise<void> {
137
+ createCheckpoint(): Promise<number> {
138
138
  return this.guardAndPush(() => this.target.createCheckpoint());
139
139
  }
140
140
  commitCheckpoint(): Promise<void> {
@@ -143,11 +143,11 @@ export class GuardedMerkleTreeOperations implements MerkleTreeWriteOperations {
143
143
  revertCheckpoint(): Promise<void> {
144
144
  return this.guardAndPush(() => this.target.revertCheckpoint());
145
145
  }
146
- commitAllCheckpoints(): Promise<void> {
147
- return this.guardAndPush(() => this.target.commitAllCheckpoints());
146
+ commitAllCheckpointsTo(depth: number): Promise<void> {
147
+ return this.guardAndPush(() => this.target.commitAllCheckpointsTo(depth));
148
148
  }
149
- revertAllCheckpoints(): Promise<void> {
150
- return this.guardAndPush(() => this.target.revertAllCheckpoints());
149
+ revertAllCheckpointsTo(depth: number): Promise<void> {
150
+ return this.guardAndPush(() => this.target.revertAllCheckpointsTo(depth));
151
151
  }
152
152
  findSiblingPaths<ID extends MerkleTreeId>(
153
153
  treeId: ID,