@aztec/txe 3.0.3 → 4.0.0-devnet.1-patch.1

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 (77) hide show
  1. package/dest/constants.d.ts +3 -0
  2. package/dest/constants.d.ts.map +1 -0
  3. package/dest/constants.js +2 -0
  4. package/dest/index.d.ts +1 -1
  5. package/dest/index.d.ts.map +1 -1
  6. package/dest/index.js +3 -2
  7. package/dest/oracle/interfaces.d.ts +6 -4
  8. package/dest/oracle/interfaces.d.ts.map +1 -1
  9. package/dest/oracle/txe_oracle_public_context.d.ts +4 -4
  10. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  11. package/dest/oracle/txe_oracle_public_context.js +9 -11
  12. package/dest/oracle/txe_oracle_top_level_context.d.ts +20 -11
  13. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  14. package/dest/oracle/txe_oracle_top_level_context.js +164 -65
  15. package/dest/rpc_translator.d.ts +27 -15
  16. package/dest/rpc_translator.d.ts.map +1 -1
  17. package/dest/rpc_translator.js +108 -53
  18. package/dest/state_machine/archiver.d.ts +20 -55
  19. package/dest/state_machine/archiver.d.ts.map +1 -1
  20. package/dest/state_machine/archiver.js +62 -103
  21. package/dest/state_machine/dummy_p2p_client.d.ts +14 -12
  22. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  23. package/dest/state_machine/dummy_p2p_client.js +29 -21
  24. package/dest/state_machine/global_variable_builder.d.ts +4 -3
  25. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  26. package/dest/state_machine/global_variable_builder.js +13 -1
  27. package/dest/state_machine/index.d.ts +7 -7
  28. package/dest/state_machine/index.d.ts.map +1 -1
  29. package/dest/state_machine/index.js +40 -23
  30. package/dest/state_machine/mock_epoch_cache.d.ts +9 -6
  31. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  32. package/dest/state_machine/mock_epoch_cache.js +14 -7
  33. package/dest/state_machine/synchronizer.d.ts +3 -3
  34. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  35. package/dest/txe_session.d.ts +17 -9
  36. package/dest/txe_session.d.ts.map +1 -1
  37. package/dest/txe_session.js +147 -45
  38. package/dest/util/encoding.d.ts +617 -18
  39. package/dest/util/encoding.d.ts.map +1 -1
  40. package/dest/util/txe_account_store.d.ts +10 -0
  41. package/dest/util/txe_account_store.d.ts.map +1 -0
  42. package/dest/util/{txe_account_data_provider.js → txe_account_store.js} +1 -1
  43. package/dest/util/txe_contract_store.d.ts +12 -0
  44. package/dest/util/txe_contract_store.d.ts.map +1 -0
  45. package/dest/util/{txe_contract_data_provider.js → txe_contract_store.js} +3 -3
  46. package/dest/util/txe_public_contract_data_source.d.ts +4 -4
  47. package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
  48. package/dest/util/txe_public_contract_data_source.js +10 -10
  49. package/dest/utils/block_creation.d.ts +18 -4
  50. package/dest/utils/block_creation.d.ts.map +1 -1
  51. package/dest/utils/block_creation.js +37 -3
  52. package/dest/utils/tx_effect_creation.d.ts +2 -3
  53. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  54. package/dest/utils/tx_effect_creation.js +3 -6
  55. package/package.json +16 -16
  56. package/src/constants.ts +3 -0
  57. package/src/index.ts +15 -12
  58. package/src/oracle/interfaces.ts +5 -3
  59. package/src/oracle/txe_oracle_public_context.ts +9 -16
  60. package/src/oracle/txe_oracle_top_level_context.ts +196 -105
  61. package/src/rpc_translator.ts +123 -55
  62. package/src/state_machine/archiver.ts +58 -126
  63. package/src/state_machine/dummy_p2p_client.ts +40 -27
  64. package/src/state_machine/global_variable_builder.ts +19 -2
  65. package/src/state_machine/index.ts +60 -22
  66. package/src/state_machine/mock_epoch_cache.ts +15 -11
  67. package/src/state_machine/synchronizer.ts +2 -2
  68. package/src/txe_session.ts +197 -87
  69. package/src/util/{txe_account_data_provider.ts → txe_account_store.ts} +1 -1
  70. package/src/util/{txe_contract_data_provider.ts → txe_contract_store.ts} +3 -3
  71. package/src/util/txe_public_contract_data_source.ts +9 -9
  72. package/src/utils/block_creation.ts +47 -14
  73. package/src/utils/tx_effect_creation.ts +3 -11
  74. package/dest/util/txe_account_data_provider.d.ts +0 -10
  75. package/dest/util/txe_account_data_provider.d.ts.map +0 -1
  76. package/dest/util/txe_contract_data_provider.d.ts +0 -12
  77. package/dest/util/txe_contract_data_provider.d.ts.map +0 -1
@@ -13,9 +13,14 @@ import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@az
13
13
  import { TestDateProvider } from '@aztec/foundation/timer';
14
14
  import type { KeyStore } from '@aztec/key-store';
15
15
  import {
16
- AddressDataProvider,
16
+ AddressStore,
17
+ CapsuleStore,
18
+ NoteStore,
17
19
  ORACLE_VERSION,
18
- PXEOracleInterface,
20
+ PrivateEventStore,
21
+ RecipientTaggingStore,
22
+ SenderAddressBookStore,
23
+ SenderTaggingStore,
19
24
  enrichPublicSimulationError,
20
25
  } from '@aztec/pxe/server';
21
26
  import {
@@ -44,11 +49,10 @@ import {
44
49
  PublicContractsDB,
45
50
  PublicProcessor,
46
51
  } from '@aztec/simulator/server';
47
- import { type ContractArtifact, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
52
+ import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
48
53
  import { AuthWitness } from '@aztec/stdlib/auth-witness';
49
54
  import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
50
55
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
51
- import { Body, L2Block } from '@aztec/stdlib/block';
52
56
  import { type ContractInstanceWithAddress, computePartialAddress } from '@aztec/stdlib/contract';
53
57
  import { Gas, GasFees, GasSettings } from '@aztec/stdlib/gas';
54
58
  import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
@@ -59,7 +63,7 @@ import {
59
63
  PublicCallRequest,
60
64
  } from '@aztec/stdlib/kernel';
61
65
  import { ChonkProof } from '@aztec/stdlib/proofs';
62
- import { makeAppendOnlyTreeSnapshot, makeGlobalVariables } from '@aztec/stdlib/testing';
66
+ import { makeGlobalVariables } from '@aztec/stdlib/testing';
63
67
  import { MerkleTreeId } from '@aztec/stdlib/trees';
64
68
  import {
65
69
  CallContext,
@@ -76,15 +80,12 @@ import {
76
80
  import type { UInt64 } from '@aztec/stdlib/types';
77
81
  import { ForkCheckpoint } from '@aztec/world-state';
78
82
 
83
+ import { DEFAULT_ADDRESS } from '../constants.js';
79
84
  import type { TXEStateMachine } from '../state_machine/index.js';
80
- import type { TXEAccountDataProvider } from '../util/txe_account_data_provider.js';
81
- import type { TXEContractDataProvider } from '../util/txe_contract_data_provider.js';
85
+ import type { TXEAccountStore } from '../util/txe_account_store.js';
86
+ import type { TXEContractStore } from '../util/txe_contract_store.js';
82
87
  import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
83
- import {
84
- getSingleTxBlockRequestHash,
85
- insertTxEffectIntoWorldTrees,
86
- makeTXEBlockHeader,
87
- } from '../utils/block_creation.js';
88
+ import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
88
89
  import type { ITxeExecutionOracle } from './interfaces.js';
89
90
 
90
91
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
@@ -95,11 +96,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
95
96
 
96
97
  constructor(
97
98
  private stateMachine: TXEStateMachine,
98
- private contractDataProvider: TXEContractDataProvider,
99
+ private contractStore: TXEContractStore,
100
+ private noteStore: NoteStore,
99
101
  private keyStore: KeyStore,
100
- private addressDataProvider: AddressDataProvider,
101
- private accountDataProvider: TXEAccountDataProvider,
102
- private pxeOracleInterface: PXEOracleInterface,
102
+ private addressStore: AddressStore,
103
+ private accountStore: TXEAccountStore,
104
+ private senderTaggingStore: SenderTaggingStore,
105
+ private recipientTaggingStore: RecipientTaggingStore,
106
+ private senderAddressBookStore: SenderAddressBookStore,
107
+ private capsuleStore: CapsuleStore,
108
+ private privateEventStore: PrivateEventStore,
109
+ private jobId: string,
103
110
  private nextBlockTimestamp: bigint,
104
111
  private version: Fr,
105
112
  private chainId: Fr,
@@ -124,13 +131,18 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
124
131
  }
125
132
 
126
133
  // We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
127
- utilityDebugLog(level: number, message: string, fields: Fr[]): void {
134
+ utilityDebugLog(level: number, message: string, fields: Fr[]): Promise<void> {
128
135
  if (!LogLevels[level]) {
129
136
  throw new Error(`Invalid debug log level: ${level}`);
130
137
  }
131
138
  const levelName = LogLevels[level];
132
139
 
133
140
  this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
141
+ return Promise.resolve();
142
+ }
143
+
144
+ txeGetDefaultAddress(): AztecAddress {
145
+ return DEFAULT_ADDRESS;
134
146
  }
135
147
 
136
148
  async txeGetNextBlockNumber(): Promise<BlockNumber> {
@@ -146,7 +158,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
146
158
  }
147
159
 
148
160
  async txeGetLastTxEffects() {
149
- const block = await this.stateMachine.archiver.getBlock('latest');
161
+ const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
162
+ const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
150
163
 
151
164
  if (block!.body.txEffects.length != 1) {
152
165
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -158,6 +171,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
158
171
  return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
159
172
  }
160
173
 
174
+ async txeGetPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
175
+ return (
176
+ await this.privateEventStore.getPrivateEvents(selector, {
177
+ contractAddress,
178
+ scopes: [scope],
179
+ fromBlock: 0,
180
+ toBlock: (await this.getLastBlockNumber()) + 1,
181
+ })
182
+ ).map(e => e.packedEvent);
183
+ }
184
+
161
185
  async txeAdvanceBlocksBy(blocks: number) {
162
186
  this.logger.debug(`time traveling ${blocks} blocks`);
163
187
 
@@ -185,8 +209,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
185
209
  if (!secret.equals(Fr.ZERO)) {
186
210
  await this.txeAddAccount(artifact, instance, secret);
187
211
  } else {
188
- await this.contractDataProvider.addContractInstance(instance);
189
- await this.contractDataProvider.addContractArtifact(instance.currentContractClassId, artifact);
212
+ await this.contractStore.addContractInstance(instance);
213
+ await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
190
214
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
191
215
  }
192
216
  }
@@ -195,29 +219,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
195
219
  const partialAddress = await computePartialAddress(instance);
196
220
 
197
221
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
198
- await this.contractDataProvider.addContractInstance(instance);
199
- await this.contractDataProvider.addContractArtifact(instance.currentContractClassId, artifact);
222
+ await this.contractStore.addContractInstance(instance);
223
+ await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
200
224
 
201
225
  const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
202
- await this.accountDataProvider.setAccount(completeAddress.address, completeAddress);
203
- await this.addressDataProvider.addCompleteAddress(completeAddress);
226
+ await this.accountStore.setAccount(completeAddress.address, completeAddress);
227
+ await this.addressStore.addCompleteAddress(completeAddress);
204
228
  this.logger.debug(`Created account ${completeAddress.address}`);
205
229
 
206
230
  return completeAddress;
207
231
  }
208
232
 
209
233
  async txeCreateAccount(secret: Fr) {
210
- // This is a footgun !
234
+ // This is a foot gun !
211
235
  const completeAddress = await this.keyStore.addAccount(secret, secret);
212
- await this.accountDataProvider.setAccount(completeAddress.address, completeAddress);
213
- await this.addressDataProvider.addCompleteAddress(completeAddress);
236
+ await this.accountStore.setAccount(completeAddress.address, completeAddress);
237
+ await this.addressStore.addCompleteAddress(completeAddress);
214
238
  this.logger.debug(`Created account ${completeAddress.address}`);
215
239
 
216
240
  return completeAddress;
217
241
  }
218
242
 
219
243
  async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
220
- const account = await this.accountDataProvider.getAccount(address);
244
+ const account = await this.accountStore.getAccount(address);
221
245
  const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
222
246
 
223
247
  const schnorr = new Schnorr();
@@ -238,19 +262,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
238
262
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
239
263
  await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
240
264
 
241
- const block = new L2Block(
242
- makeAppendOnlyTreeSnapshot(),
243
- await makeTXEBlockHeader(
244
- forkedWorldTrees,
245
- makeGlobalVariables(undefined, {
246
- blockNumber,
247
- timestamp: this.nextBlockTimestamp,
248
- version: this.version,
249
- chainId: this.chainId,
250
- }),
251
- ),
252
- new Body([txEffect]),
253
- );
265
+ const globals = makeGlobalVariables(undefined, {
266
+ blockNumber,
267
+ timestamp: this.nextBlockTimestamp,
268
+ version: this.version,
269
+ chainId: this.chainId,
270
+ });
271
+ const block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
254
272
 
255
273
  await forkedWorldTrees.close();
256
274
 
@@ -268,10 +286,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
268
286
  isStaticCall: boolean = false,
269
287
  ) {
270
288
  this.logger.verbose(
271
- `Executing external function ${await this.contractDataProvider.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
289
+ `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
272
290
  );
273
291
 
274
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
292
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
275
293
  if (!artifact) {
276
294
  const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
277
295
  ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
@@ -279,51 +297,77 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
279
297
  throw new Error(message);
280
298
  }
281
299
 
300
+ // When `from` is the zero address (used when creating a new contract account for example),
301
+ // we disable scope filtering by setting effectiveScopes to undefined. This allows these operations
302
+ // to proceed without requiring keys registered for the zero address.
303
+ const effectiveScopes = from.isZero() ? undefined : [from];
304
+
305
+ // Sync notes before executing private function to discover notes from previous transactions
306
+ const utilityExecutor = async (call: FunctionCall) => {
307
+ await this.executeUtilityCall(call, effectiveScopes);
308
+ };
309
+
310
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
311
+ await this.stateMachine.contractSyncService.ensureContractSynced(
312
+ targetContractAddress,
313
+ functionSelector,
314
+ utilityExecutor,
315
+ blockHeader,
316
+ this.jobId,
317
+ );
318
+
282
319
  const blockNumber = await this.txeGetNextBlockNumber();
283
320
 
284
321
  const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
285
322
 
286
323
  const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
287
-
288
324
  const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
289
-
290
325
  const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
291
326
 
292
327
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
293
328
 
294
- const blockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
295
-
296
329
  const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
297
330
  const noteCache = new ExecutionNoteCache(protocolNullifier);
331
+ // In production, the account contract sets the min revertible counter before calling the app function.
332
+ // Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
333
+ // marking all side effects as revertible.
334
+ const minRevertibleSideEffectCounter = 1;
335
+ await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
298
336
  const taggingIndexCache = new ExecutionTaggingIndexCache();
299
337
 
300
338
  const simulator = new WASMSimulator();
301
339
 
302
- const privateExecutionOracle = new PrivateExecutionOracle(
340
+ const privateExecutionOracle = new PrivateExecutionOracle({
303
341
  argsHash,
304
342
  txContext,
305
343
  callContext,
306
- /** Header of a block whose state is used during private execution (not the block the transaction is included in). */
307
- blockHeader,
308
- /** List of transient auth witnesses to be used during this simulation */
309
- Array.from(this.authwits.values()),
310
- /** List of transient auth witnesses to be used during this simulation */
311
- [],
312
- HashedValuesCache.create([new HashedValues(args, argsHash)]),
344
+ anchorBlockHeader: blockHeader,
345
+ utilityExecutor,
346
+ authWitnesses: Array.from(this.authwits.values()),
347
+ capsules: [],
348
+ executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
313
349
  noteCache,
314
350
  taggingIndexCache,
315
- this.pxeOracleInterface,
316
- 0,
317
- 1,
318
- undefined, // log
319
- undefined, // scopes
320
- /**
321
- * In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
322
- * contract would perform, including setting senderForTags.
323
- */
324
- from,
351
+ contractStore: this.contractStore,
352
+ noteStore: this.noteStore,
353
+ keyStore: this.keyStore,
354
+ addressStore: this.addressStore,
355
+ aztecNode: this.stateMachine.node,
356
+ senderTaggingStore: this.senderTaggingStore,
357
+ recipientTaggingStore: this.recipientTaggingStore,
358
+ senderAddressBookStore: this.senderAddressBookStore,
359
+ capsuleStore: this.capsuleStore,
360
+ privateEventStore: this.privateEventStore,
361
+ contractSyncService: this.stateMachine.contractSyncService,
362
+ jobId: this.jobId,
363
+ totalPublicCalldataCount: 0,
364
+ sideEffectCounter: minRevertibleSideEffectCounter,
365
+ scopes: effectiveScopes,
366
+ // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
367
+ // contract would perform, including setting senderForTags.
368
+ senderForTags: from,
325
369
  simulator,
326
- );
370
+ });
327
371
 
328
372
  // 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.
329
373
  let result: PrivateExecutionResult;
@@ -350,19 +394,22 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
350
394
  }),
351
395
  );
352
396
 
353
- // TXE's top level context does not track side effect counters, and as such, minRevertibleSideEffectCounter is always 0.
354
- // This has the unfortunate consequence of always producing revertible nullifiers, which means we
355
- // must set the firstNullifierHint to Fr.ZERO so the txRequestHash is always used as nonce generator
356
- result = new PrivateExecutionResult(executionResult, Fr.ZERO, publicFunctionsCalldata);
397
+ noteCache.finish();
398
+ const nonceGenerator = noteCache.getNonceGenerator();
399
+ result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
357
400
  } catch (err) {
358
401
  throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
359
402
  }
360
403
 
361
- // According to the protocol rules, the nonce generator for the note hashes
362
- // can either be the first nullifier in the tx or the hash of the initial tx request
363
- // if there are none.
364
- const nonceGenerator = result.firstNullifier.equals(Fr.ZERO) ? protocolNullifier : result.firstNullifier;
365
- const { publicInputs } = await generateSimulatedProvingResult(result, nonceGenerator, this.contractDataProvider);
404
+ // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
405
+ // the nonce generator for the note hashes.
406
+ // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
407
+ const { publicInputs } = await generateSimulatedProvingResult(
408
+ result,
409
+ (addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
410
+ this.stateMachine.node,
411
+ minRevertibleSideEffectCounter,
412
+ );
366
413
 
367
414
  const globals = makeGlobalVariables();
368
415
  globals.blockNumber = blockNumber;
@@ -373,7 +420,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
373
420
 
374
421
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
375
422
 
376
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
423
+ const bindings = this.logger.getBindings();
424
+ const contractsDB = new PublicContractsDB(
425
+ new TXEPublicContractDataSource(blockNumber, this.contractStore),
426
+ bindings,
427
+ );
377
428
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
378
429
  const config = PublicSimulatorConfig.from({
379
430
  skipFeeEnforcement: true,
@@ -386,8 +437,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
386
437
  globals,
387
438
  guardedMerkleTrees,
388
439
  contractsDB,
389
- new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
440
+ new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
390
441
  new TestDateProvider(),
442
+ undefined,
443
+ createLogger('simulator:public-processor', bindings),
391
444
  );
392
445
 
393
446
  const tx = await Tx.create({
@@ -412,7 +465,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
412
465
  } else if (!processedTx.revertCode.isOK()) {
413
466
  if (processedTx.revertReason) {
414
467
  try {
415
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
468
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
416
469
  // eslint-disable-next-line no-empty
417
470
  } catch {}
418
471
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -441,13 +494,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
441
494
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
442
495
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
443
496
 
444
- const body = new Body([txEffect]);
445
-
446
- const l2Block = new L2Block(
447
- makeAppendOnlyTreeSnapshot(),
448
- await makeTXEBlockHeader(forkedWorldTrees, globals),
449
- body,
450
- );
497
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
451
498
 
452
499
  await this.stateMachine.handleL2Block(l2Block);
453
500
 
@@ -463,7 +510,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
463
510
  isStaticCall: boolean,
464
511
  ) {
465
512
  this.logger.verbose(
466
- `Executing public function ${await this.contractDataProvider.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
513
+ `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
467
514
  );
468
515
 
469
516
  const blockNumber = await this.txeGetNextBlockNumber();
@@ -476,7 +523,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
476
523
 
477
524
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
478
525
 
479
- const anchorBlockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
526
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
480
527
 
481
528
  const calldataHash = await computeCalldataHash(calldata);
482
529
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
@@ -490,7 +537,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
490
537
 
491
538
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
492
539
 
493
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
540
+ const bindings2 = this.logger.getBindings();
541
+ const contractsDB = new PublicContractsDB(
542
+ new TXEPublicContractDataSource(blockNumber, this.contractStore),
543
+ bindings2,
544
+ );
494
545
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
495
546
  const config = PublicSimulatorConfig.from({
496
547
  skipFeeEnforcement: true,
@@ -499,8 +550,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
499
550
  collectStatistics: false,
500
551
  collectCallMetadata: true,
501
552
  });
502
- const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
503
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
553
+ const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
554
+ const processor = new PublicProcessor(
555
+ globals,
556
+ guardedMerkleTrees,
557
+ contractsDB,
558
+ simulator,
559
+ new TestDateProvider(),
560
+ undefined,
561
+ createLogger('simulator:public-processor', bindings2),
562
+ );
504
563
 
505
564
  // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
506
565
  // kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
@@ -558,7 +617,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
558
617
  } else if (!processedTx.revertCode.isOK()) {
559
618
  if (processedTx.revertReason) {
560
619
  try {
561
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
620
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
562
621
  // eslint-disable-next-line no-empty
563
622
  } catch {}
564
623
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -590,13 +649,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
590
649
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
591
650
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
592
651
 
593
- const body = new Body([txEffect]);
594
-
595
- const l2Block = new L2Block(
596
- makeAppendOnlyTreeSnapshot(),
597
- await makeTXEBlockHeader(forkedWorldTrees, globals),
598
- body,
599
- );
652
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
600
653
 
601
654
  await this.stateMachine.handleL2Block(l2Block);
602
655
 
@@ -610,18 +663,39 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
610
663
  functionSelector: FunctionSelector,
611
664
  args: Fr[],
612
665
  ) {
613
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
666
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
614
667
  if (!artifact) {
615
668
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
616
669
  }
617
670
 
618
- const call = {
671
+ // Sync notes before executing utility function to discover notes from previous transactions
672
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
673
+ await this.stateMachine.contractSyncService.ensureContractSynced(
674
+ targetContractAddress,
675
+ functionSelector,
676
+ async call => {
677
+ await this.executeUtilityCall(call);
678
+ },
679
+ blockHeader,
680
+ this.jobId,
681
+ );
682
+
683
+ const call = FunctionCall.from({
619
684
  name: artifact.name,
620
- selector: functionSelector,
621
685
  to: targetContractAddress,
622
- };
686
+ selector: functionSelector,
687
+ type: FunctionType.UTILITY,
688
+ hideMsgSender: false,
689
+ isStatic: false,
690
+ args,
691
+ returnTypes: [],
692
+ });
693
+
694
+ return this.executeUtilityCall(call);
695
+ }
623
696
 
624
- const entryPointArtifact = await this.pxeOracleInterface.getFunctionArtifact(call.to, call.selector);
697
+ private async executeUtilityCall(call: FunctionCall, scopes?: AztecAddress[]): Promise<Fr[]> {
698
+ const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
625
699
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
626
700
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
627
701
  }
@@ -632,9 +706,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
632
706
  });
633
707
 
634
708
  try {
635
- const oracle = new UtilityExecutionOracle(call.to, [], [], this.pxeOracleInterface);
709
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
710
+ const oracle = new UtilityExecutionOracle({
711
+ contractAddress: call.to,
712
+ authWitnesses: [],
713
+ capsules: [],
714
+ anchorBlockHeader,
715
+ contractStore: this.contractStore,
716
+ noteStore: this.noteStore,
717
+ keyStore: this.keyStore,
718
+ addressStore: this.addressStore,
719
+ aztecNode: this.stateMachine.node,
720
+ recipientTaggingStore: this.recipientTaggingStore,
721
+ senderAddressBookStore: this.senderAddressBookStore,
722
+ capsuleStore: this.capsuleStore,
723
+ privateEventStore: this.privateEventStore,
724
+ jobId: this.jobId,
725
+ scopes,
726
+ });
636
727
  const acirExecutionResult = await new WASMSimulator()
637
- .executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
728
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
638
729
  .catch((err: Error) => {
639
730
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
640
731
  throw new ExecutionError(