@aztec/txe 0.0.1-commit.c7c42ec → 0.0.1-commit.f295ac2

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 (49) 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/oracle/txe_oracle_public_context.d.ts +3 -3
  5. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  6. package/dest/oracle/txe_oracle_top_level_context.d.ts +4 -2
  7. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  8. package/dest/oracle/txe_oracle_top_level_context.js +36 -22
  9. package/dest/rpc_translator.d.ts +6 -6
  10. package/dest/rpc_translator.d.ts.map +1 -1
  11. package/dest/rpc_translator.js +21 -20
  12. package/dest/state_machine/archiver.d.ts +20 -67
  13. package/dest/state_machine/archiver.d.ts.map +1 -1
  14. package/dest/state_machine/archiver.js +58 -178
  15. package/dest/state_machine/dummy_p2p_client.d.ts +8 -7
  16. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  17. package/dest/state_machine/dummy_p2p_client.js +13 -10
  18. package/dest/state_machine/global_variable_builder.d.ts +2 -2
  19. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  20. package/dest/state_machine/global_variable_builder.js +1 -1
  21. package/dest/state_machine/index.d.ts +3 -3
  22. package/dest/state_machine/index.d.ts.map +1 -1
  23. package/dest/state_machine/index.js +13 -4
  24. package/dest/state_machine/mock_epoch_cache.d.ts +2 -1
  25. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  26. package/dest/state_machine/mock_epoch_cache.js +5 -1
  27. package/dest/txe_session.d.ts +6 -4
  28. package/dest/txe_session.d.ts.map +1 -1
  29. package/dest/txe_session.js +51 -17
  30. package/dest/util/encoding.d.ts +17 -17
  31. package/dest/utils/block_creation.d.ts +7 -7
  32. package/dest/utils/block_creation.d.ts.map +1 -1
  33. package/dest/utils/block_creation.js +18 -7
  34. package/dest/utils/tx_effect_creation.d.ts +2 -3
  35. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  36. package/dest/utils/tx_effect_creation.js +3 -6
  37. package/package.json +16 -16
  38. package/src/constants.ts +3 -0
  39. package/src/oracle/txe_oracle_public_context.ts +2 -2
  40. package/src/oracle/txe_oracle_top_level_context.ts +53 -22
  41. package/src/rpc_translator.ts +21 -23
  42. package/src/state_machine/archiver.ts +55 -219
  43. package/src/state_machine/dummy_p2p_client.ts +18 -13
  44. package/src/state_machine/global_variable_builder.ts +1 -1
  45. package/src/state_machine/index.ts +14 -6
  46. package/src/state_machine/mock_epoch_cache.ts +5 -0
  47. package/src/txe_session.ts +79 -15
  48. package/src/utils/block_creation.ts +20 -19
  49. package/src/utils/tx_effect_creation.ts +3 -11
@@ -3,15 +3,17 @@ import { Fr } from '@aztec/foundation/curves/bn254';
3
3
  import { 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 { AddressStore, CapsuleStore, NoteService, NoteStore, PrivateEventStore, RecipientTaggingStore, SenderAddressBookStore, SenderTaggingStore } from '@aztec/pxe/server';
7
- import { ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache, PrivateExecutionOracle, UtilityExecutionOracle } from '@aztec/pxe/simulator';
8
- import { FunctionSelector } from '@aztec/stdlib/abi';
6
+ import { AddressStore, CapsuleStore, JobCoordinator, NoteService, NoteStore, PrivateEventStore, RecipientTaggingStore, SenderAddressBookStore, SenderTaggingStore } from '@aztec/pxe/server';
7
+ import { ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache, Oracle, PrivateExecutionOracle, UtilityExecutionOracle } from '@aztec/pxe/simulator';
8
+ import { ExecutionError, WASMSimulator, createSimulationError, extractCallStack, resolveAssertionMessageFromError, toACVMWitness } from '@aztec/simulator/client';
9
+ import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
9
10
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
10
11
  import { GasSettings } from '@aztec/stdlib/gas';
11
12
  import { computeProtocolNullifier } from '@aztec/stdlib/hash';
12
13
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
13
14
  import { CallContext, TxContext } from '@aztec/stdlib/tx';
14
15
  import { z } from 'zod';
16
+ import { DEFAULT_ADDRESS } from './constants.js';
15
17
  import { TXEOraclePublicContext } from './oracle/txe_oracle_public_context.js';
16
18
  import { TXEOracleTopLevelContext } from './oracle/txe_oracle_top_level_context.js';
17
19
  import { RPCTranslator } from './rpc_translator.js';
@@ -20,7 +22,6 @@ import { TXEAccountStore } from './util/txe_account_store.js';
20
22
  import { TXEContractStore } from './util/txe_contract_store.js';
21
23
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from './utils/block_creation.js';
22
24
  import { makeTxEffect } from './utils/tx_effect_creation.js';
23
- export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
24
25
  /**
25
26
  * A `TXESession` corresponds to a Noir `#[test]` function, and handles all of its oracle calls, stores test-specific
26
27
  * state, etc., independent of all other tests running in parallel.
@@ -38,12 +39,14 @@ export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
38
39
  senderAddressBookStore;
39
40
  capsuleStore;
40
41
  privateEventStore;
42
+ jobCoordinator;
43
+ currentJobId;
41
44
  chainId;
42
45
  version;
43
46
  nextBlockTimestamp;
44
47
  state;
45
48
  authwits;
46
- constructor(logger, stateMachine, oracleHandler, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, chainId, version, nextBlockTimestamp){
49
+ constructor(logger, stateMachine, oracleHandler, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, jobCoordinator, currentJobId, chainId, version, nextBlockTimestamp){
47
50
  this.logger = logger;
48
51
  this.stateMachine = stateMachine;
49
52
  this.oracleHandler = oracleHandler;
@@ -57,6 +60,8 @@ export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
57
60
  this.senderAddressBookStore = senderAddressBookStore;
58
61
  this.capsuleStore = capsuleStore;
59
62
  this.privateEventStore = privateEventStore;
63
+ this.jobCoordinator = jobCoordinator;
64
+ this.currentJobId = currentJobId;
60
65
  this.chainId = chainId;
61
66
  this.version = version;
62
67
  this.nextBlockTimestamp = nextBlockTimestamp;
@@ -77,6 +82,14 @@ export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
77
82
  const capsuleStore = new CapsuleStore(store);
78
83
  const keyStore = new KeyStore(store);
79
84
  const accountStore = new TXEAccountStore(store);
85
+ // Create job coordinator and register staged stores
86
+ const jobCoordinator = new JobCoordinator(store);
87
+ jobCoordinator.registerStores([
88
+ capsuleStore,
89
+ senderTaggingStore,
90
+ recipientTaggingStore,
91
+ privateEventStore
92
+ ]);
80
93
  // Register protocol contracts.
81
94
  for (const { contractClass, instance, artifact } of protocolContracts){
82
95
  await contractStore.addContractArtifact(contractClass.id, artifact);
@@ -86,9 +99,10 @@ export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
86
99
  const nextBlockTimestamp = BigInt(Math.floor(new Date().getTime() / 1000));
87
100
  const version = new Fr(await stateMachine.node.getVersion());
88
101
  const chainId = new Fr(await stateMachine.node.getChainId());
89
- const topLevelOracleHandler = new TXEOracleTopLevelContext(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, nextBlockTimestamp, version, chainId, new Map());
102
+ const initialJobId = jobCoordinator.beginJob();
103
+ const topLevelOracleHandler = new TXEOracleTopLevelContext(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, initialJobId, nextBlockTimestamp, version, chainId, new Map());
90
104
  await topLevelOracleHandler.txeAdvanceBlocksBy(1);
91
- return new TXESession(createLogger('txe:session'), stateMachine, topLevelOracleHandler, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, version, chainId, nextBlockTimestamp);
105
+ return new TXESession(createLogger('txe:session'), stateMachine, topLevelOracleHandler, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, jobCoordinator, initialJobId, version, chainId, nextBlockTimestamp);
92
106
  }
93
107
  /**
94
108
  * Processes an oracle function invoked by the Noir test associated to this session.
@@ -137,7 +151,10 @@ export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
137
151
  this.state;
138
152
  }
139
153
  }
140
- this.oracleHandler = new TXEOracleTopLevelContext(this.stateMachine, this.contractStore, this.noteStore, this.keyStore, this.addressStore, this.accountStore, this.senderTaggingStore, this.recipientTaggingStore, this.senderAddressBookStore, this.capsuleStore, this.privateEventStore, this.nextBlockTimestamp, this.version, this.chainId, this.authwits);
154
+ // Commit all staged stores from the job that was just completed, then begin a new job
155
+ await this.jobCoordinator.commitJob(this.currentJobId);
156
+ this.currentJobId = this.jobCoordinator.beginJob();
157
+ this.oracleHandler = new TXEOracleTopLevelContext(this.stateMachine, this.contractStore, this.noteStore, this.keyStore, this.addressStore, this.accountStore, this.senderTaggingStore, this.recipientTaggingStore, this.senderAddressBookStore, this.capsuleStore, this.privateEventStore, this.currentJobId, this.nextBlockTimestamp, this.version, this.chainId, this.authwits);
141
158
  this.state = {
142
159
  name: 'TOP_LEVEL'
143
160
  };
@@ -145,11 +162,6 @@ export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
145
162
  }
146
163
  async enterPrivateState(contractAddress = DEFAULT_ADDRESS, anchorBlockNumber) {
147
164
  this.exitTopLevelState();
148
- // There is no automatic message discovery and contract-driven syncing process in inlined private or utility
149
- // contexts, which means that known nullifiers are also not searched for, since it is during the tagging sync that
150
- // we perform this. We therefore search for known nullifiers now, as otherwise notes that were nullified would not
151
- // be removed from the database.
152
- // TODO(#12553): make the synchronizer sync here instead and remove this
153
165
  await new NoteService(this.noteStore, this.stateMachine.node, this.stateMachine.anchorBlockStore).syncNoteNullifiers(contractAddress);
154
166
  // Private execution has two associated block numbers: the anchor block (i.e. the historical block that is used to
155
167
  // build the proof), and the *next* block, i.e. the one we'll create once the execution ends, and which will contain
@@ -166,7 +178,8 @@ export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
166
178
  const protocolNullifier = await computeProtocolNullifier(txRequestHash);
167
179
  const noteCache = new ExecutionNoteCache(protocolNullifier);
168
180
  const taggingIndexCache = new ExecutionTaggingIndexCache();
169
- this.oracleHandler = new PrivateExecutionOracle(Fr.ZERO, new TxContext(this.chainId, this.version, GasSettings.empty()), new CallContext(AztecAddress.ZERO, contractAddress, FunctionSelector.empty(), false), anchorBlock, [], [], new HashedValuesCache(), noteCache, taggingIndexCache, this.contractStore, this.noteStore, this.keyStore, this.addressStore, this.stateMachine.node, this.stateMachine.anchorBlockStore, this.senderTaggingStore, this.recipientTaggingStore, this.senderAddressBookStore, this.capsuleStore, this.privateEventStore);
181
+ const utilityExecutor = this.utilityExecutorForContractSync(anchorBlock);
182
+ this.oracleHandler = new PrivateExecutionOracle(Fr.ZERO, new TxContext(this.chainId, this.version, GasSettings.empty()), new CallContext(AztecAddress.ZERO, contractAddress, FunctionSelector.empty(), false), anchorBlock, utilityExecutor, [], [], new HashedValuesCache(), noteCache, taggingIndexCache, this.contractStore, this.noteStore, this.keyStore, this.addressStore, this.stateMachine.node, this.stateMachine.anchorBlockStore, this.senderTaggingStore, this.recipientTaggingStore, this.senderAddressBookStore, this.capsuleStore, this.privateEventStore, this.currentJobId);
170
183
  // We store the note and tagging index caches fed into the PrivateExecutionOracle (along with some other auxiliary
171
184
  // data) in order to refer to it later, mimicking the way this object is used by the ContractFunctionSimulator. The
172
185
  // difference resides in that the simulator has all information needed in order to run the simulation, while ours
@@ -175,7 +188,6 @@ export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
175
188
  this.state = {
176
189
  name: 'PRIVATE',
177
190
  nextBlockGlobalVariables,
178
- protocolNullifier,
179
191
  noteCache,
180
192
  taggingIndexCache
181
193
  };
@@ -208,7 +220,7 @@ export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
208
220
  // TODO(#12553): make the synchronizer sync here instead and remove this
209
221
  await new NoteService(this.noteStore, this.stateMachine.node, this.stateMachine.anchorBlockStore).syncNoteNullifiers(contractAddress);
210
222
  const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
211
- this.oracleHandler = new UtilityExecutionOracle(contractAddress, [], [], anchorBlockHeader, this.contractStore, this.noteStore, this.keyStore, this.addressStore, this.stateMachine.node, this.stateMachine.anchorBlockStore, this.recipientTaggingStore, this.senderAddressBookStore, this.capsuleStore, this.privateEventStore);
223
+ this.oracleHandler = new UtilityExecutionOracle(contractAddress, [], [], anchorBlockHeader, this.contractStore, this.noteStore, this.keyStore, this.addressStore, this.stateMachine.node, this.stateMachine.anchorBlockStore, this.recipientTaggingStore, this.senderAddressBookStore, this.capsuleStore, this.privateEventStore, this.currentJobId);
212
224
  this.state = {
213
225
  name: 'UTILITY'
214
226
  };
@@ -238,7 +250,7 @@ export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
238
250
  });
239
251
  // We rely on the note cache to determine the effects of the transaction. This is incomplete as it doesn't private
240
252
  // logs (other effects like enqueued public calls don't need to be considered since those are not allowed).
241
- const txEffect = await makeTxEffect(this.state.noteCache, this.state.protocolNullifier, this.state.nextBlockGlobalVariables.blockNumber);
253
+ const txEffect = await makeTxEffect(this.state.noteCache, this.state.nextBlockGlobalVariables.blockNumber);
242
254
  // We build a block holding just this transaction
243
255
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
244
256
  await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
@@ -264,4 +276,26 @@ export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
264
276
  throw new Error(`Expected to be in state 'UTILITY', but got '${this.state.name}' instead`);
265
277
  }
266
278
  }
279
+ utilityExecutorForContractSync(anchorBlock) {
280
+ return async (call)=>{
281
+ const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
282
+ if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
283
+ throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
284
+ }
285
+ try {
286
+ const oracle = new UtilityExecutionOracle(call.to, [], [], anchorBlock, this.contractStore, this.noteStore, this.keyStore, this.addressStore, this.stateMachine.node, this.stateMachine.anchorBlockStore, this.recipientTaggingStore, this.senderAddressBookStore, this.capsuleStore, this.privateEventStore, this.currentJobId);
287
+ await new WASMSimulator().executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback()).catch((err)=>{
288
+ err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
289
+ throw new ExecutionError(err.message, {
290
+ contractAddress: call.to,
291
+ functionSelector: call.selector
292
+ }, extractCallStack(err, entryPointArtifact.debug), {
293
+ cause: err
294
+ });
295
+ });
296
+ } catch (err) {
297
+ throw createSimulationError(err instanceof Error ? err : new Error('Unknown error contract data sync'));
298
+ }
299
+ };
300
+ }
267
301
  }
@@ -150,7 +150,7 @@ export declare const ForeignCallArgsSchema: z.ZodArray<z.ZodUnion<[z.ZodString,
150
150
  error_kind: "custom";
151
151
  } & import("@aztec/stdlib/abi").AbiType) | undefined>;
152
152
  }>, z.ZodObject<{
153
- bytecode: import("../../../foundation/dest/schemas/types.js").ZodFor<Buffer<ArrayBufferLike>>;
153
+ bytecode: import("@aztec/foundation/schemas").ZodFor<Buffer<ArrayBufferLike>>;
154
154
  verificationKey: z.ZodOptional<z.ZodString>;
155
155
  debugSymbols: z.ZodString;
156
156
  debug: z.ZodOptional<z.ZodObject<{
@@ -656,27 +656,27 @@ export declare const ForeignCallArgsSchema: z.ZodArray<z.ZodUnion<[z.ZodString,
656
656
  }>;
657
657
  }>, z.ZodIntersection<z.ZodObject<{
658
658
  version: z.ZodLiteral<1>;
659
- salt: import("../../../foundation/dest/schemas/types.js").ZodFor<Fr>;
660
- deployer: import("../../../foundation/dest/schemas/types.js").ZodFor<AztecAddress>;
661
- currentContractClassId: import("../../../foundation/dest/schemas/types.js").ZodFor<Fr>;
662
- originalContractClassId: import("../../../foundation/dest/schemas/types.js").ZodFor<Fr>;
663
- initializationHash: import("../../../foundation/dest/schemas/types.js").ZodFor<Fr>;
659
+ salt: import("@aztec/foundation/schemas").ZodFor<Fr>;
660
+ deployer: import("@aztec/foundation/schemas").ZodFor<AztecAddress>;
661
+ currentContractClassId: import("@aztec/foundation/schemas").ZodFor<Fr>;
662
+ originalContractClassId: import("@aztec/foundation/schemas").ZodFor<Fr>;
663
+ initializationHash: import("@aztec/foundation/schemas").ZodFor<Fr>;
664
664
  publicKeys: z.ZodEffects<z.ZodObject<{
665
- masterNullifierPublicKey: z.ZodType<import("../../../foundation/dest/schemas/schemas.js").Point, any, string>;
666
- masterIncomingViewingPublicKey: z.ZodType<import("../../../foundation/dest/schemas/schemas.js").Point, any, string>;
667
- masterOutgoingViewingPublicKey: z.ZodType<import("../../../foundation/dest/schemas/schemas.js").Point, any, string>;
668
- masterTaggingPublicKey: z.ZodType<import("../../../foundation/dest/schemas/schemas.js").Point, any, string>;
665
+ masterNullifierPublicKey: z.ZodType<import("@aztec/foundation/schemas").Point, any, string>;
666
+ masterIncomingViewingPublicKey: z.ZodType<import("@aztec/foundation/schemas").Point, any, string>;
667
+ masterOutgoingViewingPublicKey: z.ZodType<import("@aztec/foundation/schemas").Point, any, string>;
668
+ masterTaggingPublicKey: z.ZodType<import("@aztec/foundation/schemas").Point, any, string>;
669
669
  }, "strip", z.ZodTypeAny, {
670
- masterNullifierPublicKey: import("../../../foundation/dest/schemas/schemas.js").Point;
671
- masterIncomingViewingPublicKey: import("../../../foundation/dest/schemas/schemas.js").Point;
672
- masterOutgoingViewingPublicKey: import("../../../foundation/dest/schemas/schemas.js").Point;
673
- masterTaggingPublicKey: import("../../../foundation/dest/schemas/schemas.js").Point;
670
+ masterNullifierPublicKey: import("@aztec/foundation/schemas").Point;
671
+ masterIncomingViewingPublicKey: import("@aztec/foundation/schemas").Point;
672
+ masterOutgoingViewingPublicKey: import("@aztec/foundation/schemas").Point;
673
+ masterTaggingPublicKey: import("@aztec/foundation/schemas").Point;
674
674
  }, {
675
675
  masterNullifierPublicKey: string;
676
676
  masterIncomingViewingPublicKey: string;
677
677
  masterOutgoingViewingPublicKey: string;
678
678
  masterTaggingPublicKey: string;
679
- }>, import("../../../stdlib/dest/keys/public_keys.js").PublicKeys, {
679
+ }>, import("@aztec/stdlib/keys").PublicKeys, {
680
680
  masterNullifierPublicKey: string;
681
681
  masterIncomingViewingPublicKey: string;
682
682
  masterOutgoingViewingPublicKey: string;
@@ -689,7 +689,7 @@ export declare const ForeignCallArgsSchema: z.ZodArray<z.ZodUnion<[z.ZodString,
689
689
  currentContractClassId: Fr;
690
690
  originalContractClassId: Fr;
691
691
  initializationHash: Fr;
692
- publicKeys: import("../../../stdlib/dest/keys/public_keys.js").PublicKeys;
692
+ publicKeys: import("@aztec/stdlib/keys").PublicKeys;
693
693
  }, {
694
694
  version: 1;
695
695
  salt?: any;
@@ -704,7 +704,7 @@ export declare const ForeignCallArgsSchema: z.ZodArray<z.ZodUnion<[z.ZodString,
704
704
  masterTaggingPublicKey: string;
705
705
  };
706
706
  }>, z.ZodObject<{
707
- address: import("../../../foundation/dest/schemas/types.js").ZodFor<AztecAddress>;
707
+ address: import("@aztec/foundation/schemas").ZodFor<AztecAddress>;
708
708
  }, "strip", z.ZodTypeAny, {
709
709
  address: AztecAddress;
710
710
  }, {
@@ -1,8 +1,8 @@
1
1
  import { BlockNumber } from '@aztec/foundation/branded-types';
2
2
  import { Fr } from '@aztec/foundation/curves/bn254';
3
- import { L2Block, L2BlockHeader } from '@aztec/stdlib/block';
3
+ import { L2BlockNew } from '@aztec/stdlib/block';
4
4
  import { type MerkleTreeWriteOperations } from '@aztec/stdlib/trees';
5
- import { GlobalVariables, TxEffect } from '@aztec/stdlib/tx';
5
+ import { BlockHeader, GlobalVariables, TxEffect } from '@aztec/stdlib/tx';
6
6
  /**
7
7
  * Returns a transaction request hash that is valid for transactions that are the only ones in a block.
8
8
  * @param blockNumber The number for the block in which there is a single transaction.
@@ -10,9 +10,9 @@ import { GlobalVariables, TxEffect } from '@aztec/stdlib/tx';
10
10
  */
11
11
  export declare function getSingleTxBlockRequestHash(blockNumber: BlockNumber): Fr;
12
12
  export declare function insertTxEffectIntoWorldTrees(txEffect: TxEffect, worldTrees: MerkleTreeWriteOperations): Promise<void>;
13
- export declare function makeTXEBlockHeader(worldTrees: MerkleTreeWriteOperations, globalVariables: GlobalVariables): Promise<L2BlockHeader>;
13
+ export declare function makeTXEBlockHeader(worldTrees: MerkleTreeWriteOperations, globalVariables: GlobalVariables): Promise<BlockHeader>;
14
14
  /**
15
- * Creates an L2Block with proper archive chaining.
15
+ * Creates an L2BlockNew with proper archive chaining.
16
16
  * This function:
17
17
  * 1. Gets the current archive state as lastArchive for the header
18
18
  * 2. Creates the block header
@@ -22,7 +22,7 @@ export declare function makeTXEBlockHeader(worldTrees: MerkleTreeWriteOperations
22
22
  * @param worldTrees - The world trees to read/write from
23
23
  * @param globalVariables - Global variables for the block
24
24
  * @param txEffects - Transaction effects to include in the block
25
- * @returns The created L2Block with proper archive chaining
25
+ * @returns The created L2BlockNew with proper archive chaining
26
26
  */
27
- export declare function makeTXEBlock(worldTrees: MerkleTreeWriteOperations, globalVariables: GlobalVariables, txEffects: TxEffect[]): Promise<L2Block>;
28
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tfY3JlYXRpb24uZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9ibG9ja19jcmVhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFNQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFOUQsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3BELE9BQU8sRUFBUSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFbkUsT0FBTyxFQUF3QyxLQUFLLHlCQUF5QixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDM0csT0FBTyxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUU3RDs7OztHQUlHO0FBQ0gsd0JBQWdCLDJCQUEyQixDQUFDLFdBQVcsRUFBRSxXQUFXLEdBQUcsRUFBRSxDQUV4RTtBQUVELHdCQUFzQiw0QkFBNEIsQ0FDaEQsUUFBUSxFQUFFLFFBQVEsRUFDbEIsVUFBVSxFQUFFLHlCQUF5QixHQUNwQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBa0JmO0FBRUQsd0JBQXNCLGtCQUFrQixDQUN0QyxVQUFVLEVBQUUseUJBQXlCLEVBQ3JDLGVBQWUsRUFBRSxlQUFlLEdBQy9CLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FjeEI7QUFFRDs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCx3QkFBc0IsWUFBWSxDQUNoQyxVQUFVLEVBQUUseUJBQXlCLEVBQ3JDLGVBQWUsRUFBRSxlQUFlLEVBQ2hDLFNBQVMsRUFBRSxRQUFRLEVBQUUsR0FDcEIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQVdsQiJ9
27
+ export declare function makeTXEBlock(worldTrees: MerkleTreeWriteOperations, globalVariables: GlobalVariables, txEffects: TxEffect[]): Promise<L2BlockNew>;
28
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tfY3JlYXRpb24uZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9ibG9ja19jcmVhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFNQSxPQUFPLEVBQUUsV0FBVyxFQUEyQyxNQUFNLGlDQUFpQyxDQUFDO0FBRXZHLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEVBQVEsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUF3QyxLQUFLLHlCQUF5QixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDM0csT0FBTyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFMUU7Ozs7R0FJRztBQUNILHdCQUFnQiwyQkFBMkIsQ0FBQyxXQUFXLEVBQUUsV0FBVyxHQUFHLEVBQUUsQ0FFeEU7QUFFRCx3QkFBc0IsNEJBQTRCLENBQ2hELFFBQVEsRUFBRSxRQUFRLEVBQ2xCLFVBQVUsRUFBRSx5QkFBeUIsR0FDcEMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQWtCZjtBQUVELHdCQUFzQixrQkFBa0IsQ0FDdEMsVUFBVSxFQUFFLHlCQUF5QixFQUNyQyxlQUFlLEVBQUUsZUFBZSxHQUMvQixPQUFPLENBQUMsV0FBVyxDQUFDLENBWXRCO0FBRUQ7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsd0JBQXNCLFlBQVksQ0FDaEMsVUFBVSxFQUFFLHlCQUF5QixFQUNyQyxlQUFlLEVBQUUsZUFBZSxFQUNoQyxTQUFTLEVBQUUsUUFBUSxFQUFFLEdBQ3BCLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FlckIifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"block_creation.d.ts","sourceRoot":"","sources":["../../src/utils/block_creation.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAQ,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,EAAwC,KAAK,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAC3G,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE7D;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,WAAW,GAAG,EAAE,CAExE;AAED,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,yBAAyB,GACpC,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,yBAAyB,EACrC,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,aAAa,CAAC,CAcxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,yBAAyB,EACrC,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,QAAQ,EAAE,GACpB,OAAO,CAAC,OAAO,CAAC,CAWlB"}
1
+ {"version":3,"file":"block_creation.d.ts","sourceRoot":"","sources":["../../src/utils/block_creation.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAA2C,MAAM,iCAAiC,CAAC;AAEvG,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAQ,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAwC,KAAK,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAC3G,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,WAAW,GAAG,EAAE,CAExE;AAED,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,yBAAyB,GACpC,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,yBAAyB,EACrC,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,WAAW,CAAC,CAYtB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,yBAAyB,EACrC,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,QAAQ,EAAE,GACpB,OAAO,CAAC,UAAU,CAAC,CAerB"}
@@ -1,9 +1,10 @@
1
1
  import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, NULLIFIER_SUBTREE_HEIGHT, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
2
+ import { CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types';
2
3
  import { padArrayEnd } from '@aztec/foundation/collection';
3
4
  import { Fr } from '@aztec/foundation/curves/bn254';
4
- import { Body, L2Block, L2BlockHeader } from '@aztec/stdlib/block';
5
- import { makeContentCommitment } from '@aztec/stdlib/testing';
5
+ import { Body, L2BlockNew } from '@aztec/stdlib/block';
6
6
  import { AppendOnlyTreeSnapshot, MerkleTreeId } from '@aztec/stdlib/trees';
7
+ import { BlockHeader } from '@aztec/stdlib/tx';
7
8
  /**
8
9
  * Returns a transaction request hash that is valid for transactions that are the only ones in a block.
9
10
  * @param blockNumber The number for the block in which there is a single transaction.
@@ -20,10 +21,17 @@ export async function insertTxEffectIntoWorldTrees(txEffect, worldTrees) {
20
21
  export async function makeTXEBlockHeader(worldTrees, globalVariables) {
21
22
  const stateReference = await worldTrees.getStateReference();
22
23
  const archiveInfo = await worldTrees.getTreeInfo(MerkleTreeId.ARCHIVE);
23
- return new L2BlockHeader(new AppendOnlyTreeSnapshot(new Fr(archiveInfo.root), Number(archiveInfo.size)), makeContentCommitment(), stateReference, globalVariables, Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO);
24
+ return BlockHeader.from({
25
+ lastArchive: new AppendOnlyTreeSnapshot(new Fr(archiveInfo.root), Number(archiveInfo.size)),
26
+ spongeBlobHash: Fr.ZERO,
27
+ state: stateReference,
28
+ globalVariables,
29
+ totalFees: Fr.ZERO,
30
+ totalManaUsed: Fr.ZERO
31
+ });
24
32
  }
25
33
  /**
26
- * Creates an L2Block with proper archive chaining.
34
+ * Creates an L2BlockNew with proper archive chaining.
27
35
  * This function:
28
36
  * 1. Gets the current archive state as lastArchive for the header
29
37
  * 2. Creates the block header
@@ -33,13 +41,16 @@ export async function makeTXEBlockHeader(worldTrees, globalVariables) {
33
41
  * @param worldTrees - The world trees to read/write from
34
42
  * @param globalVariables - Global variables for the block
35
43
  * @param txEffects - Transaction effects to include in the block
36
- * @returns The created L2Block with proper archive chaining
44
+ * @returns The created L2BlockNew with proper archive chaining
37
45
  */ export async function makeTXEBlock(worldTrees, globalVariables, txEffects) {
38
46
  const header = await makeTXEBlockHeader(worldTrees, globalVariables);
39
47
  // Update the archive tree with this block's header hash
40
- await worldTrees.updateArchive(header.toBlockHeader());
48
+ await worldTrees.updateArchive(header);
41
49
  // Get the new archive state after updating
42
50
  const newArchiveInfo = await worldTrees.getTreeInfo(MerkleTreeId.ARCHIVE);
43
51
  const newArchive = new AppendOnlyTreeSnapshot(new Fr(newArchiveInfo.root), Number(newArchiveInfo.size));
44
- return new L2Block(newArchive, header, new Body(txEffects));
52
+ // L2BlockNew requires checkpointNumber and indexWithinCheckpoint
53
+ const checkpointNumber = CheckpointNumber.fromBlockNumber(globalVariables.blockNumber);
54
+ const indexWithinCheckpoint = IndexWithinCheckpoint(0);
55
+ return new L2BlockNew(newArchive, header, new Body(txEffects), checkpointNumber, indexWithinCheckpoint);
45
56
  }
@@ -1,6 +1,5 @@
1
1
  import { BlockNumber } from '@aztec/foundation/branded-types';
2
- import { Fr } from '@aztec/foundation/curves/bn254';
3
2
  import type { ExecutionNoteCache } from '@aztec/pxe/simulator';
4
3
  import { TxEffect } from '@aztec/stdlib/tx';
5
- export declare function makeTxEffect(noteCache: ExecutionNoteCache, protocolNullifier: Fr, txBlockNumber: BlockNumber): Promise<TxEffect>;
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhfZWZmZWN0X2NyZWF0aW9uLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvdHhfZWZmZWN0X2NyZWF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUM5RCxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDcEQsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUUvRCxPQUFPLEVBQUUsUUFBUSxFQUFVLE1BQU0sa0JBQWtCLENBQUM7QUFFcEQsd0JBQXNCLFlBQVksQ0FDaEMsU0FBUyxFQUFFLGtCQUFrQixFQUM3QixpQkFBaUIsRUFBRSxFQUFFLEVBQ3JCLGFBQWEsRUFBRSxXQUFXLEdBQ3pCLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0EyQm5CIn0=
4
+ export declare function makeTxEffect(noteCache: ExecutionNoteCache, txBlockNumber: BlockNumber): Promise<TxEffect>;
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhfZWZmZWN0X2NyZWF0aW9uLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvdHhfZWZmZWN0X2NyZWF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUU5RCxPQUFPLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRS9ELE9BQU8sRUFBRSxRQUFRLEVBQVUsTUFBTSxrQkFBa0IsQ0FBQztBQUVwRCx3QkFBc0IsWUFBWSxDQUFDLFNBQVMsRUFBRSxrQkFBa0IsRUFBRSxhQUFhLEVBQUUsV0FBVyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0F1Qi9HIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"tx_effect_creation.d.ts","sourceRoot":"","sources":["../../src/utils/tx_effect_creation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,QAAQ,EAAU,MAAM,kBAAkB,CAAC;AAEpD,wBAAsB,YAAY,CAChC,SAAS,EAAE,kBAAkB,EAC7B,iBAAiB,EAAE,EAAE,EACrB,aAAa,EAAE,WAAW,GACzB,OAAO,CAAC,QAAQ,CAAC,CA2BnB"}
1
+ {"version":3,"file":"tx_effect_creation.d.ts","sourceRoot":"","sources":["../../src/utils/tx_effect_creation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,QAAQ,EAAU,MAAM,kBAAkB,CAAC;AAEpD,wBAAsB,YAAY,CAAC,SAAS,EAAE,kBAAkB,EAAE,aAAa,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAuB/G"}
@@ -1,16 +1,13 @@
1
1
  import { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import { computeNoteHashNonce, computeUniqueNoteHash, siloNoteHash } from '@aztec/stdlib/hash';
3
3
  import { TxEffect, TxHash } from '@aztec/stdlib/tx';
4
- export async function makeTxEffect(noteCache, protocolNullifier, txBlockNumber) {
4
+ export async function makeTxEffect(noteCache, txBlockNumber) {
5
5
  const txEffect = TxEffect.empty();
6
- const { usedProtocolNullifierForNonces } = noteCache.finish();
7
- const nonceGenerator = usedProtocolNullifierForNonces ? protocolNullifier : noteCache.getAllNullifiers()[0];
6
+ noteCache.finish();
7
+ const nonceGenerator = noteCache.getNonceGenerator();
8
8
  txEffect.noteHashes = await Promise.all(noteCache.getAllNotes().map(async (pendingNote, i)=>computeUniqueNoteHash(await computeNoteHashNonce(nonceGenerator, i), await siloNoteHash(pendingNote.note.contractAddress, pendingNote.noteHashForConsumption))));
9
9
  // Nullifiers are already siloed
10
10
  txEffect.nullifiers = noteCache.getAllNullifiers();
11
- if (usedProtocolNullifierForNonces) {
12
- txEffect.nullifiers.unshift(protocolNullifier);
13
- }
14
11
  txEffect.txHash = new TxHash(new Fr(txBlockNumber));
15
12
  return txEffect;
16
13
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/txe",
3
- "version": "0.0.1-commit.c7c42ec",
3
+ "version": "0.0.1-commit.f295ac2",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "bin": "./dest/bin/index.js",
@@ -61,27 +61,27 @@
61
61
  ]
62
62
  },
63
63
  "dependencies": {
64
- "@aztec/accounts": "0.0.1-commit.c7c42ec",
65
- "@aztec/archiver": "0.0.1-commit.c7c42ec",
66
- "@aztec/aztec-node": "0.0.1-commit.c7c42ec",
67
- "@aztec/aztec.js": "0.0.1-commit.c7c42ec",
68
- "@aztec/bb-prover": "0.0.1-commit.c7c42ec",
69
- "@aztec/constants": "0.0.1-commit.c7c42ec",
70
- "@aztec/foundation": "0.0.1-commit.c7c42ec",
71
- "@aztec/key-store": "0.0.1-commit.c7c42ec",
72
- "@aztec/kv-store": "0.0.1-commit.c7c42ec",
73
- "@aztec/protocol-contracts": "0.0.1-commit.c7c42ec",
74
- "@aztec/pxe": "0.0.1-commit.c7c42ec",
75
- "@aztec/simulator": "0.0.1-commit.c7c42ec",
76
- "@aztec/stdlib": "0.0.1-commit.c7c42ec",
77
- "@aztec/world-state": "0.0.1-commit.c7c42ec",
64
+ "@aztec/accounts": "0.0.1-commit.f295ac2",
65
+ "@aztec/archiver": "0.0.1-commit.f295ac2",
66
+ "@aztec/aztec-node": "0.0.1-commit.f295ac2",
67
+ "@aztec/aztec.js": "0.0.1-commit.f295ac2",
68
+ "@aztec/bb-prover": "0.0.1-commit.f295ac2",
69
+ "@aztec/constants": "0.0.1-commit.f295ac2",
70
+ "@aztec/foundation": "0.0.1-commit.f295ac2",
71
+ "@aztec/key-store": "0.0.1-commit.f295ac2",
72
+ "@aztec/kv-store": "0.0.1-commit.f295ac2",
73
+ "@aztec/protocol-contracts": "0.0.1-commit.f295ac2",
74
+ "@aztec/pxe": "0.0.1-commit.f295ac2",
75
+ "@aztec/simulator": "0.0.1-commit.f295ac2",
76
+ "@aztec/stdlib": "0.0.1-commit.f295ac2",
77
+ "@aztec/world-state": "0.0.1-commit.f295ac2",
78
78
  "zod": "^3.23.8"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@jest/globals": "^30.0.0",
82
82
  "@types/jest": "^30.0.0",
83
83
  "@types/node": "^22.15.17",
84
- "@typescript/native-preview": "7.0.0-dev.20251126.1",
84
+ "@typescript/native-preview": "7.0.0-dev.20260113.1",
85
85
  "jest": "^30.0.0",
86
86
  "jest-mock-extended": "^4.0.0",
87
87
  "ts-node": "^10.9.1",
@@ -0,0 +1,3 @@
1
+ import { AztecAddress } from '@aztec/stdlib/aztec-address';
2
+
3
+ export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
@@ -3,7 +3,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
3
3
  import { type Logger, createLogger } from '@aztec/foundation/log';
4
4
  import { PublicDataWrite } from '@aztec/stdlib/avm';
5
5
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
6
- import type { L2Block } from '@aztec/stdlib/block';
6
+ import type { L2BlockNew } from '@aztec/stdlib/block';
7
7
  import { computePublicDataTreeLeafSlot, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
8
8
  import {
9
9
  MerkleTreeId,
@@ -124,7 +124,7 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
124
124
  return value;
125
125
  }
126
126
 
127
- async close(): Promise<L2Block> {
127
+ async close(): Promise<L2BlockNew> {
128
128
  this.logger.debug('Exiting Public Context, building block with collected side effects', {
129
129
  blockNumber: this.globalVariables.blockNumber,
130
130
  });
@@ -49,7 +49,7 @@ import {
49
49
  PublicContractsDB,
50
50
  PublicProcessor,
51
51
  } from '@aztec/simulator/server';
52
- import { type ContractArtifact, EventSelector, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
52
+ import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
53
53
  import { AuthWitness } from '@aztec/stdlib/auth-witness';
54
54
  import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
55
55
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -80,8 +80,8 @@ import {
80
80
  import type { UInt64 } from '@aztec/stdlib/types';
81
81
  import { ForkCheckpoint } from '@aztec/world-state';
82
82
 
83
+ import { DEFAULT_ADDRESS } from '../constants.js';
83
84
  import type { TXEStateMachine } from '../state_machine/index.js';
84
- import { DEFAULT_ADDRESS } from '../txe_session.js';
85
85
  import type { TXEAccountStore } from '../util/txe_account_store.js';
86
86
  import type { TXEContractStore } from '../util/txe_contract_store.js';
87
87
  import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
@@ -106,6 +106,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
106
106
  private senderAddressBookStore: SenderAddressBookStore,
107
107
  private capsuleStore: CapsuleStore,
108
108
  private privateEventStore: PrivateEventStore,
109
+ private jobId: string,
109
110
  private nextBlockTimestamp: bigint,
110
111
  private version: Fr,
111
112
  private chainId: Fr,
@@ -156,7 +157,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
156
157
  }
157
158
 
158
159
  async txeGetLastTxEffects() {
159
- const block = await this.stateMachine.archiver.getL2Block('latest');
160
+ const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
161
+ const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
160
162
 
161
163
  if (block!.body.txEffects.length != 1) {
162
164
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -294,14 +296,19 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
294
296
  throw new Error(message);
295
297
  }
296
298
 
299
+ // Sync notes before executing private function to discover notes from previous transactions
300
+ const utilityExecutor = async (call: FunctionCall) => {
301
+ await this.executeUtilityCall(call);
302
+ };
303
+
304
+ await this.contractStore.syncPrivateState(targetContractAddress, functionSelector, utilityExecutor);
305
+
297
306
  const blockNumber = await this.txeGetNextBlockNumber();
298
307
 
299
308
  const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
300
309
 
301
310
  const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
302
-
303
311
  const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
304
-
305
312
  const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
306
313
 
307
314
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
@@ -310,6 +317,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
310
317
 
311
318
  const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
312
319
  const noteCache = new ExecutionNoteCache(protocolNullifier);
320
+ // In production, the account contract sets the min revertible counter before calling the app function.
321
+ // Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
322
+ // marking all side effects as revertible.
323
+ const minRevertibleSideEffectCounter = 1;
324
+ await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
313
325
  const taggingIndexCache = new ExecutionTaggingIndexCache();
314
326
 
315
327
  const simulator = new WASMSimulator();
@@ -320,6 +332,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
320
332
  callContext,
321
333
  /** Header of a block whose state is used during private execution (not the block the transaction is included in). */
322
334
  blockHeader,
335
+ utilityExecutor,
323
336
  /** List of transient auth witnesses to be used during this simulation */
324
337
  Array.from(this.authwits.values()),
325
338
  /** List of transient auth witnesses to be used during this simulation */
@@ -338,8 +351,9 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
338
351
  this.senderAddressBookStore,
339
352
  this.capsuleStore,
340
353
  this.privateEventStore,
341
- 0,
342
- 1,
354
+ this.jobId,
355
+ 0, // totalPublicArgsCount
356
+ minRevertibleSideEffectCounter, // (start) sideEffectCounter
343
357
  undefined, // log
344
358
  undefined, // scopes
345
359
  /**
@@ -375,19 +389,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
375
389
  }),
376
390
  );
377
391
 
378
- // TXE's top level context does not track side effect counters, and as such, minRevertibleSideEffectCounter is always 0.
379
- // This has the unfortunate consequence of always producing revertible nullifiers, which means we
380
- // must set the firstNullifierHint to Fr.ZERO so the txRequestHash is always used as nonce generator
381
- result = new PrivateExecutionResult(executionResult, Fr.ZERO, publicFunctionsCalldata);
392
+ noteCache.finish();
393
+ const nonceGenerator = noteCache.getNonceGenerator();
394
+ result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
382
395
  } catch (err) {
383
396
  throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
384
397
  }
385
398
 
386
- // According to the protocol rules, the nonce generator for the note hashes
387
- // can either be the first nullifier in the tx or the hash of the initial tx request
388
- // if there are none.
389
- const nonceGenerator = result.firstNullifier.equals(Fr.ZERO) ? protocolNullifier : result.firstNullifier;
390
- const { publicInputs } = await generateSimulatedProvingResult(result, nonceGenerator, this.contractStore);
399
+ // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
400
+ // the nonce generator for the note hashes.
401
+ // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
402
+ const { publicInputs } = await generateSimulatedProvingResult(
403
+ result,
404
+ this.contractStore,
405
+ minRevertibleSideEffectCounter,
406
+ );
391
407
 
392
408
  const globals = makeGlobalVariables();
393
409
  globals.blockNumber = blockNumber;
@@ -628,12 +644,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
628
644
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
629
645
  }
630
646
 
631
- const call = {
632
- name: artifact.name,
633
- selector: functionSelector,
634
- to: targetContractAddress,
635
- };
647
+ // Sync notes before executing utility function to discover notes from previous transactions
648
+ await this.contractStore.syncPrivateState(targetContractAddress, functionSelector, async call => {
649
+ await this.executeUtilityCall(call);
650
+ });
651
+
652
+ const call = new FunctionCall(
653
+ artifact.name,
654
+ targetContractAddress,
655
+ functionSelector,
656
+ FunctionType.UTILITY,
657
+ false,
658
+ false,
659
+ args,
660
+ [],
661
+ );
662
+
663
+ return this.executeUtilityCall(call);
664
+ }
636
665
 
666
+ private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
637
667
  const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
638
668
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
639
669
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
@@ -661,9 +691,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
661
691
  this.senderAddressBookStore,
662
692
  this.capsuleStore,
663
693
  this.privateEventStore,
694
+ this.jobId,
664
695
  );
665
696
  const acirExecutionResult = await new WASMSimulator()
666
- .executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
697
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
667
698
  .catch((err: Error) => {
668
699
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
669
700
  throw new ExecutionError(