@aztec/pxe 0.76.4 → 0.77.0-testnet-ignition.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bin/index.js +4 -6
- package/dest/config/index.d.ts +2 -2
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +20 -23
- package/dest/config/package_info.js +4 -2
- package/dest/contract_data_oracle/index.d.ts +10 -10
- package/dest/contract_data_oracle/index.d.ts.map +1 -1
- package/dest/contract_data_oracle/index.js +74 -89
- package/dest/contract_data_oracle/private_functions_tree.d.ts +5 -4
- package/dest/contract_data_oracle/private_functions_tree.d.ts.map +1 -1
- package/dest/contract_data_oracle/private_functions_tree.js +47 -51
- package/dest/database/contracts/contract_artifact_db.d.ts +2 -2
- package/dest/database/contracts/contract_artifact_db.d.ts.map +1 -1
- package/dest/database/contracts/contract_artifact_db.js +3 -2
- package/dest/database/contracts/contract_instance_db.d.ts +2 -1
- package/dest/database/contracts/contract_instance_db.d.ts.map +1 -1
- package/dest/database/contracts/contract_instance_db.js +3 -2
- package/dest/database/index.js +0 -1
- package/dest/database/kv_pxe_database.d.ts +9 -5
- package/dest/database/kv_pxe_database.d.ts.map +1 -1
- package/dest/database/kv_pxe_database.js +244 -257
- package/dest/database/note_dao.d.ts +13 -10
- package/dest/database/note_dao.d.ts.map +1 -1
- package/dest/database/note_dao.js +35 -48
- package/dest/database/outgoing_note_dao.d.ts +6 -3
- package/dest/database/outgoing_note_dao.d.ts.map +1 -1
- package/dest/database/outgoing_note_dao.js +25 -37
- package/dest/database/pxe_database.d.ts +12 -8
- package/dest/database/pxe_database.d.ts.map +1 -1
- package/dest/database/pxe_database.js +4 -2
- package/dest/database/pxe_database_test_suite.d.ts +1 -1
- package/dest/database/pxe_database_test_suite.d.ts.map +1 -1
- package/dest/database/pxe_database_test_suite.js +286 -147
- package/dest/index.d.ts +1 -6
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -7
- package/dest/kernel_oracle/index.d.ts +20 -10
- package/dest/kernel_oracle/index.d.ts.map +1 -1
- package/dest/kernel_oracle/index.js +32 -9
- package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts +3 -3
- package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -1
- package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.js +71 -67
- package/dest/kernel_prover/hints/index.js +0 -1
- package/dest/kernel_prover/index.js +0 -1
- package/dest/kernel_prover/kernel_prover.d.ts +6 -6
- package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
- package/dest/kernel_prover/kernel_prover.js +98 -81
- package/dest/kernel_prover/proving_data_oracle.d.ts +15 -7
- package/dest/kernel_prover/proving_data_oracle.d.ts.map +1 -1
- package/dest/kernel_prover/proving_data_oracle.js +4 -2
- package/dest/note_decryption_utils/add_public_values_to_payload.d.ts +3 -2
- package/dest/note_decryption_utils/add_public_values_to_payload.d.ts.map +1 -1
- package/dest/note_decryption_utils/add_public_values_to_payload.js +11 -12
- package/dest/pxe_http/index.js +0 -1
- package/dest/pxe_http/pxe_http_server.d.ts +1 -1
- package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
- package/dest/pxe_http/pxe_http_server.js +9 -7
- package/dest/pxe_service/error_enriching.d.ts +3 -3
- package/dest/pxe_service/error_enriching.d.ts.map +1 -1
- package/dest/pxe_service/error_enriching.js +14 -17
- package/dest/pxe_service/index.d.ts +0 -1
- package/dest/pxe_service/index.d.ts.map +1 -1
- package/dest/pxe_service/index.js +0 -2
- package/dest/pxe_service/pxe_service.d.ts +21 -12
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +279 -333
- package/dest/pxe_service/test/pxe_test_suite.d.ts +1 -1
- package/dest/pxe_service/test/pxe_test_suite.d.ts.map +1 -1
- package/dest/pxe_service/test/pxe_test_suite.js +44 -28
- package/dest/simulator/index.d.ts +3 -3
- package/dest/simulator/index.d.ts.map +1 -1
- package/dest/simulator/index.js +1 -3
- package/dest/simulator_oracle/index.d.ts +18 -6
- package/dest/simulator_oracle/index.d.ts.map +1 -1
- package/dest/simulator_oracle/index.js +307 -235
- package/dest/simulator_oracle/tagging_utils.d.ts +2 -1
- package/dest/simulator_oracle/tagging_utils.d.ts.map +1 -1
- package/dest/simulator_oracle/tagging_utils.js +5 -7
- package/dest/synchronizer/index.js +0 -1
- package/dest/synchronizer/synchronizer.d.ts +7 -4
- package/dest/synchronizer/synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/synchronizer.js +64 -43
- package/dest/utils/create_pxe_service.d.ts +2 -2
- package/dest/utils/create_pxe_service.d.ts.map +1 -1
- package/dest/utils/create_pxe_service.js +13 -11
- package/package.json +18 -19
- package/src/bin/index.ts +1 -1
- package/src/config/index.ts +3 -3
- package/src/contract_data_oracle/index.ts +20 -20
- package/src/contract_data_oracle/private_functions_tree.ts +6 -7
- package/src/database/contracts/contract_artifact_db.ts +2 -2
- package/src/database/contracts/contract_instance_db.ts +2 -1
- package/src/database/kv_pxe_database.ts +33 -32
- package/src/database/note_dao.ts +11 -8
- package/src/database/outgoing_note_dao.ts +7 -4
- package/src/database/pxe_database.ts +13 -15
- package/src/database/pxe_database_test_suite.ts +8 -11
- package/src/index.ts +1 -7
- package/src/kernel_oracle/index.ts +55 -22
- package/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts +14 -11
- package/src/kernel_prover/kernel_prover.ts +89 -69
- package/src/kernel_prover/proving_data_oracle.ts +20 -20
- package/src/note_decryption_utils/add_public_values_to_payload.ts +5 -4
- package/src/pxe_http/pxe_http_server.ts +1 -1
- package/src/pxe_service/error_enriching.ts +6 -6
- package/src/pxe_service/index.ts +0 -1
- package/src/pxe_service/pxe_service.ts +121 -224
- package/src/pxe_service/test/pxe_test_suite.ts +6 -3
- package/src/simulator/index.ts +3 -3
- package/src/simulator_oracle/index.ts +77 -47
- package/src/simulator_oracle/tagging_utils.ts +2 -1
- package/src/synchronizer/synchronizer.ts +31 -12
- package/src/utils/create_pxe_service.ts +16 -4
|
@@ -1,170 +1,176 @@
|
|
|
1
|
-
var _KVPxeDatabase_instances, _KVPxeDatabase_synchronizedBlock, _KVPxeDatabase_completeAddresses, _KVPxeDatabase_completeAddressIndex, _KVPxeDatabase_addressBook, _KVPxeDatabase_authWitnesses, _KVPxeDatabase_notes, _KVPxeDatabase_nullifiedNotes, _KVPxeDatabase_nullifierToNoteId, _KVPxeDatabase_nullifiersByBlockNumber, _KVPxeDatabase_nullifiedNotesToScope, _KVPxeDatabase_nullifiedNotesByContract, _KVPxeDatabase_nullifiedNotesByStorageSlot, _KVPxeDatabase_nullifiedNotesByTxHash, _KVPxeDatabase_nullifiedNotesByAddressPoint, _KVPxeDatabase_nullifiedNotesByNullifier, _KVPxeDatabase_contractArtifacts, _KVPxeDatabase_contractInstances, _KVPxeDatabase_db, _KVPxeDatabase_scopes, _KVPxeDatabase_notesToScope, _KVPxeDatabase_notesByContractAndScope, _KVPxeDatabase_notesByStorageSlotAndScope, _KVPxeDatabase_notesByTxHashAndScope, _KVPxeDatabase_notesByAddressPointAndScope, _KVPxeDatabase_taggingSecretIndexesForSenders, _KVPxeDatabase_taggingSecretIndexesForRecipients, _KVPxeDatabase_capsules, _KVPxeDatabase_addScope, _KVPxeDatabase_getCompleteAddress, _KVPxeDatabase_setTaggingSecretsIndexes, _KVPxeDatabase_getTaggingSecretsIndexes;
|
|
2
|
-
import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
|
|
3
|
-
import { MerkleTreeId, NoteStatus } from '@aztec/circuit-types';
|
|
4
|
-
import { AztecAddress, BlockHeader, CompleteAddress, SerializableContractInstance, } from '@aztec/circuits.js';
|
|
5
|
-
import { FunctionSelector, FunctionType } from '@aztec/foundation/abi';
|
|
6
1
|
import { toBufferBE } from '@aztec/foundation/bigint-buffer';
|
|
7
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
8
3
|
import { toArray } from '@aztec/foundation/iterable';
|
|
9
4
|
import { createDebugOnlyLogger } from '@aztec/foundation/log';
|
|
10
|
-
import {
|
|
5
|
+
import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
6
|
+
import { contractArtifactFromBuffer, contractArtifactToBuffer } from '@aztec/stdlib/abi';
|
|
7
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
8
|
+
import { CompleteAddress, SerializableContractInstance } from '@aztec/stdlib/contract';
|
|
9
|
+
import { NoteStatus } from '@aztec/stdlib/note';
|
|
10
|
+
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
11
|
+
import { BlockHeader } from '@aztec/stdlib/tx';
|
|
11
12
|
import { NoteDao } from './note_dao.js';
|
|
12
13
|
/**
|
|
13
14
|
* A PXE database backed by LMDB.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
*/ export class KVPxeDatabase {
|
|
16
|
+
db;
|
|
17
|
+
#synchronizedBlock;
|
|
18
|
+
#completeAddresses;
|
|
19
|
+
#completeAddressIndex;
|
|
20
|
+
#addressBook;
|
|
21
|
+
#authWitnesses;
|
|
22
|
+
#notes;
|
|
23
|
+
#nullifiedNotes;
|
|
24
|
+
#nullifierToNoteId;
|
|
25
|
+
#nullifiersByBlockNumber;
|
|
26
|
+
#nullifiedNotesToScope;
|
|
27
|
+
#nullifiedNotesByContract;
|
|
28
|
+
#nullifiedNotesByStorageSlot;
|
|
29
|
+
#nullifiedNotesByTxHash;
|
|
30
|
+
#nullifiedNotesByAddressPoint;
|
|
31
|
+
#nullifiedNotesByNullifier;
|
|
32
|
+
#contractArtifacts;
|
|
33
|
+
#contractInstances;
|
|
34
|
+
#db;
|
|
35
|
+
#scopes;
|
|
36
|
+
#notesToScope;
|
|
37
|
+
#notesByContractAndScope;
|
|
38
|
+
#notesByStorageSlotAndScope;
|
|
39
|
+
#notesByTxHashAndScope;
|
|
40
|
+
#notesByAddressPointAndScope;
|
|
41
|
+
// Stores the last index used for each tagging secret, taking direction into account
|
|
42
|
+
// This is necessary to avoid reusing the same index for the same secret, which happens if
|
|
43
|
+
// sender and recipient are the same
|
|
44
|
+
#taggingSecretIndexesForSenders;
|
|
45
|
+
#taggingSecretIndexesForRecipients;
|
|
46
|
+
// Arbitrary data stored by contracts. Key is computed as `${contractAddress}:${key}`
|
|
47
|
+
#capsules;
|
|
48
|
+
debug;
|
|
49
|
+
constructor(db){
|
|
18
50
|
this.db = db;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
_KVPxeDatabase_taggingSecretIndexesForSenders.set(this, void 0);
|
|
47
|
-
_KVPxeDatabase_taggingSecretIndexesForRecipients.set(this, void 0);
|
|
48
|
-
// Arbitrary data stored by contracts. Key is computed as `${contractAddress}:${key}`
|
|
49
|
-
_KVPxeDatabase_capsules.set(this, void 0);
|
|
50
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_db, db, "f");
|
|
51
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_completeAddresses, db.openArray('complete_addresses'), "f");
|
|
52
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_completeAddressIndex, db.openMap('complete_address_index'), "f");
|
|
53
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_addressBook, db.openSet('address_book'), "f");
|
|
54
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_authWitnesses, db.openMap('auth_witnesses'), "f");
|
|
55
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_contractArtifacts, db.openMap('contract_artifacts'), "f");
|
|
56
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_contractInstances, db.openMap('contracts_instances'), "f");
|
|
57
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_synchronizedBlock, db.openSingleton('header'), "f");
|
|
58
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_notes, db.openMap('notes'), "f");
|
|
59
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_nullifiedNotes, db.openMap('nullified_notes'), "f");
|
|
60
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_nullifierToNoteId, db.openMap('nullifier_to_note'), "f");
|
|
61
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_nullifiersByBlockNumber, db.openMultiMap('nullifier_to_block_number'), "f");
|
|
62
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_nullifiedNotesToScope, db.openMultiMap('nullified_notes_to_scope'), "f");
|
|
63
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_nullifiedNotesByContract, db.openMultiMap('nullified_notes_by_contract'), "f");
|
|
64
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_nullifiedNotesByStorageSlot, db.openMultiMap('nullified_notes_by_storage_slot'), "f");
|
|
65
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_nullifiedNotesByTxHash, db.openMultiMap('nullified_notes_by_tx_hash'), "f");
|
|
66
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_nullifiedNotesByAddressPoint, db.openMultiMap('nullified_notes_by_address_point'), "f");
|
|
67
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_nullifiedNotesByNullifier, db.openMap('nullified_notes_by_nullifier'), "f");
|
|
68
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_scopes, db.openSet('scopes'), "f");
|
|
69
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_notesToScope, db.openMultiMap('notes_to_scope'), "f");
|
|
70
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_notesByContractAndScope, new Map(), "f");
|
|
71
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_notesByStorageSlotAndScope, new Map(), "f");
|
|
72
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_notesByTxHashAndScope, new Map(), "f");
|
|
73
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_notesByAddressPointAndScope, new Map(), "f");
|
|
74
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_taggingSecretIndexesForSenders, db.openMap('tagging_secret_indexes_for_senders'), "f");
|
|
75
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_taggingSecretIndexesForRecipients, db.openMap('tagging_secret_indexes_for_recipients'), "f");
|
|
76
|
-
__classPrivateFieldSet(this, _KVPxeDatabase_capsules, db.openMap('capsules'), "f");
|
|
51
|
+
this.#db = db;
|
|
52
|
+
this.#completeAddresses = db.openArray('complete_addresses');
|
|
53
|
+
this.#completeAddressIndex = db.openMap('complete_address_index');
|
|
54
|
+
this.#addressBook = db.openMap('address_book');
|
|
55
|
+
this.#authWitnesses = db.openMap('auth_witnesses');
|
|
56
|
+
this.#contractArtifacts = db.openMap('contract_artifacts');
|
|
57
|
+
this.#contractInstances = db.openMap('contracts_instances');
|
|
58
|
+
this.#synchronizedBlock = db.openSingleton('header');
|
|
59
|
+
this.#notes = db.openMap('notes');
|
|
60
|
+
this.#nullifiedNotes = db.openMap('nullified_notes');
|
|
61
|
+
this.#nullifierToNoteId = db.openMap('nullifier_to_note');
|
|
62
|
+
this.#nullifiersByBlockNumber = db.openMultiMap('nullifier_to_block_number');
|
|
63
|
+
this.#nullifiedNotesToScope = db.openMultiMap('nullified_notes_to_scope');
|
|
64
|
+
this.#nullifiedNotesByContract = db.openMultiMap('nullified_notes_by_contract');
|
|
65
|
+
this.#nullifiedNotesByStorageSlot = db.openMultiMap('nullified_notes_by_storage_slot');
|
|
66
|
+
this.#nullifiedNotesByTxHash = db.openMultiMap('nullified_notes_by_tx_hash');
|
|
67
|
+
this.#nullifiedNotesByAddressPoint = db.openMultiMap('nullified_notes_by_address_point');
|
|
68
|
+
this.#nullifiedNotesByNullifier = db.openMap('nullified_notes_by_nullifier');
|
|
69
|
+
this.#scopes = db.openMap('scopes');
|
|
70
|
+
this.#notesToScope = db.openMultiMap('notes_to_scope');
|
|
71
|
+
this.#notesByContractAndScope = new Map();
|
|
72
|
+
this.#notesByStorageSlotAndScope = new Map();
|
|
73
|
+
this.#notesByTxHashAndScope = new Map();
|
|
74
|
+
this.#notesByAddressPointAndScope = new Map();
|
|
75
|
+
this.#taggingSecretIndexesForSenders = db.openMap('tagging_secret_indexes_for_senders');
|
|
76
|
+
this.#taggingSecretIndexesForRecipients = db.openMap('tagging_secret_indexes_for_recipients');
|
|
77
|
+
this.#capsules = db.openMap('capsules');
|
|
77
78
|
this.debug = createDebugOnlyLogger('aztec:kv-pxe-database');
|
|
78
79
|
}
|
|
79
80
|
static async create(db) {
|
|
80
81
|
const pxeDB = new KVPxeDatabase(db);
|
|
81
|
-
for await (const scope of
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
for await (const scope of pxeDB.#scopes.keysAsync()){
|
|
83
|
+
pxeDB.#notesByContractAndScope.set(scope, db.openMultiMap(`${scope}:notes_by_contract`));
|
|
84
|
+
pxeDB.#notesByStorageSlotAndScope.set(scope, db.openMultiMap(`${scope}:notes_by_storage_slot`));
|
|
85
|
+
pxeDB.#notesByTxHashAndScope.set(scope, db.openMultiMap(`${scope}:notes_by_tx_hash`));
|
|
86
|
+
pxeDB.#notesByAddressPointAndScope.set(scope, db.openMultiMap(`${scope}:notes_by_address_point`));
|
|
86
87
|
}
|
|
87
88
|
return pxeDB;
|
|
88
89
|
}
|
|
89
90
|
async getContract(address) {
|
|
90
91
|
const instance = await this.getContractInstance(address);
|
|
91
|
-
const artifact = instance &&
|
|
92
|
+
const artifact = instance && await this.getContractArtifact(instance?.currentContractClassId);
|
|
92
93
|
if (!instance || !artifact) {
|
|
93
94
|
return undefined;
|
|
94
95
|
}
|
|
95
|
-
return {
|
|
96
|
+
return {
|
|
97
|
+
...instance,
|
|
98
|
+
...artifact
|
|
99
|
+
};
|
|
96
100
|
}
|
|
97
101
|
async addContractArtifact(id, contract) {
|
|
98
|
-
const privateFunctions = contract.functions.filter(functionArtifact
|
|
99
|
-
const privateSelectors = await Promise.all(privateFunctions.map(async (privateFunctionArtifact)
|
|
102
|
+
const privateFunctions = contract.functions.filter((functionArtifact)=>functionArtifact.functionType === FunctionType.PRIVATE);
|
|
103
|
+
const privateSelectors = await Promise.all(privateFunctions.map(async (privateFunctionArtifact)=>(await FunctionSelector.fromNameAndParameters(privateFunctionArtifact.name, privateFunctionArtifact.parameters)).toString()));
|
|
100
104
|
if (privateSelectors.length !== new Set(privateSelectors).size) {
|
|
101
105
|
throw new Error('Repeated function selectors of private functions');
|
|
102
106
|
}
|
|
103
|
-
await
|
|
107
|
+
await this.#contractArtifacts.set(id.toString(), contractArtifactToBuffer(contract));
|
|
104
108
|
}
|
|
105
109
|
async getContractArtifact(id) {
|
|
106
|
-
const contract = await
|
|
110
|
+
const contract = await this.#contractArtifacts.getAsync(id.toString());
|
|
107
111
|
// TODO(@spalladino): AztecAsyncMap lies and returns Uint8Arrays instead of Buffers, hence the extra Buffer.from.
|
|
108
112
|
return contract && contractArtifactFromBuffer(Buffer.from(contract));
|
|
109
113
|
}
|
|
110
114
|
async addContractInstance(contract) {
|
|
111
|
-
await
|
|
115
|
+
await this.#contractInstances.set(contract.address.toString(), new SerializableContractInstance(contract).toBuffer());
|
|
112
116
|
}
|
|
113
117
|
async getContractInstance(address) {
|
|
114
|
-
const contract = await
|
|
118
|
+
const contract = await this.#contractInstances.getAsync(address.toString());
|
|
115
119
|
return contract && SerializableContractInstance.fromBuffer(contract).withAddress(address);
|
|
116
120
|
}
|
|
117
121
|
async getContractsAddresses() {
|
|
118
|
-
const keys = await toArray(
|
|
122
|
+
const keys = await toArray(this.#contractInstances.keysAsync());
|
|
119
123
|
return keys.map(AztecAddress.fromString);
|
|
120
124
|
}
|
|
121
125
|
async addAuthWitness(messageHash, witness) {
|
|
122
|
-
await
|
|
126
|
+
await this.#authWitnesses.set(messageHash.toString(), witness.map((w)=>w.toBuffer()));
|
|
123
127
|
}
|
|
124
128
|
async getAuthWitness(messageHash) {
|
|
125
|
-
const witness = await
|
|
126
|
-
return Promise.resolve(witness?.map(w
|
|
129
|
+
const witness = await this.#authWitnesses.getAsync(messageHash.toString());
|
|
130
|
+
return Promise.resolve(witness?.map((w)=>Fr.fromBuffer(w)));
|
|
127
131
|
}
|
|
128
132
|
async addNote(note, scope) {
|
|
129
|
-
await this.addNotes([
|
|
133
|
+
await this.addNotes([
|
|
134
|
+
note
|
|
135
|
+
], scope);
|
|
130
136
|
}
|
|
131
137
|
async addNotes(notes, scope = AztecAddress.ZERO) {
|
|
132
|
-
if (!
|
|
133
|
-
await
|
|
138
|
+
if (!await this.#scopes.hasAsync(scope.toString())) {
|
|
139
|
+
await this.#addScope(scope);
|
|
134
140
|
}
|
|
135
|
-
return this.db.transactionAsync(async ()
|
|
136
|
-
for (const dao of notes)
|
|
141
|
+
return this.db.transactionAsync(async ()=>{
|
|
142
|
+
for (const dao of notes){
|
|
137
143
|
// store notes by their index in the notes hash tree
|
|
138
144
|
// this provides the uniqueness we need to store individual notes
|
|
139
145
|
// and should also return notes in the order that they were created.
|
|
140
146
|
// Had we stored them by their nullifier, they would be returned in random order
|
|
141
147
|
const noteIndex = toBufferBE(dao.index, 32).toString('hex');
|
|
142
|
-
await
|
|
143
|
-
await
|
|
144
|
-
await
|
|
145
|
-
await
|
|
146
|
-
await
|
|
147
|
-
await
|
|
148
|
-
await
|
|
148
|
+
await this.#notes.set(noteIndex, dao.toBuffer());
|
|
149
|
+
await this.#notesToScope.set(noteIndex, scope.toString());
|
|
150
|
+
await this.#nullifierToNoteId.set(dao.siloedNullifier.toString(), noteIndex);
|
|
151
|
+
await this.#notesByContractAndScope.get(scope.toString()).set(dao.contractAddress.toString(), noteIndex);
|
|
152
|
+
await this.#notesByStorageSlotAndScope.get(scope.toString()).set(dao.storageSlot.toString(), noteIndex);
|
|
153
|
+
await this.#notesByTxHashAndScope.get(scope.toString()).set(dao.txHash.toString(), noteIndex);
|
|
154
|
+
await this.#notesByAddressPointAndScope.get(scope.toString()).set(dao.addressPoint.toString(), noteIndex);
|
|
149
155
|
}
|
|
150
156
|
});
|
|
151
157
|
}
|
|
152
158
|
removeNotesAfter(blockNumber) {
|
|
153
|
-
return this.db.transactionAsync(async ()
|
|
154
|
-
const notes = await toArray(
|
|
155
|
-
for (const note of notes)
|
|
159
|
+
return this.db.transactionAsync(async ()=>{
|
|
160
|
+
const notes = await toArray(this.#notes.valuesAsync());
|
|
161
|
+
for (const note of notes){
|
|
156
162
|
const noteDao = NoteDao.fromBuffer(note);
|
|
157
163
|
if (noteDao.l2BlockNumber > blockNumber) {
|
|
158
164
|
const noteIndex = toBufferBE(noteDao.index, 32).toString('hex');
|
|
159
|
-
await
|
|
160
|
-
await
|
|
161
|
-
await
|
|
162
|
-
const scopes = await toArray(
|
|
163
|
-
for (const scope of scopes)
|
|
164
|
-
await
|
|
165
|
-
await
|
|
166
|
-
await
|
|
167
|
-
await
|
|
165
|
+
await this.#notes.delete(noteIndex);
|
|
166
|
+
await this.#notesToScope.delete(noteIndex);
|
|
167
|
+
await this.#nullifierToNoteId.delete(noteDao.siloedNullifier.toString());
|
|
168
|
+
const scopes = await toArray(this.#scopes.keysAsync());
|
|
169
|
+
for (const scope of scopes){
|
|
170
|
+
await this.#notesByAddressPointAndScope.get(scope).deleteValue(noteDao.addressPoint.toString(), noteIndex);
|
|
171
|
+
await this.#notesByTxHashAndScope.get(scope).deleteValue(noteDao.txHash.toString(), noteIndex);
|
|
172
|
+
await this.#notesByContractAndScope.get(scope).deleteValue(noteDao.contractAddress.toString(), noteIndex);
|
|
173
|
+
await this.#notesByStorageSlotAndScope.get(scope).deleteValue(noteDao.storageSlot.toString(), noteIndex);
|
|
168
174
|
}
|
|
169
175
|
}
|
|
170
176
|
}
|
|
@@ -173,40 +179,40 @@ export class KVPxeDatabase {
|
|
|
173
179
|
async unnullifyNotesAfter(blockNumber) {
|
|
174
180
|
const nullifiersToUndo = [];
|
|
175
181
|
const currentBlockNumber = blockNumber + 1;
|
|
176
|
-
const maxBlockNumber =
|
|
177
|
-
for
|
|
178
|
-
nullifiersToUndo.push(...
|
|
182
|
+
const maxBlockNumber = await this.getBlockNumber() ?? currentBlockNumber;
|
|
183
|
+
for(let i = currentBlockNumber; i <= maxBlockNumber; i++){
|
|
184
|
+
nullifiersToUndo.push(...await toArray(this.#nullifiersByBlockNumber.getValuesAsync(i)));
|
|
179
185
|
}
|
|
180
|
-
const notesIndexesToReinsert = await Promise.all(nullifiersToUndo.map(nullifier
|
|
181
|
-
const notNullNoteIndexes = notesIndexesToReinsert.filter(noteIndex
|
|
182
|
-
const nullifiedNoteBuffers = await Promise.all(notNullNoteIndexes.map(noteIndex
|
|
183
|
-
const noteDaos = nullifiedNoteBuffers
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
await this.db.transactionAsync(async () => {
|
|
187
|
-
for (const dao of noteDaos) {
|
|
186
|
+
const notesIndexesToReinsert = await Promise.all(nullifiersToUndo.map((nullifier)=>this.#nullifiedNotesByNullifier.getAsync(nullifier)));
|
|
187
|
+
const notNullNoteIndexes = notesIndexesToReinsert.filter((noteIndex)=>noteIndex != undefined);
|
|
188
|
+
const nullifiedNoteBuffers = await Promise.all(notNullNoteIndexes.map((noteIndex)=>this.#nullifiedNotes.getAsync(noteIndex)));
|
|
189
|
+
const noteDaos = nullifiedNoteBuffers.filter((buffer)=>buffer != undefined).map((buffer)=>NoteDao.fromBuffer(buffer));
|
|
190
|
+
await this.db.transactionAsync(async ()=>{
|
|
191
|
+
for (const dao of noteDaos){
|
|
188
192
|
const noteIndex = toBufferBE(dao.index, 32).toString('hex');
|
|
189
|
-
await
|
|
190
|
-
await
|
|
191
|
-
let scopes =
|
|
193
|
+
await this.#notes.set(noteIndex, dao.toBuffer());
|
|
194
|
+
await this.#nullifierToNoteId.set(dao.siloedNullifier.toString(), noteIndex);
|
|
195
|
+
let scopes = await toArray(this.#nullifiedNotesToScope.getValuesAsync(noteIndex)) ?? [];
|
|
192
196
|
if (scopes.length === 0) {
|
|
193
|
-
scopes = [
|
|
197
|
+
scopes = [
|
|
198
|
+
new AztecAddress(dao.addressPoint.x).toString()
|
|
199
|
+
];
|
|
194
200
|
}
|
|
195
|
-
for (const scope of scopes)
|
|
196
|
-
await
|
|
197
|
-
await
|
|
198
|
-
await
|
|
199
|
-
await
|
|
200
|
-
await
|
|
201
|
+
for (const scope of scopes){
|
|
202
|
+
await this.#notesByContractAndScope.get(scope.toString()).set(dao.contractAddress.toString(), noteIndex);
|
|
203
|
+
await this.#notesByStorageSlotAndScope.get(scope.toString()).set(dao.storageSlot.toString(), noteIndex);
|
|
204
|
+
await this.#notesByTxHashAndScope.get(scope.toString()).set(dao.txHash.toString(), noteIndex);
|
|
205
|
+
await this.#notesByAddressPointAndScope.get(scope.toString()).set(dao.addressPoint.toString(), noteIndex);
|
|
206
|
+
await this.#notesToScope.set(noteIndex, scope);
|
|
201
207
|
}
|
|
202
|
-
await
|
|
203
|
-
await
|
|
204
|
-
await
|
|
205
|
-
await
|
|
206
|
-
await
|
|
207
|
-
await
|
|
208
|
-
await
|
|
209
|
-
await
|
|
208
|
+
await this.#nullifiedNotes.delete(noteIndex);
|
|
209
|
+
await this.#nullifiedNotesToScope.delete(noteIndex);
|
|
210
|
+
await this.#nullifiersByBlockNumber.deleteValue(dao.l2BlockNumber, dao.siloedNullifier.toString());
|
|
211
|
+
await this.#nullifiedNotesByContract.deleteValue(dao.contractAddress.toString(), noteIndex);
|
|
212
|
+
await this.#nullifiedNotesByStorageSlot.deleteValue(dao.storageSlot.toString(), noteIndex);
|
|
213
|
+
await this.#nullifiedNotesByTxHash.deleteValue(dao.txHash.toString(), noteIndex);
|
|
214
|
+
await this.#nullifiedNotesByAddressPoint.deleteValue(dao.addressPoint.toString(), noteIndex);
|
|
215
|
+
await this.#nullifiedNotesByNullifier.delete(dao.siloedNullifier.toString());
|
|
210
216
|
}
|
|
211
217
|
});
|
|
212
218
|
}
|
|
@@ -214,46 +220,28 @@ export class KVPxeDatabase {
|
|
|
214
220
|
const publicKey = filter.owner ? await filter.owner.toAddressPoint() : undefined;
|
|
215
221
|
filter.status = filter.status ?? NoteStatus.ACTIVE;
|
|
216
222
|
const candidateNoteSources = [];
|
|
217
|
-
filter.scopes
|
|
223
|
+
filter.scopes ??= (await toArray(this.#scopes.keysAsync())).map((addressString)=>AztecAddress.fromString(addressString));
|
|
218
224
|
const activeNoteIdsPerScope = [];
|
|
219
|
-
for (const scope of new Set(filter.scopes))
|
|
225
|
+
for (const scope of new Set(filter.scopes)){
|
|
220
226
|
const formattedScopeString = scope.toString();
|
|
221
|
-
if (!
|
|
227
|
+
if (!await this.#scopes.hasAsync(formattedScopeString)) {
|
|
222
228
|
throw new Error('Trying to get incoming notes of an scope that is not in the PXE database');
|
|
223
229
|
}
|
|
224
|
-
activeNoteIdsPerScope.push(publicKey
|
|
225
|
-
? await toArray(__classPrivateFieldGet(this, _KVPxeDatabase_notesByAddressPointAndScope, "f").get(formattedScopeString).getValuesAsync(publicKey.toString()))
|
|
226
|
-
: filter.txHash
|
|
227
|
-
? await toArray(__classPrivateFieldGet(this, _KVPxeDatabase_notesByTxHashAndScope, "f").get(formattedScopeString).getValuesAsync(filter.txHash.toString()))
|
|
228
|
-
: filter.contractAddress
|
|
229
|
-
? await toArray(__classPrivateFieldGet(this, _KVPxeDatabase_notesByContractAndScope, "f")
|
|
230
|
-
.get(formattedScopeString)
|
|
231
|
-
.getValuesAsync(filter.contractAddress.toString()))
|
|
232
|
-
: filter.storageSlot
|
|
233
|
-
? await toArray(__classPrivateFieldGet(this, _KVPxeDatabase_notesByStorageSlotAndScope, "f").get(formattedScopeString).getValuesAsync(filter.storageSlot.toString()))
|
|
234
|
-
: await toArray(__classPrivateFieldGet(this, _KVPxeDatabase_notesByAddressPointAndScope, "f").get(formattedScopeString).valuesAsync()));
|
|
230
|
+
activeNoteIdsPerScope.push(publicKey ? await toArray(this.#notesByAddressPointAndScope.get(formattedScopeString).getValuesAsync(publicKey.toString())) : filter.txHash ? await toArray(this.#notesByTxHashAndScope.get(formattedScopeString).getValuesAsync(filter.txHash.toString())) : filter.contractAddress ? await toArray(this.#notesByContractAndScope.get(formattedScopeString).getValuesAsync(filter.contractAddress.toString())) : filter.storageSlot ? await toArray(this.#notesByStorageSlotAndScope.get(formattedScopeString).getValuesAsync(filter.storageSlot.toString())) : await toArray(this.#notesByAddressPointAndScope.get(formattedScopeString).valuesAsync()));
|
|
235
231
|
}
|
|
236
232
|
candidateNoteSources.push({
|
|
237
233
|
ids: new Set(activeNoteIdsPerScope.flat()),
|
|
238
|
-
notes:
|
|
234
|
+
notes: this.#notes
|
|
239
235
|
});
|
|
240
236
|
if (filter.status == NoteStatus.ACTIVE_OR_NULLIFIED) {
|
|
241
237
|
candidateNoteSources.push({
|
|
242
|
-
ids: publicKey
|
|
243
|
-
|
|
244
|
-
: filter.txHash
|
|
245
|
-
? await toArray(__classPrivateFieldGet(this, _KVPxeDatabase_nullifiedNotesByTxHash, "f").getValuesAsync(filter.txHash.toString()))
|
|
246
|
-
: filter.contractAddress
|
|
247
|
-
? await toArray(__classPrivateFieldGet(this, _KVPxeDatabase_nullifiedNotesByContract, "f").getValuesAsync(filter.contractAddress.toString()))
|
|
248
|
-
: filter.storageSlot
|
|
249
|
-
? await toArray(__classPrivateFieldGet(this, _KVPxeDatabase_nullifiedNotesByStorageSlot, "f").getValuesAsync(filter.storageSlot.toString()))
|
|
250
|
-
: await toArray(__classPrivateFieldGet(this, _KVPxeDatabase_nullifiedNotes, "f").keysAsync()),
|
|
251
|
-
notes: __classPrivateFieldGet(this, _KVPxeDatabase_nullifiedNotes, "f"),
|
|
238
|
+
ids: publicKey ? await toArray(this.#nullifiedNotesByAddressPoint.getValuesAsync(publicKey.toString())) : filter.txHash ? await toArray(this.#nullifiedNotesByTxHash.getValuesAsync(filter.txHash.toString())) : filter.contractAddress ? await toArray(this.#nullifiedNotesByContract.getValuesAsync(filter.contractAddress.toString())) : filter.storageSlot ? await toArray(this.#nullifiedNotesByStorageSlot.getValuesAsync(filter.storageSlot.toString())) : await toArray(this.#nullifiedNotes.keysAsync()),
|
|
239
|
+
notes: this.#nullifiedNotes
|
|
252
240
|
});
|
|
253
241
|
}
|
|
254
242
|
const result = [];
|
|
255
|
-
for (const { ids, notes } of candidateNoteSources)
|
|
256
|
-
for (const id of ids)
|
|
243
|
+
for (const { ids, notes } of candidateNoteSources){
|
|
244
|
+
for (const id of ids){
|
|
257
245
|
const serializedNote = await notes.getAsync(id);
|
|
258
246
|
if (!serializedNote) {
|
|
259
247
|
continue;
|
|
@@ -283,91 +271,100 @@ export class KVPxeDatabase {
|
|
|
283
271
|
if (nullifiers.length === 0) {
|
|
284
272
|
return Promise.resolve([]);
|
|
285
273
|
}
|
|
286
|
-
return this.db.transactionAsync(async ()
|
|
274
|
+
return this.db.transactionAsync(async ()=>{
|
|
287
275
|
const nullifiedNotes = [];
|
|
288
|
-
for (const blockScopedNullifier of nullifiers)
|
|
276
|
+
for (const blockScopedNullifier of nullifiers){
|
|
289
277
|
const { data: nullifier, l2BlockNumber: blockNumber } = blockScopedNullifier;
|
|
290
|
-
const noteIndex = await
|
|
278
|
+
const noteIndex = await this.#nullifierToNoteId.getAsync(nullifier.toString());
|
|
291
279
|
if (!noteIndex) {
|
|
292
280
|
continue;
|
|
293
281
|
}
|
|
294
|
-
const noteBuffer = noteIndex ? await
|
|
282
|
+
const noteBuffer = noteIndex ? await this.#notes.getAsync(noteIndex) : undefined;
|
|
295
283
|
if (!noteBuffer) {
|
|
296
|
-
// note doesn't exist. Maybe it got nullified already
|
|
297
284
|
continue;
|
|
298
285
|
}
|
|
299
|
-
const noteScopes =
|
|
286
|
+
const noteScopes = await toArray(this.#notesToScope.getValuesAsync(noteIndex)) ?? [];
|
|
300
287
|
const note = NoteDao.fromBuffer(noteBuffer);
|
|
301
288
|
if (!note.addressPoint.equals(accountAddressPoint)) {
|
|
302
|
-
// tried to nullify someone else's note
|
|
303
289
|
continue;
|
|
304
290
|
}
|
|
305
291
|
nullifiedNotes.push(note);
|
|
306
|
-
await
|
|
307
|
-
await
|
|
308
|
-
const scopes = await toArray(
|
|
309
|
-
for (const scope of scopes)
|
|
310
|
-
await
|
|
311
|
-
await
|
|
312
|
-
await
|
|
313
|
-
await
|
|
292
|
+
await this.#notes.delete(noteIndex);
|
|
293
|
+
await this.#notesToScope.delete(noteIndex);
|
|
294
|
+
const scopes = await toArray(this.#scopes.keysAsync());
|
|
295
|
+
for (const scope of scopes){
|
|
296
|
+
await this.#notesByAddressPointAndScope.get(scope).deleteValue(accountAddressPoint.toString(), noteIndex);
|
|
297
|
+
await this.#notesByTxHashAndScope.get(scope).deleteValue(note.txHash.toString(), noteIndex);
|
|
298
|
+
await this.#notesByContractAndScope.get(scope).deleteValue(note.contractAddress.toString(), noteIndex);
|
|
299
|
+
await this.#notesByStorageSlotAndScope.get(scope).deleteValue(note.storageSlot.toString(), noteIndex);
|
|
314
300
|
}
|
|
315
301
|
if (noteScopes !== undefined) {
|
|
316
|
-
for (const scope of noteScopes)
|
|
317
|
-
await
|
|
302
|
+
for (const scope of noteScopes){
|
|
303
|
+
await this.#nullifiedNotesToScope.set(noteIndex, scope);
|
|
318
304
|
}
|
|
319
305
|
}
|
|
320
|
-
await
|
|
321
|
-
await
|
|
322
|
-
await
|
|
323
|
-
await
|
|
324
|
-
await
|
|
325
|
-
await
|
|
326
|
-
await
|
|
327
|
-
await
|
|
306
|
+
await this.#nullifiedNotes.set(noteIndex, note.toBuffer());
|
|
307
|
+
await this.#nullifiersByBlockNumber.set(blockNumber, nullifier.toString());
|
|
308
|
+
await this.#nullifiedNotesByContract.set(note.contractAddress.toString(), noteIndex);
|
|
309
|
+
await this.#nullifiedNotesByStorageSlot.set(note.storageSlot.toString(), noteIndex);
|
|
310
|
+
await this.#nullifiedNotesByTxHash.set(note.txHash.toString(), noteIndex);
|
|
311
|
+
await this.#nullifiedNotesByAddressPoint.set(note.addressPoint.toString(), noteIndex);
|
|
312
|
+
await this.#nullifiedNotesByNullifier.set(nullifier.toString(), noteIndex);
|
|
313
|
+
await this.#nullifierToNoteId.delete(nullifier.toString());
|
|
328
314
|
}
|
|
329
315
|
return nullifiedNotes;
|
|
330
316
|
});
|
|
331
317
|
}
|
|
332
318
|
async addNullifiedNote(note) {
|
|
333
319
|
const noteIndex = toBufferBE(note.index, 32).toString('hex');
|
|
334
|
-
await
|
|
335
|
-
await
|
|
336
|
-
await
|
|
337
|
-
await
|
|
338
|
-
await
|
|
320
|
+
await this.#nullifiedNotes.set(noteIndex, note.toBuffer());
|
|
321
|
+
await this.#nullifiedNotesByContract.set(note.contractAddress.toString(), noteIndex);
|
|
322
|
+
await this.#nullifiedNotesByStorageSlot.set(note.storageSlot.toString(), noteIndex);
|
|
323
|
+
await this.#nullifiedNotesByTxHash.set(note.txHash.toString(), noteIndex);
|
|
324
|
+
await this.#nullifiedNotesByAddressPoint.set(note.addressPoint.toString(), noteIndex);
|
|
339
325
|
}
|
|
340
326
|
async setHeader(header) {
|
|
341
|
-
await
|
|
327
|
+
await this.#synchronizedBlock.set(header.toBuffer());
|
|
342
328
|
}
|
|
343
329
|
async getBlockNumber() {
|
|
344
|
-
const headerBuffer = await
|
|
330
|
+
const headerBuffer = await this.#synchronizedBlock.getAsync();
|
|
345
331
|
if (!headerBuffer) {
|
|
346
332
|
return undefined;
|
|
347
333
|
}
|
|
348
334
|
return Number(BlockHeader.fromBuffer(headerBuffer).globalVariables.blockNumber.toBigInt());
|
|
349
335
|
}
|
|
350
336
|
async getBlockHeader() {
|
|
351
|
-
const headerBuffer = await
|
|
337
|
+
const headerBuffer = await this.#synchronizedBlock.getAsync();
|
|
352
338
|
if (!headerBuffer) {
|
|
353
339
|
throw new Error(`Header not set`);
|
|
354
340
|
}
|
|
355
341
|
return BlockHeader.fromBuffer(headerBuffer);
|
|
356
342
|
}
|
|
343
|
+
async #addScope(scope) {
|
|
344
|
+
const scopeString = scope.toString();
|
|
345
|
+
if (await this.#scopes.hasAsync(scopeString)) {
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
await this.#scopes.set(scopeString, true);
|
|
349
|
+
this.#notesByContractAndScope.set(scopeString, this.#db.openMultiMap(`${scopeString}:notes_by_contract`));
|
|
350
|
+
this.#notesByStorageSlotAndScope.set(scopeString, this.#db.openMultiMap(`${scopeString}:notes_by_storage_slot`));
|
|
351
|
+
this.#notesByTxHashAndScope.set(scopeString, this.#db.openMultiMap(`${scopeString}:notes_by_tx_hash`));
|
|
352
|
+
this.#notesByAddressPointAndScope.set(scopeString, this.#db.openMultiMap(`${scopeString}:notes_by_address_point`));
|
|
353
|
+
return true;
|
|
354
|
+
}
|
|
357
355
|
addCompleteAddress(completeAddress) {
|
|
358
|
-
return this.db.transactionAsync(async ()
|
|
359
|
-
await
|
|
356
|
+
return this.db.transactionAsync(async ()=>{
|
|
357
|
+
await this.#addScope(completeAddress.address);
|
|
360
358
|
const addressString = completeAddress.address.toString();
|
|
361
359
|
const buffer = completeAddress.toBuffer();
|
|
362
|
-
const existing = await
|
|
360
|
+
const existing = await this.#completeAddressIndex.getAsync(addressString);
|
|
363
361
|
if (existing === undefined) {
|
|
364
|
-
const index = await
|
|
365
|
-
await
|
|
366
|
-
await
|
|
362
|
+
const index = await this.#completeAddresses.lengthAsync();
|
|
363
|
+
await this.#completeAddresses.push(buffer);
|
|
364
|
+
await this.#completeAddressIndex.set(addressString, index);
|
|
367
365
|
return true;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
const existingBuffer = await __classPrivateFieldGet(this, _KVPxeDatabase_completeAddresses, "f").atAsync(existing);
|
|
366
|
+
} else {
|
|
367
|
+
const existingBuffer = await this.#completeAddresses.atAsync(existing);
|
|
371
368
|
if (existingBuffer && Buffer.from(existingBuffer).equals(buffer)) {
|
|
372
369
|
return false;
|
|
373
370
|
}
|
|
@@ -375,73 +372,87 @@ export class KVPxeDatabase {
|
|
|
375
372
|
}
|
|
376
373
|
});
|
|
377
374
|
}
|
|
375
|
+
async #getCompleteAddress(address) {
|
|
376
|
+
const index = await this.#completeAddressIndex.getAsync(address.toString());
|
|
377
|
+
if (index === undefined) {
|
|
378
|
+
return undefined;
|
|
379
|
+
}
|
|
380
|
+
const value = await this.#completeAddresses.atAsync(index);
|
|
381
|
+
return value ? await CompleteAddress.fromBuffer(value) : undefined;
|
|
382
|
+
}
|
|
378
383
|
getCompleteAddress(account) {
|
|
379
|
-
return
|
|
384
|
+
return this.#getCompleteAddress(account);
|
|
380
385
|
}
|
|
381
386
|
async getCompleteAddresses() {
|
|
382
|
-
return await Promise.all((await toArray(
|
|
387
|
+
return await Promise.all((await toArray(this.#completeAddresses.valuesAsync())).map((v)=>CompleteAddress.fromBuffer(v)));
|
|
383
388
|
}
|
|
384
389
|
async addSenderAddress(address) {
|
|
385
|
-
if (await
|
|
390
|
+
if (await this.#addressBook.hasAsync(address.toString())) {
|
|
386
391
|
return false;
|
|
387
392
|
}
|
|
388
|
-
await
|
|
393
|
+
await this.#addressBook.set(address.toString(), true);
|
|
389
394
|
return true;
|
|
390
395
|
}
|
|
391
396
|
async getSenderAddresses() {
|
|
392
|
-
return (await toArray(
|
|
397
|
+
return (await toArray(this.#addressBook.keysAsync())).map(AztecAddress.fromString);
|
|
393
398
|
}
|
|
394
399
|
async removeSenderAddress(address) {
|
|
395
|
-
if (!
|
|
400
|
+
if (!await this.#addressBook.hasAsync(address.toString())) {
|
|
396
401
|
return false;
|
|
397
402
|
}
|
|
398
|
-
await
|
|
403
|
+
await this.#addressBook.delete(address.toString());
|
|
399
404
|
return true;
|
|
400
405
|
}
|
|
401
406
|
async estimateSize() {
|
|
402
|
-
const noteSize = (await this.getNotes({})).reduce((sum, note)
|
|
403
|
-
const authWitsSize = (await toArray(
|
|
404
|
-
const addressesSize =
|
|
407
|
+
const noteSize = (await this.getNotes({})).reduce((sum, note)=>sum + note.getSize(), 0);
|
|
408
|
+
const authWitsSize = (await toArray(this.#authWitnesses.valuesAsync())).reduce((sum, value)=>sum + value.length * Fr.SIZE_IN_BYTES, 0);
|
|
409
|
+
const addressesSize = await this.#completeAddresses.lengthAsync() * CompleteAddress.SIZE_IN_BYTES;
|
|
405
410
|
const treeRootsSize = Object.keys(MerkleTreeId).length * Fr.SIZE_IN_BYTES;
|
|
406
411
|
return noteSize + treeRootsSize + authWitsSize + addressesSize;
|
|
407
412
|
}
|
|
408
413
|
async setTaggingSecretsIndexesAsSender(indexedSecrets) {
|
|
409
|
-
await
|
|
414
|
+
await this.#setTaggingSecretsIndexes(indexedSecrets, this.#taggingSecretIndexesForSenders);
|
|
410
415
|
}
|
|
411
416
|
async setTaggingSecretsIndexesAsRecipient(indexedSecrets) {
|
|
412
|
-
await
|
|
417
|
+
await this.#setTaggingSecretsIndexes(indexedSecrets, this.#taggingSecretIndexesForRecipients);
|
|
418
|
+
}
|
|
419
|
+
async #setTaggingSecretsIndexes(indexedSecrets, storageMap) {
|
|
420
|
+
await Promise.all(indexedSecrets.map((indexedSecret)=>storageMap.set(indexedSecret.appTaggingSecret.toString(), indexedSecret.index)));
|
|
413
421
|
}
|
|
414
422
|
async getTaggingSecretsIndexesAsRecipient(appTaggingSecrets) {
|
|
415
|
-
return await
|
|
423
|
+
return await this.#getTaggingSecretsIndexes(appTaggingSecrets, this.#taggingSecretIndexesForRecipients);
|
|
416
424
|
}
|
|
417
425
|
async getTaggingSecretsIndexesAsSender(appTaggingSecrets) {
|
|
418
|
-
return await
|
|
426
|
+
return await this.#getTaggingSecretsIndexes(appTaggingSecrets, this.#taggingSecretIndexesForSenders);
|
|
427
|
+
}
|
|
428
|
+
#getTaggingSecretsIndexes(appTaggingSecrets, storageMap) {
|
|
429
|
+
return Promise.all(appTaggingSecrets.map(async (secret)=>await storageMap.getAsync(`${secret.toString()}`) ?? 0));
|
|
419
430
|
}
|
|
420
431
|
resetNoteSyncData() {
|
|
421
|
-
return this.db.transactionAsync(async ()
|
|
422
|
-
const recipients = await toArray(
|
|
423
|
-
await Promise.all(recipients.map(recipient
|
|
424
|
-
const senders = await toArray(
|
|
425
|
-
await Promise.all(senders.map(sender
|
|
432
|
+
return this.db.transactionAsync(async ()=>{
|
|
433
|
+
const recipients = await toArray(this.#taggingSecretIndexesForRecipients.keysAsync());
|
|
434
|
+
await Promise.all(recipients.map((recipient)=>this.#taggingSecretIndexesForRecipients.delete(recipient)));
|
|
435
|
+
const senders = await toArray(this.#taggingSecretIndexesForSenders.keysAsync());
|
|
436
|
+
await Promise.all(senders.map((sender)=>this.#taggingSecretIndexesForSenders.delete(sender)));
|
|
426
437
|
});
|
|
427
438
|
}
|
|
428
439
|
async storeCapsule(contractAddress, slot, capsule) {
|
|
429
|
-
await
|
|
440
|
+
await this.#capsules.set(dbSlotToKey(contractAddress, slot), Buffer.concat(capsule.map((value)=>value.toBuffer())));
|
|
430
441
|
}
|
|
431
442
|
async loadCapsule(contractAddress, slot) {
|
|
432
|
-
const dataBuffer = await
|
|
443
|
+
const dataBuffer = await this.#capsules.getAsync(dbSlotToKey(contractAddress, slot));
|
|
433
444
|
if (!dataBuffer) {
|
|
434
445
|
this.debug(`Data not found for contract ${contractAddress.toString()} and slot ${slot.toString()}`);
|
|
435
446
|
return null;
|
|
436
447
|
}
|
|
437
448
|
const capsule = [];
|
|
438
|
-
for
|
|
449
|
+
for(let i = 0; i < dataBuffer.length; i += Fr.SIZE_IN_BYTES){
|
|
439
450
|
capsule.push(Fr.fromBuffer(dataBuffer.subarray(i, i + Fr.SIZE_IN_BYTES)));
|
|
440
451
|
}
|
|
441
452
|
return capsule;
|
|
442
453
|
}
|
|
443
454
|
async deleteCapsule(contractAddress, slot) {
|
|
444
|
-
await
|
|
455
|
+
await this.#capsules.delete(dbSlotToKey(contractAddress, slot));
|
|
445
456
|
}
|
|
446
457
|
async copyCapsule(contractAddress, srcSlot, dstSlot, numEntries) {
|
|
447
458
|
// In order to support overlapping source and destination regions, we need to check the relative positions of source
|
|
@@ -452,41 +463,17 @@ export class KVPxeDatabase {
|
|
|
452
463
|
if (srcSlot.lt(dstSlot)) {
|
|
453
464
|
indexes.reverse();
|
|
454
465
|
}
|
|
455
|
-
for (const i of indexes)
|
|
466
|
+
for (const i of indexes){
|
|
456
467
|
const currentSrcSlot = dbSlotToKey(contractAddress, srcSlot.add(new Fr(i)));
|
|
457
468
|
const currentDstSlot = dbSlotToKey(contractAddress, dstSlot.add(new Fr(i)));
|
|
458
|
-
const toCopy = await
|
|
469
|
+
const toCopy = await this.#capsules.getAsync(currentSrcSlot);
|
|
459
470
|
if (!toCopy) {
|
|
460
471
|
throw new Error(`Attempted to copy empty slot ${currentSrcSlot} for contract ${contractAddress.toString()}`);
|
|
461
472
|
}
|
|
462
|
-
await
|
|
473
|
+
await this.#capsules.set(currentDstSlot, toCopy);
|
|
463
474
|
}
|
|
464
475
|
}
|
|
465
476
|
}
|
|
466
|
-
_KVPxeDatabase_synchronizedBlock = new WeakMap(), _KVPxeDatabase_completeAddresses = new WeakMap(), _KVPxeDatabase_completeAddressIndex = new WeakMap(), _KVPxeDatabase_addressBook = new WeakMap(), _KVPxeDatabase_authWitnesses = new WeakMap(), _KVPxeDatabase_notes = new WeakMap(), _KVPxeDatabase_nullifiedNotes = new WeakMap(), _KVPxeDatabase_nullifierToNoteId = new WeakMap(), _KVPxeDatabase_nullifiersByBlockNumber = new WeakMap(), _KVPxeDatabase_nullifiedNotesToScope = new WeakMap(), _KVPxeDatabase_nullifiedNotesByContract = new WeakMap(), _KVPxeDatabase_nullifiedNotesByStorageSlot = new WeakMap(), _KVPxeDatabase_nullifiedNotesByTxHash = new WeakMap(), _KVPxeDatabase_nullifiedNotesByAddressPoint = new WeakMap(), _KVPxeDatabase_nullifiedNotesByNullifier = new WeakMap(), _KVPxeDatabase_contractArtifacts = new WeakMap(), _KVPxeDatabase_contractInstances = new WeakMap(), _KVPxeDatabase_db = new WeakMap(), _KVPxeDatabase_scopes = new WeakMap(), _KVPxeDatabase_notesToScope = new WeakMap(), _KVPxeDatabase_notesByContractAndScope = new WeakMap(), _KVPxeDatabase_notesByStorageSlotAndScope = new WeakMap(), _KVPxeDatabase_notesByTxHashAndScope = new WeakMap(), _KVPxeDatabase_notesByAddressPointAndScope = new WeakMap(), _KVPxeDatabase_taggingSecretIndexesForSenders = new WeakMap(), _KVPxeDatabase_taggingSecretIndexesForRecipients = new WeakMap(), _KVPxeDatabase_capsules = new WeakMap(), _KVPxeDatabase_instances = new WeakSet(), _KVPxeDatabase_addScope = async function _KVPxeDatabase_addScope(scope) {
|
|
467
|
-
const scopeString = scope.toString();
|
|
468
|
-
if (await __classPrivateFieldGet(this, _KVPxeDatabase_scopes, "f").hasAsync(scopeString)) {
|
|
469
|
-
return false;
|
|
470
|
-
}
|
|
471
|
-
await __classPrivateFieldGet(this, _KVPxeDatabase_scopes, "f").add(scopeString);
|
|
472
|
-
__classPrivateFieldGet(this, _KVPxeDatabase_notesByContractAndScope, "f").set(scopeString, __classPrivateFieldGet(this, _KVPxeDatabase_db, "f").openMultiMap(`${scopeString}:notes_by_contract`));
|
|
473
|
-
__classPrivateFieldGet(this, _KVPxeDatabase_notesByStorageSlotAndScope, "f").set(scopeString, __classPrivateFieldGet(this, _KVPxeDatabase_db, "f").openMultiMap(`${scopeString}:notes_by_storage_slot`));
|
|
474
|
-
__classPrivateFieldGet(this, _KVPxeDatabase_notesByTxHashAndScope, "f").set(scopeString, __classPrivateFieldGet(this, _KVPxeDatabase_db, "f").openMultiMap(`${scopeString}:notes_by_tx_hash`));
|
|
475
|
-
__classPrivateFieldGet(this, _KVPxeDatabase_notesByAddressPointAndScope, "f").set(scopeString, __classPrivateFieldGet(this, _KVPxeDatabase_db, "f").openMultiMap(`${scopeString}:notes_by_address_point`));
|
|
476
|
-
return true;
|
|
477
|
-
}, _KVPxeDatabase_getCompleteAddress = async function _KVPxeDatabase_getCompleteAddress(address) {
|
|
478
|
-
const index = await __classPrivateFieldGet(this, _KVPxeDatabase_completeAddressIndex, "f").getAsync(address.toString());
|
|
479
|
-
if (index === undefined) {
|
|
480
|
-
return undefined;
|
|
481
|
-
}
|
|
482
|
-
const value = await __classPrivateFieldGet(this, _KVPxeDatabase_completeAddresses, "f").atAsync(index);
|
|
483
|
-
return value ? await CompleteAddress.fromBuffer(value) : undefined;
|
|
484
|
-
}, _KVPxeDatabase_setTaggingSecretsIndexes = async function _KVPxeDatabase_setTaggingSecretsIndexes(indexedSecrets, storageMap) {
|
|
485
|
-
await Promise.all(indexedSecrets.map(indexedSecret => storageMap.set(indexedSecret.appTaggingSecret.toString(), indexedSecret.index)));
|
|
486
|
-
}, _KVPxeDatabase_getTaggingSecretsIndexes = function _KVPxeDatabase_getTaggingSecretsIndexes(appTaggingSecrets, storageMap) {
|
|
487
|
-
return Promise.all(appTaggingSecrets.map(async (secret) => (await storageMap.getAsync(`${secret.toString()}`)) ?? 0));
|
|
488
|
-
};
|
|
489
477
|
function dbSlotToKey(contractAddress, slot) {
|
|
490
478
|
return `${contractAddress.toString()}:${slot.toString()}`;
|
|
491
479
|
}
|
|
492
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia3ZfcHhlX2RhdGFiYXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RhdGFiYXNlL2t2X3B4ZV9kYXRhYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE9BQU8sRUFBZ0IsWUFBWSxFQUFFLFVBQVUsRUFBb0IsTUFBTSxzQkFBc0IsQ0FBQztBQUNoRyxPQUFPLEVBQ0wsWUFBWSxFQUNaLFdBQVcsRUFDWCxlQUFlLEVBSWYsNEJBQTRCLEdBQzdCLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQUF5QixnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM5RixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDN0QsT0FBTyxFQUFFLEVBQUUsRUFBYyxNQUFNLDBCQUEwQixDQUFDO0FBQzFELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNyRCxPQUFPLEVBQWMscUJBQXFCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQVMxRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUV4RixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR3hDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGFBQWE7SUF1Q3hCLFlBQThCLEVBQXFCOztRQUFyQixPQUFFLEdBQUYsRUFBRSxDQUFtQjtRQXRDbkQsbURBQWdEO1FBQ2hELG1EQUE0QztRQUM1QyxzREFBcUQ7UUFDckQsNkNBQW9DO1FBQ3BDLCtDQUFnRDtRQUNoRCx1Q0FBc0M7UUFDdEMsZ0RBQStDO1FBQy9DLG1EQUFrRDtRQUNsRCx5REFBNkQ7UUFFN0QsdURBQTJEO1FBQzNELDBEQUE4RDtRQUM5RCw2REFBaUU7UUFDakUsd0RBQTREO1FBQzVELDhEQUFrRTtRQUNsRSwyREFBMEQ7UUFDMUQsbURBQWtEO1FBQ2xELG1EQUFrRDtRQUNsRCxv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
|