@aztec/pxe 3.0.0-canary.a9708bd → 3.0.0-devnet.20251212
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/README.md +5 -5
- package/dest/bin/check_oracle_version.d.ts +1 -1
- package/dest/bin/check_oracle_version.js +110 -10
- package/dest/config/index.d.ts +9 -17
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +10 -16
- package/dest/config/package_info.d.ts +1 -1
- package/dest/config/package_info.js +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +6 -6
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +97 -42
- package/dest/contract_function_simulator/execution_data_provider.d.ts +40 -57
- package/dest/contract_function_simulator/execution_data_provider.d.ts.map +1 -1
- package/dest/contract_function_simulator/execution_note_cache.d.ts +11 -9
- package/dest/contract_function_simulator/execution_note_cache.d.ts.map +1 -1
- package/dest/contract_function_simulator/execution_note_cache.js +28 -17
- package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts +16 -0
- package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts.map +1 -0
- package/dest/contract_function_simulator/execution_tagging_index_cache.js +26 -0
- package/dest/contract_function_simulator/hashed_values_cache.d.ts +2 -2
- package/dest/contract_function_simulator/hashed_values_cache.d.ts.map +1 -1
- package/dest/contract_function_simulator/index.d.ts +4 -2
- package/dest/contract_function_simulator/index.d.ts.map +1 -1
- package/dest/contract_function_simulator/index.js +2 -1
- package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +2 -2
- package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts +2 -2
- package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +3 -3
- package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +8 -4
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +6 -3
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/note_validation_request.js +12 -3
- package/dest/contract_function_simulator/noir-structs/utility_context.d.ts +22 -0
- package/dest/contract_function_simulator/noir-structs/utility_context.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/utility_context.js +33 -0
- package/dest/contract_function_simulator/oracle/index.d.ts +2 -2
- package/dest/contract_function_simulator/oracle/index.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/index.js +1 -1
- package/dest/contract_function_simulator/oracle/interfaces.d.ts +104 -0
- package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -0
- package/dest/contract_function_simulator/oracle/interfaces.js +4 -0
- package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts +2 -4
- package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.js +1 -1
- package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts +10 -4
- package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/note_packing_utils.js +10 -5
- package/dest/contract_function_simulator/oracle/oracle.d.ts +17 -15
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.js +101 -81
- package/dest/contract_function_simulator/oracle/private_execution.d.ts +6 -5
- package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution.js +7 -16
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +34 -22
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +89 -25
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +23 -33
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +38 -42
- package/dest/contract_function_simulator/pick_notes.d.ts +2 -2
- package/dest/contract_function_simulator/pick_notes.d.ts.map +1 -1
- package/dest/contract_function_simulator/pick_notes.js +1 -1
- package/dest/contract_function_simulator/proxied_contract_data_source.d.ts +1 -1
- package/dest/contract_function_simulator/proxied_contract_data_source.d.ts.map +1 -1
- package/dest/contract_function_simulator/proxied_node.d.ts +1 -1
- package/dest/contract_function_simulator/proxied_node.d.ts.map +1 -1
- package/dest/contract_function_simulator/pxe_oracle_interface.d.ts +34 -68
- package/dest/contract_function_simulator/pxe_oracle_interface.d.ts.map +1 -1
- package/dest/contract_function_simulator/pxe_oracle_interface.js +220 -208
- package/dest/entrypoints/client/bundle/index.d.ts +4 -2
- package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/index.js +2 -1
- package/dest/entrypoints/client/bundle/utils.d.ts +9 -9
- package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/utils.js +12 -12
- package/dest/entrypoints/client/lazy/index.d.ts +4 -2
- package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/index.js +2 -1
- package/dest/entrypoints/client/lazy/utils.d.ts +8 -8
- package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/utils.js +11 -11
- package/dest/entrypoints/pxe_creation_options.d.ts +3 -1
- package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
- package/dest/entrypoints/server/index.d.ts +4 -2
- package/dest/entrypoints/server/index.d.ts.map +1 -1
- package/dest/entrypoints/server/index.js +2 -1
- package/dest/entrypoints/server/utils.d.ts +5 -24
- package/dest/entrypoints/server/utils.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.js +9 -41
- package/dest/error_enriching.d.ts +11 -0
- package/dest/error_enriching.d.ts.map +1 -0
- package/dest/{pxe_service/error_enriching.js → error_enriching.js} +3 -0
- package/dest/events/index.d.ts +2 -0
- package/dest/events/index.d.ts.map +1 -0
- package/dest/events/index.js +1 -0
- package/dest/events/private_event_filter_validator.d.ts +8 -0
- package/dest/events/private_event_filter_validator.d.ts.map +1 -0
- package/dest/events/private_event_filter_validator.js +39 -0
- package/dest/oracle_version.d.ts +3 -3
- package/dest/oracle_version.js +2 -2
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts +3 -3
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -1
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.js +7 -7
- package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts +1 -1
- package/dest/private_kernel/hints/compute_tx_include_by_timestamp.js +6 -6
- package/dest/private_kernel/hints/index.d.ts +1 -1
- package/dest/private_kernel/index.d.ts +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.d.ts +9 -2
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.js +38 -32
- package/dest/private_kernel/private_kernel_oracle.d.ts +3 -2
- package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_oracle_impl.d.ts +8 -7
- package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +1 -1
- package/dest/pxe.d.ts +240 -0
- package/dest/pxe.d.ts.map +1 -0
- package/dest/{pxe_service/pxe_service.js → pxe.js} +227 -241
- package/dest/storage/address_data_provider/address_data_provider.d.ts +2 -4
- package/dest/storage/address_data_provider/address_data_provider.d.ts.map +1 -1
- package/dest/storage/address_data_provider/address_data_provider.js +0 -3
- package/dest/storage/address_data_provider/index.d.ts +1 -1
- package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts +3 -5
- package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts.map +1 -1
- package/dest/storage/capsule_data_provider/capsule_data_provider.js +1 -5
- package/dest/storage/capsule_data_provider/index.d.ts +1 -1
- package/dest/storage/contract_data_provider/contract_data_provider.d.ts +6 -17
- package/dest/storage/contract_data_provider/contract_data_provider.d.ts.map +1 -1
- package/dest/storage/contract_data_provider/contract_data_provider.js +0 -15
- package/dest/storage/contract_data_provider/index.d.ts +1 -1
- package/dest/storage/contract_data_provider/private_functions_tree.d.ts +1 -1
- package/dest/storage/contract_data_provider/private_functions_tree.d.ts.map +1 -1
- package/dest/storage/contract_data_provider/private_functions_tree.js +1 -1
- package/dest/storage/index.d.ts +1 -2
- package/dest/storage/index.d.ts.map +1 -1
- package/dest/storage/index.js +0 -1
- package/dest/storage/metadata.d.ts +1 -1
- package/dest/storage/note_data_provider/index.d.ts +2 -2
- package/dest/storage/note_data_provider/index.d.ts.map +1 -1
- package/dest/storage/note_data_provider/index.js +1 -1
- package/dest/storage/note_data_provider/note_data_provider.d.ts +75 -11
- package/dest/storage/note_data_provider/note_data_provider.d.ts.map +1 -1
- package/dest/storage/note_data_provider/note_data_provider.js +143 -81
- package/dest/storage/private_event_data_provider/private_event_data_provider.d.ts +31 -17
- package/dest/storage/private_event_data_provider/private_event_data_provider.d.ts.map +1 -1
- package/dest/storage/private_event_data_provider/private_event_data_provider.js +47 -28
- package/dest/storage/sync_data_provider/index.d.ts +1 -1
- package/dest/storage/sync_data_provider/sync_data_provider.d.ts +4 -5
- package/dest/storage/sync_data_provider/sync_data_provider.d.ts.map +1 -1
- package/dest/storage/sync_data_provider/sync_data_provider.js +0 -3
- package/dest/storage/tagging_data_provider/index.d.ts +1 -1
- package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts +29 -7
- package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts.map +1 -1
- package/dest/storage/tagging_data_provider/tagging_data_provider.js +46 -39
- package/dest/synchronizer/index.d.ts +1 -1
- package/dest/synchronizer/synchronizer.d.ts +3 -2
- package/dest/synchronizer/synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/synchronizer.js +4 -4
- package/dest/tagging/constants.d.ts +2 -0
- package/dest/tagging/constants.d.ts.map +1 -0
- package/dest/tagging/constants.js +2 -0
- package/dest/tagging/index.d.ts +7 -0
- package/dest/tagging/index.d.ts.map +1 -0
- package/dest/tagging/index.js +5 -0
- package/dest/tagging/siloed_tag.d.ts +14 -0
- package/dest/tagging/siloed_tag.d.ts.map +1 -0
- package/dest/tagging/siloed_tag.js +20 -0
- package/dest/tagging/tag.d.ts +12 -0
- package/dest/tagging/tag.d.ts.map +1 -0
- package/dest/tagging/tag.js +17 -0
- package/dest/tagging/utils.d.ts +18 -0
- package/dest/tagging/utils.d.ts.map +1 -0
- package/dest/tagging/utils.js +24 -0
- package/package.json +22 -24
- package/src/bin/check_oracle_version.ts +134 -10
- package/src/config/index.ts +18 -32
- package/src/config/package_info.ts +1 -1
- package/src/contract_function_simulator/contract_function_simulator.ts +151 -62
- package/src/contract_function_simulator/execution_data_provider.ts +47 -65
- package/src/contract_function_simulator/execution_note_cache.ts +33 -17
- package/src/contract_function_simulator/execution_tagging_index_cache.ts +32 -0
- package/src/contract_function_simulator/hashed_values_cache.ts +1 -1
- package/src/contract_function_simulator/index.ts +3 -1
- package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -1
- package/src/contract_function_simulator/noir-structs/log_retrieval_request.ts +1 -1
- package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +10 -5
- package/src/contract_function_simulator/noir-structs/note_validation_request.ts +14 -2
- package/src/contract_function_simulator/noir-structs/utility_context.ts +42 -0
- package/src/contract_function_simulator/oracle/index.ts +1 -1
- package/src/contract_function_simulator/oracle/interfaces.ts +176 -0
- package/src/contract_function_simulator/oracle/message_load_oracle_inputs.ts +1 -1
- package/src/contract_function_simulator/oracle/note_packing_utils.ts +21 -5
- package/src/contract_function_simulator/oracle/oracle.ts +135 -80
- package/src/contract_function_simulator/oracle/private_execution.ts +10 -17
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +123 -49
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +68 -80
- package/src/contract_function_simulator/pick_notes.ts +1 -1
- package/src/contract_function_simulator/pxe_oracle_interface.ts +291 -271
- package/src/entrypoints/client/bundle/index.ts +3 -1
- package/src/entrypoints/client/bundle/utils.ts +15 -23
- package/src/entrypoints/client/lazy/index.ts +3 -1
- package/src/entrypoints/client/lazy/utils.ts +14 -22
- package/src/entrypoints/pxe_creation_options.ts +2 -0
- package/src/entrypoints/server/index.ts +3 -1
- package/src/entrypoints/server/utils.ts +12 -56
- package/src/{pxe_service/error_enriching.ts → error_enriching.ts} +5 -1
- package/src/events/index.ts +1 -0
- package/src/events/private_event_filter_validator.ts +47 -0
- package/src/oracle_version.ts +2 -2
- package/src/private_kernel/hints/build_private_kernel_reset_private_inputs.ts +5 -9
- package/src/private_kernel/hints/compute_tx_include_by_timestamp.ts +6 -6
- package/src/private_kernel/private_kernel_execution_prover.ts +51 -43
- package/src/private_kernel/private_kernel_oracle.ts +2 -1
- package/src/private_kernel/private_kernel_oracle_impl.ts +4 -3
- package/src/{pxe_service/pxe_service.ts → pxe.ts} +256 -308
- package/src/storage/address_data_provider/address_data_provider.ts +1 -7
- package/src/storage/capsule_data_provider/capsule_data_provider.ts +2 -12
- package/src/storage/contract_data_provider/contract_data_provider.ts +4 -27
- package/src/storage/contract_data_provider/private_functions_tree.ts +1 -1
- package/src/storage/index.ts +0 -1
- package/src/storage/note_data_provider/index.ts +1 -1
- package/src/storage/note_data_provider/note_data_provider.ts +171 -109
- package/src/storage/private_event_data_provider/private_event_data_provider.ts +69 -41
- package/src/storage/sync_data_provider/sync_data_provider.ts +3 -8
- package/src/storage/tagging_data_provider/tagging_data_provider.ts +52 -55
- package/src/synchronizer/synchronizer.ts +4 -4
- package/src/tagging/constants.ts +2 -0
- package/src/tagging/index.ts +6 -0
- package/src/tagging/siloed_tag.ts +22 -0
- package/src/tagging/tag.ts +16 -0
- package/src/tagging/utils.ts +31 -0
- package/dest/bin/index.d.ts +0 -3
- package/dest/bin/index.d.ts.map +0 -1
- package/dest/bin/index.js +0 -48
- package/dest/contract_function_simulator/oracle/typed_oracle.d.ts +0 -87
- package/dest/contract_function_simulator/oracle/typed_oracle.d.ts.map +0 -1
- package/dest/contract_function_simulator/oracle/typed_oracle.js +0 -146
- package/dest/contract_function_simulator/tagging_utils.d.ts +0 -17
- package/dest/contract_function_simulator/tagging_utils.d.ts.map +0 -1
- package/dest/contract_function_simulator/tagging_utils.js +0 -23
- package/dest/pxe_service/error_enriching.d.ts +0 -11
- package/dest/pxe_service/error_enriching.d.ts.map +0 -1
- package/dest/pxe_service/index.d.ts +0 -3
- package/dest/pxe_service/index.d.ts.map +0 -1
- package/dest/pxe_service/index.js +0 -2
- package/dest/pxe_service/pxe_service.d.ts +0 -100
- package/dest/pxe_service/pxe_service.d.ts.map +0 -1
- package/dest/storage/data_provider.d.ts +0 -4
- package/dest/storage/data_provider.d.ts.map +0 -1
- package/dest/storage/data_provider.js +0 -1
- package/dest/storage/note_data_provider/note_dao.d.ts +0 -100
- package/dest/storage/note_data_provider/note_dao.d.ts.map +0 -1
- package/dest/storage/note_data_provider/note_dao.js +0 -102
- package/dest/test/pxe_test_suite.d.ts +0 -3
- package/dest/test/pxe_test_suite.d.ts.map +0 -1
- package/dest/test/pxe_test_suite.js +0 -97
- package/src/bin/index.ts +0 -62
- package/src/contract_function_simulator/oracle/typed_oracle.ts +0 -289
- package/src/contract_function_simulator/tagging_utils.ts +0 -32
- package/src/pxe_service/index.ts +0 -2
- package/src/storage/data_provider.ts +0 -3
- package/src/storage/note_data_provider/note_dao.ts +0 -154
- package/src/test/pxe_test_suite.ts +0 -113
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import { timesParallel } from '@aztec/foundation/collection';
|
|
2
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
3
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
|
-
import { getFunctionArtifact } from '@aztec/stdlib/abi';
|
|
5
3
|
import { computeUniqueNoteHash, siloNoteHash, siloNullifier, siloPrivateLog } from '@aztec/stdlib/hash';
|
|
6
4
|
import { MAX_RPC_LEN } from '@aztec/stdlib/interfaces/client';
|
|
7
|
-
import { computeAddressSecret
|
|
8
|
-
import {
|
|
5
|
+
import { computeAddressSecret } from '@aztec/stdlib/keys';
|
|
6
|
+
import { PendingTaggedLog, PrivateLogWithTxData, PublicLogWithTxData, deriveEcdhSharedSecret } from '@aztec/stdlib/logs';
|
|
9
7
|
import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
|
|
10
8
|
import { Note } from '@aztec/stdlib/note';
|
|
9
|
+
import { NoteDao } from '@aztec/stdlib/note';
|
|
11
10
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
12
11
|
import { MessageLoadOracleInputs } from '../contract_function_simulator/oracle/message_load_oracle_inputs.js';
|
|
13
12
|
import { ORACLE_VERSION } from '../oracle_version.js';
|
|
14
|
-
import {
|
|
13
|
+
import { DirectionalAppTaggingSecret, SiloedTag, Tag, WINDOW_HALF_SIZE, getInitialIndexesMap, getPreTagsForTheWindow } from '../tagging/index.js';
|
|
15
14
|
import { EventValidationRequest } from './noir-structs/event_validation_request.js';
|
|
16
15
|
import { LogRetrievalRequest } from './noir-structs/log_retrieval_request.js';
|
|
17
16
|
import { LogRetrievalResponse } from './noir-structs/log_retrieval_response.js';
|
|
18
17
|
import { NoteValidationRequest } from './noir-structs/note_validation_request.js';
|
|
19
|
-
import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndexesMap } from './tagging_utils.js';
|
|
20
18
|
/**
|
|
21
19
|
* A data layer that provides and stores information needed for simulating/proving a transaction.
|
|
22
20
|
*/ export class PXEOracleInterface {
|
|
@@ -49,7 +47,7 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
49
47
|
const completeAddress = await this.addressDataProvider.getCompleteAddress(account);
|
|
50
48
|
if (!completeAddress) {
|
|
51
49
|
throw new Error(`No public key registered for address ${account}.
|
|
52
|
-
Register it by calling pxe.addAccount(...).\nSee docs for context: https://docs.aztec.network/developers/
|
|
50
|
+
Register it by calling pxe.addAccount(...).\nSee docs for context: https://docs.aztec.network/developers/resources/debugging/aztecnr-errors#simulation-error-no-public-key-registered-for-address-0x0-register-it-by-calling-pxeregisterrecipient-or-pxeregisteraccount`);
|
|
53
51
|
}
|
|
54
52
|
return completeAddress;
|
|
55
53
|
}
|
|
@@ -60,16 +58,19 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
60
58
|
}
|
|
61
59
|
return instance;
|
|
62
60
|
}
|
|
63
|
-
async getNotes(contractAddress, storageSlot, status, scopes) {
|
|
61
|
+
async getNotes(contractAddress, owner, storageSlot, status, scopes) {
|
|
64
62
|
const noteDaos = await this.noteDataProvider.getNotes({
|
|
65
63
|
contractAddress,
|
|
64
|
+
owner,
|
|
66
65
|
storageSlot,
|
|
67
66
|
status,
|
|
68
67
|
scopes
|
|
69
68
|
});
|
|
70
|
-
return noteDaos.map(({ contractAddress, storageSlot, noteNonce, note, noteHash, siloedNullifier, index })=>({
|
|
69
|
+
return noteDaos.map(({ contractAddress, owner, storageSlot, randomness, noteNonce, note, noteHash, siloedNullifier, index })=>({
|
|
71
70
|
contractAddress,
|
|
71
|
+
owner,
|
|
72
72
|
storageSlot,
|
|
73
|
+
randomness,
|
|
73
74
|
noteNonce,
|
|
74
75
|
note,
|
|
75
76
|
noteHash,
|
|
@@ -89,14 +90,6 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
89
90
|
debug
|
|
90
91
|
};
|
|
91
92
|
}
|
|
92
|
-
async getFunctionArtifactByName(contractAddress, functionName) {
|
|
93
|
-
const instance = await this.contractDataProvider.getContractInstance(contractAddress);
|
|
94
|
-
if (!instance) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
const artifact = await this.contractDataProvider.getContractArtifact(instance.currentContractClassId);
|
|
98
|
-
return artifact && getFunctionArtifact(artifact, functionName);
|
|
99
|
-
}
|
|
100
93
|
/**
|
|
101
94
|
* Fetches a message from the db, given its key.
|
|
102
95
|
* @param contractAddress - Address of a contract by which the message was emitted.
|
|
@@ -140,30 +133,41 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
140
133
|
}
|
|
141
134
|
}
|
|
142
135
|
async getNullifierMembershipWitnessAtLatestBlock(nullifier) {
|
|
143
|
-
|
|
136
|
+
const blockNumber = (await this.getAnchorBlockHeader()).globalVariables.blockNumber;
|
|
137
|
+
return this.getNullifierMembershipWitness(blockNumber, nullifier);
|
|
144
138
|
}
|
|
145
139
|
getNullifierMembershipWitness(blockNumber, nullifier) {
|
|
146
140
|
return this.aztecNode.getNullifierMembershipWitness(blockNumber, nullifier);
|
|
147
141
|
}
|
|
148
|
-
getLowNullifierMembershipWitness(blockNumber, nullifier) {
|
|
142
|
+
async getLowNullifierMembershipWitness(blockNumber, nullifier) {
|
|
143
|
+
const header = await this.getAnchorBlockHeader();
|
|
144
|
+
if (blockNumber !== 'latest' && blockNumber > header.globalVariables.blockNumber) {
|
|
145
|
+
throw new Error(`Block number ${blockNumber} is higher than current block ${header.globalVariables.blockNumber}`);
|
|
146
|
+
}
|
|
149
147
|
return this.aztecNode.getLowNullifierMembershipWitness(blockNumber, nullifier);
|
|
150
148
|
}
|
|
151
149
|
async getBlock(blockNumber) {
|
|
150
|
+
const header = await this.getAnchorBlockHeader();
|
|
151
|
+
if (blockNumber !== 'latest' && blockNumber > header.globalVariables.blockNumber) {
|
|
152
|
+
throw new Error(`Block number ${blockNumber} is higher than current block ${header.globalVariables.blockNumber}`);
|
|
153
|
+
}
|
|
152
154
|
return await this.aztecNode.getBlock(blockNumber);
|
|
153
155
|
}
|
|
154
156
|
async getPublicDataWitness(blockNumber, leafSlot) {
|
|
157
|
+
const header = await this.getAnchorBlockHeader();
|
|
158
|
+
if (blockNumber !== 'latest' && blockNumber > header.globalVariables.blockNumber) {
|
|
159
|
+
throw new Error(`Block number ${blockNumber} is higher than current block ${header.globalVariables.blockNumber}`);
|
|
160
|
+
}
|
|
155
161
|
return await this.aztecNode.getPublicDataWitness(blockNumber, leafSlot);
|
|
156
162
|
}
|
|
157
163
|
async getPublicStorageAt(blockNumber, contract, slot) {
|
|
164
|
+
const header = await this.getAnchorBlockHeader();
|
|
165
|
+
if (blockNumber !== 'latest' && blockNumber > header.globalVariables.blockNumber) {
|
|
166
|
+
throw new Error(`Block number ${blockNumber} is higher than current block ${header.globalVariables.blockNumber}`);
|
|
167
|
+
}
|
|
158
168
|
return await this.aztecNode.getPublicStorageAt(blockNumber, contract, slot);
|
|
159
169
|
}
|
|
160
|
-
|
|
161
|
-
* Retrieve the latest block header synchronized by the PXE.
|
|
162
|
-
* @dev This structure is fed into the circuits simulator and is used to prove against certain historical roots.
|
|
163
|
-
* @returns The BlockHeader object.
|
|
164
|
-
* TODO: I think this naming is bad as it's not the latest block header synched by the node, but the latest block
|
|
165
|
-
* header synchronized by the PXE. Would rename this to something like getSynchronizedBlockHeader().
|
|
166
|
-
*/ getBlockHeader() {
|
|
170
|
+
getAnchorBlockHeader() {
|
|
167
171
|
return this.syncDataProvider.getBlockHeader();
|
|
168
172
|
}
|
|
169
173
|
assertCompatibleOracleVersion(version) {
|
|
@@ -171,34 +175,6 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
171
175
|
throw new Error(`Incompatible oracle version. Expected version ${ORACLE_VERSION}, got ${version}.`);
|
|
172
176
|
}
|
|
173
177
|
}
|
|
174
|
-
/**
|
|
175
|
-
* Fetches the latest block number synchronized by the node.
|
|
176
|
-
* @returns The block number.
|
|
177
|
-
*/ async getBlockNumber() {
|
|
178
|
-
return await this.aztecNode.getBlockNumber();
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Fetches the timestamp of the latest block synchronized by the node.
|
|
182
|
-
* @returns The timestamp.
|
|
183
|
-
*/ async getTimestamp() {
|
|
184
|
-
const latestBlockHeader = await this.aztecNode.getBlockHeader();
|
|
185
|
-
if (!latestBlockHeader) {
|
|
186
|
-
throw new Error('Latest block header not found when getting timestamp');
|
|
187
|
-
}
|
|
188
|
-
return latestBlockHeader.globalVariables.timestamp;
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Fetches the current chain id.
|
|
192
|
-
* @returns The chain id.
|
|
193
|
-
*/ async getChainId() {
|
|
194
|
-
return await this.aztecNode.getChainId();
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Fetches the current version.
|
|
198
|
-
* @returns The version.
|
|
199
|
-
*/ async getVersion() {
|
|
200
|
-
return await this.aztecNode.getVersion();
|
|
201
|
-
}
|
|
202
178
|
getDebugFunctionName(contractAddress, selector) {
|
|
203
179
|
return this.contractDataProvider.getDebugFunctionName(contractAddress, selector);
|
|
204
180
|
}
|
|
@@ -210,57 +186,27 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
210
186
|
*/ getSenders() {
|
|
211
187
|
return this.taggingDataProvider.getSenderAddresses();
|
|
212
188
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
* Includes the next index to be used used for tagging with this secret.
|
|
216
|
-
* @param contractAddress - The contract address to silo the secret for
|
|
217
|
-
* @param sender - The address sending the note
|
|
218
|
-
* @param recipient - The address receiving the note
|
|
219
|
-
* @returns An indexed tagging secret that can be used to tag notes.
|
|
220
|
-
*/ async getIndexedTaggingSecretAsSender(contractAddress, sender, recipient) {
|
|
221
|
-
await this.syncTaggedLogsAsSender(contractAddress, sender, recipient);
|
|
222
|
-
const appTaggingSecret = await this.#calculateAppTaggingSecret(contractAddress, sender, recipient);
|
|
223
|
-
const [index] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([
|
|
224
|
-
appTaggingSecret
|
|
225
|
-
], sender);
|
|
226
|
-
return new IndexedTaggingSecret(appTaggingSecret, index);
|
|
189
|
+
getLastUsedIndexAsSender(secret) {
|
|
190
|
+
return this.taggingDataProvider.getLastUsedIndexesAsSender(secret);
|
|
227
191
|
}
|
|
228
|
-
|
|
229
|
-
* Increments the tagging secret for a given sender and recipient pair. For this to work, the ivsk_m of the sender must be known.
|
|
230
|
-
* @param contractAddress - The contract address to silo the secret for
|
|
231
|
-
* @param sender - The address sending the note
|
|
232
|
-
* @param recipient - The address receiving the note
|
|
233
|
-
*/ async incrementAppTaggingSecretIndexAsSender(contractAddress, sender, recipient) {
|
|
234
|
-
const secret = await this.#calculateAppTaggingSecret(contractAddress, sender, recipient);
|
|
235
|
-
const contractName = await this.contractDataProvider.getDebugContractName(contractAddress);
|
|
236
|
-
this.log.debug(`Incrementing app tagging secret at ${contractName}(${contractAddress})`, {
|
|
237
|
-
secret,
|
|
238
|
-
sender,
|
|
239
|
-
recipient,
|
|
240
|
-
contractName,
|
|
241
|
-
contractAddress
|
|
242
|
-
});
|
|
243
|
-
const [index] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([
|
|
244
|
-
secret
|
|
245
|
-
], sender);
|
|
246
|
-
await this.taggingDataProvider.setTaggingSecretsIndexesAsSender([
|
|
247
|
-
new IndexedTaggingSecret(secret, index + 1)
|
|
248
|
-
], sender);
|
|
249
|
-
}
|
|
250
|
-
async #calculateAppTaggingSecret(contractAddress, sender, recipient) {
|
|
192
|
+
async calculateDirectionalAppTaggingSecret(contractAddress, sender, recipient) {
|
|
251
193
|
const senderCompleteAddress = await this.getCompleteAddress(sender);
|
|
252
194
|
const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
|
|
253
|
-
return
|
|
195
|
+
return DirectionalAppTaggingSecret.compute(senderCompleteAddress, senderIvsk, recipient, contractAddress, recipient);
|
|
254
196
|
}
|
|
255
197
|
/**
|
|
256
|
-
* Returns the
|
|
198
|
+
* Returns the last used tagging indexes along with the directional app tagging secrets for a given recipient and all
|
|
199
|
+
* the senders in the address book.
|
|
257
200
|
* This method should be exposed as an oracle call to allow aztec.nr to perform the orchestration
|
|
258
201
|
* of the syncTaggedLogs and processTaggedLogs methods. However, it is not possible to do so at the moment,
|
|
259
202
|
* so we're keeping it private for now.
|
|
260
203
|
* @param contractAddress - The contract address to silo the secret for
|
|
261
204
|
* @param recipient - The address receiving the notes
|
|
262
|
-
* @returns A list of
|
|
263
|
-
|
|
205
|
+
* @returns A list of directional app tagging secrets along with the last used tagging indexes. If the corresponding
|
|
206
|
+
* secret was never used, the index is undefined.
|
|
207
|
+
* TODO(benesjan): The naming here is broken as the function name does not reflect the return type. Fix when associating
|
|
208
|
+
* indexes with tx hash.
|
|
209
|
+
*/ async #getLastUsedTaggingIndexesForSenders(contractAddress, recipient) {
|
|
264
210
|
const recipientCompleteAddress = await this.getCompleteAddress(recipient);
|
|
265
211
|
const recipientIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(recipient);
|
|
266
212
|
// We implicitly add all PXE accounts as senders, this helps us decrypt tags on notes that we send to ourselves
|
|
@@ -269,21 +215,23 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
269
215
|
...await this.taggingDataProvider.getSenderAddresses(),
|
|
270
216
|
...await this.keyStore.getAccounts()
|
|
271
217
|
].filter((address, index, self)=>index === self.findIndex((otherAddress)=>otherAddress.equals(address)));
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
218
|
+
const secrets = await Promise.all(senders.map((contact)=>{
|
|
219
|
+
return DirectionalAppTaggingSecret.compute(recipientCompleteAddress, recipientIvsk, contact, contractAddress, recipient);
|
|
220
|
+
}));
|
|
221
|
+
const indexes = await this.taggingDataProvider.getLastUsedIndexesAsRecipient(secrets);
|
|
222
|
+
if (indexes.length !== secrets.length) {
|
|
223
|
+
throw new Error('Indexes and directional app tagging secrets have different lengths');
|
|
224
|
+
}
|
|
225
|
+
return secrets.map((secret, i)=>({
|
|
226
|
+
secret,
|
|
227
|
+
index: indexes[i]
|
|
228
|
+
}));
|
|
275
229
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
* @param recipient - The address of the recipient.
|
|
282
|
-
*/ async syncTaggedLogsAsSender(contractAddress, sender, recipient) {
|
|
283
|
-
const appTaggingSecret = await this.#calculateAppTaggingSecret(contractAddress, sender, recipient);
|
|
284
|
-
const [oldIndex] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([
|
|
285
|
-
appTaggingSecret
|
|
286
|
-
], sender);
|
|
230
|
+
async syncTaggedLogsAsSender(secret, contractAddress) {
|
|
231
|
+
const lastUsedIndex = await this.taggingDataProvider.getLastUsedIndexesAsSender(secret);
|
|
232
|
+
// If lastUsedIndex is undefined, we've never used this secret, so start from 0
|
|
233
|
+
// Otherwise, start from one past the last used index
|
|
234
|
+
const startIndex = lastUsedIndex === undefined ? 0 : lastUsedIndex + 1;
|
|
287
235
|
// This algorithm works such that:
|
|
288
236
|
// 1. If we find minimum consecutive empty logs in a window of logs we set the index to the index of the last log
|
|
289
237
|
// we found and quit.
|
|
@@ -293,40 +241,50 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
293
241
|
const WINDOW_SIZE = MIN_CONSECUTIVE_EMPTY_LOGS * 2;
|
|
294
242
|
let [numConsecutiveEmptyLogs, currentIndex] = [
|
|
295
243
|
0,
|
|
296
|
-
|
|
244
|
+
startIndex
|
|
297
245
|
];
|
|
246
|
+
let lastFoundLogIndex = undefined;
|
|
298
247
|
do {
|
|
299
248
|
// We compute the tags for the current window of indexes
|
|
300
|
-
const currentTags = await timesParallel(WINDOW_SIZE, (i)=>{
|
|
301
|
-
|
|
302
|
-
|
|
249
|
+
const currentTags = await timesParallel(WINDOW_SIZE, async (i)=>{
|
|
250
|
+
return SiloedTag.compute(await Tag.compute({
|
|
251
|
+
secret,
|
|
252
|
+
index: currentIndex + i
|
|
253
|
+
}), contractAddress);
|
|
303
254
|
});
|
|
304
255
|
// We fetch the logs for the tags
|
|
305
|
-
|
|
256
|
+
// TODO: The following conversion is unfortunate and we should most likely just type the #getPrivateLogsByTags
|
|
257
|
+
// to accept SiloedTag[] instead of Fr[]. That would result in a large change so I didn't do it yet.
|
|
258
|
+
const tagsAsFr = currentTags.map((tag)=>tag.value);
|
|
259
|
+
const possibleLogs = await this.#getPrivateLogsByTags(tagsAsFr);
|
|
306
260
|
// We find the index of the last log in the window that is not empty
|
|
307
|
-
const
|
|
308
|
-
if (
|
|
261
|
+
const indexOfLastLogWithinArray = possibleLogs.findLastIndex((possibleLog)=>possibleLog.length !== 0);
|
|
262
|
+
if (indexOfLastLogWithinArray === -1) {
|
|
309
263
|
break;
|
|
310
264
|
}
|
|
311
|
-
// We
|
|
312
|
-
|
|
265
|
+
// We've found logs so we update the last found log index
|
|
266
|
+
lastFoundLogIndex = (lastFoundLogIndex ?? 0) + indexOfLastLogWithinArray;
|
|
267
|
+
// We move the current index to that of the log right after the last found log
|
|
268
|
+
currentIndex = lastFoundLogIndex + 1;
|
|
313
269
|
// We compute the number of consecutive empty logs we found and repeat the process if we haven't found enough.
|
|
314
|
-
numConsecutiveEmptyLogs = WINDOW_SIZE -
|
|
270
|
+
numConsecutiveEmptyLogs = WINDOW_SIZE - indexOfLastLogWithinArray - 1;
|
|
315
271
|
}while (numConsecutiveEmptyLogs < MIN_CONSECUTIVE_EMPTY_LOGS)
|
|
316
272
|
const contractName = await this.contractDataProvider.getDebugContractName(contractAddress);
|
|
317
|
-
if (
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
273
|
+
if (lastFoundLogIndex !== undefined) {
|
|
274
|
+
// Last found index is defined meaning we have actually found logs so we update the last used index
|
|
275
|
+
await this.taggingDataProvider.setLastUsedIndexesAsSender([
|
|
276
|
+
{
|
|
277
|
+
secret,
|
|
278
|
+
index: lastFoundLogIndex
|
|
279
|
+
}
|
|
280
|
+
]);
|
|
281
|
+
this.log.debug(`Syncing logs for secret ${secret.toString()} at contract ${contractName}(${contractAddress})`, {
|
|
324
282
|
index: currentIndex,
|
|
325
283
|
contractName,
|
|
326
284
|
contractAddress
|
|
327
285
|
});
|
|
328
286
|
} else {
|
|
329
|
-
this.log.debug(`No new logs found for
|
|
287
|
+
this.log.debug(`No new logs found for secret ${secret.toString()} at contract ${contractName}(${contractAddress})`);
|
|
330
288
|
}
|
|
331
289
|
}
|
|
332
290
|
/**
|
|
@@ -351,7 +309,7 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
351
309
|
const contractName = await this.contractDataProvider.getDebugContractName(contractAddress);
|
|
352
310
|
for (const recipient of recipients){
|
|
353
311
|
// Get all the secrets for the recipient and sender pairs (#9365)
|
|
354
|
-
const
|
|
312
|
+
const indexedSecrets = await this.#getLastUsedTaggingIndexesForSenders(contractAddress, recipient);
|
|
355
313
|
// We fetch logs for a window of indexes in a range:
|
|
356
314
|
// <latest_log_index - WINDOW_HALF_SIZE, latest_log_index + WINDOW_HALF_SIZE>.
|
|
357
315
|
//
|
|
@@ -360,25 +318,39 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
360
318
|
// for logs the first time we don't receive any logs for a tag, we might never receive anything from that sender again.
|
|
361
319
|
// Also there's a possibility that we have advanced our index, but the sender has reused it, so we might have missed
|
|
362
320
|
// some logs. For these reasons, we have to look both back and ahead of the stored index.
|
|
363
|
-
let secretsAndWindows =
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
321
|
+
let secretsAndWindows = indexedSecrets.map((indexedSecret)=>{
|
|
322
|
+
if (indexedSecret.index === undefined) {
|
|
323
|
+
return {
|
|
324
|
+
secret: indexedSecret.secret,
|
|
325
|
+
leftMostIndex: 0,
|
|
326
|
+
rightMostIndex: WINDOW_HALF_SIZE
|
|
327
|
+
};
|
|
328
|
+
} else {
|
|
329
|
+
return {
|
|
330
|
+
secret: indexedSecret.secret,
|
|
331
|
+
leftMostIndex: Math.max(0, indexedSecret.index - WINDOW_HALF_SIZE),
|
|
332
|
+
rightMostIndex: indexedSecret.index + WINDOW_HALF_SIZE
|
|
333
|
+
};
|
|
334
|
+
}
|
|
369
335
|
});
|
|
370
336
|
// As we iterate we store the largest index we have seen for a given secret to later on store it in the db.
|
|
371
337
|
const newLargestIndexMapToStore = {};
|
|
372
|
-
// The initial/unmodified indexes of the secrets stored in a key-value map where key is the app
|
|
373
|
-
|
|
338
|
+
// The initial/unmodified indexes of the secrets stored in a key-value map where key is the directional app
|
|
339
|
+
// tagging secret.
|
|
340
|
+
const initialIndexesMap = getInitialIndexesMap(indexedSecrets);
|
|
374
341
|
while(secretsAndWindows.length > 0){
|
|
375
|
-
const
|
|
376
|
-
const tagsForTheWholeWindow = await Promise.all(
|
|
342
|
+
const preTagsForTheWholeWindow = getPreTagsForTheWindow(secretsAndWindows);
|
|
343
|
+
const tagsForTheWholeWindow = await Promise.all(preTagsForTheWholeWindow.map(async (preTag)=>{
|
|
344
|
+
return SiloedTag.compute(await Tag.compute(preTag), contractAddress);
|
|
345
|
+
}));
|
|
377
346
|
// We store the new largest indexes we find in the iteration in the following map to later on construct
|
|
378
347
|
// a new set of secrets and windows to fetch logs for.
|
|
379
348
|
const newLargestIndexMapForIteration = {};
|
|
380
349
|
// Fetch the private logs for the tags and iterate over them
|
|
381
|
-
|
|
350
|
+
// TODO: The following conversion is unfortunate and we should most likely just type the #getPrivateLogsByTags
|
|
351
|
+
// to accept SiloedTag[] instead of Fr[]. That would result in a large change so I didn't do it yet.
|
|
352
|
+
const tagsForTheWholeWindowAsFr = tagsForTheWholeWindow.map((tag)=>tag.value);
|
|
353
|
+
const logsByTags = await this.#getPrivateLogsByTags(tagsForTheWholeWindowAsFr);
|
|
382
354
|
this.log.debug(`Found ${logsByTags.filter((logs)=>logs.length > 0).length} logs as recipient ${recipient}`, {
|
|
383
355
|
recipient,
|
|
384
356
|
contractName,
|
|
@@ -387,19 +359,19 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
387
359
|
for(let logIndex = 0; logIndex < logsByTags.length; logIndex++){
|
|
388
360
|
const logsByTag = logsByTags[logIndex];
|
|
389
361
|
if (logsByTag.length > 0) {
|
|
390
|
-
// We filter out the logs that are newer than the
|
|
362
|
+
// We filter out the logs that are newer than the anchor block number of the tx currently being constructed
|
|
391
363
|
const filteredLogsByBlockNumber = logsByTag.filter((l)=>l.blockNumber <= maxBlockNumber);
|
|
392
364
|
// We store the logs in capsules (to later be obtained in Noir)
|
|
393
365
|
await this.#storePendingTaggedLogs(contractAddress, pendingTaggedLogArrayBaseSlot, recipient, filteredLogsByBlockNumber);
|
|
394
|
-
// We retrieve the
|
|
366
|
+
// We retrieve the pre tag corresponding to the log as I need that to evaluate whether
|
|
395
367
|
// a new largest index have been found.
|
|
396
|
-
const
|
|
397
|
-
const initialIndex = initialIndexesMap[
|
|
398
|
-
if (
|
|
368
|
+
const preTagCorrespondingToLog = preTagsForTheWholeWindow[logIndex];
|
|
369
|
+
const initialIndex = initialIndexesMap[preTagCorrespondingToLog.secret.toString()];
|
|
370
|
+
if (preTagCorrespondingToLog.index >= initialIndex && (newLargestIndexMapForIteration[preTagCorrespondingToLog.secret.toString()] === undefined || preTagCorrespondingToLog.index >= newLargestIndexMapForIteration[preTagCorrespondingToLog.secret.toString()])) {
|
|
399
371
|
// We have found a new largest index so we store it for later processing (storing it in the db + fetching
|
|
400
372
|
// the difference of the window sets of current and the next iteration)
|
|
401
|
-
newLargestIndexMapForIteration[
|
|
402
|
-
this.log.debug(`Incrementing index to ${
|
|
373
|
+
newLargestIndexMapForIteration[preTagCorrespondingToLog.secret.toString()] = preTagCorrespondingToLog.index + 1;
|
|
374
|
+
this.log.debug(`Incrementing index to ${preTagCorrespondingToLog.index + 1} at contract ${contractName}(${contractAddress})`);
|
|
403
375
|
}
|
|
404
376
|
}
|
|
405
377
|
}
|
|
@@ -407,26 +379,31 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
407
379
|
// for. Note that it's very unlikely that a new log from the current window would appear between the iterations
|
|
408
380
|
// so we fetch the logs only for the difference of the window sets.
|
|
409
381
|
const newSecretsAndWindows = [];
|
|
410
|
-
for (const [
|
|
411
|
-
const
|
|
412
|
-
if (
|
|
382
|
+
for (const [directionalAppTaggingSecret, newIndex] of Object.entries(newLargestIndexMapForIteration)){
|
|
383
|
+
const maybeIndexedSecret = indexedSecrets.find((indexedSecret)=>indexedSecret.secret.toString() === directionalAppTaggingSecret);
|
|
384
|
+
if (maybeIndexedSecret) {
|
|
413
385
|
newSecretsAndWindows.push({
|
|
414
|
-
|
|
386
|
+
secret: maybeIndexedSecret.secret,
|
|
415
387
|
// We set the left most index to the new index to avoid fetching the same logs again
|
|
416
388
|
leftMostIndex: newIndex,
|
|
417
389
|
rightMostIndex: newIndex + WINDOW_HALF_SIZE
|
|
418
390
|
});
|
|
419
391
|
// We store the new largest index in the map to later store it in the db.
|
|
420
|
-
newLargestIndexMapToStore[
|
|
392
|
+
newLargestIndexMapToStore[directionalAppTaggingSecret] = newIndex;
|
|
421
393
|
} else {
|
|
422
|
-
throw new Error(`Secret not found for
|
|
394
|
+
throw new Error(`Secret not found for directionalAppTaggingSecret ${directionalAppTaggingSecret}. This is a bug as it should never happen!`);
|
|
423
395
|
}
|
|
424
396
|
}
|
|
425
397
|
// Now we set the new secrets and windows and proceed to the next iteration.
|
|
426
398
|
secretsAndWindows = newSecretsAndWindows;
|
|
427
399
|
}
|
|
428
|
-
// At this point we have processed all the logs for the recipient so we store the
|
|
429
|
-
|
|
400
|
+
// At this point we have processed all the logs for the recipient so we store the last used indexes in the db.
|
|
401
|
+
// newLargestIndexMapToStore contains "next" indexes to look for (one past the last found), so subtract 1 to get
|
|
402
|
+
// last used.
|
|
403
|
+
await this.taggingDataProvider.setLastUsedIndexesAsRecipient(Object.entries(newLargestIndexMapToStore).map(([directionalAppTaggingSecret, index])=>({
|
|
404
|
+
secret: DirectionalAppTaggingSecret.fromString(directionalAppTaggingSecret),
|
|
405
|
+
index: index - 1
|
|
406
|
+
})));
|
|
430
407
|
}
|
|
431
408
|
}
|
|
432
409
|
async #storePendingTaggedLogs(contractAddress, capsuleArrayBaseSlot, recipient, privateLogs) {
|
|
@@ -447,7 +424,7 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
447
424
|
// faster as we don't need to wait for the network round-trip.
|
|
448
425
|
const noteValidationRequests = (await this.capsuleDataProvider.readCapsuleArray(contractAddress, noteValidationRequestsArrayBaseSlot)).map(NoteValidationRequest.fromFields);
|
|
449
426
|
const eventValidationRequests = (await this.capsuleDataProvider.readCapsuleArray(contractAddress, eventValidationRequestsArrayBaseSlot)).map(EventValidationRequest.fromFields);
|
|
450
|
-
const noteDeliveries = noteValidationRequests.map((request)=>this.deliverNote(request.contractAddress, request.storageSlot, request.noteNonce, request.content, request.noteHash, request.nullifier, request.txHash, request.recipient));
|
|
427
|
+
const noteDeliveries = noteValidationRequests.map((request)=>this.deliverNote(request.contractAddress, request.owner, request.storageSlot, request.randomness, request.noteNonce, request.content, request.noteHash, request.nullifier, request.txHash, request.recipient));
|
|
451
428
|
const eventDeliveries = eventValidationRequests.map((request)=>this.deliverEvent(request.contractAddress, request.eventTypeId, request.serializedEvent, request.eventCommitment, request.txHash, request.recipient));
|
|
452
429
|
await Promise.all([
|
|
453
430
|
...noteDeliveries,
|
|
@@ -457,7 +434,7 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
457
434
|
await this.capsuleDataProvider.setCapsuleArray(contractAddress, noteValidationRequestsArrayBaseSlot, []);
|
|
458
435
|
await this.capsuleDataProvider.setCapsuleArray(contractAddress, eventValidationRequestsArrayBaseSlot, []);
|
|
459
436
|
}
|
|
460
|
-
async deliverNote(contractAddress, storageSlot, noteNonce, content, noteHash, nullifier, txHash, recipient) {
|
|
437
|
+
async deliverNote(contractAddress, owner, storageSlot, randomness, noteNonce, content, noteHash, nullifier, txHash, recipient) {
|
|
461
438
|
// We are going to store the new note in the NoteDataProvider, which will let us later return it via `getNotes`.
|
|
462
439
|
// There's two things we need to check before we do this however:
|
|
463
440
|
// - we must make sure the note does actually exist in the note hash tree
|
|
@@ -481,6 +458,17 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
481
458
|
// of other contracts, which would constitute a security breach.
|
|
482
459
|
const uniqueNoteHash = await computeUniqueNoteHash(noteNonce, await siloNoteHash(contractAddress, noteHash));
|
|
483
460
|
const siloedNullifier = await siloNullifier(contractAddress, nullifier);
|
|
461
|
+
const txEffect = await this.aztecNode.getTxEffect(txHash);
|
|
462
|
+
if (!txEffect) {
|
|
463
|
+
throw new Error(`Could not find tx effect for tx hash ${txHash}`);
|
|
464
|
+
}
|
|
465
|
+
if (txEffect.l2BlockNumber > syncedBlockNumber) {
|
|
466
|
+
throw new Error(`Could not find tx effect for tx hash ${txHash} as of block number ${syncedBlockNumber}`);
|
|
467
|
+
}
|
|
468
|
+
const noteInTx = txEffect.data.noteHashes.some((nh)=>nh.equals(uniqueNoteHash));
|
|
469
|
+
if (!noteInTx) {
|
|
470
|
+
throw new Error(`Note hash ${noteHash} (uniqued as ${uniqueNoteHash}) is not present in tx ${txHash}`);
|
|
471
|
+
}
|
|
484
472
|
// We store notes by their index in the global note hash tree, which has the convenient side effect of validating
|
|
485
473
|
// note existence in said tree. We concurrently also check if the note's nullifier exists, performing all node
|
|
486
474
|
// queries in a single round-trip.
|
|
@@ -495,7 +483,8 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
495
483
|
if (uniqueNoteHashTreeIndexInBlock === undefined) {
|
|
496
484
|
throw new Error(`Note hash ${noteHash} (uniqued as ${uniqueNoteHash}) is not present on the tree at block ${syncedBlockNumber} (from tx ${txHash})`);
|
|
497
485
|
}
|
|
498
|
-
const noteDao = new NoteDao(new Note(content), contractAddress, storageSlot, noteNonce, noteHash, siloedNullifier, txHash, uniqueNoteHashTreeIndexInBlock
|
|
486
|
+
const noteDao = new NoteDao(new Note(content), contractAddress, owner, storageSlot, randomness, noteNonce, noteHash, siloedNullifier, txHash, uniqueNoteHashTreeIndexInBlock.l2BlockNumber, uniqueNoteHashTreeIndexInBlock.l2BlockHash.toString(), uniqueNoteHashTreeIndexInBlock.data);
|
|
487
|
+
// The note was found by `recipient`, so we use that as the scope when storing the note.
|
|
499
488
|
await this.noteDataProvider.addNotes([
|
|
500
489
|
noteDao
|
|
501
490
|
], recipient);
|
|
@@ -508,12 +497,12 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
508
497
|
});
|
|
509
498
|
if (nullifierIndex !== undefined) {
|
|
510
499
|
const { data: _, ...blockHashAndNum } = nullifierIndex;
|
|
511
|
-
await this.noteDataProvider.
|
|
500
|
+
await this.noteDataProvider.applyNullifiers([
|
|
512
501
|
{
|
|
513
502
|
data: siloedNullifier,
|
|
514
503
|
...blockHashAndNum
|
|
515
504
|
}
|
|
516
|
-
]
|
|
505
|
+
]);
|
|
517
506
|
this.log.verbose(`Removed just-added note`, {
|
|
518
507
|
contract: contractAddress,
|
|
519
508
|
slot: storageSlot,
|
|
@@ -540,7 +529,7 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
540
529
|
} else if (privateLog !== null) {
|
|
541
530
|
return new LogRetrievalResponse(privateLog.logPayload, privateLog.txHash, privateLog.uniqueNoteHashesInTx, privateLog.firstNullifierInTx);
|
|
542
531
|
} else {
|
|
543
|
-
null;
|
|
532
|
+
return null;
|
|
544
533
|
}
|
|
545
534
|
}));
|
|
546
535
|
// Requests are cleared once we're done.
|
|
@@ -548,20 +537,39 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
548
537
|
// The responses are stored as Option<LogRetrievalResponse> in a second CapsuleArray.
|
|
549
538
|
await this.capsuleDataProvider.setCapsuleArray(contractAddress, logRetrievalResponsesArrayBaseSlot, maybeLogRetrievalResponses.map(LogRetrievalResponse.toSerializedOption));
|
|
550
539
|
}
|
|
551
|
-
async deliverEvent(contractAddress, selector, content, eventCommitment, txHash,
|
|
540
|
+
async deliverEvent(contractAddress, selector, content, eventCommitment, txHash, scope) {
|
|
552
541
|
// While using 'latest' block number would be fine for private events since they cannot be accessed from Aztec.nr
|
|
553
542
|
// (and thus we're less concerned about being ahead of the synced block), we use the synced block number to
|
|
554
543
|
// maintain consistent behavior in the PXE. Additionally, events should never be ahead of the synced block here
|
|
555
544
|
// since `fetchTaggedLogs` only processes logs up to the synced block.
|
|
556
|
-
const syncedBlockNumber = await
|
|
557
|
-
|
|
545
|
+
const [syncedBlockNumber, siloedEventCommitment, txEffect] = await Promise.all([
|
|
546
|
+
this.syncDataProvider.getBlockNumber(),
|
|
547
|
+
siloNullifier(contractAddress, eventCommitment),
|
|
548
|
+
this.aztecNode.getTxEffect(txHash)
|
|
549
|
+
]);
|
|
550
|
+
if (!txEffect) {
|
|
551
|
+
throw new Error(`Could not find tx effect for tx hash ${txHash}`);
|
|
552
|
+
}
|
|
553
|
+
if (txEffect.l2BlockNumber > syncedBlockNumber) {
|
|
554
|
+
throw new Error(`Could not find tx effect for tx hash ${txHash} as of block number ${syncedBlockNumber}`);
|
|
555
|
+
}
|
|
556
|
+
const eventInTx = txEffect.data.nullifiers.some((n)=>n.equals(siloedEventCommitment));
|
|
557
|
+
if (!eventInTx) {
|
|
558
|
+
throw new Error(`Event commitment ${eventCommitment} (siloed as ${siloedEventCommitment}) is not present in tx ${txHash}`);
|
|
559
|
+
}
|
|
558
560
|
const [nullifierIndex] = await this.aztecNode.findLeavesIndexes(syncedBlockNumber, MerkleTreeId.NULLIFIER_TREE, [
|
|
559
561
|
siloedEventCommitment
|
|
560
562
|
]);
|
|
561
563
|
if (nullifierIndex === undefined) {
|
|
562
564
|
throw new Error(`Event commitment ${eventCommitment} (siloed as ${siloedEventCommitment}) is not present on the nullifier tree at block ${syncedBlockNumber} (from tx ${txHash})`);
|
|
563
565
|
}
|
|
564
|
-
return this.privateEventDataProvider.storePrivateEventLog(
|
|
566
|
+
return this.privateEventDataProvider.storePrivateEventLog(selector, content, Number(nullifierIndex.data), {
|
|
567
|
+
contractAddress,
|
|
568
|
+
scope,
|
|
569
|
+
txHash,
|
|
570
|
+
l2BlockNumber: nullifierIndex.l2BlockNumber,
|
|
571
|
+
l2BlockHash: nullifierIndex.l2BlockHash
|
|
572
|
+
});
|
|
565
573
|
}
|
|
566
574
|
// TODO(#14555): delete this function and implement this behavior in the node instead
|
|
567
575
|
async getPublicLogByTag(tag, contractAddress) {
|
|
@@ -609,56 +617,60 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
609
617
|
}
|
|
610
618
|
return new PrivateLogWithTxData(scopedLog.log.getEmittedFieldsWithoutTag(), scopedLog.txHash, txEffect.data.noteHashes, txEffect.data.nullifiers[0]);
|
|
611
619
|
}
|
|
612
|
-
|
|
620
|
+
/**
|
|
621
|
+
* Looks for nullifiers of active contract notes and marks them as nullified if a nullifier is found.
|
|
622
|
+
*
|
|
623
|
+
* Fetches notes from the NoteDataProvider and checks which nullifiers are present in the
|
|
624
|
+
* onchain nullifier Merkle tree - up to the latest locally synced block. We use the
|
|
625
|
+
* locally synced block instead of querying the chain's 'latest' block to ensure correctness:
|
|
626
|
+
* notes are only marked nullified once their corresponding nullifier has been included in a
|
|
627
|
+
* block up to which the PXE has synced.
|
|
628
|
+
* This allows recent nullifications to be processed even if the node is not an archive node.
|
|
629
|
+
*
|
|
630
|
+
* @param contractAddress - The contract whose notes should be checked and nullified.
|
|
631
|
+
*/ async syncNoteNullifiers(contractAddress) {
|
|
613
632
|
this.log.verbose('Searching for nullifiers of known notes', {
|
|
614
633
|
contract: contractAddress
|
|
615
634
|
});
|
|
616
|
-
// We avoid making node queries at 'latest' since we mark notes as nullified only if the corresponding nullifier
|
|
617
|
-
// has been included in a block up to which PXE has synced. Note that while this technically results in historical
|
|
618
|
-
// queries, we perform it at the latest locally synced block number which *should* be recent enough to be
|
|
619
|
-
// available, even for non-archive nodes.
|
|
620
635
|
const syncedBlockNumber = await this.syncDataProvider.getBlockNumber();
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
636
|
+
const contractNotes = await this.noteDataProvider.getNotes({
|
|
637
|
+
contractAddress
|
|
638
|
+
});
|
|
639
|
+
if (contractNotes.length === 0) {
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
const nullifiersToCheck = contractNotes.map((note)=>note.siloedNullifier);
|
|
643
|
+
const nullifierBatches = nullifiersToCheck.reduce((acc, nullifier)=>{
|
|
644
|
+
if (acc[acc.length - 1].length < MAX_RPC_LEN) {
|
|
645
|
+
acc[acc.length - 1].push(nullifier);
|
|
646
|
+
} else {
|
|
647
|
+
acc.push([
|
|
648
|
+
nullifier
|
|
649
|
+
]);
|
|
628
650
|
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
};
|
|
651
|
-
}
|
|
652
|
-
}).filter((nullifier)=>nullifier !== undefined);
|
|
653
|
-
const nullifiedNotes = await this.noteDataProvider.removeNullifiedNotes(foundNullifiers, recipient);
|
|
654
|
-
nullifiedNotes.forEach((noteDao)=>{
|
|
655
|
-
this.log.verbose(`Removed note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot}`, {
|
|
656
|
-
contract: noteDao.contractAddress,
|
|
657
|
-
slot: noteDao.storageSlot,
|
|
658
|
-
nullifier: noteDao.siloedNullifier.toString()
|
|
659
|
-
});
|
|
651
|
+
return acc;
|
|
652
|
+
}, [
|
|
653
|
+
[]
|
|
654
|
+
]);
|
|
655
|
+
const nullifierIndexes = (await Promise.all(nullifierBatches.map((batch)=>this.aztecNode.findLeavesIndexes(syncedBlockNumber, MerkleTreeId.NULLIFIER_TREE, batch)))).flat();
|
|
656
|
+
const foundNullifiers = nullifiersToCheck.map((nullifier, i)=>{
|
|
657
|
+
if (nullifierIndexes[i] !== undefined) {
|
|
658
|
+
return {
|
|
659
|
+
...nullifierIndexes[i],
|
|
660
|
+
...{
|
|
661
|
+
data: nullifier
|
|
662
|
+
}
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
}).filter((nullifier)=>nullifier !== undefined);
|
|
666
|
+
const nullifiedNotes = await this.noteDataProvider.applyNullifiers(foundNullifiers);
|
|
667
|
+
nullifiedNotes.forEach((noteDao)=>{
|
|
668
|
+
this.log.verbose(`Removed note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot}`, {
|
|
669
|
+
contract: noteDao.contractAddress,
|
|
670
|
+
slot: noteDao.storageSlot,
|
|
671
|
+
nullifier: noteDao.siloedNullifier.toString()
|
|
660
672
|
});
|
|
661
|
-
}
|
|
673
|
+
});
|
|
662
674
|
}
|
|
663
675
|
storeCapsule(contractAddress, slot, capsule) {
|
|
664
676
|
return this.capsuleDataProvider.storeCapsule(contractAddress, slot, capsule);
|