@aztec/txe 0.0.1-commit.1bea0213 → 0.0.1-commit.21ecf947b

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 (40) hide show
  1. package/dest/oracle/interfaces.d.ts +2 -2
  2. package/dest/oracle/interfaces.d.ts.map +1 -1
  3. package/dest/oracle/txe_oracle_public_context.d.ts +2 -2
  4. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  5. package/dest/oracle/txe_oracle_public_context.js +3 -4
  6. package/dest/oracle/txe_oracle_top_level_context.d.ts +2 -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 +87 -26
  9. package/dest/rpc_translator.d.ts +8 -8
  10. package/dest/rpc_translator.d.ts.map +1 -1
  11. package/dest/rpc_translator.js +40 -29
  12. package/dest/state_machine/archiver.d.ts +1 -1
  13. package/dest/state_machine/archiver.d.ts.map +1 -1
  14. package/dest/state_machine/archiver.js +2 -0
  15. package/dest/state_machine/dummy_p2p_client.d.ts +11 -8
  16. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  17. package/dest/state_machine/dummy_p2p_client.js +21 -12
  18. package/dest/state_machine/index.d.ts +5 -5
  19. package/dest/state_machine/index.d.ts.map +1 -1
  20. package/dest/state_machine/index.js +14 -9
  21. package/dest/state_machine/mock_epoch_cache.d.ts +3 -1
  22. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  23. package/dest/state_machine/mock_epoch_cache.js +4 -0
  24. package/dest/txe_session.d.ts +1 -1
  25. package/dest/txe_session.d.ts.map +1 -1
  26. package/dest/txe_session.js +68 -9
  27. package/dest/utils/block_creation.d.ts +1 -1
  28. package/dest/utils/block_creation.d.ts.map +1 -1
  29. package/dest/utils/block_creation.js +3 -1
  30. package/package.json +15 -15
  31. package/src/oracle/interfaces.ts +1 -1
  32. package/src/oracle/txe_oracle_public_context.ts +3 -5
  33. package/src/oracle/txe_oracle_top_level_context.ts +106 -74
  34. package/src/rpc_translator.ts +42 -24
  35. package/src/state_machine/archiver.ts +2 -0
  36. package/src/state_machine/dummy_p2p_client.ts +29 -15
  37. package/src/state_machine/index.ts +24 -9
  38. package/src/state_machine/mock_epoch_cache.ts +5 -0
  39. package/src/txe_session.ts +70 -66
  40. package/src/utils/block_creation.ts +3 -1
@@ -3,7 +3,7 @@ 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, JobCoordinator, NoteService, NoteStore, PrivateEventStore, RecipientTaggingStore, SenderAddressBookStore, SenderTaggingStore } from '@aztec/pxe/server';
6
+ import { AddressStore, AnchorBlockStore, CapsuleStore, JobCoordinator, NoteService, NoteStore, PrivateEventStore, RecipientTaggingStore, SenderAddressBookStore, SenderTaggingStore } from '@aztec/pxe/server';
7
7
  import { ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache, Oracle, PrivateExecutionOracle, UtilityExecutionOracle } from '@aztec/pxe/simulator';
8
8
  import { ExecutionError, WASMSimulator, createSimulationError, extractCallStack, resolveAssertionMessageFromError, toACVMWitness } from '@aztec/simulator/client';
9
9
  import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
@@ -17,6 +17,7 @@ import { DEFAULT_ADDRESS } from './constants.js';
17
17
  import { TXEOraclePublicContext } from './oracle/txe_oracle_public_context.js';
18
18
  import { TXEOracleTopLevelContext } from './oracle/txe_oracle_top_level_context.js';
19
19
  import { RPCTranslator } from './rpc_translator.js';
20
+ import { TXEArchiver } from './state_machine/archiver.js';
20
21
  import { TXEStateMachine } from './state_machine/index.js';
21
22
  import { TXEAccountStore } from './util/txe_account_store.js';
22
23
  import { TXEContractStore } from './util/txe_contract_store.js';
@@ -96,7 +97,9 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
96
97
  await contractStore.addContractArtifact(contractClass.id, artifact);
97
98
  await contractStore.addContractInstance(instance);
98
99
  }
99
- const stateMachine = await TXEStateMachine.create(store);
100
+ const archiver = new TXEArchiver(store);
101
+ const anchorBlockStore = new AnchorBlockStore(store);
102
+ const stateMachine = await TXEStateMachine.create(archiver, anchorBlockStore, contractStore, noteStore);
100
103
  const nextBlockTimestamp = BigInt(Math.floor(new Date().getTime() / 1000));
101
104
  const version = new Fr(await stateMachine.node.getVersion());
102
105
  const chainId = new Fr(await stateMachine.node.getChainId());
@@ -163,11 +166,11 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
163
166
  }
164
167
  async enterPrivateState(contractAddress = DEFAULT_ADDRESS, anchorBlockNumber) {
165
168
  this.exitTopLevelState();
166
- await new NoteService(this.noteStore, this.stateMachine.node, this.stateMachine.anchorBlockStore, this.currentJobId).syncNoteNullifiers(contractAddress);
167
169
  // Private execution has two associated block numbers: the anchor block (i.e. the historical block that is used to
168
170
  // build the proof), and the *next* block, i.e. the one we'll create once the execution ends, and which will contain
169
171
  // a single transaction with the effects of what was done in the test.
170
172
  const anchorBlock = await this.stateMachine.node.getBlockHeader(anchorBlockNumber ?? 'latest');
173
+ await new NoteService(this.noteStore, this.stateMachine.node, anchorBlock, this.currentJobId).syncNoteNullifiers(contractAddress, 'ALL_SCOPES');
171
174
  const latestBlock = await this.stateMachine.node.getBlockHeader('latest');
172
175
  const nextBlockGlobalVariables = makeGlobalVariables(undefined, {
173
176
  blockNumber: BlockNumber(latestBlock.globalVariables.blockNumber + 1),
@@ -180,7 +183,31 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
180
183
  const noteCache = new ExecutionNoteCache(protocolNullifier);
181
184
  const taggingIndexCache = new ExecutionTaggingIndexCache();
182
185
  const utilityExecutor = this.utilityExecutorForContractSync(anchorBlock);
183
- 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);
186
+ this.oracleHandler = new PrivateExecutionOracle({
187
+ argsHash: Fr.ZERO,
188
+ txContext: new TxContext(this.chainId, this.version, GasSettings.empty()),
189
+ callContext: new CallContext(AztecAddress.ZERO, contractAddress, FunctionSelector.empty(), false),
190
+ anchorBlockHeader: anchorBlock,
191
+ utilityExecutor,
192
+ authWitnesses: [],
193
+ capsules: [],
194
+ executionCache: new HashedValuesCache(),
195
+ noteCache,
196
+ taggingIndexCache,
197
+ contractStore: this.contractStore,
198
+ noteStore: this.noteStore,
199
+ keyStore: this.keyStore,
200
+ addressStore: this.addressStore,
201
+ aztecNode: this.stateMachine.node,
202
+ senderTaggingStore: this.senderTaggingStore,
203
+ recipientTaggingStore: this.recipientTaggingStore,
204
+ senderAddressBookStore: this.senderAddressBookStore,
205
+ capsuleStore: this.capsuleStore,
206
+ privateEventStore: this.privateEventStore,
207
+ contractSyncService: this.stateMachine.contractSyncService,
208
+ jobId: this.currentJobId,
209
+ scopes: 'ALL_SCOPES'
210
+ });
184
211
  // We store the note and tagging index caches fed into the PrivateExecutionOracle (along with some other auxiliary
185
212
  // data) in order to refer to it later, mimicking the way this object is used by the ContractFunctionSimulator. The
186
213
  // difference resides in that the simulator has all information needed in order to run the simulation, while ours
@@ -214,14 +241,30 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
214
241
  }
215
242
  async enterUtilityState(contractAddress = DEFAULT_ADDRESS) {
216
243
  this.exitTopLevelState();
244
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
217
245
  // There is no automatic message discovery and contract-driven syncing process in inlined private or utility
218
246
  // contexts, which means that known nullifiers are also not searched for, since it is during the tagging sync that
219
247
  // we perform this. We therefore search for known nullifiers now, as otherwise notes that were nullified would not
220
248
  // be removed from the database.
221
249
  // TODO(#12553): make the synchronizer sync here instead and remove this
222
- await new NoteService(this.noteStore, this.stateMachine.node, this.stateMachine.anchorBlockStore, this.currentJobId).syncNoteNullifiers(contractAddress);
223
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
224
- 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);
250
+ await new NoteService(this.noteStore, this.stateMachine.node, anchorBlockHeader, this.currentJobId).syncNoteNullifiers(contractAddress, 'ALL_SCOPES');
251
+ this.oracleHandler = new UtilityExecutionOracle({
252
+ contractAddress,
253
+ authWitnesses: [],
254
+ capsules: [],
255
+ anchorBlockHeader,
256
+ contractStore: this.contractStore,
257
+ noteStore: this.noteStore,
258
+ keyStore: this.keyStore,
259
+ addressStore: this.addressStore,
260
+ aztecNode: this.stateMachine.node,
261
+ recipientTaggingStore: this.recipientTaggingStore,
262
+ senderAddressBookStore: this.senderAddressBookStore,
263
+ capsuleStore: this.capsuleStore,
264
+ privateEventStore: this.privateEventStore,
265
+ jobId: this.currentJobId,
266
+ scopes: 'ALL_SCOPES'
267
+ });
225
268
  this.state = {
226
269
  name: 'UTILITY'
227
270
  };
@@ -278,13 +321,29 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
278
321
  }
279
322
  }
280
323
  utilityExecutorForContractSync(anchorBlock) {
281
- return async (call)=>{
324
+ return async (call, scopes)=>{
282
325
  const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
283
326
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
284
327
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
285
328
  }
286
329
  try {
287
- 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);
330
+ const oracle = new UtilityExecutionOracle({
331
+ contractAddress: call.to,
332
+ authWitnesses: [],
333
+ capsules: [],
334
+ anchorBlockHeader: anchorBlock,
335
+ contractStore: this.contractStore,
336
+ noteStore: this.noteStore,
337
+ keyStore: this.keyStore,
338
+ addressStore: this.addressStore,
339
+ aztecNode: this.stateMachine.node,
340
+ recipientTaggingStore: this.recipientTaggingStore,
341
+ senderAddressBookStore: this.senderAddressBookStore,
342
+ capsuleStore: this.capsuleStore,
343
+ privateEventStore: this.privateEventStore,
344
+ jobId: this.currentJobId,
345
+ scopes
346
+ });
288
347
  await new WASMSimulator().executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback()).catch((err)=>{
289
348
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
290
349
  throw new ExecutionError(err.message, {
@@ -25,4 +25,4 @@ export declare function makeTXEBlockHeader(worldTrees: MerkleTreeWriteOperations
25
25
  * @returns The created L2Block with proper archive chaining
26
26
  */
27
27
  export declare function makeTXEBlock(worldTrees: MerkleTreeWriteOperations, globalVariables: GlobalVariables, txEffects: TxEffect[]): Promise<L2Block>;
28
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tfY3JlYXRpb24uZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9ibG9ja19jcmVhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFNQSxPQUFPLEVBQUUsV0FBVyxFQUEyQyxNQUFNLGlDQUFpQyxDQUFDO0FBRXZHLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEVBQVEsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUF3QyxLQUFLLHlCQUF5QixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDM0csT0FBTyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFMUU7Ozs7R0FJRztBQUNILHdCQUFnQiwyQkFBMkIsQ0FBQyxXQUFXLEVBQUUsV0FBVyxHQUFHLEVBQUUsQ0FFeEU7QUFFRCx3QkFBc0IsNEJBQTRCLENBQ2hELFFBQVEsRUFBRSxRQUFRLEVBQ2xCLFVBQVUsRUFBRSx5QkFBeUIsR0FDcEMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQWtCZjtBQUVELHdCQUFzQixrQkFBa0IsQ0FDdEMsVUFBVSxFQUFFLHlCQUF5QixFQUNyQyxlQUFlLEVBQUUsZUFBZSxHQUMvQixPQUFPLENBQUMsV0FBVyxDQUFDLENBWXRCO0FBRUQ7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsd0JBQXNCLFlBQVksQ0FDaEMsVUFBVSxFQUFFLHlCQUF5QixFQUNyQyxlQUFlLEVBQUUsZUFBZSxFQUNoQyxTQUFTLEVBQUUsUUFBUSxFQUFFLEdBQ3BCLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FlbEIifQ==
28
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tfY3JlYXRpb24uZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9ibG9ja19jcmVhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFNQSxPQUFPLEVBQUUsV0FBVyxFQUEyQyxNQUFNLGlDQUFpQyxDQUFDO0FBRXZHLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEVBQVEsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUF3QyxLQUFLLHlCQUF5QixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDM0csT0FBTyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFMUU7Ozs7R0FJRztBQUNILHdCQUFnQiwyQkFBMkIsQ0FBQyxXQUFXLEVBQUUsV0FBVyxHQUFHLEVBQUUsQ0FFeEU7QUFFRCx3QkFBc0IsNEJBQTRCLENBQ2hELFFBQVEsRUFBRSxRQUFRLEVBQ2xCLFVBQVUsRUFBRSx5QkFBeUIsR0FDcEMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQWtCZjtBQUVELHdCQUFzQixrQkFBa0IsQ0FDdEMsVUFBVSxFQUFFLHlCQUF5QixFQUNyQyxlQUFlLEVBQUUsZUFBZSxHQUMvQixPQUFPLENBQUMsV0FBVyxDQUFDLENBWXRCO0FBRUQ7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsd0JBQXNCLFlBQVksQ0FDaEMsVUFBVSxFQUFFLHlCQUF5QixFQUNyQyxlQUFlLEVBQUUsZUFBZSxFQUNoQyxTQUFTLEVBQUUsUUFBUSxFQUFFLEdBQ3BCLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FpQmxCIn0=
@@ -1 +1 @@
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,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACpD,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,OAAO,CAAC,CAelB"}
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,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACpD,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,OAAO,CAAC,CAiBlB"}
@@ -49,7 +49,9 @@ export async function makeTXEBlockHeader(worldTrees, globalVariables) {
49
49
  // Get the new archive state after updating
50
50
  const newArchiveInfo = await worldTrees.getTreeInfo(MerkleTreeId.ARCHIVE);
51
51
  const newArchive = new AppendOnlyTreeSnapshot(new Fr(newArchiveInfo.root), Number(newArchiveInfo.size));
52
- // L2Block requires checkpointNumber and indexWithinCheckpoint
52
+ // L2Block requires checkpointNumber and indexWithinCheckpoint.
53
+ // TXE uses 1-block-per-checkpoint for testing simplicity, so we can use block number as checkpoint number.
54
+ // This uses the deprecated fromBlockNumber method intentionally for the TXE testing environment.
53
55
  const checkpointNumber = CheckpointNumber.fromBlockNumber(globalVariables.blockNumber);
54
56
  const indexWithinCheckpoint = IndexWithinCheckpoint(0);
55
57
  return new L2Block(newArchive, header, new Body(txEffects), checkpointNumber, indexWithinCheckpoint);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/txe",
3
- "version": "0.0.1-commit.1bea0213",
3
+ "version": "0.0.1-commit.21ecf947b",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "bin": "./dest/bin/index.js",
@@ -61,20 +61,20 @@
61
61
  ]
62
62
  },
63
63
  "dependencies": {
64
- "@aztec/accounts": "0.0.1-commit.1bea0213",
65
- "@aztec/archiver": "0.0.1-commit.1bea0213",
66
- "@aztec/aztec-node": "0.0.1-commit.1bea0213",
67
- "@aztec/aztec.js": "0.0.1-commit.1bea0213",
68
- "@aztec/bb-prover": "0.0.1-commit.1bea0213",
69
- "@aztec/constants": "0.0.1-commit.1bea0213",
70
- "@aztec/foundation": "0.0.1-commit.1bea0213",
71
- "@aztec/key-store": "0.0.1-commit.1bea0213",
72
- "@aztec/kv-store": "0.0.1-commit.1bea0213",
73
- "@aztec/protocol-contracts": "0.0.1-commit.1bea0213",
74
- "@aztec/pxe": "0.0.1-commit.1bea0213",
75
- "@aztec/simulator": "0.0.1-commit.1bea0213",
76
- "@aztec/stdlib": "0.0.1-commit.1bea0213",
77
- "@aztec/world-state": "0.0.1-commit.1bea0213",
64
+ "@aztec/accounts": "0.0.1-commit.21ecf947b",
65
+ "@aztec/archiver": "0.0.1-commit.21ecf947b",
66
+ "@aztec/aztec-node": "0.0.1-commit.21ecf947b",
67
+ "@aztec/aztec.js": "0.0.1-commit.21ecf947b",
68
+ "@aztec/bb-prover": "0.0.1-commit.21ecf947b",
69
+ "@aztec/constants": "0.0.1-commit.21ecf947b",
70
+ "@aztec/foundation": "0.0.1-commit.21ecf947b",
71
+ "@aztec/key-store": "0.0.1-commit.21ecf947b",
72
+ "@aztec/kv-store": "0.0.1-commit.21ecf947b",
73
+ "@aztec/protocol-contracts": "0.0.1-commit.21ecf947b",
74
+ "@aztec/pxe": "0.0.1-commit.21ecf947b",
75
+ "@aztec/simulator": "0.0.1-commit.21ecf947b",
76
+ "@aztec/stdlib": "0.0.1-commit.21ecf947b",
77
+ "@aztec/world-state": "0.0.1-commit.21ecf947b",
78
78
  "zod": "^3.23.8"
79
79
  },
80
80
  "devDependencies": {
@@ -33,7 +33,7 @@ export interface IAvmExecutionOracle {
33
33
  avmOpcodeVersion(): Promise<Fr>;
34
34
  avmOpcodeEmitNullifier(nullifier: Fr): Promise<void>;
35
35
  avmOpcodeEmitNoteHash(noteHash: Fr): Promise<void>;
36
- avmOpcodeNullifierExists(innerNullifier: Fr, targetAddress: AztecAddress): Promise<boolean>;
36
+ avmOpcodeNullifierExists(siloedNullifier: Fr): Promise<boolean>;
37
37
  avmOpcodeStorageWrite(slot: Fr, value: Fr): Promise<void>;
38
38
  avmOpcodeStorageRead(slot: Fr, contractAddress: AztecAddress): Promise<Fr>;
39
39
  }
@@ -78,13 +78,11 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
78
78
  this.transientUniqueNoteHashes.push(siloedNoteHash);
79
79
  }
80
80
 
81
- async avmOpcodeNullifierExists(innerNullifier: Fr, targetAddress: AztecAddress): Promise<boolean> {
82
- const nullifier = await siloNullifier(targetAddress, innerNullifier!);
83
-
81
+ async avmOpcodeNullifierExists(siloedNullifier: Fr): Promise<boolean> {
84
82
  const treeIndex = (
85
- await this.forkedWorldTrees.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [nullifier.toBuffer()])
83
+ await this.forkedWorldTrees.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [siloedNullifier.toBuffer()])
86
84
  )[0];
87
- const transientIndex = this.transientSiloedNullifiers.find(n => n.equals(nullifier));
85
+ const transientIndex = this.transientSiloedNullifiers.find(n => n.equals(siloedNullifier));
88
86
 
89
87
  return treeIndex !== undefined || transientIndex !== undefined;
90
88
  }
@@ -12,6 +12,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
12
12
  import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@aztec/foundation/log';
13
13
  import { TestDateProvider } from '@aztec/foundation/timer';
14
14
  import type { KeyStore } from '@aztec/key-store';
15
+ import type { AccessScopes } from '@aztec/pxe/client/lazy';
15
16
  import {
16
17
  AddressStore,
17
18
  CapsuleStore,
@@ -22,7 +23,6 @@ import {
22
23
  SenderAddressBookStore,
23
24
  SenderTaggingStore,
24
25
  enrichPublicSimulationError,
25
- syncState,
26
26
  } from '@aztec/pxe/server';
27
27
  import {
28
28
  ExecutionNoteCache,
@@ -132,13 +132,14 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
132
132
  }
133
133
 
134
134
  // We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
135
- utilityDebugLog(level: number, message: string, fields: Fr[]): void {
135
+ utilityLog(level: number, message: string, fields: Fr[]): Promise<void> {
136
136
  if (!LogLevels[level]) {
137
- throw new Error(`Invalid debug log level: ${level}`);
137
+ throw new Error(`Invalid log level: ${level}`);
138
138
  }
139
139
  const levelName = LogLevels[level];
140
140
 
141
141
  this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
142
+ return Promise.resolve();
142
143
  }
143
144
 
144
145
  txeGetDefaultAddress(): AztecAddress {
@@ -297,12 +298,24 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
297
298
  throw new Error(message);
298
299
  }
299
300
 
301
+ // When `from` is the zero address (e.g. when deploying a new account contract), we return an
302
+ // empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
303
+ const effectiveScopes = from.isZero() ? [] : [from];
304
+
300
305
  // Sync notes before executing private function to discover notes from previous transactions
301
- const utilityExecutor = async (call: FunctionCall) => {
302
- await this.executeUtilityCall(call);
306
+ const utilityExecutor = async (call: FunctionCall, execScopes: AccessScopes) => {
307
+ await this.executeUtilityCall(call, execScopes);
303
308
  };
304
309
 
305
- await syncState(targetContractAddress, this.contractStore, functionSelector, utilityExecutor);
310
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
311
+ await this.stateMachine.contractSyncService.ensureContractSynced(
312
+ targetContractAddress,
313
+ functionSelector,
314
+ utilityExecutor,
315
+ blockHeader,
316
+ this.jobId,
317
+ effectiveScopes,
318
+ );
306
319
 
307
320
  const blockNumber = await this.txeGetNextBlockNumber();
308
321
 
@@ -314,8 +327,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
314
327
 
315
328
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
316
329
 
317
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
318
-
319
330
  const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
320
331
  const noteCache = new ExecutionNoteCache(protocolNullifier);
321
332
  // In production, the account contract sets the min revertible counter before calling the app function.
@@ -327,43 +338,37 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
327
338
 
328
339
  const simulator = new WASMSimulator();
329
340
 
330
- const privateExecutionOracle = new PrivateExecutionOracle(
341
+ const privateExecutionOracle = new PrivateExecutionOracle({
331
342
  argsHash,
332
343
  txContext,
333
344
  callContext,
334
- /** Header of a block whose state is used during private execution (not the block the transaction is included in). */
335
- blockHeader,
345
+ anchorBlockHeader: blockHeader,
336
346
  utilityExecutor,
337
- /** List of transient auth witnesses to be used during this simulation */
338
- Array.from(this.authwits.values()),
339
- /** List of transient auth witnesses to be used during this simulation */
340
- [],
341
- HashedValuesCache.create([new HashedValues(args, argsHash)]),
347
+ authWitnesses: Array.from(this.authwits.values()),
348
+ capsules: [],
349
+ executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
342
350
  noteCache,
343
351
  taggingIndexCache,
344
- this.contractStore,
345
- this.noteStore,
346
- this.keyStore,
347
- this.addressStore,
348
- this.stateMachine.node,
349
- this.stateMachine.anchorBlockStore,
350
- this.senderTaggingStore,
351
- this.recipientTaggingStore,
352
- this.senderAddressBookStore,
353
- this.capsuleStore,
354
- this.privateEventStore,
355
- this.jobId,
356
- 0, // totalPublicArgsCount
357
- minRevertibleSideEffectCounter, // (start) sideEffectCounter
358
- undefined, // log
359
- undefined, // scopes
360
- /**
361
- * In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
362
- * contract would perform, including setting senderForTags.
363
- */
364
- from,
352
+ contractStore: this.contractStore,
353
+ noteStore: this.noteStore,
354
+ keyStore: this.keyStore,
355
+ addressStore: this.addressStore,
356
+ aztecNode: this.stateMachine.node,
357
+ senderTaggingStore: this.senderTaggingStore,
358
+ recipientTaggingStore: this.recipientTaggingStore,
359
+ senderAddressBookStore: this.senderAddressBookStore,
360
+ capsuleStore: this.capsuleStore,
361
+ privateEventStore: this.privateEventStore,
362
+ contractSyncService: this.stateMachine.contractSyncService,
363
+ jobId: this.jobId,
364
+ totalPublicCalldataCount: 0,
365
+ sideEffectCounter: minRevertibleSideEffectCounter,
366
+ scopes: effectiveScopes,
367
+ // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
368
+ // contract would perform, including setting senderForTags.
369
+ senderForTags: from,
365
370
  simulator,
366
- );
371
+ });
367
372
 
368
373
  // Note: This is a slight modification of simulator.run without any of the checks. Maybe we should modify simulator.run with a boolean value to skip checks.
369
374
  let result: PrivateExecutionResult;
@@ -402,7 +407,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
402
407
  // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
403
408
  const { publicInputs } = await generateSimulatedProvingResult(
404
409
  result,
405
- this.contractStore,
410
+ (addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
411
+ this.stateMachine.node,
406
412
  minRevertibleSideEffectCounter,
407
413
  );
408
414
 
@@ -415,7 +421,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
415
421
 
416
422
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
417
423
 
418
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
424
+ const bindings = this.logger.getBindings();
425
+ const contractsDB = new PublicContractsDB(
426
+ new TXEPublicContractDataSource(blockNumber, this.contractStore),
427
+ bindings,
428
+ );
419
429
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
420
430
  const config = PublicSimulatorConfig.from({
421
431
  skipFeeEnforcement: true,
@@ -428,8 +438,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
428
438
  globals,
429
439
  guardedMerkleTrees,
430
440
  contractsDB,
431
- new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
441
+ new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
432
442
  new TestDateProvider(),
443
+ undefined,
444
+ createLogger('simulator:public-processor', bindings),
433
445
  );
434
446
 
435
447
  const tx = await Tx.create({
@@ -526,7 +538,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
526
538
 
527
539
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
528
540
 
529
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
541
+ const bindings2 = this.logger.getBindings();
542
+ const contractsDB = new PublicContractsDB(
543
+ new TXEPublicContractDataSource(blockNumber, this.contractStore),
544
+ bindings2,
545
+ );
530
546
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
531
547
  const config = PublicSimulatorConfig.from({
532
548
  skipFeeEnforcement: true,
@@ -535,8 +551,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
535
551
  collectStatistics: false,
536
552
  collectCallMetadata: true,
537
553
  });
538
- const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
539
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
554
+ const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
555
+ const processor = new PublicProcessor(
556
+ globals,
557
+ guardedMerkleTrees,
558
+ contractsDB,
559
+ simulator,
560
+ new TestDateProvider(),
561
+ undefined,
562
+ createLogger('simulator:public-processor', bindings2),
563
+ );
540
564
 
541
565
  // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
542
566
  // kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
@@ -567,7 +591,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
567
591
  constantData,
568
592
  /*gasUsed=*/ new Gas(0, 0),
569
593
  /*feePayer=*/ AztecAddress.zero(),
570
- /*includeByTimestamp=*/ 0n,
594
+ /*expirationTimestamp=*/ 0n,
571
595
  inputsForPublic,
572
596
  undefined,
573
597
  );
@@ -646,25 +670,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
646
670
  }
647
671
 
648
672
  // Sync notes before executing utility function to discover notes from previous transactions
649
- await syncState(targetContractAddress, this.contractStore, functionSelector, async call => {
650
- await this.executeUtilityCall(call);
651
- });
652
-
653
- const call = new FunctionCall(
654
- artifact.name,
673
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
674
+ await this.stateMachine.contractSyncService.ensureContractSynced(
655
675
  targetContractAddress,
656
676
  functionSelector,
657
- FunctionType.UTILITY,
658
- false,
659
- false,
660
- args,
661
- [],
677
+ async (call, execScopes) => {
678
+ await this.executeUtilityCall(call, execScopes);
679
+ },
680
+ blockHeader,
681
+ this.jobId,
682
+ 'ALL_SCOPES',
662
683
  );
663
684
 
664
- return this.executeUtilityCall(call);
685
+ const call = FunctionCall.from({
686
+ name: artifact.name,
687
+ to: targetContractAddress,
688
+ selector: functionSelector,
689
+ type: FunctionType.UTILITY,
690
+ hideMsgSender: false,
691
+ isStatic: false,
692
+ args,
693
+ returnTypes: [],
694
+ });
695
+
696
+ return this.executeUtilityCall(call, 'ALL_SCOPES');
665
697
  }
666
698
 
667
- private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
699
+ private async executeUtilityCall(call: FunctionCall, scopes: AccessScopes): Promise<Fr[]> {
668
700
  const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
669
701
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
670
702
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
@@ -677,23 +709,23 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
677
709
 
678
710
  try {
679
711
  const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
680
- const oracle = new UtilityExecutionOracle(
681
- call.to,
682
- [],
683
- [],
712
+ const oracle = new UtilityExecutionOracle({
713
+ contractAddress: call.to,
714
+ authWitnesses: [],
715
+ capsules: [],
684
716
  anchorBlockHeader,
685
- this.contractStore,
686
- this.noteStore,
687
- this.keyStore,
688
- this.addressStore,
689
- this.stateMachine.node,
690
- this.stateMachine.anchorBlockStore,
691
- this.recipientTaggingStore,
692
- this.senderAddressBookStore,
693
- this.capsuleStore,
694
- this.privateEventStore,
695
- this.jobId,
696
- );
717
+ contractStore: this.contractStore,
718
+ noteStore: this.noteStore,
719
+ keyStore: this.keyStore,
720
+ addressStore: this.addressStore,
721
+ aztecNode: this.stateMachine.node,
722
+ recipientTaggingStore: this.recipientTaggingStore,
723
+ senderAddressBookStore: this.senderAddressBookStore,
724
+ capsuleStore: this.capsuleStore,
725
+ privateEventStore: this.privateEventStore,
726
+ jobId: this.jobId,
727
+ scopes,
728
+ });
697
729
  const acirExecutionResult = await new WASMSimulator()
698
730
  .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
699
731
  .catch((err: Error) => {