@aztec/pxe 0.71.0 → 0.72.1
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.
- package/dest/database/kv_pxe_database.d.ts +3 -3
- package/dest/database/kv_pxe_database.d.ts.map +1 -1
- package/dest/database/kv_pxe_database.js +3 -3
- package/dest/database/note_dao.d.ts +1 -1
- package/dest/database/note_dao.d.ts.map +1 -1
- package/dest/database/note_dao.js +3 -3
- package/dest/database/outgoing_note_dao.d.ts +1 -1
- package/dest/database/outgoing_note_dao.d.ts.map +1 -1
- package/dest/database/outgoing_note_dao.js +3 -3
- package/dest/database/pxe_database_test_suite.d.ts.map +1 -1
- package/dest/database/pxe_database_test_suite.js +70 -48
- package/dest/pxe_service/pxe_service.d.ts +6 -6
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +31 -28
- package/dest/pxe_service/test/pxe_test_suite.js +9 -9
- package/dest/simulator_oracle/index.d.ts.map +1 -1
- package/dest/simulator_oracle/index.js +30 -16
- package/package.json +15 -15
- package/src/database/kv_pxe_database.ts +6 -4
- package/src/database/note_dao.ts +5 -5
- package/src/database/outgoing_note_dao.ts +5 -5
- package/src/database/pxe_database_test_suite.ts +71 -56
- package/src/pxe_service/pxe_service.ts +47 -46
- package/src/pxe_service/test/pxe_test_suite.ts +8 -8
- package/src/simulator_oracle/index.ts +45 -17
|
@@ -8,11 +8,14 @@ import {
|
|
|
8
8
|
} from '@aztec/circuits.js';
|
|
9
9
|
import { makeHeader } from '@aztec/circuits.js/testing';
|
|
10
10
|
import { FunctionType } from '@aztec/foundation/abi';
|
|
11
|
+
import { timesParallel } from '@aztec/foundation/collection';
|
|
11
12
|
import { randomInt } from '@aztec/foundation/crypto';
|
|
12
13
|
import { Fr, Point } from '@aztec/foundation/fields';
|
|
13
14
|
import { BenchmarkingContractArtifact } from '@aztec/noir-contracts.js/Benchmarking';
|
|
14
15
|
import { TestContractArtifact } from '@aztec/noir-contracts.js/Test';
|
|
15
16
|
|
|
17
|
+
import times from 'lodash.times';
|
|
18
|
+
|
|
16
19
|
import { NoteDao } from './note_dao.js';
|
|
17
20
|
import { type PxeDatabase } from './pxe_database.js';
|
|
18
21
|
|
|
@@ -80,53 +83,62 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
80
83
|
let storageSlots: Fr[];
|
|
81
84
|
let notes: NoteDao[];
|
|
82
85
|
|
|
83
|
-
const filteringTests: [() => NotesFilter
|
|
84
|
-
[() => ({}), () => notes],
|
|
86
|
+
const filteringTests: [() => Promise<NotesFilter>, () => Promise<NoteDao[]>][] = [
|
|
87
|
+
[() => Promise.resolve({}), () => Promise.resolve(notes)],
|
|
85
88
|
|
|
86
89
|
[
|
|
87
|
-
() => ({ contractAddress: contractAddresses[0] }),
|
|
88
|
-
() => notes.filter(note => note.contractAddress.equals(contractAddresses[0])),
|
|
90
|
+
() => Promise.resolve({ contractAddress: contractAddresses[0] }),
|
|
91
|
+
() => Promise.resolve(notes.filter(note => note.contractAddress.equals(contractAddresses[0]))),
|
|
89
92
|
],
|
|
90
|
-
[() => ({ contractAddress: AztecAddress.random() }), () => []],
|
|
93
|
+
[async () => ({ contractAddress: await AztecAddress.random() }), () => Promise.resolve([])],
|
|
91
94
|
|
|
92
95
|
[
|
|
93
|
-
() => ({ storageSlot: storageSlots[0] }),
|
|
94
|
-
() => notes.filter(note => note.storageSlot.equals(storageSlots[0])),
|
|
96
|
+
() => Promise.resolve({ storageSlot: storageSlots[0] }),
|
|
97
|
+
() => Promise.resolve(notes.filter(note => note.storageSlot.equals(storageSlots[0]))),
|
|
95
98
|
],
|
|
96
|
-
[() => ({ storageSlot: Fr.random() }), () => []],
|
|
99
|
+
[() => Promise.resolve({ storageSlot: Fr.random() }), () => Promise.resolve([])],
|
|
97
100
|
|
|
98
|
-
[() => ({ txHash: notes[0].txHash }), () => [notes[0]]],
|
|
99
|
-
[() => ({ txHash: randomTxHash() }), () => []],
|
|
101
|
+
[() => Promise.resolve({ txHash: notes[0].txHash }), () => Promise.resolve([notes[0]])],
|
|
102
|
+
[() => Promise.resolve({ txHash: randomTxHash() }), () => Promise.resolve([])],
|
|
100
103
|
|
|
101
104
|
[
|
|
102
|
-
() => ({ owner: owners[0].address }),
|
|
103
|
-
() =>
|
|
105
|
+
() => Promise.resolve({ owner: owners[0].address }),
|
|
106
|
+
async () => {
|
|
107
|
+
const ownerAddressPoint = await owners[0].address.toAddressPoint();
|
|
108
|
+
return notes.filter(note => note.addressPoint.equals(ownerAddressPoint));
|
|
109
|
+
},
|
|
104
110
|
],
|
|
105
111
|
|
|
106
112
|
[
|
|
107
|
-
() => ({ contractAddress: contractAddresses[0], storageSlot: storageSlots[0] }),
|
|
113
|
+
() => Promise.resolve({ contractAddress: contractAddresses[0], storageSlot: storageSlots[0] }),
|
|
108
114
|
() =>
|
|
109
|
-
|
|
110
|
-
|
|
115
|
+
Promise.resolve(
|
|
116
|
+
notes.filter(
|
|
117
|
+
note => note.contractAddress.equals(contractAddresses[0]) && note.storageSlot.equals(storageSlots[0]),
|
|
118
|
+
),
|
|
111
119
|
),
|
|
112
120
|
],
|
|
113
|
-
[
|
|
121
|
+
[
|
|
122
|
+
() => Promise.resolve({ contractAddress: contractAddresses[0], storageSlot: storageSlots[1] }),
|
|
123
|
+
() => Promise.resolve([]),
|
|
124
|
+
],
|
|
114
125
|
];
|
|
115
126
|
|
|
116
127
|
beforeEach(async () => {
|
|
117
|
-
owners =
|
|
118
|
-
contractAddresses =
|
|
119
|
-
storageSlots =
|
|
128
|
+
owners = await timesParallel(2, () => CompleteAddress.random());
|
|
129
|
+
contractAddresses = await timesParallel(2, () => AztecAddress.random());
|
|
130
|
+
storageSlots = times(2, () => Fr.random());
|
|
120
131
|
|
|
121
|
-
notes =
|
|
122
|
-
|
|
132
|
+
notes = await timesParallel(10, async i => {
|
|
133
|
+
const addressPoint = await owners[i % owners.length].address.toAddressPoint();
|
|
134
|
+
return NoteDao.random({
|
|
123
135
|
contractAddress: contractAddresses[i % contractAddresses.length],
|
|
124
136
|
storageSlot: storageSlots[i % storageSlots.length],
|
|
125
|
-
addressPoint
|
|
137
|
+
addressPoint,
|
|
126
138
|
index: BigInt(i),
|
|
127
139
|
l2BlockNumber: i,
|
|
128
|
-
})
|
|
129
|
-
);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
130
142
|
|
|
131
143
|
for (const owner of owners) {
|
|
132
144
|
await database.addCompleteAddress(owner);
|
|
@@ -135,9 +147,9 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
135
147
|
|
|
136
148
|
it.each(filteringTests)('stores notes in bulk and retrieves notes', async (getFilter, getExpected) => {
|
|
137
149
|
await database.addNotes(notes);
|
|
138
|
-
const returnedNotes = await database.getNotes(getFilter());
|
|
139
|
-
|
|
140
|
-
expect(returnedNotes.sort()).toEqual(
|
|
150
|
+
const returnedNotes = await database.getNotes(await getFilter());
|
|
151
|
+
const expected = await getExpected();
|
|
152
|
+
expect(returnedNotes.sort()).toEqual(expected.sort());
|
|
141
153
|
});
|
|
142
154
|
|
|
143
155
|
it.each(filteringTests)('stores notes one by one and retrieves notes', async (getFilter, getExpected) => {
|
|
@@ -145,9 +157,10 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
145
157
|
await database.addNote(note);
|
|
146
158
|
}
|
|
147
159
|
|
|
148
|
-
const returnedNotes = await database.getNotes(getFilter());
|
|
160
|
+
const returnedNotes = await database.getNotes(await getFilter());
|
|
149
161
|
|
|
150
|
-
|
|
162
|
+
const expected = await getExpected();
|
|
163
|
+
expect(returnedNotes.sort()).toEqual(expected.sort());
|
|
151
164
|
});
|
|
152
165
|
|
|
153
166
|
it.each(filteringTests)('retrieves nullified notes', async (getFilter, getExpected) => {
|
|
@@ -155,26 +168,25 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
155
168
|
|
|
156
169
|
// Nullify all notes and use the same filter as other test cases
|
|
157
170
|
for (const owner of owners) {
|
|
158
|
-
const
|
|
171
|
+
const ownerAddressPoint = await owner.address.toAddressPoint();
|
|
172
|
+
const notesToNullify = notes.filter(note => note.addressPoint.equals(ownerAddressPoint));
|
|
159
173
|
const nullifiers = notesToNullify.map(note => ({
|
|
160
174
|
data: note.siloedNullifier,
|
|
161
175
|
l2BlockNumber: note.l2BlockNumber,
|
|
162
176
|
l2BlockHash: note.l2BlockHash,
|
|
163
177
|
}));
|
|
164
|
-
await expect(database.removeNullifiedNotes(nullifiers,
|
|
165
|
-
notesToNullify,
|
|
166
|
-
);
|
|
178
|
+
await expect(database.removeNullifiedNotes(nullifiers, ownerAddressPoint)).resolves.toEqual(notesToNullify);
|
|
167
179
|
}
|
|
168
|
-
|
|
169
|
-
await
|
|
170
|
-
|
|
171
|
-
);
|
|
180
|
+
const filter = await getFilter();
|
|
181
|
+
const returnedNotes = await database.getNotes({ ...filter, status: NoteStatus.ACTIVE_OR_NULLIFIED });
|
|
182
|
+
const expected = await getExpected();
|
|
183
|
+
expect(returnedNotes.sort()).toEqual(expected.sort());
|
|
172
184
|
});
|
|
173
185
|
|
|
174
186
|
it('skips nullified notes by default or when requesting active', async () => {
|
|
175
187
|
await database.addNotes(notes);
|
|
176
|
-
|
|
177
|
-
const notesToNullify = notes.filter(note => note.addressPoint.equals(
|
|
188
|
+
const ownerAddressPoint = await owners[0].address.toAddressPoint();
|
|
189
|
+
const notesToNullify = notes.filter(note => note.addressPoint.equals(ownerAddressPoint));
|
|
178
190
|
const nullifiers = notesToNullify.map(note => ({
|
|
179
191
|
data: note.siloedNullifier,
|
|
180
192
|
l2BlockNumber: note.l2BlockNumber,
|
|
@@ -194,8 +206,9 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
194
206
|
it('handles note unnullification', async () => {
|
|
195
207
|
await database.setHeader(makeHeader(randomInt(1000), 100, 0 /** slot number */));
|
|
196
208
|
await database.addNotes(notes);
|
|
209
|
+
const ownerAddressPoint = await owners[0].address.toAddressPoint();
|
|
197
210
|
|
|
198
|
-
const notesToNullify = notes.filter(note => note.addressPoint.equals(
|
|
211
|
+
const notesToNullify = notes.filter(note => note.addressPoint.equals(ownerAddressPoint));
|
|
199
212
|
const nullifiers = notesToNullify.map(note => ({
|
|
200
213
|
data: note.siloedNullifier,
|
|
201
214
|
l2BlockNumber: 99,
|
|
@@ -213,8 +226,9 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
213
226
|
|
|
214
227
|
it('returns active and nullified notes when requesting either', async () => {
|
|
215
228
|
await database.addNotes(notes);
|
|
229
|
+
const ownerAddressPoint = await owners[0].address.toAddressPoint();
|
|
216
230
|
|
|
217
|
-
const notesToNullify = notes.filter(note => note.addressPoint.equals(
|
|
231
|
+
const notesToNullify = notes.filter(note => note.addressPoint.equals(ownerAddressPoint));
|
|
218
232
|
const nullifiers = notesToNullify.map(note => ({
|
|
219
233
|
data: note.siloedNullifier,
|
|
220
234
|
l2BlockNumber: note.l2BlockNumber,
|
|
@@ -275,7 +289,7 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
275
289
|
scopes: [owners[1].address],
|
|
276
290
|
}),
|
|
277
291
|
).resolves.toEqual([notes[0]]);
|
|
278
|
-
|
|
292
|
+
const ownerAddressPoint = await owners[0].address.toAddressPoint();
|
|
279
293
|
await expect(
|
|
280
294
|
database.removeNullifiedNotes(
|
|
281
295
|
[
|
|
@@ -285,7 +299,7 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
285
299
|
l2BlockNumber: notes[0].l2BlockNumber,
|
|
286
300
|
},
|
|
287
301
|
],
|
|
288
|
-
|
|
302
|
+
ownerAddressPoint,
|
|
289
303
|
),
|
|
290
304
|
).resolves.toEqual([notes[0]]);
|
|
291
305
|
|
|
@@ -325,22 +339,22 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
325
339
|
|
|
326
340
|
describe('addresses', () => {
|
|
327
341
|
it('stores and retrieves addresses', async () => {
|
|
328
|
-
const address = CompleteAddress.random();
|
|
342
|
+
const address = await CompleteAddress.random();
|
|
329
343
|
await expect(database.addCompleteAddress(address)).resolves.toBe(true);
|
|
330
344
|
await expect(database.getCompleteAddress(address.address)).resolves.toEqual(address);
|
|
331
345
|
});
|
|
332
346
|
|
|
333
347
|
it('silently ignores an address it already knows about', async () => {
|
|
334
|
-
const address = CompleteAddress.random();
|
|
348
|
+
const address = await CompleteAddress.random();
|
|
335
349
|
await expect(database.addCompleteAddress(address)).resolves.toBe(true);
|
|
336
350
|
await expect(database.addCompleteAddress(address)).resolves.toBe(false);
|
|
337
351
|
});
|
|
338
352
|
|
|
339
353
|
it.skip('refuses to overwrite an address with a different public key', async () => {
|
|
340
|
-
const address = CompleteAddress.random();
|
|
341
|
-
const otherAddress =
|
|
354
|
+
const address = await CompleteAddress.random();
|
|
355
|
+
const otherAddress = await CompleteAddress.create(
|
|
342
356
|
address.address,
|
|
343
|
-
new PublicKeys(Point.random(), Point.random(), Point.random(), Point.random()),
|
|
357
|
+
new PublicKeys(await Point.random(), await Point.random(), await Point.random(), await Point.random()),
|
|
344
358
|
address.partialAddress,
|
|
345
359
|
);
|
|
346
360
|
|
|
@@ -349,7 +363,7 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
349
363
|
});
|
|
350
364
|
|
|
351
365
|
it('returns all addresses', async () => {
|
|
352
|
-
const addresses =
|
|
366
|
+
const addresses = await timesParallel(10, () => CompleteAddress.random());
|
|
353
367
|
for (const address of addresses) {
|
|
354
368
|
await database.addCompleteAddress(address);
|
|
355
369
|
}
|
|
@@ -359,7 +373,7 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
359
373
|
});
|
|
360
374
|
|
|
361
375
|
it('returns a single address', async () => {
|
|
362
|
-
const addresses =
|
|
376
|
+
const addresses = await timesParallel(10, () => CompleteAddress.random());
|
|
363
377
|
for (const address of addresses) {
|
|
364
378
|
await database.addCompleteAddress(address);
|
|
365
379
|
}
|
|
@@ -373,7 +387,8 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
373
387
|
});
|
|
374
388
|
|
|
375
389
|
it("returns undefined if it doesn't have an address", async () => {
|
|
376
|
-
|
|
390
|
+
const completeAddress = await CompleteAddress.random();
|
|
391
|
+
expect(await database.getCompleteAddress(completeAddress.address)).toBeUndefined();
|
|
377
392
|
});
|
|
378
393
|
});
|
|
379
394
|
|
|
@@ -399,8 +414,8 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
399
414
|
});
|
|
400
415
|
|
|
401
416
|
it('stores a contract instance', async () => {
|
|
402
|
-
const address = AztecAddress.random();
|
|
403
|
-
const instance = SerializableContractInstance.random().withAddress(address);
|
|
417
|
+
const address = await AztecAddress.random();
|
|
418
|
+
const instance = (await SerializableContractInstance.random()).withAddress(address);
|
|
404
419
|
await database.addContractInstance(instance);
|
|
405
420
|
await expect(database.getContractInstance(address)).resolves.toEqual(instance);
|
|
406
421
|
});
|
|
@@ -409,9 +424,9 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
409
424
|
describe('contract non-volatile database', () => {
|
|
410
425
|
let contract: AztecAddress;
|
|
411
426
|
|
|
412
|
-
beforeEach(() => {
|
|
427
|
+
beforeEach(async () => {
|
|
413
428
|
// Setup mock contract address
|
|
414
|
-
contract = AztecAddress.random();
|
|
429
|
+
contract = await AztecAddress.random();
|
|
415
430
|
});
|
|
416
431
|
|
|
417
432
|
it('stores and loads a single value', async () => {
|
|
@@ -445,7 +460,7 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
|
|
|
445
460
|
});
|
|
446
461
|
|
|
447
462
|
it('stores values for different contracts independently', async () => {
|
|
448
|
-
const anotherContract = AztecAddress.random();
|
|
463
|
+
const anotherContract = await AztecAddress.random();
|
|
449
464
|
const slot = new Fr(1);
|
|
450
465
|
const values1 = [new Fr(42)];
|
|
451
466
|
const values2 = [new Fr(100)];
|
|
@@ -5,7 +5,8 @@ import {
|
|
|
5
5
|
type EventMetadataDefinition,
|
|
6
6
|
type ExtendedNote,
|
|
7
7
|
type FunctionCall,
|
|
8
|
-
type
|
|
8
|
+
type GetContractClassLogsResponse,
|
|
9
|
+
type GetPublicLogsResponse,
|
|
9
10
|
type InBlock,
|
|
10
11
|
L1EventPayload,
|
|
11
12
|
type L2Block,
|
|
@@ -234,7 +235,8 @@ export class PXEService implements PXE {
|
|
|
234
235
|
`Artifact does not match expected class id (computed ${contractClassId} but instance refers to ${instance.contractClassId})`,
|
|
235
236
|
);
|
|
236
237
|
}
|
|
237
|
-
|
|
238
|
+
const computedAddress = await computeContractAddressFromInstance(instance);
|
|
239
|
+
if (!computedAddress.equals(instance.address)) {
|
|
238
240
|
throw new Error('Added a contract in which the address does not match the contract instance.');
|
|
239
241
|
}
|
|
240
242
|
|
|
@@ -278,13 +280,15 @@ export class PXEService implements PXE {
|
|
|
278
280
|
const extendedNotes = noteDaos.map(async dao => {
|
|
279
281
|
let owner = filter.owner;
|
|
280
282
|
if (owner === undefined) {
|
|
281
|
-
const completeAddresses =
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
283
|
+
const completeAddresses = await this.db.getCompleteAddresses();
|
|
284
|
+
const completeAddressIndex = (
|
|
285
|
+
await Promise.all(completeAddresses.map(completeAddresses => completeAddresses.address.toAddressPoint()))
|
|
286
|
+
).findIndex(addressPoint => addressPoint.equals(dao.addressPoint));
|
|
287
|
+
const completeAddress = completeAddresses[completeAddressIndex];
|
|
288
|
+
if (completeAddress === undefined) {
|
|
285
289
|
throw new Error(`Cannot find complete address for addressPoint ${dao.addressPoint.toString()}`);
|
|
286
290
|
}
|
|
287
|
-
owner =
|
|
291
|
+
owner = completeAddress.address;
|
|
288
292
|
}
|
|
289
293
|
return new UniqueNote(
|
|
290
294
|
dao.note,
|
|
@@ -357,7 +361,7 @@ export class PXEService implements PXE {
|
|
|
357
361
|
l2BlockNumber,
|
|
358
362
|
l2BlockHash,
|
|
359
363
|
index,
|
|
360
|
-
owner.address.toAddressPoint(),
|
|
364
|
+
await owner.address.toAddressPoint(),
|
|
361
365
|
note.noteTypeId,
|
|
362
366
|
),
|
|
363
367
|
scope,
|
|
@@ -402,7 +406,7 @@ export class PXEService implements PXE {
|
|
|
402
406
|
l2BlockNumber,
|
|
403
407
|
l2BlockHash,
|
|
404
408
|
index,
|
|
405
|
-
note.owner.toAddressPoint(),
|
|
409
|
+
await note.owner.toAddressPoint(),
|
|
406
410
|
note.noteTypeId,
|
|
407
411
|
),
|
|
408
412
|
);
|
|
@@ -608,12 +612,12 @@ export class PXEService implements PXE {
|
|
|
608
612
|
}
|
|
609
613
|
|
|
610
614
|
/**
|
|
611
|
-
* Gets
|
|
615
|
+
* Gets public logs based on the provided filter.
|
|
612
616
|
* @param filter - The filter to apply to the logs.
|
|
613
617
|
* @returns The requested logs.
|
|
614
618
|
*/
|
|
615
|
-
public
|
|
616
|
-
return this.node.
|
|
619
|
+
public getPublicLogs(filter: LogFilter): Promise<GetPublicLogsResponse> {
|
|
620
|
+
return this.node.getPublicLogs(filter);
|
|
617
621
|
}
|
|
618
622
|
|
|
619
623
|
/**
|
|
@@ -621,7 +625,7 @@ export class PXEService implements PXE {
|
|
|
621
625
|
* @param filter - The filter to apply to the logs.
|
|
622
626
|
* @returns The requested logs.
|
|
623
627
|
*/
|
|
624
|
-
public getContractClassLogs(filter: LogFilter): Promise<
|
|
628
|
+
public getContractClassLogs(filter: LogFilter): Promise<GetContractClassLogsResponse> {
|
|
625
629
|
return this.node.getContractClassLogs(filter);
|
|
626
630
|
}
|
|
627
631
|
|
|
@@ -687,7 +691,7 @@ export class PXEService implements PXE {
|
|
|
687
691
|
async #registerProtocolContracts() {
|
|
688
692
|
const registered: Record<string, string> = {};
|
|
689
693
|
for (const name of protocolContractNames) {
|
|
690
|
-
const { address, contractClass, instance, artifact } = getCanonicalProtocolContract(name);
|
|
694
|
+
const { address, contractClass, instance, artifact } = await getCanonicalProtocolContract(name);
|
|
691
695
|
await this.db.addContractArtifact(contractClass.id, artifact);
|
|
692
696
|
await this.db.addContractInstance(instance);
|
|
693
697
|
registered[name] = address.toString();
|
|
@@ -833,7 +837,7 @@ export class PXEService implements PXE {
|
|
|
833
837
|
return !!(await this.node.getNullifierMembershipWitness('latest', initNullifier));
|
|
834
838
|
}
|
|
835
839
|
|
|
836
|
-
public async
|
|
840
|
+
public async getPrivateEvents<T>(
|
|
837
841
|
eventMetadataDef: EventMetadataDefinition,
|
|
838
842
|
from: number,
|
|
839
843
|
limit: number,
|
|
@@ -864,25 +868,29 @@ export class PXEService implements PXE {
|
|
|
864
868
|
|
|
865
869
|
const preaddress = registeredAccount.getPreaddress();
|
|
866
870
|
|
|
867
|
-
secretKey = computeAddressSecret(preaddress, secretKey);
|
|
871
|
+
secretKey = await computeAddressSecret(preaddress, secretKey);
|
|
868
872
|
}
|
|
869
873
|
|
|
870
874
|
return secretKey;
|
|
871
875
|
}),
|
|
872
876
|
);
|
|
873
877
|
|
|
874
|
-
const visibleEvents =
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
878
|
+
const visibleEvents = (
|
|
879
|
+
await Promise.all(
|
|
880
|
+
privateLogs.map(async log => {
|
|
881
|
+
for (const sk of vsks) {
|
|
882
|
+
// TODO: Verify that the first field of the log is the tag siloed with contract address.
|
|
883
|
+
// Or use tags to query logs, like we do with notes.
|
|
884
|
+
const decryptedEvent = await L1EventPayload.decryptAsIncoming(log, sk);
|
|
885
|
+
if (decryptedEvent !== undefined) {
|
|
886
|
+
return [decryptedEvent];
|
|
887
|
+
}
|
|
888
|
+
}
|
|
883
889
|
|
|
884
|
-
|
|
885
|
-
|
|
890
|
+
return [];
|
|
891
|
+
}),
|
|
892
|
+
)
|
|
893
|
+
).flat();
|
|
886
894
|
|
|
887
895
|
const decodedEvents = visibleEvents
|
|
888
896
|
.map(visibleEvent => {
|
|
@@ -892,11 +900,6 @@ export class PXEService implements PXE {
|
|
|
892
900
|
if (!visibleEvent.eventTypeId.equals(eventMetadata.eventSelector)) {
|
|
893
901
|
return undefined;
|
|
894
902
|
}
|
|
895
|
-
if (visibleEvent.event.items.length !== eventMetadata.fieldNames.length) {
|
|
896
|
-
throw new Error(
|
|
897
|
-
'Something is weird here, we have matching EventSelectors, but the actual payload has mismatched length',
|
|
898
|
-
);
|
|
899
|
-
}
|
|
900
903
|
|
|
901
904
|
return eventMetadata.decode(visibleEvent);
|
|
902
905
|
})
|
|
@@ -905,34 +908,32 @@ export class PXEService implements PXE {
|
|
|
905
908
|
return decodedEvents;
|
|
906
909
|
}
|
|
907
910
|
|
|
908
|
-
async
|
|
911
|
+
async getPublicEvents<T>(eventMetadataDef: EventMetadataDefinition, from: number, limit: number): Promise<T[]> {
|
|
909
912
|
const eventMetadata = new EventMetadata<T>(eventMetadataDef);
|
|
910
|
-
const { logs
|
|
913
|
+
const { logs } = await this.node.getPublicLogs({
|
|
911
914
|
fromBlock: from,
|
|
912
915
|
toBlock: from + limit,
|
|
913
916
|
});
|
|
914
917
|
|
|
915
|
-
const decodedEvents =
|
|
916
|
-
.map(
|
|
917
|
-
|
|
918
|
+
const decodedEvents = logs
|
|
919
|
+
.map(log => {
|
|
920
|
+
// +1 for the event selector
|
|
921
|
+
const expectedLength = eventMetadata.fieldNames.length + 1;
|
|
922
|
+
const logFields = log.log.log.slice(0, expectedLength);
|
|
918
923
|
// We are assuming here that event logs are the last 4 bytes of the event. This is not enshrined but is a function of aztec.nr raw log emission.
|
|
919
|
-
if (
|
|
920
|
-
!EventSelector.fromBuffer(unencryptedLogBuf.subarray(unencryptedLogBuf.byteLength - 4)).equals(
|
|
921
|
-
eventMetadata.eventSelector,
|
|
922
|
-
)
|
|
923
|
-
) {
|
|
924
|
+
if (!EventSelector.fromField(logFields[logFields.length - 1]).equals(eventMetadata.eventSelector)) {
|
|
924
925
|
return undefined;
|
|
925
926
|
}
|
|
926
|
-
|
|
927
|
-
if (
|
|
927
|
+
// If any of the remaining fields, are non-zero, the payload does match expected:
|
|
928
|
+
if (log.log.log.slice(expectedLength + 1).find(f => !f.isZero())) {
|
|
928
929
|
throw new Error(
|
|
929
930
|
'Something is weird here, we have matching EventSelectors, but the actual payload has mismatched length',
|
|
930
931
|
);
|
|
931
932
|
}
|
|
932
933
|
|
|
933
|
-
return eventMetadata.decode(
|
|
934
|
+
return eventMetadata.decode(log.log);
|
|
934
935
|
})
|
|
935
|
-
.filter(
|
|
936
|
+
.filter(log => log !== undefined) as T[];
|
|
936
937
|
|
|
937
938
|
return decodedEvents;
|
|
938
939
|
}
|
|
@@ -35,7 +35,7 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise<PXE>) =>
|
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
it('successfully adds a contract', async () => {
|
|
38
|
-
const contracts = [randomDeployedContract(), randomDeployedContract()];
|
|
38
|
+
const contracts = await Promise.all([randomDeployedContract(), randomDeployedContract()]);
|
|
39
39
|
for (const contract of contracts) {
|
|
40
40
|
await pxe.registerContract(contract);
|
|
41
41
|
}
|
|
@@ -49,7 +49,7 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise<PXE>) =>
|
|
|
49
49
|
const artifact = randomContractArtifact();
|
|
50
50
|
const contractClass = getContractClassFromArtifact(artifact);
|
|
51
51
|
const contractClassId = contractClass.id;
|
|
52
|
-
const instance = randomContractInstanceWithAddress({ contractClassId });
|
|
52
|
+
const instance = await randomContractInstanceWithAddress({ contractClassId });
|
|
53
53
|
|
|
54
54
|
await pxe.registerContractClass(artifact);
|
|
55
55
|
expect(await pxe.getContractClass(contractClassId)).toMatchObject(
|
|
@@ -64,12 +64,12 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise<PXE>) =>
|
|
|
64
64
|
const artifact = randomContractArtifact();
|
|
65
65
|
const contractClass = getContractClassFromArtifact(artifact);
|
|
66
66
|
const contractClassId = contractClass.id;
|
|
67
|
-
const instance = randomContractInstanceWithAddress({ contractClassId });
|
|
67
|
+
const instance = await randomContractInstanceWithAddress({ contractClassId });
|
|
68
68
|
await expect(
|
|
69
69
|
pxe.registerContract({
|
|
70
70
|
instance: {
|
|
71
71
|
...instance,
|
|
72
|
-
address: AztecAddress.random(),
|
|
72
|
+
address: await AztecAddress.random(),
|
|
73
73
|
},
|
|
74
74
|
artifact,
|
|
75
75
|
}),
|
|
@@ -77,13 +77,13 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise<PXE>) =>
|
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
it('refuses to register a contract with a class that has not been registered', async () => {
|
|
80
|
-
const instance = randomContractInstanceWithAddress();
|
|
80
|
+
const instance = await randomContractInstanceWithAddress();
|
|
81
81
|
await expect(pxe.registerContract({ instance })).rejects.toThrow(/Missing contract artifact/i);
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
it('refuses to register a contract with an artifact with mismatching class id', async () => {
|
|
85
85
|
const artifact = randomContractArtifact();
|
|
86
|
-
const instance = randomContractInstanceWithAddress();
|
|
86
|
+
const instance = await randomContractInstanceWithAddress();
|
|
87
87
|
await expect(pxe.registerContract({ instance, artifact })).rejects.toThrow(/Artifact does not match/i);
|
|
88
88
|
});
|
|
89
89
|
|
|
@@ -91,13 +91,13 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise<PXE>) =>
|
|
|
91
91
|
// a larger setup and it's sufficiently tested in the e2e tests.
|
|
92
92
|
|
|
93
93
|
it('throws when getting public storage for non-existent contract', async () => {
|
|
94
|
-
const contract = AztecAddress.random();
|
|
94
|
+
const contract = await AztecAddress.random();
|
|
95
95
|
await expect(async () => await pxe.getPublicStorageAt(contract, new Fr(0n))).rejects.toThrow(
|
|
96
96
|
`Contract ${contract.toString()} is not deployed`,
|
|
97
97
|
);
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
-
// Note: Not testing `getContractData` and `
|
|
100
|
+
// Note: Not testing `getContractData` and `getPublicLogs` here as these
|
|
101
101
|
// functions only call AztecNode and these methods are frequently used by the e2e tests.
|
|
102
102
|
|
|
103
103
|
it('successfully gets a block number', async () => {
|