@aztec/txe 0.0.1-commit.2f68f620 → 0.0.1-commit.3100065

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 (131) 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 +2 -2
  19. package/dest/{chunk-W2NSX64C.js → chunk-PDOEF22H.js} +2 -2
  20. package/dest/{chunk-W2NSX64C.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/constants.d.ts +1 -1
  24. package/dest/constants.d.ts.map +1 -1
  25. package/dest/constants.js +1 -1
  26. package/dest/dispatcher_pool.d.ts +2 -2
  27. package/dest/dispatcher_pool.d.ts.map +1 -1
  28. package/dest/dispatcher_pool.js +5 -3
  29. package/dest/index.d.ts +2 -136
  30. package/dest/index.d.ts.map +1 -1
  31. package/dest/index.js +5 -3
  32. package/dest/metafile.json +10346 -7008
  33. package/dest/oracle/interfaces.d.ts +19 -10
  34. package/dest/oracle/interfaces.d.ts.map +1 -1
  35. package/dest/oracle/tagging_secret_strategy.d.ts +12 -0
  36. package/dest/oracle/tagging_secret_strategy.d.ts.map +1 -0
  37. package/dest/oracle/tagging_secret_strategy.js +12 -0
  38. package/dest/oracle/test-resolver/default_fixtures.d.ts +9 -0
  39. package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
  40. package/dest/oracle/test-resolver/default_fixtures.js +207 -0
  41. package/dest/oracle/test-resolver/index.d.ts +1 -1
  42. package/dest/oracle/test-resolver/index.d.ts.map +1 -1
  43. package/dest/oracle/test-resolver/index.js +1 -2
  44. package/dest/oracle/test-resolver/resolver.d.ts +21 -7
  45. package/dest/oracle/test-resolver/resolver.d.ts.map +1 -1
  46. package/dest/oracle/test-resolver/resolver.js +100 -33
  47. package/dest/oracle/txe_oracle_public_context.d.ts +9 -9
  48. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  49. package/dest/oracle/txe_oracle_public_context.js +15 -9
  50. package/dest/oracle/txe_oracle_registry.d.ts +47 -24
  51. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -1
  52. package/dest/oracle/txe_oracle_registry.js +221 -34
  53. package/dest/oracle/txe_oracle_top_level_context.d.ts +16 -8
  54. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  55. package/dest/oracle/txe_oracle_top_level_context.js +116 -54
  56. package/dest/oracle/txe_oracle_version.d.ts +3 -3
  57. package/dest/oracle/txe_oracle_version.js +3 -3
  58. package/dest/rpc_translator.d.ts +21 -4
  59. package/dest/rpc_translator.d.ts.map +1 -1
  60. package/dest/rpc_translator.js +150 -80
  61. package/dest/server.bundle.js +1 -1
  62. package/dest/state_machine/archiver.d.ts +1 -1
  63. package/dest/state_machine/archiver.d.ts.map +1 -1
  64. package/dest/state_machine/archiver.js +1 -2
  65. package/dest/state_machine/dummy_p2p_client.d.ts +5 -2
  66. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  67. package/dest/state_machine/dummy_p2p_client.js +9 -0
  68. package/dest/state_machine/global_variable_builder.d.ts +3 -4
  69. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  70. package/dest/state_machine/global_variable_builder.js +0 -3
  71. package/dest/state_machine/index.d.ts +8 -6
  72. package/dest/state_machine/index.d.ts.map +1 -1
  73. package/dest/state_machine/index.js +41 -19
  74. package/dest/state_machine/synchronizer.d.ts +5 -2
  75. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  76. package/dest/state_machine/synchronizer.js +6 -2
  77. package/dest/txe_session.d.ts +26 -18
  78. package/dest/txe_session.d.ts.map +1 -1
  79. package/dest/txe_session.js +148 -38
  80. package/dest/utils/block_creation.d.ts +2 -2
  81. package/dest/utils/block_creation.d.ts.map +1 -1
  82. package/dest/utils/block_creation.js +2 -2
  83. package/dest/utils/encoding.d.ts +4 -3
  84. package/dest/utils/encoding.d.ts.map +1 -1
  85. package/dest/utils/tx_effect_creation.d.ts +1 -1
  86. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  87. package/dest/utils/tx_effect_creation.js +0 -1
  88. package/dest/utils/txe_public_contract_data_source.d.ts +1 -1
  89. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -1
  90. package/dest/utils/txe_public_contract_data_source.js +7 -4
  91. package/dest/worker.bundle.js +1 -1
  92. package/package.json +17 -17
  93. package/src/bin/oracle_test_server.ts +2 -2
  94. package/src/constants.ts +1 -1
  95. package/src/dispatcher_pool.ts +4 -3
  96. package/src/index.ts +6 -4
  97. package/src/oracle/interfaces.ts +21 -8
  98. package/src/oracle/tagging_secret_strategy.ts +25 -0
  99. package/src/oracle/test-resolver/default_fixtures.ts +282 -0
  100. package/src/oracle/test-resolver/index.ts +1 -2
  101. package/src/oracle/test-resolver/resolver.ts +121 -41
  102. package/src/oracle/txe_oracle_public_context.ts +16 -14
  103. package/src/oracle/txe_oracle_registry.ts +154 -16
  104. package/src/oracle/txe_oracle_top_level_context.ts +157 -55
  105. package/src/oracle/txe_oracle_version.ts +3 -3
  106. package/src/rpc_translator.ts +205 -107
  107. package/src/state_machine/archiver.ts +0 -1
  108. package/src/state_machine/dummy_p2p_client.ts +13 -0
  109. package/src/state_machine/global_variable_builder.ts +2 -16
  110. package/src/state_machine/index.ts +50 -34
  111. package/src/state_machine/synchronizer.ts +8 -2
  112. package/src/txe_session.ts +263 -42
  113. package/src/utils/block_creation.ts +2 -1
  114. package/src/utils/tx_effect_creation.ts +0 -2
  115. package/src/utils/txe_public_contract_data_source.ts +6 -4
  116. package/dest/ContractClassRegistry-PII7Q556.js +0 -3
  117. package/dest/ContractClassRegistry-PII7Q556.js.map +0 -7
  118. package/dest/ContractInstanceRegistry-3MHLGFNZ.js +0 -3
  119. package/dest/ContractInstanceRegistry-3MHLGFNZ.js.map +0 -7
  120. package/dest/FeeJuice-TQV5AQK7.js +0 -3
  121. package/dest/FeeJuice-TQV5AQK7.js.map +0 -7
  122. package/dest/MultiCallEntrypoint-SBJUIJY7.js +0 -3
  123. package/dest/MultiCallEntrypoint-SBJUIJY7.js.map +0 -7
  124. package/dest/SchnorrAccount-MQXPIZ44.js +0 -3
  125. package/dest/SchnorrAccount-MQXPIZ44.js.map +0 -7
  126. package/dest/chunk-CDITIZHX.js +0 -257
  127. package/dest/chunk-CDITIZHX.js.map +0 -7
  128. package/dest/oracle/test-resolver/fixtures.d.ts +0 -43
  129. package/dest/oracle/test-resolver/fixtures.d.ts.map +0 -1
  130. package/dest/oracle/test-resolver/fixtures.js +0 -39
  131. package/src/oracle/test-resolver/fixtures.ts +0 -84
@@ -7,16 +7,20 @@ 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,
14
+ FactService,
15
+ FactStore,
13
16
  JobCoordinator,
14
17
  NoteService,
15
18
  NoteStore,
16
19
  PrivateEventStore,
17
20
  RecipientTaggingStore,
18
- SenderAddressBookStore,
19
21
  SenderTaggingStore,
22
+ TaggingSecretSourcesStore,
23
+ composeHooks,
20
24
  } from '@aztec/pxe/server';
21
25
  import {
22
26
  ExecutionNoteCache,
@@ -25,9 +29,11 @@ import {
25
29
  type IMiscOracle,
26
30
  type IPrivateExecutionOracle,
27
31
  type IUtilityExecutionOracle,
32
+ LEGACY_ORACLE_REGISTRY,
28
33
  Option,
29
- Oracle,
34
+ TransientArrayService,
30
35
  UtilityExecutionOracle,
36
+ buildACIRCallback,
31
37
  } from '@aztec/pxe/simulator';
32
38
  import {
33
39
  ExecutionError,
@@ -38,7 +44,7 @@ import {
38
44
  toACVMWitness,
39
45
  } from '@aztec/simulator/client';
40
46
  import { STANDARD_AUTH_REGISTRY_ADDRESS } from '@aztec/standard-contracts/auth-registry/constants';
41
- import { FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
47
+ import { EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
42
48
  import type { AuthWitness } from '@aztec/stdlib/auth-witness';
43
49
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
44
50
  import type { GasSettings } from '@aztec/stdlib/gas';
@@ -51,11 +57,16 @@ import { z } from 'zod';
51
57
 
52
58
  import { DEFAULT_ADDRESS, MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY, MAX_OFFCHAIN_EFFECT_LEN } from './constants.js';
53
59
  import type { IAvmExecutionOracle, ITxeExecutionOracle } from './oracle/interfaces.js';
60
+ import {
61
+ type TXETaggingSecretStrategies,
62
+ makeResolveTaggingSecretStrategyHook,
63
+ } from './oracle/tagging_secret_strategy.js';
54
64
  import { TXEOraclePublicContext } from './oracle/txe_oracle_public_context.js';
65
+ import { callTxeLegacyHandler } from './oracle/txe_oracle_registry.js';
55
66
  import { TXEOracleTopLevelContext } from './oracle/txe_oracle_top_level_context.js';
56
67
  import { TXE_ORACLE_VERSION_MAJOR, TXE_ORACLE_VERSION_MINOR } from './oracle/txe_oracle_version.js';
57
68
  import { TXEPrivateExecutionOracle } from './oracle/txe_private_execution_oracle.js';
58
- import { RPCTranslator } from './rpc_translator.js';
69
+ import { RPCTranslator, UnavailableOracleError } from './rpc_translator.js';
59
70
  import { TXEArchiver } from './state_machine/archiver.js';
60
71
  import { TXEStateMachine } from './state_machine/index.js';
61
72
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from './utils/block_creation.js';
@@ -127,14 +138,45 @@ export interface TXESessionStateHandler {
127
138
  ): Promise<PrivateContextInputs>;
128
139
  enterUtilityState(contractAddress: Option<AztecAddress>): Promise<void>;
129
140
 
130
- // TODO(F-335): Exposing the job info is abstraction breakage - drop the following 2 functions.
131
- cycleJob(): Promise<string>;
132
- getCurrentJob(): string;
141
+ /**
142
+ * Executes a top-level private call: runs the private function, drains its offchain effects into the session buffer,
143
+ * commits the job, and (for non-static calls) tags the result with the mined tx hash.
144
+ */
145
+ executePrivateCall(
146
+ from: Option<AztecAddress>,
147
+ targetContractAddress: AztecAddress,
148
+ functionSelector: FunctionSelector,
149
+ args: Fr[],
150
+ argsHash: Fr,
151
+ isStaticCall: boolean,
152
+ additionalScopes: AztecAddress[],
153
+ authorizedUtilityCallTargets: AztecAddress[],
154
+ gasSettings: GasSettings,
155
+ ): Promise<Fr[]>;
156
+
157
+ /** Executes a top-level utility function and commits the job. */
158
+ executeUtilityFunction(
159
+ from: Option<AztecAddress>,
160
+ targetContractAddress: AztecAddress,
161
+ functionSelector: FunctionSelector,
162
+ args: Fr[],
163
+ authorizedUtilityCallTargets: AztecAddress[],
164
+ ): Promise<Fr[]>;
133
165
 
134
166
  /**
135
- * Runs an executor-style top-level call (private/public call, utility execution) with last-call tracking.
167
+ * Executes a top-level public call, commits the job, and (for non-static calls) tags the result with the mined tx
168
+ * hash.
136
169
  */
137
- withTopLevelCallTracking<T>(work: () => Promise<{ result: T; txHash?: Fr }>): Promise<T>;
170
+ executePublicCall(
171
+ from: Option<AztecAddress>,
172
+ targetContractAddress: AztecAddress,
173
+ calldata: Fr[],
174
+ isStaticCall: boolean,
175
+ gasSettings: GasSettings,
176
+ ): Promise<Fr[]>;
177
+
178
+ /** Syncs the target contract and returns the private events it emitted matching the given selector and scope. */
179
+ getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress): Promise<Fr[][]>;
138
180
 
139
181
  /**
140
182
  * Captures a raw offchain effect payload for consumption from test environment. Called by the `emit_offchain_effect`
@@ -198,6 +240,7 @@ function emptyLastCallState(): LastCallState {
198
240
  export class TXESession implements TXESessionStateHandler {
199
241
  private state: SessionState = { name: 'TOP_LEVEL' };
200
242
  private authwits: Map<string, AuthWitness> = new Map();
243
+ private taggingSecretStrategies: TXETaggingSecretStrategies = new Map();
201
244
  private lastCallInfo: LastCallState = emptyLastCallState();
202
245
  private txeOracleVersion: { major: number; minor: number } | undefined;
203
246
 
@@ -220,8 +263,9 @@ export class TXESession implements TXESessionStateHandler {
220
263
  private accountStore: TXEAccountStore,
221
264
  private senderTaggingStore: SenderTaggingStore,
222
265
  private recipientTaggingStore: RecipientTaggingStore,
223
- private senderAddressBookStore: SenderAddressBookStore,
266
+ private taggingSecretSourcesStore: TaggingSecretSourcesStore,
224
267
  private capsuleStore: CapsuleStore,
268
+ private factStore: FactStore,
225
269
  private privateEventStore: PrivateEventStore,
226
270
  private jobCoordinator: JobCoordinator,
227
271
  private currentJobId: string,
@@ -271,14 +315,16 @@ export class TXESession implements TXESessionStateHandler {
271
315
  const noteStore = new NoteStore(store);
272
316
  const senderTaggingStore = new SenderTaggingStore(store);
273
317
  const recipientTaggingStore = new RecipientTaggingStore(store);
274
- const senderAddressBookStore = new SenderAddressBookStore(store);
318
+ const taggingSecretSourcesStore = new TaggingSecretSourcesStore(store);
275
319
  const capsuleStore = new CapsuleStore(store);
320
+ const factStore = new FactStore(store);
276
321
  const keyStore = new KeyStore(store);
277
322
  const accountStore = new TXEAccountStore(store);
278
323
 
279
324
  const jobCoordinator = new JobCoordinator(store);
280
325
  jobCoordinator.registerStores([
281
326
  capsuleStore,
327
+ factStore,
282
328
  senderTaggingStore,
283
329
  recipientTaggingStore,
284
330
  privateEventStore,
@@ -306,13 +352,15 @@ export class TXESession implements TXESessionStateHandler {
306
352
  accountStore,
307
353
  senderTaggingStore,
308
354
  recipientTaggingStore,
309
- senderAddressBookStore,
355
+ taggingSecretSourcesStore,
310
356
  capsuleStore,
357
+ factStore,
311
358
  privateEventStore,
312
359
  nextBlockTimestamp,
313
360
  version,
314
361
  chainId,
315
362
  new Map(),
363
+ new Map(),
316
364
  artifactResolver,
317
365
  rootPath,
318
366
  packageName,
@@ -332,8 +380,9 @@ export class TXESession implements TXESessionStateHandler {
332
380
  accountStore,
333
381
  senderTaggingStore,
334
382
  recipientTaggingStore,
335
- senderAddressBookStore,
383
+ taggingSecretSourcesStore,
336
384
  capsuleStore,
385
+ factStore,
337
386
  privateEventStore,
338
387
  jobCoordinator,
339
388
  initialJobId,
@@ -354,6 +403,18 @@ export class TXESession implements TXESessionStateHandler {
354
403
  */
355
404
  processFunction(functionName: TXEOracleFunctionName, inputs: ForeignCallArgs): Promise<ForeignCallResult> {
356
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
+
357
418
  const translator = new RPCTranslator(this, this.oracleHandler) as any;
358
419
  // We perform a runtime validation to check that the function name corresponds to a real oracle handler.
359
420
  const validatedFunctionName = z
@@ -398,12 +459,8 @@ export class TXESession implements TXESessionStateHandler {
398
459
  }
399
460
  }
400
461
 
401
- getCurrentJob(): string {
402
- return this.currentJobId;
403
- }
404
-
405
462
  /** Commits the current job and begins a new one. Returns the new job ID. */
406
- async cycleJob(): Promise<string> {
463
+ private async cycleJob(): Promise<string> {
407
464
  await this.jobCoordinator.commitJob(this.currentJobId);
408
465
  this.currentJobId = this.jobCoordinator.beginJob();
409
466
  return this.currentJobId;
@@ -433,7 +490,7 @@ export class TXESession implements TXESessionStateHandler {
433
490
  this.lastCallInfo.anchorBlockTimestamp = anchorBlockTimestamp;
434
491
  }
435
492
 
436
- async withTopLevelCallTracking<T>(work: () => Promise<{ result: T; txHash?: Fr }>): Promise<T> {
493
+ private async withTopLevelCallTracking<T>(work: () => Promise<{ result: T; txHash?: Fr }>): Promise<T> {
437
494
  this.resetLastCall();
438
495
  // Capture the anchor *before* `work` runs: private/public executor calls mine a new block as a
439
496
  // side effect, and that block's timestamp should not be attributed to this call's anchor.
@@ -463,6 +520,119 @@ export class TXESession implements TXESessionStateHandler {
463
520
  return { txHash, anchorBlockTimestamp };
464
521
  }
465
522
 
523
+ async executePrivateCall(
524
+ from: Option<AztecAddress>,
525
+ targetContractAddress: AztecAddress,
526
+ functionSelector: FunctionSelector,
527
+ args: Fr[],
528
+ argsHash: Fr,
529
+ isStaticCall: boolean,
530
+ additionalScopes: AztecAddress[],
531
+ authorizedUtilityCallTargets: AztecAddress[],
532
+ gasSettings: GasSettings,
533
+ ): Promise<Fr[]> {
534
+ const handler = this.handlerAsTxe();
535
+ return await this.withTopLevelCallTracking(async () => {
536
+ const { returnValues, offchainEffects } = await handler.privateCallNewFlow(
537
+ from?.value,
538
+ targetContractAddress,
539
+ functionSelector,
540
+ args,
541
+ argsHash,
542
+ isStaticCall,
543
+ additionalScopes,
544
+ this.currentJobId,
545
+ authorizedUtilityCallTargets,
546
+ gasSettings,
547
+ );
548
+
549
+ // Private execution collects offchain effects inside PXE's PrivateExecutionOracle rather than round-tripping
550
+ // them through `aztec_utl_emitOffchainEffect`, so the session buffer is empty at this point. Drain the effects
551
+ // from the execution tree into the session buffer so the next `env.offchain_messages()` call in the test sees
552
+ // them.
553
+ for (const data of offchainEffects) {
554
+ this.recordOffchainEffect(data);
555
+ }
556
+
557
+ await this.cycleJob();
558
+
559
+ if (isStaticCall) {
560
+ // Static calls revert their checkpoint and mine no block, so there is no tx hash to tag offchain effects
561
+ // with. Querying `getLastTxEffects()` here would return an unrelated predecessor tx.
562
+ return { result: returnValues };
563
+ }
564
+ const { txHash } = await handler.getLastTxEffects();
565
+ return { result: returnValues, txHash: txHash.hash };
566
+ });
567
+ }
568
+
569
+ async executeUtilityFunction(
570
+ from: Option<AztecAddress>,
571
+ targetContractAddress: AztecAddress,
572
+ functionSelector: FunctionSelector,
573
+ args: Fr[],
574
+ authorizedUtilityCallTargets: AztecAddress[],
575
+ ): Promise<Fr[]> {
576
+ const handler = this.handlerAsTxe();
577
+ return await this.withTopLevelCallTracking(async () => {
578
+ const returnValues = await handler.executeUtilityFunction(
579
+ from?.value,
580
+ targetContractAddress,
581
+ functionSelector,
582
+ args,
583
+ this.currentJobId,
584
+ authorizedUtilityCallTargets,
585
+ );
586
+
587
+ await this.cycleJob();
588
+
589
+ return { result: returnValues };
590
+ });
591
+ }
592
+
593
+ async executePublicCall(
594
+ from: Option<AztecAddress>,
595
+ targetContractAddress: AztecAddress,
596
+ calldata: Fr[],
597
+ isStaticCall: boolean,
598
+ gasSettings: GasSettings,
599
+ ): Promise<Fr[]> {
600
+ const handler = this.handlerAsTxe();
601
+ return await this.withTopLevelCallTracking(async () => {
602
+ const returnValues = await handler.publicCallNewFlow(
603
+ from?.value,
604
+ targetContractAddress,
605
+ calldata,
606
+ isStaticCall,
607
+ gasSettings,
608
+ );
609
+
610
+ await this.cycleJob();
611
+
612
+ if (isStaticCall) {
613
+ // See the equivalent branch in `executePrivateCall`.
614
+ return { result: returnValues };
615
+ }
616
+ const { txHash } = await handler.getLastTxEffects();
617
+ return { result: returnValues, txHash: txHash.hash };
618
+ });
619
+ }
620
+
621
+ async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress): Promise<Fr[][]> {
622
+ const handler = this.handlerAsTxe();
623
+ await handler.syncContractNonOracleMethod(contractAddress, scope, this.currentJobId);
624
+ // Cycle the job to commit the stores after the contract sync.
625
+ await this.cycleJob();
626
+ return handler.getPrivateEvents(selector, contractAddress, scope);
627
+ }
628
+
629
+ private handlerAsTxe(): ITxeExecutionOracle {
630
+ if (!('isTxe' in this.oracleHandler)) {
631
+ throw new UnavailableOracleError('Txe');
632
+ }
633
+ return this.oracleHandler;
634
+ }
635
+
466
636
  setTxeOracleVersion(major: number, minor: number): void {
467
637
  if (major !== TXE_ORACLE_VERSION_MAJOR) {
468
638
  const hint =
@@ -512,13 +682,15 @@ export class TXESession implements TXESessionStateHandler {
512
682
  this.accountStore,
513
683
  this.senderTaggingStore,
514
684
  this.recipientTaggingStore,
515
- this.senderAddressBookStore,
685
+ this.taggingSecretSourcesStore,
516
686
  this.capsuleStore,
687
+ this.factStore,
517
688
  this.privateEventStore,
518
689
  this.nextBlockTimestamp,
519
690
  this.version,
520
691
  this.chainId,
521
692
  this.authwits,
693
+ this.taggingSecretStrategies,
522
694
  this.artifactResolver,
523
695
  this.rootPath,
524
696
  this.packageName,
@@ -562,9 +734,16 @@ export class TXESession implements TXESessionStateHandler {
562
734
  const taggingIndexCache = new ExecutionTaggingIndexCache();
563
735
 
564
736
  const utilityExecutor = this.utilityExecutorForContractSync(anchorBlock);
737
+ const transientArrayService = new TransientArrayService();
738
+ const anchoredContractData = new AnchoredContractData(
739
+ this.contractStore,
740
+ this.stateMachine.contractClassService,
741
+ anchorBlock!,
742
+ );
565
743
  this.oracleHandler = new TXEPrivateExecutionOracle({
566
744
  argsHash: Fr.ZERO,
567
745
  txContext: new TxContext(this.chainId, this.version, gasSettings),
746
+ txRequestSalt: Fr.ZERO,
568
747
  callContext: new CallContext(AztecAddress.ZERO, contractAddress, FunctionSelector.empty(), false),
569
748
  anchorBlockHeader: anchorBlock!,
570
749
  utilityExecutor,
@@ -573,22 +752,27 @@ export class TXESession implements TXESessionStateHandler {
573
752
  executionCache: new HashedValuesCache(),
574
753
  noteCache,
575
754
  taggingIndexCache,
576
- contractStore: this.contractStore,
755
+ anchoredContractData,
577
756
  noteStore: this.noteStore,
578
757
  keyStore: this.keyStore,
579
758
  addressStore: this.addressStore,
580
759
  aztecNode: this.stateMachine.node,
581
760
  senderTaggingStore: this.senderTaggingStore,
582
761
  recipientTaggingStore: this.recipientTaggingStore,
583
- senderAddressBookStore: this.senderAddressBookStore,
762
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
584
763
  capsuleService: new CapsuleService(this.capsuleStore, await this.keyStore.getAccounts()),
764
+ factService: new FactService(this.factStore, await this.keyStore.getAccounts()),
585
765
  privateEventStore: this.privateEventStore,
586
766
  contractSyncService: this.stateMachine.contractSyncService,
587
767
  l2TipsStore: this.stateMachine.l2TipsProvider,
588
768
  jobId: this.currentJobId,
589
769
  scopes: await this.keyStore.getAccounts(),
590
- messageContextService: this.stateMachine.messageContextService,
770
+ txResolver: this.stateMachine.txResolver,
591
771
  simulator: new WASMSimulator(),
772
+ hooks: composeHooks({
773
+ resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies),
774
+ }),
775
+ transientArrayService,
592
776
  });
593
777
 
594
778
  // We store the note and tagging index caches fed into the PrivateExecutionOracle (along with some other auxiliary
@@ -656,26 +840,39 @@ export class TXESession implements TXESessionStateHandler {
656
840
  ).syncNoteNullifiers(contractAddress, await this.keyStore.getAccounts());
657
841
 
658
842
  this.oracleHandler = new UtilityExecutionOracle({
659
- contractAddress,
843
+ callContext: CallContext.from({
844
+ msgSender: AztecAddress.NULL_MSG_SENDER,
845
+ contractAddress,
846
+ // No specific function is being executed in this inlined utility context, hence the empty selector.
847
+ functionSelector: FunctionSelector.empty(),
848
+ isStaticCall: true,
849
+ }),
660
850
  authWitnesses: [],
661
851
  capsules: [],
662
852
  anchorBlockHeader,
663
- contractStore: this.contractStore,
853
+ anchoredContractData: new AnchoredContractData(
854
+ this.contractStore,
855
+ this.stateMachine.contractClassService,
856
+ anchorBlockHeader,
857
+ ),
664
858
  noteStore: this.noteStore,
665
859
  keyStore: this.keyStore,
666
860
  addressStore: this.addressStore,
667
861
  aztecNode: this.stateMachine.node,
668
862
  recipientTaggingStore: this.recipientTaggingStore,
669
- senderAddressBookStore: this.senderAddressBookStore,
863
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
670
864
  capsuleService: new CapsuleService(this.capsuleStore, await this.keyStore.getAccounts()),
865
+ factService: new FactService(this.factStore, await this.keyStore.getAccounts()),
671
866
  privateEventStore: this.privateEventStore,
672
- messageContextService: this.stateMachine.messageContextService,
867
+ txResolver: this.stateMachine.txResolver,
673
868
  contractSyncService: this.stateMachine.contractSyncService,
674
869
  l2TipsStore: this.stateMachine.l2TipsProvider,
675
870
  jobId: this.currentJobId,
676
871
  scopes: await this.keyStore.getAccounts(),
677
872
  simulator: new WASMSimulator(),
678
873
  utilityExecutor: this.utilityExecutorForContractSync(anchorBlockHeader),
874
+ // Execution-tree root (top-level utility run): own store; nested frames inherit it.
875
+ transientArrayService: new TransientArrayService(),
679
876
  });
680
877
 
681
878
  this.state = { name: 'UTILITY' };
@@ -691,15 +888,20 @@ export class TXESession implements TXESessionStateHandler {
691
888
  }
692
889
 
693
890
  // Note that while all public and private contexts do is build a single block that we then process when exiting
694
- // those, the top level context performs a large number of actions not captured in the following 'close' call. Among
695
- // others, it will create empty blocks (via `advanceBlocksBy` and `deploy`), create blocks with transactions via
696
- // `privateCallNewFlow` and `publicCallNewFlow`, add accounts to PXE via `addAccount`, etc. This is a
697
- // slight inconsistency in the working model of this class, but is not too bad.
698
- // TODO: it's quite unfortunate that we need to capture the authwits created to later pass them again when the top
699
- // level context is re-created. This is because authwits create a temporary utility context that'd otherwise reset
700
- // the authwits if not persisted, so we'd not be able to pass more than one per execution.
701
- // Ideally authwits would be passed alongside a contract call instead of pre-seeded.
702
- [this.nextBlockTimestamp, this.authwits] = (this.oracleHandler as TXEOracleTopLevelContext).close();
891
+ // them, the top level context does most of its work as it goes: it creates empty blocks (via `advanceBlocksBy`
892
+ // and `deploy`), creates blocks with transactions (via `privateCallNewFlow` and `publicCallNewFlow`), adds
893
+ // accounts to PXE (via `addAccount`), etc. This is a slight inconsistency in the working model of this class, but
894
+ // is not too bad. The `close` call below therefore only hands back the session-scoped values that a test
895
+ // sets directly at the top level, outside any contract execution (e.g. via `advanceTimestampBy`,
896
+ // `addAuthWitness`, `setTaggingSecretStrategies`). The oracle handler is discarded on every state transition,
897
+ // so the session must seed these values into the contexts it creates later.
898
+
899
+ // TODO: persisting authwits this way is quite unfortunate: they create a temporary utility context that would
900
+ // otherwise reset them, so we'd not be able to pass more than one per execution. Ideally authwits would be passed
901
+ // alongside a contract call instead of pre-seeded.
902
+ [this.nextBlockTimestamp, this.authwits, this.taggingSecretStrategies] = (
903
+ this.oracleHandler as TXEOracleTopLevelContext
904
+ ).close();
703
905
  }
704
906
 
705
907
  private async exitPrivateState() {
@@ -748,7 +950,18 @@ export class TXESession implements TXESessionStateHandler {
748
950
 
749
951
  private utilityExecutorForContractSync(anchorBlock: any) {
750
952
  return async (call: FunctionCall, scopes: AztecAddress[]) => {
751
- 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
+ }
752
965
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
753
966
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
754
967
  }
@@ -756,29 +969,37 @@ export class TXESession implements TXESessionStateHandler {
756
969
  try {
757
970
  const simulator = new WASMSimulator();
758
971
  const oracle = new UtilityExecutionOracle({
759
- contractAddress: call.to,
972
+ callContext: CallContext.from({
973
+ msgSender: AztecAddress.NULL_MSG_SENDER,
974
+ contractAddress: call.to,
975
+ functionSelector: call.selector,
976
+ isStaticCall: true,
977
+ }),
760
978
  authWitnesses: [],
761
979
  capsules: [],
762
980
  anchorBlockHeader: anchorBlock!,
763
- contractStore: this.contractStore,
981
+ anchoredContractData,
764
982
  noteStore: this.noteStore,
765
983
  keyStore: this.keyStore,
766
984
  addressStore: this.addressStore,
767
985
  aztecNode: this.stateMachine.node,
768
986
  recipientTaggingStore: this.recipientTaggingStore,
769
- senderAddressBookStore: this.senderAddressBookStore,
987
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
770
988
  capsuleService: new CapsuleService(this.capsuleStore, scopes),
989
+ factService: new FactService(this.factStore, scopes),
771
990
  privateEventStore: this.privateEventStore,
772
- messageContextService: this.stateMachine.messageContextService,
991
+ txResolver: this.stateMachine.txResolver,
773
992
  contractSyncService: this.stateMachine.contractSyncService,
774
993
  l2TipsStore: this.stateMachine.l2TipsProvider,
775
994
  jobId: this.currentJobId,
776
995
  scopes,
777
996
  simulator,
778
997
  utilityExecutor: this.utilityExecutorForContractSync(anchorBlock),
998
+ // Top-level utility entrypoint: gets a fresh store. Nested frames inherit it via UtilityExecutionOracle.
999
+ transientArrayService: new TransientArrayService(),
779
1000
  });
780
1001
  await simulator
781
- .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
1002
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle))
782
1003
  .catch((err: Error) => {
783
1004
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
784
1005
  throw new ExecutionError(
@@ -23,6 +23,7 @@ export function getSingleTxBlockRequestHash(blockNumber: BlockNumber): Fr {
23
23
  export async function insertTxEffectIntoWorldTrees(
24
24
  txEffect: TxEffect,
25
25
  worldTrees: MerkleTreeWriteOperations,
26
+ l1ToL2Messages: Fr[] = [],
26
27
  ): Promise<void> {
27
28
  await worldTrees.appendLeaves(
28
29
  MerkleTreeId.NOTE_HASH_TREE,
@@ -37,7 +38,7 @@ export async function insertTxEffectIntoWorldTrees(
37
38
 
38
39
  await worldTrees.appendLeaves(
39
40
  MerkleTreeId.L1_TO_L2_MESSAGE_TREE,
40
- padArrayEnd<Fr, number>(txEffect.l2ToL1Msgs, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP),
41
+ padArrayEnd<Fr, number>(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP),
41
42
  );
42
43
 
43
44
  // We do not need to add public data writes because we apply them as we go.
@@ -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
@@ -36,7 +36,8 @@ export class TXEPublicContractDataSource implements ContractDataSource {
36
36
 
37
37
  async getContract(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
38
38
  const instance = await this.contractStore.getContractInstance(address);
39
- return instance && { ...instance, address };
39
+ // TXE has no contract updates, so the current class always equals the original.
40
+ return instance && { ...instance, address, currentContractClassId: instance.originalContractClassId };
40
41
  }
41
42
 
42
43
  getContractClassIds(): Promise<Fr[]> {
@@ -44,12 +45,13 @@ export class TXEPublicContractDataSource implements ContractDataSource {
44
45
  }
45
46
 
46
47
  async getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined> {
47
- const instance = await this.contractStore.getContractInstance(address);
48
- return instance && this.contractStore.getContractArtifact(instance.currentContractClassId);
48
+ const instance = await this.getContract(address);
49
+ return instance && this.contractStore.getContractArtifact(instance.originalContractClassId);
49
50
  }
50
51
 
51
52
  async getDebugFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
52
- return await this.contractStore.getDebugFunctionName(address, selector);
53
+ const instance = await this.getContract(address);
54
+ return instance && this.contractStore.getDebugFunctionName(instance.originalContractClassId, selector);
53
55
  }
54
56
 
55
57
  registerContractFunctionSignatures(_signatures: []): Promise<void> {