@aztec/txe 5.0.0-rc.2 → 5.0.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 (108) hide show
  1. package/dest/AuthRegistry-FSRZIMX6.js +3 -0
  2. package/dest/AuthRegistry-FSRZIMX6.js.map +7 -0
  3. package/dest/ContractClassRegistry-N6NA3SFA.js +3 -0
  4. package/dest/ContractClassRegistry-N6NA3SFA.js.map +7 -0
  5. package/dest/ContractInstanceRegistry-NADDSLGL.js +3 -0
  6. package/dest/ContractInstanceRegistry-NADDSLGL.js.map +7 -0
  7. package/dest/FeeJuice-QBH5JWJV.js +3 -0
  8. package/dest/FeeJuice-QBH5JWJV.js.map +7 -0
  9. package/dest/HandshakeRegistry-KKUEU7XW.js +3 -0
  10. package/dest/HandshakeRegistry-KKUEU7XW.js.map +7 -0
  11. package/dest/MultiCallEntrypoint-TGICA67H.js +3 -0
  12. package/dest/MultiCallEntrypoint-TGICA67H.js.map +7 -0
  13. package/dest/SchnorrAccount-J5T6OKR3.js +3 -0
  14. package/dest/SchnorrAccount-J5T6OKR3.js.map +7 -0
  15. package/dest/SchnorrInitializerlessAccount-OOES6Q4F.js +3 -0
  16. package/dest/SchnorrInitializerlessAccount-OOES6Q4F.js.map +7 -0
  17. package/dest/bin/index.js +1 -1
  18. package/dest/bin/oracle_test_server.js +1 -1
  19. package/dest/{chunk-I6DL4FT2.js → chunk-PDOEF22H.js} +2 -2
  20. package/dest/{chunk-I6DL4FT2.js.map → chunk-PDOEF22H.js.map} +3 -3
  21. package/dest/chunk-YP4ODNMQ.js +268 -0
  22. package/dest/chunk-YP4ODNMQ.js.map +7 -0
  23. package/dest/index.d.ts +1 -1
  24. package/dest/index.d.ts.map +1 -1
  25. package/dest/index.js +5 -3
  26. package/dest/metafile.json +3419 -2900
  27. package/dest/oracle/interfaces.d.ts +11 -7
  28. package/dest/oracle/interfaces.d.ts.map +1 -1
  29. package/dest/oracle/tagging_secret_strategy.d.ts +12 -0
  30. package/dest/oracle/tagging_secret_strategy.d.ts.map +1 -0
  31. package/dest/oracle/tagging_secret_strategy.js +12 -0
  32. package/dest/oracle/test-resolver/default_fixtures.d.ts +3 -3
  33. package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -1
  34. package/dest/oracle/test-resolver/default_fixtures.js +54 -11
  35. package/dest/oracle/test-resolver/resolver.d.ts +1 -1
  36. package/dest/oracle/test-resolver/resolver.js +39 -2
  37. package/dest/oracle/txe_oracle_public_context.d.ts +6 -6
  38. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  39. package/dest/oracle/txe_oracle_public_context.js +15 -9
  40. package/dest/oracle/txe_oracle_registry.d.ts +19 -16
  41. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -1
  42. package/dest/oracle/txe_oracle_registry.js +51 -17
  43. package/dest/oracle/txe_oracle_top_level_context.d.ts +8 -6
  44. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  45. package/dest/oracle/txe_oracle_top_level_context.js +47 -31
  46. package/dest/oracle/txe_oracle_version.d.ts +3 -3
  47. package/dest/oracle/txe_oracle_version.js +3 -3
  48. package/dest/rpc_translator.d.ts +7 -5
  49. package/dest/rpc_translator.d.ts.map +1 -1
  50. package/dest/rpc_translator.js +28 -12
  51. package/dest/server.bundle.js +1 -1
  52. package/dest/state_machine/dummy_p2p_client.d.ts +2 -1
  53. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  54. package/dest/state_machine/dummy_p2p_client.js +3 -0
  55. package/dest/state_machine/index.d.ts +4 -3
  56. package/dest/state_machine/index.d.ts.map +1 -1
  57. package/dest/state_machine/index.js +7 -4
  58. package/dest/state_machine/synchronizer.d.ts +3 -1
  59. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  60. package/dest/state_machine/synchronizer.js +3 -0
  61. package/dest/txe_session.d.ts +2 -2
  62. package/dest/txe_session.d.ts.map +1 -1
  63. package/dest/txe_session.js +28 -14
  64. package/dest/utils/encoding.d.ts +4 -3
  65. package/dest/utils/encoding.d.ts.map +1 -1
  66. package/dest/utils/tx_effect_creation.d.ts +1 -1
  67. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  68. package/dest/utils/tx_effect_creation.js +0 -1
  69. package/dest/utils/txe_public_contract_data_source.d.ts +1 -1
  70. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -1
  71. package/dest/utils/txe_public_contract_data_source.js +7 -4
  72. package/dest/worker.bundle.js +1 -1
  73. package/package.json +17 -17
  74. package/src/bin/oracle_test_server.ts +1 -1
  75. package/src/index.ts +5 -3
  76. package/src/oracle/interfaces.ts +13 -6
  77. package/src/oracle/tagging_secret_strategy.ts +25 -0
  78. package/src/oracle/test-resolver/default_fixtures.ts +73 -17
  79. package/src/oracle/test-resolver/resolver.ts +49 -2
  80. package/src/oracle/txe_oracle_public_context.ts +13 -11
  81. package/src/oracle/txe_oracle_registry.ts +54 -9
  82. package/src/oracle/txe_oracle_top_level_context.ts +82 -31
  83. package/src/oracle/txe_oracle_version.ts +3 -3
  84. package/src/rpc_translator.ts +33 -13
  85. package/src/state_machine/dummy_p2p_client.ts +4 -0
  86. package/src/state_machine/index.ts +19 -2
  87. package/src/state_machine/synchronizer.ts +5 -0
  88. package/src/txe_session.ts +50 -12
  89. package/src/utils/tx_effect_creation.ts +0 -2
  90. package/src/utils/txe_public_contract_data_source.ts +6 -4
  91. package/dest/AuthRegistry-URXCCPYF.js +0 -3
  92. package/dest/AuthRegistry-URXCCPYF.js.map +0 -7
  93. package/dest/ContractClassRegistry-5RDBM6TC.js +0 -3
  94. package/dest/ContractClassRegistry-5RDBM6TC.js.map +0 -7
  95. package/dest/ContractInstanceRegistry-GCR4G4D7.js +0 -3
  96. package/dest/ContractInstanceRegistry-GCR4G4D7.js.map +0 -7
  97. package/dest/FeeJuice-O3KOSZO5.js +0 -3
  98. package/dest/FeeJuice-O3KOSZO5.js.map +0 -7
  99. package/dest/HandshakeRegistry-TXSMHMNY.js +0 -3
  100. package/dest/HandshakeRegistry-TXSMHMNY.js.map +0 -7
  101. package/dest/MultiCallEntrypoint-P4FSRXAD.js +0 -3
  102. package/dest/MultiCallEntrypoint-P4FSRXAD.js.map +0 -7
  103. package/dest/SchnorrAccount-AQZX7ROU.js +0 -3
  104. package/dest/SchnorrAccount-AQZX7ROU.js.map +0 -7
  105. package/dest/SchnorrInitializerlessAccount-KMX2H3J6.js +0 -3
  106. package/dest/SchnorrInitializerlessAccount-KMX2H3J6.js.map +0 -7
  107. package/dest/chunk-IAO54JS2.js +0 -266
  108. package/dest/chunk-IAO54JS2.js.map +0 -7
@@ -12,6 +12,7 @@ import { TestDateProvider } from '@aztec/foundation/timer';
12
12
  import type { KeyStore } from '@aztec/key-store';
13
13
  import {
14
14
  AddressStore,
15
+ AnchoredContractData,
15
16
  CapsuleService,
16
17
  CapsuleStore,
17
18
  type ContractStore,
@@ -70,7 +71,9 @@ import {
70
71
  PrivateToPublicAccumulatedData,
71
72
  PublicCallRequest,
72
73
  } from '@aztec/stdlib/kernel';
73
- import { hashPublicKey } from '@aztec/stdlib/keys';
74
+ import { deriveKeys, hashPublicKey } from '@aztec/stdlib/keys';
75
+ import type { PrivateLog } from '@aztec/stdlib/logs';
76
+ import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
74
77
  import { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
75
78
  import { ChonkProof } from '@aztec/stdlib/proofs';
76
79
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
@@ -97,6 +100,7 @@ import type { TXEAccountStore } from '../utils/txe_account_store.js';
97
100
  import type { TXEArtifactResolver } from '../utils/txe_artifact_resolver.js';
98
101
  import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
99
102
  import type { ITxeExecutionOracle } from './interfaces.js';
103
+ import { type TXETaggingSecretStrategies, makeResolveTaggingSecretStrategyHook } from './tagging_secret_strategy.js';
100
104
 
101
105
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
102
106
  isMisc = true as const;
@@ -121,7 +125,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
121
125
  private version: Fr,
122
126
  private chainId: Fr,
123
127
  private authwits: Map<string, AuthWitness>,
124
- private taggingSecretStrategy: TaggingSecretStrategy | undefined,
128
+ private taggingSecretStrategies: TXETaggingSecretStrategies,
125
129
  private readonly artifactResolver: TXEArtifactResolver,
126
130
  private readonly rootPath: string,
127
131
  private readonly packageName: string,
@@ -183,7 +187,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
183
187
  return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
184
188
  }
185
189
 
186
- async getLastTxEffects() {
190
+ async getLastTxEffects(): Promise<{ txHash: TxHash; noteHashes: Fr[]; nullifiers: Fr[]; privateLogs: PrivateLog[] }> {
187
191
  const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
188
192
  const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
189
193
 
@@ -323,7 +327,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
323
327
  await this.contractStore.addContractInstance(instance);
324
328
  await this.contractStore.addContractArtifact(artifact);
325
329
 
326
- const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
330
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
327
331
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
328
332
  await this.addressStore.addCompleteAddress(completeAddress);
329
333
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -333,7 +337,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
333
337
 
334
338
  async createAccount(secret: Fr) {
335
339
  // This is a foot gun !
336
- const completeAddress = await this.keyStore.addAccount(secret, secret);
340
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), secret);
337
341
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
338
342
  await this.addressStore.addCompleteAddress(completeAddress);
339
343
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -354,8 +358,19 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
354
358
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
355
359
  }
356
360
 
357
- setTaggingSecretStrategy(strategy: Option<TaggingSecretStrategy>): void {
358
- this.taggingSecretStrategy = strategy.value;
361
+ setTaggingSecretStrategies(
362
+ unconstrainedStrategy: Option<TaggingSecretStrategy>,
363
+ constrainedStrategy: Option<TaggingSecretStrategy>,
364
+ ): void {
365
+ const apply = (mode: AppTaggingSecretKind, strategy: Option<TaggingSecretStrategy>) => {
366
+ if (strategy.isSome()) {
367
+ this.taggingSecretStrategies.set(mode, strategy.value);
368
+ } else {
369
+ this.taggingSecretStrategies.delete(mode);
370
+ }
371
+ };
372
+ apply(AppTaggingSecretKind.UNCONSTRAINED, unconstrainedStrategy);
373
+ apply(AppTaggingSecretKind.CONSTRAINED, constrainedStrategy);
359
374
  }
360
375
 
361
376
  async sendL1ToL2Message(content: Fr, secretHash: Fr, sender: EthAddress, recipient: AztecAddress): Promise<Fr> {
@@ -415,11 +430,18 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
415
430
  authorizedUtilityCallTargets: AztecAddress[],
416
431
  gasSettings: GasSettings,
417
432
  ) {
433
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
434
+ const anchoredContractData = new AnchoredContractData(
435
+ this.contractStore,
436
+ this.stateMachine.contractClassService,
437
+ blockHeader,
438
+ );
439
+
418
440
  this.logger.verbose(
419
- `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
441
+ `Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
420
442
  );
421
443
 
422
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
444
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
423
445
  if (!artifact) {
424
446
  const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
425
447
  ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
@@ -434,7 +456,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
434
456
  await this.executeUtilityCall(call, { scopes: execScopes, jobId });
435
457
  };
436
458
 
437
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
438
459
  await this.stateMachine.contractSyncService.ensureContractSynced(
439
460
  targetContractAddress,
440
461
  functionSelector,
@@ -463,10 +484,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
463
484
  const simulator = new WASMSimulator();
464
485
 
465
486
  const transientArrayService = new TransientArrayService();
466
- const taggingSecretStrategy = this.taggingSecretStrategy;
467
487
  const privateExecutionOracle = new PrivateExecutionOracle({
468
488
  argsHash,
469
489
  txContext,
490
+ // The TXE does not run the init kernel's salt binding, so no tx-request salt is in scope.
491
+ txRequestSalt: Fr.ZERO,
470
492
  callContext,
471
493
  anchorBlockHeader: blockHeader,
472
494
  utilityExecutor,
@@ -475,7 +497,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
475
497
  executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
476
498
  noteCache,
477
499
  taggingIndexCache,
478
- contractStore: this.contractStore,
500
+ anchoredContractData,
479
501
  noteStore: this.noteStore,
480
502
  keyStore: this.keyStore,
481
503
  addressStore: this.addressStore,
@@ -502,9 +524,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
502
524
  isStaticCall ? 'private view' : 'private',
503
525
  authorizedUtilityCallTargets,
504
526
  ),
505
- // Only configure the hook when a strategy was explicitly set, so that otherwise the default tagging secret
506
- // strategy is exercised.
507
- resolveTaggingSecretStrategy: taggingSecretStrategy ? () => Promise.resolve(taggingSecretStrategy) : undefined,
527
+ resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies),
508
528
  }),
509
529
  transientArrayService,
510
530
  });
@@ -534,7 +554,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
534
554
  }),
535
555
  );
536
556
 
537
- noteCache.finish();
538
557
  const nonceGenerator = noteCache.getNonceGenerator();
539
558
  result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
540
559
  } catch (err) {
@@ -546,7 +565,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
546
565
  // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
547
566
  const { publicInputs } = await generateSimulatedProvingResult(
548
567
  result,
549
- (addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
568
+ (addr, sel) => anchoredContractData.getDebugFunctionName(addr, sel),
550
569
  this.stateMachine.node,
551
570
  minRevertibleSideEffectCounter,
552
571
  );
@@ -605,7 +624,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
605
624
  } else if (!processedTx.revertCode.isOK()) {
606
625
  if (processedTx.revertReason) {
607
626
  try {
608
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
627
+ await enrichPublicSimulationError(
628
+ processedTx.revertReason,
629
+ this.contractStore,
630
+ this.stateMachine.contractClassService,
631
+ await this.stateMachine.anchorBlockStore.getBlockHeader(),
632
+ this.logger,
633
+ );
609
634
  // eslint-disable-next-line no-empty
610
635
  } catch {}
611
636
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -656,16 +681,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
656
681
  isStaticCall: boolean,
657
682
  gasSettings: GasSettings,
658
683
  ) {
684
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
685
+ const anchoredContractData = new AnchoredContractData(
686
+ this.contractStore,
687
+ this.stateMachine.contractClassService,
688
+ anchorBlockHeader,
689
+ );
690
+
659
691
  this.logger.verbose(
660
- `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
692
+ `Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
661
693
  );
662
694
 
663
695
  const blockNumber = await this.getNextBlockNumber();
664
696
 
665
697
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
666
698
 
667
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
668
-
669
699
  const calldataHash = await computeCalldataHash(calldata);
670
700
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
671
701
 
@@ -758,7 +788,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
758
788
  } else if (!processedTx.revertCode.isOK()) {
759
789
  if (processedTx.revertReason) {
760
790
  try {
761
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
791
+ await enrichPublicSimulationError(
792
+ processedTx.revertReason,
793
+ this.contractStore,
794
+ this.stateMachine.contractClassService,
795
+ anchorBlockHeader,
796
+ this.logger,
797
+ );
762
798
  // eslint-disable-next-line no-empty
763
799
  } catch {}
764
800
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -807,13 +843,19 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
807
843
  jobId: string,
808
844
  authorizedUtilityCallTargets: AztecAddress[],
809
845
  ) {
810
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
846
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
847
+ const anchoredContractData = new AnchoredContractData(
848
+ this.contractStore,
849
+ this.stateMachine.contractClassService,
850
+ blockHeader,
851
+ );
852
+
853
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
811
854
  if (!artifact) {
812
855
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
813
856
  }
814
857
 
815
858
  // Sync notes before executing utility function to discover notes from previous transactions
816
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
817
859
  await this.stateMachine.contractSyncService.ensureContractSynced(
818
860
  targetContractAddress,
819
861
  functionSelector,
@@ -853,7 +895,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
853
895
  authorizedUtilityCallTargets = [],
854
896
  }: { from?: AztecAddress; scopes: AztecAddress[]; jobId: string; authorizedUtilityCallTargets?: AztecAddress[] },
855
897
  ): Promise<Fr[]> {
856
- const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
898
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
899
+ const anchoredContractData = new AnchoredContractData(
900
+ this.contractStore,
901
+ this.stateMachine.contractClassService,
902
+ anchorBlockHeader,
903
+ );
904
+
905
+ const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
906
+ if (!entryPointArtifact) {
907
+ throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
908
+ }
857
909
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
858
910
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
859
911
  }
@@ -864,10 +916,9 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
864
916
  });
865
917
 
866
918
  try {
867
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
868
919
  const simulator = new WASMSimulator();
869
920
  const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
870
- await this.executeUtilityCall(syncCall, { scopes: execScopes, jobId });
921
+ await this.executeUtilityCall(syncCall, { scopes: execScopes, jobId, authorizedUtilityCallTargets });
871
922
  };
872
923
  const oracle = new UtilityExecutionOracle({
873
924
  callContext: CallContext.from({
@@ -879,7 +930,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
879
930
  authWitnesses: [],
880
931
  capsules: [],
881
932
  anchorBlockHeader,
882
- contractStore: this.contractStore,
933
+ anchoredContractData,
883
934
  noteStore: this.noteStore,
884
935
  keyStore: this.keyStore,
885
936
  addressStore: this.addressStore,
@@ -895,10 +946,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
895
946
  jobId,
896
947
  scopes,
897
948
  simulator,
949
+ utilityExecutor,
898
950
  hooks: composeHooks({
899
951
  authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
900
952
  }),
901
- utilityExecutor,
902
953
  // Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
903
954
  transientArrayService: new TransientArrayService(),
904
955
  });
@@ -924,9 +975,9 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
924
975
  }
925
976
  }
926
977
 
927
- close(): [bigint, Map<string, AuthWitness>, TaggingSecretStrategy | undefined] {
978
+ close(): [bigint, Map<string, AuthWitness>, TXETaggingSecretStrategies] {
928
979
  this.logger.debug('Exiting Top Level Context');
929
- return [this.nextBlockTimestamp, this.authwits, this.taggingSecretStrategy];
980
+ return [this.nextBlockTimestamp, this.authwits, this.taggingSecretStrategies];
930
981
  }
931
982
 
932
983
  private async getLastBlockNumber(): Promise<BlockNumber> {
@@ -5,8 +5,8 @@
5
5
  *
6
6
  * The Noir counterparts are in `noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr`.
7
7
  */
8
- export const TXE_ORACLE_VERSION_MAJOR = 2;
9
- export const TXE_ORACLE_VERSION_MINOR = 2;
8
+ export const TXE_ORACLE_VERSION_MAJOR = 3;
9
+ export const TXE_ORACLE_VERSION_MINOR = 0;
10
10
 
11
11
  /**
12
12
  * This hash is computed from the TXE oracle interfaces (IAvmExecutionOracle and ITxeExecutionOracle) and is used to
@@ -14,4 +14,4 @@ export const TXE_ORACLE_VERSION_MINOR = 2;
14
14
  * - TXE_ORACLE_VERSION_MAJOR (and reset MINOR to 0) for breaking changes, or
15
15
  * - TXE_ORACLE_VERSION_MINOR for additive changes (new oracle method added).
16
16
  */
17
- export const TXE_ORACLE_INTERFACE_HASH = '118698345ea9d368ca82ea574a051e72f4df0b85454539ade14838a934976b62';
17
+ export const TXE_ORACLE_INTERFACE_HASH = 'bea75bd85baebd7aa1438efb1defab496d27540bc805a8d854bb74b8d45fd859';
@@ -221,11 +221,12 @@ export class RPCTranslator {
221
221
  }
222
222
 
223
223
  // eslint-disable-next-line camelcase
224
- aztec_txe_setTaggingSecretStrategy(...inputs: ForeignCallArgs) {
224
+ aztec_txe_setTaggingSecretStrategies(...inputs: ForeignCallArgs) {
225
225
  return callTxeHandler({
226
- oracle: 'aztec_txe_setTaggingSecretStrategy',
226
+ oracle: 'aztec_txe_setTaggingSecretStrategies',
227
227
  inputs,
228
- handler: ([strategy]) => this.handlerAsTxe().setTaggingSecretStrategy(strategy),
228
+ handler: ([unconstrainedStrategy, constrainedStrategy]) =>
229
+ this.handlerAsTxe().setTaggingSecretStrategies(unconstrainedStrategy, constrainedStrategy),
229
230
  });
230
231
  }
231
232
 
@@ -488,12 +489,12 @@ export class RPCTranslator {
488
489
  }
489
490
 
490
491
  // eslint-disable-next-line camelcase
491
- aztec_utl_getL1ToL2MembershipWitness(...inputs: ForeignCallArgs) {
492
+ aztec_utl_getL1ToL2MembershipWitnessV2(...inputs: ForeignCallArgs) {
492
493
  return callTxeHandler({
493
- oracle: 'aztec_utl_getL1ToL2MembershipWitness',
494
+ oracle: 'aztec_utl_getL1ToL2MembershipWitnessV2',
494
495
  inputs,
495
- handler: ([contractAddress, messageHash, secret]) =>
496
- this.handlerAsUtility().getL1ToL2MembershipWitness(contractAddress, messageHash, secret),
496
+ handler: ([messageHash, nullifier]) =>
497
+ this.handlerAsUtility().getL1ToL2MembershipWitnessV2(messageHash, nullifier),
497
498
  });
498
499
  }
499
500
 
@@ -571,6 +572,16 @@ export class RPCTranslator {
571
572
  });
572
573
  }
573
574
 
575
+ // eslint-disable-next-line camelcase
576
+ aztec_utl_areBlockHashesInArchive(...inputs: ForeignCallArgs) {
577
+ return callTxeHandler({
578
+ oracle: 'aztec_utl_areBlockHashesInArchive',
579
+ inputs,
580
+ handler: ([anchorBlockHash, blockHashes]) =>
581
+ this.handlerAsUtility().areBlockHashesInArchive(anchorBlockHash, blockHashes),
582
+ });
583
+ }
584
+
574
585
  // eslint-disable-next-line camelcase
575
586
  aztec_utl_getLowNullifierMembershipWitness(...inputs: ForeignCallArgs) {
576
587
  return callTxeHandler({
@@ -582,11 +593,11 @@ export class RPCTranslator {
582
593
  }
583
594
 
584
595
  // eslint-disable-next-line camelcase
585
- aztec_utl_getPendingTaggedLogs(...inputs: ForeignCallArgs) {
596
+ aztec_utl_getPendingTaggedLogsV2(...inputs: ForeignCallArgs) {
586
597
  return callTxeHandler({
587
- oracle: 'aztec_utl_getPendingTaggedLogs',
598
+ oracle: 'aztec_utl_getPendingTaggedLogsV2',
588
599
  inputs,
589
- handler: ([scope, providedSecrets]) => this.handlerAsUtility().getPendingTaggedLogs(scope, providedSecrets),
600
+ handler: ([scope, providedSecrets]) => this.handlerAsUtility().getPendingTaggedLogsV2(scope, providedSecrets),
590
601
  });
591
602
  }
592
603
 
@@ -605,11 +616,11 @@ export class RPCTranslator {
605
616
  }
606
617
 
607
618
  // eslint-disable-next-line camelcase
608
- aztec_utl_getLogsByTag(...inputs: ForeignCallArgs) {
619
+ aztec_utl_getLogsByTagV2(...inputs: ForeignCallArgs) {
609
620
  return callTxeHandler({
610
- oracle: 'aztec_utl_getLogsByTag',
621
+ oracle: 'aztec_utl_getLogsByTagV2',
611
622
  inputs,
612
- handler: ([requestArrayBaseSlot]) => this.handlerAsUtility().getLogsByTag(requestArrayBaseSlot),
623
+ handler: ([requestArrayBaseSlot]) => this.handlerAsUtility().getLogsByTagV2(requestArrayBaseSlot),
613
624
  });
614
625
  }
615
626
 
@@ -1161,6 +1172,15 @@ export class RPCTranslator {
1161
1172
  });
1162
1173
  }
1163
1174
 
1175
+ // eslint-disable-next-line camelcase
1176
+ aztec_prv_resolveCustomRequest(...inputs: ForeignCallArgs) {
1177
+ return callTxeHandler({
1178
+ oracle: 'aztec_prv_resolveCustomRequest',
1179
+ inputs,
1180
+ handler: ([kind, payload]) => this.handlerAsPrivate().resolveCustomRequest(kind, payload),
1181
+ });
1182
+ }
1183
+
1164
1184
  // eslint-disable-next-line camelcase
1165
1185
  aztec_prv_getAppTaggingSecret(...inputs: ForeignCallArgs) {
1166
1186
  return callTxeHandler({
@@ -122,6 +122,10 @@ export class DummyP2P implements P2P {
122
122
  throw new Error('DummyP2P does not implement "getPendingTxCount"');
123
123
  }
124
124
 
125
+ public hasEligiblePendingTxs(_minCount: number): Promise<boolean> {
126
+ throw new Error('DummyP2P does not implement "hasEligiblePendingTxs"');
127
+ }
128
+
125
129
  public start(): Promise<void> {
126
130
  throw new Error('DummyP2P does not implement "start"');
127
131
  }
@@ -3,7 +3,13 @@ import { TestCircuitVerifier } from '@aztec/bb-prover/test';
3
3
  import { CheckpointNumber } from '@aztec/foundation/branded-types';
4
4
  import { Fr } from '@aztec/foundation/curves/bn254';
5
5
  import { createLogger } from '@aztec/foundation/log';
6
- import { type AnchorBlockStore, type ContractStore, ContractSyncService, type NoteStore } from '@aztec/pxe/server';
6
+ import {
7
+ type AnchorBlockStore,
8
+ ContractClassService,
9
+ type ContractStore,
10
+ ContractSyncService,
11
+ type NoteStore,
12
+ } from '@aztec/pxe/server';
7
13
  import { TxResolverService } from '@aztec/pxe/simulator';
8
14
  import { L2Block, type L2TipsProvider } from '@aztec/stdlib/block';
9
15
  import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
@@ -29,6 +35,7 @@ export class TXEStateMachine {
29
35
  public archiver: TXEArchiver,
30
36
  public anchorBlockStore: AnchorBlockStore,
31
37
  public contractSyncService: ContractSyncService,
38
+ public contractClassService: ContractClassService,
32
39
  public txResolver: TxResolverService,
33
40
  ) {}
34
41
 
@@ -68,16 +75,26 @@ export class TXEStateMachine {
68
75
  log,
69
76
  });
70
77
 
78
+ const contractClassService = new ContractClassService(node, contractStore);
71
79
  const contractSyncService = new ContractSyncService(
72
80
  node,
73
81
  contractStore,
82
+ contractClassService,
74
83
  noteStore,
75
84
  createLogger('txe:contract_sync'),
76
85
  );
77
86
 
78
87
  const txResolver = new TxResolverService(node);
79
88
 
80
- return new this(node, synchronizer, archiver, anchorBlockStore, contractSyncService, txResolver);
89
+ return new this(
90
+ node,
91
+ synchronizer,
92
+ archiver,
93
+ anchorBlockStore,
94
+ contractSyncService,
95
+ contractClassService,
96
+ txResolver,
97
+ );
81
98
  }
82
99
 
83
100
  /** Returns an {@link L2TipsProvider} backed by this node's chain tips. */
@@ -58,6 +58,11 @@ export class TXESynchronizer implements WorldStateSynchronizer {
58
58
  return this.nativeWorldStateService.getSnapshot(BlockNumber(blockNumber));
59
59
  }
60
60
 
61
+ /** Gets a snapshot at the given block number. The TXE has no reorgs, so the fork hash is not verified. */
62
+ public getVerifiedSnapshot(blockNumber: number, _blockHash: BlockHash): Promise<MerkleTreeReadOperations> {
63
+ return Promise.resolve(this.getSnapshot(blockNumber));
64
+ }
65
+
61
66
  /** Backups the db to the target path. */
62
67
  public backupTo(dstPath: string, compact?: boolean): Promise<Record<Exclude<SnapshotDataKeys, 'archiver'>, string>> {
63
68
  return this.nativeWorldStateService.backupTo(dstPath, compact);
@@ -7,6 +7,7 @@ import { openEphemeralStore } from '@aztec/kv-store/lmdb-v2';
7
7
  import {
8
8
  AddressStore,
9
9
  AnchorBlockStore,
10
+ AnchoredContractData,
10
11
  CapsuleService,
11
12
  CapsuleStore,
12
13
  ContractStore,
@@ -19,7 +20,6 @@ import {
19
20
  RecipientTaggingStore,
20
21
  SenderTaggingStore,
21
22
  TaggingSecretSourcesStore,
22
- type TaggingSecretStrategy,
23
23
  composeHooks,
24
24
  } from '@aztec/pxe/server';
25
25
  import {
@@ -29,6 +29,7 @@ import {
29
29
  type IMiscOracle,
30
30
  type IPrivateExecutionOracle,
31
31
  type IUtilityExecutionOracle,
32
+ LEGACY_ORACLE_REGISTRY,
32
33
  Option,
33
34
  TransientArrayService,
34
35
  UtilityExecutionOracle,
@@ -56,7 +57,12 @@ import { z } from 'zod';
56
57
 
57
58
  import { DEFAULT_ADDRESS, MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY, MAX_OFFCHAIN_EFFECT_LEN } from './constants.js';
58
59
  import type { IAvmExecutionOracle, ITxeExecutionOracle } from './oracle/interfaces.js';
60
+ import {
61
+ type TXETaggingSecretStrategies,
62
+ makeResolveTaggingSecretStrategyHook,
63
+ } from './oracle/tagging_secret_strategy.js';
59
64
  import { TXEOraclePublicContext } from './oracle/txe_oracle_public_context.js';
65
+ import { callTxeLegacyHandler } from './oracle/txe_oracle_registry.js';
60
66
  import { TXEOracleTopLevelContext } from './oracle/txe_oracle_top_level_context.js';
61
67
  import { TXE_ORACLE_VERSION_MAJOR, TXE_ORACLE_VERSION_MINOR } from './oracle/txe_oracle_version.js';
62
68
  import { TXEPrivateExecutionOracle } from './oracle/txe_private_execution_oracle.js';
@@ -234,7 +240,7 @@ function emptyLastCallState(): LastCallState {
234
240
  export class TXESession implements TXESessionStateHandler {
235
241
  private state: SessionState = { name: 'TOP_LEVEL' };
236
242
  private authwits: Map<string, AuthWitness> = new Map();
237
- private taggingSecretStrategy: TaggingSecretStrategy | undefined = undefined;
243
+ private taggingSecretStrategies: TXETaggingSecretStrategies = new Map();
238
244
  private lastCallInfo: LastCallState = emptyLastCallState();
239
245
  private txeOracleVersion: { major: number; minor: number } | undefined;
240
246
 
@@ -354,7 +360,7 @@ export class TXESession implements TXESessionStateHandler {
354
360
  version,
355
361
  chainId,
356
362
  new Map(),
357
- undefined,
363
+ new Map(),
358
364
  artifactResolver,
359
365
  rootPath,
360
366
  packageName,
@@ -397,6 +403,18 @@ export class TXESession implements TXESessionStateHandler {
397
403
  */
398
404
  processFunction(functionName: TXEOracleFunctionName, inputs: ForeignCallArgs): Promise<ForeignCallResult> {
399
405
  try {
406
+ // Oracles retired into the PXE legacy registry have no translator method; dispatch them through the same
407
+ // buildACIRCallback legacy path that contract execution uses, keeping TXE's two oracle paths in sync.
408
+ // Use an own-property check: `in` would match inherited `Object.prototype` keys (e.g. `constructor`), routing
409
+ // them into the legacy path instead of letting them fall through to the unknown-oracle error.
410
+ if (Object.hasOwn(LEGACY_ORACLE_REGISTRY, functionName)) {
411
+ return callTxeLegacyHandler(
412
+ functionName,
413
+ inputs,
414
+ this.oracleHandler as Parameters<typeof buildACIRCallback>[0],
415
+ );
416
+ }
417
+
400
418
  const translator = new RPCTranslator(this, this.oracleHandler) as any;
401
419
  // We perform a runtime validation to check that the function name corresponds to a real oracle handler.
402
420
  const validatedFunctionName = z
@@ -672,7 +690,7 @@ export class TXESession implements TXESessionStateHandler {
672
690
  this.version,
673
691
  this.chainId,
674
692
  this.authwits,
675
- this.taggingSecretStrategy,
693
+ this.taggingSecretStrategies,
676
694
  this.artifactResolver,
677
695
  this.rootPath,
678
696
  this.packageName,
@@ -717,10 +735,15 @@ export class TXESession implements TXESessionStateHandler {
717
735
 
718
736
  const utilityExecutor = this.utilityExecutorForContractSync(anchorBlock);
719
737
  const transientArrayService = new TransientArrayService();
720
- const taggingSecretStrategy = this.taggingSecretStrategy;
738
+ const anchoredContractData = new AnchoredContractData(
739
+ this.contractStore,
740
+ this.stateMachine.contractClassService,
741
+ anchorBlock!,
742
+ );
721
743
  this.oracleHandler = new TXEPrivateExecutionOracle({
722
744
  argsHash: Fr.ZERO,
723
745
  txContext: new TxContext(this.chainId, this.version, gasSettings),
746
+ txRequestSalt: Fr.ZERO,
724
747
  callContext: new CallContext(AztecAddress.ZERO, contractAddress, FunctionSelector.empty(), false),
725
748
  anchorBlockHeader: anchorBlock!,
726
749
  utilityExecutor,
@@ -729,7 +752,7 @@ export class TXESession implements TXESessionStateHandler {
729
752
  executionCache: new HashedValuesCache(),
730
753
  noteCache,
731
754
  taggingIndexCache,
732
- contractStore: this.contractStore,
755
+ anchoredContractData,
733
756
  noteStore: this.noteStore,
734
757
  keyStore: this.keyStore,
735
758
  addressStore: this.addressStore,
@@ -747,7 +770,7 @@ export class TXESession implements TXESessionStateHandler {
747
770
  txResolver: this.stateMachine.txResolver,
748
771
  simulator: new WASMSimulator(),
749
772
  hooks: composeHooks({
750
- resolveTaggingSecretStrategy: taggingSecretStrategy ? () => Promise.resolve(taggingSecretStrategy) : undefined,
773
+ resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies),
751
774
  }),
752
775
  transientArrayService,
753
776
  });
@@ -827,7 +850,11 @@ export class TXESession implements TXESessionStateHandler {
827
850
  authWitnesses: [],
828
851
  capsules: [],
829
852
  anchorBlockHeader,
830
- contractStore: this.contractStore,
853
+ anchoredContractData: new AnchoredContractData(
854
+ this.contractStore,
855
+ this.stateMachine.contractClassService,
856
+ anchorBlockHeader,
857
+ ),
831
858
  noteStore: this.noteStore,
832
859
  keyStore: this.keyStore,
833
860
  addressStore: this.addressStore,
@@ -866,13 +893,13 @@ export class TXESession implements TXESessionStateHandler {
866
893
  // accounts to PXE (via `addAccount`), etc. This is a slight inconsistency in the working model of this class, but
867
894
  // is not too bad. The `close` call below therefore only hands back the session-scoped values that a test
868
895
  // sets directly at the top level, outside any contract execution (e.g. via `advanceTimestampBy`,
869
- // `addAuthWitness`, `setTaggingSecretStrategy`). The oracle handler is discarded on every state transition,
896
+ // `addAuthWitness`, `setTaggingSecretStrategies`). The oracle handler is discarded on every state transition,
870
897
  // so the session must seed these values into the contexts it creates later.
871
898
 
872
899
  // TODO: persisting authwits this way is quite unfortunate: they create a temporary utility context that would
873
900
  // otherwise reset them, so we'd not be able to pass more than one per execution. Ideally authwits would be passed
874
901
  // alongside a contract call instead of pre-seeded.
875
- [this.nextBlockTimestamp, this.authwits, this.taggingSecretStrategy] = (
902
+ [this.nextBlockTimestamp, this.authwits, this.taggingSecretStrategies] = (
876
903
  this.oracleHandler as TXEOracleTopLevelContext
877
904
  ).close();
878
905
  }
@@ -923,7 +950,18 @@ export class TXESession implements TXESessionStateHandler {
923
950
 
924
951
  private utilityExecutorForContractSync(anchorBlock: any) {
925
952
  return async (call: FunctionCall, scopes: AztecAddress[]) => {
926
- const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
953
+ const anchoredContractData = new AnchoredContractData(
954
+ this.contractStore,
955
+ this.stateMachine.contractClassService,
956
+ anchorBlock!,
957
+ );
958
+ const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(
959
+ call.to,
960
+ call.selector,
961
+ );
962
+ if (!entryPointArtifact) {
963
+ throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
964
+ }
927
965
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
928
966
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
929
967
  }
@@ -940,7 +978,7 @@ export class TXESession implements TXESessionStateHandler {
940
978
  authWitnesses: [],
941
979
  capsules: [],
942
980
  anchorBlockHeader: anchorBlock!,
943
- contractStore: this.contractStore,
981
+ anchoredContractData,
944
982
  noteStore: this.noteStore,
945
983
  keyStore: this.keyStore,
946
984
  addressStore: this.addressStore,
@@ -7,8 +7,6 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
7
7
  export async function makeTxEffect(noteCache: ExecutionNoteCache, txBlockNumber: BlockNumber): Promise<TxEffect> {
8
8
  const txEffect = TxEffect.empty();
9
9
 
10
- noteCache.finish();
11
-
12
10
  const nonceGenerator = noteCache.getNonceGenerator();
13
11
  txEffect.noteHashes = await Promise.all(
14
12
  noteCache