@aztec/txe 0.0.1-commit.03f7ef2 → 0.0.1-commit.0658669b3

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 (74) hide show
  1. package/dest/constants.d.ts +3 -0
  2. package/dest/constants.d.ts.map +1 -0
  3. package/dest/constants.js +2 -0
  4. package/dest/index.d.ts +1 -1
  5. package/dest/index.d.ts.map +1 -1
  6. package/dest/index.js +82 -50
  7. package/dest/oracle/interfaces.d.ts +6 -5
  8. package/dest/oracle/interfaces.d.ts.map +1 -1
  9. package/dest/oracle/txe_oracle_public_context.d.ts +3 -3
  10. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  11. package/dest/oracle/txe_oracle_public_context.js +6 -6
  12. package/dest/oracle/txe_oracle_top_level_context.d.ts +18 -16
  13. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  14. package/dest/oracle/txe_oracle_top_level_context.js +159 -72
  15. package/dest/rpc_translator.d.ts +21 -15
  16. package/dest/rpc_translator.d.ts.map +1 -1
  17. package/dest/rpc_translator.js +91 -54
  18. package/dest/state_machine/archiver.d.ts +20 -67
  19. package/dest/state_machine/archiver.d.ts.map +1 -1
  20. package/dest/state_machine/archiver.js +59 -178
  21. package/dest/state_machine/dummy_p2p_client.d.ts +20 -15
  22. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  23. package/dest/state_machine/dummy_p2p_client.js +39 -24
  24. package/dest/state_machine/global_variable_builder.d.ts +2 -2
  25. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  26. package/dest/state_machine/global_variable_builder.js +1 -1
  27. package/dest/state_machine/index.d.ts +6 -6
  28. package/dest/state_machine/index.d.ts.map +1 -1
  29. package/dest/state_machine/index.js +37 -14
  30. package/dest/state_machine/mock_epoch_cache.d.ts +9 -6
  31. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  32. package/dest/state_machine/mock_epoch_cache.js +14 -7
  33. package/dest/state_machine/synchronizer.d.ts +3 -3
  34. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  35. package/dest/txe_session.d.ts +22 -16
  36. package/dest/txe_session.d.ts.map +1 -1
  37. package/dest/txe_session.js +150 -53
  38. package/dest/util/encoding.d.ts +17 -17
  39. package/dest/util/txe_account_store.d.ts +10 -0
  40. package/dest/util/txe_account_store.d.ts.map +1 -0
  41. package/dest/util/{txe_account_data_provider.js → txe_account_store.js} +1 -1
  42. package/dest/util/txe_public_contract_data_source.d.ts +5 -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 +12 -29
  45. package/dest/utils/block_creation.d.ts +4 -4
  46. package/dest/utils/block_creation.d.ts.map +1 -1
  47. package/dest/utils/block_creation.js +18 -5
  48. package/dest/utils/tx_effect_creation.d.ts +2 -3
  49. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  50. package/dest/utils/tx_effect_creation.js +3 -6
  51. package/package.json +16 -16
  52. package/src/constants.ts +3 -0
  53. package/src/index.ts +83 -49
  54. package/src/oracle/interfaces.ts +8 -3
  55. package/src/oracle/txe_oracle_public_context.ts +6 -8
  56. package/src/oracle/txe_oracle_top_level_context.ts +196 -112
  57. package/src/rpc_translator.ts +96 -55
  58. package/src/state_machine/archiver.ts +54 -220
  59. package/src/state_machine/dummy_p2p_client.ts +55 -32
  60. package/src/state_machine/global_variable_builder.ts +1 -1
  61. package/src/state_machine/index.ts +50 -12
  62. package/src/state_machine/mock_epoch_cache.ts +15 -11
  63. package/src/state_machine/synchronizer.ts +2 -2
  64. package/src/txe_session.ts +204 -117
  65. package/src/util/{txe_account_data_provider.ts → txe_account_store.ts} +1 -1
  66. package/src/util/txe_public_contract_data_source.ts +16 -42
  67. package/src/utils/block_creation.ts +19 -16
  68. package/src/utils/tx_effect_creation.ts +3 -11
  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
  73. package/dest/util/txe_contract_data_provider.js +0 -22
  74. package/src/util/txe_contract_data_provider.ts +0 -36
@@ -3,15 +3,19 @@ import { Fr } from '@aztec/foundation/curves/bn254';
3
3
  import { type Logger, createLogger } from '@aztec/foundation/log';
4
4
  import { KeyStore } from '@aztec/key-store';
5
5
  import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
6
- import type { ProtocolContract } from '@aztec/protocol-contracts';
6
+ import type { AccessScopes } from '@aztec/pxe/client/lazy';
7
7
  import {
8
- AddressDataProvider,
9
- CapsuleDataProvider,
10
- NoteDataProvider,
8
+ AddressStore,
9
+ AnchorBlockStore,
10
+ CapsuleStore,
11
+ ContractStore,
12
+ JobCoordinator,
11
13
  NoteService,
12
- PrivateEventDataProvider,
13
- RecipientTaggingDataProvider,
14
- SenderTaggingDataProvider,
14
+ NoteStore,
15
+ PrivateEventStore,
16
+ RecipientTaggingStore,
17
+ SenderAddressBookStore,
18
+ SenderTaggingStore,
15
19
  } from '@aztec/pxe/server';
16
20
  import {
17
21
  ExecutionNoteCache,
@@ -19,10 +23,19 @@ import {
19
23
  HashedValuesCache,
20
24
  type IPrivateExecutionOracle,
21
25
  type IUtilityExecutionOracle,
26
+ Oracle,
22
27
  PrivateExecutionOracle,
23
28
  UtilityExecutionOracle,
24
29
  } from '@aztec/pxe/simulator';
25
- import { FunctionSelector } from '@aztec/stdlib/abi';
30
+ import {
31
+ ExecutionError,
32
+ WASMSimulator,
33
+ createSimulationError,
34
+ extractCallStack,
35
+ resolveAssertionMessageFromError,
36
+ toACVMWitness,
37
+ } from '@aztec/simulator/client';
38
+ import { FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
26
39
  import type { AuthWitness } from '@aztec/stdlib/auth-witness';
27
40
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
28
41
  import { GasSettings } from '@aztec/stdlib/gas';
@@ -33,14 +46,15 @@ import { CallContext, GlobalVariables, TxContext } from '@aztec/stdlib/tx';
33
46
 
34
47
  import { z } from 'zod';
35
48
 
49
+ import { DEFAULT_ADDRESS } from './constants.js';
36
50
  import type { IAvmExecutionOracle, ITxeExecutionOracle } from './oracle/interfaces.js';
37
51
  import { TXEOraclePublicContext } from './oracle/txe_oracle_public_context.js';
38
52
  import { TXEOracleTopLevelContext } from './oracle/txe_oracle_top_level_context.js';
39
53
  import { RPCTranslator } from './rpc_translator.js';
54
+ import { TXEArchiver } from './state_machine/archiver.js';
40
55
  import { TXEStateMachine } from './state_machine/index.js';
41
56
  import type { ForeignCallArgs, ForeignCallResult } from './util/encoding.js';
42
- import { TXEAccountDataProvider } from './util/txe_account_data_provider.js';
43
- import { TXEContractDataProvider } from './util/txe_contract_data_provider.js';
57
+ import { TXEAccountStore } from './util/txe_account_store.js';
44
58
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from './utils/block_creation.js';
45
59
  import { makeTxEffect } from './utils/tx_effect_creation.js';
46
60
 
@@ -63,7 +77,6 @@ type SessionState =
63
77
  | {
64
78
  name: 'PRIVATE';
65
79
  nextBlockGlobalVariables: GlobalVariables;
66
- protocolNullifier: Fr;
67
80
  noteCache: ExecutionNoteCache;
68
81
  taggingIndexCache: ExecutionTaggingIndexCache;
69
82
  }
@@ -100,9 +113,11 @@ export interface TXESessionStateHandler {
100
113
  enterPublicState(contractAddress?: AztecAddress): Promise<void>;
101
114
  enterPrivateState(contractAddress?: AztecAddress, anchorBlockNumber?: BlockNumber): Promise<PrivateContextInputs>;
102
115
  enterUtilityState(contractAddress?: AztecAddress): Promise<void>;
103
- }
104
116
 
105
- export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
117
+ // TODO(F-335): Exposing the job info is abstraction breakage - drop the following 2 functions.
118
+ cycleJob(): Promise<string>;
119
+ getCurrentJob(): string;
120
+ }
106
121
 
107
122
  /**
108
123
  * A `TXESession` corresponds to a Noir `#[test]` function, and handles all of its oracle calls, stores test-specific
@@ -120,56 +135,68 @@ export class TXESession implements TXESessionStateHandler {
120
135
  | IPrivateExecutionOracle
121
136
  | IAvmExecutionOracle
122
137
  | ITxeExecutionOracle,
123
- private contractDataProvider: TXEContractDataProvider,
124
- private noteDataProvider: NoteDataProvider,
138
+ private contractStore: ContractStore,
139
+ private noteStore: NoteStore,
125
140
  private keyStore: KeyStore,
126
- private addressDataProvider: AddressDataProvider,
127
- private accountDataProvider: TXEAccountDataProvider,
128
- private senderTaggingDataProvider: SenderTaggingDataProvider,
129
- private recipientTaggingDataProvider: RecipientTaggingDataProvider,
130
- private capsuleDataProvider: CapsuleDataProvider,
131
- private privateEventDataProvider: PrivateEventDataProvider,
141
+ private addressStore: AddressStore,
142
+ private accountStore: TXEAccountStore,
143
+ private senderTaggingStore: SenderTaggingStore,
144
+ private recipientTaggingStore: RecipientTaggingStore,
145
+ private senderAddressBookStore: SenderAddressBookStore,
146
+ private capsuleStore: CapsuleStore,
147
+ private privateEventStore: PrivateEventStore,
148
+ private jobCoordinator: JobCoordinator,
149
+ private currentJobId: string,
132
150
  private chainId: Fr,
133
151
  private version: Fr,
134
152
  private nextBlockTimestamp: bigint,
135
153
  ) {}
136
154
 
137
- static async init(protocolContracts: ProtocolContract[]) {
155
+ static async init(contractStore: ContractStore) {
138
156
  const store = await openTmpStore('txe-session');
139
157
 
140
- const addressDataProvider = new AddressDataProvider(store);
141
- const privateEventDataProvider = new PrivateEventDataProvider(store);
142
- const contractDataProvider = new TXEContractDataProvider(store);
143
- const noteDataProvider = await NoteDataProvider.create(store);
144
- const senderTaggingDataProvider = new SenderTaggingDataProvider(store);
145
- const recipientTaggingDataProvider = new RecipientTaggingDataProvider(store);
146
- const capsuleDataProvider = new CapsuleDataProvider(store);
158
+ const addressStore = new AddressStore(store);
159
+ const privateEventStore = new PrivateEventStore(store);
160
+ const noteStore = new NoteStore(store);
161
+ const senderTaggingStore = new SenderTaggingStore(store);
162
+ const recipientTaggingStore = new RecipientTaggingStore(store);
163
+ const senderAddressBookStore = new SenderAddressBookStore(store);
164
+ const capsuleStore = new CapsuleStore(store);
147
165
  const keyStore = new KeyStore(store);
148
- const accountDataProvider = new TXEAccountDataProvider(store);
149
-
150
- // Register protocol contracts.
151
- for (const { contractClass, instance, artifact } of protocolContracts) {
152
- await contractDataProvider.addContractArtifact(contractClass.id, artifact);
153
- await contractDataProvider.addContractInstance(instance);
154
- }
155
-
156
- const stateMachine = await TXEStateMachine.create(store);
166
+ const accountStore = new TXEAccountStore(store);
167
+
168
+ // Create job coordinator and register staged stores
169
+ const jobCoordinator = new JobCoordinator(store);
170
+ jobCoordinator.registerStores([
171
+ capsuleStore,
172
+ senderTaggingStore,
173
+ recipientTaggingStore,
174
+ privateEventStore,
175
+ noteStore,
176
+ ]);
177
+
178
+ const archiver = new TXEArchiver(store);
179
+ const anchorBlockStore = new AnchorBlockStore(store);
180
+ const stateMachine = await TXEStateMachine.create(archiver, anchorBlockStore, contractStore, noteStore);
157
181
 
158
182
  const nextBlockTimestamp = BigInt(Math.floor(new Date().getTime() / 1000));
159
183
  const version = new Fr(await stateMachine.node.getVersion());
160
184
  const chainId = new Fr(await stateMachine.node.getChainId());
161
185
 
186
+ const initialJobId = jobCoordinator.beginJob();
187
+
162
188
  const topLevelOracleHandler = new TXEOracleTopLevelContext(
163
189
  stateMachine,
164
- contractDataProvider,
165
- noteDataProvider,
190
+ contractStore,
191
+ noteStore,
166
192
  keyStore,
167
- addressDataProvider,
168
- accountDataProvider,
169
- senderTaggingDataProvider,
170
- recipientTaggingDataProvider,
171
- capsuleDataProvider,
172
- privateEventDataProvider,
193
+ addressStore,
194
+ accountStore,
195
+ senderTaggingStore,
196
+ recipientTaggingStore,
197
+ senderAddressBookStore,
198
+ capsuleStore,
199
+ privateEventStore,
173
200
  nextBlockTimestamp,
174
201
  version,
175
202
  chainId,
@@ -181,15 +208,18 @@ export class TXESession implements TXESessionStateHandler {
181
208
  createLogger('txe:session'),
182
209
  stateMachine,
183
210
  topLevelOracleHandler,
184
- contractDataProvider,
185
- noteDataProvider,
211
+ contractStore,
212
+ noteStore,
186
213
  keyStore,
187
- addressDataProvider,
188
- accountDataProvider,
189
- senderTaggingDataProvider,
190
- recipientTaggingDataProvider,
191
- capsuleDataProvider,
192
- privateEventDataProvider,
214
+ addressStore,
215
+ accountStore,
216
+ senderTaggingStore,
217
+ recipientTaggingStore,
218
+ senderAddressBookStore,
219
+ capsuleStore,
220
+ privateEventStore,
221
+ jobCoordinator,
222
+ initialJobId,
193
223
  version,
194
224
  chainId,
195
225
  nextBlockTimestamp,
@@ -227,6 +257,17 @@ export class TXESession implements TXESessionStateHandler {
227
257
  }
228
258
  }
229
259
 
260
+ getCurrentJob(): string {
261
+ return this.currentJobId;
262
+ }
263
+
264
+ /** Commits the current job and begins a new one. Returns the new job ID. */
265
+ async cycleJob(): Promise<string> {
266
+ await this.jobCoordinator.commitJob(this.currentJobId);
267
+ this.currentJobId = this.jobCoordinator.beginJob();
268
+ return this.currentJobId;
269
+ }
270
+
230
271
  async enterTopLevelState() {
231
272
  switch (this.state.name) {
232
273
  case 'PRIVATE': {
@@ -249,17 +290,21 @@ export class TXESession implements TXESessionStateHandler {
249
290
  }
250
291
  }
251
292
 
293
+ // Commit all staged stores from the job that was just completed, then begin a new job
294
+ await this.cycleJob();
295
+
252
296
  this.oracleHandler = new TXEOracleTopLevelContext(
253
297
  this.stateMachine,
254
- this.contractDataProvider,
255
- this.noteDataProvider,
298
+ this.contractStore,
299
+ this.noteStore,
256
300
  this.keyStore,
257
- this.addressDataProvider,
258
- this.accountDataProvider,
259
- this.senderTaggingDataProvider,
260
- this.recipientTaggingDataProvider,
261
- this.capsuleDataProvider,
262
- this.privateEventDataProvider,
301
+ this.addressStore,
302
+ this.accountStore,
303
+ this.senderTaggingStore,
304
+ this.recipientTaggingStore,
305
+ this.senderAddressBookStore,
306
+ this.capsuleStore,
307
+ this.privateEventStore,
263
308
  this.nextBlockTimestamp,
264
309
  this.version,
265
310
  this.chainId,
@@ -276,21 +321,15 @@ export class TXESession implements TXESessionStateHandler {
276
321
  ): Promise<PrivateContextInputs> {
277
322
  this.exitTopLevelState();
278
323
 
279
- // There is no automatic message discovery and contract-driven syncing process in inlined private or utility
280
- // contexts, which means that known nullifiers are also not searched for, since it is during the tagging sync that
281
- // we perform this. We therefore search for known nullifiers now, as otherwise notes that were nullified would not
282
- // be removed from the database.
283
- // TODO(#12553): make the synchronizer sync here instead and remove this
284
- await new NoteService(
285
- this.noteDataProvider,
286
- this.stateMachine.node,
287
- this.stateMachine.anchorBlockDataProvider,
288
- ).syncNoteNullifiers(contractAddress);
289
-
290
324
  // Private execution has two associated block numbers: the anchor block (i.e. the historical block that is used to
291
325
  // build the proof), and the *next* block, i.e. the one we'll create once the execution ends, and which will contain
292
326
  // a single transaction with the effects of what was done in the test.
293
327
  const anchorBlock = await this.stateMachine.node.getBlockHeader(anchorBlockNumber ?? 'latest');
328
+
329
+ await new NoteService(this.noteStore, this.stateMachine.node, anchorBlock!, this.currentJobId).syncNoteNullifiers(
330
+ contractAddress,
331
+ 'ALL_SCOPES',
332
+ );
294
333
  const latestBlock = await this.stateMachine.node.getBlockHeader('latest');
295
334
 
296
335
  const nextBlockGlobalVariables = makeGlobalVariables(undefined, {
@@ -305,34 +344,39 @@ export class TXESession implements TXESessionStateHandler {
305
344
  const noteCache = new ExecutionNoteCache(protocolNullifier);
306
345
  const taggingIndexCache = new ExecutionTaggingIndexCache();
307
346
 
308
- this.oracleHandler = new PrivateExecutionOracle(
309
- Fr.ZERO,
310
- new TxContext(this.chainId, this.version, GasSettings.empty()),
311
- new CallContext(AztecAddress.ZERO, contractAddress, FunctionSelector.empty(), false),
312
- anchorBlock!,
313
- [],
314
- [],
315
- new HashedValuesCache(),
347
+ const utilityExecutor = this.utilityExecutorForContractSync(anchorBlock);
348
+ this.oracleHandler = new PrivateExecutionOracle({
349
+ argsHash: Fr.ZERO,
350
+ txContext: new TxContext(this.chainId, this.version, GasSettings.empty()),
351
+ callContext: new CallContext(AztecAddress.ZERO, contractAddress, FunctionSelector.empty(), false),
352
+ anchorBlockHeader: anchorBlock!,
353
+ utilityExecutor,
354
+ authWitnesses: [],
355
+ capsules: [],
356
+ executionCache: new HashedValuesCache(),
316
357
  noteCache,
317
358
  taggingIndexCache,
318
- this.contractDataProvider,
319
- this.noteDataProvider,
320
- this.keyStore,
321
- this.addressDataProvider,
322
- this.stateMachine.node,
323
- this.stateMachine.anchorBlockDataProvider,
324
- this.senderTaggingDataProvider,
325
- this.recipientTaggingDataProvider,
326
- this.capsuleDataProvider,
327
- this.privateEventDataProvider,
328
- );
359
+ contractStore: this.contractStore,
360
+ noteStore: this.noteStore,
361
+ keyStore: this.keyStore,
362
+ addressStore: this.addressStore,
363
+ aztecNode: this.stateMachine.node,
364
+ senderTaggingStore: this.senderTaggingStore,
365
+ recipientTaggingStore: this.recipientTaggingStore,
366
+ senderAddressBookStore: this.senderAddressBookStore,
367
+ capsuleStore: this.capsuleStore,
368
+ privateEventStore: this.privateEventStore,
369
+ contractSyncService: this.stateMachine.contractSyncService,
370
+ jobId: this.currentJobId,
371
+ scopes: 'ALL_SCOPES',
372
+ });
329
373
 
330
374
  // We store the note and tagging index caches fed into the PrivateExecutionOracle (along with some other auxiliary
331
375
  // data) in order to refer to it later, mimicking the way this object is used by the ContractFunctionSimulator. The
332
376
  // difference resides in that the simulator has all information needed in order to run the simulation, while ours
333
377
  // will be ongoing as the different oracles will be invoked from the Noir test, until eventually the private
334
378
  // execution finishes.
335
- this.state = { name: 'PRIVATE', nextBlockGlobalVariables, protocolNullifier, noteCache, taggingIndexCache };
379
+ this.state = { name: 'PRIVATE', nextBlockGlobalVariables, noteCache, taggingIndexCache };
336
380
  this.logger.debug(`Entered state ${this.state.name}`);
337
381
 
338
382
  return (this.oracleHandler as PrivateExecutionOracle).getPrivateContextInputs();
@@ -365,35 +409,37 @@ export class TXESession implements TXESessionStateHandler {
365
409
  async enterUtilityState(contractAddress: AztecAddress = DEFAULT_ADDRESS) {
366
410
  this.exitTopLevelState();
367
411
 
412
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
413
+
368
414
  // There is no automatic message discovery and contract-driven syncing process in inlined private or utility
369
415
  // contexts, which means that known nullifiers are also not searched for, since it is during the tagging sync that
370
416
  // we perform this. We therefore search for known nullifiers now, as otherwise notes that were nullified would not
371
417
  // be removed from the database.
372
418
  // TODO(#12553): make the synchronizer sync here instead and remove this
373
419
  await new NoteService(
374
- this.noteDataProvider,
420
+ this.noteStore,
375
421
  this.stateMachine.node,
376
- this.stateMachine.anchorBlockDataProvider,
377
- ).syncNoteNullifiers(contractAddress);
378
-
379
- const anchorBlockHeader = await this.stateMachine.anchorBlockDataProvider.getBlockHeader();
422
+ anchorBlockHeader,
423
+ this.currentJobId,
424
+ ).syncNoteNullifiers(contractAddress, 'ALL_SCOPES');
380
425
 
381
- this.oracleHandler = new UtilityExecutionOracle(
426
+ this.oracleHandler = new UtilityExecutionOracle({
382
427
  contractAddress,
383
- [],
384
- [],
428
+ authWitnesses: [],
429
+ capsules: [],
385
430
  anchorBlockHeader,
386
- this.contractDataProvider,
387
- this.noteDataProvider,
388
- this.keyStore,
389
- this.addressDataProvider,
390
- this.stateMachine.node,
391
- this.stateMachine.anchorBlockDataProvider,
392
- this.senderTaggingDataProvider,
393
- this.recipientTaggingDataProvider,
394
- this.capsuleDataProvider,
395
- this.privateEventDataProvider,
396
- );
431
+ contractStore: this.contractStore,
432
+ noteStore: this.noteStore,
433
+ keyStore: this.keyStore,
434
+ addressStore: this.addressStore,
435
+ aztecNode: this.stateMachine.node,
436
+ recipientTaggingStore: this.recipientTaggingStore,
437
+ senderAddressBookStore: this.senderAddressBookStore,
438
+ capsuleStore: this.capsuleStore,
439
+ privateEventStore: this.privateEventStore,
440
+ jobId: this.currentJobId,
441
+ scopes: 'ALL_SCOPES',
442
+ });
397
443
 
398
444
  this.state = { name: 'UTILITY' };
399
445
  this.logger.debug(`Entered state ${this.state.name}`);
@@ -428,11 +474,7 @@ export class TXESession implements TXESessionStateHandler {
428
474
  // We rely on the note cache to determine the effects of the transaction. This is incomplete as it doesn't private
429
475
  // logs (other effects like enqueued public calls don't need to be considered since those are not allowed).
430
476
 
431
- const txEffect = await makeTxEffect(
432
- this.state.noteCache,
433
- this.state.protocolNullifier,
434
- this.state.nextBlockGlobalVariables.blockNumber,
435
- );
477
+ const txEffect = await makeTxEffect(this.state.noteCache, this.state.nextBlockGlobalVariables.blockNumber);
436
478
 
437
479
  // We build a block holding just this transaction
438
480
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
@@ -463,4 +505,49 @@ export class TXESession implements TXESessionStateHandler {
463
505
  throw new Error(`Expected to be in state 'UTILITY', but got '${this.state.name}' instead`);
464
506
  }
465
507
  }
508
+
509
+ private utilityExecutorForContractSync(anchorBlock: any) {
510
+ return async (call: FunctionCall, scopes: AccessScopes) => {
511
+ const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
512
+ if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
513
+ throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
514
+ }
515
+
516
+ try {
517
+ const oracle = new UtilityExecutionOracle({
518
+ contractAddress: call.to,
519
+ authWitnesses: [],
520
+ capsules: [],
521
+ anchorBlockHeader: anchorBlock!,
522
+ contractStore: this.contractStore,
523
+ noteStore: this.noteStore,
524
+ keyStore: this.keyStore,
525
+ addressStore: this.addressStore,
526
+ aztecNode: this.stateMachine.node,
527
+ recipientTaggingStore: this.recipientTaggingStore,
528
+ senderAddressBookStore: this.senderAddressBookStore,
529
+ capsuleStore: this.capsuleStore,
530
+ privateEventStore: this.privateEventStore,
531
+ jobId: this.currentJobId,
532
+ scopes,
533
+ });
534
+ await new WASMSimulator()
535
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
536
+ .catch((err: Error) => {
537
+ err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
538
+ throw new ExecutionError(
539
+ err.message,
540
+ {
541
+ contractAddress: call.to,
542
+ functionSelector: call.selector,
543
+ },
544
+ extractCallStack(err, entryPointArtifact.debug),
545
+ { cause: err },
546
+ );
547
+ });
548
+ } catch (err) {
549
+ throw createSimulationError(err instanceof Error ? err : new Error('Unknown error contract data sync'));
550
+ }
551
+ };
552
+ }
466
553
  }
@@ -2,7 +2,7 @@ import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
2
2
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
3
3
  import { CompleteAddress } from '@aztec/stdlib/contract';
4
4
 
5
- export class TXEAccountDataProvider {
5
+ export class TXEAccountStore {
6
6
  #accounts: AztecAsyncMap<string, Buffer>;
7
7
 
8
8
  constructor(store: AztecAsyncKVStore) {
@@ -1,22 +1,14 @@
1
1
  import { BlockNumber } from '@aztec/foundation/branded-types';
2
2
  import { Fr } from '@aztec/foundation/curves/bn254';
3
- import type { ContractDataProvider } from '@aztec/pxe/server';
4
- import { type ContractArtifact, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
3
+ import type { ContractStore } from '@aztec/pxe/server';
4
+ import { type ContractArtifact, FunctionSelector } from '@aztec/stdlib/abi';
5
5
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
6
- import {
7
- type ContractClassPublic,
8
- type ContractDataSource,
9
- type ContractInstanceWithAddress,
10
- computePrivateFunctionsRoot,
11
- computePublicBytecodeCommitment,
12
- getContractClassPrivateFunctionFromArtifact,
13
- } from '@aztec/stdlib/contract';
6
+ import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
14
7
 
15
8
  export class TXEPublicContractDataSource implements ContractDataSource {
16
- #privateFunctionsRoot: Map<string, Buffer> = new Map();
17
9
  constructor(
18
10
  private blockNumber: BlockNumber,
19
- private contractDataProvider: ContractDataProvider,
11
+ private contractStore: ContractStore,
20
12
  ) {}
21
13
 
22
14
  getBlockNumber(): Promise<BlockNumber> {
@@ -24,46 +16,28 @@ export class TXEPublicContractDataSource implements ContractDataSource {
24
16
  }
25
17
 
26
18
  async getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
27
- const contractClass = await this.contractDataProvider.getContractClass(id);
19
+ const contractClass = await this.contractStore.getContractClassWithPreimage(id);
28
20
  if (!contractClass) {
29
21
  return;
30
22
  }
31
- const artifact = await this.contractDataProvider.getContractArtifact(id);
32
- if (!artifact) {
33
- return;
34
- }
35
-
36
- let privateFunctionsRoot;
37
- if (!this.#privateFunctionsRoot.has(id.toString())) {
38
- const privateFunctions = await Promise.all(
39
- artifact.functions
40
- .filter(fn => fn.functionType === FunctionType.PRIVATE)
41
- .map(fn => getContractClassPrivateFunctionFromArtifact(fn)),
42
- );
43
- privateFunctionsRoot = await computePrivateFunctionsRoot(privateFunctions);
44
- this.#privateFunctionsRoot.set(id.toString(), privateFunctionsRoot.toBuffer());
45
- } else {
46
- privateFunctionsRoot = Fr.fromBuffer(this.#privateFunctionsRoot.get(id.toString())!);
47
- }
48
-
49
23
  return {
50
- id,
51
- artifactHash: contractClass!.artifactHash,
52
- packedBytecode: contractClass!.packedBytecode,
53
- privateFunctionsRoot,
54
- version: contractClass!.version,
24
+ id: contractClass.id,
25
+ artifactHash: contractClass.artifactHash,
26
+ packedBytecode: contractClass.packedBytecode,
27
+ privateFunctionsRoot: contractClass.privateFunctionsRoot,
28
+ version: contractClass.version,
55
29
  privateFunctions: [],
56
30
  utilityFunctions: [],
57
31
  };
58
32
  }
59
33
 
60
34
  async getBytecodeCommitment(id: Fr): Promise<Fr | undefined> {
61
- const contractClass = await this.contractDataProvider.getContractClass(id);
62
- return contractClass && computePublicBytecodeCommitment(contractClass.packedBytecode);
35
+ const contractClass = await this.contractStore.getContractClassWithPreimage(id);
36
+ return contractClass?.publicBytecodeCommitment;
63
37
  }
64
38
 
65
39
  async getContract(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
66
- const instance = await this.contractDataProvider.getContractInstance(address);
40
+ const instance = await this.contractStore.getContractInstance(address);
67
41
  return instance && { ...instance, address };
68
42
  }
69
43
 
@@ -72,12 +46,12 @@ export class TXEPublicContractDataSource implements ContractDataSource {
72
46
  }
73
47
 
74
48
  async getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined> {
75
- const instance = await this.contractDataProvider.getContractInstance(address);
76
- return instance && this.contractDataProvider.getContractArtifact(instance.currentContractClassId);
49
+ const instance = await this.contractStore.getContractInstance(address);
50
+ return instance && this.contractStore.getContractArtifact(instance.currentContractClassId);
77
51
  }
78
52
 
79
53
  async getDebugFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
80
- return await this.contractDataProvider.getDebugFunctionName(address, selector);
54
+ return await this.contractStore.getDebugFunctionName(address, selector);
81
55
  }
82
56
 
83
57
  registerContractFunctionSignatures(_signatures: []): Promise<void> {
@@ -4,13 +4,12 @@ import {
4
4
  NULLIFIER_SUBTREE_HEIGHT,
5
5
  NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
6
6
  } from '@aztec/constants';
7
- import { BlockNumber } from '@aztec/foundation/branded-types';
7
+ import { BlockNumber, CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types';
8
8
  import { padArrayEnd } from '@aztec/foundation/collection';
9
9
  import { Fr } from '@aztec/foundation/curves/bn254';
10
- import { Body, L2Block, L2BlockHeader } from '@aztec/stdlib/block';
11
- import { makeContentCommitment } from '@aztec/stdlib/testing';
10
+ import { Body, L2Block } from '@aztec/stdlib/block';
12
11
  import { AppendOnlyTreeSnapshot, MerkleTreeId, type MerkleTreeWriteOperations } from '@aztec/stdlib/trees';
13
- import { GlobalVariables, TxEffect } from '@aztec/stdlib/tx';
12
+ import { BlockHeader, GlobalVariables, TxEffect } from '@aztec/stdlib/tx';
14
13
 
15
14
  /**
16
15
  * Returns a transaction request hash that is valid for transactions that are the only ones in a block.
@@ -47,20 +46,18 @@ export async function insertTxEffectIntoWorldTrees(
47
46
  export async function makeTXEBlockHeader(
48
47
  worldTrees: MerkleTreeWriteOperations,
49
48
  globalVariables: GlobalVariables,
50
- ): Promise<L2BlockHeader> {
49
+ ): Promise<BlockHeader> {
51
50
  const stateReference = await worldTrees.getStateReference();
52
51
  const archiveInfo = await worldTrees.getTreeInfo(MerkleTreeId.ARCHIVE);
53
52
 
54
- return new L2BlockHeader(
55
- new AppendOnlyTreeSnapshot(new Fr(archiveInfo.root), Number(archiveInfo.size)),
56
- makeContentCommitment(),
57
- stateReference,
53
+ return BlockHeader.from({
54
+ lastArchive: new AppendOnlyTreeSnapshot(new Fr(archiveInfo.root), Number(archiveInfo.size)),
55
+ spongeBlobHash: Fr.ZERO,
56
+ state: stateReference,
58
57
  globalVariables,
59
- Fr.ZERO,
60
- Fr.ZERO,
61
- Fr.ZERO,
62
- Fr.ZERO,
63
- );
58
+ totalFees: Fr.ZERO,
59
+ totalManaUsed: Fr.ZERO,
60
+ });
64
61
  }
65
62
 
66
63
  /**
@@ -84,11 +81,17 @@ export async function makeTXEBlock(
84
81
  const header = await makeTXEBlockHeader(worldTrees, globalVariables);
85
82
 
86
83
  // Update the archive tree with this block's header hash
87
- await worldTrees.updateArchive(header.toBlockHeader());
84
+ await worldTrees.updateArchive(header);
88
85
 
89
86
  // Get the new archive state after updating
90
87
  const newArchiveInfo = await worldTrees.getTreeInfo(MerkleTreeId.ARCHIVE);
91
88
  const newArchive = new AppendOnlyTreeSnapshot(new Fr(newArchiveInfo.root), Number(newArchiveInfo.size));
92
89
 
93
- return new L2Block(newArchive, header, new Body(txEffects));
90
+ // L2Block requires checkpointNumber and indexWithinCheckpoint.
91
+ // TXE uses 1-block-per-checkpoint for testing simplicity, so we can use block number as checkpoint number.
92
+ // This uses the deprecated fromBlockNumber method intentionally for the TXE testing environment.
93
+ const checkpointNumber = CheckpointNumber.fromBlockNumber(globalVariables.blockNumber);
94
+ const indexWithinCheckpoint = IndexWithinCheckpoint(0);
95
+
96
+ return new L2Block(newArchive, header, new Body(txEffects), checkpointNumber, indexWithinCheckpoint);
94
97
  }