@aztec/pxe 0.0.1-commit.b8a057fa → 0.0.1-commit.be03c316
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bin/check_oracle_version.js +3 -8
- package/dest/bin/index.d.ts +2 -2
- package/dest/bin/index.d.ts.map +1 -1
- package/dest/bin/index.js +1 -1
- package/dest/bin/oracle_version_helpers.d.ts +8 -25
- package/dest/bin/oracle_version_helpers.d.ts.map +1 -1
- package/dest/bin/oracle_version_helpers.js +11 -219
- package/dest/contract/helpers.d.ts +1 -1
- package/dest/contract/helpers.d.ts.map +1 -1
- package/dest/contract/helpers.js +3 -3
- package/dest/contract/skip_sync_contracts.d.ts +11 -0
- package/dest/contract/skip_sync_contracts.d.ts.map +1 -0
- package/dest/contract/skip_sync_contracts.js +18 -0
- package/dest/contract_function_simulator/aztec_node_read_cache.d.ts +39 -0
- package/dest/contract_function_simulator/aztec_node_read_cache.d.ts.map +1 -0
- package/dest/contract_function_simulator/aztec_node_read_cache.js +60 -0
- package/dest/contract_function_simulator/index.d.ts +3 -3
- package/dest/contract_function_simulator/index.d.ts.map +1 -1
- package/dest/contract_function_simulator/index.js +1 -2
- package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.d.ts +1 -1
- package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.js +7 -0
- package/dest/contract_function_simulator/noir-structs/resolved_tx.d.ts +7 -9
- package/dest/contract_function_simulator/noir-structs/resolved_tx.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/resolved_tx.js +3 -44
- package/dest/contract_function_simulator/noir-structs/tx_effect_data.d.ts +5 -4
- package/dest/contract_function_simulator/noir-structs/tx_effect_data.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/tx_effect_data.js +2 -2
- package/dest/contract_function_simulator/oracle/acir_callback.js +1 -1
- package/dest/contract_function_simulator/oracle/legacy_oracle_registry.d.ts +3 -3
- package/dest/contract_function_simulator/oracle/legacy_oracle_registry.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/legacy_oracle_registry.js +34 -1
- package/dest/contract_function_simulator/oracle/oracle_registry.d.ts +7 -4
- package/dest/contract_function_simulator/oracle/oracle_registry.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle_registry.js +40 -13
- package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts +87 -35
- package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle_type_mappings.js +286 -286
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +7 -10
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +14 -8
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +61 -34
- package/dest/entrypoints/client/bundle/index.d.ts +2 -1
- package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/index.js +1 -0
- 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 -4
- package/dest/entrypoints/client/lazy/index.d.ts +2 -1
- package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/index.js +1 -0
- 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 -4
- package/dest/entrypoints/client/store.d.ts +14 -0
- package/dest/entrypoints/client/store.d.ts.map +1 -0
- package/dest/entrypoints/client/store.js +42 -0
- 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/store.d.ts +18 -0
- package/dest/entrypoints/server/store.d.ts.map +1 -0
- package/dest/entrypoints/server/store.js +28 -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 +8 -2
- package/dest/hooks/index.d.ts +2 -2
- package/dest/hooks/index.d.ts.map +1 -1
- package/dest/hooks/index.js +1 -0
- package/dest/hooks/resolve_tagging_secret_strategy.d.ts +3 -1
- package/dest/hooks/resolve_tagging_secret_strategy.d.ts.map +1 -1
- package/dest/hooks/resolve_tagging_secret_strategy.js +3 -3
- 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 +12 -3
- package/dest/messages/tx_resolver_service.d.ts +2 -2
- package/dest/messages/tx_resolver_service.d.ts.map +1 -1
- package/dest/messages/tx_resolver_service.js +7 -2
- package/dest/notes/note_service.d.ts +1 -1
- package/dest/notes/note_service.js +1 -1
- package/dest/oracle_version.d.ts +2 -2
- package/dest/oracle_version.js +3 -3
- package/dest/pxe.d.ts +1 -1
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +8 -5
- package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts +1 -1
- package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts.map +1 -1
- package/dest/storage/backwards_compatibility_tests/schema_tests.js +26 -2
- package/dest/storage/fact_store/index.d.ts +2 -2
- package/dest/storage/fact_store/index.d.ts.map +1 -1
- package/dest/storage/fact_store/index.js +1 -1
- package/dest/storage/fact_store/origin_state.d.ts +3 -1
- package/dest/storage/fact_store/origin_state.d.ts.map +1 -1
- package/dest/storage/fact_store/origin_state.js +7 -0
- package/dest/storage/metadata.d.ts +1 -1
- package/dest/storage/metadata.js +1 -1
- package/dest/storage/store_identity.d.ts +35 -0
- package/dest/storage/store_identity.d.ts.map +1 -0
- package/dest/storage/store_identity.js +44 -0
- package/dest/storage/tagging_store/sender_tagging_store.d.ts +19 -3
- package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/sender_tagging_store.js +48 -11
- package/dest/tagging/constants.d.ts +3 -2
- package/dest/tagging/constants.d.ts.map +1 -1
- package/dest/tagging/constants.js +26 -5
- package/dest/tagging/index.d.ts +2 -2
- package/dest/tagging/index.d.ts.map +1 -1
- package/dest/tagging/index.js +1 -1
- package/dest/tagging/recipient_sync/sync_tagged_private_logs.d.ts +9 -4
- package/dest/tagging/recipient_sync/sync_tagged_private_logs.d.ts.map +1 -1
- package/dest/tagging/recipient_sync/sync_tagged_private_logs.js +60 -25
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +1 -1
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +1 -1
- 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 +6 -2
- package/dest/tagging/testing/tag_query_test_utils.d.ts +6 -0
- package/dest/tagging/testing/tag_query_test_utils.d.ts.map +1 -0
- package/dest/tagging/testing/tag_query_test_utils.js +10 -0
- package/package.json +17 -17
- package/src/bin/check_oracle_version.ts +3 -10
- package/src/bin/index.ts +1 -5
- package/src/bin/oracle_version_helpers.ts +11 -268
- package/src/contract/helpers.ts +3 -3
- package/src/contract/skip_sync_contracts.ts +23 -0
- package/src/contract_function_simulator/aztec_node_read_cache.ts +89 -0
- package/src/contract_function_simulator/index.ts +23 -3
- package/src/contract_function_simulator/noir-structs/resolved_tagging_strategy.ts +8 -0
- package/src/contract_function_simulator/noir-structs/resolved_tx.ts +11 -45
- package/src/contract_function_simulator/noir-structs/tx_effect_data.ts +4 -3
- package/src/contract_function_simulator/oracle/acir_callback.ts +1 -1
- package/src/contract_function_simulator/oracle/legacy_oracle_registry.ts +30 -3
- package/src/contract_function_simulator/oracle/oracle_registry.ts +32 -11
- package/src/contract_function_simulator/oracle/oracle_type_mappings.ts +285 -197
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +17 -12
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +92 -39
- package/src/entrypoints/client/bundle/index.ts +1 -0
- package/src/entrypoints/client/bundle/utils.ts +15 -3
- package/src/entrypoints/client/lazy/index.ts +1 -0
- package/src/entrypoints/client/lazy/utils.ts +15 -3
- package/src/entrypoints/client/store.ts +54 -0
- package/src/entrypoints/server/index.ts +1 -0
- package/src/entrypoints/server/store.ts +47 -0
- package/src/entrypoints/server/utils.ts +21 -7
- package/src/hooks/index.ts +1 -0
- package/src/hooks/resolve_tagging_secret_strategy.ts +3 -0
- package/src/logs/log_service.ts +11 -2
- package/src/messages/tx_resolver_service.ts +8 -8
- package/src/notes/note_service.ts +1 -1
- package/src/oracle_version.ts +3 -3
- package/src/pxe.ts +8 -5
- package/src/storage/backwards_compatibility_tests/__snapshots__/RecipientTaggingStore.json +11 -3
- package/src/storage/backwards_compatibility_tests/__snapshots__/SenderTaggingStore.json +12 -4
- package/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json +1 -1
- package/src/storage/backwards_compatibility_tests/schema_tests.ts +30 -1
- package/src/storage/fact_store/index.ts +1 -0
- package/src/storage/fact_store/origin_state.ts +9 -0
- package/src/storage/metadata.ts +1 -1
- package/src/storage/store_identity.ts +72 -0
- package/src/storage/tagging_store/sender_tagging_store.ts +62 -15
- package/src/tagging/constants.ts +27 -5
- package/src/tagging/index.ts +1 -1
- package/src/tagging/recipient_sync/sync_tagged_private_logs.ts +103 -46
- package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +1 -1
- package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +6 -2
- package/src/tagging/testing/tag_query_test_utils.ts +11 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import { isDefined } from '@aztec/foundation/types';
|
|
3
3
|
import { AppTaggingSecretKind, SiloedTag } from '@aztec/stdlib/logs';
|
|
4
|
-
import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../constants.js';
|
|
4
|
+
import { INITIAL_CONSTRAINED_PROBE_LEN, UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../constants.js';
|
|
5
5
|
import { getAllPrivateLogsByTags } from '../get_all_logs_by_tags.js';
|
|
6
6
|
import { findHighestIndexes } from './utils/find_highest_indexes.js';
|
|
7
7
|
/**
|
|
@@ -55,9 +55,14 @@ import { findHighestIndexes } from './utils/find_highest_indexes.js';
|
|
|
55
55
|
* - The lower bound is `highestFinalizedIndex + 1`. The `highestAgedIndex` mechanism is unnecessary because
|
|
56
56
|
* the nullifier chain prevents out-of-order index usage: no device can fill in a lower index after a higher
|
|
57
57
|
* one is already on-chain.
|
|
58
|
-
* -
|
|
59
|
-
*
|
|
60
|
-
*
|
|
58
|
+
* - Because the sequence is gapless, the scan stops at the first missing index: that gap proves the sequence has
|
|
59
|
+
* ended and no further logs exist. We exploit this with a doubling first-miss probe (see
|
|
60
|
+
* `INITIAL_CONSTRAINED_PROBE_LEN` in ../constants.ts), so a
|
|
61
|
+
* steady-state sync with no new logs costs two tags instead of the whole window. The probe length is in-memory
|
|
62
|
+
* state scoped to one sync call, so every sync restarts at the initial probe.
|
|
63
|
+
* - The upper bound is the same as unconstrained: `highestFinalizedIndex + WINDOW_LEN`. Advancing the probe is
|
|
64
|
+
* decoupled from persisting the finalized index, so unfinalized logs at the top of the run are still fetched
|
|
65
|
+
* while only the finalized prefix is persisted.
|
|
61
66
|
*
|
|
62
67
|
* # Batching across secrets
|
|
63
68
|
*
|
|
@@ -87,8 +92,7 @@ import { findHighestIndexes } from './utils/find_highest_indexes.js';
|
|
|
87
92
|
allLogs.push(...logsFoundWithSecret.map(({ log })=>log));
|
|
88
93
|
// Persist new indexes. If the finalized index moved forward, the window advances
|
|
89
94
|
// and we need another round for this secret.
|
|
90
|
-
|
|
91
|
-
return await processForKind(pendingSecret, logsFoundWithSecret, taggingStore, currentTimestamp, finalizedBlockNumber, jobId);
|
|
95
|
+
return pendingSecret.kind === AppTaggingSecretKind.CONSTRAINED ? await processConstrainedResults(pendingSecret, logsFoundWithSecret, taggingStore, currentTimestamp, finalizedBlockNumber, jobId) : await processUnconstrainedResults(pendingSecret, logsFoundWithSecret, taggingStore, currentTimestamp, finalizedBlockNumber, jobId);
|
|
92
96
|
}));
|
|
93
97
|
pending = nextRound.filter(isDefined);
|
|
94
98
|
}
|
|
@@ -97,13 +101,29 @@ import { findHighestIndexes } from './utils/find_highest_indexes.js';
|
|
|
97
101
|
/** Reads stored indexes for each secret and computes the initial index range to query. */ function getIndexRangesForSecrets(secrets, taggingStore, jobId) {
|
|
98
102
|
return Promise.all(secrets.map(async (secret)=>{
|
|
99
103
|
const currentHighestFinalizedIndex = await taggingStore.getHighestFinalizedIndex(secret, jobId);
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
104
|
+
const boundEnd = (currentHighestFinalizedIndex ?? 0) + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN + 1;
|
|
105
|
+
if (secret.kind === AppTaggingSecretKind.CONSTRAINED) {
|
|
106
|
+
// Constrained streams are gapless and resume at the finalized index, so probe a small initial window and stop
|
|
107
|
+
// at the first missing tag instead of always fetching the full window. The probe grows each round up to the
|
|
108
|
+
// window cap.
|
|
109
|
+
const start = currentHighestFinalizedIndex === undefined ? 0 : currentHighestFinalizedIndex + 1;
|
|
110
|
+
return {
|
|
111
|
+
kind: AppTaggingSecretKind.CONSTRAINED,
|
|
112
|
+
secret,
|
|
113
|
+
start,
|
|
114
|
+
end: Math.min(boundEnd, start + INITIAL_CONSTRAINED_PROBE_LEN),
|
|
115
|
+
boundEnd,
|
|
116
|
+
probeLen: INITIAL_CONSTRAINED_PROBE_LEN
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// Unconstrained secrets can have gaps, so they scan the whole window starting past the highest aged index.
|
|
120
|
+
const highestAgedIndex = await taggingStore.getHighestAgedIndex(secret, jobId);
|
|
121
|
+
const start = highestAgedIndex === undefined ? 0 : highestAgedIndex + 1;
|
|
103
122
|
return {
|
|
123
|
+
kind: AppTaggingSecretKind.UNCONSTRAINED,
|
|
104
124
|
secret,
|
|
105
125
|
start,
|
|
106
|
-
end
|
|
126
|
+
end: boundEnd
|
|
107
127
|
};
|
|
108
128
|
}));
|
|
109
129
|
}
|
|
@@ -148,30 +168,43 @@ import { findHighestIndexes } from './utils/find_highest_indexes.js';
|
|
|
148
168
|
return logsPerSecret;
|
|
149
169
|
}
|
|
150
170
|
/**
|
|
151
|
-
* Processes fetched logs for a constrained secret
|
|
152
|
-
*
|
|
171
|
+
* Processes fetched logs for a constrained secret: persists the finalized index and advances the probe. See the
|
|
172
|
+
* "# Constrained secrets" section above for why the scan stops at the first missing index. Only `highestFinalizedIndex`
|
|
153
173
|
* is tracked (no aged index).
|
|
154
174
|
*/ async function processConstrainedResults(pending, logsWithIndexes, taggingStore, currentTimestamp, finalizedBlockNumber, jobId) {
|
|
155
|
-
// Find where the contiguous run of indexes ends
|
|
156
|
-
// first gap, so all logs in the batch are within this prefix.
|
|
175
|
+
// Find where the contiguous run of indexes ends; all logs in the batch fall within this prefix.
|
|
157
176
|
const indexesWithLogs = new Set(logsWithIndexes.map((l)=>l.taggingIndex));
|
|
158
177
|
let firstMissingIndex = pending.start;
|
|
159
178
|
while(firstMissingIndex < pending.end && indexesWithLogs.has(firstMissingIndex)){
|
|
160
179
|
firstMissingIndex++;
|
|
161
180
|
}
|
|
162
|
-
//
|
|
163
|
-
// transaction, guaranteeing the log cannot disappear once included, so we persist the
|
|
164
|
-
//
|
|
181
|
+
// Persist the highest finalized index found. The nullifier for a constrained-delivery log is emitted in the same
|
|
182
|
+
// transaction, guaranteeing the log cannot disappear once included, so we persist even when a gap stops the scan.
|
|
183
|
+
// This lets the next sync round skip already-finalized indexes.
|
|
165
184
|
const { highestFinalizedIndex } = findHighestIndexes(logsWithIndexes, currentTimestamp, finalizedBlockNumber);
|
|
166
185
|
if (highestFinalizedIndex !== undefined) {
|
|
167
186
|
await taggingStore.updateHighestFinalizedIndex(pending.secret, highestFinalizedIndex, jobId);
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
187
|
+
}
|
|
188
|
+
// Advancing the probe is decoupled from persisting the finalized index: keep scanning as long as the probe was
|
|
189
|
+
// entirely hits (no gap) and there is room before the protocol bound, even if none of those hits is finalized yet.
|
|
190
|
+
// Gating this on finalization would drop logs in unfinalized blocks, which sit at the top of the contiguous run.
|
|
191
|
+
// The bound re-anchors to any finalized index found this round.
|
|
192
|
+
const probeFullyConsumed = firstMissingIndex >= pending.end;
|
|
193
|
+
const boundEnd = highestFinalizedIndex !== undefined ? Math.max(pending.boundEnd, highestFinalizedIndex + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN + 1) : pending.boundEnd;
|
|
194
|
+
// Double the probe each round, capped at the window (see INITIAL_CONSTRAINED_PROBE_LEN in ../constants.ts).
|
|
195
|
+
// The queried range is already bounded by boundEnd (a probe can never reach
|
|
196
|
+
// more than WINDOW_LEN past the finalized frontier); this cap just keeps the stored length from growing unbounded
|
|
197
|
+
// once the probe saturates the window.
|
|
198
|
+
const nextProbeLen = Math.min(pending.probeLen * 2, UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN);
|
|
199
|
+
if (probeFullyConsumed && pending.end < boundEnd) {
|
|
200
|
+
return {
|
|
201
|
+
kind: AppTaggingSecretKind.CONSTRAINED,
|
|
202
|
+
secret: pending.secret,
|
|
203
|
+
start: pending.end,
|
|
204
|
+
end: Math.min(boundEnd, pending.end + nextProbeLen),
|
|
205
|
+
boundEnd,
|
|
206
|
+
probeLen: nextProbeLen
|
|
207
|
+
};
|
|
175
208
|
}
|
|
176
209
|
return undefined;
|
|
177
210
|
}
|
|
@@ -195,9 +228,11 @@ import { findHighestIndexes } from './utils/find_highest_indexes.js';
|
|
|
195
228
|
await taggingStore.updateHighestFinalizedIndex(pending.secret, highestFinalizedIndex, jobId);
|
|
196
229
|
// For the next iteration we want to look only at indexes for which we have not yet fetched logs while
|
|
197
230
|
// ensuring that we do not look further than WINDOW_LEN ahead of the highest finalized index.
|
|
231
|
+
const end = highestFinalizedIndex + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN + 1;
|
|
198
232
|
return {
|
|
233
|
+
kind: AppTaggingSecretKind.UNCONSTRAINED,
|
|
199
234
|
secret: pending.secret,
|
|
200
235
|
start: pending.end,
|
|
201
|
-
end
|
|
236
|
+
end
|
|
202
237
|
};
|
|
203
238
|
}
|
|
@@ -48,7 +48,7 @@ import { loadAndStoreNewTaggingIndexes } from './utils/load_and_store_new_taggin
|
|
|
48
48
|
break;
|
|
49
49
|
}
|
|
50
50
|
// Receipts for pending tx hashes that the logs query just surfaced still need a sequential follow-up call.
|
|
51
|
-
// `
|
|
51
|
+
// `mergePendingIndexes` is idempotent on (secret, txHash), so a re-discovered hash stays classified as known
|
|
52
52
|
// and is not re-fetched here.
|
|
53
53
|
const knownSet = new Set(knownPendingTxHashes.map((h)=>h.toString()));
|
|
54
54
|
const newPendingTxHashes = allPendingTxHashes.filter((h)=>!knownSet.has(h.toString()));
|
|
@@ -16,4 +16,4 @@ import type { SenderTaggingStore } from '../../../storage/tagging_store/sender_t
|
|
|
16
16
|
* preserving way.
|
|
17
17
|
*/
|
|
18
18
|
export declare function loadAndStoreNewTaggingIndexes(extendedSecret: AppTaggingSecret, start: number, end: number, aztecNode: AztecNode, taggingStore: SenderTaggingStore, anchorBlockHash: BlockHash, jobId: string): Promise<void>;
|
|
19
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
19
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZF9hbmRfc3RvcmVfbmV3X3RhZ2dpbmdfaW5kZXhlcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3RhZ2dpbmcvc2VuZGVyX3N5bmMvdXRpbHMvbG9hZF9hbmRfc3RvcmVfbmV3X3RhZ2dpbmdfaW5kZXhlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsS0FBSyxnQkFBZ0IsRUFBYSxNQUFNLG9CQUFvQixDQUFDO0FBR3RFLE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0RBQXdELENBQUM7QUFHakc7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsd0JBQXNCLDZCQUE2QixDQUNqRCxjQUFjLEVBQUUsZ0JBQWdCLEVBQ2hDLEtBQUssRUFBRSxNQUFNLEVBQ2IsR0FBRyxFQUFFLE1BQU0sRUFDWCxTQUFTLEVBQUUsU0FBUyxFQUNwQixZQUFZLEVBQUUsa0JBQWtCLEVBQ2hDLGVBQWUsRUFBRSxTQUFTLEVBQzFCLEtBQUssRUFBRSxNQUFNLGlCQW9CZCJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load_and_store_new_tagging_indexes.d.ts","sourceRoot":"","sources":["../../../../src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,KAAK,gBAAgB,EAAa,MAAM,oBAAoB,CAAC;AAGtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wDAAwD,CAAC;AAGjG;;;;;;;;;;;;GAYG;AACH,wBAAsB,6BAA6B,CACjD,cAAc,EAAE,gBAAgB,EAChC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,kBAAkB,EAChC,eAAe,EAAE,SAAS,EAC1B,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"load_and_store_new_tagging_indexes.d.ts","sourceRoot":"","sources":["../../../../src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,KAAK,gBAAgB,EAAa,MAAM,oBAAoB,CAAC;AAGtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wDAAwD,CAAC;AAGjG;;;;;;;;;;;;GAYG;AACH,wBAAsB,6BAA6B,CACjD,cAAc,EAAE,gBAAgB,EAChC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,kBAAkB,EAChC,eAAe,EAAE,SAAS,EAC1B,KAAK,EAAE,MAAM,iBAoBd"}
|
|
@@ -23,7 +23,11 @@ import { getAllPrivateLogsByTags } from '../../get_all_logs_by_tags.js';
|
|
|
23
23
|
})));
|
|
24
24
|
const txsForTags = await getTxsContainingTags(siloedTagsForWindow, aztecNode, anchorBlockHash);
|
|
25
25
|
const txIndexesMap = getTxIndexesMap(txsForTags, start, siloedTagsForWindow.length);
|
|
26
|
-
// Now we iterate over the map, construct the tagging index ranges and store them in the db.
|
|
26
|
+
// Now we iterate over the map, construct the tagging index ranges and store them in the db. A tx already tracked
|
|
27
|
+
// in the store is merged rather than range-checked: if this PXE sent the tx and it partially reverted, the chain
|
|
28
|
+
// only shows the surviving sub-range of the prove-time entry (the finalized receipt step of the sync owns
|
|
29
|
+
// resolving that difference), and a tx from another PXE may straddle a sync window boundary, in which case the
|
|
30
|
+
// entry is widened so the next index choice covers the full onchain range.
|
|
27
31
|
for (const [txHashStr, indexes] of txIndexesMap.entries()){
|
|
28
32
|
const txHash = TxHash.fromString(txHashStr);
|
|
29
33
|
const ranges = [
|
|
@@ -33,7 +37,7 @@ import { getAllPrivateLogsByTags } from '../../get_all_logs_by_tags.js';
|
|
|
33
37
|
highestIndex: Math.max(...indexes)
|
|
34
38
|
}
|
|
35
39
|
];
|
|
36
|
-
await taggingStore.
|
|
40
|
+
await taggingStore.mergePendingIndexes(ranges, txHash, jobId);
|
|
37
41
|
}
|
|
38
42
|
}
|
|
39
43
|
// Returns txs that used the given tags. A tag might have been used in multiple txs and for this reason we return
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type AppTaggingSecret, type PrivateLogsQuery, SiloedTag } from '@aztec/stdlib/logs';
|
|
2
|
+
/** Computes the siloed tag */
|
|
3
|
+
export declare function computeSiloedTagForIndex(secret: AppTaggingSecret, index: number): Promise<SiloedTag>;
|
|
4
|
+
/** Extracts the bare-tag set from a query */
|
|
5
|
+
export declare function extractTags(query: PrivateLogsQuery): SiloedTag[];
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFnX3F1ZXJ5X3Rlc3RfdXRpbHMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90YWdnaW5nL3Rlc3RpbmcvdGFnX3F1ZXJ5X3Rlc3RfdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssZ0JBQWdCLEVBQUUsS0FBSyxnQkFBZ0IsRUFBRSxTQUFTLEVBQWlCLE1BQU0sb0JBQW9CLENBQUM7QUFFNUcsOEJBQThCO0FBQzlCLHdCQUFnQix3QkFBd0IsQ0FBQyxNQUFNLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBRXBHO0FBRUQsNkNBQTZDO0FBQzdDLHdCQUFnQixXQUFXLENBQUMsS0FBSyxFQUFFLGdCQUFnQixHQUFHLFNBQVMsRUFBRSxDQUVoRSJ9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tag_query_test_utils.d.ts","sourceRoot":"","sources":["../../../src/tagging/testing/tag_query_test_utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,SAAS,EAAiB,MAAM,oBAAoB,CAAC;AAE5G,8BAA8B;AAC9B,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAEpG;AAED,6CAA6C;AAC7C,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,SAAS,EAAE,CAEhE"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SiloedTag } from '@aztec/stdlib/logs';
|
|
2
|
+
/** Computes the siloed tag */ export function computeSiloedTagForIndex(secret, index) {
|
|
3
|
+
return SiloedTag.compute({
|
|
4
|
+
extendedSecret: secret,
|
|
5
|
+
index
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
/** Extracts the bare-tag set from a query */ export function extractTags(query) {
|
|
9
|
+
return query.tags.map((entry)=>entry instanceof SiloedTag ? entry : entry.tag);
|
|
10
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/pxe",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.be03c316",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"typedocOptions": {
|
|
6
6
|
"entryPoints": [
|
|
@@ -71,20 +71,20 @@
|
|
|
71
71
|
]
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
|
-
"@aztec/bb-prover": "0.0.1-commit.
|
|
75
|
-
"@aztec/bb.js": "0.0.1-commit.
|
|
76
|
-
"@aztec/builder": "0.0.1-commit.
|
|
77
|
-
"@aztec/constants": "0.0.1-commit.
|
|
78
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
79
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
80
|
-
"@aztec/key-store": "0.0.1-commit.
|
|
81
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
82
|
-
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.
|
|
83
|
-
"@aztec/noir-types": "0.0.1-commit.
|
|
84
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
85
|
-
"@aztec/simulator": "0.0.1-commit.
|
|
86
|
-
"@aztec/standard-contracts": "0.0.1-commit.
|
|
87
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
74
|
+
"@aztec/bb-prover": "0.0.1-commit.be03c316",
|
|
75
|
+
"@aztec/bb.js": "0.0.1-commit.be03c316",
|
|
76
|
+
"@aztec/builder": "0.0.1-commit.be03c316",
|
|
77
|
+
"@aztec/constants": "0.0.1-commit.be03c316",
|
|
78
|
+
"@aztec/ethereum": "0.0.1-commit.be03c316",
|
|
79
|
+
"@aztec/foundation": "0.0.1-commit.be03c316",
|
|
80
|
+
"@aztec/key-store": "0.0.1-commit.be03c316",
|
|
81
|
+
"@aztec/kv-store": "0.0.1-commit.be03c316",
|
|
82
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.be03c316",
|
|
83
|
+
"@aztec/noir-types": "0.0.1-commit.be03c316",
|
|
84
|
+
"@aztec/protocol-contracts": "0.0.1-commit.be03c316",
|
|
85
|
+
"@aztec/simulator": "0.0.1-commit.be03c316",
|
|
86
|
+
"@aztec/standard-contracts": "0.0.1-commit.be03c316",
|
|
87
|
+
"@aztec/stdlib": "0.0.1-commit.be03c316",
|
|
88
88
|
"koa": "^2.16.1",
|
|
89
89
|
"koa-router": "^13.1.1",
|
|
90
90
|
"lodash.omit": "^4.5.0",
|
|
@@ -93,8 +93,8 @@
|
|
|
93
93
|
"viem": "npm:@aztec/viem@2.38.2"
|
|
94
94
|
},
|
|
95
95
|
"devDependencies": {
|
|
96
|
-
"@aztec/noir-test-contracts.js": "0.0.1-commit.
|
|
97
|
-
"@aztec/world-state": "0.0.1-commit.
|
|
96
|
+
"@aztec/noir-test-contracts.js": "0.0.1-commit.be03c316",
|
|
97
|
+
"@aztec/world-state": "0.0.1-commit.be03c316",
|
|
98
98
|
"@jest/globals": "^30.0.0",
|
|
99
99
|
"@types/jest": "^30.0.0",
|
|
100
100
|
"@types/lodash.omit": "^4.5.7",
|
|
@@ -3,6 +3,7 @@ import { keccak256String } from '@aztec/foundation/crypto/keccak';
|
|
|
3
3
|
import { dirname, join } from 'path';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
|
|
6
|
+
import { ORACLE_REGISTRY } from '../contract_function_simulator/index.js';
|
|
6
7
|
import { ORACLE_INTERFACE_HASH, ORACLE_VERSION_MAJOR } from '../oracle_version.js';
|
|
7
8
|
import { getOracleRegistrySignature, readNumericGlobal } from './oracle_version_helpers.js';
|
|
8
9
|
|
|
@@ -10,7 +11,7 @@ import { getOracleRegistrySignature, readNumericGlobal } from './oracle_version_
|
|
|
10
11
|
* Verifies that the Oracle interface matches the expected interface hash.
|
|
11
12
|
*
|
|
12
13
|
* The Oracle interface needs to be versioned to ensure compatibility between Aztec.nr and PXE. This function computes
|
|
13
|
-
* a hash of
|
|
14
|
+
* a hash of `ORACLE_REGISTRY` (where each oracle's parameter names, parameter types, and return type
|
|
14
15
|
* live) and compares it against a known hash. If they don't match, it means the interface has changed and the oracle
|
|
15
16
|
* version needs to be bumped:
|
|
16
17
|
* - If the change is backward-breaking (e.g. removing/renaming an oracle, or changing its params/return), bump
|
|
@@ -18,16 +19,8 @@ import { getOracleRegistrySignature, readNumericGlobal } from './oracle_version_
|
|
|
18
19
|
* - If the change is an oracle addition (non-breaking), bump ORACLE_VERSION_MINOR.
|
|
19
20
|
*/
|
|
20
21
|
function assertOracleInterfaceMatches(): void {
|
|
21
|
-
// The script runs from dest/bin/ after compilation, so we go up to the package root then into src/ to find
|
|
22
|
-
// the source file.
|
|
23
|
-
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
24
|
-
const packageRoot = dirname(dirname(currentDir)); // Go up from bin/ to pxe/
|
|
25
|
-
const registrySourcePath = join(packageRoot, 'src/contract_function_simulator/oracle/oracle_registry.ts');
|
|
26
|
-
|
|
27
|
-
const oracleInterfaceSignature = getOracleRegistrySignature(registrySourcePath, 'ORACLE_REGISTRY');
|
|
28
|
-
|
|
29
22
|
// We use keccak256 here just because we already have it in the dependencies.
|
|
30
|
-
const oracleInterfaceHash = keccak256String(
|
|
23
|
+
const oracleInterfaceHash = keccak256String(getOracleRegistrySignature(ORACLE_REGISTRY));
|
|
31
24
|
if (oracleInterfaceHash !== ORACLE_INTERFACE_HASH) {
|
|
32
25
|
throw new Error(
|
|
33
26
|
`The Oracle interface has changed. Update ORACLE_INTERFACE_HASH to ${oracleInterfaceHash} in pxe/src/oracle_version.ts and bump the oracle version (ORACLE_VERSION_MAJOR for breaking changes, ORACLE_VERSION_MINOR for oracle additions).`,
|
package/src/bin/index.ts
CHANGED
|
@@ -1,75 +1,13 @@
|
|
|
1
|
-
/* eslint-disable import-x/no-named-as-default-member */
|
|
2
1
|
import { readFileSync } from 'fs';
|
|
3
|
-
import ts from 'typescript';
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
* Extracts method signatures from TypeScript classes or interfaces and returns a deterministic string representation.
|
|
7
|
-
*
|
|
8
|
-
* This is used to detect when an oracle interface changes so that the oracle version can be bumped. It works with both
|
|
9
|
-
* class declarations (e.g. PXE's `Oracle` class) and interface declarations (e.g. TXE's `IAvmExecutionOracle`).
|
|
10
|
-
*
|
|
11
|
-
* @param sourcePath - Absolute path to the TypeScript source file to parse.
|
|
12
|
-
* @param targets - Names of classes or interfaces to extract methods from.
|
|
13
|
-
* @param excludedMembers - Method names to skip (e.g. non-oracle helpers like `constructor`).
|
|
14
|
-
*/
|
|
15
|
-
export function getOracleInterfaceSignature(sourcePath: string, targets: string[], excludedMembers: string[]): string {
|
|
16
|
-
const sourceCode = readFileSync(sourcePath, 'utf-8');
|
|
17
|
-
const sourceFile = ts.createSourceFile(sourcePath, sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
18
|
-
|
|
19
|
-
const methodSignatures: string[] = [];
|
|
20
|
-
|
|
21
|
-
function visit(node: ts.Node) {
|
|
22
|
-
const isTarget =
|
|
23
|
-
(ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)) && targets.includes(node.name?.text ?? '');
|
|
24
|
-
|
|
25
|
-
if (isTarget) {
|
|
26
|
-
node.members.forEach(member => {
|
|
27
|
-
if (
|
|
28
|
-
(ts.isMethodDeclaration(member) || ts.isMethodSignature(member)) &&
|
|
29
|
-
member.name &&
|
|
30
|
-
ts.isIdentifier(member.name)
|
|
31
|
-
) {
|
|
32
|
-
const methodName = member.name.text;
|
|
33
|
-
|
|
34
|
-
if (excludedMembers.includes(methodName)) {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const paramSignatures: string[] = [];
|
|
39
|
-
member.parameters.forEach(param => {
|
|
40
|
-
const paramName = extractParameterName(param, sourceFile);
|
|
41
|
-
const paramType = extractTypeString(param.type, sourceFile);
|
|
42
|
-
paramSignatures.push(`${paramName}: ${paramType}`);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
const returnType = extractTypeString(member.type, sourceFile);
|
|
46
|
-
|
|
47
|
-
const signature = `${methodName}(${paramSignatures.join(', ')}): ${returnType}`;
|
|
48
|
-
methodSignatures.push(signature);
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
ts.forEachChild(node, visit);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
visit(sourceFile);
|
|
57
|
-
|
|
58
|
-
methodSignatures.sort();
|
|
59
|
-
|
|
60
|
-
return methodSignatures.join('');
|
|
61
|
-
}
|
|
3
|
+
import type { OracleRegistryEntry } from '../contract_function_simulator/index.js';
|
|
62
4
|
|
|
63
5
|
/**
|
|
64
|
-
* Extracts a deterministic signature string from an oracle registry
|
|
65
|
-
*
|
|
66
|
-
* Reads the registry declaration where each oracle's wire ABI lives: the ordered parameter names with their
|
|
67
|
-
* `TypeMapping` expressions and the return type. The resulting hash is sensitive to parameter, type, and return
|
|
68
|
-
* changes, not just oracle additions and removals.
|
|
6
|
+
* Extracts a deterministic signature string from an oracle registry (e.g. PXE's `ORACLE_REGISTRY`).
|
|
69
7
|
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
8
|
+
* Reads the registry where each oracle's wire ABI lives: the ordered parameter names with their `TypeMapping` labels
|
|
9
|
+
* and the return type. The resulting hash is sensitive to parameter, type, and return changes, not just oracle
|
|
10
|
+
* additions and removals.
|
|
73
11
|
*
|
|
74
12
|
* @example
|
|
75
13
|
* // Given a registry like:
|
|
@@ -79,32 +17,13 @@ export function getOracleInterfaceSignature(sourcePath: string, targets: string[
|
|
|
79
17
|
* // } satisfies Record<string, OracleRegistryEntry>;
|
|
80
18
|
* //
|
|
81
19
|
* // Returns (sorted, newline-joined):
|
|
82
|
-
* // "aztec_prv_bar(): void\naztec_utl_foo(a:
|
|
83
|
-
*
|
|
84
|
-
* @param sourcePath - Absolute path to the TypeScript source file declaring the registry.
|
|
85
|
-
* @param registryName - Name of the registry constant to read (e.g. `ORACLE_REGISTRY`).
|
|
20
|
+
* // "aztec_prv_bar(): void\naztec_utl_foo(a: u32): bool"
|
|
86
21
|
*/
|
|
87
|
-
export function getOracleRegistrySignature(
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (!registry) {
|
|
93
|
-
throw new Error(`Could not find oracle registry '${registryName}' in ${sourcePath}.`);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const oracleSignatures = registry.properties.map(property => {
|
|
97
|
-
if (!ts.isPropertyAssignment(property)) {
|
|
98
|
-
throw new Error(
|
|
99
|
-
`Unexpected member in oracle registry '${registryName}': ${property.getText(sourceFile)}. Spread elements ` +
|
|
100
|
-
`are not supported.`,
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const oracleName = getPropertyName(property.name, sourceFile);
|
|
105
|
-
const { params, returnType } = extractRegistryEntry(property.initializer, sourceFile);
|
|
106
|
-
const paramSignatures = params.map(param => `${param.name}: ${param.type}`);
|
|
107
|
-
return `${oracleName}(${paramSignatures.join(', ')}): ${returnType}`;
|
|
22
|
+
export function getOracleRegistrySignature(registry: Record<string, OracleRegistryEntry>): string {
|
|
23
|
+
const oracleSignatures = Object.entries(registry).map(([name, entry]) => {
|
|
24
|
+
const paramSignatures = entry.params.map(p => `${p.name}: ${p.type.label}`);
|
|
25
|
+
const returnType = entry.returnType === undefined ? 'void' : entry.returnType.label;
|
|
26
|
+
return `${name}(${paramSignatures.join(', ')}): ${returnType}`;
|
|
108
27
|
});
|
|
109
28
|
|
|
110
29
|
oracleSignatures.sort();
|
|
@@ -133,179 +52,3 @@ export function readNumericGlobal(sourcePath: string, name: string): number {
|
|
|
133
52
|
}
|
|
134
53
|
return Number(match[1]);
|
|
135
54
|
}
|
|
136
|
-
|
|
137
|
-
function extractParameterName(param: ts.ParameterDeclaration, sourceFile: ts.SourceFile): string {
|
|
138
|
-
const name = param.name;
|
|
139
|
-
|
|
140
|
-
if (ts.isIdentifier(name)) {
|
|
141
|
-
return name.text;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (ts.isArrayBindingPattern(name)) {
|
|
145
|
-
if (name.elements.length > 0) {
|
|
146
|
-
const element = name.elements[0];
|
|
147
|
-
if (ts.isBindingElement(element)) {
|
|
148
|
-
const elementName = element.name;
|
|
149
|
-
if (ts.isIdentifier(elementName)) {
|
|
150
|
-
return elementName.text;
|
|
151
|
-
}
|
|
152
|
-
if (ts.isArrayBindingPattern(elementName) || ts.isObjectBindingPattern(elementName)) {
|
|
153
|
-
return elementName.getText(sourceFile);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
return name.getText(sourceFile);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (ts.isObjectBindingPattern(name)) {
|
|
161
|
-
return name.getText(sourceFile);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return (name as ts.Node).getText(sourceFile);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/** Returns the source text of a type annotation, or `'void'` if absent. */
|
|
168
|
-
function extractTypeString(typeNode: ts.TypeNode | undefined, sourceFile: ts.SourceFile): string {
|
|
169
|
-
if (!typeNode) {
|
|
170
|
-
return 'void';
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return typeNode.getText(sourceFile).replace(/\s+/g, ' ').trim();
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Finds a top-level object-literal-valued constant by name, unwrapping `satisfies`/`as`/parenthesized wrappers.
|
|
178
|
-
*
|
|
179
|
-
* @example
|
|
180
|
-
* // `const REGISTRY = { ... } satisfies Record<string, Entry>` => the `{ ... }` ObjectLiteralExpression
|
|
181
|
-
*/
|
|
182
|
-
function findObjectLiteral(sourceFile: ts.SourceFile, name: string): ts.ObjectLiteralExpression | undefined {
|
|
183
|
-
let result: ts.ObjectLiteralExpression | undefined;
|
|
184
|
-
|
|
185
|
-
function visit(node: ts.Node) {
|
|
186
|
-
if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.name.text === name && node.initializer) {
|
|
187
|
-
result = unwrapObjectLiteral(node.initializer);
|
|
188
|
-
}
|
|
189
|
-
ts.forEachChild(node, visit);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
visit(sourceFile);
|
|
193
|
-
return result;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/** Peels `satisfies`, `as`, and parenthesized wrappers off an expression to reach the underlying object literal. */
|
|
197
|
-
function unwrapObjectLiteral(node: ts.Expression): ts.ObjectLiteralExpression | undefined {
|
|
198
|
-
let current = node;
|
|
199
|
-
while (ts.isSatisfiesExpression(current) || ts.isAsExpression(current) || ts.isParenthesizedExpression(current)) {
|
|
200
|
-
current = current.expression;
|
|
201
|
-
}
|
|
202
|
-
return ts.isObjectLiteralExpression(current) ? current : undefined;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Extracts the ordered `params` (names + type expressions) and `returnType` from a `makeEntry({ ... })` call.
|
|
207
|
-
*
|
|
208
|
-
* @example
|
|
209
|
-
* // makeEntry({ params: [{ name: 'a', type: OPTION(FIELD) }], returnType: BOOL })
|
|
210
|
-
* // => { params: [{ name: 'a', type: 'OPTION(FIELD)' }], returnType: 'BOOL' }
|
|
211
|
-
* //
|
|
212
|
-
* // makeEntry()
|
|
213
|
-
* // => { params: [], returnType: 'void' }
|
|
214
|
-
*/
|
|
215
|
-
function extractRegistryEntry(
|
|
216
|
-
initializer: ts.Expression,
|
|
217
|
-
sourceFile: ts.SourceFile,
|
|
218
|
-
): { params: { name: string; type: string }[]; returnType: string } {
|
|
219
|
-
if (!ts.isCallExpression(initializer)) {
|
|
220
|
-
throw new Error(`Expected a makeEntry(...) call but got: ${initializer.getText(sourceFile)}`);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
const [arg] = initializer.arguments;
|
|
224
|
-
if (arg === undefined) {
|
|
225
|
-
return { params: [], returnType: 'void' };
|
|
226
|
-
}
|
|
227
|
-
if (!ts.isObjectLiteralExpression(arg)) {
|
|
228
|
-
throw new Error(`Expected a makeEntry object argument but got: ${arg.getText(sourceFile)}`);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
let params: { name: string; type: string }[] = [];
|
|
232
|
-
let returnType = 'void';
|
|
233
|
-
|
|
234
|
-
arg.properties.forEach(property => {
|
|
235
|
-
if (!ts.isPropertyAssignment(property)) {
|
|
236
|
-
throw new Error(`Unexpected makeEntry property: ${property.getText(sourceFile)}`);
|
|
237
|
-
}
|
|
238
|
-
const key = getPropertyName(property.name, sourceFile);
|
|
239
|
-
if (key === 'params') {
|
|
240
|
-
params = extractRegistryParams(property.initializer, sourceFile);
|
|
241
|
-
} else if (key === 'returnType') {
|
|
242
|
-
returnType = normalizeExpressionText(property.initializer, sourceFile);
|
|
243
|
-
} else {
|
|
244
|
-
throw new Error(`Unexpected makeEntry property '${key}'.`);
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
return { params, returnType };
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Extracts `{ name, type }` pairs from the `params` array literal inside a `makeEntry` call.
|
|
253
|
-
*/
|
|
254
|
-
function extractRegistryParams(
|
|
255
|
-
initializer: ts.Expression,
|
|
256
|
-
sourceFile: ts.SourceFile,
|
|
257
|
-
): { name: string; type: string }[] {
|
|
258
|
-
if (!ts.isArrayLiteralExpression(initializer)) {
|
|
259
|
-
throw new Error(`Expected a params array but got: ${initializer.getText(sourceFile)}`);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
return initializer.elements.map(element => {
|
|
263
|
-
if (!ts.isObjectLiteralExpression(element)) {
|
|
264
|
-
throw new Error(`Expected a param object but got: ${element.getText(sourceFile)}`);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
let name: string | undefined;
|
|
268
|
-
let type: string | undefined;
|
|
269
|
-
element.properties.forEach(property => {
|
|
270
|
-
if (!ts.isPropertyAssignment(property)) {
|
|
271
|
-
throw new Error(`Unexpected param property: ${property.getText(sourceFile)}`);
|
|
272
|
-
}
|
|
273
|
-
const key = getPropertyName(property.name, sourceFile);
|
|
274
|
-
if (key === 'name') {
|
|
275
|
-
if (!ts.isStringLiteralLike(property.initializer)) {
|
|
276
|
-
throw new Error(`Expected a string literal param name but got: ${property.initializer.getText(sourceFile)}`);
|
|
277
|
-
}
|
|
278
|
-
name = property.initializer.text;
|
|
279
|
-
} else if (key === 'type') {
|
|
280
|
-
type = normalizeExpressionText(property.initializer, sourceFile);
|
|
281
|
-
} else {
|
|
282
|
-
throw new Error(`Unexpected param property '${key}'.`);
|
|
283
|
-
}
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
if (name === undefined || type === undefined) {
|
|
287
|
-
throw new Error(`Param missing 'name' or 'type': ${element.getText(sourceFile)}`);
|
|
288
|
-
}
|
|
289
|
-
return { name, type };
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/** Returns the text of an identifier or string-literal property name, throwing on computed or numeric names. */
|
|
294
|
-
function getPropertyName(name: ts.PropertyName, sourceFile: ts.SourceFile): string {
|
|
295
|
-
if (ts.isIdentifier(name) || ts.isStringLiteralLike(name)) {
|
|
296
|
-
return name.text;
|
|
297
|
-
}
|
|
298
|
-
throw new Error(`Unsupported property name: ${name.getText(sourceFile)}`);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Returns the source text of an expression with all whitespace stripped for format-insensitive comparison.
|
|
303
|
-
*
|
|
304
|
-
* @example
|
|
305
|
-
* // `OPTION(\n AZTEC_ADDRESS\n)` => `"OPTION(AZTEC_ADDRESS)"`
|
|
306
|
-
*/
|
|
307
|
-
function normalizeExpressionText(node: ts.Expression, sourceFile: ts.SourceFile): string {
|
|
308
|
-
// Type expressions are TypeMapping references and calls (identifiers, parentheses, commas, numbers) with no
|
|
309
|
-
// meaningful whitespace, so we strip it entirely to keep the signature stable across reformatting.
|
|
310
|
-
return node.getText(sourceFile).replace(/\s+/g, '');
|
|
311
|
-
}
|
package/src/contract/helpers.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { isProtocolContract } from '@aztec/protocol-contracts';
|
|
2
1
|
import type { FunctionCall, FunctionSelector } from '@aztec/stdlib/abi';
|
|
3
2
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
3
|
import type { BlockHeader } from '@aztec/stdlib/tx';
|
|
5
4
|
|
|
6
5
|
import type { ContractStore } from '../storage/contract_store/contract_store.js';
|
|
7
6
|
import type { ContractClassService } from './contract_class_service.js';
|
|
7
|
+
import { isSkipSyncContract } from './skip_sync_contracts.js';
|
|
8
8
|
|
|
9
9
|
export async function syncScope(
|
|
10
10
|
contractAddress: AztecAddress,
|
|
@@ -15,8 +15,8 @@ export async function syncScope(
|
|
|
15
15
|
utilityExecutor: (privateSyncCall: FunctionCall, scopes: AztecAddress[]) => Promise<any>,
|
|
16
16
|
scope: AztecAddress,
|
|
17
17
|
) {
|
|
18
|
-
//
|
|
19
|
-
if (
|
|
18
|
+
// Some canonical contracts hold no private state, so there is nothing to sync (see `skipSyncContracts`).
|
|
19
|
+
if (isSkipSyncContract(contractAddress)) {
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
22
|
|