@aztec/pxe 0.11.1 → 0.13.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/contract_data_oracle/index.d.ts +9 -0
- package/dest/contract_data_oracle/index.d.ts.map +1 -1
- package/dest/contract_data_oracle/index.js +13 -1
- package/dest/contract_tree/index.js +2 -2
- package/dest/database/database.d.ts +17 -28
- package/dest/database/database.d.ts.map +1 -1
- package/dest/database/index.d.ts +0 -1
- package/dest/database/index.d.ts.map +1 -1
- package/dest/database/index.js +1 -2
- package/dest/database/memory_db.d.ts +8 -8
- package/dest/database/memory_db.d.ts.map +1 -1
- package/dest/database/memory_db.js +27 -19
- package/dest/database/note_dao.d.ts +61 -0
- package/dest/database/note_dao.d.ts.map +1 -0
- package/dest/database/note_dao.js +83 -0
- package/dest/kernel_oracle/index.js +2 -2
- package/dest/kernel_prover/kernel_prover.d.ts +4 -4
- package/dest/kernel_prover/kernel_prover.js +2 -2
- package/dest/note_processor/note_processor.d.ts +7 -6
- package/dest/note_processor/note_processor.d.ts.map +1 -1
- package/dest/note_processor/note_processor.js +31 -36
- package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
- package/dest/pxe_http/pxe_http_server.js +4 -3
- package/dest/pxe_service/pxe_service.d.ts +4 -4
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +33 -38
- package/dest/simulator_oracle/index.d.ts +2 -1
- package/dest/simulator_oracle/index.d.ts.map +1 -1
- package/dest/simulator_oracle/index.js +17 -6
- package/package.json +9 -9
- package/src/contract_data_oracle/index.ts +13 -0
- package/src/contract_tree/index.ts +1 -1
- package/src/database/database.ts +17 -28
- package/src/database/index.ts +0 -1
- package/src/database/memory_db.ts +33 -23
- package/src/database/note_dao.ts +90 -0
- package/src/kernel_oracle/index.ts +1 -1
- package/src/kernel_prover/kernel_prover.ts +4 -4
- package/src/note_processor/note_processor.ts +50 -48
- package/src/pxe_http/pxe_http_server.ts +4 -2
- package/src/pxe_service/pxe_service.ts +53 -51
- package/src/simulator_oracle/index.ts +29 -15
- package/dest/database/note_spending_info_dao.d.ts +0 -50
- package/dest/database/note_spending_info_dao.d.ts.map +0 -1
- package/dest/database/note_spending_info_dao.js +0 -24
- package/src/database/note_spending_info_dao.ts +0 -75
|
@@ -15,7 +15,7 @@ export class SimulatorOracle {
|
|
|
15
15
|
async getCompleteAddress(address) {
|
|
16
16
|
const completeAddress = await this.db.getCompleteAddress(address);
|
|
17
17
|
if (!completeAddress)
|
|
18
|
-
throw new Error(`No public key registered for address ${address.toString()}. Register it by calling pxe.registerRecipient(...) or pxe.registerAccount(...)`);
|
|
18
|
+
throw new Error(`No public key registered for address ${address.toString()}. Register it by calling pxe.registerRecipient(...) or pxe.registerAccount(...).\nSee docs for context: https://docs.aztec.network/dev_docs/contracts/common_errors#no-public-key-registered-error`);
|
|
19
19
|
return completeAddress;
|
|
20
20
|
}
|
|
21
21
|
async getAuthWitness(messageHash) {
|
|
@@ -25,12 +25,12 @@ export class SimulatorOracle {
|
|
|
25
25
|
return witness;
|
|
26
26
|
}
|
|
27
27
|
async getNotes(contractAddress, storageSlot) {
|
|
28
|
-
const noteDaos = await this.db.
|
|
29
|
-
return noteDaos.map(({ contractAddress, storageSlot, nonce,
|
|
28
|
+
const noteDaos = await this.db.getNotes({ contractAddress, storageSlot });
|
|
29
|
+
return noteDaos.map(({ contractAddress, storageSlot, nonce, note, innerNoteHash, siloedNullifier, index }) => ({
|
|
30
30
|
contractAddress,
|
|
31
31
|
storageSlot,
|
|
32
32
|
nonce,
|
|
33
|
-
|
|
33
|
+
note,
|
|
34
34
|
innerNoteHash,
|
|
35
35
|
siloedNullifier,
|
|
36
36
|
// PXE can use this index to get full MembershipWitness
|
|
@@ -45,6 +45,17 @@ export class SimulatorOracle {
|
|
|
45
45
|
debug,
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
|
+
async getFunctionArtifactByName(contractAddress, functionName) {
|
|
49
|
+
const artifact = await this.contractDataOracle.getFunctionArtifactByName(contractAddress, functionName);
|
|
50
|
+
if (!artifact) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const debug = await this.contractDataOracle.getFunctionDebugMetadata(contractAddress, artifact.selector);
|
|
54
|
+
return {
|
|
55
|
+
...artifact,
|
|
56
|
+
debug,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
48
59
|
async getPortalContractAddress(contractAddress) {
|
|
49
60
|
return await this.contractDataOracle.getPortalContractAddress(contractAddress);
|
|
50
61
|
}
|
|
@@ -60,7 +71,7 @@ export class SimulatorOracle {
|
|
|
60
71
|
const messageAndIndex = await this.stateInfoProvider.getL1ToL2MessageAndIndex(msgKey);
|
|
61
72
|
const message = messageAndIndex.message.toFieldArray();
|
|
62
73
|
const index = messageAndIndex.index;
|
|
63
|
-
const siblingPath = await this.stateInfoProvider.
|
|
74
|
+
const siblingPath = await this.stateInfoProvider.getL1ToL2MessageSiblingPath(index);
|
|
64
75
|
return {
|
|
65
76
|
message,
|
|
66
77
|
siblingPath: siblingPath.toFieldArray(),
|
|
@@ -88,4 +99,4 @@ export class SimulatorOracle {
|
|
|
88
99
|
return Promise.resolve(this.db.getHistoricBlockData());
|
|
89
100
|
}
|
|
90
101
|
}
|
|
91
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
102
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2ltdWxhdG9yX29yYWNsZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFXQSxPQUFPLEVBQVksWUFBWSxFQUFxQixNQUFNLGNBQWMsQ0FBQztBQUt6RTs7R0FFRztBQUNILE1BQU0sT0FBTyxlQUFlO0lBQzFCLFlBQ1Usa0JBQXNDLEVBQ3RDLEVBQVksRUFDWixRQUFrQixFQUNsQixpQkFBb0M7UUFIcEMsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUN0QyxPQUFFLEdBQUYsRUFBRSxDQUFVO1FBQ1osYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNsQixzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO0lBQzNDLENBQUM7SUFFSixZQUFZLENBQUMsZ0JBQThCLEVBQUUsTUFBaUI7UUFDNUQsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFFRCxLQUFLLENBQUMsa0JBQWtCLENBQUMsT0FBcUI7UUFDNUMsTUFBTSxlQUFlLEdBQUcsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2xFLElBQUksQ0FBQyxlQUFlO1lBQ2xCLE1BQU0sSUFBSSxLQUFLLENBQ2Isd0NBQXdDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsb01BQW9NLENBQy9QLENBQUM7UUFDSixPQUFPLGVBQWUsQ0FBQztJQUN6QixDQUFDO0lBRUQsS0FBSyxDQUFDLGNBQWMsQ0FBQyxXQUFlO1FBQ2xDLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLE9BQU87WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHlDQUF5QyxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FB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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.13.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dest/index.js",
|
|
6
6
|
"bin": "./dest/bin/index.js",
|
|
@@ -26,19 +26,19 @@
|
|
|
26
26
|
"jest": {
|
|
27
27
|
"preset": "ts-jest/presets/default-esm",
|
|
28
28
|
"moduleNameMapper": {
|
|
29
|
-
"^(\\.{1,2}/.*)\\.
|
|
29
|
+
"^(\\.{1,2}/.*)\\.[cm]?js$": "$1"
|
|
30
30
|
},
|
|
31
31
|
"testRegex": "./src/.*\\.test\\.(js|mjs|ts)$",
|
|
32
32
|
"rootDir": "./src"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@aztec/acir-simulator": "0.
|
|
36
|
-
"@aztec/circuits.js": "0.
|
|
37
|
-
"@aztec/ethereum": "0.
|
|
38
|
-
"@aztec/foundation": "0.
|
|
39
|
-
"@aztec/key-store": "0.
|
|
40
|
-
"@aztec/noir-compiler": "0.
|
|
41
|
-
"@aztec/types": "0.
|
|
35
|
+
"@aztec/acir-simulator": "0.13.0",
|
|
36
|
+
"@aztec/circuits.js": "0.13.0",
|
|
37
|
+
"@aztec/ethereum": "0.13.0",
|
|
38
|
+
"@aztec/foundation": "0.13.0",
|
|
39
|
+
"@aztec/key-store": "0.13.0",
|
|
40
|
+
"@aztec/noir-compiler": "0.13.0",
|
|
41
|
+
"@aztec/types": "0.13.0",
|
|
42
42
|
"koa": "^2.14.2",
|
|
43
43
|
"koa-router": "^12.0.0",
|
|
44
44
|
"lodash.omit": "^4.5.0",
|
|
@@ -44,6 +44,19 @@ export class ContractDataOracle {
|
|
|
44
44
|
return tree.getFunctionArtifact(selector);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Retrieves the artifact of a specified function within a given contract.
|
|
49
|
+
* The function is identified by its name, which is unique within a contract.
|
|
50
|
+
*
|
|
51
|
+
* @param contractAddress - The AztecAddress representing the contract containing the function.
|
|
52
|
+
* @param functionName - The name of the function.
|
|
53
|
+
* @returns The corresponding function's artifact as an object.
|
|
54
|
+
*/
|
|
55
|
+
public async getFunctionArtifactByName(contractAddress: AztecAddress, functionName: string) {
|
|
56
|
+
const contract = await this.db.getContract(contractAddress);
|
|
57
|
+
return contract?.functions.find(f => f.name === functionName);
|
|
58
|
+
}
|
|
59
|
+
|
|
47
60
|
/**
|
|
48
61
|
* Retrieves the debug metadata of a specified function within a given contract.
|
|
49
62
|
* The function is identified by its selector, which is a unique code generated from the function's signature.
|
|
@@ -154,7 +154,7 @@ export class ContractTree {
|
|
|
154
154
|
public async getContractMembershipWitness() {
|
|
155
155
|
const index = await this.getContractIndex();
|
|
156
156
|
|
|
157
|
-
const siblingPath = await this.stateInfoProvider.
|
|
157
|
+
const siblingPath = await this.stateInfoProvider.getContractSiblingPath(index);
|
|
158
158
|
return new MembershipWitness<typeof CONTRACT_TREE_HEIGHT>(
|
|
159
159
|
CONTRACT_TREE_HEIGHT,
|
|
160
160
|
index,
|
package/src/database/database.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js';
|
|
1
|
+
import { CompleteAddress, HistoricBlockData, PublicKey } from '@aztec/circuits.js';
|
|
2
2
|
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
3
3
|
import { Fr } from '@aztec/foundation/fields';
|
|
4
|
-
import { ContractDatabase, MerkleTreeId,
|
|
4
|
+
import { ContractDatabase, MerkleTreeId, NoteFilter } from '@aztec/types';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { NoteDao } from './note_dao.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* A database interface that provides methods for retrieving, adding, and removing transactional data related to Aztec
|
|
@@ -25,46 +25,35 @@ export interface Database extends ContractDatabase {
|
|
|
25
25
|
getAuthWitness(messageHash: Fr): Promise<Fr[]>;
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* @param contract - The contract address.
|
|
33
|
-
* @param storageSlot - A Fr object representing the storage slot to search for in the auxiliary data.
|
|
34
|
-
* @returns An array of NoteSpendingInfoDao objects that fulfill the contract address and storage slot criteria.
|
|
28
|
+
* Gets notes based on the provided filter.
|
|
29
|
+
* @param filter - The filter to apply to the notes.
|
|
30
|
+
* @returns The requested notes.
|
|
35
31
|
*/
|
|
36
|
-
|
|
32
|
+
getNotes(filter: NoteFilter): Promise<NoteDao[]>;
|
|
37
33
|
|
|
38
34
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* such as contract address and storage slot, in the database.
|
|
42
|
-
*
|
|
43
|
-
* @param noteSpendingInfoDao - The NoteSpendingInfoDao instance containing the auxiliary data of a transaction.
|
|
44
|
-
* @returns A promise that resolves when the auxiliary data is added to the database.
|
|
35
|
+
* Adds a note to DB.
|
|
36
|
+
* @param note - The note to add.
|
|
45
37
|
*/
|
|
46
|
-
|
|
38
|
+
addNote(note: NoteDao): Promise<void>;
|
|
47
39
|
|
|
48
40
|
/**
|
|
49
|
-
* Adds an array of
|
|
50
|
-
* This function is used to insert multiple
|
|
41
|
+
* Adds an array of notes to DB.
|
|
42
|
+
* This function is used to insert multiple notes to the database at once,
|
|
51
43
|
* which can improve performance when dealing with large numbers of transactions.
|
|
52
44
|
*
|
|
53
|
-
* @param
|
|
54
|
-
* @returns A Promise that resolves when all NoteSpendingInfoDaos have been successfully added to the noteSpendingInfoTable.
|
|
45
|
+
* @param notes - An array of notes.
|
|
55
46
|
*/
|
|
56
|
-
|
|
47
|
+
addNotes(notes: NoteDao[]): Promise<void>;
|
|
57
48
|
|
|
58
49
|
/**
|
|
59
|
-
* Remove nullified
|
|
60
|
-
* The function filters the records based on matching account and nullifier values, and updates the
|
|
61
|
-
* noteSpendingInfoTable with the remaining records. It returns an array of removed NoteSpendingInfoDao instances.
|
|
50
|
+
* Remove nullified notes associated with the given account and nullifiers.
|
|
62
51
|
*
|
|
63
52
|
* @param nullifiers - An array of Fr instances representing nullifiers to be matched.
|
|
64
53
|
* @param account - A PublicKey instance representing the account for which the records are being removed.
|
|
65
|
-
* @returns
|
|
54
|
+
* @returns Removed notes.
|
|
66
55
|
*/
|
|
67
|
-
|
|
56
|
+
removeNullifiedNotes(nullifiers: Fr[], account: PublicKey): Promise<NoteDao[]>;
|
|
68
57
|
|
|
69
58
|
/**
|
|
70
59
|
* Retrieve the stored Merkle tree roots from the database.
|
package/src/database/index.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js';
|
|
1
|
+
import { CompleteAddress, HistoricBlockData, PublicKey } from '@aztec/circuits.js';
|
|
2
2
|
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
3
3
|
import { Fr } from '@aztec/foundation/fields';
|
|
4
4
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
5
|
-
import { MerkleTreeId,
|
|
5
|
+
import { MerkleTreeId, NoteFilter } from '@aztec/types';
|
|
6
6
|
|
|
7
7
|
import { MemoryContractDatabase } from '../contract_database/index.js';
|
|
8
8
|
import { Database } from './database.js';
|
|
9
|
-
import {
|
|
9
|
+
import { NoteDao } from './note_dao.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* The MemoryDB class provides an in-memory implementation of a database to manage transactions and auxiliary data.
|
|
@@ -15,7 +15,7 @@ import { NoteSpendingInfoDao, getNoteSpendingInfoDaoSize } from './note_spending
|
|
|
15
15
|
* As an in-memory database, the stored data will not persist beyond the life of the application instance.
|
|
16
16
|
*/
|
|
17
17
|
export class MemoryDB extends MemoryContractDatabase implements Database {
|
|
18
|
-
private
|
|
18
|
+
private notesTable: NoteDao[] = [];
|
|
19
19
|
private treeRoots: Record<MerkleTreeId, Fr> | undefined;
|
|
20
20
|
private globalVariablesHash: Fr | undefined;
|
|
21
21
|
private addresses: CompleteAddress[] = [];
|
|
@@ -44,41 +44,51 @@ export class MemoryDB extends MemoryContractDatabase implements Database {
|
|
|
44
44
|
return Promise.resolve(this.authWitnesses[messageHash.toString()]);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
public
|
|
48
|
-
this.
|
|
47
|
+
public addNote(note: NoteDao) {
|
|
48
|
+
this.notesTable.push(note);
|
|
49
49
|
return Promise.resolve();
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
public
|
|
53
|
-
this.
|
|
52
|
+
public addNotes(notes: NoteDao[]) {
|
|
53
|
+
this.notesTable.push(...notes);
|
|
54
54
|
return Promise.resolve();
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
public
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
public async getNotes(filter: NoteFilter): Promise<NoteDao[]> {
|
|
58
|
+
let ownerPublicKey: PublicKey | undefined;
|
|
59
|
+
if (filter.owner !== undefined) {
|
|
60
|
+
const ownerCompleteAddress = await this.getCompleteAddress(filter.owner);
|
|
61
|
+
if (ownerCompleteAddress === undefined) {
|
|
62
|
+
throw new Error(`Owner ${filter.owner.toString()} not found in memory database`);
|
|
63
|
+
}
|
|
64
|
+
ownerPublicKey = ownerCompleteAddress.publicKey;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return this.notesTable.filter(
|
|
68
|
+
note =>
|
|
69
|
+
(filter.contractAddress == undefined || note.contractAddress.equals(filter.contractAddress)) &&
|
|
70
|
+
(filter.txHash == undefined || note.txHash.equals(filter.txHash)) &&
|
|
71
|
+
(filter.storageSlot == undefined || note.storageSlot.equals(filter.storageSlot!)) &&
|
|
72
|
+
(ownerPublicKey == undefined || note.publicKey.equals(ownerPublicKey!)),
|
|
62
73
|
);
|
|
63
|
-
return Promise.resolve(res);
|
|
64
74
|
}
|
|
65
75
|
|
|
66
|
-
public
|
|
76
|
+
public removeNullifiedNotes(nullifiers: Fr[], account: PublicKey) {
|
|
67
77
|
const nullifierSet = new Set(nullifiers.map(nullifier => nullifier.toString()));
|
|
68
|
-
const [remaining, removed] = this.
|
|
69
|
-
(acc: [
|
|
70
|
-
const nullifier =
|
|
71
|
-
if (
|
|
72
|
-
acc[1].push(
|
|
78
|
+
const [remaining, removed] = this.notesTable.reduce(
|
|
79
|
+
(acc: [NoteDao[], NoteDao[]], note) => {
|
|
80
|
+
const nullifier = note.siloedNullifier.toString();
|
|
81
|
+
if (note.publicKey.equals(account) && nullifierSet.has(nullifier)) {
|
|
82
|
+
acc[1].push(note);
|
|
73
83
|
} else {
|
|
74
|
-
acc[0].push(
|
|
84
|
+
acc[0].push(note);
|
|
75
85
|
}
|
|
76
86
|
return acc;
|
|
77
87
|
},
|
|
78
88
|
[[], []],
|
|
79
89
|
);
|
|
80
90
|
|
|
81
|
-
this.
|
|
91
|
+
this.notesTable = remaining;
|
|
82
92
|
|
|
83
93
|
return Promise.resolve(removed);
|
|
84
94
|
}
|
|
@@ -146,7 +156,7 @@ export class MemoryDB extends MemoryContractDatabase implements Database {
|
|
|
146
156
|
}
|
|
147
157
|
|
|
148
158
|
public estimateSize() {
|
|
149
|
-
const notesSize = this.
|
|
159
|
+
const notesSize = this.notesTable.reduce((sum, note) => sum + note.getSize(), 0);
|
|
150
160
|
const treeRootsSize = this.treeRoots ? Object.entries(this.treeRoots).length * Fr.SIZE_IN_BYTES : 0;
|
|
151
161
|
const authWits = Object.entries(this.authWitnesses);
|
|
152
162
|
const authWitsSize = authWits.reduce((sum, [key, value]) => sum + key.length + value.length * Fr.SIZE_IN_BYTES, 0);
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { AztecAddress, Fr, Point, PublicKey } from '@aztec/circuits.js';
|
|
2
|
+
import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer';
|
|
3
|
+
import { BufferReader, Note, TxHash } from '@aztec/types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A note with contextual data.
|
|
7
|
+
*/
|
|
8
|
+
export class NoteDao {
|
|
9
|
+
constructor(
|
|
10
|
+
/** The note as emitted from the Noir contract. */
|
|
11
|
+
public note: Note,
|
|
12
|
+
/** The contract address this note is created in. */
|
|
13
|
+
public contractAddress: AztecAddress,
|
|
14
|
+
/** The specific storage location of the note on the contract. */
|
|
15
|
+
public storageSlot: Fr,
|
|
16
|
+
/** The hash of the tx the note was created in. */
|
|
17
|
+
public txHash: TxHash,
|
|
18
|
+
/** The nonce of the note. */
|
|
19
|
+
public nonce: Fr,
|
|
20
|
+
/**
|
|
21
|
+
* Inner note hash of the note. This is customizable by the app circuit.
|
|
22
|
+
* We can use this value to compute siloedNoteHash and uniqueSiloedNoteHash.
|
|
23
|
+
*/
|
|
24
|
+
public innerNoteHash: Fr,
|
|
25
|
+
/** The nullifier of the note (siloed by contract address). */
|
|
26
|
+
public siloedNullifier: Fr,
|
|
27
|
+
/** The location of the relevant note in the note hash tree. */
|
|
28
|
+
public index: bigint,
|
|
29
|
+
/** The public key with which the note was encrypted. */
|
|
30
|
+
public publicKey: PublicKey,
|
|
31
|
+
) {}
|
|
32
|
+
|
|
33
|
+
toBuffer(): Buffer {
|
|
34
|
+
return Buffer.concat([
|
|
35
|
+
this.note.toBuffer(),
|
|
36
|
+
this.contractAddress.toBuffer(),
|
|
37
|
+
this.storageSlot.toBuffer(),
|
|
38
|
+
this.txHash.buffer,
|
|
39
|
+
this.nonce.toBuffer(),
|
|
40
|
+
this.innerNoteHash.toBuffer(),
|
|
41
|
+
this.siloedNullifier.toBuffer(),
|
|
42
|
+
toBufferBE(this.index, 32),
|
|
43
|
+
this.publicKey.toBuffer(),
|
|
44
|
+
]);
|
|
45
|
+
}
|
|
46
|
+
static fromBuffer(buffer: Buffer | BufferReader) {
|
|
47
|
+
const reader = BufferReader.asReader(buffer);
|
|
48
|
+
|
|
49
|
+
const note = Note.fromBuffer(reader);
|
|
50
|
+
const contractAddress = AztecAddress.fromBuffer(reader);
|
|
51
|
+
const storageSlot = Fr.fromBuffer(reader);
|
|
52
|
+
const txHash = new TxHash(reader.readBytes(TxHash.SIZE));
|
|
53
|
+
const nonce = Fr.fromBuffer(reader);
|
|
54
|
+
const innerNoteHash = Fr.fromBuffer(reader);
|
|
55
|
+
const siloedNullifier = Fr.fromBuffer(reader);
|
|
56
|
+
const index = toBigIntBE(reader.readBytes(32));
|
|
57
|
+
const publicKey = Point.fromBuffer(reader);
|
|
58
|
+
|
|
59
|
+
return new NoteDao(
|
|
60
|
+
note,
|
|
61
|
+
contractAddress,
|
|
62
|
+
storageSlot,
|
|
63
|
+
txHash,
|
|
64
|
+
nonce,
|
|
65
|
+
innerNoteHash,
|
|
66
|
+
siloedNullifier,
|
|
67
|
+
index,
|
|
68
|
+
publicKey,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
toString() {
|
|
73
|
+
return '0x' + this.toBuffer().toString('hex');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static fromString(str: string) {
|
|
77
|
+
const hex = str.replace(/^0x/, '');
|
|
78
|
+
return NoteDao.fromBuffer(Buffer.from(hex, 'hex'));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Returns the size in bytes of the Note Dao.
|
|
83
|
+
* @returns - Its size in bytes.
|
|
84
|
+
*/
|
|
85
|
+
public getSize() {
|
|
86
|
+
const indexSize = Math.ceil(Math.log2(Number(this.index)));
|
|
87
|
+
const noteSize = 4 + this.note.items.length * Fr.SIZE_IN_BYTES;
|
|
88
|
+
return noteSize + AztecAddress.SIZE_IN_BYTES + Fr.SIZE_IN_BYTES * 4 + TxHash.SIZE + Point.SIZE_IN_BYTES + indexSize;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -24,7 +24,7 @@ export class KernelOracle implements ProvingDataOracle {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
async getNoteMembershipWitness(leafIndex: bigint): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT>> {
|
|
27
|
-
const path = await this.node.
|
|
27
|
+
const path = await this.node.getNoteHashSiblingPath(leafIndex);
|
|
28
28
|
return new MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT>(
|
|
29
29
|
path.pathSize,
|
|
30
30
|
leafIndex,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ExecutionResult,
|
|
1
|
+
import { ExecutionResult, NoteAndSlot } from '@aztec/acir-simulator';
|
|
2
2
|
import {
|
|
3
3
|
AztecAddress,
|
|
4
4
|
CONTRACT_TREE_HEIGHT,
|
|
@@ -42,7 +42,7 @@ export interface OutputNoteData {
|
|
|
42
42
|
/**
|
|
43
43
|
* The encrypted note data for an output note.
|
|
44
44
|
*/
|
|
45
|
-
data:
|
|
45
|
+
data: NoteAndSlot;
|
|
46
46
|
/**
|
|
47
47
|
* The unique value representing the note.
|
|
48
48
|
*/
|
|
@@ -231,11 +231,11 @@ export class KernelProver {
|
|
|
231
231
|
|
|
232
232
|
/**
|
|
233
233
|
* Retrieves the new output notes for a given execution result.
|
|
234
|
-
* The function maps over the new
|
|
234
|
+
* The function maps over the new notes and associates them with their corresponding
|
|
235
235
|
* commitments in the public inputs of the execution result. It also includes the contract address
|
|
236
236
|
* from the call context of the public inputs.
|
|
237
237
|
*
|
|
238
|
-
* @param executionResult - The execution result object containing
|
|
238
|
+
* @param executionResult - The execution result object containing notes and public inputs.
|
|
239
239
|
* @returns An array of OutputNoteData objects, each representing an output note with its associated data.
|
|
240
240
|
*/
|
|
241
241
|
private async getNewNotes(executionResult: ExecutionResult): Promise<OutputNoteData[]> {
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { CircuitsWasm, MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX } from '@aztec/circuits.js';
|
|
1
|
+
import { CircuitsWasm, MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, PublicKey } from '@aztec/circuits.js';
|
|
2
2
|
import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/abis';
|
|
3
3
|
import { Grumpkin } from '@aztec/circuits.js/barretenberg';
|
|
4
4
|
import { Fr } from '@aztec/foundation/fields';
|
|
5
5
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
6
6
|
import { Timer } from '@aztec/foundation/timer';
|
|
7
|
-
import { AztecNode, KeyStore, L2BlockContext, L2BlockL2Logs
|
|
7
|
+
import { AztecNode, KeyStore, L1NotePayload, L2BlockContext, L2BlockL2Logs } from '@aztec/types';
|
|
8
8
|
import { NoteProcessorStats } from '@aztec/types/stats';
|
|
9
9
|
|
|
10
|
-
import { Database
|
|
10
|
+
import { Database } from '../database/index.js';
|
|
11
|
+
import { NoteDao } from '../database/note_dao.js';
|
|
11
12
|
import { getAcirSimulator } from '../simulator/index.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -19,9 +20,9 @@ interface ProcessedData {
|
|
|
19
20
|
*/
|
|
20
21
|
blockContext: L2BlockContext;
|
|
21
22
|
/**
|
|
22
|
-
*
|
|
23
|
+
* DAOs of processed notes.
|
|
23
24
|
*/
|
|
24
|
-
|
|
25
|
+
noteDaos: NoteDao[];
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
/**
|
|
@@ -92,22 +93,23 @@ export class NoteProcessor {
|
|
|
92
93
|
return;
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
const
|
|
96
|
+
const blocksAndNotes: ProcessedData[] = [];
|
|
96
97
|
const curve = await Grumpkin.new();
|
|
97
98
|
|
|
98
99
|
// Iterate over both blocks and encrypted logs.
|
|
99
100
|
for (let blockIndex = 0; blockIndex < encryptedL2BlockLogs.length; ++blockIndex) {
|
|
100
101
|
this.stats.blocks++;
|
|
101
102
|
const { txLogs } = encryptedL2BlockLogs[blockIndex];
|
|
102
|
-
const
|
|
103
|
+
const blockContext = l2BlockContexts[blockIndex];
|
|
104
|
+
const block = blockContext.block;
|
|
103
105
|
const dataStartIndexForBlock = block.startNoteHashTreeSnapshot.nextAvailableLeafIndex;
|
|
104
106
|
|
|
105
107
|
// We are using set for `userPertainingTxIndices` to avoid duplicates. This would happen in case there were
|
|
106
108
|
// multiple encrypted logs in a tx pertaining to a user.
|
|
107
|
-
const
|
|
109
|
+
const noteDaos: NoteDao[] = [];
|
|
108
110
|
const privateKey = await this.keyStore.getAccountPrivateKey(this.publicKey);
|
|
109
111
|
|
|
110
|
-
// Iterate over all the encrypted logs and try decrypting them. If successful, store the note
|
|
112
|
+
// Iterate over all the encrypted logs and try decrypting them. If successful, store the note.
|
|
111
113
|
for (let indexOfTxInABlock = 0; indexOfTxInABlock < txLogs.length; ++indexOfTxInABlock) {
|
|
112
114
|
this.stats.txs++;
|
|
113
115
|
const dataStartIndexForTx = dataStartIndexForBlock + indexOfTxInABlock * MAX_NEW_COMMITMENTS_PER_TX;
|
|
@@ -126,26 +128,31 @@ export class NoteProcessor {
|
|
|
126
128
|
for (const functionLogs of txFunctionLogs) {
|
|
127
129
|
for (const logs of functionLogs.logs) {
|
|
128
130
|
this.stats.seen++;
|
|
129
|
-
const
|
|
130
|
-
if (
|
|
131
|
+
const payload = L1NotePayload.fromEncryptedBuffer(logs, privateKey, curve);
|
|
132
|
+
if (payload) {
|
|
131
133
|
// We have successfully decrypted the data.
|
|
132
134
|
try {
|
|
133
135
|
const { commitmentIndex, nonce, innerNoteHash, siloedNullifier } = await this.findNoteIndexAndNullifier(
|
|
134
136
|
newCommitments,
|
|
135
137
|
newNullifiers[0],
|
|
136
|
-
|
|
138
|
+
payload,
|
|
137
139
|
excludedIndices,
|
|
138
140
|
);
|
|
139
141
|
const index = BigInt(dataStartIndexForTx + commitmentIndex);
|
|
140
142
|
excludedIndices.add(commitmentIndex);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
143
|
+
noteDaos.push(
|
|
144
|
+
new NoteDao(
|
|
145
|
+
payload.note,
|
|
146
|
+
payload.contractAddress,
|
|
147
|
+
payload.storageSlot,
|
|
148
|
+
blockContext.getTxHash(indexOfTxInABlock),
|
|
149
|
+
nonce,
|
|
150
|
+
innerNoteHash,
|
|
151
|
+
siloedNullifier,
|
|
152
|
+
index,
|
|
153
|
+
this.publicKey,
|
|
154
|
+
),
|
|
155
|
+
);
|
|
149
156
|
this.stats.decrypted++;
|
|
150
157
|
} catch (e) {
|
|
151
158
|
this.stats.failed++;
|
|
@@ -156,13 +163,13 @@ export class NoteProcessor {
|
|
|
156
163
|
}
|
|
157
164
|
}
|
|
158
165
|
|
|
159
|
-
|
|
166
|
+
blocksAndNotes.push({
|
|
160
167
|
blockContext: l2BlockContexts[blockIndex],
|
|
161
|
-
|
|
168
|
+
noteDaos,
|
|
162
169
|
});
|
|
163
170
|
}
|
|
164
171
|
|
|
165
|
-
await this.
|
|
172
|
+
await this.processBlocksAndNotes(blocksAndNotes);
|
|
166
173
|
|
|
167
174
|
this.syncedToBlock = l2BlockContexts[l2BlockContexts.length - 1].block.number;
|
|
168
175
|
this.log(`Synched block ${this.syncedToBlock}`);
|
|
@@ -173,20 +180,20 @@ export class NoteProcessor {
|
|
|
173
180
|
* commitment for the current tx matches this value.
|
|
174
181
|
* Compute the nullifier for a given transaction auxiliary data.
|
|
175
182
|
* The nullifier is calculated using the private key of the account,
|
|
176
|
-
* contract address, and note
|
|
183
|
+
* contract address, and the note associated with the l1NotePayload.
|
|
177
184
|
* This method assists in identifying spent commitments in the private state.
|
|
178
185
|
* @param commitments - Commitments in the tx. One of them should be the note's commitment.
|
|
179
186
|
* @param firstNullifier - First nullifier in the tx.
|
|
180
|
-
* @param
|
|
187
|
+
* @param l1NotePayload - An instance of l1NotePayload containing transaction details.
|
|
181
188
|
* @param excludedIndices - Indices that have been assigned a note in the same tx. Notes in a tx can have the same
|
|
182
|
-
*
|
|
189
|
+
* l1NotePayload. We need to find a different index for each replicate.
|
|
183
190
|
* @returns Information for a decrypted note, including the index of its commitment, nonce, inner note
|
|
184
191
|
* hash, and the siloed nullifier. Throw if cannot find the nonce for the note.
|
|
185
192
|
*/
|
|
186
193
|
private async findNoteIndexAndNullifier(
|
|
187
194
|
commitments: Fr[],
|
|
188
195
|
firstNullifier: Fr,
|
|
189
|
-
{ contractAddress, storageSlot,
|
|
196
|
+
{ contractAddress, storageSlot, note }: L1NotePayload,
|
|
190
197
|
excludedIndices: Set<number>,
|
|
191
198
|
) {
|
|
192
199
|
const wasm = await CircuitsWasm.get();
|
|
@@ -204,12 +211,7 @@ export class NoteProcessor {
|
|
|
204
211
|
|
|
205
212
|
const expectedNonce = computeCommitmentNonce(wasm, firstNullifier, commitmentIndex);
|
|
206
213
|
({ innerNoteHash, siloedNoteHash, uniqueSiloedNoteHash, innerNullifier } =
|
|
207
|
-
await this.simulator.computeNoteHashAndNullifier(
|
|
208
|
-
contractAddress,
|
|
209
|
-
expectedNonce,
|
|
210
|
-
storageSlot,
|
|
211
|
-
notePreimage.items,
|
|
212
|
-
));
|
|
214
|
+
await this.simulator.computeNoteHashAndNullifier(contractAddress, expectedNonce, storageSlot, note));
|
|
213
215
|
if (commitment.equals(uniqueSiloedNoteHash)) {
|
|
214
216
|
nonce = expectedNonce;
|
|
215
217
|
break;
|
|
@@ -253,28 +255,28 @@ https://github.com/AztecProtocol/aztec-packages/issues/1641`;
|
|
|
253
255
|
* transaction auxiliary data from the database. This function keeps track of new nullifiers
|
|
254
256
|
* and ensures all other transactions are updated with newly settled block information.
|
|
255
257
|
*
|
|
256
|
-
* @param
|
|
258
|
+
* @param blocksAndNotes - Array of objects containing L2BlockContexts, user-pertaining transaction indices, and NoteDaos.
|
|
257
259
|
*/
|
|
258
|
-
private async
|
|
259
|
-
const
|
|
260
|
-
if (
|
|
261
|
-
await this.db.
|
|
262
|
-
|
|
260
|
+
private async processBlocksAndNotes(blocksAndNotes: ProcessedData[]) {
|
|
261
|
+
const noteDaos = blocksAndNotes.flatMap(b => b.noteDaos);
|
|
262
|
+
if (noteDaos.length) {
|
|
263
|
+
await this.db.addNotes(noteDaos);
|
|
264
|
+
noteDaos.forEach(noteDao => {
|
|
263
265
|
this.log(
|
|
264
|
-
`Added note
|
|
265
|
-
|
|
266
|
-
} with nullifier ${
|
|
266
|
+
`Added note for contract ${noteDao.contractAddress} at slot ${
|
|
267
|
+
noteDao.storageSlot
|
|
268
|
+
} with nullifier ${noteDao.siloedNullifier.toString()}`,
|
|
267
269
|
);
|
|
268
270
|
});
|
|
269
271
|
}
|
|
270
272
|
|
|
271
|
-
const newNullifiers: Fr[] =
|
|
272
|
-
const
|
|
273
|
-
|
|
273
|
+
const newNullifiers: Fr[] = blocksAndNotes.flatMap(b => b.blockContext.block.newNullifiers);
|
|
274
|
+
const removedNotes = await this.db.removeNullifiedNotes(newNullifiers, this.publicKey);
|
|
275
|
+
removedNotes.forEach(noteDao => {
|
|
274
276
|
this.log(
|
|
275
|
-
`Removed note
|
|
276
|
-
|
|
277
|
-
} with nullifier ${
|
|
277
|
+
`Removed note for contract ${noteDao.contractAddress} at slot ${
|
|
278
|
+
noteDao.storageSlot
|
|
279
|
+
} with nullifier ${noteDao.siloedNullifier.toString()}`,
|
|
278
280
|
);
|
|
279
281
|
});
|
|
280
282
|
}
|