@aztec/txe 0.0.1-commit.29c6b1a3 → 0.0.1-commit.2d9cb6034

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