@aztec/pxe 0.76.4 → 0.77.0-testnet-ignition.21

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