@aztec/pxe 5.0.0-rc.2 → 5.0.0
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 +5 -3
- package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
- package/dest/block_synchronizer/block_synchronizer.js +7 -1
- package/dest/contract/contract_class_service.d.ts +31 -0
- package/dest/contract/contract_class_service.d.ts.map +1 -0
- package/dest/contract/contract_class_service.js +68 -0
- package/dest/{contract_sync → contract}/contract_sync_service.d.ts +7 -6
- package/dest/contract/contract_sync_service.d.ts.map +1 -0
- package/dest/{contract_sync → contract}/contract_sync_service.js +10 -30
- package/dest/contract/helpers.d.ts +7 -0
- package/dest/contract/helpers.d.ts.map +1 -0
- package/dest/contract/helpers.js +20 -0
- package/dest/contract_function_simulator/anchored_contract_data.d.ts +36 -0
- package/dest/contract_function_simulator/anchored_contract_data.d.ts.map +1 -0
- package/dest/contract_function_simulator/anchored_contract_data.js +54 -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/contract_function_simulator.d.ts +9 -3
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +31 -14
- package/dest/contract_function_simulator/execution_note_cache.d.ts +3 -9
- package/dest/contract_function_simulator/execution_note_cache.d.ts.map +1 -1
- package/dest/contract_function_simulator/execution_note_cache.js +8 -28
- package/dest/contract_function_simulator/index.d.ts +4 -2
- package/dest/contract_function_simulator/index.d.ts.map +1 -1
- package/dest/contract_function_simulator/index.js +2 -1
- package/dest/contract_function_simulator/noir-structs/fact.d.ts +5 -5
- package/dest/contract_function_simulator/noir-structs/fact.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/fact.js +2 -2
- package/dest/contract_function_simulator/noir-structs/fact_collection.d.ts +3 -3
- package/dest/contract_function_simulator/noir-structs/fact_collection.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/fact_collection.js +3 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +7 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/pending_tagged_log.d.ts +11 -0
- package/dest/contract_function_simulator/noir-structs/pending_tagged_log.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/pending_tagged_log.js +4 -0
- package/dest/contract_function_simulator/noir-structs/provided_secret.d.ts +2 -2
- package/dest/contract_function_simulator/noir-structs/provided_secret.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/provided_secret.js +1 -1
- package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.d.ts +8 -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 +17 -0
- package/dest/contract_function_simulator/oracle/acir_callback.d.ts +7 -2
- package/dest/contract_function_simulator/oracle/acir_callback.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/acir_callback.js +55 -11
- package/dest/contract_function_simulator/oracle/legacy_oracle_registry.d.ts +39 -0
- package/dest/contract_function_simulator/oracle/legacy_oracle_registry.d.ts.map +1 -0
- package/dest/contract_function_simulator/oracle/legacy_oracle_registry.js +107 -0
- package/dest/contract_function_simulator/oracle/oracle_registry.d.ts +10 -7
- package/dest/contract_function_simulator/oracle/oracle_registry.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle_registry.js +41 -10
- package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts +48 -9
- package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle_type_mappings.js +51 -30
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +10 -2
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +73 -32
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +20 -16
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +68 -47
- package/dest/debug/pxe_debug_utils.d.ts +2 -2
- package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/utils.js +2 -2
- package/dest/entrypoints/client/lazy/utils.js +2 -2
- package/dest/entrypoints/server/index.d.ts +5 -2
- package/dest/entrypoints/server/index.d.ts.map +1 -1
- package/dest/entrypoints/server/index.js +3 -1
- package/dest/error_enriching.d.ts +5 -3
- package/dest/error_enriching.d.ts.map +1 -1
- package/dest/error_enriching.js +12 -10
- package/dest/hooks/execution_hooks.d.ts +15 -4
- package/dest/hooks/execution_hooks.d.ts.map +1 -1
- package/dest/hooks/index.d.ts +3 -2
- package/dest/hooks/index.d.ts.map +1 -1
- package/dest/hooks/index.js +1 -0
- package/dest/hooks/resolve_custom_request.d.ts +23 -0
- package/dest/hooks/resolve_custom_request.d.ts.map +1 -0
- package/dest/hooks/resolve_custom_request.js +3 -0
- package/dest/hooks/resolve_tagging_secret_strategy.d.ts +10 -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 +33 -16
- package/dest/oracle_version.d.ts +2 -2
- package/dest/oracle_version.js +2 -2
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts +1 -1
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts.map +1 -1
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.js +6 -2
- 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 +17 -36
- package/dest/private_kernel/private_kernel_oracle.d.ts +4 -2
- package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_oracle.js +17 -5
- package/dest/pxe.d.ts +81 -46
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +135 -104
- 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 +31 -7
- package/dest/storage/contract_store/contract_store.d.ts +27 -24
- package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
- package/dest/storage/contract_store/contract_store.js +63 -74
- package/dest/storage/fact_store/fact_service.d.ts +6 -4
- package/dest/storage/fact_store/fact_service.d.ts.map +1 -1
- package/dest/storage/fact_store/fact_service.js +19 -4
- package/dest/storage/fact_store/fact_store.d.ts +1 -1
- package/dest/storage/fact_store/fact_store.js +1 -1
- package/dest/storage/fact_store/index.d.ts +2 -1
- package/dest/storage/fact_store/index.d.ts.map +1 -1
- package/dest/storage/fact_store/index.js +1 -0
- package/dest/storage/fact_store/origin_state.d.ts +57 -0
- package/dest/storage/fact_store/origin_state.d.ts.map +1 -0
- package/dest/storage/fact_store/origin_state.js +53 -0
- package/dest/storage/metadata.d.ts +2 -2
- package/dest/storage/metadata.d.ts.map +1 -1
- package/dest/storage/metadata.js +1 -1
- package/dest/storage/tagging_store/tagging_secret_sources_store.d.ts +17 -6
- package/dest/storage/tagging_store/tagging_secret_sources_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/tagging_secret_sources_store.js +24 -11
- package/dest/tagging/constants.d.ts +2 -2
- package/dest/tagging/constants.d.ts.map +1 -1
- package/dest/tagging/constants.js +18 -9
- package/package.json +17 -17
- package/src/block_synchronizer/block_synchronizer.ts +9 -1
- package/src/contract/contract_class_service.ts +83 -0
- package/src/{contract_sync → contract}/contract_sync_service.ts +18 -37
- package/src/contract/helpers.ts +35 -0
- package/src/contract_function_simulator/anchored_contract_data.ts +74 -0
- package/src/contract_function_simulator/aztec_node_read_cache.ts +89 -0
- package/src/contract_function_simulator/contract_function_simulator.ts +56 -14
- package/src/contract_function_simulator/execution_note_cache.ts +7 -28
- package/src/contract_function_simulator/index.ts +7 -1
- package/src/contract_function_simulator/noir-structs/fact.ts +4 -4
- package/src/contract_function_simulator/noir-structs/fact_collection.ts +9 -4
- package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +6 -0
- package/src/contract_function_simulator/noir-structs/pending_tagged_log.ts +12 -0
- package/src/contract_function_simulator/noir-structs/provided_secret.ts +1 -1
- package/src/contract_function_simulator/noir-structs/resolved_tagging_strategy.ts +21 -0
- package/src/contract_function_simulator/oracle/acir_callback.ts +58 -12
- package/src/contract_function_simulator/oracle/legacy_oracle_registry.ts +147 -0
- package/src/contract_function_simulator/oracle/oracle_registry.ts +32 -7
- package/src/contract_function_simulator/oracle/oracle_type_mappings.ts +49 -32
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +92 -41
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +104 -59
- package/src/debug/pxe_debug_utils.ts +1 -1
- package/src/entrypoints/client/bundle/utils.ts +2 -2
- package/src/entrypoints/client/lazy/utils.ts +2 -2
- package/src/entrypoints/server/index.ts +5 -1
- package/src/error_enriching.ts +26 -10
- package/src/hooks/execution_hooks.ts +14 -3
- package/src/hooks/index.ts +2 -0
- package/src/hooks/resolve_custom_request.ts +24 -0
- package/src/hooks/resolve_tagging_secret_strategy.ts +14 -0
- package/src/logs/log_service.ts +31 -11
- package/src/oracle_version.ts +2 -2
- package/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +11 -1
- package/src/private_kernel/private_kernel_execution_prover.ts +22 -52
- package/src/private_kernel/private_kernel_oracle.ts +23 -4
- package/src/pxe.ts +209 -143
- package/src/storage/backwards_compatibility_tests/__snapshots__/AddressStore.json +6 -6
- package/src/storage/backwards_compatibility_tests/__snapshots__/ContractStore.json +1 -1
- package/src/storage/backwards_compatibility_tests/__snapshots__/KeyStore.json +12 -12
- 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__/TaggingSecretSourcesStore.json +3 -3
- package/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json +1 -1
- package/src/storage/backwards_compatibility_tests/schema_tests.ts +38 -4
- package/src/storage/contract_store/contract_store.ts +85 -92
- package/src/storage/fact_store/fact_service.ts +29 -5
- package/src/storage/fact_store/fact_store.ts +1 -1
- package/src/storage/fact_store/index.ts +10 -0
- package/src/storage/fact_store/origin_state.ts +75 -0
- package/src/storage/metadata.ts +1 -1
- package/src/storage/tagging_store/tagging_secret_sources_store.ts +36 -15
- package/src/tagging/constants.ts +19 -9
- package/dest/contract_function_simulator/proxied_contract_data_source.d.ts +0 -6
- package/dest/contract_function_simulator/proxied_contract_data_source.d.ts.map +0 -1
- package/dest/contract_function_simulator/proxied_contract_data_source.js +0 -51
- package/dest/contract_sync/contract_sync_service.d.ts.map +0 -1
- package/dest/contract_sync/helpers.d.ts +0 -28
- package/dest/contract_sync/helpers.d.ts.map +0 -1
- package/dest/contract_sync/helpers.js +0 -48
- package/src/contract_function_simulator/proxied_contract_data_source.ts +0 -60
- package/src/contract_sync/helpers.ts +0 -79
|
@@ -29,9 +29,11 @@ import {
|
|
|
29
29
|
type TxContext,
|
|
30
30
|
} from '@aztec/stdlib/tx';
|
|
31
31
|
|
|
32
|
-
import type {
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
import type { ResolveCustomRequest } from '../../hooks/resolve_custom_request.js';
|
|
33
|
+
import {
|
|
34
|
+
DEFAULT_TAGGING_SECRET_STRATEGY,
|
|
35
|
+
type ResolveTaggingSecretStrategy,
|
|
36
|
+
type TaggingSecretStrategy,
|
|
35
37
|
} from '../../hooks/resolve_tagging_secret_strategy.js';
|
|
36
38
|
import { NoteService } from '../../notes/note_service.js';
|
|
37
39
|
import type { SenderTaggingStore } from '../../storage/tagging_store/sender_tagging_store.js';
|
|
@@ -53,6 +55,7 @@ import { UtilityExecutionOracle, type UtilityExecutionOracleArgs } from './utili
|
|
|
53
55
|
export type PrivateExecutionOracleArgs = UtilityExecutionOracleArgs & {
|
|
54
56
|
argsHash: Fr;
|
|
55
57
|
txContext: TxContext;
|
|
58
|
+
txRequestSalt: Fr;
|
|
56
59
|
executionCache: HashedValuesCache;
|
|
57
60
|
noteCache: ExecutionNoteCache;
|
|
58
61
|
taggingIndexCache: ExecutionTaggingIndexCache;
|
|
@@ -83,6 +86,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
83
86
|
|
|
84
87
|
private readonly argsHash: Fr;
|
|
85
88
|
private readonly txContext: TxContext;
|
|
89
|
+
private readonly txRequestSalt: Fr;
|
|
86
90
|
private readonly executionCache: HashedValuesCache;
|
|
87
91
|
private readonly noteCache: ExecutionNoteCache;
|
|
88
92
|
private readonly taggingIndexCache: ExecutionTaggingIndexCache;
|
|
@@ -99,6 +103,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
99
103
|
});
|
|
100
104
|
this.argsHash = args.argsHash;
|
|
101
105
|
this.txContext = args.txContext;
|
|
106
|
+
this.txRequestSalt = args.txRequestSalt;
|
|
102
107
|
this.executionCache = args.executionCache;
|
|
103
108
|
this.noteCache = args.noteCache;
|
|
104
109
|
this.taggingIndexCache = args.taggingIndexCache;
|
|
@@ -114,6 +119,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
114
119
|
this.anchorBlockHeader,
|
|
115
120
|
this.txContext,
|
|
116
121
|
this.initialSideEffectCounter,
|
|
122
|
+
this.txRequestSalt,
|
|
117
123
|
);
|
|
118
124
|
}
|
|
119
125
|
|
|
@@ -187,30 +193,81 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
187
193
|
return Promise.resolve(this.defaultSenderForTags ? Option.some(this.defaultSenderForTags) : Option.none());
|
|
188
194
|
}
|
|
189
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Resolves a custom, caller-defined request via the {@link ResolveCustomRequest} hook, which produces the response
|
|
198
|
+
* however it needs to. Throws when no hook is configured, since the request cannot be served.
|
|
199
|
+
*/
|
|
200
|
+
public async resolveCustomRequest(kind: Fr, payload: Fr[]): Promise<Fr[]> {
|
|
201
|
+
const hook: ResolveCustomRequest | undefined = this.hooks?.resolveCustomRequest;
|
|
202
|
+
if (!hook) {
|
|
203
|
+
throw new Error('Cannot serve a request: no resolveCustomRequest hook is configured');
|
|
204
|
+
}
|
|
205
|
+
const contractClassId = await this.#getCurrentContractClassId(this.contractAddress);
|
|
206
|
+
return hook({ contractAddress: this.contractAddress, contractClassId, kind, payload });
|
|
207
|
+
}
|
|
208
|
+
|
|
190
209
|
/**
|
|
191
210
|
* Resolves the tagging strategy for a message via the wallet's {@link ResolveTaggingSecretStrategy} hook. The contract receives a ready-to-use {@link ResolvedTaggingStrategy}.
|
|
192
|
-
* When no hook is configured, applies a
|
|
211
|
+
* When no hook is configured, applies a default: a non-interactive handshake, except for an unconstrained self-send,
|
|
212
|
+
* which uses an address-derived secret.
|
|
193
213
|
*/
|
|
194
214
|
public async resolveTaggingStrategy(
|
|
195
215
|
sender: AztecAddress,
|
|
196
216
|
recipient: AztecAddress,
|
|
197
217
|
deliveryMode: AppTaggingSecretKind,
|
|
198
218
|
): Promise<ResolvedTaggingStrategy> {
|
|
219
|
+
const [isUnconstrainedSelfSend, chosenStrategy] = await Promise.all([
|
|
220
|
+
this.#isUnconstrainedSelfSend(recipient, deliveryMode),
|
|
221
|
+
this.#chooseTaggingSecretStrategy(sender, recipient, deliveryMode),
|
|
222
|
+
]);
|
|
223
|
+
|
|
224
|
+
// For unconstrained delivery, a self-send uses a local address-derived secret instead of a non-interactive
|
|
225
|
+
// handshake. A self-send is one where the wallet controls the recipient's keys, so both sides' keys are local: no
|
|
226
|
+
// handshake is needed and nothing is revealed onchain. It also avoids a recursion: a handshake self-delivers its
|
|
227
|
+
// note via unconstrained delivery, which would establish yet another handshake. This guard runs regardless of the
|
|
228
|
+
// resolved strategy (hook or default), to protect wallets from invalid configuration.
|
|
229
|
+
const strategy: TaggingSecretStrategy = isUnconstrainedSelfSend ? { type: 'address-derived' } : chosenStrategy;
|
|
230
|
+
|
|
231
|
+
return this.#resolveTaggingSecretStrategy(strategy, sender, recipient);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async #chooseTaggingSecretStrategy(
|
|
235
|
+
sender: AztecAddress,
|
|
236
|
+
recipient: AztecAddress,
|
|
237
|
+
deliveryMode: AppTaggingSecretKind,
|
|
238
|
+
): Promise<TaggingSecretStrategy> {
|
|
199
239
|
const hook: ResolveTaggingSecretStrategy | undefined = this.hooks?.resolveTaggingSecretStrategy;
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const { currentContractClassId } = await this.getContractInstance(this.contractAddress);
|
|
203
|
-
strategy = await hook({
|
|
204
|
-
contractAddress: this.contractAddress,
|
|
205
|
-
contractClassId: currentContractClassId,
|
|
206
|
-
sender,
|
|
207
|
-
recipient,
|
|
208
|
-
deliveryMode,
|
|
209
|
-
});
|
|
210
|
-
} else {
|
|
211
|
-
strategy = this.#defaultTaggingSecretStrategy(deliveryMode, recipient);
|
|
240
|
+
if (!hook) {
|
|
241
|
+
return DEFAULT_TAGGING_SECRET_STRATEGY;
|
|
212
242
|
}
|
|
213
|
-
|
|
243
|
+
|
|
244
|
+
const contractClassId = await this.#getCurrentContractClassId(this.contractAddress);
|
|
245
|
+
return hook({
|
|
246
|
+
contractAddress: this.contractAddress,
|
|
247
|
+
contractClassId,
|
|
248
|
+
sender,
|
|
249
|
+
recipient,
|
|
250
|
+
deliveryMode,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Resolves the class id the given contract runs at this simulation's anchor block. The instance no longer carries
|
|
256
|
+
* its class id (it is chain-derived), so it is resolved via the anchored contract data instead.
|
|
257
|
+
*/
|
|
258
|
+
async #getCurrentContractClassId(address: AztecAddress): Promise<Fr> {
|
|
259
|
+
const classId = await this.anchoredContractData.getCurrentClassId(address);
|
|
260
|
+
if (classId === undefined) {
|
|
261
|
+
throw new Error(`Cannot resolve the current contract class for ${address}`);
|
|
262
|
+
}
|
|
263
|
+
return classId;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/** Whether this is an unconstrained delivery to one of the wallet's own accounts (a self-send). */
|
|
267
|
+
#isUnconstrainedSelfSend(recipient: AztecAddress, deliveryMode: AppTaggingSecretKind) {
|
|
268
|
+
return deliveryMode === AppTaggingSecretKind.UNCONSTRAINED
|
|
269
|
+
? this.keyStore.hasAccount(recipient)
|
|
270
|
+
: Promise.resolve(false);
|
|
214
271
|
}
|
|
215
272
|
|
|
216
273
|
/** Resolves a wallet-provided {@link TaggingSecretStrategy} into the app-siloed secret handed to the contract. */
|
|
@@ -225,29 +282,22 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
225
282
|
switch (strategy.type) {
|
|
226
283
|
case 'non-interactive-handshake':
|
|
227
284
|
return { type: 'non-interactive-handshake' };
|
|
285
|
+
case 'interactive-handshake':
|
|
286
|
+
return { type: 'interactive-handshake' };
|
|
228
287
|
case 'address-derived':
|
|
229
288
|
return this.#addressDerivedSecret(sender, recipient);
|
|
230
289
|
case 'arbitrary-secret': {
|
|
231
290
|
// App-silo the raw arbitrary secret point here so wallets never replicate the derivation.
|
|
232
|
-
const appTaggingSecret = await AppTaggingSecret.
|
|
291
|
+
const appTaggingSecret = await AppTaggingSecret.computeDirectional(
|
|
292
|
+
strategy.secret,
|
|
293
|
+
this.contractAddress,
|
|
294
|
+
recipient,
|
|
295
|
+
);
|
|
233
296
|
return { type: 'unconstrained-secret', secret: appTaggingSecret.secret };
|
|
234
297
|
}
|
|
235
298
|
}
|
|
236
299
|
}
|
|
237
300
|
|
|
238
|
-
/** The privacy-safe tagging secret strategy used when no {@link ResolveTaggingSecretStrategy} hook is configured. */
|
|
239
|
-
#defaultTaggingSecretStrategy(deliveryMode: AppTaggingSecretKind, recipient: AztecAddress): TaggingSecretStrategy {
|
|
240
|
-
if (deliveryMode === AppTaggingSecretKind.CONSTRAINED) {
|
|
241
|
-
// Constrained delivery has no "safe" default: a non-interactive handshake would reveal the recipient onchain,
|
|
242
|
-
// and an interactive handshake always needs a wallet interaction (i.e. a configured hook). With no hook there is
|
|
243
|
-
// nothing safe to fall back to, so we always fail.
|
|
244
|
-
throw new Error(`Constrained delivery to ${recipient} requires a configured resolveTaggingSecretStrategy hook.`);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// Unconstrained default: an address-derived (Diffie-Hellman) shared secret, which leaves no onchain trace.
|
|
248
|
-
return { type: 'address-derived' };
|
|
249
|
-
}
|
|
250
|
-
|
|
251
301
|
/**
|
|
252
302
|
* The app-siloed, recipient-directional secret derived from the sender's and recipient's address keys via ECDH,
|
|
253
303
|
* ready to hand to the contract. Callers must validate the recipient in-circuit before reaching here, so an invalid one is unexpected.
|
|
@@ -307,13 +357,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
307
357
|
async #calculateAppTaggingSecret(contractAddress: AztecAddress, sender: AztecAddress, recipient: AztecAddress) {
|
|
308
358
|
const senderCompleteAddress = await this.getCompleteAddressOrFail(sender);
|
|
309
359
|
const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
|
|
310
|
-
return AppTaggingSecret.
|
|
311
|
-
senderCompleteAddress,
|
|
312
|
-
senderIvsk,
|
|
313
|
-
recipient,
|
|
314
|
-
contractAddress,
|
|
315
|
-
recipient,
|
|
316
|
-
);
|
|
360
|
+
return AppTaggingSecret.computeViaEcdh(senderCompleteAddress, senderIvsk, recipient, contractAddress, recipient);
|
|
317
361
|
}
|
|
318
362
|
|
|
319
363
|
async #getIndexToUseForSecret(secret: AppTaggingSecret): Promise<number> {
|
|
@@ -615,10 +659,16 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
615
659
|
this.scopes,
|
|
616
660
|
);
|
|
617
661
|
|
|
618
|
-
const targetArtifact = await this.
|
|
662
|
+
const targetArtifact = await this.anchoredContractData.getFunctionArtifactWithDebugMetadata(
|
|
619
663
|
targetContractAddress,
|
|
620
664
|
functionSelector,
|
|
621
665
|
);
|
|
666
|
+
if (!targetArtifact) {
|
|
667
|
+
throw new Error(
|
|
668
|
+
`Cannot call ${targetContractAddress}:${functionSelector}: the contract is not registered. ` +
|
|
669
|
+
`Register it via wallet.registerContract(...).`,
|
|
670
|
+
);
|
|
671
|
+
}
|
|
622
672
|
|
|
623
673
|
const derivedTxContext = this.txContext.clone();
|
|
624
674
|
|
|
@@ -627,6 +677,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
627
677
|
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
628
678
|
argsHash,
|
|
629
679
|
txContext: derivedTxContext,
|
|
680
|
+
txRequestSalt: this.txRequestSalt,
|
|
630
681
|
callContext: derivedCallContext,
|
|
631
682
|
anchorBlockHeader: this.anchorBlockHeader,
|
|
632
683
|
utilityExecutor: this.utilityExecutor,
|
|
@@ -635,7 +686,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
635
686
|
executionCache: this.executionCache,
|
|
636
687
|
noteCache: this.noteCache,
|
|
637
688
|
taggingIndexCache: this.taggingIndexCache,
|
|
638
|
-
|
|
689
|
+
anchoredContractData: this.anchoredContractData,
|
|
639
690
|
noteStore: this.noteStore,
|
|
640
691
|
keyStore: this.keyStore,
|
|
641
692
|
addressStore: this.addressStore,
|
|
@@ -739,7 +790,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
739
790
|
}
|
|
740
791
|
|
|
741
792
|
public getDebugFunctionName() {
|
|
742
|
-
return this.
|
|
793
|
+
return this.anchoredContractData.getDebugFunctionName(this.contractAddress, this.callContext.functionSelector);
|
|
743
794
|
}
|
|
744
795
|
|
|
745
796
|
protected override get callerContext() {
|
|
@@ -20,18 +20,13 @@ import { type FunctionCall, FunctionSelector } from '@aztec/stdlib/abi';
|
|
|
20
20
|
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
21
21
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
22
22
|
import { BlockHash, type L2TipsProvider } from '@aztec/stdlib/block';
|
|
23
|
-
import type { CompleteAddress,
|
|
23
|
+
import type { CompleteAddress, ContractInstancePreimageWithAddress, PartialAddress } from '@aztec/stdlib/contract';
|
|
24
24
|
import { siloNullifier } from '@aztec/stdlib/hash';
|
|
25
25
|
import type { AztecNode } from '@aztec/stdlib/interfaces/server';
|
|
26
26
|
import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
|
|
27
27
|
import { PublicKeys, computeAddressSecret, hashPublicKey } from '@aztec/stdlib/keys';
|
|
28
|
-
import {
|
|
29
|
-
|
|
30
|
-
FlatPublicLogs,
|
|
31
|
-
type PendingTaggedLog,
|
|
32
|
-
deriveAppSiloedSharedSecret,
|
|
33
|
-
} from '@aztec/stdlib/logs';
|
|
34
|
-
import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
|
|
28
|
+
import { AppTaggingSecret, FlatPublicLogs, appSiloEcdhSharedSecret } from '@aztec/stdlib/logs';
|
|
29
|
+
import { type UnsiloedMessageNullifier, getL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
|
|
35
30
|
import type { NoteStatus } from '@aztec/stdlib/note';
|
|
36
31
|
import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
37
32
|
import {
|
|
@@ -43,8 +38,8 @@ import {
|
|
|
43
38
|
type TxHash,
|
|
44
39
|
} from '@aztec/stdlib/tx';
|
|
45
40
|
|
|
41
|
+
import type { ContractSyncService } from '../../contract/contract_sync_service.js';
|
|
46
42
|
import { createContractLogger, logContractMessage, stripAztecnrLogPrefix } from '../../contract_logging.js';
|
|
47
|
-
import type { ContractSyncService } from '../../contract_sync/contract_sync_service.js';
|
|
48
43
|
import { EventService } from '../../events/event_service.js';
|
|
49
44
|
import type { UtilityCallAuthorizationRequest } from '../../hooks/authorize_utility_call.js';
|
|
50
45
|
import type { ExecutionHooks } from '../../hooks/index.js';
|
|
@@ -54,13 +49,14 @@ import { NoteService } from '../../notes/note_service.js';
|
|
|
54
49
|
import { ORACLE_VERSION_MAJOR } from '../../oracle_version.js';
|
|
55
50
|
import type { AddressStore } from '../../storage/address_store/address_store.js';
|
|
56
51
|
import type { CapsuleService } from '../../storage/capsule_store/capsule_service.js';
|
|
57
|
-
import
|
|
58
|
-
import { FactCollectionKey, FactCollectionTypeKey } from '../../storage/fact_store/index.js';
|
|
52
|
+
import { FactCollectionKey, FactCollectionTypeKey, anchoredTipBlockNumbers } from '../../storage/fact_store/index.js';
|
|
59
53
|
import type { FactService, OriginBlock } from '../../storage/fact_store/index.js';
|
|
60
54
|
import type { NoteStore } from '../../storage/note_store/note_store.js';
|
|
61
55
|
import type { PrivateEventStore } from '../../storage/private_event_store/private_event_store.js';
|
|
62
56
|
import type { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js';
|
|
63
57
|
import type { TaggingSecretSourcesStore } from '../../storage/tagging_store/tagging_secret_sources_store.js';
|
|
58
|
+
import type { AnchoredContractData } from '../anchored_contract_data.js';
|
|
59
|
+
import { AztecNodeReadCache } from '../aztec_node_read_cache.js';
|
|
64
60
|
import { EphemeralArrayService } from '../ephemeral_array_service.js';
|
|
65
61
|
import { BoundedVec } from '../noir-structs/bounded_vec.js';
|
|
66
62
|
import type { EmbeddedCurvePoint } from '../noir-structs/embedded_curve_point.js';
|
|
@@ -72,6 +68,7 @@ import type { LogRetrievalResponse } from '../noir-structs/log_retrieval_respons
|
|
|
72
68
|
import type { NoteData } from '../noir-structs/note_data.js';
|
|
73
69
|
import type { NoteValidationRequest } from '../noir-structs/note_validation_request.js';
|
|
74
70
|
import { Option } from '../noir-structs/option.js';
|
|
71
|
+
import type { PendingTaggedLog } from '../noir-structs/pending_tagged_log.js';
|
|
75
72
|
import type { ProvidedSecret } from '../noir-structs/provided_secret.js';
|
|
76
73
|
import type { ResolvedTx } from '../noir-structs/resolved_tx.js';
|
|
77
74
|
import type { TxEffectData } from '../noir-structs/tx_effect_data.js';
|
|
@@ -88,7 +85,7 @@ export type UtilityExecutionOracleArgs = {
|
|
|
88
85
|
authWitnesses: AuthWitness[];
|
|
89
86
|
capsules: Capsule[]; // TODO(#12425): Rename to transientCapsules
|
|
90
87
|
anchorBlockHeader: BlockHeader;
|
|
91
|
-
|
|
88
|
+
anchoredContractData: AnchoredContractData;
|
|
92
89
|
noteStore: NoteStore;
|
|
93
90
|
keyStore: KeyStore;
|
|
94
91
|
addressStore: AddressStore;
|
|
@@ -123,6 +120,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
123
120
|
private offchainEffects: OffchainEffect[] = [];
|
|
124
121
|
private readonly ephemeralArrayService = new EphemeralArrayService();
|
|
125
122
|
protected readonly transientArrayService: TransientArrayService;
|
|
123
|
+
private readonly aztecNodeReadCache: AztecNodeReadCache;
|
|
126
124
|
|
|
127
125
|
// We store oracle version to be able to show a nice error message when an oracle handler is missing.
|
|
128
126
|
private contractOracleVersion: { major: number; minor: number } | undefined;
|
|
@@ -131,7 +129,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
131
129
|
protected readonly authWitnesses: AuthWitness[];
|
|
132
130
|
protected readonly capsules: Capsule[];
|
|
133
131
|
protected readonly anchorBlockHeader: BlockHeader;
|
|
134
|
-
protected readonly
|
|
132
|
+
protected readonly anchoredContractData: AnchoredContractData;
|
|
135
133
|
protected readonly noteStore: NoteStore;
|
|
136
134
|
protected readonly keyStore: KeyStore;
|
|
137
135
|
protected readonly addressStore: AddressStore;
|
|
@@ -156,7 +154,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
156
154
|
this.authWitnesses = args.authWitnesses;
|
|
157
155
|
this.capsules = args.capsules;
|
|
158
156
|
this.anchorBlockHeader = args.anchorBlockHeader;
|
|
159
|
-
this.
|
|
157
|
+
this.anchoredContractData = args.anchoredContractData;
|
|
160
158
|
this.noteStore = args.noteStore;
|
|
161
159
|
this.keyStore = args.keyStore;
|
|
162
160
|
this.addressStore = args.addressStore;
|
|
@@ -176,6 +174,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
176
174
|
this.hooks = args.hooks;
|
|
177
175
|
this.utilityExecutor = args.utilityExecutor;
|
|
178
176
|
this.transientArrayService = args.transientArrayService;
|
|
177
|
+
this.aztecNodeReadCache = new AztecNodeReadCache(args.aztecNode);
|
|
179
178
|
}
|
|
180
179
|
|
|
181
180
|
public assertCompatibleOracleVersion(major: number, minor: number): void {
|
|
@@ -269,11 +268,27 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
269
268
|
// hash at all. If the block hash did not exist by the reference block hash, then the node will not return the
|
|
270
269
|
// membership witness as there is none.
|
|
271
270
|
const witness = await this.#queryWithBlockHashNotAfterAnchor(referenceBlockHash, () =>
|
|
272
|
-
this.
|
|
271
|
+
this.aztecNodeReadCache.getBlockHashMembershipWitness(referenceBlockHash, blockHash),
|
|
273
272
|
);
|
|
274
273
|
return witness ? Option.some(witness) : Option.none();
|
|
275
274
|
}
|
|
276
275
|
|
|
276
|
+
/** Returns whether each block hash is present in the archive tree at the referenced block. */
|
|
277
|
+
public async areBlockHashesInArchive(
|
|
278
|
+
referenceBlockHash: BlockHash,
|
|
279
|
+
blockHashes: EphemeralArray<BlockHash>,
|
|
280
|
+
): Promise<EphemeralArray<boolean>> {
|
|
281
|
+
const hashes = blockHashes.readAll(this.ephemeralArrayService);
|
|
282
|
+
const memberships = await this.#queryWithBlockHashNotAfterAnchor(referenceBlockHash, () =>
|
|
283
|
+
Promise.all(
|
|
284
|
+
hashes.map(blockHash =>
|
|
285
|
+
this.aztecNodeReadCache.getBlockHashMembershipWitness(referenceBlockHash, blockHash).then(Boolean),
|
|
286
|
+
),
|
|
287
|
+
),
|
|
288
|
+
);
|
|
289
|
+
return EphemeralArray.fromValues(this.ephemeralArrayService, memberships);
|
|
290
|
+
}
|
|
291
|
+
|
|
277
292
|
/**
|
|
278
293
|
* Returns a nullifier membership witness for a given nullifier at a given block.
|
|
279
294
|
* @param blockHash - The block hash at which to get the index.
|
|
@@ -322,7 +337,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
322
337
|
*/
|
|
323
338
|
public async getPublicDataWitness(blockHash: BlockHash, leafSlot: Fr): Promise<PublicDataWitness> {
|
|
324
339
|
const witness = await this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
|
|
325
|
-
this.
|
|
340
|
+
this.aztecNodeReadCache.getPublicDataWitness(blockHash, leafSlot),
|
|
326
341
|
);
|
|
327
342
|
if (!witness) {
|
|
328
343
|
throw new Error(`Public data witness not found for slot ${leafSlot} at block hash ${blockHash.toString()}.`);
|
|
@@ -384,8 +399,8 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
384
399
|
* @param address - Address.
|
|
385
400
|
* @returns A contract instance.
|
|
386
401
|
*/
|
|
387
|
-
public async getContractInstance(address: AztecAddress): Promise<
|
|
388
|
-
const instance = await this.
|
|
402
|
+
public async getContractInstance(address: AztecAddress): Promise<ContractInstancePreimageWithAddress> {
|
|
403
|
+
const instance = await this.anchoredContractData.getContractInstance(address);
|
|
389
404
|
if (!instance) {
|
|
390
405
|
throw new Error(`No contract instance found for address ${address.toString()}`);
|
|
391
406
|
}
|
|
@@ -482,19 +497,17 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
482
497
|
}
|
|
483
498
|
|
|
484
499
|
/**
|
|
485
|
-
* Returns the membership witness of an
|
|
486
|
-
* @param contractAddress - Address of a contract by which the message was emitted.
|
|
500
|
+
* Returns the membership witness of an L1 to L2 message.
|
|
487
501
|
* @param messageHash - Hash of the message.
|
|
488
|
-
* @param
|
|
489
|
-
*
|
|
502
|
+
* @param nullifier - When present, the unsiloed nullifier of the message and the address to silo it with. The witness
|
|
503
|
+
* is only returned if the siloed nullifier is absent from the nullifier tree, i.e. the message has not been consumed.
|
|
490
504
|
* @returns The l1 to l2 membership witness (index of message in the tree and sibling path).
|
|
491
505
|
*/
|
|
492
|
-
public async
|
|
493
|
-
const [messageIndex, siblingPath] = await
|
|
506
|
+
public async getL1ToL2MembershipWitnessV2(messageHash: Fr, nullifier: Option<UnsiloedMessageNullifier>) {
|
|
507
|
+
const [messageIndex, siblingPath] = await getL1ToL2MessageWitness(
|
|
494
508
|
this.aztecNode,
|
|
495
|
-
contractAddress,
|
|
496
509
|
messageHash,
|
|
497
|
-
|
|
510
|
+
nullifier.value,
|
|
498
511
|
await this.anchorBlockHeader.hash(),
|
|
499
512
|
);
|
|
500
513
|
|
|
@@ -515,16 +528,16 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
515
528
|
numberOfElements: number,
|
|
516
529
|
) {
|
|
517
530
|
return this.#queryWithBlockHashNotAfterAnchor(blockHash, async () => {
|
|
518
|
-
const
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
slots.map(storageSlot => this.aztecNode.getPublicStorageAt(blockHash, contractAddress, storageSlot)),
|
|
531
|
+
const values = await this.aztecNodeReadCache.getPublicStorageRange(
|
|
532
|
+
blockHash,
|
|
533
|
+
contractAddress,
|
|
534
|
+
startStorageSlot,
|
|
535
|
+
numberOfElements,
|
|
524
536
|
);
|
|
525
537
|
|
|
526
538
|
this.logger.debug(
|
|
527
|
-
`Oracle storage read:
|
|
539
|
+
`Oracle storage read: start=${startStorageSlot.toString()} count=${numberOfElements} ` +
|
|
540
|
+
`address=${contractAddress.toString()} values=[${values.join(', ')}]`,
|
|
528
541
|
);
|
|
529
542
|
|
|
530
543
|
return values;
|
|
@@ -540,7 +553,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
540
553
|
// to re-use jobId as instanceId here as executions of different PXE jobs are isolated.
|
|
541
554
|
this.contractLogger = await createContractLogger(
|
|
542
555
|
this.contractAddress,
|
|
543
|
-
addr => this.
|
|
556
|
+
addr => this.anchoredContractData.getDebugContractName(addr),
|
|
544
557
|
'user',
|
|
545
558
|
{ instanceId: this.jobId },
|
|
546
559
|
);
|
|
@@ -557,7 +570,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
557
570
|
// to re-use jobId as instanceId here as executions of different PXE jobs are isolated.
|
|
558
571
|
this.aztecnrLogger = await createContractLogger(
|
|
559
572
|
this.contractAddress,
|
|
560
|
-
addr => this.
|
|
573
|
+
addr => this.anchoredContractData.getDebugContractName(addr),
|
|
561
574
|
'aztecnr',
|
|
562
575
|
{ instanceId: this.jobId },
|
|
563
576
|
);
|
|
@@ -577,7 +590,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
577
590
|
}
|
|
578
591
|
|
|
579
592
|
/** Fetches pending tagged logs into a freshly allocated ephemeral array and returns it. */
|
|
580
|
-
public async
|
|
593
|
+
public async getPendingTaggedLogsV2(
|
|
581
594
|
scope: AztecAddress,
|
|
582
595
|
providedSecrets: EphemeralArray<ProvidedSecret>,
|
|
583
596
|
): Promise<EphemeralArray<PendingTaggedLog>> {
|
|
@@ -635,7 +648,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
635
648
|
]);
|
|
636
649
|
}
|
|
637
650
|
|
|
638
|
-
public async
|
|
651
|
+
public async getLogsByTagV2(
|
|
639
652
|
requests: EphemeralArray<LogRetrievalRequest>,
|
|
640
653
|
): Promise<EphemeralArray<EphemeralArray<LogRetrievalResponse>>> {
|
|
641
654
|
const logRetrievalRequests = requests.readAll(this.ephemeralArrayService);
|
|
@@ -670,7 +683,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
670
683
|
throw new Error('Invalid tx hash passed into aztec_utl_getTxEffect oracle handler');
|
|
671
684
|
}
|
|
672
685
|
|
|
673
|
-
const receipt = await this.
|
|
686
|
+
const receipt = await this.aztecNodeReadCache.getTxReceiptWithEffect(txHash);
|
|
674
687
|
if (!receipt.isMined() || !receipt.txEffect || receipt.blockNumber > this.anchorBlockHeader.getBlockNumber()) {
|
|
675
688
|
return Option.none();
|
|
676
689
|
}
|
|
@@ -777,8 +790,10 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
777
790
|
factCollectionId: Fr,
|
|
778
791
|
): Promise<Option<FactCollection>> {
|
|
779
792
|
this.#assertOwnContract(contractAddress);
|
|
793
|
+
const tips = anchoredTipBlockNumbers(await this.l2TipsStore.getL2Tips(), this.anchorBlockHeader.getBlockNumber());
|
|
780
794
|
const collection = await this.factService.getFactCollection(
|
|
781
795
|
new FactCollectionKey(contractAddress, scope, factCollectionTypeId, factCollectionId),
|
|
796
|
+
tips,
|
|
782
797
|
this.jobId,
|
|
783
798
|
);
|
|
784
799
|
return collection
|
|
@@ -802,8 +817,10 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
802
817
|
factCollectionTypeId: Fr,
|
|
803
818
|
): Promise<EphemeralArray<FactCollection>> {
|
|
804
819
|
this.#assertOwnContract(contractAddress);
|
|
820
|
+
const tips = anchoredTipBlockNumbers(await this.l2TipsStore.getL2Tips(), this.anchorBlockHeader.getBlockNumber());
|
|
805
821
|
const collections = await this.factService.getFactCollectionsByType(
|
|
806
822
|
new FactCollectionTypeKey(contractAddress, scope, factCollectionTypeId),
|
|
823
|
+
tips,
|
|
807
824
|
this.jobId,
|
|
808
825
|
);
|
|
809
826
|
return EphemeralArray.fromValues(
|
|
@@ -853,7 +870,8 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
853
870
|
* @param address - The recipient address.
|
|
854
871
|
* @param ephPks - Ephemeral array containing the serialized Points.
|
|
855
872
|
* @param contractAddress - The contract address for app-siloing (validated against execution context).
|
|
856
|
-
* @returns A new ephemeral array containing the computed shared secrets
|
|
873
|
+
* @returns A new ephemeral array containing the computed shared secrets, or an empty array when the PXE does not
|
|
874
|
+
* hold the keys for `address`, signaling that no secrets can be derived for it.
|
|
857
875
|
*/
|
|
858
876
|
public async getSharedSecrets(
|
|
859
877
|
address: AztecAddress,
|
|
@@ -865,14 +883,24 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
865
883
|
`getSharedSecrets called with contract address ${contractAddress}, expected ${this.contractAddress}`,
|
|
866
884
|
);
|
|
867
885
|
}
|
|
868
|
-
const recipientCompleteAddress = await this.
|
|
886
|
+
const recipientCompleteAddress = await this.addressStore.getCompleteAddress(address);
|
|
887
|
+
if (!recipientCompleteAddress) {
|
|
888
|
+
this.logger.warn(
|
|
889
|
+
`Computing shared secrets for address ${address} whose keys are not held - returning no secrets`,
|
|
890
|
+
{
|
|
891
|
+
address,
|
|
892
|
+
contractAddress: this.contractAddress,
|
|
893
|
+
},
|
|
894
|
+
);
|
|
895
|
+
return EphemeralArray.fromValues<Fr>(this.ephemeralArrayService, []);
|
|
896
|
+
}
|
|
869
897
|
const ivpkMHash = await hashPublicKey(recipientCompleteAddress.publicKeys.ivpkM);
|
|
870
898
|
const ivskM = await this.keyStore.getMasterSecretKey(ivpkMHash);
|
|
871
899
|
const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM);
|
|
872
900
|
|
|
873
901
|
const ephPkPoints = ephPks.readAll(this.ephemeralArrayService);
|
|
874
902
|
const secrets = await Promise.all(
|
|
875
|
-
ephPkPoints.map(({ x, y }) =>
|
|
903
|
+
ephPkPoints.map(({ x, y }) => appSiloEcdhSharedSecret(addressSecret, new Point(x, y), this.contractAddress)),
|
|
876
904
|
);
|
|
877
905
|
|
|
878
906
|
return EphemeralArray.fromValues(this.ephemeralArrayService, secrets);
|
|
@@ -945,23 +973,35 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
945
973
|
functionSelector: FunctionSelector,
|
|
946
974
|
args: Fr[],
|
|
947
975
|
): Promise<Fr[]> {
|
|
948
|
-
const targetArtifact = await this.
|
|
976
|
+
const targetArtifact = await this.anchoredContractData.getFunctionArtifactWithDebugMetadata(
|
|
949
977
|
targetContractAddress,
|
|
950
978
|
functionSelector,
|
|
951
979
|
);
|
|
980
|
+
if (!targetArtifact) {
|
|
981
|
+
throw new Error(
|
|
982
|
+
`Cannot call ${targetContractAddress}:${functionSelector}: the contract is not registered. ` +
|
|
983
|
+
`Register it via wallet.registerContract(...).`,
|
|
984
|
+
);
|
|
985
|
+
}
|
|
952
986
|
|
|
953
987
|
if (!targetContractAddress.equals(this.contractAddress)) {
|
|
954
988
|
// Standard handshake registry reads are authorized by default; every other cross-contract call needs the hook.
|
|
955
989
|
if (!(await isStandardHandshakeRegistryUtilityRead(targetContractAddress, functionSelector))) {
|
|
956
|
-
const [
|
|
957
|
-
this.
|
|
958
|
-
this.
|
|
990
|
+
const [callerClassId, targetClassId] = await Promise.all([
|
|
991
|
+
this.anchoredContractData.getCurrentClassId(this.contractAddress),
|
|
992
|
+
this.anchoredContractData.getCurrentClassId(targetContractAddress),
|
|
959
993
|
]);
|
|
994
|
+
if (!callerClassId || !targetClassId) {
|
|
995
|
+
throw new Error(
|
|
996
|
+
`Cannot authorize utility call from ${this.contractAddress} to ${targetContractAddress}: ` +
|
|
997
|
+
`${!callerClassId ? this.contractAddress : targetContractAddress} is not registered.`,
|
|
998
|
+
);
|
|
999
|
+
}
|
|
960
1000
|
const request: UtilityCallAuthorizationRequest = {
|
|
961
1001
|
caller: this.contractAddress,
|
|
962
|
-
callerClassId
|
|
1002
|
+
callerClassId,
|
|
963
1003
|
target: targetContractAddress,
|
|
964
|
-
targetClassId
|
|
1004
|
+
targetClassId,
|
|
965
1005
|
functionSelector,
|
|
966
1006
|
functionName: targetArtifact.name,
|
|
967
1007
|
args,
|
|
@@ -1006,7 +1046,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
1006
1046
|
authWitnesses: this.authWitnesses,
|
|
1007
1047
|
capsules: this.capsules,
|
|
1008
1048
|
anchorBlockHeader: this.anchorBlockHeader,
|
|
1009
|
-
|
|
1049
|
+
anchoredContractData: this.anchoredContractData,
|
|
1010
1050
|
noteStore: this.noteStore,
|
|
1011
1051
|
keyStore: this.keyStore,
|
|
1012
1052
|
addressStore: this.addressStore,
|
|
@@ -1056,9 +1096,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
1056
1096
|
*/
|
|
1057
1097
|
async #fetchTxEffects(txHashes: TxHash[]): Promise<Map<string, IndexedTxEffect>> {
|
|
1058
1098
|
const uniqueTxHashes = uniqueBy(txHashes, h => h.toString());
|
|
1059
|
-
const fetched = await Promise.all(
|
|
1060
|
-
uniqueTxHashes.map(h => this.aztecNode.getTxReceipt(h, { includeTxEffect: true })),
|
|
1061
|
-
);
|
|
1099
|
+
const fetched = await Promise.all(uniqueTxHashes.map(h => this.aztecNodeReadCache.getTxReceiptWithEffect(h)));
|
|
1062
1100
|
return new Map(
|
|
1063
1101
|
uniqueTxHashes
|
|
1064
1102
|
.map((h, i): [string, IndexedTxEffect | undefined] => {
|
|
@@ -1092,7 +1130,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
1092
1130
|
const [response] = await Promise.all([
|
|
1093
1131
|
query(),
|
|
1094
1132
|
(async () => {
|
|
1095
|
-
const block = await this.
|
|
1133
|
+
const block = await this.aztecNodeReadCache.getBlock(blockHash);
|
|
1096
1134
|
const header = block?.header;
|
|
1097
1135
|
if (!header) {
|
|
1098
1136
|
throw new Error(`Could not find block header for block hash ${blockHash}`);
|
|
@@ -1119,8 +1157,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
1119
1157
|
}
|
|
1120
1158
|
}
|
|
1121
1159
|
|
|
1122
|
-
|
|
1123
|
-
|
|
1160
|
+
// Registry reads that any contract may issue without an `authorizeUtilityCall` hook. The constrained-delivery
|
|
1161
|
+
// library calls these implicitly for the app, and they are safe to default-authorize: `get_app_siloed_secrets`
|
|
1162
|
+
// siloes every returned secret to `msg_sender`, and `get_non_interactive_handshakes` only exposes ephemeral public
|
|
1163
|
+
// keys, from which the shared secret cannot be derived without the recipient's secret keys.
|
|
1164
|
+
const STANDARD_HANDSHAKE_REGISTRY_DEFAULT_AUTHORIZED_READ_SIGNATURES = [
|
|
1165
|
+
'get_non_interactive_handshakes((Field),u32)',
|
|
1166
|
+
'get_app_siloed_secrets((Field),(Field))',
|
|
1167
|
+
];
|
|
1124
1168
|
|
|
1125
1169
|
async function doesSelectorHaveSignature(functionSelector: FunctionSelector, signature: string): Promise<boolean> {
|
|
1126
1170
|
return functionSelector.equals(await FunctionSelector.fromSignature(signature));
|
|
@@ -1140,9 +1184,10 @@ async function isStandardHandshakeRegistryUtilityRead(
|
|
|
1140
1184
|
return false;
|
|
1141
1185
|
}
|
|
1142
1186
|
|
|
1143
|
-
const
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1187
|
+
const matches = await Promise.all(
|
|
1188
|
+
STANDARD_HANDSHAKE_REGISTRY_DEFAULT_AUTHORIZED_READ_SIGNATURES.map(signature =>
|
|
1189
|
+
doesSelectorHaveSignature(functionSelector, signature),
|
|
1190
|
+
),
|
|
1191
|
+
);
|
|
1192
|
+
return matches.some(Boolean);
|
|
1148
1193
|
}
|
|
@@ -5,8 +5,8 @@ import type { NoteDao } from '@aztec/stdlib/note';
|
|
|
5
5
|
import type { ContractOverrides } from '@aztec/stdlib/tx';
|
|
6
6
|
|
|
7
7
|
import type { BlockSynchronizer } from '../block_synchronizer/block_synchronizer.js';
|
|
8
|
+
import type { ContractSyncService } from '../contract/contract_sync_service.js';
|
|
8
9
|
import type { ContractFunctionSimulator } from '../contract_function_simulator/contract_function_simulator.js';
|
|
9
|
-
import type { ContractSyncService } from '../contract_sync/contract_sync_service.js';
|
|
10
10
|
import type { NotesFilter } from '../notes_filter.js';
|
|
11
11
|
import type { AnchorBlockStore } from '../storage/index.js';
|
|
12
12
|
import type { NoteStore } from '../storage/note_store/note_store.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BBBundlePrivateKernelProver } from '@aztec/bb-prover/client/bundle';
|
|
2
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
-
import { createStore } from '@aztec/kv-store/
|
|
3
|
+
import { createStore } from '@aztec/kv-store/sqlite-opfs';
|
|
4
4
|
import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/providers/bundle';
|
|
5
5
|
import { WASMSimulator } from '@aztec/simulator/client';
|
|
6
6
|
import { getStandardAuthRegistry } from '@aztec/standard-contracts/auth-registry';
|
|
@@ -37,7 +37,7 @@ export async function createPXE(
|
|
|
37
37
|
...l1ContractAddresses,
|
|
38
38
|
} as PXEConfig;
|
|
39
39
|
|
|
40
|
-
const storeLogger = loggers.store ?? createLogger('pxe:data
|
|
40
|
+
const storeLogger = loggers.store ?? createLogger('pxe:data', { actor });
|
|
41
41
|
|
|
42
42
|
const store =
|
|
43
43
|
options.store ?? (await createStore('pxe_data', configWithContracts, PXE_DATA_SCHEMA_VERSION, storeLogger));
|