@aztec/pxe 0.20.0 → 0.21.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/config/index.d.ts +1 -1
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +3 -3
- package/dest/contract_data_oracle/index.js +1 -1
- package/dest/contract_tree/index.js +1 -1
- package/dest/database/contracts/contract_artifact_db.d.ts +19 -0
- package/dest/database/contracts/contract_artifact_db.d.ts.map +1 -0
- package/dest/database/contracts/contract_artifact_db.js +2 -0
- package/dest/database/contracts/contract_instance_db.d.ts +18 -0
- package/dest/database/contracts/contract_instance_db.d.ts.map +1 -0
- package/dest/database/contracts/contract_instance_db.js +2 -0
- 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/kv_pxe_database.d.ts +11 -10
- package/dest/database/kv_pxe_database.d.ts.map +1 -1
- package/dest/database/kv_pxe_database.js +139 -130
- package/dest/database/pxe_database.d.ts +8 -17
- 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 +27 -22
- package/dest/kernel_oracle/index.d.ts +5 -3
- package/dest/kernel_oracle/index.d.ts.map +1 -1
- package/dest/kernel_oracle/index.js +9 -6
- package/dest/kernel_prover/kernel_prover.d.ts +1 -0
- package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
- package/dest/kernel_prover/kernel_prover.js +17 -3
- package/dest/kernel_prover/proving_data_oracle.d.ts +8 -1
- package/dest/kernel_prover/proving_data_oracle.d.ts.map +1 -1
- package/dest/note_processor/note_processor.js +1 -1
- package/dest/note_processor/produce_note_dao.js +1 -1
- package/dest/pxe_http/pxe_http_server.d.ts +0 -23
- package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
- package/dest/pxe_http/pxe_http_server.js +2 -4
- package/dest/pxe_service/create_pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/create_pxe_service.js +3 -3
- package/dest/pxe_service/pxe_service.d.ts +1 -0
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +24 -4
- package/dest/simulator_oracle/index.d.ts +3 -3
- package/dest/simulator_oracle/index.d.ts.map +1 -1
- package/dest/simulator_oracle/index.js +5 -5
- package/dest/synchronizer/synchronizer.d.ts +1 -1
- package/dest/synchronizer/synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/synchronizer.js +7 -15
- package/package.json +12 -11
- package/dest/database/memory_db.d.ts +0 -59
- package/dest/database/memory_db.d.ts.map +0 -1
- package/dest/database/memory_db.js +0 -170
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import { MerkleTreeId } from '@aztec/circuit-types';
|
|
2
|
-
import { BlockHeader, CompleteAddress } from '@aztec/circuits.js';
|
|
3
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
4
|
-
import { createDebugLogger } from '@aztec/foundation/log';
|
|
5
|
-
import { MemoryContractDatabase } from '../contract_database/index.js';
|
|
6
|
-
/**
|
|
7
|
-
* The MemoryDB class provides an in-memory implementation of a database to manage transactions and auxiliary data.
|
|
8
|
-
* It extends the MemoryContractDatabase, allowing it to store contract-related data as well.
|
|
9
|
-
* The class offers methods to add, fetch, and remove transaction records and auxiliary data based on various filters such as transaction hash, address, and storage slot.
|
|
10
|
-
* As an in-memory database, the stored data will not persist beyond the life of the application instance.
|
|
11
|
-
*/
|
|
12
|
-
export class MemoryDB extends MemoryContractDatabase {
|
|
13
|
-
constructor(logSuffix) {
|
|
14
|
-
super(createDebugLogger(logSuffix ? 'aztec:memory_db_' + logSuffix : 'aztec:memory_db'));
|
|
15
|
-
this.notesTable = [];
|
|
16
|
-
this.deferredNotesTable = [];
|
|
17
|
-
this.addresses = [];
|
|
18
|
-
this.authWitnesses = {};
|
|
19
|
-
this.syncedBlockPerPublicKey = new Map();
|
|
20
|
-
// A capsule is a "blob" of data that is passed to the contract through an oracle.
|
|
21
|
-
// We are using a stack to keep track of the capsules that are passed to the contract.
|
|
22
|
-
this.capsuleStack = [];
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Add a auth witness to the database.
|
|
26
|
-
* @param messageHash - The message hash.
|
|
27
|
-
* @param witness - An array of field elements representing the auth witness.
|
|
28
|
-
*/
|
|
29
|
-
addAuthWitness(messageHash, witness) {
|
|
30
|
-
this.authWitnesses[messageHash.toString()] = witness;
|
|
31
|
-
return Promise.resolve();
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Fetching the auth witness for a given message hash.
|
|
35
|
-
* @param messageHash - The message hash.
|
|
36
|
-
* @returns A Promise that resolves to an array of field elements representing the auth witness.
|
|
37
|
-
*/
|
|
38
|
-
getAuthWitness(messageHash) {
|
|
39
|
-
return Promise.resolve(this.authWitnesses[messageHash.toString()]);
|
|
40
|
-
}
|
|
41
|
-
addNote(note) {
|
|
42
|
-
this.notesTable.push(note);
|
|
43
|
-
return Promise.resolve();
|
|
44
|
-
}
|
|
45
|
-
addDeferredNotes(notes) {
|
|
46
|
-
this.deferredNotesTable.push(...notes);
|
|
47
|
-
return Promise.resolve();
|
|
48
|
-
}
|
|
49
|
-
getDeferredNotesByContract(contractAddress) {
|
|
50
|
-
return Promise.resolve(this.deferredNotesTable.filter(note => note.contractAddress.equals(contractAddress)));
|
|
51
|
-
}
|
|
52
|
-
removeDeferredNotesByContract(contractAddress) {
|
|
53
|
-
const removed = [];
|
|
54
|
-
this.deferredNotesTable = this.deferredNotesTable.filter(note => {
|
|
55
|
-
if (note.contractAddress.equals(contractAddress)) {
|
|
56
|
-
removed.push(note);
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
return true;
|
|
60
|
-
});
|
|
61
|
-
return Promise.resolve(removed);
|
|
62
|
-
}
|
|
63
|
-
addCapsule(capsule) {
|
|
64
|
-
this.capsuleStack.push(capsule);
|
|
65
|
-
return Promise.resolve();
|
|
66
|
-
}
|
|
67
|
-
popCapsule() {
|
|
68
|
-
return Promise.resolve(this.capsuleStack.pop());
|
|
69
|
-
}
|
|
70
|
-
addNotes(notes) {
|
|
71
|
-
this.notesTable.push(...notes);
|
|
72
|
-
return Promise.resolve();
|
|
73
|
-
}
|
|
74
|
-
async getNotes(filter) {
|
|
75
|
-
let ownerPublicKey;
|
|
76
|
-
if (filter.owner !== undefined) {
|
|
77
|
-
const ownerCompleteAddress = await this.getCompleteAddress(filter.owner);
|
|
78
|
-
if (ownerCompleteAddress === undefined) {
|
|
79
|
-
throw new Error(`Owner ${filter.owner.toString()} not found in memory database`);
|
|
80
|
-
}
|
|
81
|
-
ownerPublicKey = ownerCompleteAddress.publicKey;
|
|
82
|
-
}
|
|
83
|
-
return this.notesTable.filter(note => (filter.contractAddress == undefined || note.contractAddress.equals(filter.contractAddress)) &&
|
|
84
|
-
(filter.txHash == undefined || note.txHash.equals(filter.txHash)) &&
|
|
85
|
-
(filter.storageSlot == undefined || note.storageSlot.equals(filter.storageSlot)) &&
|
|
86
|
-
(ownerPublicKey == undefined || note.publicKey.equals(ownerPublicKey)));
|
|
87
|
-
}
|
|
88
|
-
removeNullifiedNotes(nullifiers, account) {
|
|
89
|
-
const nullifierSet = new Set(nullifiers.map(nullifier => nullifier.toString()));
|
|
90
|
-
const [remaining, removed] = this.notesTable.reduce((acc, note) => {
|
|
91
|
-
const nullifier = note.siloedNullifier.toString();
|
|
92
|
-
if (note.publicKey.equals(account) && nullifierSet.has(nullifier)) {
|
|
93
|
-
acc[1].push(note);
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
acc[0].push(note);
|
|
97
|
-
}
|
|
98
|
-
return acc;
|
|
99
|
-
}, [[], []]);
|
|
100
|
-
this.notesTable = remaining;
|
|
101
|
-
return Promise.resolve(removed);
|
|
102
|
-
}
|
|
103
|
-
getTreeRoots() {
|
|
104
|
-
const roots = this.treeRoots;
|
|
105
|
-
if (!roots) {
|
|
106
|
-
throw new Error(`Tree roots not set in memory database`);
|
|
107
|
-
}
|
|
108
|
-
return roots;
|
|
109
|
-
}
|
|
110
|
-
setTreeRoots(roots) {
|
|
111
|
-
this.treeRoots = roots;
|
|
112
|
-
}
|
|
113
|
-
getBlockHeader() {
|
|
114
|
-
const roots = this.getTreeRoots();
|
|
115
|
-
if (!this.globalVariablesHash) {
|
|
116
|
-
throw new Error(`Global variables hash not set in memory database`);
|
|
117
|
-
}
|
|
118
|
-
return new BlockHeader(roots[MerkleTreeId.NOTE_HASH_TREE], roots[MerkleTreeId.NULLIFIER_TREE], roots[MerkleTreeId.CONTRACT_TREE], roots[MerkleTreeId.L1_TO_L2_MESSAGE_TREE], roots[MerkleTreeId.ARCHIVE], Fr.ZERO, // todo: private kernel vk tree root
|
|
119
|
-
roots[MerkleTreeId.PUBLIC_DATA_TREE], this.globalVariablesHash);
|
|
120
|
-
}
|
|
121
|
-
setBlockData(blockNumber, blockHeader) {
|
|
122
|
-
this.globalVariablesHash = blockHeader.globalVariablesHash;
|
|
123
|
-
this.blockNumber = blockNumber;
|
|
124
|
-
this.setTreeRoots({
|
|
125
|
-
[MerkleTreeId.NOTE_HASH_TREE]: blockHeader.noteHashTreeRoot,
|
|
126
|
-
[MerkleTreeId.NULLIFIER_TREE]: blockHeader.nullifierTreeRoot,
|
|
127
|
-
[MerkleTreeId.CONTRACT_TREE]: blockHeader.contractTreeRoot,
|
|
128
|
-
[MerkleTreeId.L1_TO_L2_MESSAGE_TREE]: blockHeader.l1ToL2MessageTreeRoot,
|
|
129
|
-
[MerkleTreeId.ARCHIVE]: blockHeader.archiveRoot,
|
|
130
|
-
[MerkleTreeId.PUBLIC_DATA_TREE]: blockHeader.publicDataTreeRoot,
|
|
131
|
-
});
|
|
132
|
-
return Promise.resolve();
|
|
133
|
-
}
|
|
134
|
-
getBlockNumber() {
|
|
135
|
-
return this.blockNumber;
|
|
136
|
-
}
|
|
137
|
-
addCompleteAddress(completeAddress) {
|
|
138
|
-
const accountIndex = this.addresses.findIndex(r => r.address.equals(completeAddress.address));
|
|
139
|
-
if (accountIndex !== -1) {
|
|
140
|
-
if (this.addresses[accountIndex].equals(completeAddress)) {
|
|
141
|
-
return Promise.resolve(false);
|
|
142
|
-
}
|
|
143
|
-
return Promise.reject(new Error(`Complete address with aztec address ${completeAddress.address.toString()} but different public key or partial key already exists in memory database`));
|
|
144
|
-
}
|
|
145
|
-
this.addresses.push(completeAddress);
|
|
146
|
-
return Promise.resolve(true);
|
|
147
|
-
}
|
|
148
|
-
getCompleteAddress(address) {
|
|
149
|
-
const recipient = this.addresses.find(r => r.address.equals(address));
|
|
150
|
-
return Promise.resolve(recipient);
|
|
151
|
-
}
|
|
152
|
-
getCompleteAddresses() {
|
|
153
|
-
return Promise.resolve(this.addresses);
|
|
154
|
-
}
|
|
155
|
-
getSynchedBlockNumberForPublicKey(publicKey) {
|
|
156
|
-
return this.syncedBlockPerPublicKey.get(publicKey.toString());
|
|
157
|
-
}
|
|
158
|
-
setSynchedBlockNumberForPublicKey(publicKey, blockNumber) {
|
|
159
|
-
this.syncedBlockPerPublicKey.set(publicKey.toString(), blockNumber);
|
|
160
|
-
return Promise.resolve(true);
|
|
161
|
-
}
|
|
162
|
-
estimateSize() {
|
|
163
|
-
const notesSize = this.notesTable.reduce((sum, note) => sum + note.getSize(), 0);
|
|
164
|
-
const treeRootsSize = this.treeRoots ? Object.entries(this.treeRoots).length * Fr.SIZE_IN_BYTES : 0;
|
|
165
|
-
const authWits = Object.entries(this.authWitnesses);
|
|
166
|
-
const authWitsSize = authWits.reduce((sum, [key, value]) => sum + key.length + value.length * Fr.SIZE_IN_BYTES, 0);
|
|
167
|
-
return notesSize + treeRootsSize + authWitsSize + this.addresses.length * CompleteAddress.SIZE_IN_BYTES;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5X2RiLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RhdGFiYXNlL21lbW9yeV9kYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFjLE1BQU0sc0JBQXNCLENBQUM7QUFDaEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQWEsTUFBTSxvQkFBb0IsQ0FBQztBQUU3RSxPQUFPLEVBQUUsRUFBRSxFQUFTLE1BQU0sMEJBQTBCLENBQUM7QUFDckQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFMUQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFLdkU7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sUUFBUyxTQUFRLHNCQUFzQjtJQWFsRCxZQUFZLFNBQWtCO1FBQzVCLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO1FBYm5GLGVBQVUsR0FBYyxFQUFFLENBQUM7UUFDM0IsdUJBQWtCLEdBQXNCLEVBQUUsQ0FBQztRQUkzQyxjQUFTLEdBQXNCLEVBQUUsQ0FBQztRQUNsQyxrQkFBYSxHQUF5QixFQUFFLENBQUM7UUFDekMsNEJBQXVCLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7UUFDNUQsa0ZBQWtGO1FBQ2xGLHNGQUFzRjtRQUM5RSxpQkFBWSxHQUFXLEVBQUUsQ0FBQztJQUlsQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLGNBQWMsQ0FBQyxXQUFlLEVBQUUsT0FBYTtRQUNsRCxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQztRQUNyRCxPQUFPLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJ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
|