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

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 +124 -78
  16. package/dest/rpc_translator.d.ts +29 -14
  17. package/dest/rpc_translator.d.ts.map +1 -1
  18. package/dest/rpc_translator.js +108 -45
  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 +64 -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 +22 -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 +174 -105
  66. package/src/rpc_translator.ts +134 -56
  67. package/src/state_machine/archiver.ts +65 -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 +27 -18
  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,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,32 @@ 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
+ await this.contractStore.syncPrivateState(targetContractAddress, functionSelector, utilityExecutor);
305
+
280
306
  const blockNumber = await this.txeGetNextBlockNumber();
281
307
 
282
308
  const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
283
309
 
284
310
  const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
285
-
286
311
  const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
287
-
288
312
  const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
289
313
 
290
314
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
291
315
 
292
- const blockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
316
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
293
317
 
294
- const txRequestHash = getSingleTxBlockRequestHash(blockNumber);
295
- const noteCache = new ExecutionNoteCache(txRequestHash);
318
+ const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
319
+ const noteCache = new ExecutionNoteCache(protocolNullifier);
320
+ // In production, the account contract sets the min revertible counter before calling the app function.
321
+ // Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
322
+ // marking all side effects as revertible.
323
+ const minRevertibleSideEffectCounter = 1;
324
+ await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
296
325
  const taggingIndexCache = new ExecutionTaggingIndexCache();
297
326
 
298
327
  const simulator = new WASMSimulator();
@@ -303,6 +332,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
303
332
  callContext,
304
333
  /** Header of a block whose state is used during private execution (not the block the transaction is included in). */
305
334
  blockHeader,
335
+ utilityExecutor,
306
336
  /** List of transient auth witnesses to be used during this simulation */
307
337
  Array.from(this.authwits.values()),
308
338
  /** List of transient auth witnesses to be used during this simulation */
@@ -310,9 +340,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
310
340
  HashedValuesCache.create([new HashedValues(args, argsHash)]),
311
341
  noteCache,
312
342
  taggingIndexCache,
313
- this.pxeOracleInterface,
314
- 0,
315
- 1,
343
+ this.contractStore,
344
+ this.noteStore,
345
+ this.keyStore,
346
+ this.addressStore,
347
+ this.stateMachine.node,
348
+ this.stateMachine.anchorBlockStore,
349
+ this.senderTaggingStore,
350
+ this.recipientTaggingStore,
351
+ this.senderAddressBookStore,
352
+ this.capsuleStore,
353
+ this.privateEventStore,
354
+ this.jobId,
355
+ 0, // totalPublicArgsCount
356
+ minRevertibleSideEffectCounter, // (start) sideEffectCounter
316
357
  undefined, // log
317
358
  undefined, // scopes
318
359
  /**
@@ -348,19 +389,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
348
389
  }),
349
390
  );
350
391
 
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);
392
+ noteCache.finish();
393
+ const nonceGenerator = noteCache.getNonceGenerator();
394
+ result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
355
395
  } catch (err) {
356
396
  throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
357
397
  }
358
398
 
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);
399
+ // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
400
+ // the nonce generator for the note hashes.
401
+ // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
402
+ const { publicInputs } = await generateSimulatedProvingResult(
403
+ result,
404
+ this.contractStore,
405
+ minRevertibleSideEffectCounter,
406
+ );
364
407
 
365
408
  const globals = makeGlobalVariables();
366
409
  globals.blockNumber = blockNumber;
@@ -371,16 +414,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
371
414
 
372
415
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
373
416
 
374
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
417
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
375
418
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
419
+ const config = PublicSimulatorConfig.from({
420
+ skipFeeEnforcement: true,
421
+ collectDebugLogs: true,
422
+ collectHints: false,
423
+ collectStatistics: false,
424
+ collectCallMetadata: true,
425
+ });
376
426
  const processor = new PublicProcessor(
377
427
  globals,
378
428
  guardedMerkleTrees,
379
429
  contractsDB,
380
- new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, {
381
- doMerkleOperations: true,
382
- skipFeeEnforcement: true,
383
- }),
430
+ new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
384
431
  new TestDateProvider(),
385
432
  );
386
433
 
@@ -406,7 +453,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
406
453
  } else if (!processedTx.revertCode.isOK()) {
407
454
  if (processedTx.revertReason) {
408
455
  try {
409
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
456
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
410
457
  // eslint-disable-next-line no-empty
411
458
  } catch {}
412
459
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -435,13 +482,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
435
482
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
436
483
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
437
484
 
438
- const body = new Body([txEffect]);
439
-
440
- const l2Block = new L2Block(
441
- makeAppendOnlyTreeSnapshot(),
442
- await makeTXEBlockHeader(forkedWorldTrees, globals),
443
- body,
444
- );
485
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
445
486
 
446
487
  await this.stateMachine.handleL2Block(l2Block);
447
488
 
@@ -457,7 +498,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
457
498
  isStaticCall: boolean,
458
499
  ) {
459
500
  this.logger.verbose(
460
- `Executing public function ${await this.contractDataProvider.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
501
+ `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
461
502
  );
462
503
 
463
504
  const blockNumber = await this.txeGetNextBlockNumber();
@@ -470,7 +511,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
470
511
 
471
512
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
472
513
 
473
- const anchorBlockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
514
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
474
515
 
475
516
  const calldataHash = await computeCalldataHash(calldata);
476
517
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
@@ -484,12 +525,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
484
525
 
485
526
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
486
527
 
487
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
528
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
488
529
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
489
- const simulator = new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, {
490
- doMerkleOperations: true,
530
+ const config = PublicSimulatorConfig.from({
491
531
  skipFeeEnforcement: true,
532
+ collectDebugLogs: true,
533
+ collectHints: false,
534
+ collectStatistics: false,
535
+ collectCallMetadata: true,
492
536
  });
537
+ const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
493
538
  const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
494
539
 
495
540
  // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
@@ -497,9 +542,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
497
542
  // side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
498
543
  // unique.
499
544
  const nonRevertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
500
- if (!isStaticCall) {
501
- nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
502
- }
545
+ nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
503
546
 
504
547
  // The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
505
548
  // may require producing reverts.
@@ -550,7 +593,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
550
593
  } else if (!processedTx.revertCode.isOK()) {
551
594
  if (processedTx.revertReason) {
552
595
  try {
553
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
596
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
554
597
  // eslint-disable-next-line no-empty
555
598
  } catch {}
556
599
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -582,13 +625,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
582
625
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
583
626
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
584
627
 
585
- const body = new Body([txEffect]);
586
-
587
- const l2Block = new L2Block(
588
- makeAppendOnlyTreeSnapshot(),
589
- await makeTXEBlockHeader(forkedWorldTrees, globals),
590
- body,
591
- );
628
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
592
629
 
593
630
  await this.stateMachine.handleL2Block(l2Block);
594
631
 
@@ -602,18 +639,32 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
602
639
  functionSelector: FunctionSelector,
603
640
  args: Fr[],
604
641
  ) {
605
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
642
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
606
643
  if (!artifact) {
607
644
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
608
645
  }
609
646
 
610
- const call = {
611
- name: artifact.name,
612
- selector: functionSelector,
613
- to: targetContractAddress,
614
- };
647
+ // Sync notes before executing utility function to discover notes from previous transactions
648
+ await this.contractStore.syncPrivateState(targetContractAddress, functionSelector, async call => {
649
+ await this.executeUtilityCall(call);
650
+ });
615
651
 
616
- const entryPointArtifact = await this.pxeOracleInterface.getFunctionArtifact(call.to, call.selector);
652
+ const call = new FunctionCall(
653
+ artifact.name,
654
+ targetContractAddress,
655
+ functionSelector,
656
+ FunctionType.UTILITY,
657
+ false,
658
+ false,
659
+ args,
660
+ [],
661
+ );
662
+
663
+ return this.executeUtilityCall(call);
664
+ }
665
+
666
+ private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
667
+ const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
617
668
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
618
669
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
619
670
  }
@@ -624,9 +675,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
624
675
  });
625
676
 
626
677
  try {
627
- const oracle = new UtilityExecutionOracle(call.to, [], [], this.pxeOracleInterface);
678
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
679
+ const oracle = new UtilityExecutionOracle(
680
+ call.to,
681
+ [],
682
+ [],
683
+ anchorBlockHeader,
684
+ this.contractStore,
685
+ this.noteStore,
686
+ this.keyStore,
687
+ this.addressStore,
688
+ this.stateMachine.node,
689
+ this.stateMachine.anchorBlockStore,
690
+ this.recipientTaggingStore,
691
+ this.senderAddressBookStore,
692
+ this.capsuleStore,
693
+ this.privateEventStore,
694
+ this.jobId,
695
+ );
628
696
  const acirExecutionResult = await new WASMSimulator()
629
- .executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
697
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
630
698
  .catch((err: Error) => {
631
699
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
632
700
  throw new ExecutionError(
@@ -652,7 +720,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
652
720
  return [this.nextBlockTimestamp, this.authwits];
653
721
  }
654
722
 
655
- private async getLastBlockNumber(): Promise<number> {
656
- return (await this.stateMachine.node.getBlockHeader('latest'))?.globalVariables.blockNumber ?? 0;
723
+ private async getLastBlockNumber(): Promise<BlockNumber> {
724
+ const header = await this.stateMachine.node.getBlockHeader('latest');
725
+ return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
657
726
  }
658
727
  }