@aztec/pxe 0.0.1-commit.54489865 → 0.0.1-commit.592b9384
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_function_simulator/contract_function_simulator.d.ts +2 -4
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +3 -5
- package/dest/contract_function_simulator/oracle/interfaces.d.ts +7 -7
- package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.d.ts +3 -3
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.js +9 -9
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +2 -3
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +4 -4
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +15 -11
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +23 -19
- package/dest/entrypoints/client/bundle/utils.d.ts +1 -1
- package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/utils.js +2 -1
- package/dest/entrypoints/client/lazy/utils.d.ts +1 -1
- package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/utils.js +2 -1
- package/dest/events/event_service.d.ts +4 -5
- package/dest/events/event_service.d.ts.map +1 -1
- package/dest/events/event_service.js +5 -6
- package/dest/logs/log_service.d.ts +4 -4
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +7 -10
- package/dest/notes/note_service.d.ts +4 -5
- package/dest/notes/note_service.d.ts.map +1 -1
- package/dest/notes/note_service.js +6 -7
- package/dest/oracle_version.d.ts +3 -3
- package/dest/oracle_version.d.ts.map +1 -1
- package/dest/oracle_version.js +2 -2
- package/dest/pxe.d.ts +1 -1
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +1 -1
- package/dest/storage/address_store/address_store.d.ts +1 -1
- package/dest/storage/address_store/address_store.d.ts.map +1 -1
- package/dest/storage/address_store/address_store.js +12 -11
- package/dest/storage/anchor_block_store/anchor_block_store.d.ts +9 -1
- package/dest/storage/anchor_block_store/anchor_block_store.d.ts.map +1 -1
- package/dest/storage/anchor_block_store/anchor_block_store.js +8 -1
- package/dest/storage/capsule_store/capsule_store.js +6 -8
- package/dest/storage/contract_store/contract_store.d.ts +1 -1
- package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
- package/dest/storage/contract_store/contract_store.js +22 -13
- package/dest/storage/metadata.d.ts +1 -1
- package/dest/storage/metadata.js +1 -1
- package/dest/storage/note_store/note_store.d.ts +11 -1
- package/dest/storage/note_store/note_store.d.ts.map +1 -1
- package/dest/storage/note_store/note_store.js +169 -129
- package/dest/storage/private_event_store/private_event_store.d.ts +1 -1
- package/dest/storage/private_event_store/private_event_store.d.ts.map +1 -1
- package/dest/storage/private_event_store/private_event_store.js +126 -101
- package/dest/storage/tagging_store/recipient_tagging_store.d.ts +1 -1
- package/dest/storage/tagging_store/recipient_tagging_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/recipient_tagging_store.js +31 -19
- package/dest/storage/tagging_store/sender_address_book_store.d.ts +1 -1
- package/dest/storage/tagging_store/sender_address_book_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/sender_address_book_store.js +20 -14
- package/dest/storage/tagging_store/sender_tagging_store.d.ts +1 -1
- package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/sender_tagging_store.js +183 -113
- package/package.json +16 -16
- package/src/contract_function_simulator/contract_function_simulator.ts +0 -4
- package/src/contract_function_simulator/oracle/interfaces.ts +8 -8
- package/src/contract_function_simulator/oracle/oracle.ts +21 -11
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +1 -5
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +24 -20
- package/src/entrypoints/client/bundle/utils.ts +3 -1
- package/src/entrypoints/client/lazy/utils.ts +3 -1
- package/src/events/event_service.ts +4 -6
- package/src/logs/log_service.ts +6 -9
- package/src/notes/note_service.ts +5 -7
- package/src/oracle_version.ts +2 -2
- package/src/pxe.ts +0 -1
- package/src/storage/address_store/address_store.ts +15 -15
- package/src/storage/anchor_block_store/anchor_block_store.ts +8 -0
- package/src/storage/capsule_store/capsule_store.ts +8 -8
- package/src/storage/contract_store/contract_store.ts +22 -11
- package/src/storage/metadata.ts +1 -1
- package/src/storage/note_store/note_store.ts +185 -150
- package/src/storage/private_event_store/private_event_store.ts +151 -128
- package/src/storage/tagging_store/recipient_tagging_store.ts +31 -21
- package/src/storage/tagging_store/sender_address_book_store.ts +20 -14
- package/src/storage/tagging_store/sender_tagging_store.ts +210 -126
|
@@ -40,14 +40,12 @@ export class CapsuleStore {
|
|
|
40
40
|
* If it is not there, it reads it from the KV store.
|
|
41
41
|
*/ async #getFromStage(jobId, dbSlotKey) {
|
|
42
42
|
const jobStagedCapsules = this.#getJobStagedCapsules(jobId);
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
return staged;
|
|
43
|
+
const staged = jobStagedCapsules.get(dbSlotKey);
|
|
44
|
+
// Always issue DB read to keep IndexedDB transaction alive, even if the value is in the job staged data. This
|
|
45
|
+
// keeps IndexedDB transactions alive (they auto-commit when a new micro-task starts and there are no pending read
|
|
46
|
+
// requests). The staged value still takes precedence if it exists (including null for deletions).
|
|
47
|
+
const dbValue = await this.#loadCapsuleFromDb(dbSlotKey);
|
|
48
|
+
return staged !== undefined ? staged : dbValue;
|
|
51
49
|
}
|
|
52
50
|
/**
|
|
53
51
|
* Writes a capsule to the stage of a job.
|
|
@@ -63,4 +63,4 @@ export declare class ContractStore {
|
|
|
63
63
|
getDebugFunctionName(contractAddress: AztecAddress, selector: FunctionSelector): Promise<string>;
|
|
64
64
|
getFunctionCall(functionName: string, args: any[], to: AztecAddress): Promise<FunctionCall>;
|
|
65
65
|
}
|
|
66
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
66
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3Rfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zdG9yYWdlL2NvbnRyYWN0X3N0b3JlL2NvbnRyYWN0X3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDN0QsT0FBTyxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFFekQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNqRSxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBaUIsTUFBTSxpQkFBaUIsQ0FBQztBQUN4RSxPQUFPLEVBQ0wsS0FBSyxnQkFBZ0IsRUFDckIsS0FBSyxXQUFXLEVBRWhCLEtBQUssZ0NBQWdDLEVBQ3JDLFlBQVksRUFDWixLQUFLLHFCQUFxQixFQUMxQixnQkFBZ0IsRUFNakIsTUFBTSxtQkFBbUIsQ0FBQztBQUMzQixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDM0QsT0FBTyxFQUNMLEtBQUssYUFBYSxFQUNsQixLQUFLLDJCQUEyQixFQUdqQyxNQUFNLHdCQUF3QixDQUFDO0FBSWhDOzs7Ozs7R0FNRztBQUNILHFCQUFhLGFBQWE7O0lBWXhCLFlBQVksS0FBSyxFQUFFLGlCQUFpQixFQUluQztJQUlZLG1CQUFtQixDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FxQmxGO0lBRUssbUJBQW1CLENBQUMsUUFBUSxFQUFFLDJCQUEyQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FPOUU7SUE0Q0QscUJBQXFCLElBQUksT0FBTyxDQUFDLFlBQVksRUFBRSxDQUFDLENBSy9DO0lBRUQsNEVBQTRFO0lBQ3JFLG1CQUFtQixDQUFDLGVBQWUsRUFBRSxZQUFZLEdBQUcsT0FBTyxDQUFDLDJCQUEyQixHQUFHLFNBQVMsQ0FBQyxDQUsxRztJQUVNLG1CQUFtQixDQUFDLGVBQWUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixHQUFHLFNBQVMsQ0FBQyxDQU1yRjtJQUVELDBFQUEwRTtJQUM3RCxnQkFBZ0IsQ0FBQyxlQUFlLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxhQUFhLEdBQUcsU0FBUyxDQUFDLENBR3JGO0lBRVksV0FBVyxDQUN0QixPQUFPLEVBQUUsWUFBWSxHQUNwQixPQUFPLENBQUMsQ0FBQywyQkFBMkIsR0FBRyxnQkFBZ0IsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQVV2RTtJQUVEOzs7Ozs7OztPQVFHO0lBQ1UsbUJBQW1CLENBQzlCLGVBQWUsRUFBRSxZQUFZLEVBQzdCLFFBQVEsRUFBRSxnQkFBZ0IsR0FDekIsT0FBTyxDQUFDLGdDQUFnQyxHQUFHLFNBQVMsQ0FBQyxDQUl2RDtJQUVZLG9DQUFvQyxDQUMvQyxlQUFlLEVBQUUsWUFBWSxFQUM3QixRQUFRLEVBQUUsZ0JBQWdCLEdBQ3pCLE9BQU8sQ0FBQyxnQ0FBZ0MsQ0FBQyxDQVUzQztJQUVZLHlCQUF5QixDQUNwQyxlQUFlLEVBQUUsWUFBWSxHQUM1QixPQUFPLENBQUMsZ0NBQWdDLEdBQUcsU0FBUyxDQUFDLENBSXZEO0lBRVksY0FBYyxDQUN6QixlQUFlLEVBQUUsWUFBWSxFQUM3QixRQUFRLEVBQUUsZ0JBQWdCLEdBQ3pCLE9BQU8sQ0FBQyxXQUFXLEdBQUcsU0FBUyxDQUFDLENBR2xDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ1Usd0JBQXdCLENBQ25DLGVBQWUsRUFBRSxZQUFZLEVBQzdCLFFBQVEsRUFBRSxnQkFBZ0IsR0FDekIsT0FBTyxDQUFDLHFCQUFxQixHQUFHLFNBQVMsQ0FBQyxDQUk1QztJQUVZLDhCQUE4QixDQUN6QyxlQUFlLEVBQUUsWUFBWSxHQUM1QixPQUFPLENBQUMscUJBQXFCLEdBQUcsU0FBUyxDQUFDLENBSTVDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDVSw0QkFBNEIsQ0FDdkMsZUFBZSxFQUFFLEVBQUUsRUFDbkIsUUFBUSxFQUFFLGdCQUFnQixHQUN6QixPQUFPLENBQUMsaUJBQWlCLENBQUMsT0FBTyxvQkFBb0IsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUdyRTtJQUVZLG9CQUFvQixDQUFDLGVBQWUsRUFBRSxZQUFZLCtCQUc5RDtJQUVZLG9CQUFvQixDQUFDLGVBQWUsRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixtQkFJMUY7SUE4QlksZUFBZSxDQUFDLFlBQVksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQXVCdkc7Q0FDRiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract_store.d.ts","sourceRoot":"","sources":["../../../src/storage/contract_store/contract_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAEzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAEhB,KAAK,gCAAgC,EACrC,YAAY,EACZ,KAAK,qBAAqB,EAC1B,gBAAgB,EAMjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,2BAA2B,EAGjC,MAAM,wBAAwB,CAAC;AAIhC;;;;;;GAMG;AACH,qBAAa,aAAa;;
|
|
1
|
+
{"version":3,"file":"contract_store.d.ts","sourceRoot":"","sources":["../../../src/storage/contract_store/contract_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAEzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAEhB,KAAK,gCAAgC,EACrC,YAAY,EACZ,KAAK,qBAAqB,EAC1B,gBAAgB,EAMjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,2BAA2B,EAGjC,MAAM,wBAAwB,CAAC;AAIhC;;;;;;GAMG;AACH,qBAAa,aAAa;;IAYxB,YAAY,KAAK,EAAE,iBAAiB,EAInC;IAIY,mBAAmB,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBlF;IAEK,mBAAmB,CAAC,QAAQ,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAO9E;IA4CD,qBAAqB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAK/C;IAED,4EAA4E;IACrE,mBAAmB,CAAC,eAAe,EAAE,YAAY,GAAG,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC,CAK1G;IAEM,mBAAmB,CAAC,eAAe,EAAE,EAAE,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAMrF;IAED,0EAA0E;IAC7D,gBAAgB,CAAC,eAAe,EAAE,EAAE,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAGrF;IAEY,WAAW,CACtB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,CAAC,2BAA2B,GAAG,gBAAgB,CAAC,GAAG,SAAS,CAAC,CAUvE;IAED;;;;;;;;OAQG;IACU,mBAAmB,CAC9B,eAAe,EAAE,YAAY,EAC7B,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,gCAAgC,GAAG,SAAS,CAAC,CAIvD;IAEY,oCAAoC,CAC/C,eAAe,EAAE,YAAY,EAC7B,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,gCAAgC,CAAC,CAU3C;IAEY,yBAAyB,CACpC,eAAe,EAAE,YAAY,GAC5B,OAAO,CAAC,gCAAgC,GAAG,SAAS,CAAC,CAIvD;IAEY,cAAc,CACzB,eAAe,EAAE,YAAY,EAC7B,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAGlC;IAED;;;;;;;;;OASG;IACU,wBAAwB,CACnC,eAAe,EAAE,YAAY,EAC7B,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAI5C;IAEY,8BAA8B,CACzC,eAAe,EAAE,YAAY,GAC5B,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAI5C;IAED;;;;;;;;OAQG;IACU,4BAA4B,CACvC,eAAe,EAAE,EAAE,EACnB,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,iBAAiB,CAAC,OAAO,oBAAoB,CAAC,GAAG,SAAS,CAAC,CAGrE;IAEY,oBAAoB,CAAC,eAAe,EAAE,YAAY,+BAG9D;IAEY,oBAAoB,CAAC,eAAe,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,mBAI1F;IA8BY,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAuBvG;CACF"}
|
|
@@ -13,20 +13,23 @@ import { PrivateFunctionsTree } from './private_functions_tree.js';
|
|
|
13
13
|
/** Map from contract class id to private function tree. */ // TODO: Update it to be LRU cache so that it doesn't keep all the data all the time.
|
|
14
14
|
#privateFunctionTrees = new Map();
|
|
15
15
|
/** Map from contract address to contract class id */ #contractClassIdMap = new Map();
|
|
16
|
+
#store;
|
|
16
17
|
#contractArtifacts;
|
|
17
18
|
#contractInstances;
|
|
18
19
|
constructor(store){
|
|
20
|
+
this.#store = store;
|
|
19
21
|
this.#contractArtifacts = store.openMap('contract_artifacts');
|
|
20
22
|
this.#contractInstances = store.openMap('contracts_instances');
|
|
21
23
|
}
|
|
22
24
|
// Setters
|
|
23
25
|
async addContractArtifact(id, contract) {
|
|
26
|
+
// Validation outside transactionAsync - these are not DB operations
|
|
24
27
|
const privateFunctions = contract.functions.filter((functionArtifact)=>functionArtifact.functionType === FunctionType.PRIVATE);
|
|
25
28
|
const privateSelectors = await Promise.all(privateFunctions.map(async (privateFunctionArtifact)=>(await FunctionSelector.fromNameAndParameters(privateFunctionArtifact.name, privateFunctionArtifact.parameters)).toString()));
|
|
26
29
|
if (privateSelectors.length !== new Set(privateSelectors).size) {
|
|
27
30
|
throw new Error('Repeated function selectors of private functions');
|
|
28
31
|
}
|
|
29
|
-
await this.#contractArtifacts.set(id.toString(), contractArtifactToBuffer(contract));
|
|
32
|
+
await this.#store.transactionAsync(()=>this.#contractArtifacts.set(id.toString(), contractArtifactToBuffer(contract)));
|
|
30
33
|
}
|
|
31
34
|
async addContractInstance(contract) {
|
|
32
35
|
this.#contractClassIdMap.set(contract.address.toString(), contract.currentContractClassId);
|
|
@@ -68,18 +71,24 @@ import { PrivateFunctionsTree } from './private_functions_tree.js';
|
|
|
68
71
|
return contractClassId && this.getContractArtifact(contractClassId);
|
|
69
72
|
}
|
|
70
73
|
// Public getters
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
74
|
+
getContractsAddresses() {
|
|
75
|
+
return this.#store.transactionAsync(async ()=>{
|
|
76
|
+
const keys = await toArray(this.#contractInstances.keysAsync());
|
|
77
|
+
return keys.map(AztecAddress.fromString);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/** Returns a contract instance for a given address. Throws if not found. */ getContractInstance(contractAddress) {
|
|
81
|
+
return this.#store.transactionAsync(async ()=>{
|
|
82
|
+
const contract = await this.#contractInstances.getAsync(contractAddress.toString());
|
|
83
|
+
return contract && SerializableContractInstance.fromBuffer(contract).withAddress(contractAddress);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
getContractArtifact(contractClassId) {
|
|
87
|
+
return this.#store.transactionAsync(async ()=>{
|
|
88
|
+
const contract = await this.#contractArtifacts.getAsync(contractClassId.toString());
|
|
89
|
+
// TODO(@spalladino): AztecAsyncMap lies and returns Uint8Arrays instead of Buffers, hence the extra Buffer.from.
|
|
90
|
+
return contract && contractArtifactFromBuffer(Buffer.from(contract));
|
|
91
|
+
});
|
|
83
92
|
}
|
|
84
93
|
/** Returns a contract class for a given class id. Throws if not found. */ async getContractClass(contractClassId) {
|
|
85
94
|
const artifact = await this.getContractArtifact(contractClassId);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const PXE_DATA_SCHEMA_VERSION =
|
|
1
|
+
export declare const PXE_DATA_SCHEMA_VERSION = 3;
|
|
2
2
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0YWRhdGEuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yYWdlL21ldGFkYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGVBQU8sTUFBTSx1QkFBdUIsSUFBSSxDQUFDIn0=
|
package/dest/storage/metadata.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const PXE_DATA_SCHEMA_VERSION =
|
|
1
|
+
export const PXE_DATA_SCHEMA_VERSION = 3;
|
|
@@ -67,7 +67,17 @@ export declare class NoteStore implements StagedStore {
|
|
|
67
67
|
* @param synchedBlockNumber - The block number up to which PXE managed to sync before the reorg happened.
|
|
68
68
|
*/
|
|
69
69
|
rollback(blockNumber: number, synchedBlockNumber: number): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Commits in memory job data to persistent storage.
|
|
72
|
+
*
|
|
73
|
+
* Called by JobCoordinator when a job completes successfully.
|
|
74
|
+
*
|
|
75
|
+
* Note: JobCoordinator wraps all commits in a single transaction, so we don't need our own transactionAsync here
|
|
76
|
+
* (and using one would throw on IndexedDB as it does not support nested txs).
|
|
77
|
+
*
|
|
78
|
+
* @param jobId - The jobId identifying which staged data to commit
|
|
79
|
+
*/
|
|
70
80
|
commit(jobId: string): Promise<void>;
|
|
71
81
|
discardStaged(jobId: string): Promise<void>;
|
|
72
82
|
}
|
|
73
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
83
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90ZV9zdG9yZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3N0b3JhZ2Uvbm90ZV9zdG9yZS9ub3RlX3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sS0FBSyxFQUFFLEVBQUUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3BELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFxQyxNQUFNLGlCQUFpQixDQUFDO0FBQzVGLE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2hFLE9BQU8sS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxPQUFPLEVBQWMsS0FBSyxXQUFXLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUUzRSxPQUFPLEtBQUssRUFBRSxXQUFXLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUc1RTs7Ozs7SUFLSTtBQUNKLHFCQUFhLFNBQVUsWUFBVyxXQUFXOztJQUMzQyxRQUFRLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBVTtJQStCcEMsWUFBWSxLQUFLLEVBQUUsaUJBQWlCLEVBUW5DO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksUUFBUSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBYXJGO0lBY0Q7Ozs7Ozs7Ozs7O09BV0c7SUFDSCxRQUFRLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQTZGL0Q7SUFFRDs7Ozs7Ozs7Ozs7Ozs7T0FjRztJQUNILGVBQWUsQ0FBQyxVQUFVLEVBQUUsV0FBVyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FxQ2hGO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDVSxRQUFRLENBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQU1wRjtJQTZFRDs7Ozs7Ozs7O09BU0c7SUFDRyxNQUFNLENBQUMsS0FBSyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBVXpDO0lBRUQsYUFBYSxDQUFDLEtBQUssRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUcxQztDQWtDRiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"note_store.d.ts","sourceRoot":"","sources":["../../../src/storage/note_store/note_store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"note_store.d.ts","sourceRoot":"","sources":["../../../src/storage/note_store/note_store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,2BAA2B,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAqC,MAAM,iBAAiB,CAAC;AAC5F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAC;AAG5E;;;;;IAKI;AACJ,qBAAa,SAAU,YAAW,WAAW;;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAU;IA+BpC,YAAY,KAAK,EAAE,iBAAiB,EAQnC;IAED;;;;;;;;;OASG;IACI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAarF;IAcD;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CA6F/D;IAED;;;;;;;;;;;;;;OAcG;IACH,eAAe,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAqChF;IAED;;;;;;;;;;;OAWG;IACU,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMpF;IA6ED;;;;;;;;;OASG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUzC;IAED,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1C;CAkCF"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { toArray } from '@aztec/foundation/iterable';
|
|
2
1
|
import { Semaphore } from '@aztec/foundation/queue';
|
|
3
2
|
import { NoteStatus } from '@aztec/stdlib/note';
|
|
4
3
|
import { StoredNote } from './stored_note.js';
|
|
@@ -9,6 +8,7 @@ import { StoredNote } from './stored_note.js';
|
|
|
9
8
|
* the case of a reorg.
|
|
10
9
|
**/ export class NoteStore {
|
|
11
10
|
storeName = 'note';
|
|
11
|
+
#store;
|
|
12
12
|
// Note that we use the siloedNullifier as the note id in the store as it's guaranteed to be unique.
|
|
13
13
|
// Main storage for notes. Avoid performing full scans on it as it contains all notes PXE knows, use
|
|
14
14
|
// #nullifiersByContractAddress or #nullifiersByNullificationBlockNumber to find relevant note nullifiers that can be
|
|
@@ -31,6 +31,7 @@ import { StoredNote } from './stored_note.js';
|
|
|
31
31
|
// jobId => lock
|
|
32
32
|
#jobLocks;
|
|
33
33
|
constructor(store){
|
|
34
|
+
this.#store = store;
|
|
34
35
|
this.#notes = store.openMap('notes');
|
|
35
36
|
this.#nullifiersByContractAddress = store.openMultiMap('note_nullifiers_by_contract');
|
|
36
37
|
this.#nullifiersByNullificationBlockNumber = store.openMultiMap('note_block_number_to_nullifier');
|
|
@@ -47,26 +48,18 @@ import { StoredNote } from './stored_note.js';
|
|
|
47
48
|
* @param scope - The scope (user/account) under which to store the notes
|
|
48
49
|
* @param jobId - The job context for staged writes
|
|
49
50
|
*/ addNotes(notes, scope, jobId) {
|
|
50
|
-
return this.#withJobLock(jobId, ()=>Promise.all(notes.map((
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
noteForJob.addScope(scope.toString());
|
|
56
|
-
this.#writeNote(noteForJob, jobId);
|
|
51
|
+
return this.#withJobLock(jobId, ()=>this.#store.transactionAsync(()=>Promise.all(notes.map(async (note)=>{
|
|
52
|
+
const noteForJob = await this.#readNote(note.siloedNullifier.toString(), jobId) ?? new StoredNote(note, new Set());
|
|
53
|
+
noteForJob.addScope(scope.toString());
|
|
54
|
+
this.#writeNote(noteForJob, jobId);
|
|
55
|
+
}))));
|
|
57
56
|
}
|
|
58
57
|
async #readNote(nullifier, jobId) {
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
if (noteForJob) {
|
|
62
|
-
return noteForJob;
|
|
63
|
-
}
|
|
64
|
-
// Then check persistent storage
|
|
58
|
+
// Always issue DB read to keep IndexedDB transaction alive (they auto-commit when a new micro-task starts and there
|
|
59
|
+
// are no pending read requests). The staged value still takes precedence if it exists.
|
|
65
60
|
const noteBuffer = await this.#notes.getAsync(nullifier);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
return undefined;
|
|
61
|
+
const noteForJob = this.#getNotesForJob(jobId).get(nullifier);
|
|
62
|
+
return noteForJob ?? (noteBuffer ? StoredNote.fromBuffer(noteBuffer) : undefined);
|
|
70
63
|
}
|
|
71
64
|
#writeNote(note, jobId) {
|
|
72
65
|
this.#getNotesForJob(jobId).set(note.noteDao.siloedNullifier.toString(), note);
|
|
@@ -82,48 +75,84 @@ import { StoredNote } from './stored_note.js';
|
|
|
82
75
|
* @returns Filtered and deduplicated notes (a note might be present in multiple scopes - we ensure it is only
|
|
83
76
|
* returned once if this is the case)
|
|
84
77
|
* @throws If filtering by an empty scopes array. Scopes have to be set to undefined or to a non-empty array.
|
|
85
|
-
*/
|
|
78
|
+
*/ getNotes(filter, jobId) {
|
|
86
79
|
if (filter.scopes !== undefined && filter.scopes.length === 0) {
|
|
87
|
-
|
|
80
|
+
return Promise.reject(new Error('Trying to get notes with an empty scopes array'));
|
|
88
81
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
|
|
82
|
+
return this.#store.transactionAsync(async ()=>{
|
|
83
|
+
const targetStatus = filter.status ?? NoteStatus.ACTIVE;
|
|
84
|
+
// The code below might read a bit unnatural, the reason is that we need to be careful in how we use `await` inside
|
|
85
|
+
// `transactionAsync`, otherwise browsers might choose to auto-commit the IndexedDB transaction forcing us to
|
|
86
|
+
// explicitly handle that condition. The rule we need to honor is: do not await unless you generate a database
|
|
87
|
+
// read or write or you're done using the DB for the remainder of the transaction. The following sequence is
|
|
88
|
+
// unsafe in IndexedDB:
|
|
89
|
+
//
|
|
90
|
+
// 1. start transactionAsync()
|
|
91
|
+
// 2. await readDb() <-- OK, transaction alive because we issued DB ops
|
|
92
|
+
// 3. run a bunch of computations (no await involved) <-- OK, tx alive because we are in the same microtask
|
|
93
|
+
// 4. await doSthNotInDb() <-- no DB ops issued in this task, browser's free to decide to commit the tx
|
|
94
|
+
// 5. await readDb() <-- BOOM, TransactionInactiveError
|
|
95
|
+
//
|
|
96
|
+
// Note that the real issue is in step number 5: we try to continue using a transaction that the browser might
|
|
97
|
+
// have already committed.
|
|
98
|
+
//
|
|
99
|
+
// We need to read candidate notes which are either indexed by contract address in the DB (in
|
|
100
|
+
// #nullifiersByContractAddress), or lie in memory for the not yet committed `jobId`.
|
|
101
|
+
// So we collect promises based on both sources without awaiting for them.
|
|
102
|
+
const noteReadPromises = new Map();
|
|
103
|
+
// Awaiting the getValuesAsync iterator is fine because it's reading from the DB
|
|
104
|
+
for await (const nullifier of this.#nullifiersByContractAddress.getValuesAsync(filter.contractAddress.toString())){
|
|
105
|
+
// Each #readNote will perform a DB read
|
|
106
|
+
noteReadPromises.set(nullifier, this.#readNote(nullifier, jobId));
|
|
101
107
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
if (filter.scopes && note.scopes.intersection(new Set(filter.scopes.map((s)=>s.toString()))).size === 0) {
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
foundNotes.set(note.noteDao.siloedNullifier.toString(), note.noteDao);
|
|
115
|
-
}
|
|
116
|
-
// Sort by block number, then by tx index within block, then by note index within tx
|
|
117
|
-
return [
|
|
118
|
-
...foundNotes.values()
|
|
119
|
-
].sort((a, b)=>{
|
|
120
|
-
if (a.l2BlockNumber !== b.l2BlockNumber) {
|
|
121
|
-
return a.l2BlockNumber - b.l2BlockNumber;
|
|
108
|
+
// Add staged nullifiers from job, no awaits involved, so we are fine
|
|
109
|
+
for (const storedNote of this.#getNotesForJob(jobId).values()){
|
|
110
|
+
if (storedNote.noteDao.contractAddress.equals(filter.contractAddress)) {
|
|
111
|
+
const nullifier = storedNote.noteDao.siloedNullifier.toString();
|
|
112
|
+
if (!noteReadPromises.has(nullifier)) {
|
|
113
|
+
noteReadPromises.set(nullifier, Promise.resolve(storedNote));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
122
116
|
}
|
|
123
|
-
|
|
124
|
-
|
|
117
|
+
// By now we have pending DB requests from all the #readNote calls. Await them all together.
|
|
118
|
+
const notes = await Promise.all(noteReadPromises.values());
|
|
119
|
+
// The rest of the function is await-free, and just deals with filtering and sorting our findings.
|
|
120
|
+
const foundNotes = new Map();
|
|
121
|
+
for (const note of notes){
|
|
122
|
+
// Defensive: hitting this case means we're mishandling contract indices or in-memory job data
|
|
123
|
+
if (!note) {
|
|
124
|
+
throw new Error('PXE note database is corrupted.');
|
|
125
|
+
}
|
|
126
|
+
// Apply filters
|
|
127
|
+
if (targetStatus === NoteStatus.ACTIVE && note.isNullified()) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (filter.owner && !note.noteDao.owner.equals(filter.owner)) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (filter.storageSlot && !note.noteDao.storageSlot.equals(filter.storageSlot)) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (filter.siloedNullifier && !note.noteDao.siloedNullifier.equals(filter.siloedNullifier)) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (filter.scopes && note.scopes.intersection(new Set(filter.scopes.map((s)=>s.toString()))).size === 0) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
foundNotes.set(note.noteDao.siloedNullifier.toString(), note.noteDao);
|
|
125
143
|
}
|
|
126
|
-
|
|
144
|
+
// Sort by block number, then by tx index within block, then by note index within tx
|
|
145
|
+
return [
|
|
146
|
+
...foundNotes.values()
|
|
147
|
+
].sort((a, b)=>{
|
|
148
|
+
if (a.l2BlockNumber !== b.l2BlockNumber) {
|
|
149
|
+
return a.l2BlockNumber - b.l2BlockNumber;
|
|
150
|
+
}
|
|
151
|
+
if (a.txIndexInBlock !== b.txIndexInBlock) {
|
|
152
|
+
return a.txIndexInBlock - b.txIndexInBlock;
|
|
153
|
+
}
|
|
154
|
+
return a.noteIndexInTx - b.noteIndexInTx;
|
|
155
|
+
});
|
|
127
156
|
});
|
|
128
157
|
}
|
|
129
158
|
/**
|
|
@@ -141,37 +170,36 @@ import { StoredNote } from './stored_note.js';
|
|
|
141
170
|
* @returns Array of NoteDao objects that were nullified
|
|
142
171
|
* @throws Error if any nullifier is not found in this notes store
|
|
143
172
|
*/ applyNullifiers(nullifiers, jobId) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
173
|
+
if (nullifiers.length === 0) {
|
|
174
|
+
return Promise.resolve([]);
|
|
175
|
+
}
|
|
176
|
+
return this.#withJobLock(jobId, ()=>this.#store.transactionAsync(async ()=>{
|
|
177
|
+
const notesToNullify = await Promise.all(nullifiers.map(async (nullifierInBlock)=>{
|
|
178
|
+
const nullifier = nullifierInBlock.data.toString();
|
|
179
|
+
const storedNote = await this.#readNote(nullifier, jobId);
|
|
180
|
+
if (!storedNote) {
|
|
181
|
+
throw new Error(`Attempted to mark a note as nullified which does not exist in PXE DB`);
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
storedNote,
|
|
185
|
+
blockNumber: nullifierInBlock.l2BlockNumber
|
|
186
|
+
};
|
|
187
|
+
}));
|
|
188
|
+
const notesNullifiedInThisCall = new Map();
|
|
189
|
+
for (const noteToNullify of notesToNullify){
|
|
190
|
+
const note = noteToNullify.storedNote;
|
|
191
|
+
// Skip already nullified notes
|
|
192
|
+
if (note.isNullified()) {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
note.markAsNullified(noteToNullify.blockNumber);
|
|
196
|
+
this.#writeNote(note, jobId);
|
|
197
|
+
notesNullifiedInThisCall.set(note.noteDao.siloedNullifier.toString(), note.noteDao);
|
|
153
198
|
}
|
|
154
|
-
return
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
};
|
|
199
|
+
return [
|
|
200
|
+
...notesNullifiedInThisCall.values()
|
|
201
|
+
];
|
|
158
202
|
}));
|
|
159
|
-
const notesNullifiedInThisCall = new Map();
|
|
160
|
-
for (const noteToNullify of notesToNullify){
|
|
161
|
-
// Safe to coerce (!) because we throw if we find any undefined above
|
|
162
|
-
const note = noteToNullify.storedNote;
|
|
163
|
-
// Skip already nullified notes
|
|
164
|
-
if (note.isNullified()) {
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
note.markAsNullified(noteToNullify.blockNumber);
|
|
168
|
-
this.#writeNote(note, jobId);
|
|
169
|
-
notesNullifiedInThisCall.set(note.noteDao.siloedNullifier.toString(), note.noteDao);
|
|
170
|
-
}
|
|
171
|
-
return [
|
|
172
|
-
...notesNullifiedInThisCall.values()
|
|
173
|
-
];
|
|
174
|
-
});
|
|
175
203
|
}
|
|
176
204
|
/**
|
|
177
205
|
* Synchronizes notes and nullifiers to a specific block number.
|
|
@@ -198,15 +226,22 @@ import { StoredNote } from './stored_note.js';
|
|
|
198
226
|
*
|
|
199
227
|
* @param blockNumber - Notes created after this block number will be deleted
|
|
200
228
|
*/ async #deleteActiveNotesAfterBlock(blockNumber) {
|
|
201
|
-
|
|
202
|
-
|
|
229
|
+
// Collect notes to delete during iteration to keep IndexedDB transaction alive.
|
|
230
|
+
const notesToDelete = [];
|
|
231
|
+
for await (const noteBuffer of this.#notes.valuesAsync()){
|
|
203
232
|
const storedNote = StoredNote.fromBuffer(noteBuffer);
|
|
204
233
|
if (storedNote.noteDao.l2BlockNumber > blockNumber) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
234
|
+
notesToDelete.push({
|
|
235
|
+
nullifier: storedNote.noteDao.siloedNullifier.toString(),
|
|
236
|
+
contractAddress: storedNote.noteDao.contractAddress.toString()
|
|
237
|
+
});
|
|
208
238
|
}
|
|
209
239
|
}
|
|
240
|
+
// Delete all collected notes. Each delete is a DB operation that keeps the transaction alive.
|
|
241
|
+
for (const { nullifier, contractAddress } of notesToDelete){
|
|
242
|
+
await this.#notes.delete(nullifier);
|
|
243
|
+
await this.#nullifiersByContractAddress.deleteValue(contractAddress, nullifier);
|
|
244
|
+
}
|
|
210
245
|
}
|
|
211
246
|
/**
|
|
212
247
|
* Rewinds nullifications after a given block number.
|
|
@@ -217,47 +252,62 @@ import { StoredNote } from './stored_note.js';
|
|
|
217
252
|
* @param blockNumber - Revert nullifications that occurred after this block
|
|
218
253
|
* @param anchorBlockNumber - Upper bound for the block range to process
|
|
219
254
|
*/ async #rewindNullifiedNotesAfterBlock(blockNumber, anchorBlockNumber) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
255
|
+
// First pass: collect all nullifiers for all blocks, starting reads during iteration to keep tx alive.
|
|
256
|
+
const nullifiersByBlock = new Map();
|
|
257
|
+
for(let i = blockNumber + 1; i <= anchorBlockNumber; i++){
|
|
258
|
+
const blockNullifiers = [];
|
|
259
|
+
for await (const nullifier of this.#nullifiersByNullificationBlockNumber.getValuesAsync(i)){
|
|
260
|
+
// Start read immediately during iteration to keep IndexedDB transaction alive
|
|
261
|
+
blockNullifiers.push({
|
|
262
|
+
nullifier,
|
|
263
|
+
noteReadPromise: this.#notes.getAsync(nullifier)
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
if (blockNullifiers.length > 0) {
|
|
267
|
+
nullifiersByBlock.set(i, blockNullifiers);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// Second pass: await reads and perform writes
|
|
271
|
+
for (const [block, nullifiers] of nullifiersByBlock){
|
|
272
|
+
for (const { nullifier, noteReadPromise } of nullifiers){
|
|
273
|
+
const noteBuffer = await noteReadPromise;
|
|
274
|
+
if (!noteBuffer) {
|
|
275
|
+
throw new Error(`PXE DB integrity error: no note found with nullifier ${nullifier}`);
|
|
227
276
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
for (const storedNote of storedNotes){
|
|
232
|
-
const noteNullifier = storedNote.noteDao.siloedNullifier.toString();
|
|
233
|
-
const scopes = storedNote.scopes;
|
|
234
|
-
if (scopes.size === 0) {
|
|
235
|
-
// We should never run into this error because notes always have a scope assigned to them - either on initial
|
|
236
|
-
// insertion via `addNotes` or when removing their nullifiers.
|
|
237
|
-
throw new Error(`No scopes found for nullified note with nullifier ${noteNullifier}`);
|
|
277
|
+
const storedNote = StoredNote.fromBuffer(noteBuffer);
|
|
278
|
+
if (storedNote.scopes.size === 0) {
|
|
279
|
+
throw new Error(`No scopes found for nullified note with nullifier ${nullifier}`);
|
|
238
280
|
}
|
|
239
281
|
storedNote.markAsActive();
|
|
240
282
|
await Promise.all([
|
|
241
|
-
this.#notes.set(
|
|
242
|
-
this.#nullifiersByNullificationBlockNumber.deleteValue(
|
|
283
|
+
this.#notes.set(nullifier, storedNote.toBuffer()),
|
|
284
|
+
this.#nullifiersByNullificationBlockNumber.deleteValue(block, nullifier)
|
|
243
285
|
]);
|
|
244
286
|
}
|
|
245
287
|
}
|
|
246
288
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
289
|
+
/**
|
|
290
|
+
* Commits in memory job data to persistent storage.
|
|
291
|
+
*
|
|
292
|
+
* Called by JobCoordinator when a job completes successfully.
|
|
293
|
+
*
|
|
294
|
+
* Note: JobCoordinator wraps all commits in a single transaction, so we don't need our own transactionAsync here
|
|
295
|
+
* (and using one would throw on IndexedDB as it does not support nested txs).
|
|
296
|
+
*
|
|
297
|
+
* @param jobId - The jobId identifying which staged data to commit
|
|
298
|
+
*/ async commit(jobId) {
|
|
299
|
+
for (const [nullifier, storedNote] of this.#getNotesForJob(jobId)){
|
|
300
|
+
await this.#notes.set(nullifier, storedNote.toBuffer());
|
|
301
|
+
await this.#nullifiersByContractAddress.set(storedNote.noteDao.contractAddress.toString(), nullifier);
|
|
302
|
+
if (storedNote.nullifiedAt !== undefined) {
|
|
303
|
+
await this.#nullifiersByNullificationBlockNumber.set(storedNote.nullifiedAt, nullifier);
|
|
255
304
|
}
|
|
256
|
-
|
|
257
|
-
|
|
305
|
+
}
|
|
306
|
+
this.#clearJobData(jobId);
|
|
258
307
|
}
|
|
259
308
|
discardStaged(jobId) {
|
|
260
|
-
|
|
309
|
+
this.#clearJobData(jobId);
|
|
310
|
+
return Promise.resolve();
|
|
261
311
|
}
|
|
262
312
|
#clearJobData(jobId) {
|
|
263
313
|
this.#notesForJob.delete(jobId);
|
|
@@ -288,14 +338,4 @@ import { StoredNote } from './stored_note.js';
|
|
|
288
338
|
}
|
|
289
339
|
return notesForJob;
|
|
290
340
|
}
|
|
291
|
-
async #nullifiersOfContract(contractAddress, jobId) {
|
|
292
|
-
// Collect persisted nullifiers for this contract
|
|
293
|
-
const persistedNullifiers = await toArray(this.#nullifiersByContractAddress.getValuesAsync(contractAddress.toString()));
|
|
294
|
-
// Collect staged nullifiers from the job where the note's contract matches
|
|
295
|
-
const stagedNullifiers = this.#getNotesForJob(jobId).values().filter((storedNote)=>storedNote.noteDao.contractAddress.equals(contractAddress)).map((storedNote)=>storedNote.noteDao.siloedNullifier.toString());
|
|
296
|
-
return new Set([
|
|
297
|
-
...persistedNullifiers,
|
|
298
|
-
...stagedNullifiers
|
|
299
|
-
]);
|
|
300
|
-
}
|
|
301
341
|
}
|
|
@@ -88,4 +88,4 @@ export declare class PrivateEventStore implements StagedStore {
|
|
|
88
88
|
discardStaged(jobId: string): Promise<void>;
|
|
89
89
|
}
|
|
90
90
|
export {};
|
|
91
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
91
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpdmF0ZV9ldmVudF9zdG9yZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3N0b3JhZ2UvcHJpdmF0ZV9ldmVudF9zdG9yZS9wcml2YXRlX2V2ZW50X3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUdwRCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBcUMsTUFBTSxpQkFBaUIsQ0FBQztBQUM1RixPQUFPLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN2RCxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNoRSxPQUFPLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFckQsT0FBTyxLQUFLLEVBQUUsV0FBVyxFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDNUUsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFHdkQsTUFBTSxNQUFNLHVCQUF1QixHQUFHO0lBQ3BDLGVBQWUsRUFBRSxZQUFZLENBQUM7SUFDOUIsU0FBUyxFQUFFLE1BQU0sQ0FBQztJQUNsQixPQUFPLEVBQUUsTUFBTSxDQUFDO0lBQ2hCLE1BQU0sRUFBRSxZQUFZLEVBQUUsQ0FBQztJQUN2QixNQUFNLENBQUMsRUFBRSxNQUFNLENBQUM7Q0FDakIsQ0FBQztBQUVGLEtBQUssb0JBQW9CLEdBQUcsSUFBSSxHQUFHO0lBQ2pDLGVBQWUsRUFBRSxZQUFZLENBQUM7SUFDOUIsS0FBSyxFQUFFLFlBQVksQ0FBQztJQUNwQiwyQ0FBMkM7SUFDM0MsY0FBYyxFQUFFLE1BQU0sQ0FBQztJQUN2Qix5RUFBeUU7SUFDekUsY0FBYyxFQUFFLE1BQU0sQ0FBQztDQUN4QixDQUFDO0FBRUY7O0dBRUc7QUFDSCxxQkFBYSxpQkFBa0IsWUFBVyxXQUFXOztJQUNuRCxRQUFRLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBbUI7SUFnQjdDLE1BQU0seUNBQXVDO0lBRTdDLFlBQVksS0FBSyxFQUFFLGlCQUFpQixFQVFuQztJQUVEOzs7Ozs7Ozs7OztPQVdHO0lBQ0gsb0JBQW9CLENBQ2xCLGFBQWEsRUFBRSxhQUFhLEVBQzVCLFVBQVUsRUFBRSxFQUFFLEVBQ2QsVUFBVSxFQUFFLEVBQUUsRUFBRSxFQUNoQixxQkFBcUIsRUFBRSxFQUFFLEVBQ3pCLFFBQVEsRUFBRSxvQkFBb0IsRUFDOUIsS0FBSyxFQUFFLE1BQU0saUJBeUNkO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLGdCQUFnQixDQUNyQixhQUFhLEVBQUUsYUFBYSxFQUM1QixNQUFNLEVBQUUsdUJBQXVCLEdBQzlCLE9BQU8sQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBK0UvQjtJQUVEOzs7Ozs7Ozs7Ozs7Ozs7O09BZ0JHO0lBQ1UsUUFBUSxDQUFDLFdBQVcsRUFBRSxNQUFNLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FzQ3BGO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0csTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQWdCekM7SUFFRDs7T0FFRztJQUNILGFBQWEsQ0FBQyxLQUFLLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FHMUM7Q0EwRUYifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"private_event_store.d.ts","sourceRoot":"","sources":["../../../src/storage/private_event_store/private_event_store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"private_event_store.d.ts","sourceRoot":"","sources":["../../../src/storage/private_event_store/private_event_store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAGpD,OAAO,KAAK,EAAE,iBAAiB,EAAqC,MAAM,iBAAiB,CAAC;AAC5F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGvD,MAAM,MAAM,uBAAuB,GAAG;IACpC,eAAe,EAAE,YAAY,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,oBAAoB,GAAG,IAAI,GAAG;IACjC,eAAe,EAAE,YAAY,CAAC;IAC9B,KAAK,EAAE,YAAY,CAAC;IACpB,2CAA2C;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,qBAAa,iBAAkB,YAAW,WAAW;;IACnD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAmB;IAgB7C,MAAM,yCAAuC;IAE7C,YAAY,KAAK,EAAE,iBAAiB,EAQnC;IAED;;;;;;;;;;;OAWG;IACH,oBAAoB,CAClB,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,EAAE,EACd,UAAU,EAAE,EAAE,EAAE,EAChB,qBAAqB,EAAE,EAAE,EACzB,QAAQ,EAAE,oBAAoB,EAC9B,KAAK,EAAE,MAAM,iBAyCd;IAED;;;;;;;;;;OAUG;IACI,gBAAgB,CACrB,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,kBAAkB,EAAE,CAAC,CA+E/B;IAED;;;;;;;;;;;;;;;;OAgBG;IACU,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCpF;IAED;;;;;;;;;OASG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBzC;IAED;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1C;CA0EF"}
|