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

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 +11 -8
  9. package/dest/oracle/interfaces.d.ts.map +1 -1
  10. package/dest/oracle/txe_oracle_public_context.d.ts +7 -7
  11. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  12. package/dest/oracle/txe_oracle_public_context.js +10 -12
  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 +128 -80
  16. package/dest/rpc_translator.d.ts +31 -16
  17. package/dest/rpc_translator.d.ts.map +1 -1
  18. package/dest/rpc_translator.js +113 -51
  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 +10 -7
  64. package/src/oracle/txe_oracle_public_context.ts +12 -19
  65. package/src/oracle/txe_oracle_top_level_context.ts +194 -106
  66. package/src/rpc_translator.ts +139 -62
  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,17 +415,27 @@ 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 bindings = this.logger.getBindings();
419
+ const contractsDB = new PublicContractsDB(
420
+ new TXEPublicContractDataSource(blockNumber, this.contractStore),
421
+ bindings,
422
+ );
375
423
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
424
+ const config = PublicSimulatorConfig.from({
425
+ skipFeeEnforcement: true,
426
+ collectDebugLogs: true,
427
+ collectHints: false,
428
+ collectStatistics: false,
429
+ collectCallMetadata: true,
430
+ });
376
431
  const processor = new PublicProcessor(
377
432
  globals,
378
433
  guardedMerkleTrees,
379
434
  contractsDB,
380
- new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, {
381
- doMerkleOperations: true,
382
- skipFeeEnforcement: true,
383
- }),
435
+ new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
384
436
  new TestDateProvider(),
437
+ undefined,
438
+ createLogger('simulator:public-processor', bindings),
385
439
  );
386
440
 
387
441
  const tx = await Tx.create({
@@ -406,7 +460,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
406
460
  } else if (!processedTx.revertCode.isOK()) {
407
461
  if (processedTx.revertReason) {
408
462
  try {
409
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
463
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
410
464
  // eslint-disable-next-line no-empty
411
465
  } catch {}
412
466
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -435,13 +489,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
435
489
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
436
490
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
437
491
 
438
- const body = new Body([txEffect]);
439
-
440
- const l2Block = new L2Block(
441
- makeAppendOnlyTreeSnapshot(),
442
- await makeTXEBlockHeader(forkedWorldTrees, globals),
443
- body,
444
- );
492
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
445
493
 
446
494
  await this.stateMachine.handleL2Block(l2Block);
447
495
 
@@ -457,7 +505,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
457
505
  isStaticCall: boolean,
458
506
  ) {
459
507
  this.logger.verbose(
460
- `Executing public function ${await this.contractDataProvider.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
508
+ `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
461
509
  );
462
510
 
463
511
  const blockNumber = await this.txeGetNextBlockNumber();
@@ -470,7 +518,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
470
518
 
471
519
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
472
520
 
473
- const anchorBlockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
521
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
474
522
 
475
523
  const calldataHash = await computeCalldataHash(calldata);
476
524
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
@@ -484,22 +532,36 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
484
532
 
485
533
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
486
534
 
487
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
535
+ const bindings2 = this.logger.getBindings();
536
+ const contractsDB = new PublicContractsDB(
537
+ new TXEPublicContractDataSource(blockNumber, this.contractStore),
538
+ bindings2,
539
+ );
488
540
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
489
- const simulator = new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, {
490
- doMerkleOperations: true,
541
+ const config = PublicSimulatorConfig.from({
491
542
  skipFeeEnforcement: true,
543
+ collectDebugLogs: true,
544
+ collectHints: false,
545
+ collectStatistics: false,
546
+ collectCallMetadata: true,
492
547
  });
493
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
548
+ const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
549
+ const processor = new PublicProcessor(
550
+ globals,
551
+ guardedMerkleTrees,
552
+ contractsDB,
553
+ simulator,
554
+ new TestDateProvider(),
555
+ undefined,
556
+ createLogger('simulator:public-processor', bindings2),
557
+ );
494
558
 
495
559
  // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
496
560
  // kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
497
561
  // side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
498
562
  // unique.
499
563
  const nonRevertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
500
- if (!isStaticCall) {
501
- nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
502
- }
564
+ nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
503
565
 
504
566
  // The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
505
567
  // may require producing reverts.
@@ -550,7 +612,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
550
612
  } else if (!processedTx.revertCode.isOK()) {
551
613
  if (processedTx.revertReason) {
552
614
  try {
553
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
615
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
554
616
  // eslint-disable-next-line no-empty
555
617
  } catch {}
556
618
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -582,13 +644,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
582
644
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
583
645
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
584
646
 
585
- const body = new Body([txEffect]);
586
-
587
- const l2Block = new L2Block(
588
- makeAppendOnlyTreeSnapshot(),
589
- await makeTXEBlockHeader(forkedWorldTrees, globals),
590
- body,
591
- );
647
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
592
648
 
593
649
  await this.stateMachine.handleL2Block(l2Block);
594
650
 
@@ -602,18 +658,32 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
602
658
  functionSelector: FunctionSelector,
603
659
  args: Fr[],
604
660
  ) {
605
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
661
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
606
662
  if (!artifact) {
607
663
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
608
664
  }
609
665
 
610
- const call = {
611
- name: artifact.name,
612
- selector: functionSelector,
613
- to: targetContractAddress,
614
- };
666
+ // Sync notes before executing utility function to discover notes from previous transactions
667
+ await syncState(targetContractAddress, this.contractStore, functionSelector, async call => {
668
+ await this.executeUtilityCall(call);
669
+ });
670
+
671
+ const call = new FunctionCall(
672
+ artifact.name,
673
+ targetContractAddress,
674
+ functionSelector,
675
+ FunctionType.UTILITY,
676
+ false,
677
+ false,
678
+ args,
679
+ [],
680
+ );
615
681
 
616
- const entryPointArtifact = await this.pxeOracleInterface.getFunctionArtifact(call.to, call.selector);
682
+ return this.executeUtilityCall(call);
683
+ }
684
+
685
+ private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
686
+ const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
617
687
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
618
688
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
619
689
  }
@@ -624,9 +694,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
624
694
  });
625
695
 
626
696
  try {
627
- const oracle = new UtilityExecutionOracle(call.to, [], [], this.pxeOracleInterface);
697
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
698
+ const oracle = new UtilityExecutionOracle(
699
+ call.to,
700
+ [],
701
+ [],
702
+ anchorBlockHeader,
703
+ this.contractStore,
704
+ this.noteStore,
705
+ this.keyStore,
706
+ this.addressStore,
707
+ this.stateMachine.node,
708
+ this.stateMachine.anchorBlockStore,
709
+ this.recipientTaggingStore,
710
+ this.senderAddressBookStore,
711
+ this.capsuleStore,
712
+ this.privateEventStore,
713
+ this.jobId,
714
+ );
628
715
  const acirExecutionResult = await new WASMSimulator()
629
- .executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
716
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
630
717
  .catch((err: Error) => {
631
718
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
632
719
  throw new ExecutionError(
@@ -652,7 +739,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
652
739
  return [this.nextBlockTimestamp, this.authwits];
653
740
  }
654
741
 
655
- private async getLastBlockNumber(): Promise<number> {
656
- return (await this.stateMachine.node.getBlockHeader('latest'))?.globalVariables.blockNumber ?? 0;
742
+ private async getLastBlockNumber(): Promise<BlockNumber> {
743
+ const header = await this.stateMachine.node.getBlockHeader('latest');
744
+ return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
657
745
  }
658
746
  }