@aztec/txe 0.0.1-commit.f295ac2 → 0.0.1-commit.f504929

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