@aztec/pxe 0.0.1-commit.f295ac2 → 0.0.1-commit.fc805bf

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 (183) hide show
  1. package/dest/bin/check_oracle_version.js +1 -1
  2. package/dest/block_synchronizer/block_synchronizer.d.ts +7 -5
  3. package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
  4. package/dest/block_synchronizer/block_synchronizer.js +56 -16
  5. package/dest/config/index.d.ts +3 -1
  6. package/dest/config/index.d.ts.map +1 -1
  7. package/dest/config/index.js +17 -0
  8. package/dest/contract_function_simulator/contract_function_simulator.d.ts +2 -4
  9. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  10. package/dest/contract_function_simulator/contract_function_simulator.js +8 -13
  11. package/dest/contract_function_simulator/index.d.ts +2 -2
  12. package/dest/contract_function_simulator/index.d.ts.map +1 -1
  13. package/dest/contract_function_simulator/index.js +1 -1
  14. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +1 -1
  15. package/dest/contract_function_simulator/noir-structs/event_validation_request.js +1 -1
  16. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +1 -1
  17. package/dest/contract_function_simulator/noir-structs/note_validation_request.js +1 -1
  18. package/dest/contract_function_simulator/oracle/interfaces.d.ts +13 -10
  19. package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
  20. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts +4 -4
  21. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts.map +1 -1
  22. package/dest/contract_function_simulator/oracle/note_packing_utils.js +4 -4
  23. package/dest/contract_function_simulator/oracle/oracle.d.ts +6 -4
  24. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
  25. package/dest/contract_function_simulator/oracle/oracle.js +33 -23
  26. package/dest/contract_function_simulator/oracle/private_execution.d.ts +2 -22
  27. package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -1
  28. package/dest/contract_function_simulator/oracle/private_execution.js +0 -37
  29. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +10 -3
  30. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  31. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +19 -8
  32. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +29 -17
  33. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  34. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +47 -45
  35. package/dest/contract_sync/index.d.ts +23 -0
  36. package/dest/contract_sync/index.d.ts.map +1 -0
  37. package/dest/contract_sync/index.js +54 -0
  38. package/dest/debug/pxe_debug_utils.d.ts +16 -6
  39. package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
  40. package/dest/debug/pxe_debug_utils.js +20 -10
  41. package/dest/entrypoints/client/bundle/utils.d.ts +1 -1
  42. package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
  43. package/dest/entrypoints/client/bundle/utils.js +12 -6
  44. package/dest/entrypoints/client/lazy/utils.d.ts +2 -2
  45. package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
  46. package/dest/entrypoints/client/lazy/utils.js +13 -7
  47. package/dest/entrypoints/pxe_creation_options.d.ts +3 -2
  48. package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
  49. package/dest/entrypoints/server/index.d.ts +2 -1
  50. package/dest/entrypoints/server/index.d.ts.map +1 -1
  51. package/dest/entrypoints/server/index.js +1 -0
  52. package/dest/entrypoints/server/utils.d.ts +1 -1
  53. package/dest/entrypoints/server/utils.d.ts.map +1 -1
  54. package/dest/entrypoints/server/utils.js +19 -8
  55. package/dest/events/event_service.d.ts +5 -6
  56. package/dest/events/event_service.d.ts.map +1 -1
  57. package/dest/events/event_service.js +6 -7
  58. package/dest/job_coordinator/job_coordinator.d.ts +3 -2
  59. package/dest/job_coordinator/job_coordinator.d.ts.map +1 -1
  60. package/dest/job_coordinator/job_coordinator.js +3 -2
  61. package/dest/logs/log_service.d.ts +5 -4
  62. package/dest/logs/log_service.d.ts.map +1 -1
  63. package/dest/logs/log_service.js +18 -15
  64. package/dest/notes/note_service.d.ts +6 -6
  65. package/dest/notes/note_service.d.ts.map +1 -1
  66. package/dest/notes/note_service.js +14 -14
  67. package/dest/oracle_version.d.ts +3 -3
  68. package/dest/oracle_version.d.ts.map +1 -1
  69. package/dest/oracle_version.js +4 -3
  70. package/dest/private_kernel/private_kernel_execution_prover.d.ts +3 -2
  71. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
  72. package/dest/private_kernel/private_kernel_execution_prover.js +2 -2
  73. package/dest/private_kernel/private_kernel_oracle.d.ts +3 -3
  74. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
  75. package/dest/pxe.d.ts +1 -1
  76. package/dest/pxe.d.ts.map +1 -1
  77. package/dest/pxe.js +19 -15
  78. package/dest/storage/address_store/address_store.d.ts +1 -1
  79. package/dest/storage/address_store/address_store.d.ts.map +1 -1
  80. package/dest/storage/address_store/address_store.js +12 -11
  81. package/dest/storage/anchor_block_store/anchor_block_store.d.ts +9 -1
  82. package/dest/storage/anchor_block_store/anchor_block_store.d.ts.map +1 -1
  83. package/dest/storage/anchor_block_store/anchor_block_store.js +8 -1
  84. package/dest/storage/capsule_store/capsule_store.js +6 -8
  85. package/dest/storage/contract_store/contract_store.d.ts +1 -2
  86. package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
  87. package/dest/storage/contract_store/contract_store.js +22 -25
  88. package/dest/storage/metadata.d.ts +1 -1
  89. package/dest/storage/metadata.js +1 -1
  90. package/dest/storage/note_store/note_store.d.ts +48 -50
  91. package/dest/storage/note_store/note_store.d.ts.map +1 -1
  92. package/dest/storage/note_store/note_store.js +276 -252
  93. package/dest/storage/note_store/stored_note.d.ts +16 -0
  94. package/dest/storage/note_store/stored_note.d.ts.map +1 -0
  95. package/dest/storage/note_store/stored_note.js +43 -0
  96. package/dest/storage/private_event_store/private_event_store.d.ts +17 -4
  97. package/dest/storage/private_event_store/private_event_store.d.ts.map +1 -1
  98. package/dest/storage/private_event_store/private_event_store.js +198 -147
  99. package/dest/storage/private_event_store/stored_private_event.d.ts +23 -0
  100. package/dest/storage/private_event_store/stored_private_event.d.ts.map +1 -0
  101. package/dest/storage/private_event_store/stored_private_event.js +56 -0
  102. package/dest/storage/tagging_store/recipient_tagging_store.d.ts +1 -1
  103. package/dest/storage/tagging_store/recipient_tagging_store.d.ts.map +1 -1
  104. package/dest/storage/tagging_store/recipient_tagging_store.js +31 -19
  105. package/dest/storage/tagging_store/sender_address_book_store.d.ts +1 -1
  106. package/dest/storage/tagging_store/sender_address_book_store.d.ts.map +1 -1
  107. package/dest/storage/tagging_store/sender_address_book_store.js +20 -14
  108. package/dest/storage/tagging_store/sender_tagging_store.d.ts +1 -1
  109. package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
  110. package/dest/storage/tagging_store/sender_tagging_store.js +183 -113
  111. package/dest/tagging/get_all_logs_by_tags.d.ts +24 -0
  112. package/dest/tagging/get_all_logs_by_tags.d.ts.map +1 -0
  113. package/dest/tagging/get_all_logs_by_tags.js +46 -0
  114. package/dest/tagging/index.d.ts +2 -1
  115. package/dest/tagging/index.d.ts.map +1 -1
  116. package/dest/tagging/index.js +1 -0
  117. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +3 -2
  118. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +1 -1
  119. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +2 -2
  120. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts +3 -2
  121. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts.map +1 -1
  122. package/dest/tagging/recipient_sync/utils/load_logs_for_range.js +5 -2
  123. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +3 -2
  124. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
  125. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +2 -2
  126. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts +1 -1
  127. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts.map +1 -1
  128. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.js +5 -8
  129. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +3 -2
  130. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -1
  131. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.js +7 -4
  132. package/package.json +16 -16
  133. package/src/bin/check_oracle_version.ts +1 -0
  134. package/src/block_synchronizer/block_synchronizer.ts +70 -33
  135. package/src/config/index.ts +14 -0
  136. package/src/contract_function_simulator/contract_function_simulator.ts +7 -15
  137. package/src/contract_function_simulator/index.ts +1 -1
  138. package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -1
  139. package/src/contract_function_simulator/noir-structs/note_validation_request.ts +1 -1
  140. package/src/contract_function_simulator/oracle/interfaces.ts +18 -9
  141. package/src/contract_function_simulator/oracle/note_packing_utils.ts +4 -4
  142. package/src/contract_function_simulator/oracle/oracle.ts +48 -25
  143. package/src/contract_function_simulator/oracle/private_execution.ts +1 -60
  144. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +32 -10
  145. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +67 -53
  146. package/src/contract_sync/index.ts +98 -0
  147. package/src/debug/pxe_debug_utils.ts +26 -11
  148. package/src/entrypoints/client/bundle/utils.ts +7 -14
  149. package/src/entrypoints/client/lazy/utils.ts +8 -14
  150. package/src/entrypoints/pxe_creation_options.ts +2 -1
  151. package/src/entrypoints/server/index.ts +1 -0
  152. package/src/entrypoints/server/utils.ts +15 -19
  153. package/src/events/event_service.ts +5 -7
  154. package/src/job_coordinator/job_coordinator.ts +4 -3
  155. package/src/logs/log_service.ts +29 -13
  156. package/src/notes/note_service.ts +21 -20
  157. package/src/oracle_version.ts +4 -3
  158. package/src/private_kernel/private_kernel_execution_prover.ts +6 -3
  159. package/src/private_kernel/private_kernel_oracle.ts +2 -2
  160. package/src/pxe.ts +48 -17
  161. package/src/storage/address_store/address_store.ts +15 -15
  162. package/src/storage/anchor_block_store/anchor_block_store.ts +8 -0
  163. package/src/storage/capsule_store/capsule_store.ts +8 -8
  164. package/src/storage/contract_store/contract_store.ts +22 -31
  165. package/src/storage/metadata.ts +1 -1
  166. package/src/storage/note_store/note_store.ts +314 -318
  167. package/src/storage/note_store/stored_note.ts +48 -0
  168. package/src/storage/private_event_store/private_event_store.ts +250 -190
  169. package/src/storage/private_event_store/stored_private_event.ts +73 -0
  170. package/src/storage/tagging_store/recipient_tagging_store.ts +31 -21
  171. package/src/storage/tagging_store/sender_address_book_store.ts +20 -14
  172. package/src/storage/tagging_store/sender_tagging_store.ts +210 -126
  173. package/src/tagging/get_all_logs_by_tags.ts +68 -0
  174. package/src/tagging/index.ts +1 -0
  175. package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +11 -1
  176. package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +7 -1
  177. package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +3 -1
  178. package/src/tagging/sender_sync/utils/get_status_change_of_pending.ts +5 -17
  179. package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +12 -3
  180. package/dest/tree_membership/tree_membership_service.d.ts +0 -50
  181. package/dest/tree_membership/tree_membership_service.d.ts.map +0 -1
  182. package/dest/tree_membership/tree_membership_service.js +0 -75
  183. package/src/tree_membership/tree_membership_service.ts +0 -97
@@ -3,20 +3,19 @@ import type { EventSelector } from '@aztec/stdlib/abi';
3
3
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
4
4
  import { siloNullifier } from '@aztec/stdlib/hash';
5
5
  import type { AztecNode } from '@aztec/stdlib/interfaces/server';
6
- import type { TxHash } from '@aztec/stdlib/tx';
6
+ import type { BlockHeader, TxHash } from '@aztec/stdlib/tx';
7
7
 
8
- import { AnchorBlockStore } from '../storage/anchor_block_store/anchor_block_store.js';
9
8
  import { PrivateEventStore } from '../storage/private_event_store/private_event_store.js';
10
9
 
11
10
  export class EventService {
12
11
  constructor(
13
- private readonly anchorBlockStore: AnchorBlockStore,
12
+ private readonly anchorBlockHeader: BlockHeader,
14
13
  private readonly aztecNode: AztecNode,
15
14
  private readonly privateEventStore: PrivateEventStore,
16
15
  private readonly jobId: string,
17
16
  ) {}
18
17
 
19
- public async storeEvent(
18
+ public async validateAndStoreEvent(
20
19
  contractAddress: AztecAddress,
21
20
  selector: EventSelector,
22
21
  randomness: Fr,
@@ -29,13 +28,12 @@ export class EventService {
29
28
  // (and thus we're less concerned about being ahead of the synced block), we use the synced block number to
30
29
  // maintain consistent behavior in the PXE. Additionally, events should never be ahead of the synced block here
31
30
  // since `fetchTaggedLogs` only processes logs up to the synced block.
32
- const [anchorBlockHeader, siloedEventCommitment, txEffect] = await Promise.all([
33
- this.anchorBlockStore.getBlockHeader(),
31
+ const [siloedEventCommitment, txEffect] = await Promise.all([
34
32
  siloNullifier(contractAddress, eventCommitment),
35
33
  this.aztecNode.getTxEffect(txHash),
36
34
  ]);
37
35
 
38
- const anchorBlockNumber = anchorBlockHeader.getBlockNumber();
36
+ const anchorBlockNumber = this.anchorBlockHeader.getBlockNumber();
39
37
 
40
38
  if (!txEffect) {
41
39
  throw new Error(`Could not find tx effect for tx hash ${txHash}`);
@@ -1,5 +1,5 @@
1
1
  import { randomBytes } from '@aztec/foundation/crypto/random';
2
- import { createLogger } from '@aztec/foundation/log';
2
+ import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
3
3
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
4
4
 
5
5
  /**
@@ -40,7 +40,7 @@ export interface StagedStore {
40
40
  * using a job queue with concurrency=1.
41
41
  */
42
42
  export class JobCoordinator {
43
- private readonly log = createLogger('pxe:job_coordinator');
43
+ private readonly log: Logger;
44
44
 
45
45
  /** The underlying KV store */
46
46
  kvStore: AztecAsyncKVStore;
@@ -48,8 +48,9 @@ export class JobCoordinator {
48
48
  #currentJobId: string | undefined;
49
49
  #stores: Map<string, StagedStore> = new Map();
50
50
 
51
- constructor(kvStore: AztecAsyncKVStore) {
51
+ constructor(kvStore: AztecAsyncKVStore, bindings?: LoggerBindings) {
52
52
  this.kvStore = kvStore;
53
+ this.log = createLogger('pxe:job_coordinator', bindings);
53
54
  }
54
55
 
55
56
  /**
@@ -1,33 +1,40 @@
1
1
  import type { Fr } from '@aztec/foundation/curves/bn254';
2
- import { createLogger } from '@aztec/foundation/log';
2
+ import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
3
3
  import type { KeyStore } from '@aztec/key-store';
4
4
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
5
5
  import type { CompleteAddress } from '@aztec/stdlib/contract';
6
6
  import type { AztecNode } from '@aztec/stdlib/interfaces/server';
7
7
  import { DirectionalAppTaggingSecret, PendingTaggedLog, SiloedTag, Tag, TxScopedL2Log } from '@aztec/stdlib/logs';
8
+ import type { BlockHeader } from '@aztec/stdlib/tx';
8
9
 
9
10
  import type { LogRetrievalRequest } from '../contract_function_simulator/noir-structs/log_retrieval_request.js';
10
11
  import { LogRetrievalResponse } from '../contract_function_simulator/noir-structs/log_retrieval_response.js';
11
12
  import { AddressStore } from '../storage/address_store/address_store.js';
12
- import { AnchorBlockStore } from '../storage/anchor_block_store/anchor_block_store.js';
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 { loadPrivateLogsForSenderRecipientPair } from '../tagging/index.js';
16
+ import {
17
+ getAllPrivateLogsByTags,
18
+ getAllPublicLogsByTagsFromContract,
19
+ loadPrivateLogsForSenderRecipientPair,
20
+ } from '../tagging/index.js';
17
21
 
18
22
  export class LogService {
19
- private log = createLogger('log_service');
23
+ private log: Logger;
20
24
 
21
25
  constructor(
22
26
  private readonly aztecNode: AztecNode,
23
- private readonly anchorBlockStore: AnchorBlockStore,
27
+ private readonly anchorBlockHeader: BlockHeader,
24
28
  private readonly keyStore: KeyStore,
25
29
  private readonly capsuleStore: CapsuleStore,
26
30
  private readonly recipientTaggingStore: RecipientTaggingStore,
27
31
  private readonly senderAddressBookStore: SenderAddressBookStore,
28
32
  private readonly addressStore: AddressStore,
29
33
  private readonly jobId: string,
30
- ) {}
34
+ bindings?: LoggerBindings,
35
+ ) {
36
+ this.log = createLogger('pxe:log_service', bindings);
37
+ }
31
38
 
32
39
  public async bulkRetrieveLogs(logRetrievalRequests: LogRetrievalRequest[]): Promise<(LogRetrievalResponse | null)[]> {
33
40
  return await Promise.all(
@@ -49,10 +56,16 @@ export class LogService {
49
56
  }
50
57
 
51
58
  async #getPublicLogByTag(tag: Tag, contractAddress: AztecAddress): Promise<LogRetrievalResponse | null> {
52
- const logs = await this.aztecNode.getPublicLogsByTagsFromContract(contractAddress, [tag]);
53
- const logsForTag = logs[0];
59
+ const anchorBlockHash = await this.anchorBlockHeader.hash();
60
+ const allLogsPerTag = await getAllPublicLogsByTagsFromContract(
61
+ this.aztecNode,
62
+ contractAddress,
63
+ [tag],
64
+ anchorBlockHash,
65
+ );
66
+ const logsForTag = allLogsPerTag[0];
54
67
 
55
- if (logsForTag.length == 0) {
68
+ if (logsForTag.length === 0) {
56
69
  return null;
57
70
  } else if (logsForTag.length > 1) {
58
71
  // TODO(#11627): handle this case
@@ -72,10 +85,11 @@ export class LogService {
72
85
  }
73
86
 
74
87
  async #getPrivateLogByTag(siloedTag: SiloedTag): Promise<LogRetrievalResponse | null> {
75
- const logs = await this.aztecNode.getPrivateLogsByTags([siloedTag]);
76
- const logsForTag = logs[0];
88
+ const anchorBlockHash = await this.anchorBlockHeader.hash();
89
+ const allLogsPerTag = await getAllPrivateLogsByTags(this.aztecNode, [siloedTag], anchorBlockHash);
90
+ const logsForTag = allLogsPerTag[0];
77
91
 
78
- if (logsForTag.length == 0) {
92
+ if (logsForTag.length === 0) {
79
93
  return null;
80
94
  } else if (logsForTag.length > 1) {
81
95
  // TODO(#11627): handle this case
@@ -102,7 +116,8 @@ export class LogService {
102
116
  this.log.verbose('Searching for tagged logs', { contract: contractAddress });
103
117
 
104
118
  // We only load logs from block up to and including the anchor block number
105
- const anchorBlockNumber = (await this.anchorBlockStore.getBlockHeader()).getBlockNumber();
119
+ const anchorBlockNumber = this.anchorBlockHeader.getBlockNumber();
120
+ const anchorBlockHash = await this.anchorBlockHeader.hash();
106
121
 
107
122
  // Determine recipients: use scopes if provided, otherwise get all accounts
108
123
  const recipients = scopes && scopes.length > 0 ? scopes : await this.keyStore.getAccounts();
@@ -123,6 +138,7 @@ export class LogService {
123
138
  this.aztecNode,
124
139
  this.recipientTaggingStore,
125
140
  anchorBlockNumber,
141
+ anchorBlockHash,
126
142
  this.jobId,
127
143
  ),
128
144
  ),
@@ -1,21 +1,20 @@
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';
5
4
  import { computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
6
5
  import { type AztecNode, MAX_RPC_LEN } from '@aztec/stdlib/interfaces/client';
7
6
  import { Note, NoteDao, NoteStatus } from '@aztec/stdlib/note';
8
7
  import { MerkleTreeId } from '@aztec/stdlib/trees';
9
- import type { TxHash } from '@aztec/stdlib/tx';
8
+ import type { BlockHeader, TxHash } from '@aztec/stdlib/tx';
10
9
 
11
- import type { AnchorBlockStore } from '../storage/anchor_block_store/anchor_block_store.js';
12
10
  import type { NoteStore } from '../storage/note_store/note_store.js';
13
11
 
14
12
  export class NoteService {
15
13
  constructor(
16
14
  private readonly noteStore: NoteStore,
17
15
  private readonly aztecNode: AztecNode,
18
- private readonly anchorBlockStore: AnchorBlockStore,
16
+ private readonly anchorBlockHeader: BlockHeader,
17
+ private readonly jobId: string,
19
18
  ) {}
20
19
 
21
20
  /**
@@ -34,13 +33,16 @@ export class NoteService {
34
33
  status: NoteStatus,
35
34
  scopes?: AztecAddress[],
36
35
  ) {
37
- const noteDaos = await this.noteStore.getNotes({
38
- contractAddress,
39
- owner,
40
- storageSlot,
41
- status,
42
- scopes,
43
- });
36
+ const noteDaos = await this.noteStore.getNotes(
37
+ {
38
+ contractAddress,
39
+ owner,
40
+ storageSlot,
41
+ status,
42
+ scopes,
43
+ },
44
+ this.jobId,
45
+ );
44
46
  return noteDaos.map(
45
47
  ({ contractAddress, owner, storageSlot, randomness, noteNonce, note, noteHash, siloedNullifier }) => ({
46
48
  contractAddress,
@@ -69,9 +71,9 @@ export class NoteService {
69
71
  * @param contractAddress - The contract whose notes should be checked and nullified.
70
72
  */
71
73
  public async syncNoteNullifiers(contractAddress: AztecAddress): Promise<void> {
72
- const anchorBlockHash = L2BlockHash.fromField(await (await this.anchorBlockStore.getBlockHeader()).hash());
74
+ const anchorBlockHash = await this.anchorBlockHeader.hash();
73
75
 
74
- const contractNotes = await this.noteStore.getNotes({ contractAddress });
76
+ const contractNotes = await this.noteStore.getNotes({ contractAddress }, this.jobId);
75
77
 
76
78
  if (contractNotes.length === 0) {
77
79
  return;
@@ -105,10 +107,10 @@ export class NoteService {
105
107
  })
106
108
  .filter(nullifier => nullifier !== undefined) as DataInBlock<Fr>[];
107
109
 
108
- await this.noteStore.applyNullifiers(foundNullifiers);
110
+ await this.noteStore.applyNullifiers(foundNullifiers, this.jobId);
109
111
  }
110
112
 
111
- public async storeNote(
113
+ public async validateAndStoreNote(
112
114
  contractAddress: AztecAddress,
113
115
  owner: AztecAddress,
114
116
  storageSlot: Fr,
@@ -139,9 +141,8 @@ export class NoteService {
139
141
  // number which *should* be recent enough to be available, even for non-archive nodes.
140
142
  // Also note that the note should never be ahead of the synced block here since `fetchTaggedLogs` only processes
141
143
  // logs up to the synced block making this only an additional safety check.
142
- const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
143
- const anchorBlockNumber = anchorBlockHeader.getBlockNumber();
144
- const anchorBlockHash = L2BlockHash.fromField(await anchorBlockHeader.hash());
144
+ const anchorBlockNumber = this.anchorBlockHeader.getBlockNumber();
145
+ const anchorBlockHash = await this.anchorBlockHeader.hash();
145
146
 
146
147
  // By computing siloed and unique note hashes ourselves we prevent contracts from interfering with the note storage
147
148
  // of other contracts, which would constitute a security breach.
@@ -183,12 +184,12 @@ export class NoteService {
183
184
  );
184
185
 
185
186
  // The note was found by `recipient`, so we use that as the scope when storing the note.
186
- await this.noteStore.addNotes([noteDao], recipient);
187
+ await this.noteStore.addNotes([noteDao], recipient, this.jobId);
187
188
 
188
189
  if (nullifierIndex !== undefined) {
189
190
  // We found nullifier index which implies that the note has already been nullified.
190
191
  const { data: _, ...blockHashAndNum } = nullifierIndex;
191
- await this.noteStore.applyNullifiers([{ data: siloedNullifier, ...blockHashAndNum }]);
192
+ await this.noteStore.applyNullifiers([{ data: siloedNullifier, ...blockHashAndNum }], this.jobId);
192
193
  }
193
194
  }
194
195
  }
@@ -4,8 +4,9 @@
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 = 6;
7
+ export const ORACLE_VERSION = 10;
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.
11
- export const ORACLE_INTERFACE_HASH = 'cc2a1f26a3b39ef194d710f94683929f63939d725f10b4fe2c82749a47a74c7b';
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 = 'a3b284ee5abff0509986d6d2fa78a3e6e2ec212325674de78355c5e70b05784c';
@@ -1,6 +1,6 @@
1
1
  import { vkAsFieldsMegaHonk } from '@aztec/foundation/crypto/keys';
2
2
  import { Fr } from '@aztec/foundation/curves/bn254';
3
- import { createLogger } from '@aztec/foundation/log';
3
+ import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
4
4
  import { pushTestData } from '@aztec/foundation/testing';
5
5
  import { Timer } from '@aztec/foundation/timer';
6
6
  import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
@@ -56,13 +56,16 @@ export interface PrivateKernelExecutionProverConfig {
56
56
  * inform state tree updates.
57
57
  */
58
58
  export class PrivateKernelExecutionProver {
59
- private log = createLogger('pxe:private-kernel-execution-prover');
59
+ private log: Logger;
60
60
 
61
61
  constructor(
62
62
  private oracle: PrivateKernelOracle,
63
63
  private proofCreator: PrivateKernelProver,
64
64
  private fakeProofs = false,
65
- ) {}
65
+ bindings?: LoggerBindings,
66
+ ) {
67
+ this.log = createLogger('pxe:private-kernel-execution-prover', bindings);
68
+ }
66
69
 
67
70
  /**
68
71
  * Generate a proof for a given transaction request and execution result.
@@ -7,7 +7,7 @@ import { getVKIndex, getVKSiblingPath } from '@aztec/noir-protocol-circuits-type
7
7
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
8
8
  import type { FunctionSelector } from '@aztec/stdlib/abi';
9
9
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
10
- import { L2BlockHash } from '@aztec/stdlib/block';
10
+ import { BlockHash } from '@aztec/stdlib/block';
11
11
  import {
12
12
  type ContractInstanceWithAddress,
13
13
  computeContractClassIdPreimage,
@@ -30,7 +30,7 @@ export class PrivateKernelOracle {
30
30
  private contractStore: ContractStore,
31
31
  private keyStore: KeyStore,
32
32
  private node: AztecNode,
33
- private blockHash: L2BlockHash,
33
+ private blockHash: BlockHash,
34
34
  ) {}
35
35
 
36
36
  /** Retrieves the preimage of a contract address from the registered contract instances db. */
package/src/pxe.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { PrivateEventFilter } from '@aztec/aztec.js/wallet';
2
2
  import { BlockNumber } from '@aztec/foundation/branded-types';
3
3
  import { Fr } from '@aztec/foundation/curves/bn254';
4
- import { type Logger, createLogger } from '@aztec/foundation/log';
4
+ import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
5
5
  import { SerialQueue } from '@aztec/foundation/queue';
6
6
  import { Timer } from '@aztec/foundation/timer';
7
7
  import { KeyStore } from '@aztec/key-store';
@@ -18,7 +18,6 @@ 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';
22
21
  import {
23
22
  CompleteAddress,
24
23
  type ContractInstanceWithAddress,
@@ -59,8 +58,8 @@ import {
59
58
  ContractFunctionSimulator,
60
59
  generateSimulatedProvingResult,
61
60
  } from './contract_function_simulator/contract_function_simulator.js';
62
- import { readCurrentClassId } from './contract_function_simulator/oracle/private_execution.js';
63
61
  import { ProxiedContractStoreFactory } from './contract_function_simulator/proxied_contract_data_source.js';
62
+ import { ensureContractSynced, readCurrentClassId } from './contract_sync/index.js';
64
63
  import { PXEDebugUtils } from './debug/pxe_debug_utils.js';
65
64
  import { enrichPublicSimulationError, enrichSimulationError } from './error_enriching.js';
66
65
  import { PrivateEventFilterValidator } from './events/private_event_filter_validator.js';
@@ -129,6 +128,10 @@ export class PXE {
129
128
  config: PXEConfig,
130
129
  loggerOrSuffix?: string | Logger,
131
130
  ) {
131
+ // Extract bindings from the logger, or use empty bindings if a string suffix is provided.
132
+ const bindings: LoggerBindings | undefined =
133
+ loggerOrSuffix && typeof loggerOrSuffix !== 'string' ? loggerOrSuffix.getBindings() : undefined;
134
+
132
135
  const log =
133
136
  !loggerOrSuffix || typeof loggerOrSuffix === 'string'
134
137
  ? createLogger(loggerOrSuffix ? `pxe:service:${loggerOrSuffix}` : `pxe:service`)
@@ -138,7 +141,7 @@ export class PXE {
138
141
  const addressStore = new AddressStore(store);
139
142
  const privateEventStore = new PrivateEventStore(store);
140
143
  const contractStore = new ContractStore(store);
141
- const noteStore = await NoteStore.create(store);
144
+ const noteStore = new NoteStore(store);
142
145
  const anchorBlockStore = new AnchorBlockStore(store);
143
146
  const senderTaggingStore = new SenderTaggingStore(store);
144
147
  const senderAddressBookStore = new SenderAddressBookStore(store);
@@ -154,13 +157,19 @@ export class PXE {
154
157
  privateEventStore,
155
158
  tipsStore,
156
159
  config,
157
- loggerOrSuffix,
160
+ bindings,
158
161
  );
159
162
 
160
- const jobCoordinator = new JobCoordinator(store);
161
- jobCoordinator.registerStores([capsuleStore, senderTaggingStore, recipientTaggingStore, privateEventStore]);
163
+ const jobCoordinator = new JobCoordinator(store, bindings);
164
+ jobCoordinator.registerStores([
165
+ capsuleStore,
166
+ senderTaggingStore,
167
+ recipientTaggingStore,
168
+ privateEventStore,
169
+ noteStore,
170
+ ]);
162
171
 
163
- const debugUtils = new PXEDebugUtils(contractStore, noteStore);
172
+ const debugUtils = new PXEDebugUtils(contractStore, noteStore, synchronizer, anchorBlockStore);
164
173
 
165
174
  const jobQueue = new SerialQueue();
166
175
 
@@ -187,7 +196,7 @@ export class PXE {
187
196
  debugUtils,
188
197
  );
189
198
 
190
- debugUtils.setPXE(pxe);
199
+ debugUtils.setPXE(pxe, pxe.#putInJobQueue.bind(pxe));
191
200
 
192
201
  pxe.jobQueue.start();
193
202
 
@@ -208,7 +217,6 @@ export class PXE {
208
217
  this.keyStore,
209
218
  this.addressStore,
210
219
  BenchmarkedNodeFactory.create(this.node),
211
- this.anchorBlockStore,
212
220
  this.senderTaggingStore,
213
221
  this.recipientTaggingStore,
214
222
  this.senderAddressBookStore,
@@ -289,6 +297,15 @@ export class PXE {
289
297
  try {
290
298
  const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
291
299
 
300
+ await ensureContractSynced(
301
+ contractAddress,
302
+ functionSelector,
303
+ privateSyncCall => this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
304
+ this.node,
305
+ this.contractStore,
306
+ anchorBlockHeader,
307
+ );
308
+
292
309
  const result = await contractFunctionSimulator.run(
293
310
  txRequest,
294
311
  contractAddress,
@@ -384,9 +401,14 @@ export class PXE {
384
401
  config: PrivateKernelExecutionProverConfig,
385
402
  ): Promise<PrivateKernelExecutionProofOutput<PrivateKernelTailCircuitPublicInputs>> {
386
403
  const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
387
- const anchorBlockHash = L2BlockHash.fromField(await anchorBlockHeader.hash());
404
+ const anchorBlockHash = await anchorBlockHeader.hash();
388
405
  const kernelOracle = new PrivateKernelOracle(this.contractStore, this.keyStore, this.node, anchorBlockHash);
389
- const kernelTraceProver = new PrivateKernelExecutionProver(kernelOracle, proofCreator, !this.proverEnabled);
406
+ const kernelTraceProver = new PrivateKernelExecutionProver(
407
+ kernelOracle,
408
+ proofCreator,
409
+ !this.proverEnabled,
410
+ this.log.getBindings(),
411
+ );
390
412
  this.log.debug(`Executing kernel trace prover (${JSON.stringify(config)})...`);
391
413
  return await kernelTraceProver.proveWithKernels(txExecutionRequest.toTxRequest(), privateExecutionResult, config);
392
414
  }
@@ -428,7 +450,6 @@ export class PXE {
428
450
  }
429
451
 
430
452
  await this.addressStore.addCompleteAddress(accountCompleteAddress);
431
- await this.noteStore.addScope(accountCompleteAddress.address);
432
453
  return accountCompleteAddress;
433
454
  }
434
455
 
@@ -948,8 +969,14 @@ export class PXE {
948
969
  const functionTimer = new Timer();
949
970
  const contractFunctionSimulator = this.#getSimulatorForTx();
950
971
 
951
- await this.contractStore.syncPrivateState(call.to, call.selector, privateSyncCall =>
952
- this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
972
+ const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
973
+ await ensureContractSynced(
974
+ call.to,
975
+ call.selector,
976
+ privateSyncCall => this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
977
+ this.node,
978
+ this.contractStore,
979
+ anchorBlockHeader,
953
980
  );
954
981
 
955
982
  const executionResult = await this.#simulateUtility(
@@ -1008,15 +1035,19 @@ export class PXE {
1008
1035
  await this.#putInJobQueue(async jobId => {
1009
1036
  await this.blockStateSynchronizer.sync();
1010
1037
 
1011
- anchorBlockNumber = (await this.anchorBlockStore.getBlockHeader()).getBlockNumber();
1038
+ const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
1039
+ anchorBlockNumber = anchorBlockHeader.getBlockNumber();
1012
1040
 
1013
1041
  const contractFunctionSimulator = this.#getSimulatorForTx();
1014
1042
 
1015
- await this.contractStore.syncPrivateState(
1043
+ await ensureContractSynced(
1016
1044
  filter.contractAddress,
1017
1045
  null,
1018
1046
  async privateSyncCall =>
1019
1047
  await this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
1048
+ this.node,
1049
+ this.contractStore,
1050
+ anchorBlockHeader,
1020
1051
  );
1021
1052
  });
1022
1053
 
@@ -43,23 +43,23 @@ export class AddressStore {
43
43
  });
44
44
  }
45
45
 
46
- async #getCompleteAddress(address: AztecAddress): Promise<CompleteAddress | undefined> {
47
- const index = await this.#completeAddressIndex.getAsync(address.toString());
48
- if (index === undefined) {
49
- return undefined;
50
- }
51
-
52
- const value = await this.#completeAddresses.atAsync(index);
53
- return value ? await CompleteAddress.fromBuffer(value) : undefined;
54
- }
55
-
56
46
  getCompleteAddress(account: AztecAddress): Promise<CompleteAddress | undefined> {
57
- return this.#getCompleteAddress(account);
47
+ return this.#store.transactionAsync(async () => {
48
+ const index = await this.#completeAddressIndex.getAsync(account.toString());
49
+ if (index === undefined) {
50
+ return undefined;
51
+ }
52
+
53
+ const value = await this.#completeAddresses.atAsync(index);
54
+ return value ? await CompleteAddress.fromBuffer(value) : undefined;
55
+ });
58
56
  }
59
57
 
60
- async getCompleteAddresses(): Promise<CompleteAddress[]> {
61
- return await Promise.all(
62
- (await toArray(this.#completeAddresses.valuesAsync())).map(v => CompleteAddress.fromBuffer(v)),
63
- );
58
+ getCompleteAddresses(): Promise<CompleteAddress[]> {
59
+ return this.#store.transactionAsync(async () => {
60
+ return await Promise.all(
61
+ (await toArray(this.#completeAddresses.valuesAsync())).map(v => CompleteAddress.fromBuffer(v)),
62
+ );
63
+ });
64
64
  }
65
65
  }
@@ -10,6 +10,14 @@ export class AnchorBlockStore {
10
10
  this.#synchronizedHeader = this.#store.openSingleton('header');
11
11
  }
12
12
 
13
+ /**
14
+ * Sets the currently synchronized block
15
+ *
16
+ * Important: this method is only called from BlockSynchronizer, and since we need it to run atomically with other
17
+ * stores in the case of a reorg, it MUST NOT be wrapped in a `transactionAsync` call. Doing so would result in a
18
+ * deadlock when the backend is IndexedDB, because `transactionAsync` is not designed to support reentrancy.
19
+ *
20
+ */
13
21
  async setHeader(header: BlockHeader): Promise<void> {
14
22
  await this.#synchronizedHeader.set(header.toBuffer());
15
23
  }
@@ -57,14 +57,14 @@ export class CapsuleStore implements StagedStore {
57
57
  */
58
58
  async #getFromStage(jobId: string, dbSlotKey: string): Promise<Buffer | null | undefined> {
59
59
  const jobStagedCapsules = this.#getJobStagedCapsules(jobId);
60
- let staged: Buffer | null | undefined = jobStagedCapsules.get(dbSlotKey);
61
- // Note that if staged === null, we marked it for deletion, so we don't want to
62
- // re-read it from DB
63
- if (staged === undefined) {
64
- // If we don't have a staged version of this dbSlotKey, first we check if there's one in DB
65
- staged = await this.#loadCapsuleFromDb(dbSlotKey);
66
- }
67
- return staged;
60
+ const staged: Buffer | null | undefined = jobStagedCapsules.get(dbSlotKey);
61
+
62
+ // Always issue DB read to keep IndexedDB transaction alive, even if the value is in the job staged data. This
63
+ // keeps IndexedDB transactions alive (they auto-commit when a new micro-task starts and there are no pending read
64
+ // requests). The staged value still takes precedence if it exists (including null for deletions).
65
+ const dbValue = await this.#loadCapsuleFromDb(dbSlotKey);
66
+
67
+ return staged !== undefined ? staged : dbValue;
68
68
  }
69
69
 
70
70
  /**