@aztec/txe 0.0.1-commit.3469e52 → 0.0.1-commit.35158ae7e

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 (58) hide show
  1. package/dest/index.d.ts +1 -1
  2. package/dest/index.d.ts.map +1 -1
  3. package/dest/index.js +88 -54
  4. package/dest/oracle/interfaces.d.ts +29 -28
  5. package/dest/oracle/interfaces.d.ts.map +1 -1
  6. package/dest/oracle/txe_oracle_public_context.d.ts +15 -15
  7. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  8. package/dest/oracle/txe_oracle_public_context.js +16 -16
  9. package/dest/oracle/txe_oracle_top_level_context.d.ts +23 -23
  10. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  11. package/dest/oracle/txe_oracle_top_level_context.js +130 -54
  12. package/dest/rpc_translator.d.ts +92 -81
  13. package/dest/rpc_translator.d.ts.map +1 -1
  14. package/dest/rpc_translator.js +315 -169
  15. package/dest/state_machine/archiver.d.ts +4 -4
  16. package/dest/state_machine/archiver.d.ts.map +1 -1
  17. package/dest/state_machine/archiver.js +8 -9
  18. package/dest/state_machine/dummy_p2p_client.d.ts +16 -12
  19. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  20. package/dest/state_machine/dummy_p2p_client.js +28 -16
  21. package/dest/state_machine/index.d.ts +9 -7
  22. package/dest/state_machine/index.d.ts.map +1 -1
  23. package/dest/state_machine/index.js +35 -17
  24. package/dest/state_machine/mock_epoch_cache.d.ts +22 -4
  25. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  26. package/dest/state_machine/mock_epoch_cache.js +38 -3
  27. package/dest/state_machine/synchronizer.d.ts +6 -6
  28. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  29. package/dest/state_machine/synchronizer.js +3 -3
  30. package/dest/txe_session.d.ts +10 -6
  31. package/dest/txe_session.d.ts.map +1 -1
  32. package/dest/txe_session.js +97 -28
  33. package/dest/util/encoding.d.ts +69 -1
  34. package/dest/util/encoding.d.ts.map +1 -1
  35. package/dest/util/txe_public_contract_data_source.d.ts +2 -3
  36. package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
  37. package/dest/util/txe_public_contract_data_source.js +6 -25
  38. package/dest/utils/block_creation.d.ts +5 -5
  39. package/dest/utils/block_creation.d.ts.map +1 -1
  40. package/dest/utils/block_creation.js +7 -5
  41. package/package.json +15 -15
  42. package/src/index.ts +89 -52
  43. package/src/oracle/interfaces.ts +32 -31
  44. package/src/oracle/txe_oracle_public_context.ts +18 -20
  45. package/src/oracle/txe_oracle_top_level_context.ts +160 -102
  46. package/src/rpc_translator.ts +349 -185
  47. package/src/state_machine/archiver.ts +9 -11
  48. package/src/state_machine/dummy_p2p_client.ts +40 -22
  49. package/src/state_machine/index.ts +54 -19
  50. package/src/state_machine/mock_epoch_cache.ts +49 -4
  51. package/src/state_machine/synchronizer.ts +5 -5
  52. package/src/txe_session.ts +115 -86
  53. package/src/util/txe_public_contract_data_source.ts +10 -38
  54. package/src/utils/block_creation.ts +8 -6
  55. package/dest/util/txe_contract_store.d.ts +0 -12
  56. package/dest/util/txe_contract_store.d.ts.map +0 -1
  57. package/dest/util/txe_contract_store.js +0 -22
  58. package/src/util/txe_contract_store.ts +0 -36
@@ -12,9 +12,12 @@ import { Fr } from '@aztec/foundation/curves/bn254';
12
12
  import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@aztec/foundation/log';
13
13
  import { TestDateProvider } from '@aztec/foundation/timer';
14
14
  import type { KeyStore } from '@aztec/key-store';
15
+ import type { AccessScopes } from '@aztec/pxe/client/lazy';
15
16
  import {
16
17
  AddressStore,
17
18
  CapsuleStore,
19
+ type ContractStore,
20
+ type ContractSyncService,
18
21
  NoteStore,
19
22
  ORACLE_VERSION,
20
23
  PrivateEventStore,
@@ -83,7 +86,6 @@ import { ForkCheckpoint } from '@aztec/world-state';
83
86
  import { DEFAULT_ADDRESS } from '../constants.js';
84
87
  import type { TXEStateMachine } from '../state_machine/index.js';
85
88
  import type { TXEAccountStore } from '../util/txe_account_store.js';
86
- import type { TXEContractStore } from '../util/txe_contract_store.js';
87
89
  import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
88
90
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
89
91
  import type { ITxeExecutionOracle } from './interfaces.js';
@@ -96,7 +98,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
96
98
 
97
99
  constructor(
98
100
  private stateMachine: TXEStateMachine,
99
- private contractStore: TXEContractStore,
101
+ private contractStore: ContractStore,
100
102
  private noteStore: NoteStore,
101
103
  private keyStore: KeyStore,
102
104
  private addressStore: AddressStore,
@@ -106,17 +108,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
106
108
  private senderAddressBookStore: SenderAddressBookStore,
107
109
  private capsuleStore: CapsuleStore,
108
110
  private privateEventStore: PrivateEventStore,
109
- private jobId: string,
110
111
  private nextBlockTimestamp: bigint,
111
112
  private version: Fr,
112
113
  private chainId: Fr,
113
114
  private authwits: Map<string, AuthWitness>,
115
+ private readonly contractSyncService: ContractSyncService,
114
116
  ) {
115
117
  this.logger = createLogger('txe:top_level_context');
116
118
  this.logger.debug('Entering Top Level Context');
117
119
  }
118
120
 
119
- utilityAssertCompatibleOracleVersion(version: number): void {
121
+ assertCompatibleOracleVersion(version: number): void {
120
122
  if (version !== ORACLE_VERSION) {
121
123
  throw new Error(
122
124
  `Incompatible oracle version. TXE is using version '${ORACLE_VERSION}', but got a request for '${version}'.`,
@@ -126,37 +128,38 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
126
128
 
127
129
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
128
130
  // setup.
129
- utilityGetRandomField(): Fr {
131
+ getRandomField(): Fr {
130
132
  return Fr.random();
131
133
  }
132
134
 
133
135
  // We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
134
- utilityDebugLog(level: number, message: string, fields: Fr[]): void {
136
+ log(level: number, message: string, fields: Fr[]): Promise<void> {
135
137
  if (!LogLevels[level]) {
136
- throw new Error(`Invalid debug log level: ${level}`);
138
+ throw new Error(`Invalid log level: ${level}`);
137
139
  }
138
140
  const levelName = LogLevels[level];
139
141
 
140
142
  this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
143
+ return Promise.resolve();
141
144
  }
142
145
 
143
- txeGetDefaultAddress(): AztecAddress {
146
+ getDefaultAddress(): AztecAddress {
144
147
  return DEFAULT_ADDRESS;
145
148
  }
146
149
 
147
- async txeGetNextBlockNumber(): Promise<BlockNumber> {
150
+ async getNextBlockNumber(): Promise<BlockNumber> {
148
151
  return BlockNumber((await this.getLastBlockNumber()) + 1);
149
152
  }
150
153
 
151
- txeGetNextBlockTimestamp(): Promise<bigint> {
154
+ getNextBlockTimestamp(): Promise<bigint> {
152
155
  return Promise.resolve(this.nextBlockTimestamp);
153
156
  }
154
157
 
155
- async txeGetLastBlockTimestamp() {
158
+ async getLastBlockTimestamp() {
156
159
  return (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.timestamp;
157
160
  }
158
161
 
159
- async txeGetLastTxEffects() {
162
+ async getLastTxEffects() {
160
163
  const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
161
164
  const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
162
165
 
@@ -170,7 +173,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
170
173
  return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
171
174
  }
172
175
 
173
- async txeGetPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
176
+ async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
177
+ if (contractAddress.equals(DEFAULT_ADDRESS)) {
178
+ this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
179
+ return;
180
+ }
181
+
182
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
183
+ await this.stateMachine.contractSyncService.ensureContractSynced(
184
+ contractAddress,
185
+ null,
186
+ async (call, execScopes) => {
187
+ await this.executeUtilityCall(call, execScopes, jobId);
188
+ },
189
+ blockHeader,
190
+ jobId,
191
+ [scope],
192
+ );
193
+ }
194
+
195
+ async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
174
196
  return (
175
197
  await this.privateEventStore.getPrivateEvents(selector, {
176
198
  contractAddress,
@@ -181,7 +203,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
181
203
  ).map(e => e.packedEvent);
182
204
  }
183
205
 
184
- async txeAdvanceBlocksBy(blocks: number) {
206
+ async advanceBlocksBy(blocks: number) {
185
207
  this.logger.debug(`time traveling ${blocks} blocks`);
186
208
 
187
209
  for (let i = 0; i < blocks; i++) {
@@ -189,12 +211,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
189
211
  }
190
212
  }
191
213
 
192
- txeAdvanceTimestampBy(duration: UInt64) {
214
+ advanceTimestampBy(duration: UInt64) {
193
215
  this.logger.debug(`time traveling ${duration} seconds`);
194
216
  this.nextBlockTimestamp += duration;
195
217
  }
196
218
 
197
- async txeDeploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
219
+ async deploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
198
220
  // Emit deployment nullifier
199
221
  await this.mineBlock({
200
222
  nullifiers: [
@@ -206,20 +228,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
206
228
  });
207
229
 
208
230
  if (!secret.equals(Fr.ZERO)) {
209
- await this.txeAddAccount(artifact, instance, secret);
231
+ await this.addAccount(artifact, instance, secret);
210
232
  } else {
211
233
  await this.contractStore.addContractInstance(instance);
212
- await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
234
+ await this.contractStore.addContractArtifact(artifact);
213
235
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
214
236
  }
215
237
  }
216
238
 
217
- async txeAddAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
239
+ async addAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
218
240
  const partialAddress = await computePartialAddress(instance);
219
241
 
220
242
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
221
243
  await this.contractStore.addContractInstance(instance);
222
- await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
244
+ await this.contractStore.addContractArtifact(artifact);
223
245
 
224
246
  const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
225
247
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
@@ -229,7 +251,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
229
251
  return completeAddress;
230
252
  }
231
253
 
232
- async txeCreateAccount(secret: Fr) {
254
+ async createAccount(secret: Fr) {
233
255
  // This is a foot gun !
234
256
  const completeAddress = await this.keyStore.addAccount(secret, secret);
235
257
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
@@ -239,7 +261,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
239
261
  return completeAddress;
240
262
  }
241
263
 
242
- async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
264
+ async addAuthWitness(address: AztecAddress, messageHash: Fr) {
243
265
  const account = await this.accountStore.getAccount(address);
244
266
  const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
245
267
 
@@ -252,7 +274,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
252
274
  }
253
275
 
254
276
  async mineBlock(options: { nullifiers?: Fr[] } = {}) {
255
- const blockNumber = await this.txeGetNextBlockNumber();
277
+ const blockNumber = await this.getNextBlockNumber();
256
278
 
257
279
  const txEffect = TxEffect.empty();
258
280
  txEffect.nullifiers = [getSingleTxBlockRequestHash(blockNumber), ...(options.nullifiers ?? [])];
@@ -276,13 +298,14 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
276
298
  await this.stateMachine.handleL2Block(block);
277
299
  }
278
300
 
279
- async txePrivateCallNewFlow(
301
+ async privateCallNewFlow(
280
302
  from: AztecAddress,
281
303
  targetContractAddress: AztecAddress = AztecAddress.zero(),
282
304
  functionSelector: FunctionSelector = FunctionSelector.empty(),
283
305
  args: Fr[],
284
306
  argsHash: Fr = Fr.zero(),
285
307
  isStaticCall: boolean = false,
308
+ jobId: string,
286
309
  ) {
287
310
  this.logger.verbose(
288
311
  `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
@@ -296,14 +319,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
296
319
  throw new Error(message);
297
320
  }
298
321
 
322
+ // When `from` is the zero address (e.g. when deploying a new account contract), we return an
323
+ // empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
324
+ const effectiveScopes = from.isZero() ? [] : [from];
325
+
299
326
  // Sync notes before executing private function to discover notes from previous transactions
300
- const utilityExecutor = async (call: FunctionCall) => {
301
- await this.executeUtilityCall(call);
327
+ const utilityExecutor = async (call: FunctionCall, execScopes: AccessScopes) => {
328
+ await this.executeUtilityCall(call, execScopes, jobId);
302
329
  };
303
330
 
304
- await this.contractStore.syncPrivateState(targetContractAddress, functionSelector, utilityExecutor);
331
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
332
+ await this.stateMachine.contractSyncService.ensureContractSynced(
333
+ targetContractAddress,
334
+ functionSelector,
335
+ utilityExecutor,
336
+ blockHeader,
337
+ jobId,
338
+ effectiveScopes,
339
+ );
305
340
 
306
- const blockNumber = await this.txeGetNextBlockNumber();
341
+ const blockNumber = await this.getNextBlockNumber();
307
342
 
308
343
  const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
309
344
 
@@ -313,8 +348,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
313
348
 
314
349
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
315
350
 
316
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
317
-
318
351
  const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
319
352
  const noteCache = new ExecutionNoteCache(protocolNullifier);
320
353
  // In production, the account contract sets the min revertible counter before calling the app function.
@@ -326,43 +359,38 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
326
359
 
327
360
  const simulator = new WASMSimulator();
328
361
 
329
- const privateExecutionOracle = new PrivateExecutionOracle(
362
+ const privateExecutionOracle = new PrivateExecutionOracle({
330
363
  argsHash,
331
364
  txContext,
332
365
  callContext,
333
- /** Header of a block whose state is used during private execution (not the block the transaction is included in). */
334
- blockHeader,
366
+ anchorBlockHeader: blockHeader,
335
367
  utilityExecutor,
336
- /** List of transient auth witnesses to be used during this simulation */
337
- Array.from(this.authwits.values()),
338
- /** List of transient auth witnesses to be used during this simulation */
339
- [],
340
- HashedValuesCache.create([new HashedValues(args, argsHash)]),
368
+ authWitnesses: Array.from(this.authwits.values()),
369
+ capsules: [],
370
+ executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
341
371
  noteCache,
342
372
  taggingIndexCache,
343
- this.contractStore,
344
- this.noteStore,
345
- this.keyStore,
346
- this.addressStore,
347
- this.stateMachine.node,
348
- this.stateMachine.anchorBlockStore,
349
- this.senderTaggingStore,
350
- this.recipientTaggingStore,
351
- this.senderAddressBookStore,
352
- this.capsuleStore,
353
- this.privateEventStore,
354
- this.jobId,
355
- 0, // totalPublicArgsCount
356
- minRevertibleSideEffectCounter, // (start) sideEffectCounter
357
- undefined, // log
358
- undefined, // scopes
359
- /**
360
- * In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
361
- * contract would perform, including setting senderForTags.
362
- */
363
- from,
373
+ contractStore: this.contractStore,
374
+ noteStore: this.noteStore,
375
+ keyStore: this.keyStore,
376
+ addressStore: this.addressStore,
377
+ aztecNode: this.stateMachine.node,
378
+ senderTaggingStore: this.senderTaggingStore,
379
+ recipientTaggingStore: this.recipientTaggingStore,
380
+ senderAddressBookStore: this.senderAddressBookStore,
381
+ capsuleStore: this.capsuleStore,
382
+ privateEventStore: this.privateEventStore,
383
+ contractSyncService: this.stateMachine.contractSyncService,
384
+ jobId,
385
+ totalPublicCalldataCount: 0,
386
+ sideEffectCounter: minRevertibleSideEffectCounter,
387
+ scopes: effectiveScopes,
388
+ // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
389
+ // contract would perform, including setting senderForTags.
390
+ senderForTags: from,
364
391
  simulator,
365
- );
392
+ messageContextService: this.stateMachine.messageContextService,
393
+ });
366
394
 
367
395
  // Note: This is a slight modification of simulator.run without any of the checks. Maybe we should modify simulator.run with a boolean value to skip checks.
368
396
  let result: PrivateExecutionResult;
@@ -384,7 +412,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
384
412
  );
385
413
  const publicFunctionsCalldata = await Promise.all(
386
414
  publicCallRequests.map(async r => {
387
- const calldata = await privateExecutionOracle.privateLoadFromExecutionCache(r.calldataHash);
415
+ const calldata = await privateExecutionOracle.loadFromExecutionCache(r.calldataHash);
388
416
  return new HashedValues(calldata, r.calldataHash);
389
417
  }),
390
418
  );
@@ -401,7 +429,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
401
429
  // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
402
430
  const { publicInputs } = await generateSimulatedProvingResult(
403
431
  result,
404
- this.contractStore,
432
+ (addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
433
+ this.stateMachine.node,
405
434
  minRevertibleSideEffectCounter,
406
435
  );
407
436
 
@@ -414,7 +443,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
414
443
 
415
444
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
416
445
 
417
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
446
+ const bindings = this.logger.getBindings();
447
+ const contractsDB = new PublicContractsDB(
448
+ new TXEPublicContractDataSource(blockNumber, this.contractStore),
449
+ bindings,
450
+ );
418
451
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
419
452
  const config = PublicSimulatorConfig.from({
420
453
  skipFeeEnforcement: true,
@@ -427,8 +460,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
427
460
  globals,
428
461
  guardedMerkleTrees,
429
462
  contractsDB,
430
- new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
463
+ new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
431
464
  new TestDateProvider(),
465
+ undefined,
466
+ createLogger('simulator:public-processor', bindings),
432
467
  );
433
468
 
434
469
  const tx = await Tx.create({
@@ -491,7 +526,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
491
526
  return executionResult.returnValues ?? [];
492
527
  }
493
528
 
494
- async txePublicCallNewFlow(
529
+ async publicCallNewFlow(
495
530
  from: AztecAddress,
496
531
  targetContractAddress: AztecAddress,
497
532
  calldata: Fr[],
@@ -501,7 +536,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
501
536
  `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
502
537
  );
503
538
 
504
- const blockNumber = await this.txeGetNextBlockNumber();
539
+ const blockNumber = await this.getNextBlockNumber();
505
540
 
506
541
  const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
507
542
 
@@ -525,7 +560,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
525
560
 
526
561
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
527
562
 
528
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
563
+ const bindings2 = this.logger.getBindings();
564
+ const contractsDB = new PublicContractsDB(
565
+ new TXEPublicContractDataSource(blockNumber, this.contractStore),
566
+ bindings2,
567
+ );
529
568
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
530
569
  const config = PublicSimulatorConfig.from({
531
570
  skipFeeEnforcement: true,
@@ -534,8 +573,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
534
573
  collectStatistics: false,
535
574
  collectCallMetadata: true,
536
575
  });
537
- const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
538
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
576
+ const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
577
+ const processor = new PublicProcessor(
578
+ globals,
579
+ guardedMerkleTrees,
580
+ contractsDB,
581
+ simulator,
582
+ new TestDateProvider(),
583
+ undefined,
584
+ createLogger('simulator:public-processor', bindings2),
585
+ );
539
586
 
540
587
  // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
541
588
  // kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
@@ -566,7 +613,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
566
613
  constantData,
567
614
  /*gasUsed=*/ new Gas(0, 0),
568
615
  /*feePayer=*/ AztecAddress.zero(),
569
- /*includeByTimestamp=*/ 0n,
616
+ /*expirationTimestamp=*/ 0n,
570
617
  inputsForPublic,
571
618
  undefined,
572
619
  );
@@ -634,10 +681,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
634
681
  return returnValues ?? [];
635
682
  }
636
683
 
637
- async txeSimulateUtilityFunction(
684
+ async executeUtilityFunction(
638
685
  targetContractAddress: AztecAddress,
639
686
  functionSelector: FunctionSelector,
640
687
  args: Fr[],
688
+ jobId: string,
641
689
  ) {
642
690
  const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
643
691
  if (!artifact) {
@@ -645,25 +693,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
645
693
  }
646
694
 
647
695
  // Sync notes before executing utility function to discover notes from previous transactions
648
- await this.contractStore.syncPrivateState(targetContractAddress, functionSelector, async call => {
649
- await this.executeUtilityCall(call);
650
- });
651
-
652
- const call = new FunctionCall(
653
- artifact.name,
696
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
697
+ await this.stateMachine.contractSyncService.ensureContractSynced(
654
698
  targetContractAddress,
655
699
  functionSelector,
656
- FunctionType.UTILITY,
657
- false,
658
- false,
659
- args,
660
- [],
700
+ async (call, execScopes) => {
701
+ await this.executeUtilityCall(call, execScopes, jobId);
702
+ },
703
+ blockHeader,
704
+ jobId,
705
+ 'ALL_SCOPES',
661
706
  );
662
707
 
663
- return this.executeUtilityCall(call);
708
+ const call = FunctionCall.from({
709
+ name: artifact.name,
710
+ to: targetContractAddress,
711
+ selector: functionSelector,
712
+ type: FunctionType.UTILITY,
713
+ hideMsgSender: false,
714
+ isStatic: false,
715
+ args,
716
+ returnTypes: [],
717
+ });
718
+
719
+ return this.executeUtilityCall(call, 'ALL_SCOPES', jobId);
664
720
  }
665
721
 
666
- private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
722
+ private async executeUtilityCall(call: FunctionCall, scopes: AccessScopes, jobId: string): Promise<Fr[]> {
667
723
  const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
668
724
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
669
725
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
@@ -676,23 +732,25 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
676
732
 
677
733
  try {
678
734
  const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
679
- const oracle = new UtilityExecutionOracle(
680
- call.to,
681
- [],
682
- [],
735
+ const oracle = new UtilityExecutionOracle({
736
+ contractAddress: call.to,
737
+ authWitnesses: [],
738
+ capsules: [],
683
739
  anchorBlockHeader,
684
- this.contractStore,
685
- this.noteStore,
686
- this.keyStore,
687
- this.addressStore,
688
- this.stateMachine.node,
689
- this.stateMachine.anchorBlockStore,
690
- this.recipientTaggingStore,
691
- this.senderAddressBookStore,
692
- this.capsuleStore,
693
- this.privateEventStore,
694
- this.jobId,
695
- );
740
+ contractStore: this.contractStore,
741
+ noteStore: this.noteStore,
742
+ keyStore: this.keyStore,
743
+ addressStore: this.addressStore,
744
+ aztecNode: this.stateMachine.node,
745
+ recipientTaggingStore: this.recipientTaggingStore,
746
+ senderAddressBookStore: this.senderAddressBookStore,
747
+ capsuleStore: this.capsuleStore,
748
+ privateEventStore: this.privateEventStore,
749
+ messageContextService: this.stateMachine.messageContextService,
750
+ contractSyncService: this.contractSyncService,
751
+ jobId,
752
+ scopes,
753
+ });
696
754
  const acirExecutionResult = await new WASMSimulator()
697
755
  .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
698
756
  .catch((err: Error) => {
@@ -708,10 +766,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
708
766
  );
709
767
  });
710
768
 
711
- this.logger.verbose(`Utility simulation for ${call.to}.${call.selector} completed`);
769
+ this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
712
770
  return witnessMapToFields(acirExecutionResult.returnWitness);
713
771
  } catch (err) {
714
- throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility simulation'));
772
+ throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
715
773
  }
716
774
  }
717
775