@aztec/txe 3.0.0-nightly.20250925 → 3.0.0-nightly.20250927

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 (33) hide show
  1. package/dest/oracle/interfaces.d.ts +51 -0
  2. package/dest/oracle/interfaces.d.ts.map +1 -0
  3. package/dest/oracle/interfaces.js +3 -0
  4. package/dest/oracle/txe_oracle_public_context.d.ts +5 -3
  5. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  6. package/dest/oracle/txe_oracle_public_context.js +14 -3
  7. package/dest/oracle/txe_oracle_top_level_context.d.ts +9 -7
  8. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  9. package/dest/oracle/txe_oracle_top_level_context.js +24 -24
  10. package/dest/rpc_translator.d.ts +13 -4
  11. package/dest/rpc_translator.d.ts.map +1 -1
  12. package/dest/rpc_translator.js +101 -66
  13. package/dest/txe_session.d.ts +15 -15
  14. package/dest/txe_session.d.ts.map +1 -1
  15. package/dest/txe_session.js +141 -99
  16. package/dest/utils/tx_effect_creation.d.ts +5 -0
  17. package/dest/utils/tx_effect_creation.d.ts.map +1 -0
  18. package/dest/utils/tx_effect_creation.js +16 -0
  19. package/package.json +15 -15
  20. package/src/oracle/interfaces.ts +80 -0
  21. package/src/oracle/txe_oracle_public_context.ts +20 -15
  22. package/src/oracle/txe_oracle_top_level_context.ts +26 -43
  23. package/src/rpc_translator.ts +125 -69
  24. package/src/txe_session.ts +196 -120
  25. package/src/utils/tx_effect_creation.ts +37 -0
  26. package/dest/oracle/txe_oracle.d.ts +0 -64
  27. package/dest/oracle/txe_oracle.d.ts.map +0 -1
  28. package/dest/oracle/txe_oracle.js +0 -263
  29. package/dest/oracle/txe_typed_oracle.d.ts +0 -41
  30. package/dest/oracle/txe_typed_oracle.d.ts.map +0 -1
  31. package/dest/oracle/txe_typed_oracle.js +0 -89
  32. package/src/oracle/txe_oracle.ts +0 -419
  33. package/src/oracle/txe_typed_oracle.ts +0 -147
@@ -11,51 +11,75 @@ import {
11
11
  PrivateEventDataProvider,
12
12
  TaggingDataProvider,
13
13
  } from '@aztec/pxe/server';
14
+ import {
15
+ ExecutionNoteCache,
16
+ HashedValuesCache,
17
+ type IPrivateExecutionOracle,
18
+ type IUtilityExecutionOracle,
19
+ PrivateExecutionOracle,
20
+ UtilityExecutionOracle,
21
+ } from '@aztec/pxe/simulator';
14
22
  import { FunctionSelector } from '@aztec/stdlib/abi';
23
+ import type { AuthWitness } from '@aztec/stdlib/auth-witness';
15
24
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
25
+ import { Body, L2Block } from '@aztec/stdlib/block';
16
26
  import { GasSettings } from '@aztec/stdlib/gas';
17
27
  import { PrivateContextInputs } from '@aztec/stdlib/kernel';
18
- import { makeGlobalVariables } from '@aztec/stdlib/testing';
28
+ import { makeAppendOnlyTreeSnapshot, makeGlobalVariables } from '@aztec/stdlib/testing';
19
29
  import { CallContext, GlobalVariables, TxContext } from '@aztec/stdlib/tx';
20
30
  import type { UInt32 } from '@aztec/stdlib/types';
21
31
 
22
- import { TXE } from './oracle/txe_oracle.js';
32
+ import type { IAvmExecutionOracle, ITxeExecutionOracle } from './oracle/interfaces.js';
23
33
  import { TXEOraclePublicContext } from './oracle/txe_oracle_public_context.js';
24
34
  import { TXEOracleTopLevelContext } from './oracle/txe_oracle_top_level_context.js';
25
- import type { TXETypedOracle } from './oracle/txe_typed_oracle.js';
26
35
  import { RPCTranslator } from './rpc_translator.js';
27
36
  import { TXEStateMachine } from './state_machine/index.js';
28
37
  import type { ForeignCallArgs, ForeignCallResult } from './util/encoding.js';
29
38
  import { TXEAccountDataProvider } from './util/txe_account_data_provider.js';
30
39
  import { TXEContractDataProvider } from './util/txe_contract_data_provider.js';
31
- import { getSingleTxBlockRequestHash } from './utils/block_creation.js';
40
+ import {
41
+ getSingleTxBlockRequestHash,
42
+ insertTxEffectIntoWorldTrees,
43
+ makeTXEBlockHeader,
44
+ } from './utils/block_creation.js';
45
+ import { makeTxEffect } from './utils/tx_effect_creation.js';
32
46
 
33
47
  /**
34
- * A TXE Session can be ine one of four states, which change as the test progresses and different oracles are called.
35
- * The current state determines which oracles are available.
48
+ * A TXE Session can be in one of four states, which change as the test progresses and different oracles are called.
49
+ * The current state determines which oracles are available. Some states also have data associated with them.
36
50
  */
37
- enum SessionState {
51
+ type SessionState =
38
52
  /**
39
53
  * The top-level state is the default state, before any other state has been entered. This is where contracts can be
40
54
  * deployed, accounts created, blocks mined, etc.
41
55
  */
42
- TOP_LEVEL,
56
+ | {
57
+ name: 'TOP_LEVEL';
58
+ }
43
59
  /**
44
60
  * The private state is entered via the `private_context` function. In this state the PXE oracles that `#[private]`
45
61
  * functions use are available, such as those related to note retrieval, notification of side-effects, capsule access,
46
62
  * etc. */
47
- PRIVATE,
63
+ | {
64
+ name: 'PRIVATE';
65
+ nextBlockGlobalVariables: GlobalVariables;
66
+ txRequestHash: Fr;
67
+ noteCache: ExecutionNoteCache;
68
+ }
48
69
  /**
49
70
  * The public state is entered via the `public_context` function. In this state the AVM opcodes that `#[public]`
50
71
  * functions execute are resolved as oracles by TXE, since Noir tests are not transpiled. */
51
- PUBLIC,
72
+ | {
73
+ name: 'PUBLIC';
74
+ }
52
75
  /**
53
76
  * The utility state is entered via the `utility_context` function. In this state the PXE oracles that `#[utility]`
54
77
  * functions use are available, such as those related to (unconstrained) note retrieval, capsule access, public
55
78
  * storage reads, etc.
56
79
  */
57
- UTILITY,
58
- }
80
+ | {
81
+ name: 'UTILITY';
82
+ };
59
83
 
60
84
  type MethodNames<T> = {
61
85
  [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
@@ -68,10 +92,10 @@ type MethodNames<T> = {
68
92
  export type TXEOracleFunctionName = MethodNames<RPCTranslator>;
69
93
 
70
94
  export interface TXESessionStateHandler {
71
- setTopLevelContext(): Promise<void>;
72
- setPublicContext(contractAddress?: AztecAddress): Promise<void>;
73
- setPrivateContext(contractAddress?: AztecAddress, anchorBlockNumber?: UInt32): Promise<PrivateContextInputs>;
74
- setUtilityContext(contractAddress?: AztecAddress): Promise<void>;
95
+ enterTopLevelState(): Promise<void>;
96
+ enterPublicState(contractAddress?: AztecAddress): Promise<void>;
97
+ enterPrivateState(contractAddress?: AztecAddress, anchorBlockNumber?: UInt32): Promise<PrivateContextInputs>;
98
+ enterUtilityState(contractAddress?: AztecAddress): Promise<void>;
75
99
  }
76
100
 
77
101
  const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
@@ -81,12 +105,17 @@ const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
81
105
  * state, etc., independent of all other tests running in parallel.
82
106
  */
83
107
  export class TXESession implements TXESessionStateHandler {
84
- private state = SessionState.TOP_LEVEL;
108
+ private state: SessionState = { name: 'TOP_LEVEL' };
109
+ private authwits: Map<string, AuthWitness> = new Map();
85
110
 
86
111
  constructor(
87
112
  private logger: Logger,
88
113
  private stateMachine: TXEStateMachine,
89
- private oracleHandler: TXETypedOracle,
114
+ private oracleHandler:
115
+ | IUtilityExecutionOracle
116
+ | IPrivateExecutionOracle
117
+ | IAvmExecutionOracle
118
+ | ITxeExecutionOracle,
90
119
  private contractDataProvider: TXEContractDataProvider,
91
120
  private keyStore: KeyStore,
92
121
  private addressDataProvider: AddressDataProvider,
@@ -143,6 +172,7 @@ export class TXESession implements TXESessionStateHandler {
143
172
  nextBlockTimestamp,
144
173
  version,
145
174
  chainId,
175
+ new Map(),
146
176
  );
147
177
  await topLevelOracleHandler.txeAdvanceBlocksBy(1);
148
178
 
@@ -168,20 +198,41 @@ export class TXESession implements TXESessionStateHandler {
168
198
  * @returns The oracle return values.
169
199
  */
170
200
  processFunction(functionName: TXEOracleFunctionName, inputs: ForeignCallArgs): Promise<ForeignCallResult> {
171
- return (new RPCTranslator(this, this.oracleHandler) as any)[functionName](...inputs);
201
+ try {
202
+ return (new RPCTranslator(this, this.oracleHandler) as any)[functionName](...inputs);
203
+ } catch (error) {
204
+ if (error instanceof Error) {
205
+ throw new Error(
206
+ `Execution error while processing function ${functionName} in state ${this.state.name}: ${error.message}`,
207
+ );
208
+ } else {
209
+ throw new Error(
210
+ `Unknown execution error while processing function ${functionName} in state ${this.state.name}`,
211
+ );
212
+ }
213
+ }
172
214
  }
173
215
 
174
- async setTopLevelContext() {
175
- if (this.state == SessionState.PRIVATE) {
176
- await this.exitPrivateContext();
177
- } else if (this.state == SessionState.PUBLIC) {
178
- await this.exitPublicContext();
179
- } else if (this.state == SessionState.UTILITY) {
180
- this.exitUtilityContext();
181
- } else if (this.state == SessionState.TOP_LEVEL) {
182
- throw new Error(`Expected to be in state other than ${SessionState[SessionState.TOP_LEVEL]}`);
183
- } else {
184
- throw new Error(`Unexpected state '${this.state}'`);
216
+ async enterTopLevelState() {
217
+ switch (this.state.name) {
218
+ case 'PRIVATE': {
219
+ await this.exitPrivateState();
220
+ break;
221
+ }
222
+ case 'PUBLIC': {
223
+ await this.exitPublicState();
224
+ break;
225
+ }
226
+ case 'UTILITY': {
227
+ this.exitUtilityContext();
228
+ break;
229
+ }
230
+ case 'TOP_LEVEL': {
231
+ throw new Error(`Expected to be in state other than TOP_LEVEL`);
232
+ }
233
+ default: {
234
+ this.state satisfies never;
235
+ }
185
236
  }
186
237
 
187
238
  this.oracleHandler = new TXEOracleTopLevelContext(
@@ -194,144 +245,169 @@ export class TXESession implements TXESessionStateHandler {
194
245
  this.nextBlockTimestamp,
195
246
  this.version,
196
247
  this.chainId,
248
+ this.authwits,
197
249
  );
198
250
 
199
- this.state = SessionState.TOP_LEVEL;
200
- this.logger.debug(`Entered state ${SessionState[this.state]}`);
251
+ this.state = { name: 'TOP_LEVEL' };
252
+ this.logger.debug(`Entered state ${this.state.name}`);
201
253
  }
202
254
 
203
- async setPublicContext(contractAddress?: AztecAddress) {
204
- this.exitTopLevelContext();
255
+ async enterPrivateState(
256
+ contractAddress: AztecAddress = DEFAULT_ADDRESS,
257
+ anchorBlockNumber?: UInt32,
258
+ ): Promise<PrivateContextInputs> {
259
+ this.exitTopLevelState();
260
+
261
+ // There is no automatic message discovery and contract-driven syncing process in inlined private or utility
262
+ // contexts, which means that known nullifiers are also not searched for, since it is during the tagging sync that
263
+ // we perform this. We therefore search for known nullifiers now, as otherwise notes that were nullified would not
264
+ // be removed from the database.
265
+ // TODO(#12553): make the synchronizer sync here instead and remove this
266
+ await this.pxeOracleInterface.removeNullifiedNotes(contractAddress);
267
+
268
+ // Private execution has two associated block numbers: the anchor block (i.e. the historical block that is used to
269
+ // build the proof), and the *next* block, i.e. the one we'll create once the execution ends, and which will contain
270
+ // a single transaction with the effects of what was done in the test.
271
+ const anchorBlock = await this.stateMachine.node.getBlockHeader(anchorBlockNumber ?? 'latest');
272
+ const latestBlock = await this.stateMachine.node.getBlockHeader('latest');
205
273
 
206
- // The PublicContext will create a block with a single transaction in it, containing the effects of what was done in
207
- // the test. The block therefore gets the *next* block number and timestamp.
208
- const latestBlockNumber = (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.blockNumber;
209
- const globalVariables = makeGlobalVariables(undefined, {
210
- blockNumber: latestBlockNumber + 1,
274
+ const nextBlockGlobalVariables = makeGlobalVariables(undefined, {
275
+ blockNumber: latestBlock!.globalVariables.blockNumber + 1,
211
276
  timestamp: this.nextBlockTimestamp,
212
277
  version: this.version,
213
278
  chainId: this.chainId,
214
279
  });
215
280
 
216
- this.oracleHandler = new TXEOraclePublicContext(
217
- contractAddress ?? DEFAULT_ADDRESS,
218
- await this.stateMachine.synchronizer.nativeWorldStateService.fork(),
219
- getSingleTxBlockRequestHash(globalVariables.blockNumber),
220
- globalVariables,
221
- );
281
+ const txRequestHash = getSingleTxBlockRequestHash(nextBlockGlobalVariables.blockNumber);
282
+ const noteCache = new ExecutionNoteCache(txRequestHash);
222
283
 
223
- this.state = SessionState.PUBLIC;
224
- this.logger.debug(`Entered state ${SessionState[this.state]}`);
225
- }
284
+ this.oracleHandler = new PrivateExecutionOracle(
285
+ Fr.ZERO,
286
+ new TxContext(this.chainId, this.version, GasSettings.empty()),
287
+ new CallContext(AztecAddress.ZERO, contractAddress, FunctionSelector.empty(), false),
288
+ anchorBlock!,
289
+ [],
290
+ [],
291
+ new HashedValuesCache(),
292
+ noteCache,
293
+ this.pxeOracleInterface,
294
+ );
226
295
 
227
- async setPrivateContext(contractAddress?: AztecAddress, anchorBlockNumber?: UInt32): Promise<PrivateContextInputs> {
228
- this.exitTopLevelContext();
296
+ // We store the note cache fed into the PrivateExecutionOracle (along with some other auxiliary data) in order to
297
+ // refer to it later, mimicking the way this object is used by the ContractFunctionSimulator. The difference resides
298
+ // in that the simulator has all information needed in order to run the simulation, while ours will be ongoing as
299
+ // the different oracles will be invoked from the Noir test, until eventually the private execution finishes.
300
+ this.state = { name: 'PRIVATE', nextBlockGlobalVariables, txRequestHash, noteCache };
301
+ this.logger.debug(`Entered state ${this.state.name}`);
229
302
 
230
- // A PrivateContext has two associated block numbers: the anchor block (i.e. the historical block that is used to build the
231
- // proof), and the *next* block, i.e. the one the PrivateContext will create with the single transaction that
232
- // contains the effects of what was done in the test.
233
- const anchorBlock = await this.stateMachine.node.getBlockHeader(anchorBlockNumber ?? 'latest');
234
- const latestBlock = await this.stateMachine.node.getBlockHeader('latest');
303
+ return (this.oracleHandler as PrivateExecutionOracle).getPrivateContextInputs();
304
+ }
235
305
 
236
- const anchorBlockGlobalVariables = makeGlobalVariables(undefined, {
237
- blockNumber: anchorBlock!.globalVariables.blockNumber,
238
- timestamp: anchorBlock!.globalVariables.timestamp,
239
- version: this.version,
240
- chainId: this.chainId,
241
- });
306
+ async enterPublicState(contractAddress?: AztecAddress) {
307
+ this.exitTopLevelState();
242
308
 
243
- const nextBlockGlobalVariables = makeGlobalVariables(undefined, {
244
- blockNumber: latestBlock!.globalVariables.blockNumber + 1,
309
+ // The PublicContext will create a block with a single transaction in it, containing the effects of what was done in
310
+ // the test. The block therefore gets the *next* block number and timestamp.
311
+ const latestBlockNumber = (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.blockNumber;
312
+ const globalVariables = makeGlobalVariables(undefined, {
313
+ blockNumber: latestBlockNumber + 1,
245
314
  timestamp: this.nextBlockTimestamp,
246
315
  version: this.version,
247
316
  chainId: this.chainId,
248
317
  });
249
318
 
250
- const privateContextInputs = await this.getPrivateContextInputs(
251
- anchorBlockGlobalVariables.blockNumber,
252
- contractAddress ?? DEFAULT_ADDRESS,
253
- );
254
-
255
- this.oracleHandler = await TXE.create(
319
+ this.oracleHandler = new TXEOraclePublicContext(
256
320
  contractAddress ?? DEFAULT_ADDRESS,
257
- this.pxeOracleInterface,
258
321
  await this.stateMachine.synchronizer.nativeWorldStateService.fork(),
259
- anchorBlockGlobalVariables,
260
- nextBlockGlobalVariables,
261
- getSingleTxBlockRequestHash(nextBlockGlobalVariables.blockNumber), // The tx will be inserted in the *next* block
322
+ getSingleTxBlockRequestHash(globalVariables.blockNumber),
323
+ globalVariables,
262
324
  );
263
325
 
264
- this.state = SessionState.PRIVATE;
265
- this.logger.debug(`Entered state ${SessionState[this.state]}`);
266
-
267
- return privateContextInputs;
326
+ this.state = { name: 'PUBLIC' };
327
+ this.logger.debug(`Entered state ${this.state.name}`);
268
328
  }
269
329
 
270
- async setUtilityContext(contractAddress?: AztecAddress) {
271
- this.exitTopLevelContext();
330
+ async enterUtilityState(contractAddress: AztecAddress = DEFAULT_ADDRESS) {
331
+ this.exitTopLevelState();
272
332
 
273
- // A UtilityContext is built using the latest block as a reference, mimicking what would happen if PXE had synced
274
- // all the way to the tip of the chain.
275
- const latestBlock = await this.stateMachine.node.getBlockHeader('latest');
333
+ // There is no automatic message discovery and contract-driven syncing process in inlined private or utility
334
+ // contexts, which means that known nullifiers are also not searched for, since it is during the tagging sync that
335
+ // we perform this. We therefore search for known nullifiers now, as otherwise notes that were nullified would not
336
+ // be removed from the database.
337
+ // TODO(#12553): make the synchronizer sync here instead and remove this
338
+ await this.pxeOracleInterface.removeNullifiedNotes(contractAddress);
276
339
 
277
- this.oracleHandler = await TXE.create(
278
- contractAddress ?? DEFAULT_ADDRESS,
279
- this.pxeOracleInterface,
280
- await this.stateMachine.synchronizer.nativeWorldStateService.fork(),
281
- latestBlock!.globalVariables,
282
- GlobalVariables.empty(), // unused - will be removed after private/utility split
283
- Fr.random(), // unused - will be removed after private/utility split
284
- );
340
+ this.oracleHandler = new UtilityExecutionOracle(contractAddress, [], [], this.pxeOracleInterface);
285
341
 
286
- this.state = SessionState.UTILITY;
287
- this.logger.debug(`Entered state ${SessionState[this.state]}`);
342
+ this.state = { name: 'UTILITY' };
343
+ this.logger.debug(`Entered state ${this.state.name}`);
288
344
  }
289
345
 
290
- private exitTopLevelContext() {
291
- this.assertState(SessionState.TOP_LEVEL);
346
+ private exitTopLevelState() {
347
+ if (this.state.name != 'TOP_LEVEL') {
348
+ throw new Error(`Expected to be in state 'TOP_LEVEL', but got '${this.state.name}' instead`);
349
+ }
292
350
 
293
351
  // Note that while all public and private contexts do is build a single block that we then process when exiting
294
352
  // those, the top level context performs a large number of actions not captured in the following 'close' call. Among
295
353
  // others, it will create empty blocks (via `txeAdvanceBlocksBy` and `deploy`), create blocks with transactions via
296
354
  // `txePrivateCallNewFlow` and `txePublicCallNewFlow`, add accounts to PXE via `txeAddAccount`, etc. This is a
297
355
  // slight inconsistency in the working model of this class, but is not too bad.
298
- this.nextBlockTimestamp = (this.oracleHandler as TXEOracleTopLevelContext).close();
356
+ // TODO: it's quite unfortunate that we need to capture the authwits created to later pass them again when the top
357
+ // level context is re-created. This is because authwits create a temporary utility context that'd otherwise reset
358
+ // the authwits if not persisted, so we'd not be able to pass more than one per execution.
359
+ // Ideally authwits would be passed alongside a contract call instead of pre-seeded.
360
+ [this.nextBlockTimestamp, this.authwits] = (this.oracleHandler as TXEOracleTopLevelContext).close();
299
361
  }
300
362
 
301
- private async exitPublicContext() {
302
- this.assertState(SessionState.PUBLIC);
363
+ private async exitPrivateState() {
364
+ if (this.state.name != 'PRIVATE') {
365
+ throw new Error(`Expected to be in state 'PRIVATE', but got '${this.state.name}' instead`);
366
+ }
303
367
 
304
- const block = await (this.oracleHandler as TXEOraclePublicContext).close();
305
- await this.stateMachine.handleL2Block(block);
306
- }
368
+ this.logger.debug('Exiting Private state, building block with collected side effects', {
369
+ blockNumber: this.state.nextBlockGlobalVariables.blockNumber,
370
+ });
307
371
 
308
- private async exitPrivateContext() {
309
- this.assertState(SessionState.PRIVATE);
372
+ // We rely on the note cache to determine the effects of the transaction. This is incomplete as it doesn't private
373
+ // logs (other effects like enqueued public calls don't need to be considered since those are not allowed).
374
+ const txEffect = await makeTxEffect(
375
+ this.state.noteCache,
376
+ this.state.txRequestHash,
377
+ this.state.nextBlockGlobalVariables.blockNumber,
378
+ );
310
379
 
311
- const block = await (this.oracleHandler as TXE).close();
380
+ // We build a block holding just this transaction
381
+ const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
382
+ await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
383
+
384
+ const block = new L2Block(
385
+ makeAppendOnlyTreeSnapshot(),
386
+ await makeTXEBlockHeader(forkedWorldTrees, this.state.nextBlockGlobalVariables),
387
+ new Body([txEffect]),
388
+ );
312
389
  await this.stateMachine.handleL2Block(block);
313
- }
314
390
 
315
- private exitUtilityContext() {
316
- this.assertState(SessionState.UTILITY);
317
- }
391
+ await forkedWorldTrees.close();
318
392
 
319
- private assertState(state: SessionState) {
320
- if (this.state != state) {
321
- throw new Error(`Expected to be in state ${SessionState[state]}, but got '${SessionState[this.state]}' instead`);
322
- }
393
+ this.logger.debug('Exited PublicContext with built block', {
394
+ blockNumber: block.number,
395
+ txEffects: block.body.txEffects,
396
+ });
323
397
  }
324
398
 
325
- private async getPrivateContextInputs(anchorBlockNumber: number, contractAddress: AztecAddress) {
326
- this.logger.info(`Creating private context for block ${anchorBlockNumber}`);
399
+ private async exitPublicState() {
400
+ if (this.state.name != 'PUBLIC') {
401
+ throw new Error(`Expected to be in state 'PUBLIC', but got '${this.state.name}' instead`);
402
+ }
327
403
 
328
- const sender = await AztecAddress.random();
404
+ const block = await (this.oracleHandler as TXEOraclePublicContext).close();
405
+ await this.stateMachine.handleL2Block(block);
406
+ }
329
407
 
330
- return new PrivateContextInputs(
331
- new CallContext(sender, contractAddress, FunctionSelector.empty(), false),
332
- (await this.stateMachine.node.getBlockHeader(anchorBlockNumber))!,
333
- new TxContext(this.chainId, this.version, GasSettings.empty()),
334
- 0,
335
- );
408
+ private exitUtilityContext() {
409
+ if (this.state.name != 'UTILITY') {
410
+ throw new Error(`Expected to be in state 'UTILITY', but got '${this.state.name}' instead`);
411
+ }
336
412
  }
337
413
  }
@@ -0,0 +1,37 @@
1
+ import { Fr } from '@aztec/foundation/fields';
2
+ import type { ExecutionNoteCache } from '@aztec/pxe/simulator';
3
+ import { computeNoteHashNonce, computeUniqueNoteHash, siloNoteHash } from '@aztec/stdlib/hash';
4
+ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
5
+
6
+ export async function makeTxEffect(
7
+ noteCache: ExecutionNoteCache,
8
+ txRequestHash: Fr,
9
+ txBlockNumber: number,
10
+ ): Promise<TxEffect> {
11
+ const txEffect = TxEffect.empty();
12
+
13
+ const { usedTxRequestHashForNonces } = noteCache.finish();
14
+ const nonceGenerator = usedTxRequestHashForNonces ? txRequestHash : noteCache.getAllNullifiers()[0];
15
+
16
+ txEffect.noteHashes = await Promise.all(
17
+ noteCache
18
+ .getAllNotes()
19
+ .map(async (pendingNote, i) =>
20
+ computeUniqueNoteHash(
21
+ await computeNoteHashNonce(nonceGenerator, i),
22
+ await siloNoteHash(pendingNote.note.contractAddress, pendingNote.noteHashForConsumption),
23
+ ),
24
+ ),
25
+ );
26
+
27
+ // Nullifiers are already siloed
28
+ txEffect.nullifiers = noteCache.getAllNullifiers();
29
+
30
+ if (usedTxRequestHashForNonces) {
31
+ txEffect.nullifiers.unshift(txRequestHash);
32
+ }
33
+
34
+ txEffect.txHash = new TxHash(new Fr(txBlockNumber));
35
+
36
+ return txEffect;
37
+ }
@@ -1,64 +0,0 @@
1
- import { Fr, Point } from '@aztec/foundation/fields';
2
- import { PXEOracleInterface } from '@aztec/pxe/server';
3
- import { ExecutionNoteCache, type NoteData, UtilityContext } from '@aztec/pxe/simulator';
4
- import type { NoteSelector } from '@aztec/stdlib/abi';
5
- import { AztecAddress } from '@aztec/stdlib/aztec-address';
6
- import { L2Block } from '@aztec/stdlib/block';
7
- import type { ContractInstance } from '@aztec/stdlib/contract';
8
- import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
9
- import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
10
- import { IndexedTaggingSecret } from '@aztec/stdlib/logs';
11
- import { type NoteStatus } from '@aztec/stdlib/note';
12
- import { MerkleTreeId, NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
13
- import { BlockHeader, GlobalVariables } from '@aztec/stdlib/tx';
14
- import { TXETypedOracle } from './txe_typed_oracle.js';
15
- export declare class TXE extends TXETypedOracle {
16
- private contractAddress;
17
- private pxeOracleInterface;
18
- private forkedWorldTrees;
19
- private anchorBlockGlobalVariables;
20
- private nextBlockGlobalVariables;
21
- private txRequestHash;
22
- private logger;
23
- private executionCache;
24
- private senderForTags?;
25
- noteCache: ExecutionNoteCache;
26
- private constructor();
27
- static create(contractAddress: AztecAddress, pxeOracleInterface: PXEOracleInterface, forkedWorldTrees: MerkleTreeWriteOperations, anchorBlockGlobalVariables: GlobalVariables, nextBlockGlobalVariables: GlobalVariables, txRequestHash: Fr): Promise<TXE>;
28
- checkNullifiersNotInTree(contractAddress: AztecAddress, nullifiers: Fr[]): Promise<void>;
29
- utilityGetRandomField(): Fr;
30
- utilityGetUtilityContext(): Promise<UtilityContext>;
31
- privateStoreInExecutionCache(values: Fr[], hash: Fr): void;
32
- privateLoadFromExecutionCache(hash: Fr): Promise<Fr[]>;
33
- utilityGetKeyValidationRequest(pkMHash: Fr): Promise<KeyValidationRequest>;
34
- utilityGetContractInstance(address: AztecAddress): Promise<ContractInstance>;
35
- utilityGetMembershipWitness(blockNumber: number, treeId: MerkleTreeId, leafValue: Fr): Promise<Fr[] | undefined>;
36
- utilityGetNullifierMembershipWitness(blockNumber: number, nullifier: Fr): Promise<NullifierMembershipWitness | undefined>;
37
- utilityGetPublicDataWitness(blockNumber: number, leafSlot: Fr): Promise<PublicDataWitness | undefined>;
38
- utilityGetLowNullifierMembershipWitness(blockNumber: number, nullifier: Fr): Promise<NullifierMembershipWitness | undefined>;
39
- utilityGetBlockHeader(blockNumber: number): Promise<BlockHeader | undefined>;
40
- utilityGetPublicKeysAndPartialAddress(account: AztecAddress): Promise<import("@aztec/stdlib/contract").CompleteAddress>;
41
- utilityGetNotes(storageSlot: Fr, numSelects: number, selectByIndexes: number[], selectByOffsets: number[], selectByLengths: number[], selectValues: Fr[], selectComparators: number[], sortByIndexes: number[], sortByOffsets: number[], sortByLengths: number[], sortOrder: number[], limit: number, offset: number, status: NoteStatus): Promise<NoteData[]>;
42
- privateNotifyCreatedNote(storageSlot: Fr, _noteTypeId: NoteSelector, noteItems: Fr[], noteHash: Fr, counter: number): void;
43
- privateNotifyNullifiedNote(innerNullifier: Fr, noteHash: Fr, _counter: number): Promise<void>;
44
- privateNotifyCreatedNullifier(innerNullifier: Fr): Promise<void>;
45
- utilityCheckNullifierExists(innerNullifier: Fr): Promise<boolean>;
46
- utilityStorageRead(contractAddress: AztecAddress, startStorageSlot: Fr, blockNumber: number, numberOfElements: number): Promise<Fr[]>;
47
- utilityDebugLog(message: string, fields: Fr[]): void;
48
- privateIncrementAppTaggingSecretIndexAsSender(sender: AztecAddress, recipient: AztecAddress): Promise<void>;
49
- utilityGetIndexedTaggingSecretAsSender(sender: AztecAddress, recipient: AztecAddress): Promise<IndexedTaggingSecret>;
50
- utilityFetchTaggedLogs(pendingTaggedLogArrayBaseSlot: Fr): Promise<void>;
51
- utilityValidateEnqueuedNotesAndEvents(contractAddress: AztecAddress, noteValidationRequestsArrayBaseSlot: Fr, eventValidationRequestsArrayBaseSlot: Fr): Promise<void>;
52
- utilityBulkRetrieveLogs(contractAddress: AztecAddress, logRetrievalRequestsArrayBaseSlot: Fr, logRetrievalResponsesArrayBaseSlot: Fr): Promise<void>;
53
- utilityStoreCapsule(contractAddress: AztecAddress, slot: Fr, capsule: Fr[]): Promise<void>;
54
- utilityLoadCapsule(contractAddress: AztecAddress, slot: Fr): Promise<Fr[] | null>;
55
- utilityDeleteCapsule(contractAddress: AztecAddress, slot: Fr): Promise<void>;
56
- utilityCopyCapsule(contractAddress: AztecAddress, srcSlot: Fr, dstSlot: Fr, numEntries: number): Promise<void>;
57
- utilityAes128Decrypt(ciphertext: Buffer, iv: Buffer, symKey: Buffer): Promise<Buffer>;
58
- utilityGetSharedSecret(address: AztecAddress, ephPk: Point): Promise<Point>;
59
- privateGetSenderForTags(): Promise<AztecAddress | undefined>;
60
- privateSetSenderForTags(senderForTags: AztecAddress): Promise<void>;
61
- close(): Promise<L2Block>;
62
- private makeTxEffect;
63
- }
64
- //# sourceMappingURL=txe_oracle.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"txe_oracle.d.ts","sourceRoot":"","sources":["../../src/oracle/txe_oracle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAErD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAqB,KAAK,QAAQ,EAAE,cAAc,EAAa,MAAM,sBAAsB,CAAC;AACvH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAQ,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAClG,OAAO,EAAE,WAAW,EAAE,eAAe,EAAoB,MAAM,kBAAkB,CAAC;AAGlF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,qBAAa,GAAI,SAAQ,cAAc;IASnC,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,0BAA0B;IAClC,OAAO,CAAC,wBAAwB;IAChC,OAAO,CAAC,aAAa;IAbvB,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,cAAc,CAA2B;IACjD,OAAO,CAAC,aAAa,CAAC,CAAe;IAE9B,SAAS,EAAE,kBAAkB,CAAC;IAErC,OAAO;WAgBM,MAAM,CACjB,eAAe,EAAE,YAAY,EAC7B,kBAAkB,EAAE,kBAAkB,EACtC,gBAAgB,EAAE,yBAAyB,EAC3C,0BAA0B,EAAE,eAAe,EAC3C,wBAAwB,EAAE,eAAe,EACzC,aAAa,EAAE,EAAE;IAoBb,wBAAwB,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,EAAE;IAcrE,qBAAqB;IAIrB,wBAAwB;IAYxB,4BAA4B,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;IAInD,6BAA6B,CAAC,IAAI,EAAE,EAAE;IAQtC,8BAA8B,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAI1E,0BAA0B,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAI5E,2BAA2B,CAClC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,EAAE,GACZ,OAAO,CAAC,EAAE,EAAE,GAAG,SAAS,CAAC;IAInB,oCAAoC,CAC3C,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,EAAE,GACZ,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC;IAIzC,2BAA2B,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAItG,uCAAuC,CAC9C,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,EAAE,GACZ,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC;IAInC,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAIlF,qCAAqC,CAAC,OAAO,EAAE,YAAY;IAIrD,eAAe,CAC5B,WAAW,EAAE,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,EAAE,EACzB,eAAe,EAAE,MAAM,EAAE,EACzB,eAAe,EAAE,MAAM,EAAE,EACzB,YAAY,EAAE,EAAE,EAAE,EAClB,iBAAiB,EAAE,MAAM,EAAE,EAC3B,aAAa,EAAE,MAAM,EAAE,EACvB,aAAa,EAAE,MAAM,EAAE,EACvB,aAAa,EAAE,MAAM,EAAE,EACvB,SAAS,EAAE,MAAM,EAAE,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU;IAuCX,wBAAwB,CAC/B,WAAW,EAAE,EAAE,EACf,WAAW,EAAE,YAAY,EACzB,SAAS,EAAE,EAAE,EAAE,EACf,QAAQ,EAAE,EAAE,EACZ,OAAO,EAAE,MAAM;IAgBF,0BAA0B,CAAC,cAAc,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM;IAK7E,6BAA6B,CAAC,cAAc,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAKhE,2BAA2B,CAAC,cAAc,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAMjE,kBAAkB,CAC/B,eAAe,EAAE,YAAY,EAC7B,gBAAgB,EAAE,EAAE,EACpB,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,EAAE,EAAE,CAAC;IAUP,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI;IAI9C,6CAA6C,CAC1D,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,YAAY,GACtB,OAAO,CAAC,IAAI,CAAC;IAID,sCAAsC,CACnD,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,YAAY,GACtB,OAAO,CAAC,oBAAoB,CAAC;IAIjB,sBAAsB,CAAC,6BAA6B,EAAE,EAAE;IAQjD,qCAAqC,CACzD,eAAe,EAAE,YAAY,EAC7B,mCAAmC,EAAE,EAAE,EACvC,oCAAoC,EAAE,EAAE,GACvC,OAAO,CAAC,IAAI,CAAC;IAQD,uBAAuB,CACpC,eAAe,EAAE,YAAY,EAC7B,iCAAiC,EAAE,EAAE,EACrC,kCAAkC,EAAE,EAAE,GACrC,OAAO,CAAC,IAAI,CAAC;IAQP,mBAAmB,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ1F,kBAAkB,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC;IAQjF,oBAAoB,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ5E,kBAAkB,CACzB,eAAe,EAAE,YAAY,EAC7B,OAAO,EAAE,EAAE,EACX,OAAO,EAAE,EAAE,EACX,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAQP,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKrF,sBAAsB,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAI3E,uBAAuB,IAAI,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAI5D,uBAAuB,CAAC,aAAa,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtE,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;YAyBjB,YAAY;CA4B3B"}