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

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 (81) 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 +91 -56
  8. package/dest/oracle/interfaces.d.ts +33 -29
  9. package/dest/oracle/interfaces.d.ts.map +1 -1
  10. package/dest/oracle/txe_oracle_public_context.d.ts +16 -16
  11. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  12. package/dest/oracle/txe_oracle_public_context.js +20 -22
  13. package/dest/oracle/txe_oracle_top_level_context.d.ts +37 -27
  14. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  15. package/dest/oracle/txe_oracle_top_level_context.js +228 -106
  16. package/dest/rpc_translator.d.ts +98 -78
  17. package/dest/rpc_translator.d.ts.map +1 -1
  18. package/dest/rpc_translator.js +367 -171
  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 +66 -99
  22. package/dest/state_machine/dummy_p2p_client.d.ts +21 -14
  23. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  24. package/dest/state_machine/dummy_p2p_client.js +42 -22
  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 +9 -7
  29. package/dest/state_machine/index.d.ts.map +1 -1
  30. package/dest/state_machine/index.js +44 -23
  31. package/dest/state_machine/mock_epoch_cache.d.ts +30 -12
  32. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  33. package/dest/state_machine/mock_epoch_cache.js +53 -15
  34. package/dest/state_machine/synchronizer.d.ts +6 -5
  35. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  36. package/dest/state_machine/synchronizer.js +8 -7
  37. package/dest/txe_session.d.ts +27 -15
  38. package/dest/txe_session.d.ts.map +1 -1
  39. package/dest/txe_session.js +173 -56
  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_public_contract_data_source.d.ts +8 -8
  49. package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
  50. package/dest/util/txe_public_contract_data_source.js +12 -29
  51. package/dest/utils/block_creation.d.ts +21 -6
  52. package/dest/utils/block_creation.d.ts.map +1 -1
  53. package/dest/utils/block_creation.js +38 -4
  54. package/dest/utils/tx_effect_creation.d.ts +3 -3
  55. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  56. package/dest/utils/tx_effect_creation.js +4 -7
  57. package/package.json +18 -17
  58. package/src/constants.ts +3 -0
  59. package/src/index.ts +103 -63
  60. package/src/oracle/interfaces.ts +36 -32
  61. package/src/oracle/txe_oracle_public_context.ts +21 -28
  62. package/src/oracle/txe_oracle_top_level_context.ts +272 -145
  63. package/src/rpc_translator.ts +422 -194
  64. package/src/state_machine/archiver.ts +63 -117
  65. package/src/state_machine/dummy_p2p_client.ts +59 -29
  66. package/src/state_machine/global_variable_builder.ts +22 -4
  67. package/src/state_machine/index.ts +64 -21
  68. package/src/state_machine/mock_epoch_cache.ts +67 -23
  69. package/src/state_machine/synchronizer.ts +9 -8
  70. package/src/txe_session.ts +239 -105
  71. package/src/util/encoding.ts +1 -1
  72. package/src/util/{txe_account_data_provider.ts → txe_account_store.ts} +1 -1
  73. package/src/util/txe_public_contract_data_source.ts +20 -45
  74. package/src/utils/block_creation.ts +49 -14
  75. package/src/utils/tx_effect_creation.ts +5 -12
  76. package/dest/util/txe_account_data_provider.d.ts +0 -10
  77. package/dest/util/txe_account_data_provider.d.ts.map +0 -1
  78. package/dest/util/txe_contract_data_provider.d.ts +0 -12
  79. package/dest/util/txe_contract_data_provider.d.ts.map +0 -1
  80. package/dest/util/txe_contract_data_provider.js +0 -22
  81. package/src/util/txe_contract_data_provider.ts +0 -36
@@ -1,15 +1,22 @@
1
- import { Fr } from '@aztec/foundation/fields';
1
+ import { BlockNumber } from '@aztec/foundation/branded-types';
2
+ import { Fr } from '@aztec/foundation/curves/bn254';
2
3
  import { type Logger, createLogger } from '@aztec/foundation/log';
3
4
  import { KeyStore } from '@aztec/key-store';
4
5
  import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
5
- import type { ProtocolContract } from '@aztec/protocol-contracts';
6
+ import type { AccessScopes } from '@aztec/pxe/client/lazy';
6
7
  import {
7
- AddressDataProvider,
8
- CapsuleDataProvider,
9
- NoteDataProvider,
10
- PXEOracleInterface,
11
- PrivateEventDataProvider,
12
- TaggingDataProvider,
8
+ AddressStore,
9
+ AnchorBlockStore,
10
+ CapsuleStore,
11
+ ContractStore,
12
+ ContractSyncService,
13
+ JobCoordinator,
14
+ NoteService,
15
+ NoteStore,
16
+ PrivateEventStore,
17
+ RecipientTaggingStore,
18
+ SenderAddressBookStore,
19
+ SenderTaggingStore,
13
20
  } from '@aztec/pxe/server';
14
21
  import {
15
22
  ExecutionNoteCache,
@@ -17,34 +24,39 @@ import {
17
24
  HashedValuesCache,
18
25
  type IPrivateExecutionOracle,
19
26
  type IUtilityExecutionOracle,
27
+ Oracle,
20
28
  PrivateExecutionOracle,
21
29
  UtilityExecutionOracle,
22
30
  } from '@aztec/pxe/simulator';
23
- import { FunctionSelector } from '@aztec/stdlib/abi';
31
+ import {
32
+ ExecutionError,
33
+ WASMSimulator,
34
+ createSimulationError,
35
+ extractCallStack,
36
+ resolveAssertionMessageFromError,
37
+ toACVMWitness,
38
+ } from '@aztec/simulator/client';
39
+ import { FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
24
40
  import type { AuthWitness } from '@aztec/stdlib/auth-witness';
25
41
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
26
- import { Body, L2Block } from '@aztec/stdlib/block';
27
42
  import { GasSettings } from '@aztec/stdlib/gas';
43
+ import { computeProtocolNullifier } from '@aztec/stdlib/hash';
28
44
  import { PrivateContextInputs } from '@aztec/stdlib/kernel';
29
- import { makeAppendOnlyTreeSnapshot, makeGlobalVariables } from '@aztec/stdlib/testing';
45
+ import { makeGlobalVariables } from '@aztec/stdlib/testing';
30
46
  import { CallContext, GlobalVariables, TxContext } from '@aztec/stdlib/tx';
31
- import type { UInt32 } from '@aztec/stdlib/types';
32
47
 
33
48
  import { z } from 'zod';
34
49
 
50
+ import { DEFAULT_ADDRESS } from './constants.js';
35
51
  import type { IAvmExecutionOracle, ITxeExecutionOracle } from './oracle/interfaces.js';
36
52
  import { TXEOraclePublicContext } from './oracle/txe_oracle_public_context.js';
37
53
  import { TXEOracleTopLevelContext } from './oracle/txe_oracle_top_level_context.js';
38
54
  import { RPCTranslator } from './rpc_translator.js';
55
+ import { TXEArchiver } from './state_machine/archiver.js';
39
56
  import { TXEStateMachine } from './state_machine/index.js';
40
57
  import type { ForeignCallArgs, ForeignCallResult } from './util/encoding.js';
41
- import { TXEAccountDataProvider } from './util/txe_account_data_provider.js';
42
- import { TXEContractDataProvider } from './util/txe_contract_data_provider.js';
43
- import {
44
- getSingleTxBlockRequestHash,
45
- insertTxEffectIntoWorldTrees,
46
- makeTXEBlockHeader,
47
- } from './utils/block_creation.js';
58
+ import { TXEAccountStore } from './util/txe_account_store.js';
59
+ import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from './utils/block_creation.js';
48
60
  import { makeTxEffect } from './utils/tx_effect_creation.js';
49
61
 
50
62
  /**
@@ -66,7 +78,6 @@ type SessionState =
66
78
  | {
67
79
  name: 'PRIVATE';
68
80
  nextBlockGlobalVariables: GlobalVariables;
69
- txRequestHash: Fr;
70
81
  noteCache: ExecutionNoteCache;
71
82
  taggingIndexCache: ExecutionTaggingIndexCache;
72
83
  }
@@ -101,11 +112,13 @@ export type TXEOracleFunctionName = Exclude<
101
112
  export interface TXESessionStateHandler {
102
113
  enterTopLevelState(): Promise<void>;
103
114
  enterPublicState(contractAddress?: AztecAddress): Promise<void>;
104
- enterPrivateState(contractAddress?: AztecAddress, anchorBlockNumber?: UInt32): Promise<PrivateContextInputs>;
115
+ enterPrivateState(contractAddress?: AztecAddress, anchorBlockNumber?: BlockNumber): Promise<PrivateContextInputs>;
105
116
  enterUtilityState(contractAddress?: AztecAddress): Promise<void>;
106
- }
107
117
 
108
- const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
118
+ // TODO(F-335): Exposing the job info is abstraction breakage - drop the following 2 functions.
119
+ cycleJob(): Promise<string>;
120
+ getCurrentJob(): string;
121
+ }
109
122
 
110
123
  /**
111
124
  * A `TXESession` corresponds to a Noir `#[test]` function, and handles all of its oracle calls, stores test-specific
@@ -123,78 +136,100 @@ export class TXESession implements TXESessionStateHandler {
123
136
  | IPrivateExecutionOracle
124
137
  | IAvmExecutionOracle
125
138
  | ITxeExecutionOracle,
126
- private contractDataProvider: TXEContractDataProvider,
139
+ private contractStore: ContractStore,
140
+ private noteStore: NoteStore,
127
141
  private keyStore: KeyStore,
128
- private addressDataProvider: AddressDataProvider,
129
- private accountDataProvider: TXEAccountDataProvider,
142
+ private addressStore: AddressStore,
143
+ private accountStore: TXEAccountStore,
144
+ private senderTaggingStore: SenderTaggingStore,
145
+ private recipientTaggingStore: RecipientTaggingStore,
146
+ private senderAddressBookStore: SenderAddressBookStore,
147
+ private capsuleStore: CapsuleStore,
148
+ private privateEventStore: PrivateEventStore,
149
+ private jobCoordinator: JobCoordinator,
150
+ private currentJobId: string,
130
151
  private chainId: Fr,
131
152
  private version: Fr,
132
153
  private nextBlockTimestamp: bigint,
133
- private pxeOracleInterface: PXEOracleInterface,
154
+ private contractSyncService: ContractSyncService,
134
155
  ) {}
135
156
 
136
- static async init(protocolContracts: ProtocolContract[]) {
157
+ static async init(contractStore: ContractStore) {
137
158
  const store = await openTmpStore('txe-session');
138
159
 
139
- const addressDataProvider = new AddressDataProvider(store);
140
- const privateEventDataProvider = new PrivateEventDataProvider(store);
141
- const contractDataProvider = new TXEContractDataProvider(store);
142
- const noteDataProvider = await NoteDataProvider.create(store);
143
- const taggingDataProvider = new TaggingDataProvider(store);
144
- const capsuleDataProvider = new CapsuleDataProvider(store);
160
+ const addressStore = new AddressStore(store);
161
+ const privateEventStore = new PrivateEventStore(store);
162
+ const noteStore = new NoteStore(store);
163
+ const senderTaggingStore = new SenderTaggingStore(store);
164
+ const recipientTaggingStore = new RecipientTaggingStore(store);
165
+ const senderAddressBookStore = new SenderAddressBookStore(store);
166
+ const capsuleStore = new CapsuleStore(store);
145
167
  const keyStore = new KeyStore(store);
146
- const accountDataProvider = new TXEAccountDataProvider(store);
147
-
148
- // Register protocol contracts.
149
- for (const { contractClass, instance, artifact } of protocolContracts) {
150
- await contractDataProvider.addContractArtifact(contractClass.id, artifact);
151
- await contractDataProvider.addContractInstance(instance);
152
- }
153
-
154
- const stateMachine = await TXEStateMachine.create(store);
168
+ const accountStore = new TXEAccountStore(store);
169
+
170
+ // Create job coordinator and register staged stores
171
+ const jobCoordinator = new JobCoordinator(store);
172
+ jobCoordinator.registerStores([
173
+ capsuleStore,
174
+ senderTaggingStore,
175
+ recipientTaggingStore,
176
+ privateEventStore,
177
+ noteStore,
178
+ ]);
179
+
180
+ const archiver = new TXEArchiver(store);
181
+ const anchorBlockStore = new AnchorBlockStore(store);
182
+ const stateMachine = await TXEStateMachine.create(archiver, anchorBlockStore, contractStore, noteStore);
155
183
 
156
184
  const nextBlockTimestamp = BigInt(Math.floor(new Date().getTime() / 1000));
157
185
  const version = new Fr(await stateMachine.node.getVersion());
158
186
  const chainId = new Fr(await stateMachine.node.getChainId());
159
187
 
160
- const pxeOracleInterface = new PXEOracleInterface(
161
- stateMachine.node,
162
- keyStore,
163
- contractDataProvider,
164
- noteDataProvider,
165
- capsuleDataProvider,
166
- stateMachine.syncDataProvider,
167
- taggingDataProvider,
168
- addressDataProvider,
169
- privateEventDataProvider,
170
- );
188
+ const initialJobId = jobCoordinator.beginJob();
189
+
190
+ const logger = createLogger('txe:session');
191
+ const contractSyncService = new ContractSyncService(stateMachine.node, contractStore, noteStore, logger);
171
192
 
172
193
  const topLevelOracleHandler = new TXEOracleTopLevelContext(
173
194
  stateMachine,
174
- contractDataProvider,
195
+ contractStore,
196
+ noteStore,
175
197
  keyStore,
176
- addressDataProvider,
177
- accountDataProvider,
178
- pxeOracleInterface,
198
+ addressStore,
199
+ accountStore,
200
+ senderTaggingStore,
201
+ recipientTaggingStore,
202
+ senderAddressBookStore,
203
+ capsuleStore,
204
+ privateEventStore,
179
205
  nextBlockTimestamp,
180
206
  version,
181
207
  chainId,
182
208
  new Map(),
209
+ contractSyncService,
183
210
  );
184
- await topLevelOracleHandler.txeAdvanceBlocksBy(1);
211
+ await topLevelOracleHandler.advanceBlocksBy(1);
185
212
 
186
213
  return new TXESession(
187
- createLogger('txe:session'),
214
+ logger,
188
215
  stateMachine,
189
216
  topLevelOracleHandler,
190
- contractDataProvider,
217
+ contractStore,
218
+ noteStore,
191
219
  keyStore,
192
- addressDataProvider,
193
- accountDataProvider,
220
+ addressStore,
221
+ accountStore,
222
+ senderTaggingStore,
223
+ recipientTaggingStore,
224
+ senderAddressBookStore,
225
+ capsuleStore,
226
+ privateEventStore,
227
+ jobCoordinator,
228
+ initialJobId,
194
229
  version,
195
230
  chainId,
196
231
  nextBlockTimestamp,
197
- pxeOracleInterface,
232
+ contractSyncService,
198
233
  );
199
234
  }
200
235
 
@@ -229,6 +264,17 @@ export class TXESession implements TXESessionStateHandler {
229
264
  }
230
265
  }
231
266
 
267
+ getCurrentJob(): string {
268
+ return this.currentJobId;
269
+ }
270
+
271
+ /** Commits the current job and begins a new one. Returns the new job ID. */
272
+ async cycleJob(): Promise<string> {
273
+ await this.jobCoordinator.commitJob(this.currentJobId);
274
+ this.currentJobId = this.jobCoordinator.beginJob();
275
+ return this.currentJobId;
276
+ }
277
+
232
278
  async enterTopLevelState() {
233
279
  switch (this.state.name) {
234
280
  case 'PRIVATE': {
@@ -251,17 +297,26 @@ export class TXESession implements TXESessionStateHandler {
251
297
  }
252
298
  }
253
299
 
300
+ // Commit all staged stores from the job that was just completed, then begin a new job
301
+ await this.cycleJob();
302
+
254
303
  this.oracleHandler = new TXEOracleTopLevelContext(
255
304
  this.stateMachine,
256
- this.contractDataProvider,
305
+ this.contractStore,
306
+ this.noteStore,
257
307
  this.keyStore,
258
- this.addressDataProvider,
259
- this.accountDataProvider,
260
- this.pxeOracleInterface,
308
+ this.addressStore,
309
+ this.accountStore,
310
+ this.senderTaggingStore,
311
+ this.recipientTaggingStore,
312
+ this.senderAddressBookStore,
313
+ this.capsuleStore,
314
+ this.privateEventStore,
261
315
  this.nextBlockTimestamp,
262
316
  this.version,
263
317
  this.chainId,
264
318
  this.authwits,
319
+ this.contractSyncService,
265
320
  );
266
321
 
267
322
  this.state = { name: 'TOP_LEVEL' };
@@ -270,53 +325,67 @@ export class TXESession implements TXESessionStateHandler {
270
325
 
271
326
  async enterPrivateState(
272
327
  contractAddress: AztecAddress = DEFAULT_ADDRESS,
273
- anchorBlockNumber?: UInt32,
328
+ anchorBlockNumber?: BlockNumber,
274
329
  ): Promise<PrivateContextInputs> {
275
330
  this.exitTopLevelState();
276
331
 
277
- // There is no automatic message discovery and contract-driven syncing process in inlined private or utility
278
- // contexts, which means that known nullifiers are also not searched for, since it is during the tagging sync that
279
- // we perform this. We therefore search for known nullifiers now, as otherwise notes that were nullified would not
280
- // be removed from the database.
281
- // TODO(#12553): make the synchronizer sync here instead and remove this
282
- await this.pxeOracleInterface.syncNoteNullifiers(contractAddress);
283
-
284
332
  // Private execution has two associated block numbers: the anchor block (i.e. the historical block that is used to
285
333
  // build the proof), and the *next* block, i.e. the one we'll create once the execution ends, and which will contain
286
334
  // a single transaction with the effects of what was done in the test.
287
335
  const anchorBlock = await this.stateMachine.node.getBlockHeader(anchorBlockNumber ?? 'latest');
336
+
337
+ await new NoteService(this.noteStore, this.stateMachine.node, anchorBlock!, this.currentJobId).syncNoteNullifiers(
338
+ contractAddress,
339
+ 'ALL_SCOPES',
340
+ );
288
341
  const latestBlock = await this.stateMachine.node.getBlockHeader('latest');
289
342
 
290
343
  const nextBlockGlobalVariables = makeGlobalVariables(undefined, {
291
- blockNumber: latestBlock!.globalVariables.blockNumber + 1,
344
+ blockNumber: BlockNumber(latestBlock!.globalVariables.blockNumber + 1),
292
345
  timestamp: this.nextBlockTimestamp,
293
346
  version: this.version,
294
347
  chainId: this.chainId,
295
348
  });
296
349
 
297
350
  const txRequestHash = getSingleTxBlockRequestHash(nextBlockGlobalVariables.blockNumber);
298
- const noteCache = new ExecutionNoteCache(txRequestHash);
351
+ const protocolNullifier = await computeProtocolNullifier(txRequestHash);
352
+ const noteCache = new ExecutionNoteCache(protocolNullifier);
299
353
  const taggingIndexCache = new ExecutionTaggingIndexCache();
300
354
 
301
- this.oracleHandler = new PrivateExecutionOracle(
302
- Fr.ZERO,
303
- new TxContext(this.chainId, this.version, GasSettings.empty()),
304
- new CallContext(AztecAddress.ZERO, contractAddress, FunctionSelector.empty(), false),
305
- anchorBlock!,
306
- [],
307
- [],
308
- new HashedValuesCache(),
355
+ const utilityExecutor = this.utilityExecutorForContractSync(anchorBlock);
356
+ this.oracleHandler = new PrivateExecutionOracle({
357
+ argsHash: Fr.ZERO,
358
+ txContext: new TxContext(this.chainId, this.version, GasSettings.empty()),
359
+ callContext: new CallContext(AztecAddress.ZERO, contractAddress, FunctionSelector.empty(), false),
360
+ anchorBlockHeader: anchorBlock!,
361
+ utilityExecutor,
362
+ authWitnesses: [],
363
+ capsules: [],
364
+ executionCache: new HashedValuesCache(),
309
365
  noteCache,
310
366
  taggingIndexCache,
311
- this.pxeOracleInterface,
312
- );
367
+ contractStore: this.contractStore,
368
+ noteStore: this.noteStore,
369
+ keyStore: this.keyStore,
370
+ addressStore: this.addressStore,
371
+ aztecNode: this.stateMachine.node,
372
+ senderTaggingStore: this.senderTaggingStore,
373
+ recipientTaggingStore: this.recipientTaggingStore,
374
+ senderAddressBookStore: this.senderAddressBookStore,
375
+ capsuleStore: this.capsuleStore,
376
+ privateEventStore: this.privateEventStore,
377
+ contractSyncService: this.stateMachine.contractSyncService,
378
+ jobId: this.currentJobId,
379
+ scopes: 'ALL_SCOPES',
380
+ messageContextService: this.stateMachine.messageContextService,
381
+ });
313
382
 
314
383
  // We store the note and tagging index caches fed into the PrivateExecutionOracle (along with some other auxiliary
315
384
  // data) in order to refer to it later, mimicking the way this object is used by the ContractFunctionSimulator. The
316
385
  // difference resides in that the simulator has all information needed in order to run the simulation, while ours
317
386
  // will be ongoing as the different oracles will be invoked from the Noir test, until eventually the private
318
387
  // execution finishes.
319
- this.state = { name: 'PRIVATE', nextBlockGlobalVariables, txRequestHash, noteCache, taggingIndexCache };
388
+ this.state = { name: 'PRIVATE', nextBlockGlobalVariables, noteCache, taggingIndexCache };
320
389
  this.logger.debug(`Entered state ${this.state.name}`);
321
390
 
322
391
  return (this.oracleHandler as PrivateExecutionOracle).getPrivateContextInputs();
@@ -329,7 +398,7 @@ export class TXESession implements TXESessionStateHandler {
329
398
  // the test. The block therefore gets the *next* block number and timestamp.
330
399
  const latestBlockNumber = (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.blockNumber;
331
400
  const globalVariables = makeGlobalVariables(undefined, {
332
- blockNumber: latestBlockNumber + 1,
401
+ blockNumber: BlockNumber(latestBlockNumber + 1),
333
402
  timestamp: this.nextBlockTimestamp,
334
403
  version: this.version,
335
404
  chainId: this.chainId,
@@ -349,14 +418,39 @@ export class TXESession implements TXESessionStateHandler {
349
418
  async enterUtilityState(contractAddress: AztecAddress = DEFAULT_ADDRESS) {
350
419
  this.exitTopLevelState();
351
420
 
421
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
422
+
352
423
  // There is no automatic message discovery and contract-driven syncing process in inlined private or utility
353
424
  // contexts, which means that known nullifiers are also not searched for, since it is during the tagging sync that
354
425
  // we perform this. We therefore search for known nullifiers now, as otherwise notes that were nullified would not
355
426
  // be removed from the database.
356
427
  // TODO(#12553): make the synchronizer sync here instead and remove this
357
- await this.pxeOracleInterface.syncNoteNullifiers(contractAddress);
358
-
359
- this.oracleHandler = new UtilityExecutionOracle(contractAddress, [], [], this.pxeOracleInterface);
428
+ await new NoteService(
429
+ this.noteStore,
430
+ this.stateMachine.node,
431
+ anchorBlockHeader,
432
+ this.currentJobId,
433
+ ).syncNoteNullifiers(contractAddress, 'ALL_SCOPES');
434
+
435
+ this.oracleHandler = new UtilityExecutionOracle({
436
+ contractAddress,
437
+ authWitnesses: [],
438
+ capsules: [],
439
+ anchorBlockHeader,
440
+ contractStore: this.contractStore,
441
+ noteStore: this.noteStore,
442
+ keyStore: this.keyStore,
443
+ addressStore: this.addressStore,
444
+ aztecNode: this.stateMachine.node,
445
+ recipientTaggingStore: this.recipientTaggingStore,
446
+ senderAddressBookStore: this.senderAddressBookStore,
447
+ capsuleStore: this.capsuleStore,
448
+ privateEventStore: this.privateEventStore,
449
+ messageContextService: this.stateMachine.messageContextService,
450
+ contractSyncService: this.contractSyncService,
451
+ jobId: this.currentJobId,
452
+ scopes: 'ALL_SCOPES',
453
+ });
360
454
 
361
455
  this.state = { name: 'UTILITY' };
362
456
  this.logger.debug(`Entered state ${this.state.name}`);
@@ -369,8 +463,8 @@ export class TXESession implements TXESessionStateHandler {
369
463
 
370
464
  // Note that while all public and private contexts do is build a single block that we then process when exiting
371
465
  // those, the top level context performs a large number of actions not captured in the following 'close' call. Among
372
- // others, it will create empty blocks (via `txeAdvanceBlocksBy` and `deploy`), create blocks with transactions via
373
- // `txePrivateCallNewFlow` and `txePublicCallNewFlow`, add accounts to PXE via `txeAddAccount`, etc. This is a
466
+ // others, it will create empty blocks (via `advanceBlocksBy` and `deploy`), create blocks with transactions via
467
+ // `privateCallNewFlow` and `publicCallNewFlow`, add accounts to PXE via `addAccount`, etc. This is a
374
468
  // slight inconsistency in the working model of this class, but is not too bad.
375
469
  // TODO: it's quite unfortunate that we need to capture the authwits created to later pass them again when the top
376
470
  // level context is re-created. This is because authwits create a temporary utility context that'd otherwise reset
@@ -390,21 +484,14 @@ export class TXESession implements TXESessionStateHandler {
390
484
 
391
485
  // We rely on the note cache to determine the effects of the transaction. This is incomplete as it doesn't private
392
486
  // logs (other effects like enqueued public calls don't need to be considered since those are not allowed).
393
- const txEffect = await makeTxEffect(
394
- this.state.noteCache,
395
- this.state.txRequestHash,
396
- this.state.nextBlockGlobalVariables.blockNumber,
397
- );
487
+
488
+ const txEffect = await makeTxEffect(this.state.noteCache, this.state.nextBlockGlobalVariables.blockNumber);
398
489
 
399
490
  // We build a block holding just this transaction
400
491
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
401
492
  await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
402
493
 
403
- const block = new L2Block(
404
- makeAppendOnlyTreeSnapshot(),
405
- await makeTXEBlockHeader(forkedWorldTrees, this.state.nextBlockGlobalVariables),
406
- new Body([txEffect]),
407
- );
494
+ const block = await makeTXEBlock(forkedWorldTrees, this.state.nextBlockGlobalVariables, [txEffect]);
408
495
  await this.stateMachine.handleL2Block(block);
409
496
 
410
497
  await forkedWorldTrees.close();
@@ -429,4 +516,51 @@ export class TXESession implements TXESessionStateHandler {
429
516
  throw new Error(`Expected to be in state 'UTILITY', but got '${this.state.name}' instead`);
430
517
  }
431
518
  }
519
+
520
+ private utilityExecutorForContractSync(anchorBlock: any) {
521
+ return async (call: FunctionCall, scopes: AccessScopes) => {
522
+ const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
523
+ if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
524
+ throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
525
+ }
526
+
527
+ try {
528
+ const oracle = new UtilityExecutionOracle({
529
+ contractAddress: call.to,
530
+ authWitnesses: [],
531
+ capsules: [],
532
+ anchorBlockHeader: anchorBlock!,
533
+ contractStore: this.contractStore,
534
+ noteStore: this.noteStore,
535
+ keyStore: this.keyStore,
536
+ addressStore: this.addressStore,
537
+ aztecNode: this.stateMachine.node,
538
+ recipientTaggingStore: this.recipientTaggingStore,
539
+ senderAddressBookStore: this.senderAddressBookStore,
540
+ capsuleStore: this.capsuleStore,
541
+ privateEventStore: this.privateEventStore,
542
+ messageContextService: this.stateMachine.messageContextService,
543
+ contractSyncService: this.contractSyncService,
544
+ jobId: this.currentJobId,
545
+ scopes,
546
+ });
547
+ await new WASMSimulator()
548
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
549
+ .catch((err: Error) => {
550
+ err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
551
+ throw new ExecutionError(
552
+ err.message,
553
+ {
554
+ contractAddress: call.to,
555
+ functionSelector: call.selector,
556
+ },
557
+ extractCallStack(err, entryPointArtifact.debug),
558
+ { cause: err },
559
+ );
560
+ });
561
+ } catch (err) {
562
+ throw createSimulationError(err instanceof Error ? err : new Error('Unknown error contract data sync'));
563
+ }
564
+ };
565
+ }
432
566
  }
@@ -1,5 +1,5 @@
1
+ import { Fr } from '@aztec/foundation/curves/bn254';
1
2
  import type { EthAddress } from '@aztec/foundation/eth-address';
2
- import { Fr } from '@aztec/foundation/fields';
3
3
  import { hexToBuffer } from '@aztec/foundation/string';
4
4
  import { type ContractArtifact, ContractArtifactSchema } from '@aztec/stdlib/abi';
5
5
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -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,68 +1,43 @@
1
- import { Fr } from '@aztec/foundation/fields';
2
- import type { ContractDataProvider } from '@aztec/pxe/server';
3
- import { type ContractArtifact, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
1
+ import { BlockNumber } from '@aztec/foundation/branded-types';
2
+ import { Fr } from '@aztec/foundation/curves/bn254';
3
+ import type { ContractStore } from '@aztec/pxe/server';
4
+ import { type ContractArtifact, FunctionSelector } from '@aztec/stdlib/abi';
4
5
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
5
- import {
6
- type ContractClassPublic,
7
- type ContractDataSource,
8
- type ContractInstanceWithAddress,
9
- computePrivateFunctionsRoot,
10
- computePublicBytecodeCommitment,
11
- getContractClassPrivateFunctionFromArtifact,
12
- } from '@aztec/stdlib/contract';
6
+ import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
13
7
 
14
8
  export class TXEPublicContractDataSource implements ContractDataSource {
15
- #privateFunctionsRoot: Map<string, Buffer> = new Map();
16
9
  constructor(
17
- private blockNumber: number,
18
- private contractDataProvider: ContractDataProvider,
10
+ private blockNumber: BlockNumber,
11
+ private contractStore: ContractStore,
19
12
  ) {}
20
13
 
21
- getBlockNumber(): Promise<number> {
14
+ getBlockNumber(): Promise<BlockNumber> {
22
15
  return Promise.resolve(this.blockNumber);
23
16
  }
24
17
 
25
18
  async getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
26
- const contractClass = await this.contractDataProvider.getContractClass(id);
19
+ const contractClass = await this.contractStore.getContractClassWithPreimage(id);
27
20
  if (!contractClass) {
28
21
  return;
29
22
  }
30
- const artifact = await this.contractDataProvider.getContractArtifact(id);
31
- if (!artifact) {
32
- return;
33
- }
34
-
35
- let privateFunctionsRoot;
36
- if (!this.#privateFunctionsRoot.has(id.toString())) {
37
- const privateFunctions = await Promise.all(
38
- artifact.functions
39
- .filter(fn => fn.functionType === FunctionType.PRIVATE)
40
- .map(fn => getContractClassPrivateFunctionFromArtifact(fn)),
41
- );
42
- privateFunctionsRoot = await computePrivateFunctionsRoot(privateFunctions);
43
- this.#privateFunctionsRoot.set(id.toString(), privateFunctionsRoot.toBuffer());
44
- } else {
45
- privateFunctionsRoot = Fr.fromBuffer(this.#privateFunctionsRoot.get(id.toString())!);
46
- }
47
-
48
23
  return {
49
- id,
50
- artifactHash: contractClass!.artifactHash,
51
- packedBytecode: contractClass!.packedBytecode,
52
- privateFunctionsRoot,
53
- version: contractClass!.version,
24
+ id: contractClass.id,
25
+ artifactHash: contractClass.artifactHash,
26
+ packedBytecode: contractClass.packedBytecode,
27
+ privateFunctionsRoot: contractClass.privateFunctionsRoot,
28
+ version: contractClass.version,
54
29
  privateFunctions: [],
55
30
  utilityFunctions: [],
56
31
  };
57
32
  }
58
33
 
59
34
  async getBytecodeCommitment(id: Fr): Promise<Fr | undefined> {
60
- const contractClass = await this.contractDataProvider.getContractClass(id);
61
- return contractClass && computePublicBytecodeCommitment(contractClass.packedBytecode);
35
+ const contractClass = await this.contractStore.getContractClassWithPreimage(id);
36
+ return contractClass?.publicBytecodeCommitment;
62
37
  }
63
38
 
64
39
  async getContract(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
65
- const instance = await this.contractDataProvider.getContractInstance(address);
40
+ const instance = await this.contractStore.getContractInstance(address);
66
41
  return instance && { ...instance, address };
67
42
  }
68
43
 
@@ -71,12 +46,12 @@ export class TXEPublicContractDataSource implements ContractDataSource {
71
46
  }
72
47
 
73
48
  async getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined> {
74
- const instance = await this.contractDataProvider.getContractInstance(address);
75
- return instance && this.contractDataProvider.getContractArtifact(instance.currentContractClassId);
49
+ const instance = await this.contractStore.getContractInstance(address);
50
+ return instance && this.contractStore.getContractArtifact(instance.currentContractClassId);
76
51
  }
77
52
 
78
53
  async getDebugFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
79
- return await this.contractDataProvider.getDebugFunctionName(address, selector);
54
+ return await this.contractStore.getDebugFunctionName(address, selector);
80
55
  }
81
56
 
82
57
  registerContractFunctionSignatures(_signatures: []): Promise<void> {