@aztec/pxe 0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2 → 0.75.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 (101) hide show
  1. package/dest/bin/index.d.ts +3 -0
  2. package/dest/bin/index.d.ts.map +1 -0
  3. package/dest/bin/index.js +5 -3
  4. package/dest/config/index.d.ts +46 -0
  5. package/dest/config/index.d.ts.map +1 -0
  6. package/dest/config/index.js +21 -18
  7. package/dest/config/package_info.d.ts +5 -0
  8. package/dest/config/package_info.d.ts.map +1 -0
  9. package/dest/config/package_info.js +2 -4
  10. package/dest/contract_data_oracle/index.d.ts +104 -0
  11. package/dest/contract_data_oracle/index.d.ts.map +1 -0
  12. package/dest/contract_data_oracle/index.js +79 -69
  13. package/dest/contract_data_oracle/private_functions_tree.d.ts +65 -0
  14. package/dest/contract_data_oracle/private_functions_tree.d.ts.map +1 -0
  15. package/dest/contract_data_oracle/private_functions_tree.js +50 -44
  16. package/dest/database/contracts/contract_artifact_db.d.ts +20 -0
  17. package/dest/database/contracts/contract_artifact_db.d.ts.map +1 -0
  18. package/dest/database/contracts/contract_artifact_db.js +2 -3
  19. package/dest/database/contracts/contract_instance_db.d.ts +19 -0
  20. package/dest/database/contracts/contract_instance_db.d.ts.map +1 -0
  21. package/dest/database/contracts/contract_instance_db.js +2 -3
  22. package/dest/database/index.d.ts +3 -0
  23. package/dest/database/index.d.ts.map +1 -0
  24. package/dest/database/index.js +1 -0
  25. package/dest/database/kv_pxe_database.d.ts +55 -0
  26. package/dest/database/kv_pxe_database.d.ts.map +1 -0
  27. package/dest/database/kv_pxe_database.js +259 -243
  28. package/dest/database/note_dao.d.ts +103 -0
  29. package/dest/database/note_dao.d.ts.map +1 -0
  30. package/dest/database/note_dao.js +43 -28
  31. package/dest/database/outgoing_note_dao.d.ts +73 -0
  32. package/dest/database/outgoing_note_dao.d.ts.map +1 -0
  33. package/dest/database/outgoing_note_dao.js +34 -20
  34. package/dest/database/pxe_database.d.ts +216 -0
  35. package/dest/database/pxe_database.d.ts.map +1 -0
  36. package/dest/database/pxe_database.js +2 -4
  37. package/dest/database/pxe_database_test_suite.d.ts +7 -0
  38. package/dest/database/pxe_database_test_suite.d.ts.map +1 -0
  39. package/dest/database/pxe_database_test_suite.js +151 -296
  40. package/dest/index.d.ts +15 -0
  41. package/dest/index.d.ts.map +1 -0
  42. package/dest/index.js +1 -0
  43. package/dest/kernel_oracle/index.d.ts +34 -0
  44. package/dest/kernel_oracle/index.d.ts.map +1 -0
  45. package/dest/kernel_oracle/index.js +6 -9
  46. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts +28 -0
  47. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -0
  48. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.js +66 -68
  49. package/dest/kernel_prover/hints/index.d.ts +2 -0
  50. package/dest/kernel_prover/hints/index.d.ts.map +1 -0
  51. package/dest/kernel_prover/hints/index.js +1 -0
  52. package/dest/kernel_prover/index.d.ts +3 -0
  53. package/dest/kernel_prover/index.d.ts.map +1 -0
  54. package/dest/kernel_prover/index.js +1 -0
  55. package/dest/kernel_prover/kernel_prover.d.ts +38 -0
  56. package/dest/kernel_prover/kernel_prover.d.ts.map +1 -0
  57. package/dest/kernel_prover/kernel_prover.js +65 -60
  58. package/dest/kernel_prover/proving_data_oracle.d.ts +65 -0
  59. package/dest/kernel_prover/proving_data_oracle.d.ts.map +1 -0
  60. package/dest/kernel_prover/proving_data_oracle.js +2 -4
  61. package/dest/note_decryption_utils/add_public_values_to_payload.d.ts +10 -0
  62. package/dest/note_decryption_utils/add_public_values_to_payload.d.ts.map +1 -0
  63. package/dest/note_decryption_utils/add_public_values_to_payload.js +9 -8
  64. package/dest/pxe_http/index.d.ts +2 -0
  65. package/dest/pxe_http/index.d.ts.map +1 -0
  66. package/dest/pxe_http/index.js +1 -0
  67. package/dest/pxe_http/pxe_http_server.d.ts +16 -0
  68. package/dest/pxe_http/pxe_http_server.d.ts.map +1 -0
  69. package/dest/pxe_http/pxe_http_server.js +6 -8
  70. package/dest/pxe_service/error_enriching.d.ts +11 -0
  71. package/dest/pxe_service/error_enriching.d.ts.map +1 -0
  72. package/dest/pxe_service/error_enriching.js +13 -10
  73. package/dest/pxe_service/index.d.ts +4 -0
  74. package/dest/pxe_service/index.d.ts.map +1 -0
  75. package/dest/pxe_service/index.js +1 -0
  76. package/dest/pxe_service/pxe_service.d.ts +98 -0
  77. package/dest/pxe_service/pxe_service.d.ts.map +1 -0
  78. package/dest/pxe_service/pxe_service.js +290 -282
  79. package/dest/pxe_service/test/pxe_test_suite.d.ts +3 -0
  80. package/dest/pxe_service/test/pxe_test_suite.d.ts.map +1 -0
  81. package/dest/pxe_service/test/pxe_test_suite.js +27 -40
  82. package/dest/simulator/index.d.ts +10 -0
  83. package/dest/simulator/index.d.ts.map +1 -0
  84. package/dest/simulator/index.js +3 -1
  85. package/dest/simulator_oracle/index.d.ts +129 -0
  86. package/dest/simulator_oracle/index.d.ts.map +1 -0
  87. package/dest/simulator_oracle/index.js +231 -266
  88. package/dest/simulator_oracle/tagging_utils.d.ts +16 -0
  89. package/dest/simulator_oracle/tagging_utils.d.ts.map +1 -0
  90. package/dest/simulator_oracle/tagging_utils.js +6 -4
  91. package/dest/synchronizer/index.d.ts +2 -0
  92. package/dest/synchronizer/index.d.ts.map +1 -0
  93. package/dest/synchronizer/index.js +1 -0
  94. package/dest/synchronizer/synchronizer.d.ts +30 -0
  95. package/dest/synchronizer/synchronizer.d.ts.map +1 -0
  96. package/dest/synchronizer/synchronizer.js +42 -42
  97. package/dest/utils/create_pxe_service.d.ts +16 -0
  98. package/dest/utils/create_pxe_service.d.ts.map +1 -0
  99. package/dest/utils/create_pxe_service.js +9 -9
  100. package/package.json +15 -15
  101. package/src/pxe_service/pxe_service.ts +10 -5
@@ -1,5 +1,5 @@
1
1
  import { NoteStatus, randomTxHash } from '@aztec/circuit-types';
2
- import { AztecAddress, CompleteAddress, INITIAL_L2_BLOCK_NUM, PublicKeys, SerializableContractInstance } from '@aztec/circuits.js';
2
+ import { AztecAddress, CompleteAddress, INITIAL_L2_BLOCK_NUM, PublicKeys, SerializableContractInstance, } from '@aztec/circuits.js';
3
3
  import { makeHeader } from '@aztec/circuits.js/testing';
4
4
  import { FunctionType } from '@aztec/foundation/abi';
5
5
  import { timesParallel } from '@aztec/foundation/collection';
@@ -12,441 +12,339 @@ import { NoteDao } from './note_dao.js';
12
12
  /**
13
13
  * A common test suite for a PXE database.
14
14
  * @param getDatabase - A function that returns a database instance.
15
- */ export function describePxeDatabase(getDatabase) {
15
+ */
16
+ export function describePxeDatabase(getDatabase) {
16
17
  let database;
17
- beforeEach(()=>{
18
+ beforeEach(() => {
18
19
  database = getDatabase();
19
20
  });
20
- describe('Database', ()=>{
21
- describe('auth witnesses', ()=>{
22
- it('stores and retrieves auth witnesses', async ()=>{
21
+ describe('Database', () => {
22
+ describe('auth witnesses', () => {
23
+ it('stores and retrieves auth witnesses', async () => {
23
24
  const messageHash = Fr.random();
24
- const witness = [
25
- Fr.random(),
26
- Fr.random()
27
- ];
25
+ const witness = [Fr.random(), Fr.random()];
28
26
  await database.addAuthWitness(messageHash, witness);
29
27
  await expect(database.getAuthWitness(messageHash)).resolves.toEqual(witness);
30
28
  });
31
- it("returns undefined if it doesn't have auth witnesses for the message", async ()=>{
29
+ it("returns undefined if it doesn't have auth witnesses for the message", async () => {
32
30
  const messageHash = Fr.random();
33
31
  await expect(database.getAuthWitness(messageHash)).resolves.toBeUndefined();
34
32
  });
35
- it.skip('refuses to overwrite auth witnesses for the same message', async ()=>{
33
+ it.skip('refuses to overwrite auth witnesses for the same message', async () => {
36
34
  const messageHash = Fr.random();
37
- const witness = [
38
- Fr.random(),
39
- Fr.random()
40
- ];
35
+ const witness = [Fr.random(), Fr.random()];
41
36
  await database.addAuthWitness(messageHash, witness);
42
37
  await expect(database.addAuthWitness(messageHash, witness)).rejects.toThrow();
43
38
  });
44
39
  });
45
- describe('capsules', ()=>{
46
- it('stores and retrieves capsules', async ()=>{
47
- const capsule = [
48
- Fr.random(),
49
- Fr.random()
50
- ];
40
+ describe('capsules', () => {
41
+ it('stores and retrieves capsules', async () => {
42
+ const capsule = [Fr.random(), Fr.random()];
51
43
  await database.addCapsule(capsule);
52
44
  await expect(database.popCapsule()).resolves.toEqual(capsule);
53
45
  });
54
- it("returns undefined if it doesn't have capsules", async ()=>{
46
+ it("returns undefined if it doesn't have capsules", async () => {
55
47
  await expect(database.popCapsule()).resolves.toBeUndefined();
56
48
  });
57
- it('behaves like a stack when storing capsules', async ()=>{
58
- const capsule1 = [
59
- Fr.random(),
60
- Fr.random()
61
- ];
62
- const capsule2 = [
63
- Fr.random(),
64
- Fr.random()
65
- ];
49
+ it('behaves like a stack when storing capsules', async () => {
50
+ const capsule1 = [Fr.random(), Fr.random()];
51
+ const capsule2 = [Fr.random(), Fr.random()];
66
52
  await database.addCapsule(capsule1);
67
53
  await database.addCapsule(capsule2);
68
54
  await expect(database.popCapsule()).resolves.toEqual(capsule2);
69
55
  await expect(database.popCapsule()).resolves.toEqual(capsule1);
70
56
  });
71
57
  });
72
- describe('incoming notes', ()=>{
58
+ describe('incoming notes', () => {
73
59
  let owners;
74
60
  let contractAddresses;
75
61
  let storageSlots;
76
62
  let notes;
77
63
  const filteringTests = [
64
+ [() => Promise.resolve({}), () => Promise.resolve(notes)],
78
65
  [
79
- ()=>Promise.resolve({}),
80
- ()=>Promise.resolve(notes)
66
+ () => Promise.resolve({ contractAddress: contractAddresses[0] }),
67
+ () => Promise.resolve(notes.filter(note => note.contractAddress.equals(contractAddresses[0]))),
81
68
  ],
69
+ [async () => ({ contractAddress: await AztecAddress.random() }), () => Promise.resolve([])],
82
70
  [
83
- ()=>Promise.resolve({
84
- contractAddress: contractAddresses[0]
85
- }),
86
- ()=>Promise.resolve(notes.filter((note)=>note.contractAddress.equals(contractAddresses[0])))
71
+ () => Promise.resolve({ storageSlot: storageSlots[0] }),
72
+ () => Promise.resolve(notes.filter(note => note.storageSlot.equals(storageSlots[0]))),
87
73
  ],
74
+ [() => Promise.resolve({ storageSlot: Fr.random() }), () => Promise.resolve([])],
75
+ [() => Promise.resolve({ txHash: notes[0].txHash }), () => Promise.resolve([notes[0]])],
76
+ [() => Promise.resolve({ txHash: randomTxHash() }), () => Promise.resolve([])],
88
77
  [
89
- async ()=>({
90
- contractAddress: await AztecAddress.random()
91
- }),
92
- ()=>Promise.resolve([])
93
- ],
94
- [
95
- ()=>Promise.resolve({
96
- storageSlot: storageSlots[0]
97
- }),
98
- ()=>Promise.resolve(notes.filter((note)=>note.storageSlot.equals(storageSlots[0])))
99
- ],
100
- [
101
- ()=>Promise.resolve({
102
- storageSlot: Fr.random()
103
- }),
104
- ()=>Promise.resolve([])
105
- ],
106
- [
107
- ()=>Promise.resolve({
108
- txHash: notes[0].txHash
109
- }),
110
- ()=>Promise.resolve([
111
- notes[0]
112
- ])
113
- ],
114
- [
115
- ()=>Promise.resolve({
116
- txHash: randomTxHash()
117
- }),
118
- ()=>Promise.resolve([])
119
- ],
120
- [
121
- ()=>Promise.resolve({
122
- owner: owners[0].address
123
- }),
124
- async ()=>{
78
+ () => Promise.resolve({ owner: owners[0].address }),
79
+ async () => {
125
80
  const ownerAddressPoint = await owners[0].address.toAddressPoint();
126
- return notes.filter((note)=>note.addressPoint.equals(ownerAddressPoint));
127
- }
81
+ return notes.filter(note => note.addressPoint.equals(ownerAddressPoint));
82
+ },
128
83
  ],
129
84
  [
130
- ()=>Promise.resolve({
131
- contractAddress: contractAddresses[0],
132
- storageSlot: storageSlots[0]
133
- }),
134
- ()=>Promise.resolve(notes.filter((note)=>note.contractAddress.equals(contractAddresses[0]) && note.storageSlot.equals(storageSlots[0])))
85
+ () => Promise.resolve({ contractAddress: contractAddresses[0], storageSlot: storageSlots[0] }),
86
+ () => Promise.resolve(notes.filter(note => note.contractAddress.equals(contractAddresses[0]) && note.storageSlot.equals(storageSlots[0]))),
135
87
  ],
136
88
  [
137
- ()=>Promise.resolve({
138
- contractAddress: contractAddresses[0],
139
- storageSlot: storageSlots[1]
140
- }),
141
- ()=>Promise.resolve([])
142
- ]
89
+ () => Promise.resolve({ contractAddress: contractAddresses[0], storageSlot: storageSlots[1] }),
90
+ () => Promise.resolve([]),
91
+ ],
143
92
  ];
144
- beforeEach(async ()=>{
145
- owners = await timesParallel(2, ()=>CompleteAddress.random());
146
- contractAddresses = await timesParallel(2, ()=>AztecAddress.random());
147
- storageSlots = times(2, ()=>Fr.random());
148
- notes = await timesParallel(10, async (i)=>{
93
+ beforeEach(async () => {
94
+ owners = await timesParallel(2, () => CompleteAddress.random());
95
+ contractAddresses = await timesParallel(2, () => AztecAddress.random());
96
+ storageSlots = times(2, () => Fr.random());
97
+ notes = await timesParallel(10, async (i) => {
149
98
  const addressPoint = await owners[i % owners.length].address.toAddressPoint();
150
99
  return NoteDao.random({
151
100
  contractAddress: contractAddresses[i % contractAddresses.length],
152
101
  storageSlot: storageSlots[i % storageSlots.length],
153
102
  addressPoint,
154
103
  index: BigInt(i),
155
- l2BlockNumber: i
104
+ l2BlockNumber: i,
156
105
  });
157
106
  });
158
- for (const owner of owners){
107
+ for (const owner of owners) {
159
108
  await database.addCompleteAddress(owner);
160
109
  }
161
110
  });
162
- it.each(filteringTests)('stores notes in bulk and retrieves notes', async (getFilter, getExpected)=>{
111
+ it.each(filteringTests)('stores notes in bulk and retrieves notes', async (getFilter, getExpected) => {
163
112
  await database.addNotes(notes);
164
113
  const returnedNotes = await database.getNotes(await getFilter());
165
114
  const expected = await getExpected();
166
115
  expect(returnedNotes.sort()).toEqual(expected.sort());
167
116
  });
168
- it.each(filteringTests)('stores notes one by one and retrieves notes', async (getFilter, getExpected)=>{
169
- for (const note of notes){
117
+ it.each(filteringTests)('stores notes one by one and retrieves notes', async (getFilter, getExpected) => {
118
+ for (const note of notes) {
170
119
  await database.addNote(note);
171
120
  }
172
121
  const returnedNotes = await database.getNotes(await getFilter());
173
122
  const expected = await getExpected();
174
123
  expect(returnedNotes.sort()).toEqual(expected.sort());
175
124
  });
176
- it.each(filteringTests)('retrieves nullified notes', async (getFilter, getExpected)=>{
125
+ it.each(filteringTests)('retrieves nullified notes', async (getFilter, getExpected) => {
177
126
  await database.addNotes(notes);
178
127
  // Nullify all notes and use the same filter as other test cases
179
- for (const owner of owners){
128
+ for (const owner of owners) {
180
129
  const ownerAddressPoint = await owner.address.toAddressPoint();
181
- const notesToNullify = notes.filter((note)=>note.addressPoint.equals(ownerAddressPoint));
182
- const nullifiers = notesToNullify.map((note)=>({
183
- data: note.siloedNullifier,
184
- l2BlockNumber: note.l2BlockNumber,
185
- l2BlockHash: note.l2BlockHash
186
- }));
130
+ const notesToNullify = notes.filter(note => note.addressPoint.equals(ownerAddressPoint));
131
+ const nullifiers = notesToNullify.map(note => ({
132
+ data: note.siloedNullifier,
133
+ l2BlockNumber: note.l2BlockNumber,
134
+ l2BlockHash: note.l2BlockHash,
135
+ }));
187
136
  await expect(database.removeNullifiedNotes(nullifiers, ownerAddressPoint)).resolves.toEqual(notesToNullify);
188
137
  }
189
138
  const filter = await getFilter();
190
- const returnedNotes = await database.getNotes({
191
- ...filter,
192
- status: NoteStatus.ACTIVE_OR_NULLIFIED
193
- });
139
+ const returnedNotes = await database.getNotes({ ...filter, status: NoteStatus.ACTIVE_OR_NULLIFIED });
194
140
  const expected = await getExpected();
195
141
  expect(returnedNotes.sort()).toEqual(expected.sort());
196
142
  });
197
- it('skips nullified notes by default or when requesting active', async ()=>{
143
+ it('skips nullified notes by default or when requesting active', async () => {
198
144
  await database.addNotes(notes);
199
145
  const ownerAddressPoint = await owners[0].address.toAddressPoint();
200
- const notesToNullify = notes.filter((note)=>note.addressPoint.equals(ownerAddressPoint));
201
- const nullifiers = notesToNullify.map((note)=>({
202
- data: note.siloedNullifier,
203
- l2BlockNumber: note.l2BlockNumber,
204
- l2BlockHash: note.l2BlockHash
205
- }));
146
+ const notesToNullify = notes.filter(note => note.addressPoint.equals(ownerAddressPoint));
147
+ const nullifiers = notesToNullify.map(note => ({
148
+ data: note.siloedNullifier,
149
+ l2BlockNumber: note.l2BlockNumber,
150
+ l2BlockHash: note.l2BlockHash,
151
+ }));
206
152
  await expect(database.removeNullifiedNotes(nullifiers, notesToNullify[0].addressPoint)).resolves.toEqual(notesToNullify);
207
153
  const actualNotesWithDefault = await database.getNotes({});
208
- const actualNotesWithActive = await database.getNotes({
209
- status: NoteStatus.ACTIVE
210
- });
154
+ const actualNotesWithActive = await database.getNotes({ status: NoteStatus.ACTIVE });
211
155
  expect(actualNotesWithDefault).toEqual(actualNotesWithActive);
212
- expect(actualNotesWithActive).toEqual(notes.filter((note)=>!notesToNullify.includes(note)));
156
+ expect(actualNotesWithActive).toEqual(notes.filter(note => !notesToNullify.includes(note)));
213
157
  });
214
- it('handles note unnullification', async ()=>{
215
- await database.setHeader(makeHeader(randomInt(1000), 100, 0 /** slot number */ ));
158
+ it('handles note unnullification', async () => {
159
+ await database.setHeader(makeHeader(randomInt(1000), 100, 0 /** slot number */));
216
160
  await database.addNotes(notes);
217
161
  const ownerAddressPoint = await owners[0].address.toAddressPoint();
218
- const notesToNullify = notes.filter((note)=>note.addressPoint.equals(ownerAddressPoint));
219
- const nullifiers = notesToNullify.map((note)=>({
220
- data: note.siloedNullifier,
221
- l2BlockNumber: 99,
222
- l2BlockHash: Fr.random().toString()
223
- }));
162
+ const notesToNullify = notes.filter(note => note.addressPoint.equals(ownerAddressPoint));
163
+ const nullifiers = notesToNullify.map(note => ({
164
+ data: note.siloedNullifier,
165
+ l2BlockNumber: 99,
166
+ l2BlockHash: Fr.random().toString(),
167
+ }));
224
168
  await expect(database.removeNullifiedNotes(nullifiers, notesToNullify[0].addressPoint)).resolves.toEqual(notesToNullify);
225
169
  await expect(database.unnullifyNotesAfter(98)).resolves.toEqual(undefined);
226
- const result = await database.getNotes({
227
- status: NoteStatus.ACTIVE,
228
- owner: owners[0].address
229
- });
230
- expect(result.sort()).toEqual([
231
- ...notesToNullify
232
- ].sort());
170
+ const result = await database.getNotes({ status: NoteStatus.ACTIVE, owner: owners[0].address });
171
+ expect(result.sort()).toEqual([...notesToNullify].sort());
233
172
  });
234
- it('returns active and nullified notes when requesting either', async ()=>{
173
+ it('returns active and nullified notes when requesting either', async () => {
235
174
  await database.addNotes(notes);
236
175
  const ownerAddressPoint = await owners[0].address.toAddressPoint();
237
- const notesToNullify = notes.filter((note)=>note.addressPoint.equals(ownerAddressPoint));
238
- const nullifiers = notesToNullify.map((note)=>({
239
- data: note.siloedNullifier,
240
- l2BlockNumber: note.l2BlockNumber,
241
- l2BlockHash: note.l2BlockHash
242
- }));
176
+ const notesToNullify = notes.filter(note => note.addressPoint.equals(ownerAddressPoint));
177
+ const nullifiers = notesToNullify.map(note => ({
178
+ data: note.siloedNullifier,
179
+ l2BlockNumber: note.l2BlockNumber,
180
+ l2BlockHash: note.l2BlockHash,
181
+ }));
243
182
  await expect(database.removeNullifiedNotes(nullifiers, notesToNullify[0].addressPoint)).resolves.toEqual(notesToNullify);
244
183
  const result = await database.getNotes({
245
- status: NoteStatus.ACTIVE_OR_NULLIFIED
184
+ status: NoteStatus.ACTIVE_OR_NULLIFIED,
246
185
  });
247
186
  // We have to compare the sorted arrays since the database does not return the same order as when originally
248
187
  // inserted combining active and nullified results.
249
- expect(result.sort()).toEqual([
250
- ...notes
251
- ].sort());
188
+ expect(result.sort()).toEqual([...notes].sort());
252
189
  });
253
- it('stores notes one by one and retrieves notes with siloed account', async ()=>{
254
- for (const note of notes.slice(0, 5)){
190
+ it('stores notes one by one and retrieves notes with siloed account', async () => {
191
+ for (const note of notes.slice(0, 5)) {
255
192
  await database.addNote(note, owners[0].address);
256
193
  }
257
- for (const note of notes.slice(5)){
194
+ for (const note of notes.slice(5)) {
258
195
  await database.addNote(note, owners[1].address);
259
196
  }
260
197
  const owner0Notes = await database.getNotes({
261
- scopes: [
262
- owners[0].address
263
- ]
198
+ scopes: [owners[0].address],
264
199
  });
265
200
  expect(owner0Notes.sort()).toEqual(notes.slice(0, 5).sort());
266
201
  const owner1Notes = await database.getNotes({
267
- scopes: [
268
- owners[1].address
269
- ]
202
+ scopes: [owners[1].address],
270
203
  });
271
204
  expect(owner1Notes.sort()).toEqual(notes.slice(5).sort());
272
205
  const bothOwnerNotes = await database.getNotes({
273
- scopes: [
274
- owners[0].address,
275
- owners[1].address
276
- ]
206
+ scopes: [owners[0].address, owners[1].address],
277
207
  });
278
208
  expect(bothOwnerNotes.sort()).toEqual(notes.sort());
279
209
  });
280
- it('a nullified note removes notes from all accounts in the pxe', async ()=>{
210
+ it('a nullified note removes notes from all accounts in the pxe', async () => {
281
211
  await database.addNote(notes[0], owners[0].address);
282
212
  await database.addNote(notes[0], owners[1].address);
283
213
  await expect(database.getNotes({
284
- scopes: [
285
- owners[0].address
286
- ]
287
- })).resolves.toEqual([
288
- notes[0]
289
- ]);
214
+ scopes: [owners[0].address],
215
+ })).resolves.toEqual([notes[0]]);
290
216
  await expect(database.getNotes({
291
- scopes: [
292
- owners[1].address
293
- ]
294
- })).resolves.toEqual([
295
- notes[0]
296
- ]);
217
+ scopes: [owners[1].address],
218
+ })).resolves.toEqual([notes[0]]);
297
219
  const ownerAddressPoint = await owners[0].address.toAddressPoint();
298
220
  await expect(database.removeNullifiedNotes([
299
221
  {
300
222
  data: notes[0].siloedNullifier,
301
223
  l2BlockHash: notes[0].l2BlockHash,
302
- l2BlockNumber: notes[0].l2BlockNumber
303
- }
304
- ], ownerAddressPoint)).resolves.toEqual([
305
- notes[0]
306
- ]);
224
+ l2BlockNumber: notes[0].l2BlockNumber,
225
+ },
226
+ ], ownerAddressPoint)).resolves.toEqual([notes[0]]);
307
227
  await expect(database.getNotes({
308
- scopes: [
309
- owners[0].address
310
- ]
228
+ scopes: [owners[0].address],
311
229
  })).resolves.toEqual([]);
312
230
  await expect(database.getNotes({
313
- scopes: [
314
- owners[1].address
315
- ]
231
+ scopes: [owners[1].address],
316
232
  })).resolves.toEqual([]);
317
233
  });
318
- it('removes notes after a given block', async ()=>{
234
+ it('removes notes after a given block', async () => {
319
235
  await database.addNotes(notes, owners[0].address);
320
236
  await database.removeNotesAfter(5);
321
- const result = await database.getNotes({
322
- scopes: [
323
- owners[0].address
324
- ]
325
- });
237
+ const result = await database.getNotes({ scopes: [owners[0].address] });
326
238
  expect(new Set(result)).toEqual(new Set(notes.slice(0, 6)));
327
239
  });
328
240
  });
329
- describe('block header', ()=>{
330
- it('stores and retrieves the block header', async ()=>{
331
- const header = makeHeader(randomInt(1000), INITIAL_L2_BLOCK_NUM, 0 /** slot number */ );
241
+ describe('block header', () => {
242
+ it('stores and retrieves the block header', async () => {
243
+ const header = makeHeader(randomInt(1000), INITIAL_L2_BLOCK_NUM, 0 /** slot number */);
332
244
  await database.setHeader(header);
333
245
  await expect(database.getBlockHeader()).resolves.toEqual(header);
334
246
  });
335
- it('rejects getting header if no block set', async ()=>{
336
- await expect(()=>database.getBlockHeader()).rejects.toThrow();
247
+ it('rejects getting header if no block set', async () => {
248
+ await expect(() => database.getBlockHeader()).rejects.toThrow();
337
249
  });
338
250
  });
339
- describe('addresses', ()=>{
340
- it('stores and retrieves addresses', async ()=>{
251
+ describe('addresses', () => {
252
+ it('stores and retrieves addresses', async () => {
341
253
  const address = await CompleteAddress.random();
342
254
  await expect(database.addCompleteAddress(address)).resolves.toBe(true);
343
255
  await expect(database.getCompleteAddress(address.address)).resolves.toEqual(address);
344
256
  });
345
- it('silently ignores an address it already knows about', async ()=>{
257
+ it('silently ignores an address it already knows about', async () => {
346
258
  const address = await CompleteAddress.random();
347
259
  await expect(database.addCompleteAddress(address)).resolves.toBe(true);
348
260
  await expect(database.addCompleteAddress(address)).resolves.toBe(false);
349
261
  });
350
- it.skip('refuses to overwrite an address with a different public key', async ()=>{
262
+ it.skip('refuses to overwrite an address with a different public key', async () => {
351
263
  const address = await CompleteAddress.random();
352
264
  const otherAddress = await CompleteAddress.create(address.address, new PublicKeys(await Point.random(), await Point.random(), await Point.random(), await Point.random()), address.partialAddress);
353
265
  await database.addCompleteAddress(address);
354
266
  await expect(database.addCompleteAddress(otherAddress)).rejects.toThrow();
355
267
  });
356
- it('returns all addresses', async ()=>{
357
- const addresses = await timesParallel(10, ()=>CompleteAddress.random());
358
- for (const address of addresses){
268
+ it('returns all addresses', async () => {
269
+ const addresses = await timesParallel(10, () => CompleteAddress.random());
270
+ for (const address of addresses) {
359
271
  await database.addCompleteAddress(address);
360
272
  }
361
273
  const result = await database.getCompleteAddresses();
362
274
  expect(result).toEqual(expect.arrayContaining(addresses));
363
275
  });
364
- it('returns a single address', async ()=>{
365
- const addresses = await timesParallel(10, ()=>CompleteAddress.random());
366
- for (const address of addresses){
276
+ it('returns a single address', async () => {
277
+ const addresses = await timesParallel(10, () => CompleteAddress.random());
278
+ for (const address of addresses) {
367
279
  await database.addCompleteAddress(address);
368
280
  }
369
281
  const result = await database.getCompleteAddress(addresses[3].address);
370
282
  expect(result).toEqual(addresses[3]);
371
283
  });
372
- it("returns an empty array if it doesn't have addresses", async ()=>{
284
+ it("returns an empty array if it doesn't have addresses", async () => {
373
285
  expect(await database.getCompleteAddresses()).toEqual([]);
374
286
  });
375
- it("returns undefined if it doesn't have an address", async ()=>{
287
+ it("returns undefined if it doesn't have an address", async () => {
376
288
  const completeAddress = await CompleteAddress.random();
377
289
  expect(await database.getCompleteAddress(completeAddress.address)).toBeUndefined();
378
290
  });
379
291
  });
380
- describe('contracts', ()=>{
381
- it('stores a contract artifact', async ()=>{
292
+ describe('contracts', () => {
293
+ it('stores a contract artifact', async () => {
382
294
  const artifact = BenchmarkingContractArtifact;
383
295
  const id = Fr.random();
384
296
  await database.addContractArtifact(id, artifact);
385
297
  await expect(database.getContractArtifact(id)).resolves.toEqual(artifact);
386
298
  });
387
- it('does not store a contract artifact with a duplicate private function selector', async ()=>{
299
+ it('does not store a contract artifact with a duplicate private function selector', async () => {
388
300
  const artifact = TestContractArtifact;
389
- const index = artifact.functions.findIndex((fn)=>fn.functionType === FunctionType.PRIVATE);
301
+ const index = artifact.functions.findIndex(fn => fn.functionType === FunctionType.PRIVATE);
390
302
  const copiedFn = structuredClone(artifact.functions[index]);
391
303
  artifact.functions.push(copiedFn);
392
304
  const id = Fr.random();
393
305
  await expect(database.addContractArtifact(id, artifact)).rejects.toThrow('Repeated function selectors of private functions');
394
306
  });
395
- it('stores a contract instance', async ()=>{
307
+ it('stores a contract instance', async () => {
396
308
  const address = await AztecAddress.random();
397
309
  const instance = (await SerializableContractInstance.random()).withAddress(address);
398
310
  await database.addContractInstance(instance);
399
311
  await expect(database.getContractInstance(address)).resolves.toEqual(instance);
400
312
  });
401
313
  });
402
- describe('contract non-volatile database', ()=>{
314
+ describe('contract non-volatile database', () => {
403
315
  let contract;
404
- beforeEach(async ()=>{
316
+ beforeEach(async () => {
405
317
  // Setup mock contract address
406
318
  contract = await AztecAddress.random();
407
319
  });
408
- it('stores and loads a single value', async ()=>{
320
+ it('stores and loads a single value', async () => {
409
321
  const slot = new Fr(1);
410
- const values = [
411
- new Fr(42)
412
- ];
322
+ const values = [new Fr(42)];
413
323
  await database.dbStore(contract, slot, values);
414
324
  const result = await database.dbLoad(contract, slot);
415
325
  expect(result).toEqual(values);
416
326
  });
417
- it('stores and loads multiple values', async ()=>{
327
+ it('stores and loads multiple values', async () => {
418
328
  const slot = new Fr(1);
419
- const values = [
420
- new Fr(42),
421
- new Fr(43),
422
- new Fr(44)
423
- ];
329
+ const values = [new Fr(42), new Fr(43), new Fr(44)];
424
330
  await database.dbStore(contract, slot, values);
425
331
  const result = await database.dbLoad(contract, slot);
426
332
  expect(result).toEqual(values);
427
333
  });
428
- it('overwrites existing values', async ()=>{
334
+ it('overwrites existing values', async () => {
429
335
  const slot = new Fr(1);
430
- const initialValues = [
431
- new Fr(42)
432
- ];
433
- const newValues = [
434
- new Fr(100)
435
- ];
336
+ const initialValues = [new Fr(42)];
337
+ const newValues = [new Fr(100)];
436
338
  await database.dbStore(contract, slot, initialValues);
437
339
  await database.dbStore(contract, slot, newValues);
438
340
  const result = await database.dbLoad(contract, slot);
439
341
  expect(result).toEqual(newValues);
440
342
  });
441
- it('stores values for different contracts independently', async ()=>{
343
+ it('stores values for different contracts independently', async () => {
442
344
  const anotherContract = await AztecAddress.random();
443
345
  const slot = new Fr(1);
444
- const values1 = [
445
- new Fr(42)
446
- ];
447
- const values2 = [
448
- new Fr(100)
449
- ];
346
+ const values1 = [new Fr(42)];
347
+ const values2 = [new Fr(100)];
450
348
  await database.dbStore(contract, slot, values1);
451
349
  await database.dbStore(anotherContract, slot, values2);
452
350
  const result1 = await database.dbLoad(contract, slot);
@@ -454,48 +352,34 @@ import { NoteDao } from './note_dao.js';
454
352
  expect(result1).toEqual(values1);
455
353
  expect(result2).toEqual(values2);
456
354
  });
457
- it('returns null for non-existent slots', async ()=>{
355
+ it('returns null for non-existent slots', async () => {
458
356
  const slot = Fr.random();
459
357
  const result = await database.dbLoad(contract, slot);
460
358
  expect(result).toBeNull();
461
359
  });
462
- it('deletes a slot', async ()=>{
360
+ it('deletes a slot', async () => {
463
361
  const slot = new Fr(1);
464
- const values = [
465
- new Fr(42)
466
- ];
362
+ const values = [new Fr(42)];
467
363
  await database.dbStore(contract, slot, values);
468
364
  await database.dbDelete(contract, slot);
469
365
  expect(await database.dbLoad(contract, slot)).toBeNull();
470
366
  });
471
- it('deletes an empty slot', async ()=>{
367
+ it('deletes an empty slot', async () => {
472
368
  const slot = new Fr(1);
473
369
  await database.dbDelete(contract, slot);
474
370
  expect(await database.dbLoad(contract, slot)).toBeNull();
475
371
  });
476
- it('copies a single value', async ()=>{
372
+ it('copies a single value', async () => {
477
373
  const slot = new Fr(1);
478
- const values = [
479
- new Fr(42)
480
- ];
374
+ const values = [new Fr(42)];
481
375
  await database.dbStore(contract, slot, values);
482
376
  const dstSlot = new Fr(5);
483
377
  await database.dbCopy(contract, slot, dstSlot, 1);
484
378
  expect(await database.dbLoad(contract, dstSlot)).toEqual(values);
485
379
  });
486
- it('copies multiple non-overlapping values', async ()=>{
380
+ it('copies multiple non-overlapping values', async () => {
487
381
  const src = new Fr(1);
488
- const valuesArray = [
489
- [
490
- new Fr(42)
491
- ],
492
- [
493
- new Fr(1337)
494
- ],
495
- [
496
- new Fr(13)
497
- ]
498
- ];
382
+ const valuesArray = [[new Fr(42)], [new Fr(1337)], [new Fr(13)]];
499
383
  await database.dbStore(contract, src, valuesArray[0]);
500
384
  await database.dbStore(contract, src.add(new Fr(1)), valuesArray[1]);
501
385
  await database.dbStore(contract, src.add(new Fr(2)), valuesArray[2]);
@@ -505,19 +389,9 @@ import { NoteDao } from './note_dao.js';
505
389
  expect(await database.dbLoad(contract, dst.add(new Fr(1)))).toEqual(valuesArray[1]);
506
390
  expect(await database.dbLoad(contract, dst.add(new Fr(2)))).toEqual(valuesArray[2]);
507
391
  });
508
- it('copies overlapping values with src ahead', async ()=>{
392
+ it('copies overlapping values with src ahead', async () => {
509
393
  const src = new Fr(1);
510
- const valuesArray = [
511
- [
512
- new Fr(42)
513
- ],
514
- [
515
- new Fr(1337)
516
- ],
517
- [
518
- new Fr(13)
519
- ]
520
- ];
394
+ const valuesArray = [[new Fr(42)], [new Fr(1337)], [new Fr(13)]];
521
395
  await database.dbStore(contract, src, valuesArray[0]);
522
396
  await database.dbStore(contract, src.add(new Fr(1)), valuesArray[1]);
523
397
  await database.dbStore(contract, src.add(new Fr(2)), valuesArray[2]);
@@ -531,19 +405,9 @@ import { NoteDao } from './note_dao.js';
531
405
  expect(await database.dbLoad(contract, src.add(new Fr(1)))).toEqual(valuesArray[0]); // dst[0]
532
406
  expect(await database.dbLoad(contract, src.add(new Fr(2)))).toEqual(valuesArray[1]); // dst[1]
533
407
  });
534
- it('copies overlapping values with dst ahead', async ()=>{
408
+ it('copies overlapping values with dst ahead', async () => {
535
409
  const src = new Fr(5);
536
- const valuesArray = [
537
- [
538
- new Fr(42)
539
- ],
540
- [
541
- new Fr(1337)
542
- ],
543
- [
544
- new Fr(13)
545
- ]
546
- ];
410
+ const valuesArray = [[new Fr(42)], [new Fr(1337)], [new Fr(13)]];
547
411
  await database.dbStore(contract, src, valuesArray[0]);
548
412
  await database.dbStore(contract, src.add(new Fr(1)), valuesArray[1]);
549
413
  await database.dbStore(contract, src.add(new Fr(2)), valuesArray[2]);
@@ -557,19 +421,9 @@ import { NoteDao } from './note_dao.js';
557
421
  expect(await database.dbLoad(contract, src.add(new Fr(1)))).toEqual(valuesArray[2]); // dst[2]
558
422
  expect(await database.dbLoad(contract, src.add(new Fr(2)))).toEqual(valuesArray[2]); // src[2] (unchanged)
559
423
  });
560
- it('copying fails if any value is empty', async ()=>{
424
+ it('copying fails if any value is empty', async () => {
561
425
  const src = new Fr(1);
562
- const valuesArray = [
563
- [
564
- new Fr(42)
565
- ],
566
- [
567
- new Fr(1337)
568
- ],
569
- [
570
- new Fr(13)
571
- ]
572
- ];
426
+ const valuesArray = [[new Fr(42)], [new Fr(1337)], [new Fr(13)]];
573
427
  await database.dbStore(contract, src, valuesArray[0]);
574
428
  // We skip src[1]
575
429
  await database.dbStore(contract, src.add(new Fr(2)), valuesArray[2]);
@@ -579,3 +433,4 @@ import { NoteDao } from './note_dao.js';
579
433
  });
580
434
  });
581
435
  }
436
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHhlX2RhdGFiYXNlX3Rlc3Rfc3VpdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGF0YWJhc2UvcHhlX2RhdGFiYXNlX3Rlc3Rfc3VpdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBb0IsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEYsT0FBTyxFQUNMLFlBQVksRUFDWixlQUFlLEVBQ2Ysb0JBQW9CLEVBQ3BCLFVBQVUsRUFDViw0QkFBNEIsR0FDN0IsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDeEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckQsT0FBTyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUNyRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUVyRSxPQUFPLEtBQUssTUFBTSxjQUFjLENBQUM7QUFFakMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUd4Qzs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsbUJBQW1CLENBQUMsV0FBOEI7SUFDaEUsSUFBSSxRQUFxQixDQUFDO0lBRTFCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7UUFDZCxRQUFRLEdBQUcsV0FBVyxFQUFFLENBQUM7SUFDM0IsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsVUFBVSxFQUFFLEdBQUcsRUFBRTtRQUN4QixRQUFRLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFO1lBQzlC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