@aztec/pxe 0.0.1-commit.2ed92850 → 0.0.1-commit.3469e52

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 (124) hide show
  1. package/dest/bin/check_oracle_version.js +1 -1
  2. package/dest/block_synchronizer/block_synchronizer.d.ts +4 -6
  3. package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
  4. package/dest/block_synchronizer/block_synchronizer.js +11 -51
  5. package/dest/config/index.d.ts +1 -3
  6. package/dest/config/index.d.ts.map +1 -1
  7. package/dest/config/index.js +0 -17
  8. package/dest/contract_function_simulator/contract_function_simulator.d.ts +1 -1
  9. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  10. package/dest/contract_function_simulator/contract_function_simulator.js +4 -1
  11. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +1 -1
  12. package/dest/contract_function_simulator/noir-structs/event_validation_request.js +1 -1
  13. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +1 -1
  14. package/dest/contract_function_simulator/noir-structs/note_validation_request.js +1 -1
  15. package/dest/contract_function_simulator/oracle/interfaces.d.ts +5 -8
  16. package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
  17. package/dest/contract_function_simulator/oracle/oracle.d.ts +3 -5
  18. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
  19. package/dest/contract_function_simulator/oracle/oracle.js +11 -21
  20. package/dest/contract_function_simulator/oracle/private_execution.d.ts +22 -2
  21. package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -1
  22. package/dest/contract_function_simulator/oracle/private_execution.js +37 -0
  23. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +1 -9
  24. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  25. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +5 -16
  26. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +7 -15
  27. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  28. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +36 -34
  29. package/dest/debug/pxe_debug_utils.d.ts +1 -1
  30. package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
  31. package/dest/debug/pxe_debug_utils.js +2 -3
  32. package/dest/entrypoints/server/index.d.ts +1 -2
  33. package/dest/entrypoints/server/index.d.ts.map +1 -1
  34. package/dest/entrypoints/server/index.js +0 -1
  35. package/dest/events/event_service.d.ts +2 -2
  36. package/dest/events/event_service.d.ts.map +1 -1
  37. package/dest/events/event_service.js +1 -1
  38. package/dest/logs/log_service.d.ts +1 -1
  39. package/dest/logs/log_service.d.ts.map +1 -1
  40. package/dest/logs/log_service.js +11 -17
  41. package/dest/notes/note_service.d.ts +3 -4
  42. package/dest/notes/note_service.d.ts.map +1 -1
  43. package/dest/notes/note_service.js +10 -11
  44. package/dest/oracle_version.d.ts +3 -3
  45. package/dest/oracle_version.d.ts.map +1 -1
  46. package/dest/oracle_version.js +3 -4
  47. package/dest/pxe.d.ts +1 -1
  48. package/dest/pxe.d.ts.map +1 -1
  49. package/dest/pxe.js +9 -11
  50. package/dest/storage/contract_store/contract_store.d.ts +2 -1
  51. package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
  52. package/dest/storage/contract_store/contract_store.js +12 -0
  53. package/dest/storage/note_store/note_store.d.ts +55 -43
  54. package/dest/storage/note_store/note_store.d.ts.map +1 -1
  55. package/dest/storage/note_store/note_store.js +252 -238
  56. package/dest/storage/private_event_store/private_event_store.d.ts +4 -17
  57. package/dest/storage/private_event_store/private_event_store.d.ts.map +1 -1
  58. package/dest/storage/private_event_store/private_event_store.js +135 -163
  59. package/dest/tagging/index.d.ts +1 -2
  60. package/dest/tagging/index.d.ts.map +1 -1
  61. package/dest/tagging/index.js +0 -1
  62. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +2 -3
  63. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +1 -1
  64. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +2 -2
  65. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts +2 -3
  66. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts.map +1 -1
  67. package/dest/tagging/recipient_sync/utils/load_logs_for_range.js +2 -5
  68. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +2 -3
  69. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
  70. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +2 -2
  71. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts +1 -1
  72. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts.map +1 -1
  73. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.js +8 -5
  74. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +2 -3
  75. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -1
  76. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.js +4 -7
  77. package/dest/tree_membership/tree_membership_service.d.ts +50 -0
  78. package/dest/tree_membership/tree_membership_service.d.ts.map +1 -0
  79. package/dest/tree_membership/tree_membership_service.js +75 -0
  80. package/package.json +16 -16
  81. package/src/bin/check_oracle_version.ts +0 -1
  82. package/src/block_synchronizer/block_synchronizer.ts +14 -53
  83. package/src/config/index.ts +0 -14
  84. package/src/contract_function_simulator/contract_function_simulator.ts +9 -1
  85. package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -1
  86. package/src/contract_function_simulator/noir-structs/note_validation_request.ts +1 -1
  87. package/src/contract_function_simulator/oracle/interfaces.ts +4 -13
  88. package/src/contract_function_simulator/oracle/oracle.ts +15 -28
  89. package/src/contract_function_simulator/oracle/private_execution.ts +60 -1
  90. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +6 -32
  91. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +41 -49
  92. package/src/debug/pxe_debug_utils.ts +2 -3
  93. package/src/entrypoints/server/index.ts +0 -1
  94. package/src/events/event_service.ts +1 -1
  95. package/src/logs/log_service.ts +8 -24
  96. package/src/notes/note_service.ts +15 -18
  97. package/src/oracle_version.ts +3 -4
  98. package/src/pxe.ts +10 -33
  99. package/src/storage/contract_store/contract_store.ts +20 -0
  100. package/src/storage/note_store/note_store.ts +313 -279
  101. package/src/storage/private_event_store/private_event_store.ts +175 -214
  102. package/src/tagging/index.ts +0 -1
  103. package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +1 -11
  104. package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +1 -7
  105. package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +1 -3
  106. package/src/tagging/sender_sync/utils/get_status_change_of_pending.ts +17 -5
  107. package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +3 -12
  108. package/src/tree_membership/tree_membership_service.ts +97 -0
  109. package/dest/contract_sync/index.d.ts +0 -23
  110. package/dest/contract_sync/index.d.ts.map +0 -1
  111. package/dest/contract_sync/index.js +0 -54
  112. package/dest/storage/note_store/stored_note.d.ts +0 -16
  113. package/dest/storage/note_store/stored_note.d.ts.map +0 -1
  114. package/dest/storage/note_store/stored_note.js +0 -43
  115. package/dest/storage/private_event_store/stored_private_event.d.ts +0 -23
  116. package/dest/storage/private_event_store/stored_private_event.d.ts.map +0 -1
  117. package/dest/storage/private_event_store/stored_private_event.js +0 -56
  118. package/dest/tagging/get_all_logs_by_tags.d.ts +0 -24
  119. package/dest/tagging/get_all_logs_by_tags.d.ts.map +0 -1
  120. package/dest/tagging/get_all_logs_by_tags.js +0 -46
  121. package/src/contract_sync/index.ts +0 -98
  122. package/src/storage/note_store/stored_note.ts +0 -48
  123. package/src/storage/private_event_store/stored_private_event.ts +0 -73
  124. package/src/tagging/get_all_logs_by_tags.ts +0 -68
@@ -30,7 +30,6 @@ import {
30
30
  type TxContext,
31
31
  } from '@aztec/stdlib/tx';
32
32
 
33
- import { ensureContractSynced } from '../../contract_sync/index.js';
34
33
  import { NoteService } from '../../notes/note_service.js';
35
34
  import type { AddressStore } from '../../storage/address_store/address_store.js';
36
35
  import type { AnchorBlockStore } from '../../storage/anchor_block_store/anchor_block_store.js';
@@ -47,7 +46,7 @@ import { ExecutionTaggingIndexCache } from '../execution_tagging_index_cache.js'
47
46
  import type { HashedValuesCache } from '../hashed_values_cache.js';
48
47
  import { pickNotes } from '../pick_notes.js';
49
48
  import type { IPrivateExecutionOracle, NoteData } from './interfaces.js';
50
- import { executePrivateFunction } from './private_execution.js';
49
+ import { executePrivateFunction, verifyCurrentClassId } from './private_execution.js';
51
50
  import { UtilityExecutionOracle } from './utility_execution_oracle.js';
52
51
 
53
52
  /**
@@ -266,14 +265,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
266
265
  // This is a tagging secret we've not yet used in this tx, so first sync our store to make sure its indices
267
266
  // are up to date. We do this here because this store is not synced as part of the global sync because
268
267
  // that'd be wasteful as most tagging secrets are not used in each tx.
269
- await syncSenderTaggingIndexes(
270
- secret,
271
- this.contractAddress,
272
- this.aztecNode,
273
- this.senderTaggingStore,
274
- await this.anchorBlockHeader.hash(),
275
- this.jobId,
276
- );
268
+ await syncSenderTaggingIndexes(secret, this.contractAddress, this.aztecNode, this.senderTaggingStore, this.jobId);
277
269
 
278
270
  const lastUsedIndex = await this.senderTaggingStore.getLastUsedIndex(secret, this.jobId);
279
271
  // If lastUsedIndex is undefined, we've never used this secret, so start from 0
@@ -364,7 +356,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
364
356
 
365
357
  const pendingNullifiers = this.noteCache.getNullifiers(this.callContext.contractAddress);
366
358
 
367
- const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockStore, this.jobId);
359
+ const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockStore);
368
360
  const dbNotes = await noteService.getNotes(
369
361
  this.callContext.contractAddress,
370
362
  owner,
@@ -471,19 +463,6 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
471
463
  return this.noteCache.nullifierCreated(this.callContext.contractAddress, innerNullifier);
472
464
  }
473
465
 
474
- /**
475
- * Check if a nullifier has been emitted in the same transaction, i.e. if privateNotifyCreatedNullifier has been
476
- * called for this inner nullifier from the contract with the specified address.
477
- * @param innerNullifier - The inner nullifier to check.
478
- * @param contractAddress - Address of the contract that emitted the nullifier.
479
- * @returns A boolean indicating whether the nullifier is pending or not.
480
- */
481
- public async privateIsNullifierPending(innerNullifier: Fr, contractAddress: AztecAddress): Promise<boolean> {
482
- const siloedNullifier = await siloNullifier(contractAddress, innerNullifier);
483
- const isNullifierPending = this.noteCache.getNullifiers(contractAddress).has(siloedNullifier.toBigInt());
484
- return Promise.resolve(isNullifierPending);
485
- }
486
-
487
466
  /**
488
467
  * Emit a contract class log.
489
468
  * This fn exists because we only carry a poseidon hash through the kernels, and need to
@@ -540,14 +519,9 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
540
519
 
541
520
  isStaticCall = isStaticCall || this.callContext.isStaticCall;
542
521
 
543
- await ensureContractSynced(
544
- targetContractAddress,
545
- functionSelector,
546
- this.utilityExecutor,
547
- this.aztecNode,
548
- this.contractStore,
549
- this.anchorBlockHeader,
550
- );
522
+ await verifyCurrentClassId(targetContractAddress, this.aztecNode, this.contractStore, this.anchorBlockHeader);
523
+
524
+ await this.contractStore.syncPrivateState(targetContractAddress, functionSelector, this.utilityExecutor);
551
525
 
552
526
  const targetArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(
553
527
  targetContractAddress,
@@ -1,10 +1,8 @@
1
- import type { ARCHIVE_HEIGHT, NOTE_HASH_TREE_HEIGHT } from '@aztec/constants';
2
1
  import type { BlockNumber } from '@aztec/foundation/branded-types';
3
2
  import { Aes128 } from '@aztec/foundation/crypto/aes128';
4
3
  import { Fr } from '@aztec/foundation/curves/bn254';
5
4
  import { Point } from '@aztec/foundation/curves/grumpkin';
6
5
  import { LogLevels, applyStringFormatting, createLogger } from '@aztec/foundation/log';
7
- import type { MembershipWitness } from '@aztec/foundation/trees';
8
6
  import type { KeyStore } from '@aztec/key-store';
9
7
  import type { AuthWitness } from '@aztec/stdlib/auth-witness';
10
8
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -15,7 +13,6 @@ import type { AztecNode } from '@aztec/stdlib/interfaces/server';
15
13
  import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
16
14
  import { computeAddressSecret } from '@aztec/stdlib/keys';
17
15
  import { deriveEcdhSharedSecret } from '@aztec/stdlib/logs';
18
- import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
19
16
  import type { NoteStatus } from '@aztec/stdlib/note';
20
17
  import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
21
18
  import type { BlockHeader, Capsule } from '@aztec/stdlib/tx';
@@ -32,6 +29,7 @@ import type { NoteStore } from '../../storage/note_store/note_store.js';
32
29
  import type { PrivateEventStore } from '../../storage/private_event_store/private_event_store.js';
33
30
  import type { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js';
34
31
  import type { SenderAddressBookStore } from '../../storage/tagging_store/sender_address_book_store.js';
32
+ import { TreeMembershipService } from '../../tree_membership/tree_membership_service.js';
35
33
  import { EventValidationRequest } from '../noir-structs/event_validation_request.js';
36
34
  import { LogRetrievalRequest } from '../noir-structs/log_retrieval_request.js';
37
35
  import { LogRetrievalResponse } from '../noir-structs/log_retrieval_response.js';
@@ -96,29 +94,15 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
96
94
  }
97
95
 
98
96
  /**
99
- * Fetches the index and sibling path of a leaf at a given block from the note hash tree.
97
+ * Fetches the index and sibling path of a leaf at a given block from a given tree.
100
98
  * @param blockHash - The block hash at which to get the membership witness.
99
+ * @param treeId - Id of the tree to get the sibling path from.
101
100
  * @param leafValue - The leaf value
102
- * @returns The membership witness containing the leaf index and sibling path
101
+ * @returns The index and sibling path concatenated [index, sibling_path]
103
102
  */
104
- public utilityGetNoteHashMembershipWitness(
105
- blockHash: L2BlockHash,
106
- leafValue: Fr,
107
- ): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
108
- return this.aztecNode.getNoteHashMembershipWitness(blockHash, leafValue);
109
- }
110
-
111
- /**
112
- * Fetches the index and sibling path of a leaf at a given block from the archive tree.
113
- * @param blockHash - The block hash at which to get the membership witness.
114
- * @param leafValue - The leaf value
115
- * @returns The membership witness containing the leaf index and sibling path
116
- */
117
- public utilityGetArchiveMembershipWitness(
118
- blockHash: L2BlockHash,
119
- leafValue: Fr,
120
- ): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
121
- return this.aztecNode.getArchiveMembershipWitness(blockHash, leafValue);
103
+ public utilityGetMembershipWitness(blockHash: L2BlockHash, treeId: MerkleTreeId, leafValue: Fr): Promise<Fr[]> {
104
+ const treeMembershipService = new TreeMembershipService(this.aztecNode);
105
+ return treeMembershipService.getMembershipWitness(blockHash, treeId, leafValue);
122
106
  }
123
107
 
124
108
  /**
@@ -127,11 +111,11 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
127
111
  * @param nullifier - Nullifier we try to find witness for.
128
112
  * @returns The nullifier membership witness (if found).
129
113
  */
130
- public utilityGetNullifierMembershipWitness(
114
+ public async utilityGetNullifierMembershipWitness(
131
115
  blockHash: L2BlockHash,
132
116
  nullifier: Fr,
133
117
  ): Promise<NullifierMembershipWitness | undefined> {
134
- return this.aztecNode.getNullifierMembershipWitness(blockHash, nullifier);
118
+ return await this.aztecNode.getNullifierMembershipWitness(blockHash, nullifier);
135
119
  }
136
120
 
137
121
  /**
@@ -143,11 +127,12 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
143
127
  * list structure" of leaves and proving that a lower nullifier is pointing to a bigger next value than the nullifier
144
128
  * we are trying to prove non-inclusion for.
145
129
  */
146
- public utilityGetLowNullifierMembershipWitness(
130
+ public async utilityGetLowNullifierMembershipWitness(
147
131
  blockHash: L2BlockHash,
148
132
  nullifier: Fr,
149
133
  ): Promise<NullifierMembershipWitness | undefined> {
150
- return this.aztecNode.getLowNullifierMembershipWitness(blockHash, nullifier);
134
+ const treeMembershipService = new TreeMembershipService(this.aztecNode);
135
+ return await treeMembershipService.getLowNullifierMembershipWitness(blockHash, nullifier);
151
136
  }
152
137
 
153
138
  /**
@@ -156,8 +141,12 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
156
141
  * @param leafSlot - The slot of the public data tree to get the witness for.
157
142
  * @returns - The witness
158
143
  */
159
- public utilityGetPublicDataWitness(blockHash: L2BlockHash, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
160
- return this.aztecNode.getPublicDataWitness(blockHash, leafSlot);
144
+ public async utilityGetPublicDataWitness(
145
+ blockHash: L2BlockHash,
146
+ leafSlot: Fr,
147
+ ): Promise<PublicDataWitness | undefined> {
148
+ const treeMembershipService = new TreeMembershipService(this.aztecNode);
149
+ return await treeMembershipService.getPublicDataWitness(blockHash, leafSlot);
161
150
  }
162
151
 
163
152
  /**
@@ -262,7 +251,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
262
251
  offset: number,
263
252
  status: NoteStatus,
264
253
  ): Promise<NoteData[]> {
265
- const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockStore, this.jobId);
254
+ const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockStore);
266
255
 
267
256
  const dbNotes = await noteService.getNotes(this.contractAddress, owner, storageSlot, status, this.scopes);
268
257
  return pickNotes<NoteData>(dbNotes, {
@@ -287,8 +276,9 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
287
276
  */
288
277
  public async utilityCheckNullifierExists(innerNullifier: Fr) {
289
278
  const nullifier = await siloNullifier(this.contractAddress, innerNullifier!);
290
- const [leafIndex] = await this.aztecNode.findLeavesIndexes('latest', MerkleTreeId.NULLIFIER_TREE, [nullifier]);
291
- return leafIndex?.data !== undefined;
279
+ const treeMembershipService = new TreeMembershipService(this.aztecNode);
280
+ const index = await treeMembershipService.getNullifierIndex(nullifier);
281
+ return index !== undefined;
292
282
  }
293
283
 
294
284
  /**
@@ -300,13 +290,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
300
290
  * @returns The l1 to l2 membership witness (index of message in the tree and sibling path).
301
291
  */
302
292
  public async utilityGetL1ToL2MembershipWitness(contractAddress: AztecAddress, messageHash: Fr, secret: Fr) {
303
- const [messageIndex, siblingPath] = await getNonNullifiedL1ToL2MessageWitness(
304
- this.aztecNode,
293
+ const treeMembershipService = new TreeMembershipService(this.aztecNode);
294
+ const [messageIndex, siblingPath] = await treeMembershipService.getL1ToL2MembershipWitness(
305
295
  contractAddress,
306
296
  messageHash,
307
297
  secret,
308
298
  );
309
299
 
300
+ // Assuming messageIndex is what you intended to use for the index in MessageLoadOracleInputs
310
301
  return new MessageLoadOracleInputs(messageIndex, siblingPath);
311
302
  }
312
303
 
@@ -323,18 +314,19 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
323
314
  startStorageSlot: Fr,
324
315
  numberOfElements: number,
325
316
  ) {
326
- const slots = Array(numberOfElements)
327
- .fill(0)
328
- .map((_, i) => new Fr(startStorageSlot.value + BigInt(i)));
317
+ const values = [];
329
318
 
330
- const values = await Promise.all(
331
- slots.map(storageSlot => this.aztecNode.getPublicStorageAt(blockHash, contractAddress, storageSlot)),
332
- );
333
-
334
- this.log.debug(
335
- `Oracle storage read: slots=[${slots.map(slot => slot.toString()).join(', ')}] address=${contractAddress.toString()} values=[${values.join(', ')}]`,
336
- );
319
+ // TODO: why do we serialize these requests? This should probably a single call
320
+ // Privacy considerations?
321
+ for (let i = 0n; i < numberOfElements; i++) {
322
+ const storageSlot = new Fr(startStorageSlot.value + i);
323
+ const value = await this.aztecNode.getPublicStorageAt(blockHash, contractAddress, storageSlot);
337
324
 
325
+ this.log.debug(
326
+ `Oracle storage read: slot=${storageSlot.toString()} address-${contractAddress.toString()} value=${value}`,
327
+ );
328
+ values.push(value);
329
+ }
338
330
  return values;
339
331
  }
340
332
 
@@ -358,7 +350,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
358
350
  this.jobId,
359
351
  );
360
352
 
361
- const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockStore, this.jobId);
353
+ const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockStore);
362
354
 
363
355
  // It is acceptable to run the following operations in parallel for several reasons:
364
356
  // 1. syncTaggedLogs does not write to the note store — it only stores the pending tagged logs in a capsule array,
@@ -380,7 +372,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
380
372
  * @param noteValidationRequestsArrayBaseSlot - The base slot of capsule array containing note validation requests.
381
373
  * @param eventValidationRequestsArrayBaseSlot - The base slot of capsule array containing event validation requests.
382
374
  */
383
- public async utilityValidateAndStoreEnqueuedNotesAndEvents(
375
+ public async utilityValidateEnqueuedNotesAndEvents(
384
376
  contractAddress: AztecAddress,
385
377
  noteValidationRequestsArrayBaseSlot: Fr,
386
378
  eventValidationRequestsArrayBaseSlot: Fr,
@@ -400,9 +392,9 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
400
392
  await this.capsuleStore.readCapsuleArray(contractAddress, eventValidationRequestsArrayBaseSlot, this.jobId)
401
393
  ).map(EventValidationRequest.fromFields);
402
394
 
403
- const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockStore, this.jobId);
395
+ const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockStore);
404
396
  const noteStorePromises = noteValidationRequests.map(request =>
405
- noteService.validateAndStoreNote(
397
+ noteService.storeNote(
406
398
  request.contractAddress,
407
399
  request.owner,
408
400
  request.storageSlot,
@@ -418,7 +410,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
418
410
 
419
411
  const eventService = new EventService(this.anchorBlockStore, this.aztecNode, this.privateEventStore, this.jobId);
420
412
  const eventStorePromises = eventValidationRequests.map(request =>
421
- eventService.validateAndStoreEvent(
413
+ eventService.storeEvent(
422
414
  request.contractAddress,
423
415
  request.eventTypeId,
424
416
  request.randomness,
@@ -1,4 +1,3 @@
1
- import { randomBytes } from '@aztec/foundation/crypto/random';
2
1
  import type { NoteDao, NotesFilter } from '@aztec/stdlib/note';
3
2
 
4
3
  import type { PXE } from '../pxe.js';
@@ -41,9 +40,9 @@ export class PXEDebugUtils {
41
40
  }
42
41
 
43
42
  // We need to manually trigger private state sync to have a guarantee that all the notes are available.
44
- const call = await this.contractStore.getFunctionCall('sync_state', [], filter.contractAddress);
43
+ const call = await this.contractStore.getFunctionCall('sync_private_state', [], filter.contractAddress);
45
44
  await this.#pxe.simulateUtility(call);
46
45
 
47
- return this.noteStore.getNotes(filter, randomBytes(8).toString('hex'));
46
+ return this.noteStore.getNotes(filter);
48
47
  }
49
48
  }
@@ -7,4 +7,3 @@ export { NoteService } from '../../notes/note_service.js';
7
7
  export { ORACLE_VERSION } from '../../oracle_version.js';
8
8
  export { type PXECreationOptions } from '../pxe_creation_options.js';
9
9
  export { JobCoordinator } from '../../job_coordinator/job_coordinator.js';
10
- export { syncState } from '../../contract_sync/index.js';
@@ -16,7 +16,7 @@ export class EventService {
16
16
  private readonly jobId: string,
17
17
  ) {}
18
18
 
19
- public async validateAndStoreEvent(
19
+ public async storeEvent(
20
20
  contractAddress: AztecAddress,
21
21
  selector: EventSelector,
22
22
  randomness: Fr,
@@ -13,11 +13,7 @@ import { AnchorBlockStore } from '../storage/anchor_block_store/anchor_block_sto
13
13
  import { CapsuleStore } from '../storage/capsule_store/capsule_store.js';
14
14
  import type { RecipientTaggingStore } from '../storage/tagging_store/recipient_tagging_store.js';
15
15
  import type { SenderAddressBookStore } from '../storage/tagging_store/sender_address_book_store.js';
16
- import {
17
- getAllPrivateLogsByTags,
18
- getAllPublicLogsByTagsFromContract,
19
- loadPrivateLogsForSenderRecipientPair,
20
- } from '../tagging/index.js';
16
+ import { loadPrivateLogsForSenderRecipientPair } from '../tagging/index.js';
21
17
 
22
18
  export class LogService {
23
19
  private log = createLogger('log_service');
@@ -53,17 +49,10 @@ export class LogService {
53
49
  }
54
50
 
55
51
  async #getPublicLogByTag(tag: Tag, contractAddress: AztecAddress): Promise<LogRetrievalResponse | null> {
56
- const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
57
- const anchorBlockHash = await anchorBlockHeader.hash();
58
- const allLogsPerTag = await getAllPublicLogsByTagsFromContract(
59
- this.aztecNode,
60
- contractAddress,
61
- [tag],
62
- anchorBlockHash,
63
- );
64
- const logsForTag = allLogsPerTag[0];
52
+ const logs = await this.aztecNode.getPublicLogsByTagsFromContract(contractAddress, [tag]);
53
+ const logsForTag = logs[0];
65
54
 
66
- if (logsForTag.length === 0) {
55
+ if (logsForTag.length == 0) {
67
56
  return null;
68
57
  } else if (logsForTag.length > 1) {
69
58
  // TODO(#11627): handle this case
@@ -83,12 +72,10 @@ export class LogService {
83
72
  }
84
73
 
85
74
  async #getPrivateLogByTag(siloedTag: SiloedTag): Promise<LogRetrievalResponse | null> {
86
- const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
87
- const anchorBlockHash = await anchorBlockHeader.hash();
88
- const allLogsPerTag = await getAllPrivateLogsByTags(this.aztecNode, [siloedTag], anchorBlockHash);
89
- const logsForTag = allLogsPerTag[0];
75
+ const logs = await this.aztecNode.getPrivateLogsByTags([siloedTag]);
76
+ const logsForTag = logs[0];
90
77
 
91
- if (logsForTag.length === 0) {
78
+ if (logsForTag.length == 0) {
92
79
  return null;
93
80
  } else if (logsForTag.length > 1) {
94
81
  // TODO(#11627): handle this case
@@ -115,9 +102,7 @@ export class LogService {
115
102
  this.log.verbose('Searching for tagged logs', { contract: contractAddress });
116
103
 
117
104
  // We only load logs from block up to and including the anchor block number
118
- const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
119
- const anchorBlockNumber = anchorBlockHeader.getBlockNumber();
120
- const anchorBlockHash = await anchorBlockHeader.hash();
105
+ const anchorBlockNumber = (await this.anchorBlockStore.getBlockHeader()).getBlockNumber();
121
106
 
122
107
  // Determine recipients: use scopes if provided, otherwise get all accounts
123
108
  const recipients = scopes && scopes.length > 0 ? scopes : await this.keyStore.getAccounts();
@@ -138,7 +123,6 @@ export class LogService {
138
123
  this.aztecNode,
139
124
  this.recipientTaggingStore,
140
125
  anchorBlockNumber,
141
- anchorBlockHash,
142
126
  this.jobId,
143
127
  ),
144
128
  ),
@@ -1,6 +1,7 @@
1
1
  import { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
3
3
  import type { DataInBlock } from '@aztec/stdlib/block';
4
+ import { L2BlockHash } from '@aztec/stdlib/block';
4
5
  import { computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
5
6
  import { type AztecNode, MAX_RPC_LEN } from '@aztec/stdlib/interfaces/client';
6
7
  import { Note, NoteDao, NoteStatus } from '@aztec/stdlib/note';
@@ -15,7 +16,6 @@ export class NoteService {
15
16
  private readonly noteStore: NoteStore,
16
17
  private readonly aztecNode: AztecNode,
17
18
  private readonly anchorBlockStore: AnchorBlockStore,
18
- private readonly jobId: string,
19
19
  ) {}
20
20
 
21
21
  /**
@@ -34,16 +34,13 @@ export class NoteService {
34
34
  status: NoteStatus,
35
35
  scopes?: AztecAddress[],
36
36
  ) {
37
- const noteDaos = await this.noteStore.getNotes(
38
- {
39
- contractAddress,
40
- owner,
41
- storageSlot,
42
- status,
43
- scopes,
44
- },
45
- this.jobId,
46
- );
37
+ const noteDaos = await this.noteStore.getNotes({
38
+ contractAddress,
39
+ owner,
40
+ storageSlot,
41
+ status,
42
+ scopes,
43
+ });
47
44
  return noteDaos.map(
48
45
  ({ contractAddress, owner, storageSlot, randomness, noteNonce, note, noteHash, siloedNullifier }) => ({
49
46
  contractAddress,
@@ -72,9 +69,9 @@ export class NoteService {
72
69
  * @param contractAddress - The contract whose notes should be checked and nullified.
73
70
  */
74
71
  public async syncNoteNullifiers(contractAddress: AztecAddress): Promise<void> {
75
- const anchorBlockHash = await (await this.anchorBlockStore.getBlockHeader()).hash();
72
+ const anchorBlockHash = L2BlockHash.fromField(await (await this.anchorBlockStore.getBlockHeader()).hash());
76
73
 
77
- const contractNotes = await this.noteStore.getNotes({ contractAddress }, this.jobId);
74
+ const contractNotes = await this.noteStore.getNotes({ contractAddress });
78
75
 
79
76
  if (contractNotes.length === 0) {
80
77
  return;
@@ -108,10 +105,10 @@ export class NoteService {
108
105
  })
109
106
  .filter(nullifier => nullifier !== undefined) as DataInBlock<Fr>[];
110
107
 
111
- await this.noteStore.applyNullifiers(foundNullifiers, this.jobId);
108
+ await this.noteStore.applyNullifiers(foundNullifiers);
112
109
  }
113
110
 
114
- public async validateAndStoreNote(
111
+ public async storeNote(
115
112
  contractAddress: AztecAddress,
116
113
  owner: AztecAddress,
117
114
  storageSlot: Fr,
@@ -144,7 +141,7 @@ export class NoteService {
144
141
  // logs up to the synced block making this only an additional safety check.
145
142
  const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
146
143
  const anchorBlockNumber = anchorBlockHeader.getBlockNumber();
147
- const anchorBlockHash = await anchorBlockHeader.hash();
144
+ const anchorBlockHash = L2BlockHash.fromField(await anchorBlockHeader.hash());
148
145
 
149
146
  // By computing siloed and unique note hashes ourselves we prevent contracts from interfering with the note storage
150
147
  // of other contracts, which would constitute a security breach.
@@ -186,12 +183,12 @@ export class NoteService {
186
183
  );
187
184
 
188
185
  // The note was found by `recipient`, so we use that as the scope when storing the note.
189
- await this.noteStore.addNotes([noteDao], recipient, this.jobId);
186
+ await this.noteStore.addNotes([noteDao], recipient);
190
187
 
191
188
  if (nullifierIndex !== undefined) {
192
189
  // We found nullifier index which implies that the note has already been nullified.
193
190
  const { data: _, ...blockHashAndNum } = nullifierIndex;
194
- await this.noteStore.applyNullifiers([{ data: siloedNullifier, ...blockHashAndNum }], this.jobId);
191
+ await this.noteStore.applyNullifiers([{ data: siloedNullifier, ...blockHashAndNum }]);
195
192
  }
196
193
  }
197
194
  }
@@ -4,9 +4,8 @@
4
4
  ///
5
5
  /// @dev Whenever a contract function or Noir test is run, the `utilityAssertCompatibleOracleVersion` oracle is called
6
6
  /// and if the oracle version is incompatible an error is thrown.
7
- export const ORACLE_VERSION = 9;
7
+ export const ORACLE_VERSION = 6;
8
8
 
9
9
  /// This hash is computed as by hashing the Oracle interface and it is used to detect when the Oracle interface changes,
10
- /// which in turn implies that you need to update the ORACLE_VERSION constant in this file and in
11
- /// `noir-projects/aztec-nr/aztec/src/oracle/version.nr`.
12
- export const ORACLE_INTERFACE_HASH = '9866cc52510acaef75a3d47a0ed501fd9ff92b9d53b2c8a88c8a3ffd04ced81f';
10
+ /// which in turn implies that you need to update the ORACLE_VERSION constant.
11
+ export const ORACLE_INTERFACE_HASH = '8fb18d1fa560c4844b22c55a3e79c32ffcb71ded9ac409911470ee0296a84d72';
package/src/pxe.ts CHANGED
@@ -18,6 +18,7 @@ import {
18
18
  } from '@aztec/stdlib/abi';
19
19
  import type { AuthWitness } from '@aztec/stdlib/auth-witness';
20
20
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
21
+ import { L2BlockHash } from '@aztec/stdlib/block';
21
22
  import {
22
23
  CompleteAddress,
23
24
  type ContractInstanceWithAddress,
@@ -58,8 +59,8 @@ import {
58
59
  ContractFunctionSimulator,
59
60
  generateSimulatedProvingResult,
60
61
  } from './contract_function_simulator/contract_function_simulator.js';
62
+ import { readCurrentClassId } from './contract_function_simulator/oracle/private_execution.js';
61
63
  import { ProxiedContractStoreFactory } from './contract_function_simulator/proxied_contract_data_source.js';
62
- import { ensureContractSynced, readCurrentClassId } from './contract_sync/index.js';
63
64
  import { PXEDebugUtils } from './debug/pxe_debug_utils.js';
64
65
  import { enrichPublicSimulationError, enrichSimulationError } from './error_enriching.js';
65
66
  import { PrivateEventFilterValidator } from './events/private_event_filter_validator.js';
@@ -137,7 +138,7 @@ export class PXE {
137
138
  const addressStore = new AddressStore(store);
138
139
  const privateEventStore = new PrivateEventStore(store);
139
140
  const contractStore = new ContractStore(store);
140
- const noteStore = new NoteStore(store);
141
+ const noteStore = await NoteStore.create(store);
141
142
  const anchorBlockStore = new AnchorBlockStore(store);
142
143
  const senderTaggingStore = new SenderTaggingStore(store);
143
144
  const senderAddressBookStore = new SenderAddressBookStore(store);
@@ -157,13 +158,7 @@ export class PXE {
157
158
  );
158
159
 
159
160
  const jobCoordinator = new JobCoordinator(store);
160
- jobCoordinator.registerStores([
161
- capsuleStore,
162
- senderTaggingStore,
163
- recipientTaggingStore,
164
- privateEventStore,
165
- noteStore,
166
- ]);
161
+ jobCoordinator.registerStores([capsuleStore, senderTaggingStore, recipientTaggingStore, privateEventStore]);
167
162
 
168
163
  const debugUtils = new PXEDebugUtils(contractStore, noteStore);
169
164
 
@@ -294,15 +289,6 @@ export class PXE {
294
289
  try {
295
290
  const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
296
291
 
297
- await ensureContractSynced(
298
- contractAddress,
299
- functionSelector,
300
- privateSyncCall => this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
301
- this.node,
302
- this.contractStore,
303
- anchorBlockHeader,
304
- );
305
-
306
292
  const result = await contractFunctionSimulator.run(
307
293
  txRequest,
308
294
  contractAddress,
@@ -398,7 +384,7 @@ export class PXE {
398
384
  config: PrivateKernelExecutionProverConfig,
399
385
  ): Promise<PrivateKernelExecutionProofOutput<PrivateKernelTailCircuitPublicInputs>> {
400
386
  const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
401
- const anchorBlockHash = await anchorBlockHeader.hash();
387
+ const anchorBlockHash = L2BlockHash.fromField(await anchorBlockHeader.hash());
402
388
  const kernelOracle = new PrivateKernelOracle(this.contractStore, this.keyStore, this.node, anchorBlockHash);
403
389
  const kernelTraceProver = new PrivateKernelExecutionProver(kernelOracle, proofCreator, !this.proverEnabled);
404
390
  this.log.debug(`Executing kernel trace prover (${JSON.stringify(config)})...`);
@@ -442,6 +428,7 @@ export class PXE {
442
428
  }
443
429
 
444
430
  await this.addressStore.addCompleteAddress(accountCompleteAddress);
431
+ await this.noteStore.addScope(accountCompleteAddress.address);
445
432
  return accountCompleteAddress;
446
433
  }
447
434
 
@@ -961,14 +948,8 @@ export class PXE {
961
948
  const functionTimer = new Timer();
962
949
  const contractFunctionSimulator = this.#getSimulatorForTx();
963
950
 
964
- const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
965
- await ensureContractSynced(
966
- call.to,
967
- call.selector,
968
- privateSyncCall => this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
969
- this.node,
970
- this.contractStore,
971
- anchorBlockHeader,
951
+ await this.contractStore.syncPrivateState(call.to, call.selector, privateSyncCall =>
952
+ this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
972
953
  );
973
954
 
974
955
  const executionResult = await this.#simulateUtility(
@@ -1027,19 +1008,15 @@ export class PXE {
1027
1008
  await this.#putInJobQueue(async jobId => {
1028
1009
  await this.blockStateSynchronizer.sync();
1029
1010
 
1030
- const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
1031
- anchorBlockNumber = anchorBlockHeader.getBlockNumber();
1011
+ anchorBlockNumber = (await this.anchorBlockStore.getBlockHeader()).getBlockNumber();
1032
1012
 
1033
1013
  const contractFunctionSimulator = this.#getSimulatorForTx();
1034
1014
 
1035
- await ensureContractSynced(
1015
+ await this.contractStore.syncPrivateState(
1036
1016
  filter.contractAddress,
1037
1017
  null,
1038
1018
  async privateSyncCall =>
1039
1019
  await this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
1040
- this.node,
1041
- this.contractStore,
1042
- anchorBlockHeader,
1043
1020
  );
1044
1021
  });
1045
1022
 
@@ -3,6 +3,7 @@ import type { Fr } from '@aztec/foundation/curves/bn254';
3
3
  import { toArray } from '@aztec/foundation/iterable';
4
4
  import type { MembershipWitness } from '@aztec/foundation/trees';
5
5
  import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
6
+ import { isProtocolContract } from '@aztec/protocol-contracts';
6
7
  import {
7
8
  type ContractArtifact,
8
9
  type FunctionAbi,
@@ -316,4 +317,23 @@ export class ContractStore {
316
317
  returnTypes: functionDao.returnTypes,
317
318
  };
318
319
  }
320
+
321
+ // Synchronize target contract data
322
+ public async syncPrivateState(
323
+ contractAddress: AztecAddress,
324
+ functionToInvokeAfterSync: FunctionSelector | null,
325
+ utilityExecutor: (privateSyncCall: FunctionCall) => Promise<any>,
326
+ ) {
327
+ // Protocol contracts don't have private state to sync
328
+ if (!isProtocolContract(contractAddress)) {
329
+ const syncPrivateStateFunctionCall = await this.getFunctionCall('sync_private_state', [], contractAddress);
330
+ if (functionToInvokeAfterSync && functionToInvokeAfterSync.equals(syncPrivateStateFunctionCall.selector)) {
331
+ throw new Error(
332
+ 'Forbidden `sync_private_state` invocation. `sync_private_state` can only be invoked by PXE, manual execution can lead to inconsistencies.',
333
+ );
334
+ }
335
+
336
+ return utilityExecutor(syncPrivateStateFunctionCall);
337
+ }
338
+ }
319
339
  }