@aztec/txe 0.0.1-commit.6d63667d → 0.0.1-commit.7b97ef96e

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 (40) hide show
  1. package/dest/index.d.ts +1 -1
  2. package/dest/index.d.ts.map +1 -1
  3. package/dest/index.js +82 -50
  4. package/dest/oracle/interfaces.d.ts +2 -2
  5. package/dest/oracle/interfaces.d.ts.map +1 -1
  6. package/dest/oracle/txe_oracle_top_level_context.d.ts +5 -6
  7. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  8. package/dest/oracle/txe_oracle_top_level_context.js +80 -28
  9. package/dest/rpc_translator.d.ts +5 -5
  10. package/dest/rpc_translator.d.ts.map +1 -1
  11. package/dest/rpc_translator.js +5 -5
  12. package/dest/state_machine/dummy_p2p_client.d.ts +15 -11
  13. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  14. package/dest/state_machine/dummy_p2p_client.js +27 -15
  15. package/dest/state_machine/index.d.ts +1 -1
  16. package/dest/state_machine/index.d.ts.map +1 -1
  17. package/dest/state_machine/index.js +1 -1
  18. package/dest/state_machine/mock_epoch_cache.d.ts +3 -1
  19. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  20. package/dest/state_machine/mock_epoch_cache.js +4 -0
  21. package/dest/txe_session.d.ts +4 -6
  22. package/dest/txe_session.d.ts.map +1 -1
  23. package/dest/txe_session.js +63 -14
  24. package/dest/util/txe_public_contract_data_source.d.ts +2 -3
  25. package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
  26. package/dest/util/txe_public_contract_data_source.js +5 -22
  27. package/package.json +15 -15
  28. package/src/index.ts +83 -49
  29. package/src/oracle/interfaces.ts +1 -1
  30. package/src/oracle/txe_oracle_top_level_context.ts +74 -81
  31. package/src/rpc_translator.ts +5 -5
  32. package/src/state_machine/dummy_p2p_client.ts +39 -21
  33. package/src/state_machine/index.ts +1 -0
  34. package/src/state_machine/mock_epoch_cache.ts +5 -0
  35. package/src/txe_session.ts +61 -64
  36. package/src/util/txe_public_contract_data_source.ts +10 -36
  37. package/dest/util/txe_contract_store.d.ts +0 -12
  38. package/dest/util/txe_contract_store.d.ts.map +0 -1
  39. package/dest/util/txe_contract_store.js +0 -22
  40. package/src/util/txe_contract_store.ts +0 -36
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/txe",
3
- "version": "0.0.1-commit.6d63667d",
3
+ "version": "0.0.1-commit.7b97ef96e",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "bin": "./dest/bin/index.js",
@@ -61,20 +61,20 @@
61
61
  ]
62
62
  },
63
63
  "dependencies": {
64
- "@aztec/accounts": "0.0.1-commit.6d63667d",
65
- "@aztec/archiver": "0.0.1-commit.6d63667d",
66
- "@aztec/aztec-node": "0.0.1-commit.6d63667d",
67
- "@aztec/aztec.js": "0.0.1-commit.6d63667d",
68
- "@aztec/bb-prover": "0.0.1-commit.6d63667d",
69
- "@aztec/constants": "0.0.1-commit.6d63667d",
70
- "@aztec/foundation": "0.0.1-commit.6d63667d",
71
- "@aztec/key-store": "0.0.1-commit.6d63667d",
72
- "@aztec/kv-store": "0.0.1-commit.6d63667d",
73
- "@aztec/protocol-contracts": "0.0.1-commit.6d63667d",
74
- "@aztec/pxe": "0.0.1-commit.6d63667d",
75
- "@aztec/simulator": "0.0.1-commit.6d63667d",
76
- "@aztec/stdlib": "0.0.1-commit.6d63667d",
77
- "@aztec/world-state": "0.0.1-commit.6d63667d",
64
+ "@aztec/accounts": "0.0.1-commit.7b97ef96e",
65
+ "@aztec/archiver": "0.0.1-commit.7b97ef96e",
66
+ "@aztec/aztec-node": "0.0.1-commit.7b97ef96e",
67
+ "@aztec/aztec.js": "0.0.1-commit.7b97ef96e",
68
+ "@aztec/bb-prover": "0.0.1-commit.7b97ef96e",
69
+ "@aztec/constants": "0.0.1-commit.7b97ef96e",
70
+ "@aztec/foundation": "0.0.1-commit.7b97ef96e",
71
+ "@aztec/key-store": "0.0.1-commit.7b97ef96e",
72
+ "@aztec/kv-store": "0.0.1-commit.7b97ef96e",
73
+ "@aztec/protocol-contracts": "0.0.1-commit.7b97ef96e",
74
+ "@aztec/pxe": "0.0.1-commit.7b97ef96e",
75
+ "@aztec/simulator": "0.0.1-commit.7b97ef96e",
76
+ "@aztec/stdlib": "0.0.1-commit.7b97ef96e",
77
+ "@aztec/world-state": "0.0.1-commit.7b97ef96e",
78
78
  "zod": "^3.23.8"
79
79
  },
80
80
  "devDependencies": {
package/src/index.ts CHANGED
@@ -9,9 +9,12 @@ import { Fr } from '@aztec/aztec.js/fields';
9
9
  import { PublicKeys, deriveKeys } from '@aztec/aztec.js/keys';
10
10
  import { createSafeJsonRpcServer } from '@aztec/foundation/json-rpc/server';
11
11
  import type { Logger } from '@aztec/foundation/log';
12
- import { type ProtocolContract, protocolContractNames } from '@aztec/protocol-contracts';
12
+ import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
13
+ import { protocolContractNames } from '@aztec/protocol-contracts';
13
14
  import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/providers/bundle';
15
+ import { ContractStore } from '@aztec/pxe/server';
14
16
  import { computeArtifactHash } from '@aztec/stdlib/contract';
17
+ import type { ContractArtifactWithHash } from '@aztec/stdlib/contract';
15
18
  import type { ApiSchemaFor } from '@aztec/stdlib/schemas';
16
19
  import { zodFor } from '@aztec/stdlib/schemas';
17
20
 
@@ -33,18 +36,24 @@ import {
33
36
  fromSingle,
34
37
  toSingle,
35
38
  } from './util/encoding.js';
36
- import type { ContractArtifactWithHash } from './util/txe_contract_store.js';
37
39
 
38
40
  const sessions = new Map<number, TXESession>();
39
41
 
40
42
  /*
41
43
  * TXE typically has to load the same contract artifacts over and over again for multiple tests,
42
- * so we cache them here to avoid both loading them from disk repeatedly and computing their artifact hashes
44
+ * so we cache them here to avoid loading from disk repeatedly.
45
+ *
46
+ * The in-flight map coalesces concurrent requests for the same cache key so that
47
+ * computeArtifactHash (very expensive) is only run once even under parallelism.
43
48
  */
44
49
  const TXEArtifactsCache = new Map<
45
50
  string,
46
51
  { artifact: ContractArtifactWithHash; instance: ContractInstanceWithAddress }
47
52
  >();
53
+ const TXEArtifactsCacheInFlight = new Map<
54
+ string,
55
+ Promise<{ artifact: ContractArtifactWithHash; instance: ContractInstanceWithAddress }>
56
+ >();
48
57
 
49
58
  type TXEForeignCallInput = {
50
59
  session_id: number;
@@ -68,7 +77,7 @@ const TXEForeignCallInputSchema = zodFor<TXEForeignCallInput>()(
68
77
  );
69
78
 
70
79
  class TXEDispatcher {
71
- private protocolContracts!: ProtocolContract[];
80
+ private contractStore!: ContractStore;
72
81
 
73
82
  constructor(private logger: Logger) {}
74
83
 
@@ -135,29 +144,36 @@ class TXEDispatcher {
135
144
  this.logger.debug(`Using cached artifact for ${cacheKey}`);
136
145
  ({ artifact, instance } = TXEArtifactsCache.get(cacheKey)!);
137
146
  } else {
138
- this.logger.debug(`Loading compiled artifact ${artifactPath}`);
139
- const artifactJSON = JSON.parse(await readFile(artifactPath, 'utf-8')) as NoirCompiledContract;
140
- const artifactWithoutHash = loadContractArtifact(artifactJSON);
141
- artifact = {
142
- ...artifactWithoutHash,
143
- // Artifact hash is *very* expensive to compute, so we do it here once
144
- // and the TXE contract data provider can cache it
145
- artifactHash: await computeArtifactHash(artifactWithoutHash),
146
- };
147
- this.logger.debug(
148
- `Deploy ${
149
- artifact.name
150
- } with initializer ${initializer}(${decodedArgs}) and public keys hash ${publicKeysHash.toString()}`,
151
- );
152
- instance = await getContractInstanceFromInstantiationParams(artifact, {
153
- constructorArgs: decodedArgs,
154
- skipArgsDecoding: true,
155
- salt: Fr.ONE,
156
- publicKeys,
157
- constructorArtifact: initializer ? initializer : undefined,
158
- deployer: AztecAddress.ZERO,
159
- });
160
- TXEArtifactsCache.set(cacheKey, { artifact, instance });
147
+ if (!TXEArtifactsCacheInFlight.has(cacheKey)) {
148
+ this.logger.debug(`Loading compiled artifact ${artifactPath}`);
149
+ const compute = async () => {
150
+ const artifactJSON = JSON.parse(await readFile(artifactPath, 'utf-8')) as NoirCompiledContract;
151
+ const artifactWithoutHash = loadContractArtifact(artifactJSON);
152
+ const computedArtifact: ContractArtifactWithHash = {
153
+ ...artifactWithoutHash,
154
+ // Artifact hash is *very* expensive to compute, so we do it here once
155
+ // and the TXE contract data provider can cache it
156
+ artifactHash: await computeArtifactHash(artifactWithoutHash),
157
+ };
158
+ this.logger.debug(
159
+ `Deploy ${computedArtifact.name} with initializer ${initializer}(${decodedArgs}) and public keys hash ${publicKeysHash.toString()}`,
160
+ );
161
+ const computedInstance = await getContractInstanceFromInstantiationParams(computedArtifact, {
162
+ constructorArgs: decodedArgs,
163
+ skipArgsDecoding: true,
164
+ salt: Fr.ONE,
165
+ publicKeys,
166
+ constructorArtifact: initializer ? initializer : undefined,
167
+ deployer: AztecAddress.ZERO,
168
+ });
169
+ const result = { artifact: computedArtifact, instance: computedInstance };
170
+ TXEArtifactsCache.set(cacheKey, result);
171
+ TXEArtifactsCacheInFlight.delete(cacheKey);
172
+ return result;
173
+ };
174
+ TXEArtifactsCacheInFlight.set(cacheKey, compute());
175
+ }
176
+ ({ artifact, instance } = await TXEArtifactsCacheInFlight.get(cacheKey)!);
161
177
  }
162
178
 
163
179
  inputs.splice(0, 1, artifact, instance, toSingle(secret));
@@ -175,23 +191,35 @@ class TXEDispatcher {
175
191
  this.logger.debug(`Using cached artifact for ${cacheKey}`);
176
192
  ({ artifact, instance } = TXEArtifactsCache.get(cacheKey)!);
177
193
  } else {
178
- const keys = await deriveKeys(secret);
179
- const args = [keys.publicKeys.masterIncomingViewingPublicKey.x, keys.publicKeys.masterIncomingViewingPublicKey.y];
180
- artifact = {
181
- ...SchnorrAccountContractArtifact,
182
- // Artifact hash is *very* expensive to compute, so we do it here once
183
- // and the TXE contract data provider can cache it
184
- artifactHash: await computeArtifactHash(SchnorrAccountContractArtifact),
185
- };
186
- instance = await getContractInstanceFromInstantiationParams(artifact, {
187
- constructorArgs: args,
188
- skipArgsDecoding: true,
189
- salt: Fr.ONE,
190
- publicKeys: keys.publicKeys,
191
- constructorArtifact: 'constructor',
192
- deployer: AztecAddress.ZERO,
193
- });
194
- TXEArtifactsCache.set(cacheKey, { artifact, instance });
194
+ if (!TXEArtifactsCacheInFlight.has(cacheKey)) {
195
+ const compute = async () => {
196
+ const keys = await deriveKeys(secret);
197
+ const args = [
198
+ keys.publicKeys.masterIncomingViewingPublicKey.x,
199
+ keys.publicKeys.masterIncomingViewingPublicKey.y,
200
+ ];
201
+ const computedArtifact: ContractArtifactWithHash = {
202
+ ...SchnorrAccountContractArtifact,
203
+ // Artifact hash is *very* expensive to compute, so we do it here once
204
+ // and the TXE contract data provider can cache it
205
+ artifactHash: await computeArtifactHash(SchnorrAccountContractArtifact),
206
+ };
207
+ const computedInstance = await getContractInstanceFromInstantiationParams(computedArtifact, {
208
+ constructorArgs: args,
209
+ skipArgsDecoding: true,
210
+ salt: Fr.ONE,
211
+ publicKeys: keys.publicKeys,
212
+ constructorArtifact: 'constructor',
213
+ deployer: AztecAddress.ZERO,
214
+ });
215
+ const result = { artifact: computedArtifact, instance: computedInstance };
216
+ TXEArtifactsCache.set(cacheKey, result);
217
+ TXEArtifactsCacheInFlight.delete(cacheKey);
218
+ return result;
219
+ };
220
+ TXEArtifactsCacheInFlight.set(cacheKey, compute());
221
+ }
222
+ ({ artifact, instance } = await TXEArtifactsCacheInFlight.get(cacheKey)!);
195
223
  }
196
224
 
197
225
  inputs.splice(0, 0, artifact, instance);
@@ -204,12 +232,18 @@ class TXEDispatcher {
204
232
 
205
233
  if (!sessions.has(sessionId)) {
206
234
  this.logger.debug(`Creating new session ${sessionId}`);
207
- if (!this.protocolContracts) {
208
- this.protocolContracts = await Promise.all(
209
- protocolContractNames.map(name => new BundledProtocolContractsProvider().getProtocolContractArtifact(name)),
210
- );
235
+ if (!this.contractStore) {
236
+ const kvStore = await openTmpStore('txe-contracts');
237
+ this.contractStore = new ContractStore(kvStore);
238
+ const provider = new BundledProtocolContractsProvider();
239
+ for (const name of protocolContractNames) {
240
+ const { instance, artifact } = await provider.getProtocolContractArtifact(name);
241
+ await this.contractStore.addContractArtifact(artifact);
242
+ await this.contractStore.addContractInstance(instance);
243
+ }
244
+ this.logger.debug('Registered protocol contracts in shared contract store');
211
245
  }
212
- sessions.set(sessionId, await TXESession.init(this.protocolContracts));
246
+ sessions.set(sessionId, await TXESession.init(this.contractStore));
213
247
  }
214
248
 
215
249
  switch (functionName) {
@@ -72,7 +72,7 @@ export interface ITxeExecutionOracle {
72
72
  argsHash: Fr,
73
73
  isStaticCall: boolean,
74
74
  ): Promise<Fr[]>;
75
- txeSimulateUtilityFunction(
75
+ txeExecuteUtilityFunction(
76
76
  targetContractAddress: AztecAddress,
77
77
  functionSelector: FunctionSelector,
78
78
  args: Fr[],
@@ -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,
@@ -131,13 +132,14 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
131
132
  }
132
133
 
133
134
  // 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 {
135
+ utilityLog(level: number, message: string, fields: Fr[]): Promise<void> {
135
136
  if (!LogLevels[level]) {
136
- throw new Error(`Invalid debug log level: ${level}`);
137
+ throw new Error(`Invalid log level: ${level}`);
137
138
  }
138
139
  const levelName = LogLevels[level];
139
140
 
140
141
  this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
142
+ return Promise.resolve();
141
143
  }
142
144
 
143
145
  txeGetDefaultAddress(): AztecAddress {
@@ -209,7 +211,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
209
211
  await this.txeAddAccount(artifact, instance, secret);
210
212
  } else {
211
213
  await this.contractStore.addContractInstance(instance);
212
- await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
214
+ await this.contractStore.addContractArtifact(artifact);
213
215
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
214
216
  }
215
217
  }
@@ -219,7 +221,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
219
221
 
220
222
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
221
223
  await this.contractStore.addContractInstance(instance);
222
- await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
224
+ await this.contractStore.addContractArtifact(artifact);
223
225
 
224
226
  const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
225
227
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
@@ -296,14 +298,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
296
298
  throw new Error(message);
297
299
  }
298
300
 
299
- // When `from` is the zero address (used when creating a new contract account for example),
300
- // we disable scope filtering by setting effectiveScopes to undefined. This allows these operations
301
- // to proceed without requiring keys registered for the zero address.
302
- const effectiveScopes = from.isZero() ? undefined : [from];
301
+ // When `from` is the zero address (e.g. when deploying a new account contract), we return an
302
+ // empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
303
+ const effectiveScopes = from.isZero() ? [] : [from];
303
304
 
304
305
  // Sync notes before executing private function to discover notes from previous transactions
305
- const utilityExecutor = async (call: FunctionCall) => {
306
- await this.executeUtilityCall(call, effectiveScopes);
306
+ const utilityExecutor = async (call: FunctionCall, execScopes: AccessScopes) => {
307
+ await this.executeUtilityCall(call, execScopes);
307
308
  };
308
309
 
309
310
  const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
@@ -313,6 +314,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
313
314
  utilityExecutor,
314
315
  blockHeader,
315
316
  this.jobId,
317
+ effectiveScopes,
316
318
  );
317
319
 
318
320
  const blockNumber = await this.txeGetNextBlockNumber();
@@ -336,43 +338,37 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
336
338
 
337
339
  const simulator = new WASMSimulator();
338
340
 
339
- const privateExecutionOracle = new PrivateExecutionOracle(
341
+ const privateExecutionOracle = new PrivateExecutionOracle({
340
342
  argsHash,
341
343
  txContext,
342
344
  callContext,
343
- /** Header of a block whose state is used during private execution (not the block the transaction is included in). */
344
- blockHeader,
345
+ anchorBlockHeader: blockHeader,
345
346
  utilityExecutor,
346
- /** List of transient auth witnesses to be used during this simulation */
347
- Array.from(this.authwits.values()),
348
- /** List of transient auth witnesses to be used during this simulation */
349
- [],
350
- HashedValuesCache.create([new HashedValues(args, argsHash)]),
347
+ authWitnesses: Array.from(this.authwits.values()),
348
+ capsules: [],
349
+ executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
351
350
  noteCache,
352
351
  taggingIndexCache,
353
- this.contractStore,
354
- this.noteStore,
355
- this.keyStore,
356
- this.addressStore,
357
- this.stateMachine.node,
358
- this.senderTaggingStore,
359
- this.recipientTaggingStore,
360
- this.senderAddressBookStore,
361
- this.capsuleStore,
362
- this.privateEventStore,
363
- this.stateMachine.contractSyncService,
364
- this.jobId,
365
- 0, // totalPublicArgsCount
366
- minRevertibleSideEffectCounter, // (start) sideEffectCounter
367
- undefined, // log
368
- effectiveScopes, // scopes
369
- /**
370
- * In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
371
- * contract would perform, including setting senderForTags.
372
- */
373
- from,
352
+ contractStore: this.contractStore,
353
+ noteStore: this.noteStore,
354
+ keyStore: this.keyStore,
355
+ addressStore: this.addressStore,
356
+ aztecNode: this.stateMachine.node,
357
+ senderTaggingStore: this.senderTaggingStore,
358
+ recipientTaggingStore: this.recipientTaggingStore,
359
+ senderAddressBookStore: this.senderAddressBookStore,
360
+ capsuleStore: this.capsuleStore,
361
+ privateEventStore: this.privateEventStore,
362
+ contractSyncService: this.stateMachine.contractSyncService,
363
+ jobId: this.jobId,
364
+ totalPublicCalldataCount: 0,
365
+ sideEffectCounter: minRevertibleSideEffectCounter,
366
+ scopes: effectiveScopes,
367
+ // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
368
+ // contract would perform, including setting senderForTags.
369
+ senderForTags: from,
374
370
  simulator,
375
- );
371
+ });
376
372
 
377
373
  // 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.
378
374
  let result: PrivateExecutionResult;
@@ -411,7 +407,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
411
407
  // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
412
408
  const { publicInputs } = await generateSimulatedProvingResult(
413
409
  result,
414
- this.contractStore,
410
+ (addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
411
+ this.stateMachine.node,
415
412
  minRevertibleSideEffectCounter,
416
413
  );
417
414
 
@@ -594,7 +591,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
594
591
  constantData,
595
592
  /*gasUsed=*/ new Gas(0, 0),
596
593
  /*feePayer=*/ AztecAddress.zero(),
597
- /*includeByTimestamp=*/ 0n,
594
+ /*expirationTimestamp=*/ 0n,
598
595
  inputsForPublic,
599
596
  undefined,
600
597
  );
@@ -662,11 +659,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
662
659
  return returnValues ?? [];
663
660
  }
664
661
 
665
- async txeSimulateUtilityFunction(
666
- targetContractAddress: AztecAddress,
667
- functionSelector: FunctionSelector,
668
- args: Fr[],
669
- ) {
662
+ async txeExecuteUtilityFunction(targetContractAddress: AztecAddress, functionSelector: FunctionSelector, args: Fr[]) {
670
663
  const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
671
664
  if (!artifact) {
672
665
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
@@ -677,28 +670,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
677
670
  await this.stateMachine.contractSyncService.ensureContractSynced(
678
671
  targetContractAddress,
679
672
  functionSelector,
680
- async call => {
681
- await this.executeUtilityCall(call);
673
+ async (call, execScopes) => {
674
+ await this.executeUtilityCall(call, execScopes);
682
675
  },
683
676
  blockHeader,
684
677
  this.jobId,
678
+ 'ALL_SCOPES',
685
679
  );
686
680
 
687
- const call = new FunctionCall(
688
- artifact.name,
689
- targetContractAddress,
690
- functionSelector,
691
- FunctionType.UTILITY,
692
- false,
693
- false,
681
+ const call = FunctionCall.from({
682
+ name: artifact.name,
683
+ to: targetContractAddress,
684
+ selector: functionSelector,
685
+ type: FunctionType.UTILITY,
686
+ hideMsgSender: false,
687
+ isStatic: false,
694
688
  args,
695
- [],
696
- );
689
+ returnTypes: [],
690
+ });
697
691
 
698
- return this.executeUtilityCall(call);
692
+ return this.executeUtilityCall(call, 'ALL_SCOPES');
699
693
  }
700
694
 
701
- private async executeUtilityCall(call: FunctionCall, scopes?: AztecAddress[]): Promise<Fr[]> {
695
+ private async executeUtilityCall(call: FunctionCall, scopes: AccessScopes): Promise<Fr[]> {
702
696
  const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
703
697
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
704
698
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
@@ -711,24 +705,23 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
711
705
 
712
706
  try {
713
707
  const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
714
- const oracle = new UtilityExecutionOracle(
715
- call.to,
716
- [],
717
- [],
708
+ const oracle = new UtilityExecutionOracle({
709
+ contractAddress: call.to,
710
+ authWitnesses: [],
711
+ capsules: [],
718
712
  anchorBlockHeader,
719
- this.contractStore,
720
- this.noteStore,
721
- this.keyStore,
722
- this.addressStore,
723
- this.stateMachine.node,
724
- this.recipientTaggingStore,
725
- this.senderAddressBookStore,
726
- this.capsuleStore,
727
- this.privateEventStore,
728
- this.jobId,
729
- undefined, // log
730
- scopes, // scopes - used to filter notes by account
731
- );
713
+ contractStore: this.contractStore,
714
+ noteStore: this.noteStore,
715
+ keyStore: this.keyStore,
716
+ addressStore: this.addressStore,
717
+ aztecNode: this.stateMachine.node,
718
+ recipientTaggingStore: this.recipientTaggingStore,
719
+ senderAddressBookStore: this.senderAddressBookStore,
720
+ capsuleStore: this.capsuleStore,
721
+ privateEventStore: this.privateEventStore,
722
+ jobId: this.jobId,
723
+ scopes,
724
+ });
732
725
  const acirExecutionResult = await new WASMSimulator()
733
726
  .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
734
727
  .catch((err: Error) => {
@@ -744,10 +737,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
744
737
  );
745
738
  });
746
739
 
747
- this.logger.verbose(`Utility simulation for ${call.to}.${call.selector} completed`);
740
+ this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
748
741
  return witnessMapToFields(acirExecutionResult.returnWitness);
749
742
  } catch (err) {
750
- throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility simulation'));
743
+ throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
751
744
  }
752
745
  }
753
746
 
@@ -328,7 +328,7 @@ export class RPCTranslator {
328
328
 
329
329
  // When the argument is a slice, noir automatically adds a length field to oracle call.
330
330
  // When the argument is an array, we add the field length manually to the signature.
331
- utilityDebugLog(
331
+ async utilityLog(
332
332
  foreignLevel: ForeignCallSingle,
333
333
  foreignMessage: ForeignCallArray,
334
334
  _foreignLength: ForeignCallSingle,
@@ -340,7 +340,7 @@ export class RPCTranslator {
340
340
  .join('');
341
341
  const fields = fromArray(foreignFields);
342
342
 
343
- this.handlerAsMisc().utilityDebugLog(level, message, fields);
343
+ await this.handlerAsMisc().utilityLog(level, message, fields);
344
344
 
345
345
  return toForeignCallResult([]);
346
346
  }
@@ -849,7 +849,7 @@ export class RPCTranslator {
849
849
 
850
850
  // AVM opcodes
851
851
 
852
- avmOpcodeEmitUnencryptedLog(_foreignMessage: ForeignCallArray) {
852
+ avmOpcodeEmitPublicLog(_foreignMessage: ForeignCallArray) {
853
853
  // TODO(#8811): Implement
854
854
  return toForeignCallResult([]);
855
855
  }
@@ -1043,7 +1043,7 @@ export class RPCTranslator {
1043
1043
  return toForeignCallResult([toArray(returnValues)]);
1044
1044
  }
1045
1045
 
1046
- async txeSimulateUtilityFunction(
1046
+ async txeExecuteUtilityFunction(
1047
1047
  foreignTargetContractAddress: ForeignCallSingle,
1048
1048
  foreignFunctionSelector: ForeignCallSingle,
1049
1049
  foreignArgs: ForeignCallArray,
@@ -1052,7 +1052,7 @@ export class RPCTranslator {
1052
1052
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
1053
1053
  const args = fromArray(foreignArgs);
1054
1054
 
1055
- const returnValues = await this.handlerAsTxe().txeSimulateUtilityFunction(
1055
+ const returnValues = await this.handlerAsTxe().txeExecuteUtilityFunction(
1056
1056
  targetContractAddress,
1057
1057
  functionSelector,
1058
1058
  args,