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

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 (80) 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 +5 -3
  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 +4 -6
  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 +99 -62
  15. package/dest/rpc_translator.d.ts +15 -9
  16. package/dest/rpc_translator.d.ts.map +1 -1
  17. package/dest/rpc_translator.js +65 -25
  18. package/dest/state_machine/archiver.d.ts +21 -57
  19. package/dest/state_machine/archiver.d.ts.map +1 -1
  20. package/dest/state_machine/archiver.js +62 -107
  21. package/dest/state_machine/dummy_p2p_client.d.ts +8 -7
  22. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  23. package/dest/state_machine/dummy_p2p_client.js +16 -11
  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 +6 -6
  28. package/dest/state_machine/index.d.ts.map +1 -1
  29. package/dest/state_machine/index.js +23 -20
  30. package/dest/state_machine/mock_epoch_cache.d.ts +2 -1
  31. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  32. package/dest/state_machine/mock_epoch_cache.js +5 -1
  33. package/dest/state_machine/synchronizer.d.ts +1 -1
  34. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  35. package/dest/state_machine/synchronizer.js +2 -2
  36. package/dest/txe_session.d.ts +18 -10
  37. package/dest/txe_session.d.ts.map +1 -1
  38. package/dest/txe_session.js +90 -45
  39. package/dest/util/encoding.d.ts +618 -19
  40. package/dest/util/encoding.d.ts.map +1 -1
  41. package/dest/util/encoding.js +1 -1
  42. package/dest/util/txe_account_store.d.ts +10 -0
  43. package/dest/util/txe_account_store.d.ts.map +1 -0
  44. package/dest/util/{txe_account_data_provider.js → txe_account_store.js} +1 -1
  45. package/dest/util/txe_contract_store.d.ts +12 -0
  46. package/dest/util/txe_contract_store.d.ts.map +1 -0
  47. package/dest/util/{txe_contract_data_provider.js → txe_contract_store.js} +3 -3
  48. package/dest/util/txe_public_contract_data_source.d.ts +5 -5
  49. package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
  50. package/dest/util/txe_public_contract_data_source.js +11 -11
  51. package/dest/utils/block_creation.d.ts +19 -5
  52. package/dest/utils/block_creation.d.ts.map +1 -1
  53. package/dest/utils/block_creation.js +36 -4
  54. package/dest/utils/tx_effect_creation.d.ts +2 -3
  55. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  56. package/dest/utils/tx_effect_creation.js +4 -7
  57. package/package.json +16 -16
  58. package/src/constants.ts +3 -0
  59. package/src/index.ts +15 -12
  60. package/src/oracle/interfaces.ts +4 -2
  61. package/src/oracle/txe_oracle_public_context.ts +5 -10
  62. package/src/oracle/txe_oracle_top_level_context.ts +148 -88
  63. package/src/rpc_translator.ts +82 -28
  64. package/src/state_machine/archiver.ts +60 -130
  65. package/src/state_machine/dummy_p2p_client.ts +21 -14
  66. package/src/state_machine/global_variable_builder.ts +19 -2
  67. package/src/state_machine/index.ts +28 -19
  68. package/src/state_machine/mock_epoch_cache.ts +5 -0
  69. package/src/state_machine/synchronizer.ts +1 -2
  70. package/src/txe_session.ts +179 -76
  71. package/src/util/encoding.ts +1 -1
  72. package/src/util/{txe_account_data_provider.ts → txe_account_store.ts} +1 -1
  73. package/src/util/{txe_contract_data_provider.ts → txe_contract_store.ts} +3 -3
  74. package/src/util/txe_public_contract_data_source.ts +10 -10
  75. package/src/utils/block_creation.ts +46 -15
  76. package/src/utils/tx_effect_creation.ts +4 -12
  77. package/dest/util/txe_account_data_provider.d.ts +0 -10
  78. package/dest/util/txe_account_data_provider.d.ts.map +0 -1
  79. package/dest/util/txe_contract_data_provider.d.ts +0 -12
  80. package/dest/util/txe_contract_data_provider.d.ts.map +0 -1
@@ -7,15 +7,20 @@ import {
7
7
  NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
8
8
  } from '@aztec/constants';
9
9
  import { BlockNumber } from '@aztec/foundation/branded-types';
10
- import { Schnorr } from '@aztec/foundation/crypto';
11
- import { Fr } from '@aztec/foundation/fields';
10
+ import { Schnorr } from '@aztec/foundation/crypto/schnorr';
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
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,
@@ -133,6 +140,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
133
140
  this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
134
141
  }
135
142
 
143
+ txeGetDefaultAddress(): AztecAddress {
144
+ return DEFAULT_ADDRESS;
145
+ }
146
+
136
147
  async txeGetNextBlockNumber(): Promise<BlockNumber> {
137
148
  return BlockNumber((await this.getLastBlockNumber()) + 1);
138
149
  }
@@ -146,7 +157,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
146
157
  }
147
158
 
148
159
  async txeGetLastTxEffects() {
149
- const block = await this.stateMachine.archiver.getBlock('latest');
160
+ const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
161
+ const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
150
162
 
151
163
  if (block!.body.txEffects.length != 1) {
152
164
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -158,6 +170,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
158
170
  return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
159
171
  }
160
172
 
173
+ async txeGetPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
174
+ return (
175
+ await this.privateEventStore.getPrivateEvents(selector, {
176
+ contractAddress,
177
+ scopes: [scope],
178
+ fromBlock: 0,
179
+ toBlock: (await this.getLastBlockNumber()) + 1,
180
+ })
181
+ ).map(e => e.packedEvent);
182
+ }
183
+
161
184
  async txeAdvanceBlocksBy(blocks: number) {
162
185
  this.logger.debug(`time traveling ${blocks} blocks`);
163
186
 
@@ -185,8 +208,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
185
208
  if (!secret.equals(Fr.ZERO)) {
186
209
  await this.txeAddAccount(artifact, instance, secret);
187
210
  } else {
188
- await this.contractDataProvider.addContractInstance(instance);
189
- await this.contractDataProvider.addContractArtifact(instance.currentContractClassId, artifact);
211
+ await this.contractStore.addContractInstance(instance);
212
+ await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
190
213
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
191
214
  }
192
215
  }
@@ -195,29 +218,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
195
218
  const partialAddress = await computePartialAddress(instance);
196
219
 
197
220
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
198
- await this.contractDataProvider.addContractInstance(instance);
199
- await this.contractDataProvider.addContractArtifact(instance.currentContractClassId, artifact);
221
+ await this.contractStore.addContractInstance(instance);
222
+ await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
200
223
 
201
224
  const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
202
- await this.accountDataProvider.setAccount(completeAddress.address, completeAddress);
203
- await this.addressDataProvider.addCompleteAddress(completeAddress);
225
+ await this.accountStore.setAccount(completeAddress.address, completeAddress);
226
+ await this.addressStore.addCompleteAddress(completeAddress);
204
227
  this.logger.debug(`Created account ${completeAddress.address}`);
205
228
 
206
229
  return completeAddress;
207
230
  }
208
231
 
209
232
  async txeCreateAccount(secret: Fr) {
210
- // This is a footgun !
233
+ // This is a foot gun !
211
234
  const completeAddress = await this.keyStore.addAccount(secret, secret);
212
- await this.accountDataProvider.setAccount(completeAddress.address, completeAddress);
213
- await this.addressDataProvider.addCompleteAddress(completeAddress);
235
+ await this.accountStore.setAccount(completeAddress.address, completeAddress);
236
+ await this.addressStore.addCompleteAddress(completeAddress);
214
237
  this.logger.debug(`Created account ${completeAddress.address}`);
215
238
 
216
239
  return completeAddress;
217
240
  }
218
241
 
219
242
  async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
220
- const account = await this.accountDataProvider.getAccount(address);
243
+ const account = await this.accountStore.getAccount(address);
221
244
  const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
222
245
 
223
246
  const schnorr = new Schnorr();
@@ -238,19 +261,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
238
261
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
239
262
  await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
240
263
 
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
- );
264
+ const globals = makeGlobalVariables(undefined, {
265
+ blockNumber,
266
+ timestamp: this.nextBlockTimestamp,
267
+ version: this.version,
268
+ chainId: this.chainId,
269
+ });
270
+ const block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
254
271
 
255
272
  await forkedWorldTrees.close();
256
273
 
@@ -268,10 +285,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
268
285
  isStaticCall: boolean = false,
269
286
  ) {
270
287
  this.logger.verbose(
271
- `Executing external function ${await this.contractDataProvider.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
288
+ `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
272
289
  );
273
290
 
274
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
291
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
275
292
  if (!artifact) {
276
293
  const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
277
294
  ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
@@ -279,22 +296,32 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
279
296
  throw new Error(message);
280
297
  }
281
298
 
299
+ // Sync notes before executing private function to discover notes from previous transactions
300
+ const utilityExecutor = async (call: FunctionCall) => {
301
+ await this.executeUtilityCall(call);
302
+ };
303
+
304
+ await this.contractStore.syncPrivateState(targetContractAddress, functionSelector, utilityExecutor);
305
+
282
306
  const blockNumber = await this.txeGetNextBlockNumber();
283
307
 
284
308
  const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
285
309
 
286
310
  const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
287
-
288
311
  const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
289
-
290
312
  const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
291
313
 
292
314
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
293
315
 
294
- const blockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
316
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
295
317
 
296
318
  const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
297
319
  const noteCache = new ExecutionNoteCache(protocolNullifier);
320
+ // In production, the account contract sets the min revertible counter before calling the app function.
321
+ // Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
322
+ // marking all side effects as revertible.
323
+ const minRevertibleSideEffectCounter = 1;
324
+ await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
298
325
  const taggingIndexCache = new ExecutionTaggingIndexCache();
299
326
 
300
327
  const simulator = new WASMSimulator();
@@ -305,6 +332,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
305
332
  callContext,
306
333
  /** Header of a block whose state is used during private execution (not the block the transaction is included in). */
307
334
  blockHeader,
335
+ utilityExecutor,
308
336
  /** List of transient auth witnesses to be used during this simulation */
309
337
  Array.from(this.authwits.values()),
310
338
  /** List of transient auth witnesses to be used during this simulation */
@@ -312,9 +340,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
312
340
  HashedValuesCache.create([new HashedValues(args, argsHash)]),
313
341
  noteCache,
314
342
  taggingIndexCache,
315
- this.pxeOracleInterface,
316
- 0,
317
- 1,
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
318
357
  undefined, // log
319
358
  undefined, // scopes
320
359
  /**
@@ -350,19 +389,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
350
389
  }),
351
390
  );
352
391
 
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);
392
+ noteCache.finish();
393
+ const nonceGenerator = noteCache.getNonceGenerator();
394
+ result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
357
395
  } catch (err) {
358
396
  throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
359
397
  }
360
398
 
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);
399
+ // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
400
+ // the nonce generator for the note hashes.
401
+ // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
402
+ const { publicInputs } = await generateSimulatedProvingResult(
403
+ result,
404
+ this.contractStore,
405
+ minRevertibleSideEffectCounter,
406
+ );
366
407
 
367
408
  const globals = makeGlobalVariables();
368
409
  globals.blockNumber = blockNumber;
@@ -373,7 +414,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
373
414
 
374
415
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
375
416
 
376
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
417
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
377
418
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
378
419
  const config = PublicSimulatorConfig.from({
379
420
  skipFeeEnforcement: true,
@@ -412,7 +453,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
412
453
  } else if (!processedTx.revertCode.isOK()) {
413
454
  if (processedTx.revertReason) {
414
455
  try {
415
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
456
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
416
457
  // eslint-disable-next-line no-empty
417
458
  } catch {}
418
459
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -441,13 +482,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
441
482
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
442
483
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
443
484
 
444
- const body = new Body([txEffect]);
445
-
446
- const l2Block = new L2Block(
447
- makeAppendOnlyTreeSnapshot(),
448
- await makeTXEBlockHeader(forkedWorldTrees, globals),
449
- body,
450
- );
485
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
451
486
 
452
487
  await this.stateMachine.handleL2Block(l2Block);
453
488
 
@@ -463,7 +498,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
463
498
  isStaticCall: boolean,
464
499
  ) {
465
500
  this.logger.verbose(
466
- `Executing public function ${await this.contractDataProvider.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
501
+ `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
467
502
  );
468
503
 
469
504
  const blockNumber = await this.txeGetNextBlockNumber();
@@ -476,7 +511,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
476
511
 
477
512
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
478
513
 
479
- const anchorBlockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
514
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
480
515
 
481
516
  const calldataHash = await computeCalldataHash(calldata);
482
517
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
@@ -490,7 +525,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
490
525
 
491
526
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
492
527
 
493
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
528
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
494
529
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
495
530
  const config = PublicSimulatorConfig.from({
496
531
  skipFeeEnforcement: true,
@@ -558,7 +593,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
558
593
  } else if (!processedTx.revertCode.isOK()) {
559
594
  if (processedTx.revertReason) {
560
595
  try {
561
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
596
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
562
597
  // eslint-disable-next-line no-empty
563
598
  } catch {}
564
599
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -590,13 +625,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
590
625
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
591
626
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
592
627
 
593
- const body = new Body([txEffect]);
594
-
595
- const l2Block = new L2Block(
596
- makeAppendOnlyTreeSnapshot(),
597
- await makeTXEBlockHeader(forkedWorldTrees, globals),
598
- body,
599
- );
628
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
600
629
 
601
630
  await this.stateMachine.handleL2Block(l2Block);
602
631
 
@@ -610,18 +639,32 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
610
639
  functionSelector: FunctionSelector,
611
640
  args: Fr[],
612
641
  ) {
613
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
642
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
614
643
  if (!artifact) {
615
644
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
616
645
  }
617
646
 
618
- const call = {
619
- name: artifact.name,
620
- selector: functionSelector,
621
- to: targetContractAddress,
622
- };
647
+ // 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
+ });
623
651
 
624
- const entryPointArtifact = await this.pxeOracleInterface.getFunctionArtifact(call.to, call.selector);
652
+ const call = new FunctionCall(
653
+ artifact.name,
654
+ targetContractAddress,
655
+ functionSelector,
656
+ FunctionType.UTILITY,
657
+ false,
658
+ false,
659
+ args,
660
+ [],
661
+ );
662
+
663
+ return this.executeUtilityCall(call);
664
+ }
665
+
666
+ private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
667
+ const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
625
668
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
626
669
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
627
670
  }
@@ -632,9 +675,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
632
675
  });
633
676
 
634
677
  try {
635
- const oracle = new UtilityExecutionOracle(call.to, [], [], this.pxeOracleInterface);
678
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
679
+ const oracle = new UtilityExecutionOracle(
680
+ call.to,
681
+ [],
682
+ [],
683
+ 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
+ );
636
696
  const acirExecutionResult = await new WASMSimulator()
637
- .executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
697
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
638
698
  .catch((err: Error) => {
639
699
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
640
700
  throw new ExecutionError(