@aztec/txe 0.0.1-commit.9b94fc1 → 0.0.1-commit.c7c42ec

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 (72) hide show
  1. package/dest/index.d.ts +1 -1
  2. package/dest/index.d.ts.map +1 -1
  3. package/dest/index.js +3 -2
  4. package/dest/oracle/interfaces.d.ts +9 -6
  5. package/dest/oracle/interfaces.d.ts.map +1 -1
  6. package/dest/oracle/txe_oracle_public_context.d.ts +5 -5
  7. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  8. package/dest/oracle/txe_oracle_public_context.js +4 -6
  9. package/dest/oracle/txe_oracle_top_level_context.d.ts +20 -12
  10. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  11. package/dest/oracle/txe_oracle_top_level_context.js +77 -54
  12. package/dest/rpc_translator.d.ts +11 -5
  13. package/dest/rpc_translator.d.ts.map +1 -1
  14. package/dest/rpc_translator.js +57 -15
  15. package/dest/state_machine/archiver.d.ts +26 -10
  16. package/dest/state_machine/archiver.d.ts.map +1 -1
  17. package/dest/state_machine/archiver.js +105 -17
  18. package/dest/state_machine/dummy_p2p_client.d.ts +1 -1
  19. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  20. package/dest/state_machine/dummy_p2p_client.js +3 -1
  21. package/dest/state_machine/global_variable_builder.d.ts +5 -4
  22. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  23. package/dest/state_machine/global_variable_builder.js +12 -0
  24. package/dest/state_machine/index.d.ts +5 -5
  25. package/dest/state_machine/index.d.ts.map +1 -1
  26. package/dest/state_machine/index.js +14 -20
  27. package/dest/state_machine/synchronizer.d.ts +5 -4
  28. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  29. package/dest/state_machine/synchronizer.js +5 -4
  30. package/dest/txe_session.d.ts +19 -13
  31. package/dest/txe_session.d.ts.map +1 -1
  32. package/dest/txe_session.js +50 -38
  33. package/dest/util/encoding.d.ts +610 -11
  34. package/dest/util/encoding.d.ts.map +1 -1
  35. package/dest/util/encoding.js +1 -1
  36. package/dest/util/txe_account_store.d.ts +10 -0
  37. package/dest/util/txe_account_store.d.ts.map +1 -0
  38. package/dest/util/{txe_account_data_provider.js → txe_account_store.js} +1 -1
  39. package/dest/util/txe_contract_store.d.ts +12 -0
  40. package/dest/util/txe_contract_store.d.ts.map +1 -0
  41. package/dest/util/{txe_contract_data_provider.js → txe_contract_store.js} +3 -3
  42. package/dest/util/txe_public_contract_data_source.d.ts +7 -6
  43. package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
  44. package/dest/util/txe_public_contract_data_source.js +11 -11
  45. package/dest/utils/block_creation.d.ts +19 -4
  46. package/dest/utils/block_creation.d.ts.map +1 -1
  47. package/dest/utils/block_creation.js +23 -2
  48. package/dest/utils/tx_effect_creation.d.ts +4 -3
  49. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  50. package/dest/utils/tx_effect_creation.js +1 -1
  51. package/package.json +17 -17
  52. package/src/index.ts +15 -12
  53. package/src/oracle/interfaces.ts +8 -5
  54. package/src/oracle/txe_oracle_public_context.ts +6 -11
  55. package/src/oracle/txe_oracle_top_level_context.ts +109 -80
  56. package/src/rpc_translator.ts +82 -12
  57. package/src/state_machine/archiver.ts +136 -25
  58. package/src/state_machine/dummy_p2p_client.ts +3 -1
  59. package/src/state_machine/global_variable_builder.ts +20 -3
  60. package/src/state_machine/index.ts +19 -18
  61. package/src/state_machine/synchronizer.ts +8 -7
  62. package/src/txe_session.ts +107 -68
  63. package/src/util/encoding.ts +1 -1
  64. package/src/util/{txe_account_data_provider.ts → txe_account_store.ts} +1 -1
  65. package/src/util/{txe_contract_data_provider.ts → txe_contract_store.ts} +3 -3
  66. package/src/util/txe_public_contract_data_source.ts +13 -12
  67. package/src/utils/block_creation.ts +34 -3
  68. package/src/utils/tx_effect_creation.ts +3 -2
  69. package/dest/util/txe_account_data_provider.d.ts +0 -10
  70. package/dest/util/txe_account_data_provider.d.ts.map +0 -1
  71. package/dest/util/txe_contract_data_provider.d.ts +0 -12
  72. 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,16 +44,15 @@ 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, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
47
53
  import { AuthWitness } from '@aztec/stdlib/auth-witness';
48
54
  import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
49
55
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
50
- import { Body, L2Block } from '@aztec/stdlib/block';
51
56
  import { type ContractInstanceWithAddress, computePartialAddress } from '@aztec/stdlib/contract';
52
57
  import { Gas, GasFees, GasSettings } from '@aztec/stdlib/gas';
53
58
  import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
@@ -58,7 +63,7 @@ import {
58
63
  PublicCallRequest,
59
64
  } from '@aztec/stdlib/kernel';
60
65
  import { ChonkProof } from '@aztec/stdlib/proofs';
61
- import { makeAppendOnlyTreeSnapshot, makeGlobalVariables } from '@aztec/stdlib/testing';
66
+ import { makeGlobalVariables } from '@aztec/stdlib/testing';
62
67
  import { MerkleTreeId } from '@aztec/stdlib/trees';
63
68
  import {
64
69
  CallContext,
@@ -76,14 +81,11 @@ import type { UInt64 } from '@aztec/stdlib/types';
76
81
  import { ForkCheckpoint } from '@aztec/world-state';
77
82
 
78
83
  import type { TXEStateMachine } from '../state_machine/index.js';
79
- import type { TXEAccountDataProvider } from '../util/txe_account_data_provider.js';
80
- import type { TXEContractDataProvider } from '../util/txe_contract_data_provider.js';
84
+ import { DEFAULT_ADDRESS } from '../txe_session.js';
85
+ import type { TXEAccountStore } from '../util/txe_account_store.js';
86
+ import type { TXEContractStore } from '../util/txe_contract_store.js';
81
87
  import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
82
- import {
83
- getSingleTxBlockRequestHash,
84
- insertTxEffectIntoWorldTrees,
85
- makeTXEBlockHeader,
86
- } from '../utils/block_creation.js';
88
+ import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
87
89
  import type { ITxeExecutionOracle } from './interfaces.js';
88
90
 
89
91
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
@@ -94,11 +96,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
94
96
 
95
97
  constructor(
96
98
  private stateMachine: TXEStateMachine,
97
- private contractDataProvider: TXEContractDataProvider,
99
+ private contractStore: TXEContractStore,
100
+ private noteStore: NoteStore,
98
101
  private keyStore: KeyStore,
99
- private addressDataProvider: AddressDataProvider,
100
- private accountDataProvider: TXEAccountDataProvider,
101
- 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,
102
109
  private nextBlockTimestamp: bigint,
103
110
  private version: Fr,
104
111
  private chainId: Fr,
@@ -132,8 +139,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
132
139
  this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
133
140
  }
134
141
 
135
- async txeGetNextBlockNumber(): Promise<number> {
136
- return (await this.getLastBlockNumber()) + 1;
142
+ txeGetDefaultAddress(): AztecAddress {
143
+ return DEFAULT_ADDRESS;
144
+ }
145
+
146
+ async txeGetNextBlockNumber(): Promise<BlockNumber> {
147
+ return BlockNumber((await this.getLastBlockNumber()) + 1);
137
148
  }
138
149
 
139
150
  txeGetNextBlockTimestamp(): Promise<bigint> {
@@ -145,7 +156,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
145
156
  }
146
157
 
147
158
  async txeGetLastTxEffects() {
148
- const block = await this.stateMachine.archiver.getBlock('latest');
159
+ const block = await this.stateMachine.archiver.getL2Block('latest');
149
160
 
150
161
  if (block!.body.txEffects.length != 1) {
151
162
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -157,6 +168,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
157
168
  return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
158
169
  }
159
170
 
171
+ async txeGetPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
172
+ return (
173
+ await this.privateEventStore.getPrivateEvents(selector, {
174
+ contractAddress,
175
+ scopes: [scope],
176
+ fromBlock: 0,
177
+ toBlock: (await this.getLastBlockNumber()) + 1,
178
+ })
179
+ ).map(e => e.packedEvent);
180
+ }
181
+
160
182
  async txeAdvanceBlocksBy(blocks: number) {
161
183
  this.logger.debug(`time traveling ${blocks} blocks`);
162
184
 
@@ -184,8 +206,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
184
206
  if (!secret.equals(Fr.ZERO)) {
185
207
  await this.txeAddAccount(artifact, instance, secret);
186
208
  } else {
187
- await this.contractDataProvider.addContractInstance(instance);
188
- await this.contractDataProvider.addContractArtifact(instance.currentContractClassId, artifact);
209
+ await this.contractStore.addContractInstance(instance);
210
+ await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
189
211
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
190
212
  }
191
213
  }
@@ -194,29 +216,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
194
216
  const partialAddress = await computePartialAddress(instance);
195
217
 
196
218
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
197
- await this.contractDataProvider.addContractInstance(instance);
198
- await this.contractDataProvider.addContractArtifact(instance.currentContractClassId, artifact);
219
+ await this.contractStore.addContractInstance(instance);
220
+ await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
199
221
 
200
222
  const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
201
- await this.accountDataProvider.setAccount(completeAddress.address, completeAddress);
202
- await this.addressDataProvider.addCompleteAddress(completeAddress);
223
+ await this.accountStore.setAccount(completeAddress.address, completeAddress);
224
+ await this.addressStore.addCompleteAddress(completeAddress);
203
225
  this.logger.debug(`Created account ${completeAddress.address}`);
204
226
 
205
227
  return completeAddress;
206
228
  }
207
229
 
208
230
  async txeCreateAccount(secret: Fr) {
209
- // This is a footgun !
231
+ // This is a foot gun !
210
232
  const completeAddress = await this.keyStore.addAccount(secret, secret);
211
- await this.accountDataProvider.setAccount(completeAddress.address, completeAddress);
212
- await this.addressDataProvider.addCompleteAddress(completeAddress);
233
+ await this.accountStore.setAccount(completeAddress.address, completeAddress);
234
+ await this.addressStore.addCompleteAddress(completeAddress);
213
235
  this.logger.debug(`Created account ${completeAddress.address}`);
214
236
 
215
237
  return completeAddress;
216
238
  }
217
239
 
218
240
  async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
219
- const account = await this.accountDataProvider.getAccount(address);
241
+ const account = await this.accountStore.getAccount(address);
220
242
  const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
221
243
 
222
244
  const schnorr = new Schnorr();
@@ -237,19 +259,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
237
259
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
238
260
  await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
239
261
 
240
- const block = new L2Block(
241
- makeAppendOnlyTreeSnapshot(),
242
- await makeTXEBlockHeader(
243
- forkedWorldTrees,
244
- makeGlobalVariables(undefined, {
245
- blockNumber,
246
- timestamp: this.nextBlockTimestamp,
247
- version: this.version,
248
- chainId: this.chainId,
249
- }),
250
- ),
251
- new Body([txEffect]),
252
- );
262
+ const globals = makeGlobalVariables(undefined, {
263
+ blockNumber,
264
+ timestamp: this.nextBlockTimestamp,
265
+ version: this.version,
266
+ chainId: this.chainId,
267
+ });
268
+ const block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
253
269
 
254
270
  await forkedWorldTrees.close();
255
271
 
@@ -267,10 +283,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
267
283
  isStaticCall: boolean = false,
268
284
  ) {
269
285
  this.logger.verbose(
270
- `Executing external function ${await this.contractDataProvider.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
286
+ `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
271
287
  );
272
288
 
273
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
289
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
274
290
  if (!artifact) {
275
291
  const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
276
292
  ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
@@ -290,7 +306,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
290
306
 
291
307
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
292
308
 
293
- const blockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
309
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
294
310
 
295
311
  const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
296
312
  const noteCache = new ExecutionNoteCache(protocolNullifier);
@@ -311,7 +327,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
311
327
  HashedValuesCache.create([new HashedValues(args, argsHash)]),
312
328
  noteCache,
313
329
  taggingIndexCache,
314
- this.pxeOracleInterface,
330
+ this.contractStore,
331
+ this.noteStore,
332
+ this.keyStore,
333
+ this.addressStore,
334
+ this.stateMachine.node,
335
+ this.stateMachine.anchorBlockStore,
336
+ this.senderTaggingStore,
337
+ this.recipientTaggingStore,
338
+ this.senderAddressBookStore,
339
+ this.capsuleStore,
340
+ this.privateEventStore,
315
341
  0,
316
342
  1,
317
343
  undefined, // log
@@ -361,7 +387,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
361
387
  // can either be the first nullifier in the tx or the hash of the initial tx request
362
388
  // if there are none.
363
389
  const nonceGenerator = result.firstNullifier.equals(Fr.ZERO) ? protocolNullifier : result.firstNullifier;
364
- const { publicInputs } = await generateSimulatedProvingResult(result, nonceGenerator, this.contractDataProvider);
390
+ const { publicInputs } = await generateSimulatedProvingResult(result, nonceGenerator, this.contractStore);
365
391
 
366
392
  const globals = makeGlobalVariables();
367
393
  globals.blockNumber = blockNumber;
@@ -372,7 +398,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
372
398
 
373
399
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
374
400
 
375
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
401
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
376
402
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
377
403
  const config = PublicSimulatorConfig.from({
378
404
  skipFeeEnforcement: true,
@@ -385,7 +411,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
385
411
  globals,
386
412
  guardedMerkleTrees,
387
413
  contractsDB,
388
- new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
414
+ new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
389
415
  new TestDateProvider(),
390
416
  );
391
417
 
@@ -411,7 +437,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
411
437
  } else if (!processedTx.revertCode.isOK()) {
412
438
  if (processedTx.revertReason) {
413
439
  try {
414
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
440
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
415
441
  // eslint-disable-next-line no-empty
416
442
  } catch {}
417
443
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -440,13 +466,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
440
466
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
441
467
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
442
468
 
443
- const body = new Body([txEffect]);
444
-
445
- const l2Block = new L2Block(
446
- makeAppendOnlyTreeSnapshot(),
447
- await makeTXEBlockHeader(forkedWorldTrees, globals),
448
- body,
449
- );
469
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
450
470
 
451
471
  await this.stateMachine.handleL2Block(l2Block);
452
472
 
@@ -462,7 +482,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
462
482
  isStaticCall: boolean,
463
483
  ) {
464
484
  this.logger.verbose(
465
- `Executing public function ${await this.contractDataProvider.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
485
+ `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
466
486
  );
467
487
 
468
488
  const blockNumber = await this.txeGetNextBlockNumber();
@@ -475,7 +495,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
475
495
 
476
496
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
477
497
 
478
- const anchorBlockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
498
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
479
499
 
480
500
  const calldataHash = await computeCalldataHash(calldata);
481
501
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
@@ -489,7 +509,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
489
509
 
490
510
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
491
511
 
492
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
512
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
493
513
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
494
514
  const config = PublicSimulatorConfig.from({
495
515
  skipFeeEnforcement: true,
@@ -498,7 +518,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
498
518
  collectStatistics: false,
499
519
  collectCallMetadata: true,
500
520
  });
501
- const simulator = new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
521
+ const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
502
522
  const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
503
523
 
504
524
  // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
@@ -506,9 +526,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
506
526
  // side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
507
527
  // unique.
508
528
  const nonRevertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
509
- if (!isStaticCall) {
510
- nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
511
- }
529
+ nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
512
530
 
513
531
  // The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
514
532
  // may require producing reverts.
@@ -559,7 +577,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
559
577
  } else if (!processedTx.revertCode.isOK()) {
560
578
  if (processedTx.revertReason) {
561
579
  try {
562
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
580
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
563
581
  // eslint-disable-next-line no-empty
564
582
  } catch {}
565
583
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -591,13 +609,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
591
609
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
592
610
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
593
611
 
594
- const body = new Body([txEffect]);
595
-
596
- const l2Block = new L2Block(
597
- makeAppendOnlyTreeSnapshot(),
598
- await makeTXEBlockHeader(forkedWorldTrees, globals),
599
- body,
600
- );
612
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
601
613
 
602
614
  await this.stateMachine.handleL2Block(l2Block);
603
615
 
@@ -611,7 +623,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
611
623
  functionSelector: FunctionSelector,
612
624
  args: Fr[],
613
625
  ) {
614
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
626
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
615
627
  if (!artifact) {
616
628
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
617
629
  }
@@ -622,7 +634,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
622
634
  to: targetContractAddress,
623
635
  };
624
636
 
625
- const entryPointArtifact = await this.pxeOracleInterface.getFunctionArtifact(call.to, call.selector);
637
+ const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
626
638
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
627
639
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
628
640
  }
@@ -633,7 +645,23 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
633
645
  });
634
646
 
635
647
  try {
636
- const oracle = new UtilityExecutionOracle(call.to, [], [], this.pxeOracleInterface);
648
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
649
+ const oracle = new UtilityExecutionOracle(
650
+ call.to,
651
+ [],
652
+ [],
653
+ anchorBlockHeader,
654
+ this.contractStore,
655
+ this.noteStore,
656
+ this.keyStore,
657
+ this.addressStore,
658
+ this.stateMachine.node,
659
+ this.stateMachine.anchorBlockStore,
660
+ this.recipientTaggingStore,
661
+ this.senderAddressBookStore,
662
+ this.capsuleStore,
663
+ this.privateEventStore,
664
+ );
637
665
  const acirExecutionResult = await new WASMSimulator()
638
666
  .executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
639
667
  .catch((err: Error) => {
@@ -661,7 +689,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
661
689
  return [this.nextBlockTimestamp, this.authwits];
662
690
  }
663
691
 
664
- private async getLastBlockNumber(): Promise<number> {
665
- return (await this.stateMachine.node.getBlockHeader('latest'))?.globalVariables.blockNumber ?? 0;
692
+ private async getLastBlockNumber(): Promise<BlockNumber> {
693
+ const header = await this.stateMachine.node.getBlockHeader('latest');
694
+ return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
666
695
  }
667
696
  }
@@ -1,13 +1,14 @@
1
1
  import type { ContractInstanceWithAddress } from '@aztec/aztec.js/contracts';
2
2
  import { Fr, Point } from '@aztec/aztec.js/fields';
3
3
  import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX } from '@aztec/constants';
4
+ import { BlockNumber } from '@aztec/foundation/branded-types';
4
5
  import {
5
6
  type IMiscOracle,
6
7
  type IPrivateExecutionOracle,
7
8
  type IUtilityExecutionOracle,
8
9
  packAsRetrievedNote,
9
10
  } from '@aztec/pxe/simulator';
10
- import { type ContractArtifact, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
11
+ import { type ContractArtifact, EventSelector, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
11
12
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
12
13
  import { MerkleTreeId } from '@aztec/stdlib/trees';
13
14
 
@@ -29,6 +30,9 @@ import {
29
30
  toSingle,
30
31
  } from './util/encoding.js';
31
32
 
33
+ const MAX_EVENT_LEN = 12; // This is MAX_MESSAGE_CONTENT_LEN - PRIVATE_EVENT_RESERVED_FIELDS
34
+ const MAX_PRIVATE_EVENTS_PER_TXE_QUERY = 5;
35
+
32
36
  export class UnavailableOracleError extends Error {
33
37
  constructor(oracleName: string) {
34
38
  super(`${oracleName} oracles not available with the current handler`);
@@ -117,7 +121,7 @@ export class RPCTranslator {
117
121
  : undefined;
118
122
 
119
123
  const anchorBlockNumber = fromSingle(foreignAnchorBlockNumberIsSome).toBool()
120
- ? fromSingle(foreignAnchorBlockNumberValue).toNumber()
124
+ ? BlockNumber(fromSingle(foreignAnchorBlockNumberValue).toNumber())
121
125
  : undefined;
122
126
 
123
127
  const privateContextInputs = await this.stateHandler.enterPrivateState(contractAddress, anchorBlockNumber);
@@ -155,6 +159,12 @@ export class RPCTranslator {
155
159
 
156
160
  // TXE-specific oracles
157
161
 
162
+ txeGetDefaultAddress() {
163
+ const defaultAddress = this.handlerAsTxe().txeGetDefaultAddress();
164
+
165
+ return toForeignCallResult([toSingle(defaultAddress)]);
166
+ }
167
+
158
168
  async txeGetNextBlockNumber() {
159
169
  const nextBlockNumber = await this.handlerAsTxe().txeGetNextBlockNumber();
160
170
 
@@ -266,6 +276,39 @@ export class RPCTranslator {
266
276
  ]);
267
277
  }
268
278
 
279
+ async txeGetPrivateEvents(
280
+ foreignSelector: ForeignCallSingle,
281
+ foreignContractAddress: ForeignCallSingle,
282
+ foreignScope: ForeignCallSingle,
283
+ ) {
284
+ const selector = EventSelector.fromField(fromSingle(foreignSelector));
285
+ const contractAddress = addressFromSingle(foreignContractAddress);
286
+ const scope = addressFromSingle(foreignScope);
287
+
288
+ const events = await this.handlerAsTxe().txeGetPrivateEvents(selector, contractAddress, scope);
289
+
290
+ if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
291
+ throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
292
+ }
293
+
294
+ if (events.some(e => e.length > MAX_EVENT_LEN)) {
295
+ throw new Error(`Some private event has length larger than maxLen ${MAX_EVENT_LEN}`);
296
+ }
297
+
298
+ // This is a workaround as Noir does not currently let us return nested structs with arrays. We instead return a raw
299
+ // multidimensional array in get_private_events_oracle and create the BoundedVecs here.
300
+ const rawArrayStorage = events
301
+ .map(e => e.concat(Array(MAX_EVENT_LEN - e.length).fill(new Fr(0))))
302
+ .concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(Array(MAX_EVENT_LEN).fill(new Fr(0))))
303
+ .flat();
304
+ const eventLengths = events
305
+ .map(e => new Fr(e.length))
306
+ .concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(new Fr(0)));
307
+ const queryLength = new Fr(events.length);
308
+
309
+ return toForeignCallResult([toArray(rawArrayStorage), toArray(eventLengths), toSingle(queryLength)]);
310
+ }
311
+
269
312
  privateStoreInExecutionCache(foreignValues: ForeignCallArray, foreignHash: ForeignCallSingle) {
270
313
  const values = fromArray(foreignValues);
271
314
  const hash = fromSingle(foreignHash);
@@ -310,7 +353,7 @@ export class RPCTranslator {
310
353
  ) {
311
354
  const contractAddress = addressFromSingle(foreignContractAddress);
312
355
  const startStorageSlot = fromSingle(foreignStartStorageSlot);
313
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
356
+ const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
314
357
  const numberOfElements = fromSingle(foreignNumberOfElements).toNumber();
315
358
 
316
359
  const values = await this.handlerAsUtility().utilityStorageRead(
@@ -324,7 +367,7 @@ export class RPCTranslator {
324
367
  }
325
368
 
326
369
  async utilityGetPublicDataWitness(foreignBlockNumber: ForeignCallSingle, foreignLeafSlot: ForeignCallSingle) {
327
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
370
+ const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
328
371
  const leafSlot = fromSingle(foreignLeafSlot);
329
372
 
330
373
  const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(blockNumber, leafSlot);
@@ -336,6 +379,8 @@ export class RPCTranslator {
336
379
  }
337
380
 
338
381
  async utilityGetNotes(
382
+ foreignOwnerIsSome: ForeignCallSingle,
383
+ foreignOwnerValue: ForeignCallSingle,
339
384
  foreignStorageSlot: ForeignCallSingle,
340
385
  foreignNumSelects: ForeignCallSingle,
341
386
  foreignSelectByIndexes: ForeignCallArray,
@@ -353,6 +398,10 @@ export class RPCTranslator {
353
398
  foreignMaxNotes: ForeignCallSingle,
354
399
  foreignPackedRetrievedNoteLength: ForeignCallSingle,
355
400
  ) {
401
+ // Parse Option<AztecAddress>: ownerIsSome is 0 for None, 1 for Some
402
+ const owner = fromSingle(foreignOwnerIsSome).toBool()
403
+ ? AztecAddress.fromField(fromSingle(foreignOwnerValue))
404
+ : undefined;
356
405
  const storageSlot = fromSingle(foreignStorageSlot);
357
406
  const numSelects = fromSingle(foreignNumSelects).toNumber();
358
407
  const selectByIndexes = fromArray(foreignSelectByIndexes).map(fr => fr.toNumber());
@@ -371,6 +420,7 @@ export class RPCTranslator {
371
420
  const packedRetrievedNoteLength = fromSingle(foreignPackedRetrievedNoteLength).toNumber();
372
421
 
373
422
  const noteDatas = await this.handlerAsUtility().utilityGetNotes(
423
+ owner,
374
424
  storageSlot,
375
425
  numSelects,
376
426
  selectByIndexes,
@@ -387,7 +437,17 @@ export class RPCTranslator {
387
437
  status,
388
438
  );
389
439
 
390
- const returnDataAsArrayOfArrays = noteDatas.map(packAsRetrievedNote);
440
+ const returnDataAsArrayOfArrays = noteDatas.map(noteData =>
441
+ packAsRetrievedNote({
442
+ contractAddress: noteData.contractAddress,
443
+ owner: noteData.owner,
444
+ randomness: noteData.randomness,
445
+ storageSlot: noteData.storageSlot,
446
+ noteNonce: noteData.noteNonce,
447
+ index: noteData.index,
448
+ note: noteData.note,
449
+ }),
450
+ );
391
451
 
392
452
  // Now we convert each sub-array to an array of ForeignCallSingles
393
453
  const returnDataAsArrayOfForeignCallSingleArrays = returnDataAsArrayOfArrays.map(subArray =>
@@ -405,6 +465,7 @@ export class RPCTranslator {
405
465
  }
406
466
 
407
467
  privateNotifyCreatedNote(
468
+ foreignOwner: ForeignCallSingle,
408
469
  foreignStorageSlot: ForeignCallSingle,
409
470
  foreignRandomness: ForeignCallSingle,
410
471
  foreignNoteTypeId: ForeignCallSingle,
@@ -412,6 +473,7 @@ export class RPCTranslator {
412
473
  foreignNoteHash: ForeignCallSingle,
413
474
  foreignCounter: ForeignCallSingle,
414
475
  ) {
476
+ const owner = addressFromSingle(foreignOwner);
415
477
  const storageSlot = fromSingle(foreignStorageSlot);
416
478
  const randomness = fromSingle(foreignRandomness);
417
479
  const noteTypeId = NoteSelector.fromField(fromSingle(foreignNoteTypeId));
@@ -419,7 +481,15 @@ export class RPCTranslator {
419
481
  const noteHash = fromSingle(foreignNoteHash);
420
482
  const counter = fromSingle(foreignCounter).toNumber();
421
483
 
422
- this.handlerAsPrivate().privateNotifyCreatedNote(storageSlot, randomness, noteTypeId, note, noteHash, counter);
484
+ this.handlerAsPrivate().privateNotifyCreatedNote(
485
+ owner,
486
+ storageSlot,
487
+ randomness,
488
+ noteTypeId,
489
+ note,
490
+ noteHash,
491
+ counter,
492
+ );
423
493
 
424
494
  return toForeignCallResult([]);
425
495
  }
@@ -502,7 +572,7 @@ export class RPCTranslator {
502
572
  foreignBlockNumber: ForeignCallSingle,
503
573
  foreignNullifier: ForeignCallSingle,
504
574
  ) {
505
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
575
+ const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
506
576
  const nullifier = fromSingle(foreignNullifier);
507
577
 
508
578
  const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockNumber, nullifier);
@@ -552,14 +622,14 @@ export class RPCTranslator {
552
622
  return toForeignCallResult([toSingle(new Fr(isRevertible))]);
553
623
  }
554
624
 
555
- async utilityGetUtilityContext() {
556
- const context = await this.handlerAsUtility().utilityGetUtilityContext();
625
+ utilityGetUtilityContext() {
626
+ const context = this.handlerAsUtility().utilityGetUtilityContext();
557
627
 
558
628
  return toForeignCallResult(context.toNoirRepresentation());
559
629
  }
560
630
 
561
631
  async utilityGetBlockHeader(foreignBlockNumber: ForeignCallSingle) {
562
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
632
+ const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
563
633
 
564
634
  const header = await this.handlerAsUtility().utilityGetBlockHeader(blockNumber);
565
635
 
@@ -574,7 +644,7 @@ export class RPCTranslator {
574
644
  foreignTreeId: ForeignCallSingle,
575
645
  foreignLeafValue: ForeignCallSingle,
576
646
  ) {
577
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
647
+ const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
578
648
  const treeId = fromSingle(foreignTreeId).toNumber();
579
649
  const leafValue = fromSingle(foreignLeafValue);
580
650
 
@@ -592,7 +662,7 @@ export class RPCTranslator {
592
662
  foreignBlockNumber: ForeignCallSingle,
593
663
  foreignNullifier: ForeignCallSingle,
594
664
  ) {
595
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
665
+ const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
596
666
  const nullifier = fromSingle(foreignNullifier);
597
667
 
598
668
  const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockNumber, nullifier);