@aztec/txe 0.0.1-commit.24de95ac → 0.0.1-commit.2e2504e2

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 -79
  16. package/dest/rpc_translator.d.ts +32 -17
  17. package/dest/rpc_translator.d.ts.map +1 -1
  18. package/dest/rpc_translator.js +134 -60
  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 +63 -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 +7 -7
  29. package/dest/state_machine/index.d.ts.map +1 -1
  30. package/dest/state_machine/index.js +39 -22
  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 +101 -49
  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 +38 -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 +205 -107
  66. package/src/rpc_translator.ts +159 -63
  67. package/src/state_machine/archiver.ts +63 -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 +59 -21
  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 +197 -85
  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 +49 -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,15 +6,21 @@ 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,
19
25
  } from '@aztec/pxe/server';
20
26
  import {
@@ -38,18 +44,18 @@ import {
38
44
  witnessMapToFields,
39
45
  } from '@aztec/simulator/client';
40
46
  import {
47
+ CppPublicTxSimulator,
41
48
  GuardedMerkleTreeOperations,
42
49
  PublicContractsDB,
43
50
  PublicProcessor,
44
- PublicTxSimulator,
45
51
  } from '@aztec/simulator/server';
46
- import { type ContractArtifact, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
52
+ import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
47
53
  import { AuthWitness } from '@aztec/stdlib/auth-witness';
54
+ import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
48
55
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
49
- import { Body, L2Block } from '@aztec/stdlib/block';
50
56
  import { type ContractInstanceWithAddress, computePartialAddress } from '@aztec/stdlib/contract';
51
57
  import { Gas, GasFees, GasSettings } from '@aztec/stdlib/gas';
52
- import { computeCalldataHash, siloNullifier } from '@aztec/stdlib/hash';
58
+ import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
53
59
  import {
54
60
  PartialPrivateTailPublicInputsForPublic,
55
61
  PrivateKernelTailCircuitPublicInputs,
@@ -57,7 +63,7 @@ import {
57
63
  PublicCallRequest,
58
64
  } from '@aztec/stdlib/kernel';
59
65
  import { ChonkProof } from '@aztec/stdlib/proofs';
60
- import { makeAppendOnlyTreeSnapshot, makeGlobalVariables } from '@aztec/stdlib/testing';
66
+ import { makeGlobalVariables } from '@aztec/stdlib/testing';
61
67
  import { MerkleTreeId } from '@aztec/stdlib/trees';
62
68
  import {
63
69
  CallContext,
@@ -74,15 +80,12 @@ import {
74
80
  import type { UInt64 } from '@aztec/stdlib/types';
75
81
  import { ForkCheckpoint } from '@aztec/world-state';
76
82
 
83
+ import { DEFAULT_ADDRESS } from '../constants.js';
77
84
  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';
85
+ import type { TXEAccountStore } from '../util/txe_account_store.js';
86
+ import type { TXEContractStore } from '../util/txe_contract_store.js';
80
87
  import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
81
- import {
82
- getSingleTxBlockRequestHash,
83
- insertTxEffectIntoWorldTrees,
84
- makeTXEBlockHeader,
85
- } from '../utils/block_creation.js';
88
+ import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
86
89
  import type { ITxeExecutionOracle } from './interfaces.js';
87
90
 
88
91
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
@@ -93,11 +96,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
93
96
 
94
97
  constructor(
95
98
  private stateMachine: TXEStateMachine,
96
- private contractDataProvider: TXEContractDataProvider,
99
+ private contractStore: TXEContractStore,
100
+ private noteStore: NoteStore,
97
101
  private keyStore: KeyStore,
98
- private addressDataProvider: AddressDataProvider,
99
- private accountDataProvider: TXEAccountDataProvider,
100
- 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,
101
110
  private nextBlockTimestamp: bigint,
102
111
  private version: Fr,
103
112
  private chainId: Fr,
@@ -131,8 +140,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
131
140
  this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
132
141
  }
133
142
 
134
- async txeGetNextBlockNumber(): Promise<number> {
135
- return (await this.getLastBlockNumber()) + 1;
143
+ txeGetDefaultAddress(): AztecAddress {
144
+ return DEFAULT_ADDRESS;
145
+ }
146
+
147
+ async txeGetNextBlockNumber(): Promise<BlockNumber> {
148
+ return BlockNumber((await this.getLastBlockNumber()) + 1);
136
149
  }
137
150
 
138
151
  txeGetNextBlockTimestamp(): Promise<bigint> {
@@ -144,7 +157,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
144
157
  }
145
158
 
146
159
  async txeGetLastTxEffects() {
147
- 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);
148
162
 
149
163
  if (block!.body.txEffects.length != 1) {
150
164
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -156,6 +170,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
156
170
  return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
157
171
  }
158
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
+
159
184
  async txeAdvanceBlocksBy(blocks: number) {
160
185
  this.logger.debug(`time traveling ${blocks} blocks`);
161
186
 
@@ -183,8 +208,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
183
208
  if (!secret.equals(Fr.ZERO)) {
184
209
  await this.txeAddAccount(artifact, instance, secret);
185
210
  } else {
186
- await this.contractDataProvider.addContractInstance(instance);
187
- await this.contractDataProvider.addContractArtifact(instance.currentContractClassId, artifact);
211
+ await this.contractStore.addContractInstance(instance);
212
+ await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
188
213
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
189
214
  }
190
215
  }
@@ -193,29 +218,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
193
218
  const partialAddress = await computePartialAddress(instance);
194
219
 
195
220
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
196
- await this.contractDataProvider.addContractInstance(instance);
197
- await this.contractDataProvider.addContractArtifact(instance.currentContractClassId, artifact);
221
+ await this.contractStore.addContractInstance(instance);
222
+ await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
198
223
 
199
224
  const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
200
- await this.accountDataProvider.setAccount(completeAddress.address, completeAddress);
201
- await this.addressDataProvider.addCompleteAddress(completeAddress);
225
+ await this.accountStore.setAccount(completeAddress.address, completeAddress);
226
+ await this.addressStore.addCompleteAddress(completeAddress);
202
227
  this.logger.debug(`Created account ${completeAddress.address}`);
203
228
 
204
229
  return completeAddress;
205
230
  }
206
231
 
207
232
  async txeCreateAccount(secret: Fr) {
208
- // This is a footgun !
233
+ // This is a foot gun !
209
234
  const completeAddress = await this.keyStore.addAccount(secret, secret);
210
- await this.accountDataProvider.setAccount(completeAddress.address, completeAddress);
211
- await this.addressDataProvider.addCompleteAddress(completeAddress);
235
+ await this.accountStore.setAccount(completeAddress.address, completeAddress);
236
+ await this.addressStore.addCompleteAddress(completeAddress);
212
237
  this.logger.debug(`Created account ${completeAddress.address}`);
213
238
 
214
239
  return completeAddress;
215
240
  }
216
241
 
217
242
  async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
218
- const account = await this.accountDataProvider.getAccount(address);
243
+ const account = await this.accountStore.getAccount(address);
219
244
  const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
220
245
 
221
246
  const schnorr = new Schnorr();
@@ -236,19 +261,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
236
261
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
237
262
  await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
238
263
 
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
- );
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]);
252
271
 
253
272
  await forkedWorldTrees.close();
254
273
 
@@ -266,10 +285,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
266
285
  isStaticCall: boolean = false,
267
286
  ) {
268
287
  this.logger.verbose(
269
- `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}`,
270
289
  );
271
290
 
272
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
291
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
273
292
  if (!artifact) {
274
293
  const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
275
294
  ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
@@ -277,22 +296,37 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
277
296
  throw new Error(message);
278
297
  }
279
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
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
305
+ await this.stateMachine.contractSyncService.ensureContractSynced(
306
+ targetContractAddress,
307
+ functionSelector,
308
+ utilityExecutor,
309
+ blockHeader,
310
+ this.jobId,
311
+ );
312
+
280
313
  const blockNumber = await this.txeGetNextBlockNumber();
281
314
 
282
315
  const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
283
316
 
284
317
  const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
285
-
286
318
  const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
287
-
288
319
  const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
289
320
 
290
321
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
291
322
 
292
- const blockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
293
-
294
- const txRequestHash = getSingleTxBlockRequestHash(blockNumber);
295
- const noteCache = new ExecutionNoteCache(txRequestHash);
323
+ const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
324
+ const noteCache = new ExecutionNoteCache(protocolNullifier);
325
+ // In production, the account contract sets the min revertible counter before calling the app function.
326
+ // Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
327
+ // marking all side effects as revertible.
328
+ const minRevertibleSideEffectCounter = 1;
329
+ await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
296
330
  const taggingIndexCache = new ExecutionTaggingIndexCache();
297
331
 
298
332
  const simulator = new WASMSimulator();
@@ -303,6 +337,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
303
337
  callContext,
304
338
  /** Header of a block whose state is used during private execution (not the block the transaction is included in). */
305
339
  blockHeader,
340
+ utilityExecutor,
306
341
  /** List of transient auth witnesses to be used during this simulation */
307
342
  Array.from(this.authwits.values()),
308
343
  /** List of transient auth witnesses to be used during this simulation */
@@ -310,9 +345,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
310
345
  HashedValuesCache.create([new HashedValues(args, argsHash)]),
311
346
  noteCache,
312
347
  taggingIndexCache,
313
- this.pxeOracleInterface,
314
- 0,
315
- 1,
348
+ this.contractStore,
349
+ this.noteStore,
350
+ this.keyStore,
351
+ this.addressStore,
352
+ this.stateMachine.node,
353
+ this.senderTaggingStore,
354
+ this.recipientTaggingStore,
355
+ this.senderAddressBookStore,
356
+ this.capsuleStore,
357
+ this.privateEventStore,
358
+ this.stateMachine.contractSyncService,
359
+ this.jobId,
360
+ 0, // totalPublicArgsCount
361
+ minRevertibleSideEffectCounter, // (start) sideEffectCounter
316
362
  undefined, // log
317
363
  undefined, // scopes
318
364
  /**
@@ -348,19 +394,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
348
394
  }),
349
395
  );
350
396
 
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);
397
+ noteCache.finish();
398
+ const nonceGenerator = noteCache.getNonceGenerator();
399
+ result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
355
400
  } catch (err) {
356
401
  throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
357
402
  }
358
403
 
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);
404
+ // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
405
+ // the nonce generator for the note hashes.
406
+ // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
407
+ const { publicInputs } = await generateSimulatedProvingResult(
408
+ result,
409
+ this.contractStore,
410
+ minRevertibleSideEffectCounter,
411
+ );
364
412
 
365
413
  const globals = makeGlobalVariables();
366
414
  globals.blockNumber = blockNumber;
@@ -371,17 +419,27 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
371
419
 
372
420
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
373
421
 
374
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
422
+ const bindings = this.logger.getBindings();
423
+ const contractsDB = new PublicContractsDB(
424
+ new TXEPublicContractDataSource(blockNumber, this.contractStore),
425
+ bindings,
426
+ );
375
427
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
428
+ const config = PublicSimulatorConfig.from({
429
+ skipFeeEnforcement: true,
430
+ collectDebugLogs: true,
431
+ collectHints: false,
432
+ collectStatistics: false,
433
+ collectCallMetadata: true,
434
+ });
376
435
  const processor = new PublicProcessor(
377
436
  globals,
378
437
  guardedMerkleTrees,
379
438
  contractsDB,
380
- new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, {
381
- doMerkleOperations: true,
382
- skipFeeEnforcement: true,
383
- }),
439
+ new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
384
440
  new TestDateProvider(),
441
+ undefined,
442
+ createLogger('simulator:public-processor', bindings),
385
443
  );
386
444
 
387
445
  const tx = await Tx.create({
@@ -406,7 +464,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
406
464
  } else if (!processedTx.revertCode.isOK()) {
407
465
  if (processedTx.revertReason) {
408
466
  try {
409
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
467
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
410
468
  // eslint-disable-next-line no-empty
411
469
  } catch {}
412
470
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -435,13 +493,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
435
493
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
436
494
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
437
495
 
438
- const body = new Body([txEffect]);
439
-
440
- const l2Block = new L2Block(
441
- makeAppendOnlyTreeSnapshot(),
442
- await makeTXEBlockHeader(forkedWorldTrees, globals),
443
- body,
444
- );
496
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
445
497
 
446
498
  await this.stateMachine.handleL2Block(l2Block);
447
499
 
@@ -457,7 +509,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
457
509
  isStaticCall: boolean,
458
510
  ) {
459
511
  this.logger.verbose(
460
- `Executing public function ${await this.contractDataProvider.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
512
+ `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
461
513
  );
462
514
 
463
515
  const blockNumber = await this.txeGetNextBlockNumber();
@@ -470,7 +522,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
470
522
 
471
523
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
472
524
 
473
- const anchorBlockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
525
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
474
526
 
475
527
  const calldataHash = await computeCalldataHash(calldata);
476
528
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
@@ -484,22 +536,36 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
484
536
 
485
537
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
486
538
 
487
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
539
+ const bindings2 = this.logger.getBindings();
540
+ const contractsDB = new PublicContractsDB(
541
+ new TXEPublicContractDataSource(blockNumber, this.contractStore),
542
+ bindings2,
543
+ );
488
544
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
489
- const simulator = new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, {
490
- doMerkleOperations: true,
545
+ const config = PublicSimulatorConfig.from({
491
546
  skipFeeEnforcement: true,
547
+ collectDebugLogs: true,
548
+ collectHints: false,
549
+ collectStatistics: false,
550
+ collectCallMetadata: true,
492
551
  });
493
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
552
+ const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
553
+ const processor = new PublicProcessor(
554
+ globals,
555
+ guardedMerkleTrees,
556
+ contractsDB,
557
+ simulator,
558
+ new TestDateProvider(),
559
+ undefined,
560
+ createLogger('simulator:public-processor', bindings2),
561
+ );
494
562
 
495
563
  // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
496
564
  // kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
497
565
  // side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
498
566
  // unique.
499
567
  const nonRevertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
500
- if (!isStaticCall) {
501
- nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
502
- }
568
+ nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
503
569
 
504
570
  // The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
505
571
  // may require producing reverts.
@@ -550,7 +616,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
550
616
  } else if (!processedTx.revertCode.isOK()) {
551
617
  if (processedTx.revertReason) {
552
618
  try {
553
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
619
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
554
620
  // eslint-disable-next-line no-empty
555
621
  } catch {}
556
622
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -582,13 +648,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
582
648
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
583
649
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
584
650
 
585
- const body = new Body([txEffect]);
586
-
587
- const l2Block = new L2Block(
588
- makeAppendOnlyTreeSnapshot(),
589
- await makeTXEBlockHeader(forkedWorldTrees, globals),
590
- body,
591
- );
651
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
592
652
 
593
653
  await this.stateMachine.handleL2Block(l2Block);
594
654
 
@@ -602,18 +662,39 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
602
662
  functionSelector: FunctionSelector,
603
663
  args: Fr[],
604
664
  ) {
605
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
665
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
606
666
  if (!artifact) {
607
667
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
608
668
  }
609
669
 
610
- const call = {
611
- name: artifact.name,
612
- selector: functionSelector,
613
- to: targetContractAddress,
614
- };
670
+ // Sync notes before executing utility function to discover notes from previous transactions
671
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
672
+ await this.stateMachine.contractSyncService.ensureContractSynced(
673
+ targetContractAddress,
674
+ functionSelector,
675
+ async call => {
676
+ await this.executeUtilityCall(call);
677
+ },
678
+ blockHeader,
679
+ this.jobId,
680
+ );
615
681
 
616
- const entryPointArtifact = await this.pxeOracleInterface.getFunctionArtifact(call.to, call.selector);
682
+ const call = new FunctionCall(
683
+ artifact.name,
684
+ targetContractAddress,
685
+ functionSelector,
686
+ FunctionType.UTILITY,
687
+ false,
688
+ false,
689
+ args,
690
+ [],
691
+ );
692
+
693
+ return this.executeUtilityCall(call);
694
+ }
695
+
696
+ private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
697
+ const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
617
698
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
618
699
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
619
700
  }
@@ -624,9 +705,25 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
624
705
  });
625
706
 
626
707
  try {
627
- const oracle = new UtilityExecutionOracle(call.to, [], [], this.pxeOracleInterface);
708
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
709
+ const oracle = new UtilityExecutionOracle(
710
+ call.to,
711
+ [],
712
+ [],
713
+ anchorBlockHeader,
714
+ this.contractStore,
715
+ this.noteStore,
716
+ this.keyStore,
717
+ this.addressStore,
718
+ this.stateMachine.node,
719
+ this.recipientTaggingStore,
720
+ this.senderAddressBookStore,
721
+ this.capsuleStore,
722
+ this.privateEventStore,
723
+ this.jobId,
724
+ );
628
725
  const acirExecutionResult = await new WASMSimulator()
629
- .executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
726
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
630
727
  .catch((err: Error) => {
631
728
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
632
729
  throw new ExecutionError(
@@ -652,7 +749,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
652
749
  return [this.nextBlockTimestamp, this.authwits];
653
750
  }
654
751
 
655
- private async getLastBlockNumber(): Promise<number> {
656
- return (await this.stateMachine.node.getBlockHeader('latest'))?.globalVariables.blockNumber ?? 0;
752
+ private async getLastBlockNumber(): Promise<BlockNumber> {
753
+ const header = await this.stateMachine.node.getBlockHeader('latest');
754
+ return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
657
755
  }
658
756
  }