@aztec/pxe 0.77.0 → 0.78.0

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 (180) hide show
  1. package/dest/bin/index.js +1 -1
  2. package/dest/config/index.d.ts +1 -0
  3. package/dest/config/index.d.ts.map +1 -1
  4. package/dest/config/index.js +1 -0
  5. package/dest/entrypoints/client/bundle/index.d.ts +6 -0
  6. package/dest/entrypoints/client/bundle/index.d.ts.map +1 -0
  7. package/dest/entrypoints/client/bundle/index.js +5 -0
  8. package/dest/entrypoints/client/bundle/utils.d.ts +16 -0
  9. package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -0
  10. package/dest/entrypoints/client/bundle/utils.js +30 -0
  11. package/dest/entrypoints/client/lazy/index.d.ts +6 -0
  12. package/dest/entrypoints/client/lazy/index.d.ts.map +1 -0
  13. package/dest/entrypoints/client/lazy/index.js +5 -0
  14. package/dest/entrypoints/client/lazy/utils.d.ts +15 -0
  15. package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -0
  16. package/dest/entrypoints/client/lazy/utils.js +29 -0
  17. package/dest/entrypoints/client/pxe_creation_options.d.ts +11 -0
  18. package/dest/entrypoints/client/pxe_creation_options.d.ts.map +1 -0
  19. package/dest/entrypoints/server/index.d.ts +7 -0
  20. package/dest/entrypoints/server/index.d.ts.map +1 -0
  21. package/dest/entrypoints/server/index.js +6 -0
  22. package/dest/{utils/create_pxe_service.d.ts → entrypoints/server/utils.d.ts} +4 -4
  23. package/dest/entrypoints/server/utils.d.ts.map +1 -0
  24. package/dest/{utils/create_pxe_service.js → entrypoints/server/utils.js} +5 -11
  25. package/dest/kernel_oracle/index.d.ts +2 -1
  26. package/dest/kernel_oracle/index.d.ts.map +1 -1
  27. package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
  28. package/dest/kernel_prover/kernel_prover.js +0 -24
  29. package/dest/note_decryption_utils/add_public_values_to_payload.d.ts +2 -2
  30. package/dest/note_decryption_utils/add_public_values_to_payload.d.ts.map +1 -1
  31. package/dest/note_decryption_utils/add_public_values_to_payload.js +3 -3
  32. package/dest/{pxe_data_provider → pxe_oracle_interface}/index.d.ts +17 -9
  33. package/dest/pxe_oracle_interface/index.d.ts.map +1 -0
  34. package/dest/{pxe_data_provider → pxe_oracle_interface}/index.js +104 -61
  35. package/dest/pxe_oracle_interface/tagging_utils.d.ts.map +1 -0
  36. package/dest/pxe_service/error_enriching.d.ts +3 -4
  37. package/dest/pxe_service/error_enriching.d.ts.map +1 -1
  38. package/dest/pxe_service/error_enriching.js +4 -4
  39. package/dest/pxe_service/pxe_service.d.ts +18 -14
  40. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  41. package/dest/pxe_service/pxe_service.js +118 -65
  42. package/dest/storage/address_data_provider/address_data_provider.d.ts +13 -0
  43. package/dest/storage/address_data_provider/address_data_provider.d.ts.map +1 -0
  44. package/dest/storage/address_data_provider/address_data_provider.js +50 -0
  45. package/dest/storage/address_data_provider/index.d.ts +2 -0
  46. package/dest/storage/address_data_provider/index.d.ts.map +1 -0
  47. package/dest/storage/address_data_provider/index.js +1 -0
  48. package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.d.ts +11 -0
  49. package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.d.ts.map +1 -0
  50. package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.js +20 -0
  51. package/dest/storage/auth_witness_data_provider/index.d.ts +2 -0
  52. package/dest/storage/auth_witness_data_provider/index.d.ts.map +1 -0
  53. package/dest/storage/auth_witness_data_provider/index.js +1 -0
  54. package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts +16 -0
  55. package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts.map +1 -0
  56. package/dest/storage/capsule_data_provider/capsule_data_provider.js +57 -0
  57. package/dest/storage/capsule_data_provider/index.d.ts +2 -0
  58. package/dest/storage/capsule_data_provider/index.d.ts.map +1 -0
  59. package/dest/storage/capsule_data_provider/index.js +1 -0
  60. package/dest/{contract_data_provider → storage/contract_data_provider}/contract_data_provider.d.ts +38 -33
  61. package/dest/storage/contract_data_provider/contract_data_provider.d.ts.map +1 -0
  62. package/dest/{contract_data_provider → storage/contract_data_provider}/contract_data_provider.js +87 -42
  63. package/dest/storage/contract_data_provider/index.d.ts.map +1 -0
  64. package/dest/storage/contract_data_provider/private_functions_tree.d.ts.map +1 -0
  65. package/dest/storage/data_provider.d.ts +4 -0
  66. package/dest/storage/data_provider.d.ts.map +1 -0
  67. package/dest/storage/data_provider.js +1 -0
  68. package/dest/storage/index.d.ts +10 -0
  69. package/dest/storage/index.d.ts.map +1 -0
  70. package/dest/storage/index.js +9 -0
  71. package/dest/storage/note_data_provider/index.d.ts +3 -0
  72. package/dest/storage/note_data_provider/index.d.ts.map +1 -0
  73. package/dest/storage/note_data_provider/index.js +2 -0
  74. package/dest/storage/note_data_provider/note_dao.d.ts.map +1 -0
  75. package/dest/storage/note_data_provider/note_data_provider.d.ts +20 -0
  76. package/dest/storage/note_data_provider/note_data_provider.d.ts.map +1 -0
  77. package/dest/storage/note_data_provider/note_data_provider.js +249 -0
  78. package/dest/storage/sync_data_provider/index.d.ts +2 -0
  79. package/dest/storage/sync_data_provider/index.d.ts.map +1 -0
  80. package/dest/storage/sync_data_provider/index.js +1 -0
  81. package/dest/storage/sync_data_provider/sync_data_provider.d.ts +12 -0
  82. package/dest/storage/sync_data_provider/sync_data_provider.d.ts.map +1 -0
  83. package/dest/storage/sync_data_provider/sync_data_provider.js +29 -0
  84. package/dest/storage/tagging_data_provider/index.d.ts +2 -0
  85. package/dest/storage/tagging_data_provider/index.d.ts.map +1 -0
  86. package/dest/storage/tagging_data_provider/index.js +1 -0
  87. package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts +18 -0
  88. package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts.map +1 -0
  89. package/dest/storage/tagging_data_provider/tagging_data_provider.js +65 -0
  90. package/dest/synchronizer/synchronizer.d.ts +7 -3
  91. package/dest/synchronizer/synchronizer.d.ts.map +1 -1
  92. package/dest/synchronizer/synchronizer.js +16 -11
  93. package/dest/test/pxe_test_suite.d.ts.map +1 -0
  94. package/dest/{pxe_service/test → test}/pxe_test_suite.js +2 -6
  95. package/package.json +19 -26
  96. package/src/bin/index.ts +1 -1
  97. package/src/config/index.ts +2 -0
  98. package/src/entrypoints/client/bundle/index.ts +5 -0
  99. package/src/entrypoints/client/bundle/utils.ts +58 -0
  100. package/src/entrypoints/client/lazy/index.ts +5 -0
  101. package/src/entrypoints/client/lazy/utils.ts +53 -0
  102. package/src/entrypoints/client/pxe_creation_options.ts +7 -0
  103. package/src/entrypoints/server/index.ts +6 -0
  104. package/src/{utils/create_pxe_service.ts → entrypoints/server/utils.ts} +7 -18
  105. package/src/kernel_oracle/index.ts +1 -1
  106. package/src/kernel_prover/kernel_prover.ts +0 -46
  107. package/src/note_decryption_utils/add_public_values_to_payload.ts +4 -4
  108. package/src/{pxe_data_provider → pxe_oracle_interface}/index.ts +128 -96
  109. package/src/pxe_service/error_enriching.ts +8 -6
  110. package/src/pxe_service/pxe_service.ts +155 -89
  111. package/src/storage/address_data_provider/address_data_provider.ts +71 -0
  112. package/src/storage/address_data_provider/index.ts +1 -0
  113. package/src/storage/auth_witness_data_provider/auth_witness_data_provider.ts +34 -0
  114. package/src/storage/auth_witness_data_provider/index.ts +1 -0
  115. package/src/storage/capsule_data_provider/capsule_data_provider.ts +80 -0
  116. package/src/storage/capsule_data_provider/index.ts +1 -0
  117. package/src/{contract_data_provider → storage/contract_data_provider}/contract_data_provider.ts +128 -48
  118. package/src/storage/data_provider.ts +3 -0
  119. package/src/storage/index.ts +10 -0
  120. package/src/storage/note_data_provider/index.ts +2 -0
  121. package/src/storage/note_data_provider/note_data_provider.ts +345 -0
  122. package/src/storage/sync_data_provider/index.ts +1 -0
  123. package/src/storage/sync_data_provider/sync_data_provider.ts +40 -0
  124. package/src/storage/tagging_data_provider/index.ts +1 -0
  125. package/src/storage/tagging_data_provider/tagging_data_provider.ts +92 -0
  126. package/src/synchronizer/synchronizer.ts +15 -10
  127. package/src/{pxe_service/test → test}/pxe_test_suite.ts +2 -9
  128. package/dest/contract_data_provider/contract_data_provider.d.ts.map +0 -1
  129. package/dest/contract_data_provider/index.d.ts.map +0 -1
  130. package/dest/contract_data_provider/private_functions_tree.d.ts.map +0 -1
  131. package/dest/database/index.d.ts +0 -3
  132. package/dest/database/index.d.ts.map +0 -1
  133. package/dest/database/index.js +0 -2
  134. package/dest/database/interfaces/contract_artifact_db.d.ts +0 -20
  135. package/dest/database/interfaces/contract_artifact_db.d.ts.map +0 -1
  136. package/dest/database/interfaces/contract_artifact_db.js +0 -3
  137. package/dest/database/interfaces/contract_instance_db.d.ts +0 -20
  138. package/dest/database/interfaces/contract_instance_db.d.ts.map +0 -1
  139. package/dest/database/interfaces/contract_instance_db.js +0 -3
  140. package/dest/database/interfaces/index.d.ts +0 -4
  141. package/dest/database/interfaces/index.d.ts.map +0 -1
  142. package/dest/database/interfaces/pxe_database.d.ts +0 -211
  143. package/dest/database/interfaces/pxe_database.d.ts.map +0 -1
  144. package/dest/database/interfaces/pxe_database.js +0 -4
  145. package/dest/database/interfaces/pxe_database_test_suite.d.ts +0 -7
  146. package/dest/database/interfaces/pxe_database_test_suite.d.ts.map +0 -1
  147. package/dest/database/interfaces/pxe_database_test_suite.js +0 -557
  148. package/dest/database/kv_pxe_database.d.ts +0 -58
  149. package/dest/database/kv_pxe_database.d.ts.map +0 -1
  150. package/dest/database/kv_pxe_database.js +0 -480
  151. package/dest/database/note_dao.d.ts.map +0 -1
  152. package/dest/index.d.ts +0 -9
  153. package/dest/index.d.ts.map +0 -1
  154. package/dest/index.js +0 -8
  155. package/dest/pxe_data_provider/index.d.ts.map +0 -1
  156. package/dest/pxe_data_provider/tagging_utils.d.ts.map +0 -1
  157. package/dest/pxe_service/test/pxe_test_suite.d.ts.map +0 -1
  158. package/dest/utils/create_pxe_service.d.ts.map +0 -1
  159. package/src/database/index.ts +0 -2
  160. package/src/database/interfaces/contract_artifact_db.ts +0 -20
  161. package/src/database/interfaces/contract_instance_db.ts +0 -21
  162. package/src/database/interfaces/index.ts +0 -3
  163. package/src/database/interfaces/pxe_database.ts +0 -240
  164. package/src/database/interfaces/pxe_database_test_suite.ts +0 -558
  165. package/src/database/kv_pxe_database.ts +0 -670
  166. package/src/index.ts +0 -9
  167. /package/dest/{database/interfaces/index.js → entrypoints/client/pxe_creation_options.js} +0 -0
  168. /package/dest/{pxe_data_provider → pxe_oracle_interface}/tagging_utils.d.ts +0 -0
  169. /package/dest/{pxe_data_provider → pxe_oracle_interface}/tagging_utils.js +0 -0
  170. /package/dest/{contract_data_provider → storage/contract_data_provider}/index.d.ts +0 -0
  171. /package/dest/{contract_data_provider → storage/contract_data_provider}/index.js +0 -0
  172. /package/dest/{contract_data_provider → storage/contract_data_provider}/private_functions_tree.d.ts +0 -0
  173. /package/dest/{contract_data_provider → storage/contract_data_provider}/private_functions_tree.js +0 -0
  174. /package/dest/{database → storage/note_data_provider}/note_dao.d.ts +0 -0
  175. /package/dest/{database → storage/note_data_provider}/note_dao.js +0 -0
  176. /package/dest/{pxe_service/test → test}/pxe_test_suite.d.ts +0 -0
  177. /package/src/{pxe_data_provider → pxe_oracle_interface}/tagging_utils.ts +0 -0
  178. /package/src/{contract_data_provider → storage/contract_data_provider}/index.ts +0 -0
  179. /package/src/{contract_data_provider → storage/contract_data_provider}/private_functions_tree.ts +0 -0
  180. /package/src/{database → storage/note_data_provider}/note_dao.ts +0 -0
@@ -21,9 +21,7 @@ import {
21
21
  PrivateKernelTailCircuitPrivateInputs,
22
22
  type PrivateKernelTailCircuitPublicInputs,
23
23
  PrivateVerificationKeyHints,
24
- type ScopedPrivateLogData,
25
24
  } from '@aztec/stdlib/kernel';
26
- import type { PrivateLog } from '@aztec/stdlib/logs';
27
25
  import { ClientIvcProof } from '@aztec/stdlib/proofs';
28
26
  import {
29
27
  type PrivateCallExecutionResult,
@@ -38,48 +36,10 @@ import {
38
36
  import { VerificationKeyAsFields } from '@aztec/stdlib/vks';
39
37
 
40
38
  import type { WitnessMap } from '@noir-lang/types';
41
- import { strict as assert } from 'assert';
42
39
 
43
40
  import { PrivateKernelResetPrivateInputsBuilder } from './hints/build_private_kernel_reset_private_inputs.js';
44
41
  import type { ProvingDataOracle } from './proving_data_oracle.js';
45
42
 
46
- // TODO(#10592): Temporary workaround to check that the private logs are correctly split into non-revertible set and revertible set.
47
- // This should be done in TailToPublicOutputValidator in private kernel tail.
48
- function checkPrivateLogs(
49
- privateLogs: ScopedPrivateLogData[],
50
- nonRevertiblePrivateLogs: PrivateLog[],
51
- revertiblePrivateLogs: PrivateLog[],
52
- splitCounter: number,
53
- ) {
54
- let numNonRevertible = 0;
55
- let numRevertible = 0;
56
- privateLogs
57
- .filter(privateLog => privateLog.inner.counter !== 0)
58
- .forEach(privateLog => {
59
- if (privateLog.inner.counter < splitCounter) {
60
- assert(
61
- privateLog.inner.log.toBuffer().equals(nonRevertiblePrivateLogs[numNonRevertible].toBuffer()),
62
- `mismatch non-revertible private logs at index ${numNonRevertible}`,
63
- );
64
- numNonRevertible++;
65
- } else {
66
- assert(
67
- privateLog.inner.log.toBuffer().equals(revertiblePrivateLogs[numRevertible].toBuffer()),
68
- `mismatch revertible private logs at index ${numRevertible}`,
69
- );
70
- numRevertible++;
71
- }
72
- });
73
- assert(
74
- nonRevertiblePrivateLogs.slice(numNonRevertible).every(l => l.isEmpty()),
75
- 'Unexpected non-empty private log in non-revertible set.',
76
- );
77
- assert(
78
- revertiblePrivateLogs.slice(numRevertible).every(l => l.isEmpty()),
79
- 'Unexpected non-empty private log in revertible set.',
80
- );
81
- }
82
-
83
43
  const NULL_PROVE_OUTPUT: PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs> = {
84
44
  publicInputs: PrivateKernelCircuitPublicInputs.empty(),
85
45
  verificationKey: VerificationKeyAsFields.makeEmpty(CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS),
@@ -309,12 +269,6 @@ export class KernelProver {
309
269
  const tailOutput = generateWitnesses
310
270
  ? await this.proofCreator.generateTailOutput(privateInputs)
311
271
  : await this.proofCreator.simulateTail(privateInputs);
312
- if (tailOutput.publicInputs.forPublic) {
313
- const privateLogs = privateInputs.previousKernel.publicInputs.end.privateLogs;
314
- const nonRevertiblePrivateLogs = tailOutput.publicInputs.forPublic.nonRevertibleAccumulatedData.privateLogs;
315
- const revertiblePrivateLogs = tailOutput.publicInputs.forPublic.revertibleAccumulatedData.privateLogs;
316
- checkPrivateLogs(privateLogs, nonRevertiblePrivateLogs, revertiblePrivateLogs, validationRequestsSplitCounter);
317
- }
318
272
 
319
273
  acirs.push(tailOutput.bytecode);
320
274
  witnessStack.push(tailOutput.outputWitness);
@@ -2,7 +2,7 @@ import { ContractNotFoundError } from '@aztec/simulator/client';
2
2
  import type { L1NotePayload } from '@aztec/stdlib/logs';
3
3
  import { Note } from '@aztec/stdlib/note';
4
4
 
5
- import type { PxeDatabase } from '../database/interfaces/pxe_database.js';
5
+ import type { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
6
6
 
7
7
  /**
8
8
  * Merges privately and publicly delivered note values.
@@ -11,21 +11,21 @@ import type { PxeDatabase } from '../database/interfaces/pxe_database.js';
11
11
  * @returns Note payload with public fields added.
12
12
  */
13
13
  export async function getOrderedNoteItems(
14
- db: PxeDatabase,
14
+ contractDataProvider: ContractDataProvider,
15
15
  { contractAddress, noteTypeId, privateNoteValues, publicNoteValues }: L1NotePayload,
16
16
  ): Promise<Note> {
17
17
  if (publicNoteValues.length === 0) {
18
18
  return new Note(privateNoteValues);
19
19
  }
20
20
 
21
- const instance = await db.getContractInstance(contractAddress);
21
+ const instance = await contractDataProvider.getContractInstance(contractAddress);
22
22
  if (!instance) {
23
23
  throw new ContractNotFoundError(
24
24
  `Could not find instance for ${contractAddress.toString()}. This should never happen here as the partial notes flow should be triggered only for non-deferred notes.`,
25
25
  );
26
26
  }
27
27
 
28
- const artifact = await db.getContractArtifact(instance.currentContractClassId);
28
+ const artifact = await contractDataProvider.getContractArtifact(instance.currentContractClassId);
29
29
  if (!artifact) {
30
30
  throw new Error(
31
31
  `Could not find artifact for contract class ${instance.currentContractClassId.toString()}. This should never happen here as the partial notes flow should be triggered only for non-deferred notes.`,
@@ -42,23 +42,33 @@ import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from
42
42
  import type { BlockHeader } from '@aztec/stdlib/tx';
43
43
  import { TxHash } from '@aztec/stdlib/tx';
44
44
 
45
- import { ContractDataProvider } from '../contract_data_provider/index.js';
46
- import type { PxeDatabase } from '../database/index.js';
47
- import { NoteDao } from '../database/note_dao.js';
48
45
  import { getOrderedNoteItems } from '../note_decryption_utils/add_public_values_to_payload.js';
46
+ import type { AddressDataProvider } from '../storage/address_data_provider/address_data_provider.js';
47
+ import type { AuthWitnessDataProvider } from '../storage/auth_witness_data_provider/auth_witness_data_provider.js';
48
+ import type { CapsuleDataProvider } from '../storage/capsule_data_provider/capsule_data_provider.js';
49
+ import type { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
50
+ import { NoteDao } from '../storage/note_data_provider/note_dao.js';
51
+ import type { NoteDataProvider } from '../storage/note_data_provider/note_data_provider.js';
52
+ import type { SyncDataProvider } from '../storage/sync_data_provider/sync_data_provider.js';
53
+ import type { TaggingDataProvider } from '../storage/tagging_data_provider/tagging_data_provider.js';
49
54
  import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndexesMap } from './tagging_utils.js';
50
55
 
51
56
  /**
52
57
  * A data layer that provides and stores information needed for simulating/proving a transaction.
53
58
  */
54
- export class PXEDataProvider implements ExecutionDataProvider {
59
+ export class PXEOracleInterface implements ExecutionDataProvider {
55
60
  constructor(
56
- private db: PxeDatabase,
57
- private keyStore: KeyStore,
58
61
  private aztecNode: AztecNode,
62
+ private keyStore: KeyStore,
59
63
  private simulationProvider: SimulationProvider,
60
64
  private contractDataProvider: ContractDataProvider,
61
- private log = createLogger('pxe:pxe_data_provider'),
65
+ private noteDataProvider: NoteDataProvider,
66
+ private capsuleDataProvider: CapsuleDataProvider,
67
+ private syncDataProvider: SyncDataProvider,
68
+ private taggingDataProvider: TaggingDataProvider,
69
+ private addressDataProvider: AddressDataProvider,
70
+ private authWitnessDataProvider: AuthWitnessDataProvider,
71
+ private log = createLogger('pxe:pxe_data_manager'),
62
72
  ) {}
63
73
 
64
74
  getKeyValidationRequest(pkMHash: Fr, contractAddress: AztecAddress): Promise<KeyValidationRequest> {
@@ -66,7 +76,7 @@ export class PXEDataProvider implements ExecutionDataProvider {
66
76
  }
67
77
 
68
78
  async getCompleteAddress(account: AztecAddress): Promise<CompleteAddress> {
69
- const completeAddress = await this.db.getCompleteAddress(account);
79
+ const completeAddress = await this.addressDataProvider.getCompleteAddress(account);
70
80
  if (!completeAddress) {
71
81
  throw new Error(
72
82
  `No public key registered for address ${account}.
@@ -77,23 +87,20 @@ export class PXEDataProvider implements ExecutionDataProvider {
77
87
  }
78
88
 
79
89
  async getContractInstance(address: AztecAddress): Promise<ContractInstance> {
80
- const instance = await this.db.getContractInstance(address);
90
+ const instance = await this.contractDataProvider.getContractInstance(address);
81
91
  if (!instance) {
82
92
  throw new Error(`No contract instance found for address ${address.toString()}`);
83
93
  }
84
94
  return instance;
85
95
  }
86
96
 
87
- async getAuthWitness(messageHash: Fr): Promise<Fr[]> {
88
- const witness = await this.db.getAuthWitness(messageHash);
89
- if (!witness) {
90
- throw new Error(`Unknown auth witness for message hash ${messageHash.toString()}`);
91
- }
97
+ async getAuthWitness(messageHash: Fr): Promise<Fr[] | undefined> {
98
+ const witness = await this.authWitnessDataProvider.getAuthWitness(messageHash);
92
99
  return witness;
93
100
  }
94
101
 
95
102
  async getNotes(contractAddress: AztecAddress, storageSlot: Fr, status: NoteStatus, scopes?: AztecAddress[]) {
96
- const noteDaos = await this.db.getNotes({
103
+ const noteDaos = await this.noteDataProvider.getNotes({
97
104
  contractAddress,
98
105
  storageSlot,
99
106
  status,
@@ -244,7 +251,7 @@ export class PXEDataProvider implements ExecutionDataProvider {
244
251
  * @returns A Promise that resolves to a BlockHeader object.
245
252
  */
246
253
  getBlockHeader(): Promise<BlockHeader> {
247
- return this.db.getBlockHeader();
254
+ return this.syncDataProvider.getBlockHeader();
248
255
  }
249
256
 
250
257
  /**
@@ -282,7 +289,7 @@ export class PXEDataProvider implements ExecutionDataProvider {
282
289
  * @returns The full list of the users contact addresses.
283
290
  */
284
291
  public getSenders(): Promise<AztecAddress[]> {
285
- return this.db.getSenderAddresses();
292
+ return this.taggingDataProvider.getSenderAddresses();
286
293
  }
287
294
 
288
295
  /**
@@ -301,7 +308,7 @@ export class PXEDataProvider implements ExecutionDataProvider {
301
308
  await this.syncTaggedLogsAsSender(contractAddress, sender, recipient);
302
309
 
303
310
  const appTaggingSecret = await this.#calculateAppTaggingSecret(contractAddress, sender, recipient);
304
- const [index] = await this.db.getTaggingSecretsIndexesAsSender([appTaggingSecret]);
311
+ const [index] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([appTaggingSecret]);
305
312
 
306
313
  return new IndexedTaggingSecret(appTaggingSecret, index);
307
314
  }
@@ -327,8 +334,8 @@ export class PXEDataProvider implements ExecutionDataProvider {
327
334
  contractAddress,
328
335
  });
329
336
 
330
- const [index] = await this.db.getTaggingSecretsIndexesAsSender([secret]);
331
- await this.db.setTaggingSecretsIndexesAsSender([new IndexedTaggingSecret(secret, index + 1)]);
337
+ const [index] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([secret]);
338
+ await this.taggingDataProvider.setTaggingSecretsIndexesAsSender([new IndexedTaggingSecret(secret, index + 1)]);
332
339
  }
333
340
 
334
341
  async #calculateAppTaggingSecret(contractAddress: AztecAddress, sender: AztecAddress, recipient: AztecAddress) {
@@ -358,16 +365,17 @@ export class PXEDataProvider implements ExecutionDataProvider {
358
365
 
359
366
  // We implicitly add all PXE accounts as senders, this helps us decrypt tags on notes that we send to ourselves
360
367
  // (recipient = us, sender = us)
361
- const senders = [...(await this.db.getSenderAddresses()), ...(await this.keyStore.getAccounts())].filter(
362
- (address, index, self) => index === self.findIndex(otherAddress => otherAddress.equals(address)),
363
- );
368
+ const senders = [
369
+ ...(await this.taggingDataProvider.getSenderAddresses()),
370
+ ...(await this.keyStore.getAccounts()),
371
+ ].filter((address, index, self) => index === self.findIndex(otherAddress => otherAddress.equals(address)));
364
372
  const appTaggingSecrets = await Promise.all(
365
373
  senders.map(async contact => {
366
374
  const sharedSecret = await computeTaggingSecretPoint(recipientCompleteAddress, recipientIvsk, contact);
367
375
  return poseidon2Hash([sharedSecret.x, sharedSecret.y, contractAddress]);
368
376
  }),
369
377
  );
370
- const indexes = await this.db.getTaggingSecretsIndexesAsRecipient(appTaggingSecrets);
378
+ const indexes = await this.taggingDataProvider.getTaggingSecretsIndexesAsRecipient(appTaggingSecrets);
371
379
  return appTaggingSecrets.map((secret, i) => new IndexedTaggingSecret(secret, indexes[i]));
372
380
  }
373
381
 
@@ -384,7 +392,7 @@ export class PXEDataProvider implements ExecutionDataProvider {
384
392
  recipient: AztecAddress,
385
393
  ): Promise<void> {
386
394
  const appTaggingSecret = await this.#calculateAppTaggingSecret(contractAddress, sender, recipient);
387
- const [oldIndex] = await this.db.getTaggingSecretsIndexesAsSender([appTaggingSecret]);
395
+ const [oldIndex] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([appTaggingSecret]);
388
396
 
389
397
  // This algorithm works such that:
390
398
  // 1. If we find minimum consecutive empty logs in a window of logs we set the index to the index of the last log
@@ -422,7 +430,9 @@ export class PXEDataProvider implements ExecutionDataProvider {
422
430
 
423
431
  const contractName = await this.contractDataProvider.getDebugContractName(contractAddress);
424
432
  if (currentIndex !== oldIndex) {
425
- await this.db.setTaggingSecretsIndexesAsSender([new IndexedTaggingSecret(appTaggingSecret, currentIndex)]);
433
+ await this.taggingDataProvider.setTaggingSecretsIndexesAsSender([
434
+ new IndexedTaggingSecret(appTaggingSecret, currentIndex),
435
+ ]);
426
436
 
427
437
  this.log.debug(`Syncing logs for sender ${sender} at contract ${contractName}(${contractAddress})`, {
428
438
  sender,
@@ -591,7 +601,7 @@ export class PXEDataProvider implements ExecutionDataProvider {
591
601
  );
592
602
 
593
603
  // At this point we have processed all the logs for the recipient so we store the new largest indexes in the db.
594
- await this.db.setTaggingSecretsIndexesAsRecipient(
604
+ await this.taggingDataProvider.setTaggingSecretsIndexesAsRecipient(
595
605
  Object.entries(newLargestIndexMapToStore).map(
596
606
  ([appTaggingSecret, index]) => new IndexedTaggingSecret(Fr.fromHexString(appTaggingSecret), index),
597
607
  ),
@@ -632,7 +642,7 @@ export class PXEDataProvider implements ExecutionDataProvider {
632
642
  excludedIndices.set(scopedLog.txHash.toString(), new Set());
633
643
  }
634
644
 
635
- const note = await getOrderedNoteItems(this.db, payload);
645
+ const note = await getOrderedNoteItems(this.contractDataProvider, payload);
636
646
  const plaintext = [payload.storageSlot, payload.noteTypeId.toField(), ...note.items];
637
647
 
638
648
  decrypted.push({ plaintext, txHash: scopedLog.txHash, contractAddress: payload.contractAddress });
@@ -680,7 +690,6 @@ export class PXEDataProvider implements ExecutionDataProvider {
680
690
  return;
681
691
  }
682
692
 
683
- // Called when notes are delivered, usually as a result to a call to the process_log contract function
684
693
  public async deliverNote(
685
694
  contractAddress: AztecAddress,
686
695
  storageSlot: Fr,
@@ -691,23 +700,96 @@ export class PXEDataProvider implements ExecutionDataProvider {
691
700
  txHash: Fr,
692
701
  recipient: AztecAddress,
693
702
  ): Promise<void> {
694
- const noteDao = await this.produceNoteDao(
703
+ // We are going to store the new note in the NoteDataProvider, which will let us later return it via `getNotes`.
704
+ // There's two things we need to check before we do this however:
705
+ // - we must make sure the note does actually exist in the note hash tree
706
+ // - we need to check if the note has already been nullified
707
+ //
708
+ // Failing to do either of the above would result in circuits getting either non-existent notes and failing to
709
+ // produce inclusion proofs for them, or getting nullified notes and producing duplicate nullifiers, both of which
710
+ // are catastrophic failure modes.
711
+ //
712
+ // Note that adding a note and removing it is *not* equivalent to never adding it in the first place. A nullifier
713
+ // emitted in a block that comes after note creation might result in the note being de-nullified by a chain reorg,
714
+ // so we must store both the note hash and nullifier block information.
715
+
716
+ // We avoid making node queries at 'latest' since we don't want to process notes or nullifiers that only exist ahead
717
+ // in time of the locally synced state.
718
+ // Note that while this technically results in historical queries, we perform it at the latest locally synced block
719
+ // number which *should* be recent enough to be available, even for non-archive nodes.
720
+ const syncedBlockNumber = (await this.syncDataProvider.getBlockNumber())!;
721
+ // TODO (#12559): handle undefined syncedBlockNumber
722
+ // if (syncedBlockNumber === undefined) {
723
+ // throw new Error(`Attempted to deliver a note with an unsynchronized PXE - this should never happen`);
724
+ //}
725
+
726
+ // By computing siloed and unique note hashes ourselves we prevent contracts from interfering with the note storage
727
+ // of other contracts, which would constitute a security breach.
728
+ const uniqueNoteHash = await computeUniqueNoteHash(nonce, await siloNoteHash(contractAddress, noteHash));
729
+ const siloedNullifier = await siloNullifier(contractAddress, nullifier);
730
+
731
+ // We store notes by their index in the global note hash tree, which has the convenient side effect of validating
732
+ // note existence in said tree.
733
+ const [uniqueNoteHashTreeIndex] = await this.aztecNode.findLeavesIndexes(
734
+ syncedBlockNumber,
735
+ MerkleTreeId.NOTE_HASH_TREE,
736
+ [uniqueNoteHash],
737
+ );
738
+ if (uniqueNoteHashTreeIndex === undefined) {
739
+ throw new Error(
740
+ `Note hash ${noteHash} (uniqued as ${uniqueNoteHash}) is not present on the tree at block ${syncedBlockNumber} (from tx ${txHash})`,
741
+ );
742
+ }
743
+
744
+ // TODO (#12550): findLeavesIndexes should probably return an InBlock, same as findNullifiersIndexesWithBlock. This
745
+ // would save us from having to then query the tx receipt in order to get the block hash and number. Note regardless
746
+ // that we're not validating that the note was indeed created in this tx (which would require inspecting the tx
747
+ // effects), so maybe what we really want is an InTx.
748
+ const txReceipt = await this.aztecNode.getTxReceipt(new TxHash(txHash));
749
+ if (txReceipt === undefined) {
750
+ throw new Error(`Failed to fetch tx receipt for tx hash ${txHash} when searching for note hashes`);
751
+ }
752
+
753
+ // TODO(#12549): does it make sense to store the recipient's address point instead of just its address?
754
+ const recipientAddressPoint = await recipient.toAddressPoint();
755
+ const noteDao = new NoteDao(
756
+ new Note(content),
695
757
  contractAddress,
696
758
  storageSlot,
697
759
  nonce,
698
- content,
699
760
  noteHash,
700
- nullifier,
701
- txHash,
702
- recipient,
761
+ siloedNullifier,
762
+ new TxHash(txHash),
763
+ txReceipt.blockNumber!,
764
+ txReceipt.blockHash!.toString(),
765
+ uniqueNoteHashTreeIndex,
766
+ recipientAddressPoint,
767
+ NoteSelector.empty(), // TODO(#12013): remove
703
768
  );
704
769
 
705
- await this.db.addNotes([noteDao], recipient);
770
+ await this.noteDataProvider.addNotes([noteDao], recipient);
706
771
  this.log.verbose('Added note', {
707
772
  contract: noteDao.contractAddress,
708
773
  slot: noteDao.storageSlot,
709
- nullifier: noteDao.siloedNullifier.toString,
774
+ noteHash: noteDao.noteHash,
775
+ nullifier: noteDao.siloedNullifier.toString(),
710
776
  });
777
+
778
+ const [nullifierIndex] = await this.aztecNode.findNullifiersIndexesWithBlock(syncedBlockNumber, [siloedNullifier]);
779
+ if (nullifierIndex !== undefined) {
780
+ const { data: _, ...blockHashAndNum } = nullifierIndex;
781
+ await this.noteDataProvider.removeNullifiedNotes(
782
+ [{ data: siloedNullifier, ...blockHashAndNum }],
783
+ recipientAddressPoint,
784
+ );
785
+
786
+ this.log.verbose(`Removed just-added note`, {
787
+ contract: contractAddress,
788
+ slot: storageSlot,
789
+ noteHash: noteHash,
790
+ nullifier: siloedNullifier.toString(),
791
+ });
792
+ }
711
793
  }
712
794
 
713
795
  public async getLogByTag(tag: Fr): Promise<LogWithTxData | null> {
@@ -751,7 +833,7 @@ export class PXEDataProvider implements ExecutionDataProvider {
751
833
  this.log.verbose('Searching for nullifiers of known notes', { contract: contractAddress });
752
834
 
753
835
  for (const recipient of await this.keyStore.getAccounts()) {
754
- const currentNotesForRecipient = await this.db.getNotes({ contractAddress, owner: recipient });
836
+ const currentNotesForRecipient = await this.noteDataProvider.getNotes({ contractAddress, owner: recipient });
755
837
  const nullifiersToCheck = currentNotesForRecipient.map(note => note.siloedNullifier);
756
838
  const nullifierIndexes = await this.aztecNode.findNullifiersIndexesWithBlock('latest', nullifiersToCheck);
757
839
 
@@ -763,7 +845,10 @@ export class PXEDataProvider implements ExecutionDataProvider {
763
845
  })
764
846
  .filter(nullifier => nullifier !== undefined) as InBlock<Fr>[];
765
847
 
766
- const nullifiedNotes = await this.db.removeNullifiedNotes(foundNullifiers, await recipient.toAddressPoint());
848
+ const nullifiedNotes = await this.noteDataProvider.removeNullifiedNotes(
849
+ foundNullifiers,
850
+ await recipient.toAddressPoint(),
851
+ );
767
852
  nullifiedNotes.forEach(noteDao => {
768
853
  this.log.verbose(`Removed note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot}`, {
769
854
  contract: noteDao.contractAddress,
@@ -774,59 +859,6 @@ export class PXEDataProvider implements ExecutionDataProvider {
774
859
  }
775
860
  }
776
861
 
777
- async produceNoteDao(
778
- contractAddress: AztecAddress,
779
- storageSlot: Fr,
780
- nonce: Fr,
781
- content: Fr[],
782
- noteHash: Fr,
783
- nullifier: Fr,
784
- txHash: Fr,
785
- recipient: AztecAddress,
786
- ): Promise<NoteDao> {
787
- // We need to validate that the note does indeed exist in the world state to avoid adding notes that are then
788
- // impossible to prove.
789
-
790
- const receipt = await this.aztecNode.getTxReceipt(new TxHash(txHash));
791
- if (receipt === undefined) {
792
- throw new Error(`Failed to fetch tx receipt for tx hash ${txHash} when searching for note hashes`);
793
- }
794
-
795
- // Siloed and unique hashes are computed by us instead of relying on values sent by the contract to make sure
796
- // we're not e.g. storing notes that belong to some other contract, which would constitute a security breach.
797
- const uniqueNoteHash = await computeUniqueNoteHash(nonce, await siloNoteHash(contractAddress, noteHash));
798
- const siloedNullifier = await siloNullifier(contractAddress, nullifier);
799
-
800
- // We store notes by their index in the global note hash tree, which has the convenient side effect of validating
801
- // note existence in said tree. Note that while this is technically a historical query, we perform it at the latest
802
- // locally synced block number which *should* be recent enough to be available. We avoid querying at 'latest' since
803
- // we want to avoid accidentally processing notes that only exist ahead in time of the locally synced state.
804
- const syncedBlockNumber = await this.db.getBlockNumber();
805
- const uniqueNoteHashTreeIndex = (
806
- await this.aztecNode.findLeavesIndexes(syncedBlockNumber!, MerkleTreeId.NOTE_HASH_TREE, [uniqueNoteHash])
807
- )[0];
808
- if (uniqueNoteHashTreeIndex === undefined) {
809
- throw new Error(
810
- `Note hash ${noteHash} (uniqued as ${uniqueNoteHash}) is not present on the tree at block ${syncedBlockNumber} (from tx ${txHash})`,
811
- );
812
- }
813
-
814
- return new NoteDao(
815
- new Note(content),
816
- contractAddress,
817
- storageSlot,
818
- nonce,
819
- noteHash,
820
- siloedNullifier,
821
- new TxHash(txHash),
822
- receipt.blockNumber!,
823
- receipt.blockHash!.toString(),
824
- uniqueNoteHashTreeIndex,
825
- await recipient.toAddressPoint(),
826
- NoteSelector.empty(), // TODO(#12013): remove
827
- );
828
- }
829
-
830
862
  async callProcessLog(
831
863
  contractAddress: AztecAddress,
832
864
  logPlaintext: Fr[],
@@ -836,7 +868,7 @@ export class PXEDataProvider implements ExecutionDataProvider {
836
868
  recipient: AztecAddress,
837
869
  simulator?: AcirSimulator,
838
870
  ) {
839
- const artifact: FunctionArtifact | undefined = await new ContractDataProvider(this.db).getFunctionArtifactByName(
871
+ const artifact: FunctionArtifact | undefined = await this.contractDataProvider.getFunctionArtifactByName(
840
872
  contractAddress,
841
873
  'process_log',
842
874
  );
@@ -872,19 +904,19 @@ export class PXEDataProvider implements ExecutionDataProvider {
872
904
  }
873
905
 
874
906
  storeCapsule(contractAddress: AztecAddress, slot: Fr, capsule: Fr[]): Promise<void> {
875
- return this.db.storeCapsule(contractAddress, slot, capsule);
907
+ return this.capsuleDataProvider.storeCapsule(contractAddress, slot, capsule);
876
908
  }
877
909
 
878
910
  loadCapsule(contractAddress: AztecAddress, slot: Fr): Promise<Fr[] | null> {
879
- return this.db.loadCapsule(contractAddress, slot);
911
+ return this.capsuleDataProvider.loadCapsule(contractAddress, slot);
880
912
  }
881
913
 
882
914
  deleteCapsule(contractAddress: AztecAddress, slot: Fr): Promise<void> {
883
- return this.db.deleteCapsule(contractAddress, slot);
915
+ return this.capsuleDataProvider.deleteCapsule(contractAddress, slot);
884
916
  }
885
917
 
886
918
  copyCapsule(contractAddress: AztecAddress, srcSlot: Fr, dstSlot: Fr, numEntries: number): Promise<void> {
887
- return this.db.copyCapsule(contractAddress, srcSlot, dstSlot, numEntries);
919
+ return this.capsuleDataProvider.copyCapsule(contractAddress, srcSlot, dstSlot, numEntries);
888
920
  }
889
921
  }
890
922
 
@@ -6,15 +6,18 @@ import { FunctionSelector } from '@aztec/stdlib/abi';
6
6
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
7
7
  import { type SimulationError, isNoirCallStackUnresolved } from '@aztec/stdlib/errors';
8
8
 
9
- import { ContractDataProvider } from '../contract_data_provider/index.js';
10
- import type { PxeDatabase } from '../database/interfaces/pxe_database.js';
9
+ import type { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
11
10
 
12
11
  /**
13
12
  * Adds contract and function names to a simulation error, if they
14
13
  * can be found in the PXE database
15
14
  * @param err - The error to enrich.
16
15
  */
17
- export async function enrichSimulationError(err: SimulationError, db: PxeDatabase, logger: Logger) {
16
+ export async function enrichSimulationError(
17
+ err: SimulationError,
18
+ contractDataProvider: ContractDataProvider,
19
+ logger: Logger,
20
+ ) {
18
21
  // Maps contract addresses to the set of function names that were in error.
19
22
  // Map and Set do reference equality for their keys instead of value equality, so we store the string
20
23
  // representation to get e.g. different contract address objects with the same address value to match.
@@ -30,7 +33,7 @@ export async function enrichSimulationError(err: SimulationError, db: PxeDatabas
30
33
  await Promise.all(
31
34
  [...mentionedFunctions.entries()].map(async ([contractAddress, fnNames]) => {
32
35
  const parsedContractAddress = AztecAddress.fromString(contractAddress);
33
- const contract = await db.getContract(parsedContractAddress);
36
+ const contract = await contractDataProvider.getContract(parsedContractAddress);
34
37
  if (contract) {
35
38
  err.enrichWithContractName(parsedContractAddress, contract.name);
36
39
  for (const fnName of fnNames) {
@@ -59,7 +62,6 @@ export async function enrichSimulationError(err: SimulationError, db: PxeDatabas
59
62
  export async function enrichPublicSimulationError(
60
63
  err: SimulationError,
61
64
  contractDataProvider: ContractDataProvider,
62
- db: PxeDatabase,
63
65
  logger: Logger,
64
66
  ) {
65
67
  const callStack = err.getCallStack();
@@ -99,6 +101,6 @@ export async function enrichPublicSimulationError(
99
101
  );
100
102
  }
101
103
  }
102
- await enrichSimulationError(err, db, logger);
104
+ await enrichSimulationError(err, contractDataProvider, logger);
103
105
  }
104
106
  }