@aztec/pxe 0.42.0 → 0.43.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.
- package/dest/database/deferred_note_dao.d.ts +2 -2
- package/dest/database/deferred_note_dao.d.ts.map +1 -1
- package/dest/database/deferred_note_dao.js +2 -2
- package/dest/database/incoming_note_dao.d.ts +73 -0
- package/dest/database/incoming_note_dao.d.ts.map +1 -0
- package/dest/database/incoming_note_dao.js +92 -0
- package/dest/database/kv_pxe_database.d.ts +10 -7
- package/dest/database/kv_pxe_database.d.ts.map +1 -1
- package/dest/database/kv_pxe_database.js +149 -78
- package/dest/database/{note_dao.d.ts → outgoing_note_dao.d.ts} +7 -12
- package/dest/database/outgoing_note_dao.d.ts.map +1 -0
- package/dest/database/outgoing_note_dao.js +83 -0
- package/dest/database/pxe_database.d.ts +21 -9
- package/dest/database/pxe_database.d.ts.map +1 -1
- package/dest/database/pxe_database_test_suite.d.ts.map +1 -1
- package/dest/database/pxe_database_test_suite.js +71 -24
- package/dest/kernel_oracle/index.d.ts +1 -1
- package/dest/note_processor/note_processor.d.ts +23 -20
- package/dest/note_processor/note_processor.d.ts.map +1 -1
- package/dest/note_processor/note_processor.js +123 -76
- package/dest/note_processor/produce_note_dao.d.ts +13 -4
- package/dest/note_processor/produce_note_dao.d.ts.map +1 -1
- package/dest/note_processor/produce_note_dao.js +88 -31
- package/dest/pxe_service/create_pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/create_pxe_service.js +3 -1
- package/dest/pxe_service/pxe_service.d.ts +9 -4
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +106 -28
- package/dest/simulator_oracle/index.js +2 -2
- package/dest/synchronizer/synchronizer.d.ts +2 -2
- package/dest/synchronizer/synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/synchronizer.js +37 -36
- package/package.json +14 -14
- package/src/database/deferred_note_dao.ts +1 -1
- package/src/database/{note_dao.ts → incoming_note_dao.ts} +10 -7
- package/src/database/kv_pxe_database.ts +127 -29
- package/src/database/outgoing_note_dao.ts +90 -0
- package/src/database/pxe_database.ts +23 -9
- package/src/database/pxe_database_test_suite.ts +93 -29
- package/src/note_processor/note_processor.ts +191 -121
- package/src/note_processor/produce_note_dao.ts +164 -50
- package/src/pxe_service/create_pxe_service.ts +2 -0
- package/src/pxe_service/pxe_service.ts +170 -42
- package/src/simulator_oracle/index.ts +1 -1
- package/src/synchronizer/synchronizer.ts +48 -52
- package/dest/database/note_dao.d.ts.map +0 -1
- package/dest/database/note_dao.js +0 -89
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var _Synchronizer_instances, _Synchronizer_reprocessDeferredNotesForContract;
|
|
1
|
+
var _Synchronizer_instances, _Synchronizer_reprocessDeferredNotesForContract, _Synchronizer_removeNullifiedNotes;
|
|
2
2
|
import { __classPrivateFieldGet } from "tslib";
|
|
3
|
-
import {
|
|
3
|
+
import { MerkleTreeId } from '@aztec/circuit-types';
|
|
4
4
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
|
|
5
5
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
6
6
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
@@ -89,15 +89,12 @@ export class Synchronizer {
|
|
|
89
89
|
if (blocks.length === 0) {
|
|
90
90
|
return false;
|
|
91
91
|
}
|
|
92
|
-
const noteEncryptedLogs = blocks.flatMap(block => block.body.noteEncryptedLogs);
|
|
93
92
|
// Update latest tree roots from the most recent block
|
|
94
93
|
const latestBlock = blocks[blocks.length - 1];
|
|
95
94
|
await this.setHeaderFromBlock(latestBlock);
|
|
96
|
-
|
|
97
|
-
this.log.debug(`Forwarding ${logCount} encrypted logs and blocks to ${this.noteProcessors.length} note processors`);
|
|
95
|
+
this.log.debug(`Forwarding ${blocks.length} blocks to ${this.noteProcessors.length} note processors`);
|
|
98
96
|
for (const noteProcessor of this.noteProcessors) {
|
|
99
|
-
|
|
100
|
-
await noteProcessor.process(blocks, noteEncryptedLogs);
|
|
97
|
+
await noteProcessor.process(blocks);
|
|
101
98
|
}
|
|
102
99
|
return true;
|
|
103
100
|
}
|
|
@@ -155,9 +152,6 @@ export class Synchronizer {
|
|
|
155
152
|
// behind main sync.
|
|
156
153
|
throw new Error('No blocks in processor catch up mode');
|
|
157
154
|
}
|
|
158
|
-
const noteEncryptedLogs = blocks.flatMap(block => block.body.noteEncryptedLogs);
|
|
159
|
-
const logCount = L2BlockL2Logs.getTotalLogCount(noteEncryptedLogs);
|
|
160
|
-
this.log.debug(`Forwarding ${logCount} encrypted logs and blocks to note processors in catch up mode`);
|
|
161
155
|
for (const noteProcessor of catchUpGroup) {
|
|
162
156
|
// find the index of the first block that the note processor is not yet synced to
|
|
163
157
|
const index = blocks.findIndex(block => block.number > noteProcessor.status.syncedToBlock);
|
|
@@ -167,18 +161,18 @@ export class Synchronizer {
|
|
|
167
161
|
// that needs blocks newer than the newest block we fetched.
|
|
168
162
|
break;
|
|
169
163
|
}
|
|
170
|
-
this.log.debug(`Catching up note processor ${noteProcessor.
|
|
171
|
-
await noteProcessor.process(blocks.slice(index)
|
|
164
|
+
this.log.debug(`Catching up note processor ${noteProcessor.account.toString()} by processing ${blocks.length - index} blocks`);
|
|
165
|
+
await noteProcessor.process(blocks.slice(index));
|
|
172
166
|
if (noteProcessor.status.syncedToBlock === toBlockNumber) {
|
|
173
167
|
// Note processor caught up, move it to `noteProcessors` from `noteProcessorsToCatchUp`.
|
|
174
|
-
this.log.debug(`Note processor for ${noteProcessor.
|
|
168
|
+
this.log.debug(`Note processor for ${noteProcessor.account.toString()} has caught up`, {
|
|
175
169
|
eventName: 'note-processor-caught-up',
|
|
176
|
-
|
|
170
|
+
account: noteProcessor.account.toString(),
|
|
177
171
|
duration: noteProcessor.timer.ms(),
|
|
178
|
-
dbSize: this.db.estimateSize(),
|
|
172
|
+
dbSize: await this.db.estimateSize(),
|
|
179
173
|
...noteProcessor.stats,
|
|
180
174
|
});
|
|
181
|
-
this.noteProcessorsToCatchUp = this.noteProcessorsToCatchUp.filter(np => !np.
|
|
175
|
+
this.noteProcessorsToCatchUp = this.noteProcessorsToCatchUp.filter(np => !np.account.equals(noteProcessor.account));
|
|
182
176
|
this.noteProcessors.push(noteProcessor);
|
|
183
177
|
}
|
|
184
178
|
}
|
|
@@ -217,13 +211,13 @@ export class Synchronizer {
|
|
|
217
211
|
* @param startingBlock - The block where to start scanning for notes for this accounts.
|
|
218
212
|
* @returns A promise that resolves once the account is added to the Synchronizer.
|
|
219
213
|
*/
|
|
220
|
-
addAccount(
|
|
221
|
-
const predicate = (x) => x.
|
|
214
|
+
async addAccount(account, keyStore, startingBlock) {
|
|
215
|
+
const predicate = (x) => x.account.equals(account);
|
|
222
216
|
const processor = this.noteProcessors.find(predicate) ?? this.noteProcessorsToCatchUp.find(predicate);
|
|
223
217
|
if (processor) {
|
|
224
218
|
return;
|
|
225
219
|
}
|
|
226
|
-
this.noteProcessorsToCatchUp.push(
|
|
220
|
+
this.noteProcessorsToCatchUp.push(await NoteProcessor.create(account, keyStore, this.db, this.node, startingBlock));
|
|
227
221
|
}
|
|
228
222
|
/**
|
|
229
223
|
* Checks if the specified account is synchronized.
|
|
@@ -238,8 +232,8 @@ export class Synchronizer {
|
|
|
238
232
|
if (!completeAddress) {
|
|
239
233
|
throw new Error(`Checking if account is synched is not possible for ${account} because it is not registered.`);
|
|
240
234
|
}
|
|
241
|
-
const
|
|
242
|
-
const processor = this.noteProcessors.find(
|
|
235
|
+
const findByAccountAddress = (x) => x.account.equals(completeAddress.address);
|
|
236
|
+
const processor = this.noteProcessors.find(findByAccountAddress) ?? this.noteProcessorsToCatchUp.find(findByAccountAddress);
|
|
243
237
|
if (!processor) {
|
|
244
238
|
throw new Error(`Checking if account is synched is not possible for ${account} because it is only registered as a recipient.`);
|
|
245
239
|
}
|
|
@@ -266,7 +260,7 @@ export class Synchronizer {
|
|
|
266
260
|
const lastBlockNumber = this.getSynchedBlockNumber();
|
|
267
261
|
return {
|
|
268
262
|
blocks: lastBlockNumber,
|
|
269
|
-
notes: Object.fromEntries(this.noteProcessors.map(n => [n.
|
|
263
|
+
notes: Object.fromEntries(this.noteProcessors.map(n => [n.account.toString(), n.status.syncedToBlock])),
|
|
270
264
|
};
|
|
271
265
|
}
|
|
272
266
|
/**
|
|
@@ -274,7 +268,7 @@ export class Synchronizer {
|
|
|
274
268
|
* @returns The note processor stats for notes for each public key being tracked.
|
|
275
269
|
*/
|
|
276
270
|
getSyncStats() {
|
|
277
|
-
return Object.fromEntries(this.noteProcessors.map(n => [n.
|
|
271
|
+
return Object.fromEntries(this.noteProcessors.map(n => [n.account.toString(), n.stats]));
|
|
278
272
|
}
|
|
279
273
|
/**
|
|
280
274
|
* Retry decoding any deferred notes for the specified contract address.
|
|
@@ -294,30 +288,37 @@ _Synchronizer_instances = new WeakSet(), _Synchronizer_reprocessDeferredNotesFor
|
|
|
294
288
|
txHashToDeferredNotes.set(note.txHash, notesForTx);
|
|
295
289
|
}
|
|
296
290
|
// keep track of decoded notes
|
|
297
|
-
const
|
|
291
|
+
const incomingNotes = [];
|
|
292
|
+
const outgoingNotes = [];
|
|
298
293
|
// now process each txHash
|
|
299
294
|
for (const deferredNotes of txHashToDeferredNotes.values()) {
|
|
300
295
|
// to be safe, try each note processor in case the deferred notes are for different accounts.
|
|
301
296
|
for (const processor of this.noteProcessors) {
|
|
302
|
-
const
|
|
303
|
-
|
|
297
|
+
const { incomingNotes: inNotes, outgoingNotes: outNotes } = await processor.decodeDeferredNotes(deferredNotes);
|
|
298
|
+
incomingNotes.push(...inNotes);
|
|
299
|
+
outgoingNotes.push(...outNotes);
|
|
304
300
|
}
|
|
305
301
|
}
|
|
306
302
|
// now drop the deferred notes, and add the decoded notes
|
|
307
303
|
await this.db.removeDeferredNotesByContract(contractAddress);
|
|
308
|
-
await this.db.addNotes(
|
|
309
|
-
|
|
310
|
-
this.log.debug(`Decoded deferred note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot} with nullifier ${noteDao.siloedNullifier.toString()}`);
|
|
304
|
+
await this.db.addNotes(incomingNotes, outgoingNotes);
|
|
305
|
+
incomingNotes.forEach(noteDao => {
|
|
306
|
+
this.log.debug(`Decoded deferred incoming note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot} with nullifier ${noteDao.siloedNullifier.toString()}`);
|
|
311
307
|
});
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
308
|
+
outgoingNotes.forEach(noteDao => {
|
|
309
|
+
this.log.debug(`Decoded deferred outgoing note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot}`);
|
|
310
|
+
});
|
|
311
|
+
await __classPrivateFieldGet(this, _Synchronizer_instances, "m", _Synchronizer_removeNullifiedNotes).call(this, incomingNotes);
|
|
312
|
+
}, _Synchronizer_removeNullifiedNotes = async function _Synchronizer_removeNullifiedNotes(notes) {
|
|
313
|
+
// now group the decoded incoming notes by public key
|
|
314
|
+
const publicKeyToIncomingNotes = new Map();
|
|
315
|
+
for (const noteDao of notes) {
|
|
316
|
+
const notesForPublicKey = publicKeyToIncomingNotes.get(noteDao.ivpkM) ?? [];
|
|
316
317
|
notesForPublicKey.push(noteDao);
|
|
317
|
-
|
|
318
|
+
publicKeyToIncomingNotes.set(noteDao.ivpkM, notesForPublicKey);
|
|
318
319
|
}
|
|
319
320
|
// now for each group, look for the nullifiers in the nullifier tree
|
|
320
|
-
for (const [publicKey, notes] of
|
|
321
|
+
for (const [publicKey, notes] of publicKeyToIncomingNotes.entries()) {
|
|
321
322
|
const nullifiers = notes.map(n => n.siloedNullifier);
|
|
322
323
|
const relevantNullifiers = [];
|
|
323
324
|
for (const nullifier of nullifiers) {
|
|
@@ -330,4 +331,4 @@ _Synchronizer_instances = new WeakSet(), _Synchronizer_reprocessDeferredNotesFor
|
|
|
330
331
|
await this.db.removeNullifiedNotes(relevantNullifiers, publicKey);
|
|
331
332
|
}
|
|
332
333
|
};
|
|
333
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luY2hyb25pemVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N5bmNocm9uaXplci9zeW5jaHJvbml6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQWdDLGFBQWEsRUFBRSxZQUFZLEVBQWUsTUFBTSxzQkFBc0IsQ0FBQztBQUU5RyxPQUFPLEVBQThCLG9CQUFvQixFQUFrQixNQUFNLG9CQUFvQixDQUFDO0FBRXRHLE9BQU8sRUFBb0IsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM1RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFNbkUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRTNEOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxZQUFZO0lBUXZCLFlBQW9CLElBQWUsRUFBVSxFQUFlLEVBQVUsUUFBcUIsRUFBRSxTQUFTLEdBQUcsRUFBRTs7UUFBdkYsU0FBSSxHQUFKLElBQUksQ0FBVztRQUFVLE9BQUUsR0FBRixFQUFFLENBQWE7UUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFhO1FBTm5GLG1CQUFjLEdBQW9CLEVBQUUsQ0FBQztRQUNyQyxZQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ2hCLDJCQUFzQixHQUFHLG9CQUFvQixHQUFHLENBQUMsQ0FBQztRQUVsRCw0QkFBdUIsR0FBb0IsRUFBRSxDQUFDO1FBR3BELElBQUksQ0FBQyxHQUFHLEdBQUcsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQywwQkFBMEIsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFDN0csQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSSxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsYUFBYSxHQUFHLElBQUk7UUFDaEQsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsT0FBTztR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
|
|
334
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luY2hyb25pemVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N5bmNocm9uaXplci9zeW5jaHJvbml6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQWdDLFlBQVksRUFBZSxNQUFNLHNCQUFzQixDQUFDO0FBRS9GLE9BQU8sRUFBOEIsb0JBQW9CLEVBQWtCLE1BQU0sb0JBQW9CLENBQUM7QUFFdEcsT0FBTyxFQUFvQixpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzVFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQU9uRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFM0Q7Ozs7OztHQU1HO0FBQ0gsTUFBTSxPQUFPLFlBQVk7SUFRdkIsWUFBb0IsSUFBZSxFQUFVLEVBQWUsRUFBVSxRQUFxQixFQUFFLFNBQVMsR0FBRyxFQUFFOztRQUF2RixTQUFJLEdBQUosSUFBSSxDQUFXO1FBQVUsT0FBRSxHQUFGLEVBQUUsQ0FBYTtRQUFVLGFBQVEsR0FBUixRQUFRLENBQWE7UUFObkYsbUJBQWMsR0FBb0IsRUFBRSxDQUFDO1FBQ3JDLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDaEIsMkJBQXNCLEdBQUcsb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO1FBRWxELDRCQUF1QixHQUFvQixFQUFFLENBQUM7UUFHcEQsSUFBSSxDQUFDLEdBQUcsR0FBRyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLDBCQUEwQixTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsd0JBQXdCLENBQUMsQ0FBQztJQUM3RyxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsRUFBRSxhQUFhLEdBQUcsSUFBSTtRQUNoRCxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNqQixPQUFPO1FBQ1QsQ0FBQztR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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/pxe",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.43.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dest/index.js",
|
|
6
6
|
"bin": "./dest/bin/index.js",
|
|
@@ -48,19 +48,19 @@
|
|
|
48
48
|
]
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@aztec/bb-prover": "0.
|
|
52
|
-
"@aztec/bb.js": "0.
|
|
53
|
-
"@aztec/builder": "0.
|
|
54
|
-
"@aztec/circuit-types": "0.
|
|
55
|
-
"@aztec/circuits.js": "0.
|
|
56
|
-
"@aztec/ethereum": "0.
|
|
57
|
-
"@aztec/foundation": "0.
|
|
58
|
-
"@aztec/key-store": "0.
|
|
59
|
-
"@aztec/kv-store": "0.
|
|
60
|
-
"@aztec/noir-protocol-circuits-types": "0.
|
|
61
|
-
"@aztec/protocol-contracts": "0.
|
|
62
|
-
"@aztec/simulator": "0.
|
|
63
|
-
"@aztec/types": "0.
|
|
51
|
+
"@aztec/bb-prover": "0.43.0",
|
|
52
|
+
"@aztec/bb.js": "0.43.0",
|
|
53
|
+
"@aztec/builder": "0.43.0",
|
|
54
|
+
"@aztec/circuit-types": "0.43.0",
|
|
55
|
+
"@aztec/circuits.js": "0.43.0",
|
|
56
|
+
"@aztec/ethereum": "0.43.0",
|
|
57
|
+
"@aztec/foundation": "0.43.0",
|
|
58
|
+
"@aztec/key-store": "0.43.0",
|
|
59
|
+
"@aztec/kv-store": "0.43.0",
|
|
60
|
+
"@aztec/noir-protocol-circuits-types": "0.43.0",
|
|
61
|
+
"@aztec/protocol-contracts": "0.43.0",
|
|
62
|
+
"@aztec/simulator": "0.43.0",
|
|
63
|
+
"@aztec/types": "0.43.0",
|
|
64
64
|
"@noir-lang/noirc_abi": "portal:../../noir/packages/noirc_abi",
|
|
65
65
|
"koa": "^2.14.2",
|
|
66
66
|
"koa-router": "^12.0.0",
|
|
@@ -9,7 +9,7 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
|
9
9
|
*/
|
|
10
10
|
export class DeferredNoteDao {
|
|
11
11
|
constructor(
|
|
12
|
-
/**
|
|
12
|
+
/** IvpkM or OvpkM (depending on if incoming or outgoing) the note was encrypted with. */
|
|
13
13
|
public publicKey: PublicKey,
|
|
14
14
|
/** The note as emitted from the Noir contract. */
|
|
15
15
|
public note: Note,
|
|
@@ -5,9 +5,9 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
|
5
5
|
import { type NoteData } from '@aztec/simulator';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* A note with contextual data.
|
|
8
|
+
* A note with contextual data which was decrypted as incoming.
|
|
9
9
|
*/
|
|
10
|
-
export class
|
|
10
|
+
export class IncomingNoteDao implements NoteData {
|
|
11
11
|
constructor(
|
|
12
12
|
/** The note as emitted from the Noir contract. */
|
|
13
13
|
public note: Note,
|
|
@@ -26,12 +26,15 @@ export class NoteDao implements NoteData {
|
|
|
26
26
|
* We can use this value to compute siloedNoteHash and uniqueSiloedNoteHash.
|
|
27
27
|
*/
|
|
28
28
|
public innerNoteHash: Fr,
|
|
29
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* The nullifier of the note (siloed by contract address).
|
|
31
|
+
* Note: Might be set as 0 if the note was added to PXE as nullified.
|
|
32
|
+
*/
|
|
30
33
|
public siloedNullifier: Fr,
|
|
31
34
|
/** The location of the relevant note in the note hash tree. */
|
|
32
35
|
public index: bigint,
|
|
33
36
|
/** The public key with which the note was encrypted. */
|
|
34
|
-
public
|
|
37
|
+
public ivpkM: PublicKey,
|
|
35
38
|
) {}
|
|
36
39
|
|
|
37
40
|
toBuffer(): Buffer {
|
|
@@ -45,7 +48,7 @@ export class NoteDao implements NoteData {
|
|
|
45
48
|
this.innerNoteHash,
|
|
46
49
|
this.siloedNullifier,
|
|
47
50
|
this.index,
|
|
48
|
-
this.
|
|
51
|
+
this.ivpkM,
|
|
49
52
|
]);
|
|
50
53
|
}
|
|
51
54
|
static fromBuffer(buffer: Buffer | BufferReader) {
|
|
@@ -62,7 +65,7 @@ export class NoteDao implements NoteData {
|
|
|
62
65
|
const index = toBigIntBE(reader.readBytes(32));
|
|
63
66
|
const publicKey = Point.fromBuffer(reader);
|
|
64
67
|
|
|
65
|
-
return new
|
|
68
|
+
return new IncomingNoteDao(
|
|
66
69
|
note,
|
|
67
70
|
contractAddress,
|
|
68
71
|
storageSlot,
|
|
@@ -82,7 +85,7 @@ export class NoteDao implements NoteData {
|
|
|
82
85
|
|
|
83
86
|
static fromString(str: string) {
|
|
84
87
|
const hex = str.replace(/^0x/, '');
|
|
85
|
-
return
|
|
88
|
+
return IncomingNoteDao.fromBuffer(Buffer.from(hex, 'hex'));
|
|
86
89
|
}
|
|
87
90
|
|
|
88
91
|
/**
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type IncomingNotesFilter,
|
|
3
|
+
MerkleTreeId,
|
|
4
|
+
NoteStatus,
|
|
5
|
+
type OutgoingNotesFilter,
|
|
6
|
+
type PublicKey,
|
|
7
|
+
} from '@aztec/circuit-types';
|
|
2
8
|
import { AztecAddress, CompleteAddress, Header } from '@aztec/circuits.js';
|
|
3
9
|
import { type ContractArtifact } from '@aztec/foundation/abi';
|
|
4
10
|
import { toBufferBE } from '@aztec/foundation/bigint-buffer';
|
|
@@ -14,7 +20,8 @@ import { contractArtifactFromBuffer, contractArtifactToBuffer } from '@aztec/typ
|
|
|
14
20
|
import { type ContractInstanceWithAddress, SerializableContractInstance } from '@aztec/types/contracts';
|
|
15
21
|
|
|
16
22
|
import { DeferredNoteDao } from './deferred_note_dao.js';
|
|
17
|
-
import {
|
|
23
|
+
import { IncomingNoteDao } from './incoming_note_dao.js';
|
|
24
|
+
import { OutgoingNoteDao } from './outgoing_note_dao.js';
|
|
18
25
|
import { type PxeDatabase } from './pxe_database.js';
|
|
19
26
|
|
|
20
27
|
/**
|
|
@@ -32,11 +39,11 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
32
39
|
#notesByContract: AztecMultiMap<string, string>;
|
|
33
40
|
#notesByStorageSlot: AztecMultiMap<string, string>;
|
|
34
41
|
#notesByTxHash: AztecMultiMap<string, string>;
|
|
35
|
-
#
|
|
42
|
+
#notesByIvpkM: AztecMultiMap<string, string>;
|
|
36
43
|
#nullifiedNotesByContract: AztecMultiMap<string, string>;
|
|
37
44
|
#nullifiedNotesByStorageSlot: AztecMultiMap<string, string>;
|
|
38
45
|
#nullifiedNotesByTxHash: AztecMultiMap<string, string>;
|
|
39
|
-
#
|
|
46
|
+
#nullifiedNotesByIvpkM: AztecMultiMap<string, string>;
|
|
40
47
|
#deferredNotes: AztecArray<Buffer | null>;
|
|
41
48
|
#deferredNotesByContract: AztecMultiMap<string, number>;
|
|
42
49
|
#syncedBlockPerPublicKey: AztecMap<string, number>;
|
|
@@ -44,6 +51,12 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
44
51
|
#contractInstances: AztecMap<string, Buffer>;
|
|
45
52
|
#db: AztecKVStore;
|
|
46
53
|
|
|
54
|
+
#outgoingNotes: AztecMap<string, Buffer>;
|
|
55
|
+
#outgoingNotesByContract: AztecMultiMap<string, string>;
|
|
56
|
+
#outgoingNotesByStorageSlot: AztecMultiMap<string, string>;
|
|
57
|
+
#outgoingNotesByTxHash: AztecMultiMap<string, string>;
|
|
58
|
+
#outgoingNotesByOvpkM: AztecMultiMap<string, string>;
|
|
59
|
+
|
|
47
60
|
constructor(private db: AztecKVStore) {
|
|
48
61
|
this.#db = db;
|
|
49
62
|
|
|
@@ -66,15 +79,21 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
66
79
|
this.#notesByContract = db.openMultiMap('notes_by_contract');
|
|
67
80
|
this.#notesByStorageSlot = db.openMultiMap('notes_by_storage_slot');
|
|
68
81
|
this.#notesByTxHash = db.openMultiMap('notes_by_tx_hash');
|
|
69
|
-
this.#
|
|
82
|
+
this.#notesByIvpkM = db.openMultiMap('notes_by_ivpk_m');
|
|
70
83
|
|
|
71
84
|
this.#nullifiedNotesByContract = db.openMultiMap('nullified_notes_by_contract');
|
|
72
85
|
this.#nullifiedNotesByStorageSlot = db.openMultiMap('nullified_notes_by_storage_slot');
|
|
73
86
|
this.#nullifiedNotesByTxHash = db.openMultiMap('nullified_notes_by_tx_hash');
|
|
74
|
-
this.#
|
|
87
|
+
this.#nullifiedNotesByIvpkM = db.openMultiMap('nullified_notes_by_ivpk_m');
|
|
75
88
|
|
|
76
89
|
this.#deferredNotes = db.openArray('deferred_notes');
|
|
77
90
|
this.#deferredNotesByContract = db.openMultiMap('deferred_notes_by_contract');
|
|
91
|
+
|
|
92
|
+
this.#outgoingNotes = db.openMap('outgoing_notes');
|
|
93
|
+
this.#outgoingNotesByContract = db.openMultiMap('outgoing_notes_by_contract');
|
|
94
|
+
this.#outgoingNotesByStorageSlot = db.openMultiMap('outgoing_notes_by_storage_slot');
|
|
95
|
+
this.#outgoingNotesByTxHash = db.openMultiMap('outgoing_notes_by_tx_hash');
|
|
96
|
+
this.#outgoingNotesByOvpkM = db.openMultiMap('outgoing_notes_by_ovpk_m');
|
|
78
97
|
}
|
|
79
98
|
|
|
80
99
|
public async getContract(
|
|
@@ -135,13 +154,13 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
135
154
|
return val?.map(b => Fr.fromBuffer(b));
|
|
136
155
|
}
|
|
137
156
|
|
|
138
|
-
async addNote(note:
|
|
139
|
-
await this.addNotes([note]);
|
|
157
|
+
async addNote(note: IncomingNoteDao): Promise<void> {
|
|
158
|
+
await this.addNotes([note], []);
|
|
140
159
|
}
|
|
141
160
|
|
|
142
|
-
addNotes(
|
|
161
|
+
addNotes(incomingNotes: IncomingNoteDao[], outgoingNotes: OutgoingNoteDao[]): Promise<void> {
|
|
143
162
|
return this.db.transaction(() => {
|
|
144
|
-
for (const dao of
|
|
163
|
+
for (const dao of incomingNotes) {
|
|
145
164
|
// store notes by their index in the notes hash tree
|
|
146
165
|
// this provides the uniqueness we need to store individual notes
|
|
147
166
|
// and should also return notes in the order that they were created.
|
|
@@ -152,7 +171,16 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
152
171
|
void this.#notesByContract.set(dao.contractAddress.toString(), noteIndex);
|
|
153
172
|
void this.#notesByStorageSlot.set(dao.storageSlot.toString(), noteIndex);
|
|
154
173
|
void this.#notesByTxHash.set(dao.txHash.toString(), noteIndex);
|
|
155
|
-
void this.#
|
|
174
|
+
void this.#notesByIvpkM.set(dao.ivpkM.toString(), noteIndex);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
for (const dao of outgoingNotes) {
|
|
178
|
+
const noteIndex = toBufferBE(dao.index, 32).toString('hex');
|
|
179
|
+
void this.#outgoingNotes.set(noteIndex, dao.toBuffer());
|
|
180
|
+
void this.#outgoingNotesByContract.set(dao.contractAddress.toString(), noteIndex);
|
|
181
|
+
void this.#outgoingNotesByStorageSlot.set(dao.storageSlot.toString(), noteIndex);
|
|
182
|
+
void this.#outgoingNotesByTxHash.set(dao.txHash.toString(), noteIndex);
|
|
183
|
+
void this.#outgoingNotesByOvpkM.set(dao.ovpkM.toString(), noteIndex);
|
|
156
184
|
}
|
|
157
185
|
});
|
|
158
186
|
}
|
|
@@ -207,7 +235,7 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
207
235
|
});
|
|
208
236
|
}
|
|
209
237
|
|
|
210
|
-
|
|
238
|
+
getIncomingNotes(filter: IncomingNotesFilter): Promise<IncomingNoteDao[]> {
|
|
211
239
|
const publicKey: PublicKey | undefined = filter.owner
|
|
212
240
|
? this.#getCompleteAddress(filter.owner)?.publicKeys.masterIncomingViewingPublicKey
|
|
213
241
|
: undefined;
|
|
@@ -218,7 +246,7 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
218
246
|
|
|
219
247
|
candidateNoteSources.push({
|
|
220
248
|
ids: publicKey
|
|
221
|
-
? this.#
|
|
249
|
+
? this.#notesByIvpkM.getValues(publicKey.toString())
|
|
222
250
|
: filter.txHash
|
|
223
251
|
? this.#notesByTxHash.getValues(filter.txHash.toString())
|
|
224
252
|
: filter.contractAddress
|
|
@@ -232,7 +260,7 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
232
260
|
if (filter.status == NoteStatus.ACTIVE_OR_NULLIFIED) {
|
|
233
261
|
candidateNoteSources.push({
|
|
234
262
|
ids: publicKey
|
|
235
|
-
? this.#
|
|
263
|
+
? this.#nullifiedNotesByIvpkM.getValues(publicKey.toString())
|
|
236
264
|
: filter.txHash
|
|
237
265
|
? this.#nullifiedNotesByTxHash.getValues(filter.txHash.toString())
|
|
238
266
|
: filter.contractAddress
|
|
@@ -244,7 +272,7 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
244
272
|
});
|
|
245
273
|
}
|
|
246
274
|
|
|
247
|
-
const result:
|
|
275
|
+
const result: IncomingNoteDao[] = [];
|
|
248
276
|
for (const { ids, notes } of candidateNoteSources) {
|
|
249
277
|
for (const id of ids) {
|
|
250
278
|
const serializedNote = notes.get(id);
|
|
@@ -252,7 +280,7 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
252
280
|
continue;
|
|
253
281
|
}
|
|
254
282
|
|
|
255
|
-
const note =
|
|
283
|
+
const note = IncomingNoteDao.fromBuffer(serializedNote);
|
|
256
284
|
if (filter.contractAddress && !note.contractAddress.equals(filter.contractAddress)) {
|
|
257
285
|
continue;
|
|
258
286
|
}
|
|
@@ -265,7 +293,11 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
265
293
|
continue;
|
|
266
294
|
}
|
|
267
295
|
|
|
268
|
-
if (publicKey && !note.
|
|
296
|
+
if (publicKey && !note.ivpkM.equals(publicKey)) {
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (filter.siloedNullifier && !note.siloedNullifier.equals(filter.siloedNullifier)) {
|
|
269
301
|
continue;
|
|
270
302
|
}
|
|
271
303
|
|
|
@@ -273,20 +305,66 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
273
305
|
}
|
|
274
306
|
}
|
|
275
307
|
|
|
276
|
-
return result;
|
|
308
|
+
return Promise.resolve(result);
|
|
277
309
|
}
|
|
278
310
|
|
|
279
|
-
|
|
280
|
-
|
|
311
|
+
getOutgoingNotes(filter: OutgoingNotesFilter): Promise<OutgoingNoteDao[]> {
|
|
312
|
+
const ovpkM: PublicKey | undefined = filter.owner
|
|
313
|
+
? this.#getCompleteAddress(filter.owner)?.publicKeys.masterOutgoingViewingPublicKey
|
|
314
|
+
: undefined;
|
|
315
|
+
|
|
316
|
+
// Check if ovpkM is truthy
|
|
317
|
+
const ids = ovpkM
|
|
318
|
+
? this.#outgoingNotesByOvpkM.getValues(ovpkM.toString())
|
|
319
|
+
: // If ovpkM is falsy, check if filter.txHash is truthy
|
|
320
|
+
filter.txHash
|
|
321
|
+
? this.#outgoingNotesByTxHash.getValues(filter.txHash.toString())
|
|
322
|
+
: // If both ovpkM and filter.txHash are falsy, check if filter.contractAddress is truthy
|
|
323
|
+
filter.contractAddress
|
|
324
|
+
? this.#outgoingNotesByContract.getValues(filter.contractAddress.toString())
|
|
325
|
+
: // If ovpkM, filter.txHash, and filter.contractAddress are all falsy, check if filter.storageSlot is truthy
|
|
326
|
+
filter.storageSlot
|
|
327
|
+
? this.#outgoingNotesByStorageSlot.getValues(filter.storageSlot.toString())
|
|
328
|
+
: // If none of the above conditions are met, retrieve all keys from this.#outgoingNotes
|
|
329
|
+
this.#outgoingNotes.keys();
|
|
330
|
+
|
|
331
|
+
const notes: OutgoingNoteDao[] = [];
|
|
332
|
+
for (const id of ids) {
|
|
333
|
+
const serializedNote = this.#outgoingNotes.get(id);
|
|
334
|
+
if (!serializedNote) {
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const note = OutgoingNoteDao.fromBuffer(serializedNote);
|
|
339
|
+
if (filter.contractAddress && !note.contractAddress.equals(filter.contractAddress)) {
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (filter.txHash && !note.txHash.equals(filter.txHash)) {
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (filter.storageSlot && !note.storageSlot.equals(filter.storageSlot!)) {
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (ovpkM && !note.ovpkM.equals(ovpkM)) {
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
notes.push(note);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return Promise.resolve(notes);
|
|
281
359
|
}
|
|
282
360
|
|
|
283
|
-
removeNullifiedNotes(nullifiers: Fr[], account: PublicKey): Promise<
|
|
361
|
+
removeNullifiedNotes(nullifiers: Fr[], account: PublicKey): Promise<IncomingNoteDao[]> {
|
|
284
362
|
if (nullifiers.length === 0) {
|
|
285
363
|
return Promise.resolve([]);
|
|
286
364
|
}
|
|
287
365
|
|
|
288
366
|
return this.#db.transaction(() => {
|
|
289
|
-
const nullifiedNotes:
|
|
367
|
+
const nullifiedNotes: IncomingNoteDao[] = [];
|
|
290
368
|
|
|
291
369
|
for (const nullifier of nullifiers) {
|
|
292
370
|
const noteIndex = this.#nullifierToNoteId.get(nullifier.toString());
|
|
@@ -301,8 +379,8 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
301
379
|
continue;
|
|
302
380
|
}
|
|
303
381
|
|
|
304
|
-
const note =
|
|
305
|
-
if (!note.
|
|
382
|
+
const note = IncomingNoteDao.fromBuffer(noteBuffer);
|
|
383
|
+
if (!note.ivpkM.equals(account)) {
|
|
306
384
|
// tried to nullify someone else's note
|
|
307
385
|
continue;
|
|
308
386
|
}
|
|
@@ -310,7 +388,7 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
310
388
|
nullifiedNotes.push(note);
|
|
311
389
|
|
|
312
390
|
void this.#notes.delete(noteIndex);
|
|
313
|
-
void this.#
|
|
391
|
+
void this.#notesByIvpkM.deleteValue(account.toString(), noteIndex);
|
|
314
392
|
void this.#notesByTxHash.deleteValue(note.txHash.toString(), noteIndex);
|
|
315
393
|
void this.#notesByContract.deleteValue(note.contractAddress.toString(), noteIndex);
|
|
316
394
|
void this.#notesByStorageSlot.deleteValue(note.storageSlot.toString(), noteIndex);
|
|
@@ -319,7 +397,7 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
319
397
|
void this.#nullifiedNotesByContract.set(note.contractAddress.toString(), noteIndex);
|
|
320
398
|
void this.#nullifiedNotesByStorageSlot.set(note.storageSlot.toString(), noteIndex);
|
|
321
399
|
void this.#nullifiedNotesByTxHash.set(note.txHash.toString(), noteIndex);
|
|
322
|
-
void this.#
|
|
400
|
+
void this.#nullifiedNotesByIvpkM.set(note.ivpkM.toString(), noteIndex);
|
|
323
401
|
|
|
324
402
|
void this.#nullifierToNoteId.delete(nullifier.toString());
|
|
325
403
|
}
|
|
@@ -328,6 +406,18 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
328
406
|
});
|
|
329
407
|
}
|
|
330
408
|
|
|
409
|
+
async addNullifiedNote(note: IncomingNoteDao): Promise<void> {
|
|
410
|
+
const noteIndex = toBufferBE(note.index, 32).toString('hex');
|
|
411
|
+
|
|
412
|
+
await this.#nullifiedNotes.set(noteIndex, note.toBuffer());
|
|
413
|
+
await this.#nullifiedNotesByContract.set(note.contractAddress.toString(), noteIndex);
|
|
414
|
+
await this.#nullifiedNotesByStorageSlot.set(note.storageSlot.toString(), noteIndex);
|
|
415
|
+
await this.#nullifiedNotesByTxHash.set(note.txHash.toString(), noteIndex);
|
|
416
|
+
await this.#nullifiedNotesByIvpkM.set(note.ivpkM.toString(), noteIndex);
|
|
417
|
+
|
|
418
|
+
return Promise.resolve();
|
|
419
|
+
}
|
|
420
|
+
|
|
331
421
|
async setHeader(header: Header): Promise<void> {
|
|
332
422
|
await this.#synchronizedBlock.set(header.toBuffer());
|
|
333
423
|
}
|
|
@@ -401,8 +491,16 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
401
491
|
return this.#syncedBlockPerPublicKey.set(publicKey.toString(), blockNumber);
|
|
402
492
|
}
|
|
403
493
|
|
|
404
|
-
estimateSize(): number {
|
|
405
|
-
const
|
|
494
|
+
async estimateSize(): Promise<number> {
|
|
495
|
+
const incomingNotesSize = Array.from(await this.getIncomingNotes({})).reduce(
|
|
496
|
+
(sum, note) => sum + note.getSize(),
|
|
497
|
+
0,
|
|
498
|
+
);
|
|
499
|
+
const outgoingNotesSize = Array.from(await this.getOutgoingNotes({})).reduce(
|
|
500
|
+
(sum, note) => sum + note.getSize(),
|
|
501
|
+
0,
|
|
502
|
+
);
|
|
503
|
+
|
|
406
504
|
const authWitsSize = Array.from(this.#authWitnesses.values()).reduce(
|
|
407
505
|
(sum, value) => sum + value.length * Fr.SIZE_IN_BYTES,
|
|
408
506
|
0,
|
|
@@ -410,6 +508,6 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
410
508
|
const addressesSize = this.#addresses.length * CompleteAddress.SIZE_IN_BYTES;
|
|
411
509
|
const treeRootsSize = Object.keys(MerkleTreeId).length * Fr.SIZE_IN_BYTES;
|
|
412
510
|
|
|
413
|
-
return
|
|
511
|
+
return incomingNotesSize + outgoingNotesSize + treeRootsSize + authWitsSize + addressesSize;
|
|
414
512
|
}
|
|
415
513
|
}
|