@aztec/pxe 0.0.1-commit.c7c42ec → 0.0.1-commit.f295ac2
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/block_synchronizer/block_synchronizer.d.ts +6 -2
- package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
- package/dest/block_synchronizer/block_synchronizer.js +21 -13
- package/dest/config/package_info.js +1 -1
- package/dest/contract_function_simulator/benchmarked_node.d.ts +9 -0
- package/dest/contract_function_simulator/benchmarked_node.d.ts.map +1 -0
- package/dest/contract_function_simulator/benchmarked_node.js +77 -0
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +8 -9
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +33 -16
- package/dest/contract_function_simulator/execution_note_cache.d.ts +18 -9
- package/dest/contract_function_simulator/execution_note_cache.d.ts.map +1 -1
- package/dest/contract_function_simulator/execution_note_cache.js +45 -28
- package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +3 -2
- package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/event_validation_request.js +5 -2
- package/dest/contract_function_simulator/noir-structs/utility_context.d.ts +4 -10
- package/dest/contract_function_simulator/noir-structs/utility_context.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/utility_context.js +7 -18
- package/dest/contract_function_simulator/oracle/interfaces.d.ts +9 -8
- package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts +3 -1
- package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts +4 -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 +5 -5
- package/dest/contract_function_simulator/oracle/oracle.d.ts +6 -6
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.js +20 -19
- package/dest/contract_function_simulator/oracle/private_execution.d.ts +5 -9
- package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution.js +11 -10
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +8 -18
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +10 -35
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +14 -12
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +54 -52
- 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 +10 -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 +10 -1
- package/dest/entrypoints/pxe_creation_options.d.ts +3 -2
- package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
- package/dest/entrypoints/server/index.d.ts +2 -1
- package/dest/entrypoints/server/index.d.ts.map +1 -1
- package/dest/entrypoints/server/index.js +1 -0
- package/dest/entrypoints/server/utils.d.ts +1 -1
- package/dest/entrypoints/server/utils.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.js +11 -7
- package/dest/events/event_service.d.ts +4 -3
- package/dest/events/event_service.d.ts.map +1 -1
- package/dest/events/event_service.js +17 -19
- package/dest/events/private_event_filter_validator.d.ts +5 -5
- package/dest/events/private_event_filter_validator.d.ts.map +1 -1
- package/dest/events/private_event_filter_validator.js +5 -6
- package/dest/job_coordinator/job_coordinator.d.ts +74 -0
- package/dest/job_coordinator/job_coordinator.d.ts.map +1 -0
- package/dest/job_coordinator/job_coordinator.js +93 -0
- package/dest/logs/log_service.d.ts +3 -2
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +5 -3
- package/dest/notes/note_service.d.ts +3 -3
- package/dest/notes/note_service.d.ts.map +1 -1
- package/dest/notes/note_service.js +23 -28
- package/dest/oracle_version.d.ts +2 -2
- package/dest/oracle_version.js +2 -2
- package/dest/private_kernel/hints/index.d.ts +2 -2
- package/dest/private_kernel/hints/index.d.ts.map +1 -1
- package/dest/private_kernel/hints/index.js +1 -1
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts +28 -0
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts.map +1 -0
- package/dest/private_kernel/hints/{build_private_kernel_reset_private_inputs.js → private_kernel_reset_private_inputs_builder.js} +13 -7
- package/dest/private_kernel/private_kernel_execution_prover.d.ts +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.js +4 -5
- package/dest/private_kernel/private_kernel_oracle.d.ts +24 -28
- package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_oracle.js +90 -2
- package/dest/pxe.d.ts +8 -36
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +65 -87
- package/dest/storage/capsule_store/capsule_store.d.ts +24 -9
- package/dest/storage/capsule_store/capsule_store.d.ts.map +1 -1
- package/dest/storage/capsule_store/capsule_store.js +132 -23
- package/dest/storage/contract_store/contract_store.d.ts +2 -1
- package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
- package/dest/storage/contract_store/contract_store.js +12 -0
- package/dest/storage/note_store/note_store.d.ts +6 -5
- package/dest/storage/note_store/note_store.d.ts.map +1 -1
- package/dest/storage/note_store/note_store.js +89 -94
- package/dest/storage/private_event_store/private_event_store.d.ts +33 -6
- package/dest/storage/private_event_store/private_event_store.d.ts.map +1 -1
- package/dest/storage/private_event_store/private_event_store.js +139 -32
- package/dest/storage/tagging_store/recipient_tagging_store.d.ts +15 -8
- package/dest/storage/tagging_store/recipient_tagging_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/recipient_tagging_store.js +69 -12
- package/dest/storage/tagging_store/sender_tagging_store.d.ts +19 -9
- package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/sender_tagging_store.js +110 -28
- package/dest/tagging/constants.d.ts +2 -0
- package/dest/tagging/constants.d.ts.map +1 -0
- package/dest/tagging/constants.js +10 -0
- package/dest/tagging/index.d.ts +2 -2
- package/dest/tagging/index.d.ts.map +1 -1
- package/dest/tagging/index.js +1 -10
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +2 -2
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +1 -1
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +7 -7
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +2 -2
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +8 -8
- package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts +1 -1
- package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts.map +1 -1
- package/dest/tagging/sender_sync/utils/get_status_change_of_pending.js +2 -2
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +4 -2
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -1
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.js +4 -2
- package/dest/tree_membership/tree_membership_service.d.ts +9 -11
- package/dest/tree_membership/tree_membership_service.d.ts.map +1 -1
- package/dest/tree_membership/tree_membership_service.js +25 -34
- package/package.json +18 -18
- package/src/block_synchronizer/block_synchronizer.ts +30 -12
- package/src/config/package_info.ts +1 -1
- package/src/contract_function_simulator/benchmarked_node.ts +103 -0
- package/src/contract_function_simulator/contract_function_simulator.ts +42 -16
- package/src/contract_function_simulator/execution_note_cache.ts +44 -25
- package/src/contract_function_simulator/noir-structs/event_validation_request.ts +4 -0
- package/src/contract_function_simulator/noir-structs/utility_context.ts +6 -25
- package/src/contract_function_simulator/oracle/interfaces.ts +8 -7
- package/src/contract_function_simulator/oracle/note_packing_utils.ts +6 -6
- package/src/contract_function_simulator/oracle/oracle.ts +24 -22
- package/src/contract_function_simulator/oracle/private_execution.ts +10 -19
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +13 -38
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +56 -50
- package/src/entrypoints/client/bundle/utils.ts +7 -1
- package/src/entrypoints/client/lazy/utils.ts +7 -2
- package/src/entrypoints/pxe_creation_options.ts +2 -1
- package/src/entrypoints/server/index.ts +1 -0
- package/src/entrypoints/server/utils.ts +11 -15
- package/src/events/event_service.ts +17 -21
- package/src/events/private_event_filter_validator.ts +3 -5
- package/src/job_coordinator/job_coordinator.ts +149 -0
- package/src/logs/log_service.ts +3 -1
- package/src/notes/note_service.ts +23 -29
- package/src/oracle_version.ts +2 -2
- package/src/private_kernel/hints/index.ts +1 -1
- package/src/private_kernel/hints/{build_private_kernel_reset_private_inputs.ts → private_kernel_reset_private_inputs_builder.ts} +33 -22
- package/src/private_kernel/private_kernel_execution_prover.ts +3 -5
- package/src/private_kernel/private_kernel_oracle.ts +116 -36
- package/src/pxe.ts +98 -116
- package/src/storage/capsule_store/capsule_store.ts +159 -23
- package/src/storage/contract_store/contract_store.ts +20 -0
- package/src/storage/note_store/note_store.ts +98 -95
- package/src/storage/private_event_store/private_event_store.ts +199 -37
- package/src/storage/tagging_store/recipient_tagging_store.ts +89 -13
- package/src/storage/tagging_store/sender_tagging_store.ts +129 -28
- package/src/tagging/constants.ts +10 -0
- package/src/tagging/index.ts +1 -11
- package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +10 -6
- package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +8 -7
- package/src/tagging/sender_sync/utils/get_status_change_of_pending.ts +6 -2
- package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +4 -1
- package/src/tree_membership/tree_membership_service.ts +27 -42
- package/dest/contract_function_simulator/proxied_node.d.ts +0 -9
- package/dest/contract_function_simulator/proxied_node.d.ts.map +0 -1
- package/dest/contract_function_simulator/proxied_node.js +0 -27
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts +0 -28
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts.map +0 -1
- package/dest/private_kernel/private_kernel_oracle_impl.d.ts +0 -46
- package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +0 -1
- package/dest/private_kernel/private_kernel_oracle_impl.js +0 -86
- package/dest/public_storage/public_storage_service.d.ts +0 -24
- package/dest/public_storage/public_storage_service.d.ts.map +0 -1
- package/dest/public_storage/public_storage_service.js +0 -26
- package/src/contract_function_simulator/proxied_node.ts +0 -33
- package/src/private_kernel/private_kernel_oracle_impl.ts +0 -133
- package/src/public_storage/public_storage_service.ts +0 -33
|
@@ -3,14 +3,17 @@ import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
|
3
3
|
import type { DirectionalAppTaggingSecret, PreTag } from '@aztec/stdlib/logs';
|
|
4
4
|
import { TxHash } from '@aztec/stdlib/tx';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import type { StagedStore } from '../../job_coordinator/job_coordinator.js';
|
|
7
|
+
import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../../tagging/constants.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Data provider of tagging data used when syncing the sender tagging indexes. The recipient counterpart of this class
|
|
10
|
-
* is called RecipientTaggingStore. We have the
|
|
11
|
+
* is called RecipientTaggingStore. We have the data stores separate for sender and recipient because
|
|
11
12
|
* the algorithms are completely disjoint and there is not data reuse between the two.
|
|
12
13
|
*/
|
|
13
|
-
export class SenderTaggingStore {
|
|
14
|
+
export class SenderTaggingStore implements StagedStore {
|
|
15
|
+
readonly storeName = 'sender_tagging';
|
|
16
|
+
|
|
14
17
|
#store: AztecAsyncKVStore;
|
|
15
18
|
|
|
16
19
|
// Stores the pending indexes for each directional app tagging secret. Pending here means that the tx that contained
|
|
@@ -21,18 +24,114 @@ export class SenderTaggingStore {
|
|
|
21
24
|
// the smaller ones are irrelevant due to tx atomicity.
|
|
22
25
|
//
|
|
23
26
|
// TODO(#17615): This assumes no logs are used in the non-revertible phase.
|
|
27
|
+
//
|
|
28
|
+
// directional app tagging secret => { pending index, txHash }[]
|
|
24
29
|
#pendingIndexes: AztecAsyncMap<string, { index: number; txHash: string }[]>;
|
|
25
30
|
|
|
31
|
+
// jobId => directional app tagging secret => { pending index, txHash }[]
|
|
32
|
+
#pendingIndexesForJob: Map<string, Map<string, { index: number; txHash: string }[]>>;
|
|
33
|
+
|
|
26
34
|
// Stores the last (highest) finalized index for each directional app tagging secret. We care only about the last
|
|
27
35
|
// index because unlike the pending indexes, it will never happen that a finalized index would be removed and hence
|
|
28
36
|
// we don't need to store the history.
|
|
37
|
+
//
|
|
38
|
+
// directional app tagging secret => highest finalized index
|
|
29
39
|
#lastFinalizedIndexes: AztecAsyncMap<string, number>;
|
|
30
40
|
|
|
41
|
+
// jobId => directional app tagging secret => highest finalized index
|
|
42
|
+
#lastFinalizedIndexesForJob: Map<string, Map<string, number>>;
|
|
43
|
+
|
|
31
44
|
constructor(store: AztecAsyncKVStore) {
|
|
32
45
|
this.#store = store;
|
|
33
46
|
|
|
34
47
|
this.#pendingIndexes = this.#store.openMap('pending_indexes');
|
|
35
48
|
this.#lastFinalizedIndexes = this.#store.openMap('last_finalized_indexes');
|
|
49
|
+
|
|
50
|
+
this.#pendingIndexesForJob = new Map();
|
|
51
|
+
this.#lastFinalizedIndexesForJob = new Map();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
#getPendingIndexesForJob(jobId: string): Map<string, { index: number; txHash: string }[]> {
|
|
55
|
+
let pendingIndexesForJob = this.#pendingIndexesForJob.get(jobId);
|
|
56
|
+
if (!pendingIndexesForJob) {
|
|
57
|
+
pendingIndexesForJob = new Map();
|
|
58
|
+
this.#pendingIndexesForJob.set(jobId, pendingIndexesForJob);
|
|
59
|
+
}
|
|
60
|
+
return pendingIndexesForJob;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
#getLastFinalizedIndexesForJob(jobId: string): Map<string, number> {
|
|
64
|
+
let jobStagedLastFinalizedIndexes = this.#lastFinalizedIndexesForJob.get(jobId);
|
|
65
|
+
if (!jobStagedLastFinalizedIndexes) {
|
|
66
|
+
jobStagedLastFinalizedIndexes = new Map();
|
|
67
|
+
this.#lastFinalizedIndexesForJob.set(jobId, jobStagedLastFinalizedIndexes);
|
|
68
|
+
}
|
|
69
|
+
return jobStagedLastFinalizedIndexes;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async #readPendingIndexes(jobId: string, secret: string): Promise<{ index: number; txHash: string }[]> {
|
|
73
|
+
const jobStagedPendingIndexes = this.#getPendingIndexesForJob(jobId);
|
|
74
|
+
const pendingIndexes = jobStagedPendingIndexes.get(secret);
|
|
75
|
+
// We return the staged version of this if it exists, if not, we read from the DB.
|
|
76
|
+
// If the DB also has nothing, we return an empty array [].
|
|
77
|
+
return pendingIndexes !== undefined ? pendingIndexes : ((await this.#pendingIndexes.getAsync(secret)) ?? []);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
#writePendingIndexes(jobId: string, secret: string, pendingIndexes: { index: number; txHash: string }[]) {
|
|
81
|
+
this.#getPendingIndexesForJob(jobId).set(secret, pendingIndexes);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Returns a job view of all the secrets that have a corresponding list of pending indexes either in persistent
|
|
86
|
+
* storage or the current job.
|
|
87
|
+
*/
|
|
88
|
+
async #readSecretsWithPendingIndexes(jobId: string): Promise<string[]> {
|
|
89
|
+
const storedSecrets = new Set(await toArray(this.#pendingIndexes.keysAsync()));
|
|
90
|
+
const stagedSecrets = this.#getPendingIndexesForJob(jobId).keys();
|
|
91
|
+
return [...storedSecrets.union(new Set(stagedSecrets))];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async #readLastFinalizedIndex(jobId: string, secret: string): Promise<number | undefined> {
|
|
95
|
+
return (
|
|
96
|
+
this.#getLastFinalizedIndexesForJob(jobId).get(secret) ?? (await this.#lastFinalizedIndexes.getAsync(secret))
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
#writeLastFinalizedIndex(jobId: string, secret: string, lastFinalizedIndex: number) {
|
|
101
|
+
this.#getLastFinalizedIndexesForJob(jobId).set(secret, lastFinalizedIndex);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Writes all job-specific in-memory data to persistent storage.
|
|
106
|
+
*
|
|
107
|
+
* @remark This method must run in a DB transaction context. It's designed to be called from JobCoordinator#commitJob.
|
|
108
|
+
*/
|
|
109
|
+
async commit(jobId: string): Promise<void> {
|
|
110
|
+
const pendingIndexesForJob = this.#pendingIndexesForJob.get(jobId);
|
|
111
|
+
if (pendingIndexesForJob) {
|
|
112
|
+
for (const [secret, pendingIndexes] of pendingIndexesForJob.entries()) {
|
|
113
|
+
if (pendingIndexes.length === 0) {
|
|
114
|
+
await this.#pendingIndexes.delete(secret);
|
|
115
|
+
} else {
|
|
116
|
+
await this.#pendingIndexes.set(secret, pendingIndexes);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const lastFinalizedIndexesForJob = this.#lastFinalizedIndexesForJob.get(jobId);
|
|
122
|
+
if (lastFinalizedIndexesForJob) {
|
|
123
|
+
for (const [secret, lastFinalizedIndex] of lastFinalizedIndexesForJob.entries()) {
|
|
124
|
+
await this.#lastFinalizedIndexes.set(secret, lastFinalizedIndex);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return this.discardStaged(jobId);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
discardStaged(jobId: string): Promise<void> {
|
|
132
|
+
this.#pendingIndexesForJob.delete(jobId);
|
|
133
|
+
this.#lastFinalizedIndexesForJob.delete(jobId);
|
|
134
|
+
return Promise.resolve();
|
|
36
135
|
}
|
|
37
136
|
|
|
38
137
|
/**
|
|
@@ -43,6 +142,7 @@ export class SenderTaggingStore {
|
|
|
43
142
|
* @param preTags - The pre-tags containing the directional app tagging secrets and the indexes that are to be
|
|
44
143
|
* stored in the db.
|
|
45
144
|
* @param txHash - The tx in which the pretags were used in private logs.
|
|
145
|
+
* @param jobId - job context for staged writes to this store. See `JobCoordinator` for more details.
|
|
46
146
|
* @throws If any two pre-tags contain the same directional app tagging secret. This is enforced because we care
|
|
47
147
|
* only about the highest index for a given secret that was used in the tx. Hence this check is a good way to catch
|
|
48
148
|
* bugs.
|
|
@@ -56,7 +156,7 @@ export class SenderTaggingStore {
|
|
|
56
156
|
* This is enforced because this should never happen if the syncing is done correctly as we look for logs from higher
|
|
57
157
|
* indexes than finalized ones.
|
|
58
158
|
*/
|
|
59
|
-
async storePendingIndexes(preTags: PreTag[], txHash: TxHash) {
|
|
159
|
+
async storePendingIndexes(preTags: PreTag[], txHash: TxHash, jobId: string) {
|
|
60
160
|
// The secrets in pre-tags should be unique because we always store just the highest index per given secret-txHash
|
|
61
161
|
// pair. Below we check that this is the case.
|
|
62
162
|
const secretsSet = new Set(preTags.map(preTag => preTag.secret.toString()));
|
|
@@ -67,7 +167,7 @@ export class SenderTaggingStore {
|
|
|
67
167
|
for (const { secret, index } of preTags) {
|
|
68
168
|
// First we check that for any secret the highest used index in tx is not further than window length from
|
|
69
169
|
// the highest finalized index.
|
|
70
|
-
const finalizedIndex = (await this.getLastFinalizedIndex(secret)) ?? 0;
|
|
170
|
+
const finalizedIndex = (await this.getLastFinalizedIndex(secret, jobId)) ?? 0;
|
|
71
171
|
if (index > finalizedIndex + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN) {
|
|
72
172
|
throw new Error(
|
|
73
173
|
`Highest used index ${index} is further than window length from the highest finalized index ${finalizedIndex}.
|
|
@@ -78,7 +178,7 @@ export class SenderTaggingStore {
|
|
|
78
178
|
|
|
79
179
|
// Throw if the new pending index is lower than or equal to the last finalized index
|
|
80
180
|
const secretStr = secret.toString();
|
|
81
|
-
const lastFinalizedIndex = await this.#
|
|
181
|
+
const lastFinalizedIndex = await this.#readLastFinalizedIndex(jobId, secretStr);
|
|
82
182
|
if (lastFinalizedIndex !== undefined && index <= lastFinalizedIndex) {
|
|
83
183
|
throw new Error(
|
|
84
184
|
`Cannot store pending index ${index} for secret ${secretStr}: ` +
|
|
@@ -88,7 +188,7 @@ export class SenderTaggingStore {
|
|
|
88
188
|
|
|
89
189
|
// Check if this secret + txHash combination already exists
|
|
90
190
|
const txHashStr = txHash.toString();
|
|
91
|
-
const existingForSecret =
|
|
191
|
+
const existingForSecret = await this.#readPendingIndexes(jobId, secretStr);
|
|
92
192
|
const existingForSecretAndTx = existingForSecret.find(entry => entry.txHash === txHashStr);
|
|
93
193
|
|
|
94
194
|
if (existingForSecretAndTx) {
|
|
@@ -102,7 +202,7 @@ export class SenderTaggingStore {
|
|
|
102
202
|
// If it exists with the same index, ignore the update (no-op)
|
|
103
203
|
} else {
|
|
104
204
|
// If it doesn't exist, add it
|
|
105
|
-
|
|
205
|
+
this.#writePendingIndexes(jobId, secretStr, [...existingForSecret, { index, txHash: txHashStr }]);
|
|
106
206
|
}
|
|
107
207
|
}
|
|
108
208
|
}
|
|
@@ -120,8 +220,9 @@ export class SenderTaggingStore {
|
|
|
120
220
|
secret: DirectionalAppTaggingSecret,
|
|
121
221
|
startIndex: number,
|
|
122
222
|
endIndex: number,
|
|
223
|
+
jobId: string,
|
|
123
224
|
): Promise<TxHash[]> {
|
|
124
|
-
const existing =
|
|
225
|
+
const existing = await this.#readPendingIndexes(jobId, secret.toString());
|
|
125
226
|
const txHashes = existing
|
|
126
227
|
.filter(entry => entry.index >= startIndex && entry.index < endIndex)
|
|
127
228
|
.map(entry => entry.txHash);
|
|
@@ -133,8 +234,8 @@ export class SenderTaggingStore {
|
|
|
133
234
|
* @param secret - The secret to get the last finalized index for.
|
|
134
235
|
* @returns The last (highest) finalized index for the given secret.
|
|
135
236
|
*/
|
|
136
|
-
getLastFinalizedIndex(secret: DirectionalAppTaggingSecret): Promise<number | undefined> {
|
|
137
|
-
return this.#
|
|
237
|
+
getLastFinalizedIndex(secret: DirectionalAppTaggingSecret, jobId: string): Promise<number | undefined> {
|
|
238
|
+
return this.#readLastFinalizedIndex(jobId, secret.toString());
|
|
138
239
|
}
|
|
139
240
|
|
|
140
241
|
/**
|
|
@@ -143,13 +244,13 @@ export class SenderTaggingStore {
|
|
|
143
244
|
* @param secret - The directional app tagging secret to query the last used index for.
|
|
144
245
|
* @returns The last used index.
|
|
145
246
|
*/
|
|
146
|
-
async getLastUsedIndex(secret: DirectionalAppTaggingSecret): Promise<number | undefined> {
|
|
247
|
+
async getLastUsedIndex(secret: DirectionalAppTaggingSecret, jobId: string): Promise<number | undefined> {
|
|
147
248
|
const secretStr = secret.toString();
|
|
148
|
-
const pendingTxScopedIndexes =
|
|
249
|
+
const pendingTxScopedIndexes = await this.#readPendingIndexes(jobId, secretStr);
|
|
149
250
|
const pendingIndexes = pendingTxScopedIndexes.map(entry => entry.index);
|
|
150
251
|
|
|
151
252
|
if (pendingTxScopedIndexes.length === 0) {
|
|
152
|
-
return this.#
|
|
253
|
+
return this.#readLastFinalizedIndex(jobId, secretStr);
|
|
153
254
|
}
|
|
154
255
|
|
|
155
256
|
// As the last used index we return the highest one from the pending indexes. Note that this value will be always
|
|
@@ -160,23 +261,23 @@ export class SenderTaggingStore {
|
|
|
160
261
|
/**
|
|
161
262
|
* Drops all pending indexes corresponding to the given transaction hashes.
|
|
162
263
|
*/
|
|
163
|
-
async dropPendingIndexes(txHashes: TxHash[]) {
|
|
264
|
+
async dropPendingIndexes(txHashes: TxHash[], jobId: string) {
|
|
164
265
|
if (txHashes.length === 0) {
|
|
165
266
|
return;
|
|
166
267
|
}
|
|
167
268
|
|
|
168
|
-
const
|
|
169
|
-
const allSecrets = await
|
|
269
|
+
const txHashStrings = new Set<string>(txHashes.map(txHash => txHash.toString()));
|
|
270
|
+
const allSecrets = await this.#readSecretsWithPendingIndexes(jobId);
|
|
170
271
|
|
|
171
272
|
for (const secret of allSecrets) {
|
|
172
|
-
const pendingData = await this.#
|
|
273
|
+
const pendingData = await this.#readPendingIndexes(jobId, secret);
|
|
173
274
|
if (pendingData) {
|
|
174
|
-
const filtered = pendingData.filter(item => !
|
|
275
|
+
const filtered = pendingData.filter(item => !txHashStrings.has(item.txHash));
|
|
175
276
|
if (filtered.length === 0) {
|
|
176
|
-
|
|
277
|
+
this.#writePendingIndexes(jobId, secret, []);
|
|
177
278
|
} else if (filtered.length !== pendingData.length) {
|
|
178
279
|
// Some items were filtered out, so update the pending data
|
|
179
|
-
|
|
280
|
+
this.#writePendingIndexes(jobId, secret, filtered);
|
|
180
281
|
}
|
|
181
282
|
// else: No items were filtered out (txHashes not found for this secret) --> no-op
|
|
182
283
|
}
|
|
@@ -187,7 +288,7 @@ export class SenderTaggingStore {
|
|
|
187
288
|
* Updates pending indexes corresponding to the given transaction hashes to be finalized and prunes any lower pending
|
|
188
289
|
* indexes.
|
|
189
290
|
*/
|
|
190
|
-
async finalizePendingIndexes(txHashes: TxHash[]) {
|
|
291
|
+
async finalizePendingIndexes(txHashes: TxHash[], jobId: string) {
|
|
191
292
|
if (txHashes.length === 0) {
|
|
192
293
|
return;
|
|
193
294
|
}
|
|
@@ -195,10 +296,10 @@ export class SenderTaggingStore {
|
|
|
195
296
|
for (const txHash of txHashes) {
|
|
196
297
|
const txHashStr = txHash.toString();
|
|
197
298
|
|
|
198
|
-
const allSecrets = await
|
|
299
|
+
const allSecrets = await this.#readSecretsWithPendingIndexes(jobId);
|
|
199
300
|
|
|
200
301
|
for (const secret of allSecrets) {
|
|
201
|
-
const pendingData = await this.#
|
|
302
|
+
const pendingData = await this.#readPendingIndexes(jobId, secret);
|
|
202
303
|
if (!pendingData) {
|
|
203
304
|
continue;
|
|
204
305
|
}
|
|
@@ -214,7 +315,7 @@ export class SenderTaggingStore {
|
|
|
214
315
|
throw new Error(`Multiple pending indexes found for tx hash ${txHashStr} and secret ${secret}`);
|
|
215
316
|
}
|
|
216
317
|
|
|
217
|
-
let lastFinalized = await this.#
|
|
318
|
+
let lastFinalized = await this.#readLastFinalizedIndex(jobId, secret);
|
|
218
319
|
const newFinalized = matchingIndexes[0];
|
|
219
320
|
|
|
220
321
|
if (newFinalized < (lastFinalized ?? 0)) {
|
|
@@ -225,7 +326,7 @@ export class SenderTaggingStore {
|
|
|
225
326
|
);
|
|
226
327
|
}
|
|
227
328
|
|
|
228
|
-
|
|
329
|
+
this.#writeLastFinalizedIndex(jobId, secret, newFinalized);
|
|
229
330
|
lastFinalized = newFinalized;
|
|
230
331
|
|
|
231
332
|
// When we add pending indexes, we ensure they are higher than the last finalized index. However, because we
|
|
@@ -234,9 +335,9 @@ export class SenderTaggingStore {
|
|
|
234
335
|
// outdated pending indexes.
|
|
235
336
|
const remainingItemsOfHigherIndex = pendingData.filter(item => item.index > (lastFinalized ?? 0));
|
|
236
337
|
if (remainingItemsOfHigherIndex.length === 0) {
|
|
237
|
-
|
|
338
|
+
this.#writePendingIndexes(jobId, secret, []);
|
|
238
339
|
} else {
|
|
239
|
-
|
|
340
|
+
this.#writePendingIndexes(jobId, secret, remainingItemsOfHigherIndex);
|
|
240
341
|
}
|
|
241
342
|
}
|
|
242
343
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// This window has to be as large as the largest expected number of logs emitted in a tx for a given directional app
|
|
2
|
+
// tagging secret. If we get more tag indexes consumed than this window, an error is thrown in `PXE::proveTx` function.
|
|
3
|
+
// This is set to a larger value than MAX_PRIVATE_LOGS_PER_TX (currently 64) because there could be more than
|
|
4
|
+
// MAX_PRIVATE_LOGS_PER_TX indexes consumed in case the logs are squashed. This happens when the log contains a note
|
|
5
|
+
// and the note is nullified in the same tx.
|
|
6
|
+
//
|
|
7
|
+
// Having a large window significantly slowed down `e2e_l1_with_wall_time` test as there we perform sync for more than
|
|
8
|
+
// 1000 secrets. For this reason we set it to a relatively low value of 20. 20 should be sufficient for all the use
|
|
9
|
+
// cases.
|
|
10
|
+
export const UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN = 20;
|
package/src/tagging/index.ts
CHANGED
|
@@ -11,17 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
export { loadPrivateLogsForSenderRecipientPair } from './recipient_sync/load_private_logs_for_sender_recipient_pair.js';
|
|
13
13
|
export { syncSenderTaggingIndexes } from './sender_sync/sync_sender_tagging_indexes.js';
|
|
14
|
-
|
|
15
|
-
// This window has to be as large as the largest expected number of logs emitted in a tx for a given directional app
|
|
16
|
-
// tagging secret. If we get more tag indexes consumed than this window, an error is thrown in `PXE::proveTx` function.
|
|
17
|
-
// This is set to a larger value than MAX_PRIVATE_LOGS_PER_TX (currently 64) because there could be more than
|
|
18
|
-
// MAX_PRIVATE_LOGS_PER_TX indexes consumed in case the logs are squashed. This happens when the log contains a note
|
|
19
|
-
// and the note is nullified in the same tx.
|
|
20
|
-
//
|
|
21
|
-
// Having a large window significantly slowed down `e2e_l1_with_wall_time` test as there we perform sync for more than
|
|
22
|
-
// 1000 secrets. For this reason we set it to a relatively low value of 20. 20 should be sufficient for all the use
|
|
23
|
-
// cases.
|
|
24
|
-
export const UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN = 20;
|
|
14
|
+
export { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from './constants.js';
|
|
25
15
|
|
|
26
16
|
// Re-export tagging-related types from stdlib
|
|
27
17
|
export { DirectionalAppTaggingSecret, Tag, SiloedTag } from '@aztec/stdlib/logs';
|
|
@@ -4,7 +4,7 @@ import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
|
4
4
|
import type { DirectionalAppTaggingSecret, TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
5
5
|
|
|
6
6
|
import type { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js';
|
|
7
|
-
import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../
|
|
7
|
+
import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../constants.js';
|
|
8
8
|
import { findHighestIndexes } from './utils/find_highest_indexes.js';
|
|
9
9
|
import { loadLogsForRange } from './utils/load_logs_for_range.js';
|
|
10
10
|
|
|
@@ -21,6 +21,7 @@ export async function loadPrivateLogsForSenderRecipientPair(
|
|
|
21
21
|
aztecNode: AztecNode,
|
|
22
22
|
taggingStore: RecipientTaggingStore,
|
|
23
23
|
anchorBlockNumber: BlockNumber,
|
|
24
|
+
jobId: string,
|
|
24
25
|
): Promise<TxScopedL2Log[]> {
|
|
25
26
|
// # Explanation of how the algorithm works
|
|
26
27
|
// When we perform the sync we will look at logs that correspond to the tagging index range
|
|
@@ -68,13 +69,16 @@ export async function loadPrivateLogsForSenderRecipientPair(
|
|
|
68
69
|
throw new Error('Node failed to return latest block header when syncing logs');
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
[finalizedBlockNumber, currentTimestamp] = [
|
|
72
|
+
[finalizedBlockNumber, currentTimestamp] = [
|
|
73
|
+
l2Tips.finalized.block.number,
|
|
74
|
+
latestBlockHeader.globalVariables.timestamp,
|
|
75
|
+
];
|
|
72
76
|
}
|
|
73
77
|
|
|
74
78
|
let start: number, end: number;
|
|
75
79
|
{
|
|
76
|
-
const currentHighestAgedIndex = await taggingStore.getHighestAgedIndex(secret);
|
|
77
|
-
const currentHighestFinalizedIndex = await taggingStore.getHighestFinalizedIndex(secret);
|
|
80
|
+
const currentHighestAgedIndex = await taggingStore.getHighestAgedIndex(secret, jobId);
|
|
81
|
+
const currentHighestFinalizedIndex = await taggingStore.getHighestFinalizedIndex(secret, jobId);
|
|
78
82
|
|
|
79
83
|
// We don't want to include the highest aged index so we start from `currentHighestAgedIndex + 1` (or 0 if not set)
|
|
80
84
|
start = currentHighestAgedIndex === undefined ? 0 : currentHighestAgedIndex + 1;
|
|
@@ -104,7 +108,7 @@ export async function loadPrivateLogsForSenderRecipientPair(
|
|
|
104
108
|
|
|
105
109
|
// Store updates in data provider and update local variables
|
|
106
110
|
if (highestAgedIndex !== undefined) {
|
|
107
|
-
await taggingStore.updateHighestAgedIndex(secret, highestAgedIndex);
|
|
111
|
+
await taggingStore.updateHighestAgedIndex(secret, highestAgedIndex, jobId);
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
if (highestFinalizedIndex === undefined) {
|
|
@@ -117,7 +121,7 @@ export async function loadPrivateLogsForSenderRecipientPair(
|
|
|
117
121
|
throw new Error('Highest aged index lower than highest finalized index invariant violated');
|
|
118
122
|
}
|
|
119
123
|
|
|
120
|
-
await taggingStore.updateHighestFinalizedIndex(secret, highestFinalizedIndex);
|
|
124
|
+
await taggingStore.updateHighestFinalizedIndex(secret, highestFinalizedIndex, jobId);
|
|
121
125
|
|
|
122
126
|
// For the next iteration we want to look only at indexes for which we have not attempted to load logs yet while
|
|
123
127
|
// ensuring that we do not look further than WINDOW_LEN ahead of the highest finalized index.
|
|
@@ -3,7 +3,7 @@ import type { AztecNode } from '@aztec/stdlib/interfaces/server';
|
|
|
3
3
|
import type { DirectionalAppTaggingSecret } from '@aztec/stdlib/logs';
|
|
4
4
|
|
|
5
5
|
import type { SenderTaggingStore } from '../../storage/tagging_store/sender_tagging_store.js';
|
|
6
|
-
import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../
|
|
6
|
+
import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../constants.js';
|
|
7
7
|
import { getStatusChangeOfPending } from './utils/get_status_change_of_pending.js';
|
|
8
8
|
import { loadAndStoreNewTaggingIndexes } from './utils/load_and_store_new_tagging_indexes.js';
|
|
9
9
|
|
|
@@ -26,6 +26,7 @@ export async function syncSenderTaggingIndexes(
|
|
|
26
26
|
app: AztecAddress,
|
|
27
27
|
aztecNode: AztecNode,
|
|
28
28
|
taggingStore: SenderTaggingStore,
|
|
29
|
+
jobId: string,
|
|
29
30
|
): Promise<void> {
|
|
30
31
|
// # Explanation of how syncing works
|
|
31
32
|
//
|
|
@@ -45,7 +46,7 @@ export async function syncSenderTaggingIndexes(
|
|
|
45
46
|
// Each window advance requires two queries (logs + tx status). For example, syncing indexes 0–500 with a window of
|
|
46
47
|
// 100 takes at least 10 round trips (5 windows × 2 queries).
|
|
47
48
|
|
|
48
|
-
const finalizedIndex = await taggingStore.getLastFinalizedIndex(secret);
|
|
49
|
+
const finalizedIndex = await taggingStore.getLastFinalizedIndex(secret, jobId);
|
|
49
50
|
|
|
50
51
|
let start = finalizedIndex === undefined ? 0 : finalizedIndex + 1;
|
|
51
52
|
let end = start + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN;
|
|
@@ -56,21 +57,21 @@ export async function syncSenderTaggingIndexes(
|
|
|
56
57
|
while (true) {
|
|
57
58
|
// Load and store indexes for the current window. These indexes may already exist in the database if txs using
|
|
58
59
|
// them were previously sent from this PXE. Any duplicates are handled by the tagging data provider.
|
|
59
|
-
await loadAndStoreNewTaggingIndexes(secret, app, start, end, aztecNode, taggingStore);
|
|
60
|
+
await loadAndStoreNewTaggingIndexes(secret, app, start, end, aztecNode, taggingStore, jobId);
|
|
60
61
|
|
|
61
62
|
// Retrieve all indexes within the current window from storage and update their status accordingly.
|
|
62
|
-
const pendingTxHashes = await taggingStore.getTxHashesOfPendingIndexes(secret, start, end);
|
|
63
|
+
const pendingTxHashes = await taggingStore.getTxHashesOfPendingIndexes(secret, start, end, jobId);
|
|
63
64
|
if (pendingTxHashes.length === 0) {
|
|
64
65
|
break;
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
const { txHashesToFinalize, txHashesToDrop } = await getStatusChangeOfPending(pendingTxHashes, aztecNode);
|
|
68
69
|
|
|
69
|
-
await taggingStore.dropPendingIndexes(txHashesToDrop);
|
|
70
|
-
await taggingStore.finalizePendingIndexes(txHashesToFinalize);
|
|
70
|
+
await taggingStore.dropPendingIndexes(txHashesToDrop, jobId);
|
|
71
|
+
await taggingStore.finalizePendingIndexes(txHashesToFinalize, jobId);
|
|
71
72
|
|
|
72
73
|
// We check if the finalized index has been updated.
|
|
73
|
-
newFinalizedIndex = await taggingStore.getLastFinalizedIndex(secret);
|
|
74
|
+
newFinalizedIndex = await taggingStore.getLastFinalizedIndex(secret, jobId);
|
|
74
75
|
if (previousFinalizedIndex !== newFinalizedIndex) {
|
|
75
76
|
// A new finalized index was found, so we'll run the loop again. For example:
|
|
76
77
|
// - Previous finalized index: 10
|
|
@@ -10,7 +10,7 @@ export async function getStatusChangeOfPending(
|
|
|
10
10
|
aztecNode: AztecNode,
|
|
11
11
|
): Promise<{ txHashesToFinalize: TxHash[]; txHashesToDrop: TxHash[] }> {
|
|
12
12
|
// Get receipts for all pending tx hashes and the finalized block number.
|
|
13
|
-
const [receipts,
|
|
13
|
+
const [receipts, tips] = await Promise.all([
|
|
14
14
|
Promise.all(pending.map(pendingTxHash => aztecNode.getTxReceipt(pendingTxHash))),
|
|
15
15
|
aztecNode.getL2Tips(),
|
|
16
16
|
]);
|
|
@@ -22,7 +22,11 @@ export async function getStatusChangeOfPending(
|
|
|
22
22
|
const receipt = receipts[i];
|
|
23
23
|
const txHash = pending[i];
|
|
24
24
|
|
|
25
|
-
if (
|
|
25
|
+
if (
|
|
26
|
+
receipt.status === TxStatus.SUCCESS &&
|
|
27
|
+
receipt.blockNumber &&
|
|
28
|
+
receipt.blockNumber <= tips.finalized.block.number
|
|
29
|
+
) {
|
|
26
30
|
// Tx has been included in a block and the corresponding block is finalized --> we mark the indexes as
|
|
27
31
|
// finalized.
|
|
28
32
|
txHashesToFinalize.push(txHash);
|
|
@@ -17,6 +17,8 @@ import type { SenderTaggingStore } from '../../../storage/tagging_store/sender_t
|
|
|
17
17
|
* @param end - The ending index (exclusive) of the window to process.
|
|
18
18
|
* @param aztecNode - The Aztec node instance to query for logs.
|
|
19
19
|
* @param taggingStore - The data provider to store pending indexes.
|
|
20
|
+
* @param jobId - Job identifier, used to keep writes in-memory until they can be persisted in a data integrity
|
|
21
|
+
* preserving way.
|
|
20
22
|
*/
|
|
21
23
|
export async function loadAndStoreNewTaggingIndexes(
|
|
22
24
|
secret: DirectionalAppTaggingSecret,
|
|
@@ -25,6 +27,7 @@ export async function loadAndStoreNewTaggingIndexes(
|
|
|
25
27
|
end: number,
|
|
26
28
|
aztecNode: AztecNode,
|
|
27
29
|
taggingStore: SenderTaggingStore,
|
|
30
|
+
jobId: string,
|
|
28
31
|
) {
|
|
29
32
|
// We compute the tags for the current window of indexes
|
|
30
33
|
const preTagsForWindow: PreTag[] = Array(end - start)
|
|
@@ -40,7 +43,7 @@ export async function loadAndStoreNewTaggingIndexes(
|
|
|
40
43
|
// Now we iterate over the map, reconstruct the preTags and tx hash and store them in the db.
|
|
41
44
|
for (const [txHashStr, highestIndex] of highestIndexMap.entries()) {
|
|
42
45
|
const txHash = TxHash.fromString(txHashStr);
|
|
43
|
-
await taggingStore.storePendingIndexes([{ secret, index: highestIndex }], txHash);
|
|
46
|
+
await taggingStore.storePendingIndexes([{ secret, index: highestIndex }], txHash, jobId);
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
49
|
|
|
@@ -2,73 +2,67 @@ import type { L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/constants';
|
|
|
2
2
|
import type { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
3
|
import type { SiblingPath } from '@aztec/foundation/trees';
|
|
4
4
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
|
-
import
|
|
5
|
+
import { L2BlockHash } from '@aztec/stdlib/block';
|
|
6
6
|
import type { AztecNode } from '@aztec/stdlib/interfaces/server';
|
|
7
7
|
import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
|
|
8
8
|
import { MerkleTreeId, NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
// TODO: REmove this class as it no longer seems valuable. The only somewhat real functionality in this class is in
|
|
11
|
+
// the `getMembershipWitness` method that is used by `utilityGetMembershipWitness` oracle by then in Aztec.nr we
|
|
12
|
+
// have helper functions around that oracle for archive and note hash tree and the generic method itself is not used
|
|
13
|
+
// anywhere else - make sense to just have simple specific handlers for the archive and note hash trees and drop this.
|
|
12
14
|
export class TreeMembershipService {
|
|
13
|
-
constructor(
|
|
14
|
-
private readonly aztecNode: AztecNode,
|
|
15
|
-
private readonly anchorBlockStore: AnchorBlockStore,
|
|
16
|
-
) {}
|
|
15
|
+
constructor(private readonly aztecNode: AztecNode) {}
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* Gets the index of a nullifier in the nullifier tree.
|
|
20
19
|
* @returns - The index of the nullifier. Undefined if it does not exist in the tree.
|
|
21
20
|
*/
|
|
22
|
-
public getNullifierIndex(nullifier: Fr) {
|
|
23
|
-
|
|
21
|
+
public async getNullifierIndex(nullifier: Fr): Promise<bigint | undefined> {
|
|
22
|
+
const [leafIndex] = await this.aztecNode.findLeavesIndexes('latest', MerkleTreeId.NULLIFIER_TREE, [nullifier]);
|
|
23
|
+
return leafIndex?.data;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Fetches the index and sibling path of a leaf at a given block from a given tree.
|
|
28
|
-
* @param
|
|
28
|
+
* @param blockHash - The block hash at which to get the membership witness.
|
|
29
29
|
* @param treeId - Id of the tree to get the sibling path from.
|
|
30
30
|
* @param leafValue - The leaf value
|
|
31
31
|
* @returns The index and sibling path concatenated [index, sibling_path]
|
|
32
32
|
*/
|
|
33
|
-
public async getMembershipWitness(
|
|
34
|
-
const witness = await this.#tryGetMembershipWitness(
|
|
33
|
+
public async getMembershipWitness(blockHash: L2BlockHash, treeId: MerkleTreeId, leafValue: Fr): Promise<Fr[]> {
|
|
34
|
+
const witness = await this.#tryGetMembershipWitness(blockHash, treeId, leafValue);
|
|
35
35
|
if (!witness) {
|
|
36
|
-
throw new Error(
|
|
36
|
+
throw new Error(
|
|
37
|
+
`Leaf value ${leafValue} not found in tree ${MerkleTreeId[treeId]} at block hash ${blockHash.toString()}`,
|
|
38
|
+
);
|
|
37
39
|
}
|
|
38
40
|
return witness;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
/**
|
|
42
44
|
* Returns a low nullifier membership witness for a given nullifier at a given block.
|
|
43
|
-
* @param
|
|
45
|
+
* @param blockHash - The block hash at which to get the index.
|
|
44
46
|
* @param nullifier - Nullifier we try to find the low nullifier witness for.
|
|
45
47
|
* @returns The low nullifier membership witness (if found).
|
|
46
48
|
* @remarks Low nullifier witness can be used to perform a nullifier non-inclusion proof by leveraging the "linked
|
|
47
49
|
* list structure" of leaves and proving that a lower nullifier is pointing to a bigger next value than the nullifier
|
|
48
50
|
* we are trying to prove non-inclusion for.
|
|
49
51
|
*/
|
|
50
|
-
public
|
|
51
|
-
|
|
52
|
+
public getLowNullifierMembershipWitness(
|
|
53
|
+
blockHash: L2BlockHash,
|
|
52
54
|
nullifier: Fr,
|
|
53
55
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
54
|
-
|
|
55
|
-
if (blockNumber !== 'latest' && blockNumber > anchorBlockNumber) {
|
|
56
|
-
throw new Error(`Block number ${blockNumber} is higher than current block ${anchorBlockNumber}`);
|
|
57
|
-
}
|
|
58
|
-
return this.aztecNode.getLowNullifierMembershipWitness(blockNumber, nullifier);
|
|
56
|
+
return this.aztecNode.getLowNullifierMembershipWitness(blockHash, nullifier);
|
|
59
57
|
}
|
|
60
58
|
|
|
61
59
|
/**
|
|
62
60
|
* Returns a witness for a given slot of the public data tree at a given block.
|
|
63
|
-
* @param
|
|
61
|
+
* @param blockHash - The block hash at which to get the witness.
|
|
64
62
|
* @param leafSlot - The slot of the public data in the public data tree.
|
|
65
63
|
*/
|
|
66
|
-
public
|
|
67
|
-
|
|
68
|
-
if (blockNumber !== 'latest' && blockNumber > anchorBlockNumber) {
|
|
69
|
-
throw new Error(`Block number ${blockNumber} is higher than current block ${anchorBlockNumber}`);
|
|
70
|
-
}
|
|
71
|
-
return await this.aztecNode.getPublicDataWitness(blockNumber, leafSlot);
|
|
64
|
+
public getPublicDataWitness(blockHash: L2BlockHash, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
|
|
65
|
+
return this.aztecNode.getPublicDataWitness(blockHash, leafSlot);
|
|
72
66
|
}
|
|
73
67
|
|
|
74
68
|
/**
|
|
@@ -86,27 +80,18 @@ export class TreeMembershipService {
|
|
|
86
80
|
return getNonNullifiedL1ToL2MessageWitness(this.aztecNode, contractAddress, messageHash, secret);
|
|
87
81
|
}
|
|
88
82
|
|
|
89
|
-
async #tryGetMembershipWitness(
|
|
90
|
-
blockNumber: BlockParameter,
|
|
91
|
-
treeId: MerkleTreeId,
|
|
92
|
-
value: Fr,
|
|
93
|
-
): Promise<Fr[] | undefined> {
|
|
83
|
+
async #tryGetMembershipWitness(blockHash: L2BlockHash, treeId: MerkleTreeId, value: Fr): Promise<Fr[] | undefined> {
|
|
94
84
|
switch (treeId) {
|
|
95
85
|
case MerkleTreeId.NULLIFIER_TREE:
|
|
96
|
-
return (await this.aztecNode.getNullifierMembershipWitness(
|
|
86
|
+
return (await this.aztecNode.getNullifierMembershipWitness(blockHash, value))?.withoutPreimage().toFields();
|
|
97
87
|
case MerkleTreeId.NOTE_HASH_TREE:
|
|
98
|
-
return (await this.aztecNode.getNoteHashMembershipWitness(
|
|
88
|
+
return (await this.aztecNode.getNoteHashMembershipWitness(blockHash, value))?.toFields();
|
|
99
89
|
case MerkleTreeId.PUBLIC_DATA_TREE:
|
|
100
|
-
return (await this.aztecNode.getPublicDataWitness(
|
|
90
|
+
return (await this.aztecNode.getPublicDataWitness(blockHash, value))?.withoutPreimage().toFields();
|
|
101
91
|
case MerkleTreeId.ARCHIVE:
|
|
102
|
-
return (await this.aztecNode.getArchiveMembershipWitness(
|
|
92
|
+
return (await this.aztecNode.getArchiveMembershipWitness(blockHash, value))?.toFields();
|
|
103
93
|
default:
|
|
104
94
|
throw new Error('Not implemented');
|
|
105
95
|
}
|
|
106
96
|
}
|
|
107
|
-
|
|
108
|
-
async #findLeafIndex(blockNumber: BlockParameter, treeId: MerkleTreeId, leafValue: Fr): Promise<bigint | undefined> {
|
|
109
|
-
const [leafIndex] = await this.aztecNode.findLeavesIndexes(blockNumber, treeId, [leafValue]);
|
|
110
|
-
return leafIndex?.data;
|
|
111
|
-
}
|
|
112
97
|
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
2
|
-
import type { NodeStats } from '@aztec/stdlib/tx';
|
|
3
|
-
export type ProxiedNode = AztecNode & {
|
|
4
|
-
getStats(): NodeStats;
|
|
5
|
-
};
|
|
6
|
-
export declare class ProxiedNodeFactory {
|
|
7
|
-
static create(node: AztecNode): ProxiedNode;
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJveGllZF9ub2RlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29udHJhY3RfZnVuY3Rpb25fc2ltdWxhdG9yL3Byb3hpZWRfbm9kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNqRSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUtsRCxNQUFNLE1BQU0sV0FBVyxHQUFHLFNBQVMsR0FBRztJQUFFLFFBQVEsSUFBSSxTQUFTLENBQUE7Q0FBRSxDQUFDO0FBRWhFLHFCQUFhLGtCQUFrQjtJQUM3QixNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxTQUFTLGVBcUI1QjtDQUNGIn0=
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"proxied_node.d.ts","sourceRoot":"","sources":["../../src/contract_function_simulator/proxied_node.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAKlD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG;IAAE,QAAQ,IAAI,SAAS,CAAA;CAAE,CAAC;AAEhE,qBAAa,kBAAkB;IAC7B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,eAqB5B;CACF"}
|