@aztec/pxe 0.42.0 → 0.44.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 (58) hide show
  1. package/dest/database/deferred_note_dao.d.ts +5 -4
  2. package/dest/database/deferred_note_dao.d.ts.map +1 -1
  3. package/dest/database/deferred_note_dao.js +4 -3
  4. package/dest/database/incoming_note_dao.d.ts +74 -0
  5. package/dest/database/incoming_note_dao.d.ts.map +1 -0
  6. package/dest/database/incoming_note_dao.js +93 -0
  7. package/dest/database/index.d.ts +1 -0
  8. package/dest/database/index.d.ts.map +1 -1
  9. package/dest/database/index.js +2 -1
  10. package/dest/database/kv_pxe_database.d.ts +10 -7
  11. package/dest/database/kv_pxe_database.d.ts.map +1 -1
  12. package/dest/database/kv_pxe_database.js +149 -78
  13. package/dest/database/{note_dao.d.ts → outgoing_note_dao.d.ts} +10 -14
  14. package/dest/database/outgoing_note_dao.d.ts.map +1 -0
  15. package/dest/database/outgoing_note_dao.js +84 -0
  16. package/dest/database/pxe_database.d.ts +21 -9
  17. package/dest/database/pxe_database.d.ts.map +1 -1
  18. package/dest/database/pxe_database_test_suite.d.ts.map +1 -1
  19. package/dest/database/pxe_database_test_suite.js +71 -24
  20. package/dest/index.d.ts +3 -0
  21. package/dest/index.d.ts.map +1 -1
  22. package/dest/index.js +4 -1
  23. package/dest/kernel_oracle/index.d.ts +1 -1
  24. package/dest/note_processor/note_processor.d.ts +23 -20
  25. package/dest/note_processor/note_processor.d.ts.map +1 -1
  26. package/dest/note_processor/note_processor.js +116 -76
  27. package/dest/note_processor/produce_note_dao.d.ts +13 -4
  28. package/dest/note_processor/produce_note_dao.d.ts.map +1 -1
  29. package/dest/note_processor/produce_note_dao.js +88 -31
  30. package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
  31. package/dest/pxe_http/pxe_http_server.js +3 -1
  32. package/dest/pxe_service/create_pxe_service.d.ts.map +1 -1
  33. package/dest/pxe_service/create_pxe_service.js +3 -1
  34. package/dest/pxe_service/pxe_service.d.ts +9 -4
  35. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  36. package/dest/pxe_service/pxe_service.js +106 -28
  37. package/dest/simulator_oracle/index.js +2 -2
  38. package/dest/synchronizer/synchronizer.d.ts +2 -2
  39. package/dest/synchronizer/synchronizer.d.ts.map +1 -1
  40. package/dest/synchronizer/synchronizer.js +37 -36
  41. package/package.json +23 -15
  42. package/src/database/deferred_note_dao.ts +4 -3
  43. package/src/database/{note_dao.ts → incoming_note_dao.ts} +14 -10
  44. package/src/database/index.ts +1 -0
  45. package/src/database/kv_pxe_database.ts +127 -29
  46. package/src/database/outgoing_note_dao.ts +91 -0
  47. package/src/database/pxe_database.ts +23 -9
  48. package/src/database/pxe_database_test_suite.ts +93 -29
  49. package/src/index.ts +3 -0
  50. package/src/note_processor/note_processor.ts +190 -121
  51. package/src/note_processor/produce_note_dao.ts +164 -50
  52. package/src/pxe_http/pxe_http_server.ts +2 -0
  53. package/src/pxe_service/create_pxe_service.ts +2 -0
  54. package/src/pxe_service/pxe_service.ts +170 -42
  55. package/src/simulator_oracle/index.ts +1 -1
  56. package/src/synchronizer/synchronizer.ts +48 -52
  57. package/dest/database/note_dao.d.ts.map +0 -1
  58. package/dest/database/note_dao.js +0 -89
@@ -1,9 +1,12 @@
1
1
  import { type L1NotePayload, type TxHash } from '@aztec/circuit-types';
2
2
  import { Fr, type PublicKey } from '@aztec/circuits.js';
3
3
  import { computeNoteHashNonce, siloNullifier } from '@aztec/circuits.js/hash';
4
- import { type AcirSimulator } from '@aztec/simulator';
4
+ import { type Logger } from '@aztec/foundation/log';
5
+ import { type AcirSimulator, ContractNotFoundError } from '@aztec/simulator';
5
6
 
6
- import { NoteDao } from '../database/note_dao.js';
7
+ import { DeferredNoteDao } from '../database/deferred_note_dao.js';
8
+ import { IncomingNoteDao } from '../database/incoming_note_dao.js';
9
+ import { OutgoingNoteDao } from '../database/outgoing_note_dao.js';
7
10
 
8
11
  /**
9
12
  * Decodes a note from a transaction that we know was intended for us.
@@ -11,96 +14,207 @@ import { NoteDao } from '../database/note_dao.js';
11
14
  * Accepts a set of excluded indices, which are indices that have been assigned a note in the same tx.
12
15
  * Inserts the index of the note into the excludedIndices set if the note is successfully decoded.
13
16
  *
14
- * @param publicKey - The public counterpart to the private key to be used in note decryption.
17
+ * @param ivpkM - The public counterpart to the secret key to be used in the decryption of incoming note logs.
18
+ * @param ovpkM - The public counterpart to the secret key to be used in the decryption of outgoing note logs.
15
19
  * @param payload - An instance of l1NotePayload.
16
20
  * @param txHash - The hash of the transaction that created the note. Equivalent to the first nullifier of the transaction.
17
21
  * @param newNoteHashes - New note hashes in this transaction, one of which belongs to this note.
18
22
  * @param dataStartIndexForTx - The next available leaf index for the note hash tree for this transaction.
19
23
  * @param excludedIndices - Indices that have been assigned a note in the same tx. Notes in a tx can have the same l1NotePayload, we need to find a different index for each replicate.
20
24
  * @param simulator - An instance of AcirSimulator.
21
- * @returns an instance of NoteDao, or throws. inserts the index of the note into the excludedIndices set.
25
+ * @returns An object containing the incoming, outgoing, and deferred notes.
22
26
  */
23
- export async function produceNoteDao(
27
+ export async function produceNoteDaos(
24
28
  simulator: AcirSimulator,
25
- publicKey: PublicKey,
29
+ ivpkM: PublicKey | undefined,
30
+ ovpkM: PublicKey | undefined,
26
31
  payload: L1NotePayload,
27
32
  txHash: TxHash,
28
33
  newNoteHashes: Fr[],
29
34
  dataStartIndexForTx: number,
30
35
  excludedIndices: Set<number>,
31
- ): Promise<NoteDao> {
32
- const { commitmentIndex, nonce, innerNoteHash, siloedNullifier } = await findNoteIndexAndNullifier(
33
- simulator,
34
- newNoteHashes,
35
- txHash,
36
- payload,
37
- excludedIndices,
38
- );
39
- const index = BigInt(dataStartIndexForTx + commitmentIndex);
40
- excludedIndices?.add(commitmentIndex);
41
- return new NoteDao(
42
- payload.note,
43
- payload.contractAddress,
44
- payload.storageSlot,
45
- payload.noteTypeId,
46
- txHash,
47
- nonce,
48
- innerNoteHash,
49
- siloedNullifier,
50
- index,
51
- publicKey,
52
- );
36
+ log: Logger,
37
+ ): Promise<{
38
+ incomingNote: IncomingNoteDao | undefined;
39
+ outgoingNote: OutgoingNoteDao | undefined;
40
+ incomingDeferredNote: DeferredNoteDao | undefined;
41
+ outgoingDeferredNote: DeferredNoteDao | undefined;
42
+ }> {
43
+ if (!ivpkM && !ovpkM) {
44
+ throw new Error('Both ivpkM and ovpkM are undefined. Cannot create note.');
45
+ }
46
+
47
+ let incomingNote: IncomingNoteDao | undefined;
48
+ let outgoingNote: OutgoingNoteDao | undefined;
49
+ let incomingDeferredNote: DeferredNoteDao | undefined;
50
+ let outgoingDeferredNote: DeferredNoteDao | undefined;
51
+
52
+ try {
53
+ if (ivpkM) {
54
+ const { noteHashIndex, nonce, innerNoteHash, siloedNullifier } = await findNoteIndexAndNullifier(
55
+ simulator,
56
+ newNoteHashes,
57
+ txHash,
58
+ payload,
59
+ excludedIndices,
60
+ true, // For incoming we compute a nullifier (recipient of incoming is the party that nullifies).
61
+ );
62
+ const index = BigInt(dataStartIndexForTx + noteHashIndex);
63
+ excludedIndices?.add(noteHashIndex);
64
+
65
+ incomingNote = new IncomingNoteDao(
66
+ payload.note,
67
+ payload.contractAddress,
68
+ payload.storageSlot,
69
+ payload.noteTypeId,
70
+ txHash,
71
+ nonce,
72
+ innerNoteHash,
73
+ siloedNullifier,
74
+ index,
75
+ ivpkM,
76
+ );
77
+ }
78
+ } catch (e) {
79
+ if (e instanceof ContractNotFoundError) {
80
+ log.warn(e.message);
81
+
82
+ if (ivpkM) {
83
+ incomingDeferredNote = new DeferredNoteDao(
84
+ ivpkM,
85
+ payload.note,
86
+ payload.contractAddress,
87
+ payload.storageSlot,
88
+ payload.noteTypeId,
89
+ txHash,
90
+ newNoteHashes,
91
+ dataStartIndexForTx,
92
+ );
93
+ }
94
+ } else {
95
+ log.error(`Could not process note because of "${e}". Discarding note...`);
96
+ }
97
+ }
98
+
99
+ try {
100
+ if (ovpkM) {
101
+ if (incomingNote) {
102
+ // Incoming note is defined meaning that this PXE has both the incoming and outgoing keys. We can skip computing
103
+ // note hash and note index since we already have them in the incoming note.
104
+ outgoingNote = new OutgoingNoteDao(
105
+ payload.note,
106
+ payload.contractAddress,
107
+ payload.storageSlot,
108
+ payload.noteTypeId,
109
+ txHash,
110
+ incomingNote.nonce,
111
+ incomingNote.innerNoteHash,
112
+ incomingNote.index,
113
+ ovpkM,
114
+ );
115
+ } else {
116
+ const { noteHashIndex, nonce, innerNoteHash } = await findNoteIndexAndNullifier(
117
+ simulator,
118
+ newNoteHashes,
119
+ txHash,
120
+ payload,
121
+ excludedIndices,
122
+ false, // For outgoing we do not compute a nullifier.
123
+ );
124
+ const index = BigInt(dataStartIndexForTx + noteHashIndex);
125
+ excludedIndices?.add(noteHashIndex);
126
+ outgoingNote = new OutgoingNoteDao(
127
+ payload.note,
128
+ payload.contractAddress,
129
+ payload.storageSlot,
130
+ payload.noteTypeId,
131
+ txHash,
132
+ nonce,
133
+ innerNoteHash,
134
+ index,
135
+ ovpkM,
136
+ );
137
+ }
138
+ }
139
+ } catch (e) {
140
+ if (e instanceof ContractNotFoundError) {
141
+ log.warn(e.message);
142
+
143
+ if (ovpkM) {
144
+ outgoingDeferredNote = new DeferredNoteDao(
145
+ ovpkM,
146
+ payload.note,
147
+ payload.contractAddress,
148
+ payload.storageSlot,
149
+ payload.noteTypeId,
150
+ txHash,
151
+ newNoteHashes,
152
+ dataStartIndexForTx,
153
+ );
154
+ }
155
+ } else {
156
+ log.error(`Could not process note because of "${e}". Discarding note...`);
157
+ }
158
+ }
159
+
160
+ return {
161
+ incomingNote,
162
+ outgoingNote,
163
+ incomingDeferredNote,
164
+ outgoingDeferredNote,
165
+ };
53
166
  }
54
167
 
55
168
  /**
56
- * Find the index of the note in the note hash tree by computing the note hash with different nonce and see which
57
- * commitment for the current tx matches this value.
58
- * Compute a nullifier for a given l1NotePayload.
59
- * The nullifier is calculated using the private key of the account,
60
- * contract address, and the note associated with the l1NotePayload.
61
- * This method assists in identifying spent commitments in the private state.
62
- * @param commitments - Commitments in the tx. One of them should be the note's commitment.
63
- * @param txHash - First nullifier in the tx.
64
- * @param l1NotePayload - An instance of l1NotePayload.
169
+ * Finds nonce, index, inner hash and siloed nullifier for a given note.
170
+ * @dev Finds the index in the note hash tree by computing the note hash with different nonce and see which hash for
171
+ * the current tx matches this value.
172
+ * @remarks This method assists in identifying spent notes in the note hash tree.
173
+ * @param noteHashes - Note hashes in the tx. One of them should correspond to the note we are looking for
174
+ * @param txHash - Hash of a tx the note was emitted in.
175
+ * @param l1NotePayload - The note payload.
65
176
  * @param excludedIndices - Indices that have been assigned a note in the same tx. Notes in a tx can have the same
66
177
  * l1NotePayload. We need to find a different index for each replicate.
67
- * @returns Information for a decrypted note, including the index of its commitment, nonce, inner note
68
- * hash, and the siloed nullifier. Throw if cannot find the nonce for the note.
178
+ * @param computeNullifier - A flag indicating whether to compute the nullifier or just return 0.
179
+ * @returns Nonce, index, inner hash and siloed nullifier for a given note.
180
+ * @throws If cannot find the nonce for the note.
69
181
  */
70
182
  async function findNoteIndexAndNullifier(
71
183
  simulator: AcirSimulator,
72
- commitments: Fr[],
184
+ noteHashes: Fr[],
73
185
  txHash: TxHash,
74
186
  { contractAddress, storageSlot, noteTypeId, note }: L1NotePayload,
75
187
  excludedIndices: Set<number>,
188
+ computeNullifier: boolean,
76
189
  ) {
77
- let commitmentIndex = 0;
190
+ let noteHashIndex = 0;
78
191
  let nonce: Fr | undefined;
79
192
  let innerNoteHash: Fr | undefined;
80
193
  let siloedNoteHash: Fr | undefined;
81
194
  let innerNullifier: Fr | undefined;
82
195
  const firstNullifier = Fr.fromBuffer(txHash.toBuffer());
83
196
 
84
- for (; commitmentIndex < commitments.length; ++commitmentIndex) {
85
- if (excludedIndices.has(commitmentIndex)) {
197
+ for (; noteHashIndex < noteHashes.length; ++noteHashIndex) {
198
+ if (excludedIndices.has(noteHashIndex)) {
86
199
  continue;
87
200
  }
88
201
 
89
- const commitment = commitments[commitmentIndex];
90
- if (commitment.equals(Fr.ZERO)) {
202
+ const noteHash = noteHashes[noteHashIndex];
203
+ if (noteHash.equals(Fr.ZERO)) {
91
204
  break;
92
205
  }
93
206
 
94
- const expectedNonce = computeNoteHashNonce(firstNullifier, commitmentIndex);
95
- ({ innerNoteHash, siloedNoteHash, innerNullifier } = await simulator.computeNoteHashAndNullifier(
207
+ const expectedNonce = computeNoteHashNonce(firstNullifier, noteHashIndex);
208
+ ({ innerNoteHash, siloedNoteHash, innerNullifier } = await simulator.computeNoteHashAndOptionallyANullifier(
96
209
  contractAddress,
97
210
  expectedNonce,
98
211
  storageSlot,
99
212
  noteTypeId,
213
+ computeNullifier,
100
214
  note,
101
215
  ));
102
216
 
103
- if (commitment.equals(siloedNoteHash)) {
217
+ if (noteHash.equals(siloedNoteHash)) {
104
218
  nonce = expectedNonce;
105
219
  break;
106
220
  }
@@ -109,11 +223,11 @@ async function findNoteIndexAndNullifier(
109
223
  if (!nonce) {
110
224
  // NB: this used to warn the user that a decrypted log didn't match any notes.
111
225
  // This was previously fine as we didn't chop transient note logs, but now we do (#1641 complete).
112
- throw new Error('Cannot find a matching commitment for the note.');
226
+ throw new Error('Cannot find a matching note hash for the note.');
113
227
  }
114
228
 
115
229
  return {
116
- commitmentIndex,
230
+ noteHashIndex,
117
231
  nonce,
118
232
  innerNoteHash: innerNoteHash!,
119
233
  siloedNullifier: siloNullifier(contractAddress, innerNullifier!),
@@ -18,6 +18,7 @@ import {
18
18
  UnencryptedL2BlockL2Logs,
19
19
  } from '@aztec/circuit-types';
20
20
  import { FunctionSelector } from '@aztec/circuits.js';
21
+ import { NoteSelector } from '@aztec/foundation/abi';
21
22
  import { AztecAddress } from '@aztec/foundation/aztec-address';
22
23
  import { EthAddress } from '@aztec/foundation/eth-address';
23
24
  import { Fr, GrumpkinScalar, Point } from '@aztec/foundation/fields';
@@ -49,6 +50,7 @@ export function createPXERpcServer(pxeService: PXE): JsonRpcServer {
49
50
  L2Block,
50
51
  TxEffect,
51
52
  LogId,
53
+ NoteSelector,
52
54
  },
53
55
  { SimulatedTx, Tx, TxReceipt, EncryptedNoteL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness },
54
56
  ['start', 'stop'],
@@ -5,6 +5,7 @@ import { createDebugLogger } from '@aztec/foundation/log';
5
5
  import { KeyStore } from '@aztec/key-store';
6
6
  import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
7
7
  import { initStoreForRollup } from '@aztec/kv-store/utils';
8
+ import { getCanonicalAuthRegistry } from '@aztec/protocol-contracts/auth-registry';
8
9
  import { getCanonicalClassRegisterer } from '@aztec/protocol-contracts/class-registerer';
9
10
  import { getCanonicalGasToken } from '@aztec/protocol-contracts/gas-token';
10
11
  import { getCanonicalInstanceDeployer } from '@aztec/protocol-contracts/instance-deployer';
@@ -67,6 +68,7 @@ export async function createPXEService(
67
68
  getCanonicalMultiCallEntrypointContract(),
68
69
  getCanonicalGasToken(),
69
70
  getCanonicalKeyRegistry(),
71
+ getCanonicalAuthRegistry(),
70
72
  ]) {
71
73
  await server.registerContract(contract);
72
74
  }