@aztec/txe 0.0.1-commit.b655e406 → 0.0.1-commit.bf2612ae

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 (83) hide show
  1. package/dest/bin/index.d.ts +1 -1
  2. package/dest/constants.d.ts +3 -0
  3. package/dest/constants.d.ts.map +1 -0
  4. package/dest/constants.js +2 -0
  5. package/dest/index.d.ts +1 -1
  6. package/dest/index.d.ts.map +1 -1
  7. package/dest/index.js +3 -2
  8. package/dest/oracle/interfaces.d.ts +10 -7
  9. package/dest/oracle/interfaces.d.ts.map +1 -1
  10. package/dest/oracle/txe_oracle_public_context.d.ts +6 -6
  11. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  12. package/dest/oracle/txe_oracle_public_context.js +7 -8
  13. package/dest/oracle/txe_oracle_top_level_context.d.ts +22 -12
  14. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  15. package/dest/oracle/txe_oracle_top_level_context.js +125 -79
  16. package/dest/rpc_translator.d.ts +30 -15
  17. package/dest/rpc_translator.d.ts.map +1 -1
  18. package/dest/rpc_translator.js +110 -47
  19. package/dest/state_machine/archiver.d.ts +21 -51
  20. package/dest/state_machine/archiver.d.ts.map +1 -1
  21. package/dest/state_machine/archiver.js +61 -94
  22. package/dest/state_machine/dummy_p2p_client.d.ts +9 -6
  23. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  24. package/dest/state_machine/dummy_p2p_client.js +16 -8
  25. package/dest/state_machine/global_variable_builder.d.ts +6 -4
  26. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  27. package/dest/state_machine/global_variable_builder.js +13 -1
  28. package/dest/state_machine/index.d.ts +5 -5
  29. package/dest/state_machine/index.d.ts.map +1 -1
  30. package/dest/state_machine/index.js +31 -19
  31. package/dest/state_machine/mock_epoch_cache.d.ts +12 -10
  32. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  33. package/dest/state_machine/mock_epoch_cache.js +17 -13
  34. package/dest/state_machine/synchronizer.d.ts +3 -2
  35. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  36. package/dest/state_machine/synchronizer.js +5 -4
  37. package/dest/txe_session.d.ts +21 -13
  38. package/dest/txe_session.d.ts.map +1 -1
  39. package/dest/txe_session.js +97 -48
  40. package/dest/util/encoding.d.ts +615 -16
  41. package/dest/util/encoding.d.ts.map +1 -1
  42. package/dest/util/encoding.js +1 -1
  43. package/dest/util/expected_failure_error.d.ts +1 -1
  44. package/dest/util/expected_failure_error.d.ts.map +1 -1
  45. package/dest/util/txe_account_store.d.ts +10 -0
  46. package/dest/util/txe_account_store.d.ts.map +1 -0
  47. package/dest/util/{txe_account_data_provider.js → txe_account_store.js} +1 -1
  48. package/dest/util/txe_contract_store.d.ts +12 -0
  49. package/dest/util/txe_contract_store.d.ts.map +1 -0
  50. package/dest/util/{txe_contract_data_provider.js → txe_contract_store.js} +3 -3
  51. package/dest/util/txe_public_contract_data_source.d.ts +7 -6
  52. package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
  53. package/dest/util/txe_public_contract_data_source.js +11 -11
  54. package/dest/utils/block_creation.d.ts +21 -6
  55. package/dest/utils/block_creation.d.ts.map +1 -1
  56. package/dest/utils/block_creation.js +36 -4
  57. package/dest/utils/tx_effect_creation.d.ts +3 -3
  58. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  59. package/dest/utils/tx_effect_creation.js +4 -7
  60. package/package.json +18 -17
  61. package/src/constants.ts +3 -0
  62. package/src/index.ts +15 -12
  63. package/src/oracle/interfaces.ts +9 -6
  64. package/src/oracle/txe_oracle_public_context.ts +9 -14
  65. package/src/oracle/txe_oracle_top_level_context.ts +175 -105
  66. package/src/rpc_translator.ts +136 -58
  67. package/src/state_machine/archiver.ts +61 -117
  68. package/src/state_machine/dummy_p2p_client.ts +22 -10
  69. package/src/state_machine/global_variable_builder.ts +22 -4
  70. package/src/state_machine/index.ts +40 -17
  71. package/src/state_machine/mock_epoch_cache.ts +20 -20
  72. package/src/state_machine/synchronizer.ts +6 -5
  73. package/src/txe_session.ts +195 -82
  74. package/src/util/encoding.ts +1 -1
  75. package/src/util/{txe_account_data_provider.ts → txe_account_store.ts} +1 -1
  76. package/src/util/{txe_contract_data_provider.ts → txe_contract_store.ts} +3 -3
  77. package/src/util/txe_public_contract_data_source.ts +13 -12
  78. package/src/utils/block_creation.ts +47 -14
  79. package/src/utils/tx_effect_creation.ts +5 -12
  80. package/dest/util/txe_account_data_provider.d.ts +0 -10
  81. package/dest/util/txe_account_data_provider.d.ts.map +0 -1
  82. package/dest/util/txe_contract_data_provider.d.ts +0 -12
  83. package/dest/util/txe_contract_data_provider.d.ts.map +0 -1
@@ -6,16 +6,23 @@ import {
6
6
  DEFAULT_TEARDOWN_L2_GAS_LIMIT,
7
7
  NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
8
8
  } from '@aztec/constants';
9
- import { Schnorr } from '@aztec/foundation/crypto';
10
- import { Fr } from '@aztec/foundation/fields';
9
+ import { BlockNumber } from '@aztec/foundation/branded-types';
10
+ import { Schnorr } from '@aztec/foundation/crypto/schnorr';
11
+ import { Fr } from '@aztec/foundation/curves/bn254';
11
12
  import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@aztec/foundation/log';
12
13
  import { TestDateProvider } from '@aztec/foundation/timer';
13
14
  import type { KeyStore } from '@aztec/key-store';
14
15
  import {
15
- AddressDataProvider,
16
+ AddressStore,
17
+ CapsuleStore,
18
+ NoteStore,
16
19
  ORACLE_VERSION,
17
- PXEOracleInterface,
20
+ PrivateEventStore,
21
+ RecipientTaggingStore,
22
+ SenderAddressBookStore,
23
+ SenderTaggingStore,
18
24
  enrichPublicSimulationError,
25
+ syncState,
19
26
  } from '@aztec/pxe/server';
20
27
  import {
21
28
  ExecutionNoteCache,
@@ -38,18 +45,18 @@ import {
38
45
  witnessMapToFields,
39
46
  } from '@aztec/simulator/client';
40
47
  import {
48
+ CppPublicTxSimulator,
41
49
  GuardedMerkleTreeOperations,
42
50
  PublicContractsDB,
43
51
  PublicProcessor,
44
- PublicTxSimulator,
45
52
  } from '@aztec/simulator/server';
46
- import { type ContractArtifact, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
53
+ import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
47
54
  import { AuthWitness } from '@aztec/stdlib/auth-witness';
55
+ import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
48
56
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
49
- import { Body, L2Block } from '@aztec/stdlib/block';
50
57
  import { type ContractInstanceWithAddress, computePartialAddress } from '@aztec/stdlib/contract';
51
58
  import { Gas, GasFees, GasSettings } from '@aztec/stdlib/gas';
52
- import { computeCalldataHash, siloNullifier } from '@aztec/stdlib/hash';
59
+ import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
53
60
  import {
54
61
  PartialPrivateTailPublicInputsForPublic,
55
62
  PrivateKernelTailCircuitPublicInputs,
@@ -57,7 +64,7 @@ import {
57
64
  PublicCallRequest,
58
65
  } from '@aztec/stdlib/kernel';
59
66
  import { ChonkProof } from '@aztec/stdlib/proofs';
60
- import { makeAppendOnlyTreeSnapshot, makeGlobalVariables } from '@aztec/stdlib/testing';
67
+ import { makeGlobalVariables } from '@aztec/stdlib/testing';
61
68
  import { MerkleTreeId } from '@aztec/stdlib/trees';
62
69
  import {
63
70
  CallContext,
@@ -74,15 +81,12 @@ import {
74
81
  import type { UInt64 } from '@aztec/stdlib/types';
75
82
  import { ForkCheckpoint } from '@aztec/world-state';
76
83
 
84
+ import { DEFAULT_ADDRESS } from '../constants.js';
77
85
  import type { TXEStateMachine } from '../state_machine/index.js';
78
- import type { TXEAccountDataProvider } from '../util/txe_account_data_provider.js';
79
- import type { TXEContractDataProvider } from '../util/txe_contract_data_provider.js';
86
+ import type { TXEAccountStore } from '../util/txe_account_store.js';
87
+ import type { TXEContractStore } from '../util/txe_contract_store.js';
80
88
  import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
81
- import {
82
- getSingleTxBlockRequestHash,
83
- insertTxEffectIntoWorldTrees,
84
- makeTXEBlockHeader,
85
- } from '../utils/block_creation.js';
89
+ import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
86
90
  import type { ITxeExecutionOracle } from './interfaces.js';
87
91
 
88
92
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
@@ -93,11 +97,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
93
97
 
94
98
  constructor(
95
99
  private stateMachine: TXEStateMachine,
96
- private contractDataProvider: TXEContractDataProvider,
100
+ private contractStore: TXEContractStore,
101
+ private noteStore: NoteStore,
97
102
  private keyStore: KeyStore,
98
- private addressDataProvider: AddressDataProvider,
99
- private accountDataProvider: TXEAccountDataProvider,
100
- private pxeOracleInterface: PXEOracleInterface,
103
+ private addressStore: AddressStore,
104
+ private accountStore: TXEAccountStore,
105
+ private senderTaggingStore: SenderTaggingStore,
106
+ private recipientTaggingStore: RecipientTaggingStore,
107
+ private senderAddressBookStore: SenderAddressBookStore,
108
+ private capsuleStore: CapsuleStore,
109
+ private privateEventStore: PrivateEventStore,
110
+ private jobId: string,
101
111
  private nextBlockTimestamp: bigint,
102
112
  private version: Fr,
103
113
  private chainId: Fr,
@@ -131,8 +141,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
131
141
  this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
132
142
  }
133
143
 
134
- async txeGetNextBlockNumber(): Promise<number> {
135
- return (await this.getLastBlockNumber()) + 1;
144
+ txeGetDefaultAddress(): AztecAddress {
145
+ return DEFAULT_ADDRESS;
146
+ }
147
+
148
+ async txeGetNextBlockNumber(): Promise<BlockNumber> {
149
+ return BlockNumber((await this.getLastBlockNumber()) + 1);
136
150
  }
137
151
 
138
152
  txeGetNextBlockTimestamp(): Promise<bigint> {
@@ -144,7 +158,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
144
158
  }
145
159
 
146
160
  async txeGetLastTxEffects() {
147
- 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);
148
163
 
149
164
  if (block!.body.txEffects.length != 1) {
150
165
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -156,6 +171,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
156
171
  return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
157
172
  }
158
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
+
159
185
  async txeAdvanceBlocksBy(blocks: number) {
160
186
  this.logger.debug(`time traveling ${blocks} blocks`);
161
187
 
@@ -183,8 +209,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
183
209
  if (!secret.equals(Fr.ZERO)) {
184
210
  await this.txeAddAccount(artifact, instance, secret);
185
211
  } else {
186
- await this.contractDataProvider.addContractInstance(instance);
187
- await this.contractDataProvider.addContractArtifact(instance.currentContractClassId, artifact);
212
+ await this.contractStore.addContractInstance(instance);
213
+ await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
188
214
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
189
215
  }
190
216
  }
@@ -193,29 +219,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
193
219
  const partialAddress = await computePartialAddress(instance);
194
220
 
195
221
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
196
- await this.contractDataProvider.addContractInstance(instance);
197
- await this.contractDataProvider.addContractArtifact(instance.currentContractClassId, artifact);
222
+ await this.contractStore.addContractInstance(instance);
223
+ await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
198
224
 
199
225
  const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
200
- await this.accountDataProvider.setAccount(completeAddress.address, completeAddress);
201
- await this.addressDataProvider.addCompleteAddress(completeAddress);
226
+ await this.accountStore.setAccount(completeAddress.address, completeAddress);
227
+ await this.addressStore.addCompleteAddress(completeAddress);
202
228
  this.logger.debug(`Created account ${completeAddress.address}`);
203
229
 
204
230
  return completeAddress;
205
231
  }
206
232
 
207
233
  async txeCreateAccount(secret: Fr) {
208
- // This is a footgun !
234
+ // This is a foot gun !
209
235
  const completeAddress = await this.keyStore.addAccount(secret, secret);
210
- await this.accountDataProvider.setAccount(completeAddress.address, completeAddress);
211
- await this.addressDataProvider.addCompleteAddress(completeAddress);
236
+ await this.accountStore.setAccount(completeAddress.address, completeAddress);
237
+ await this.addressStore.addCompleteAddress(completeAddress);
212
238
  this.logger.debug(`Created account ${completeAddress.address}`);
213
239
 
214
240
  return completeAddress;
215
241
  }
216
242
 
217
243
  async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
218
- const account = await this.accountDataProvider.getAccount(address);
244
+ const account = await this.accountStore.getAccount(address);
219
245
  const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
220
246
 
221
247
  const schnorr = new Schnorr();
@@ -236,19 +262,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
236
262
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
237
263
  await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
238
264
 
239
- const block = new L2Block(
240
- makeAppendOnlyTreeSnapshot(),
241
- await makeTXEBlockHeader(
242
- forkedWorldTrees,
243
- makeGlobalVariables(undefined, {
244
- blockNumber,
245
- timestamp: this.nextBlockTimestamp,
246
- version: this.version,
247
- chainId: this.chainId,
248
- }),
249
- ),
250
- new Body([txEffect]),
251
- );
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]);
252
272
 
253
273
  await forkedWorldTrees.close();
254
274
 
@@ -266,10 +286,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
266
286
  isStaticCall: boolean = false,
267
287
  ) {
268
288
  this.logger.verbose(
269
- `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}`,
270
290
  );
271
291
 
272
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
292
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
273
293
  if (!artifact) {
274
294
  const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
275
295
  ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
@@ -277,22 +297,32 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
277
297
  throw new Error(message);
278
298
  }
279
299
 
300
+ // Sync notes before executing private function to discover notes from previous transactions
301
+ const utilityExecutor = async (call: FunctionCall) => {
302
+ await this.executeUtilityCall(call);
303
+ };
304
+
305
+ await syncState(targetContractAddress, this.contractStore, functionSelector, utilityExecutor);
306
+
280
307
  const blockNumber = await this.txeGetNextBlockNumber();
281
308
 
282
309
  const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
283
310
 
284
311
  const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
285
-
286
312
  const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
287
-
288
313
  const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
289
314
 
290
315
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
291
316
 
292
- const blockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
317
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
293
318
 
294
- const txRequestHash = getSingleTxBlockRequestHash(blockNumber);
295
- const noteCache = new ExecutionNoteCache(txRequestHash);
319
+ const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
320
+ const noteCache = new ExecutionNoteCache(protocolNullifier);
321
+ // In production, the account contract sets the min revertible counter before calling the app function.
322
+ // Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
323
+ // marking all side effects as revertible.
324
+ const minRevertibleSideEffectCounter = 1;
325
+ await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
296
326
  const taggingIndexCache = new ExecutionTaggingIndexCache();
297
327
 
298
328
  const simulator = new WASMSimulator();
@@ -303,6 +333,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
303
333
  callContext,
304
334
  /** Header of a block whose state is used during private execution (not the block the transaction is included in). */
305
335
  blockHeader,
336
+ utilityExecutor,
306
337
  /** List of transient auth witnesses to be used during this simulation */
307
338
  Array.from(this.authwits.values()),
308
339
  /** List of transient auth witnesses to be used during this simulation */
@@ -310,9 +341,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
310
341
  HashedValuesCache.create([new HashedValues(args, argsHash)]),
311
342
  noteCache,
312
343
  taggingIndexCache,
313
- this.pxeOracleInterface,
314
- 0,
315
- 1,
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
316
358
  undefined, // log
317
359
  undefined, // scopes
318
360
  /**
@@ -348,19 +390,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
348
390
  }),
349
391
  );
350
392
 
351
- // TXE's top level context does not track side effect counters, and as such, minRevertibleSideEffectCounter is always 0.
352
- // This has the unfortunate consequence of always producing revertible nullifiers, which means we
353
- // must set the firstNullifierHint to Fr.ZERO so the txRequestHash is always used as nonce generator
354
- result = new PrivateExecutionResult(executionResult, Fr.ZERO, publicFunctionsCalldata);
393
+ noteCache.finish();
394
+ const nonceGenerator = noteCache.getNonceGenerator();
395
+ result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
355
396
  } catch (err) {
356
397
  throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
357
398
  }
358
399
 
359
- // According to the protocol rules, the nonce generator for the note hashes
360
- // can either be the first nullifier in the tx or the hash of the initial tx request
361
- // if there are none.
362
- const nonceGenerator = result.firstNullifier.equals(Fr.ZERO) ? txRequestHash : result.firstNullifier;
363
- const { publicInputs } = await generateSimulatedProvingResult(result, nonceGenerator, this.contractDataProvider);
400
+ // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
401
+ // the nonce generator for the note hashes.
402
+ // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
403
+ const { publicInputs } = await generateSimulatedProvingResult(
404
+ result,
405
+ this.contractStore,
406
+ minRevertibleSideEffectCounter,
407
+ );
364
408
 
365
409
  const globals = makeGlobalVariables();
366
410
  globals.blockNumber = blockNumber;
@@ -371,16 +415,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
371
415
 
372
416
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
373
417
 
374
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
418
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
375
419
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
420
+ const config = PublicSimulatorConfig.from({
421
+ skipFeeEnforcement: true,
422
+ collectDebugLogs: true,
423
+ collectHints: false,
424
+ collectStatistics: false,
425
+ collectCallMetadata: true,
426
+ });
376
427
  const processor = new PublicProcessor(
377
428
  globals,
378
429
  guardedMerkleTrees,
379
430
  contractsDB,
380
- new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, {
381
- doMerkleOperations: true,
382
- skipFeeEnforcement: true,
383
- }),
431
+ new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
384
432
  new TestDateProvider(),
385
433
  );
386
434
 
@@ -406,7 +454,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
406
454
  } else if (!processedTx.revertCode.isOK()) {
407
455
  if (processedTx.revertReason) {
408
456
  try {
409
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
457
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
410
458
  // eslint-disable-next-line no-empty
411
459
  } catch {}
412
460
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -435,13 +483,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
435
483
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
436
484
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
437
485
 
438
- const body = new Body([txEffect]);
439
-
440
- const l2Block = new L2Block(
441
- makeAppendOnlyTreeSnapshot(),
442
- await makeTXEBlockHeader(forkedWorldTrees, globals),
443
- body,
444
- );
486
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
445
487
 
446
488
  await this.stateMachine.handleL2Block(l2Block);
447
489
 
@@ -457,7 +499,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
457
499
  isStaticCall: boolean,
458
500
  ) {
459
501
  this.logger.verbose(
460
- `Executing public function ${await this.contractDataProvider.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
502
+ `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
461
503
  );
462
504
 
463
505
  const blockNumber = await this.txeGetNextBlockNumber();
@@ -470,7 +512,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
470
512
 
471
513
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
472
514
 
473
- const anchorBlockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
515
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
474
516
 
475
517
  const calldataHash = await computeCalldataHash(calldata);
476
518
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
@@ -484,12 +526,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
484
526
 
485
527
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
486
528
 
487
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
529
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
488
530
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
489
- const simulator = new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, {
490
- doMerkleOperations: true,
531
+ const config = PublicSimulatorConfig.from({
491
532
  skipFeeEnforcement: true,
533
+ collectDebugLogs: true,
534
+ collectHints: false,
535
+ collectStatistics: false,
536
+ collectCallMetadata: true,
492
537
  });
538
+ const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
493
539
  const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
494
540
 
495
541
  // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
@@ -497,9 +543,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
497
543
  // side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
498
544
  // unique.
499
545
  const nonRevertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
500
- if (!isStaticCall) {
501
- nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
502
- }
546
+ nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
503
547
 
504
548
  // The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
505
549
  // may require producing reverts.
@@ -550,7 +594,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
550
594
  } else if (!processedTx.revertCode.isOK()) {
551
595
  if (processedTx.revertReason) {
552
596
  try {
553
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
597
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
554
598
  // eslint-disable-next-line no-empty
555
599
  } catch {}
556
600
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -582,13 +626,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
582
626
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
583
627
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
584
628
 
585
- const body = new Body([txEffect]);
586
-
587
- const l2Block = new L2Block(
588
- makeAppendOnlyTreeSnapshot(),
589
- await makeTXEBlockHeader(forkedWorldTrees, globals),
590
- body,
591
- );
629
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
592
630
 
593
631
  await this.stateMachine.handleL2Block(l2Block);
594
632
 
@@ -602,18 +640,32 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
602
640
  functionSelector: FunctionSelector,
603
641
  args: Fr[],
604
642
  ) {
605
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
643
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
606
644
  if (!artifact) {
607
645
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
608
646
  }
609
647
 
610
- const call = {
611
- name: artifact.name,
612
- selector: functionSelector,
613
- to: targetContractAddress,
614
- };
648
+ // 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
+ });
615
652
 
616
- const entryPointArtifact = await this.pxeOracleInterface.getFunctionArtifact(call.to, call.selector);
653
+ const call = new FunctionCall(
654
+ artifact.name,
655
+ targetContractAddress,
656
+ functionSelector,
657
+ FunctionType.UTILITY,
658
+ false,
659
+ false,
660
+ args,
661
+ [],
662
+ );
663
+
664
+ return this.executeUtilityCall(call);
665
+ }
666
+
667
+ private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
668
+ const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
617
669
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
618
670
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
619
671
  }
@@ -624,9 +676,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
624
676
  });
625
677
 
626
678
  try {
627
- const oracle = new UtilityExecutionOracle(call.to, [], [], this.pxeOracleInterface);
679
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
680
+ const oracle = new UtilityExecutionOracle(
681
+ call.to,
682
+ [],
683
+ [],
684
+ 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
+ );
628
697
  const acirExecutionResult = await new WASMSimulator()
629
- .executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
698
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
630
699
  .catch((err: Error) => {
631
700
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
632
701
  throw new ExecutionError(
@@ -652,7 +721,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
652
721
  return [this.nextBlockTimestamp, this.authwits];
653
722
  }
654
723
 
655
- private async getLastBlockNumber(): Promise<number> {
656
- return (await this.stateMachine.node.getBlockHeader('latest'))?.globalVariables.blockNumber ?? 0;
724
+ private async getLastBlockNumber(): Promise<BlockNumber> {
725
+ const header = await this.stateMachine.node.getBlockHeader('latest');
726
+ return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
657
727
  }
658
728
  }