@aztec/pxe 0.0.1-commit.3100065 → 0.0.1-commit.321f6a9
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/config/package_info.js +1 -1
- 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/contract_function_simulator.d.ts +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +5 -3
- 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_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/oracle_registry.d.ts +4 -3
- package/dest/contract_function_simulator/oracle/oracle_registry.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle_registry.js +15 -6
- 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 +5 -6
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +6 -3
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +41 -16
- 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/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/private_kernel/batch_planner.d.ts +1 -1
- package/dest/private_kernel/batch_planner.d.ts.map +1 -1
- package/dest/private_kernel/batch_planner.js +1 -1
- 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 +45 -5
- package/dest/pxe.d.ts +1 -1
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +8 -5
- 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 -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/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 +2 -1
- package/dest/tagging/constants.d.ts.map +1 -1
- package/dest/tagging/constants.js +9 -0
- 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/config/package_info.ts +1 -1
- package/src/contract/helpers.ts +3 -3
- package/src/contract/skip_sync_contracts.ts +23 -0
- package/src/contract_function_simulator/contract_function_simulator.ts +5 -3
- package/src/contract_function_simulator/index.ts +23 -3
- 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/oracle_registry.ts +12 -8
- package/src/contract_function_simulator/oracle/oracle_type_mappings.ts +285 -197
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +12 -7
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +55 -17
- 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/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/private_kernel/batch_planner.ts +0 -1
- package/src/private_kernel/private_kernel_execution_prover.ts +90 -4
- package/src/pxe.ts +8 -5
- package/src/storage/fact_store/fact_store.ts +1 -1
- package/src/storage/fact_store/index.ts +1 -0
- package/src/storage/fact_store/origin_state.ts +9 -0
- package/src/storage/store_identity.ts +72 -0
- package/src/storage/tagging_store/sender_tagging_store.ts +62 -15
- package/src/tagging/constants.ts +10 -0
- 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
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
type TaggingSecretStrategy,
|
|
37
37
|
} from '../../hooks/resolve_tagging_secret_strategy.js';
|
|
38
38
|
import { NoteService } from '../../notes/note_service.js';
|
|
39
|
+
import { assertAllowedScope } from '../../storage/allowed_scopes.js';
|
|
39
40
|
import type { SenderTaggingStore } from '../../storage/tagging_store/sender_tagging_store.js';
|
|
40
41
|
import { syncSenderTaggingIndexes } from '../../tagging/index.js';
|
|
41
42
|
import type { ExecutionNoteCache } from '../execution_note_cache.js';
|
|
@@ -321,7 +322,17 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
321
322
|
* @returns The app tagging secret, or `None` if the recipient is invalid.
|
|
322
323
|
*/
|
|
323
324
|
public async getAppTaggingSecret(sender: AztecAddress, recipient: AztecAddress): Promise<Option<Fr>> {
|
|
324
|
-
|
|
325
|
+
assertAllowedScope(sender, this.scopes);
|
|
326
|
+
|
|
327
|
+
const senderCompleteAddress = await this.getCompleteAddressOrFail(sender);
|
|
328
|
+
const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
|
|
329
|
+
const extendedSecret = await AppTaggingSecret.computeViaEcdh(
|
|
330
|
+
senderCompleteAddress,
|
|
331
|
+
senderIvsk,
|
|
332
|
+
recipient,
|
|
333
|
+
this.contractAddress,
|
|
334
|
+
recipient,
|
|
335
|
+
);
|
|
325
336
|
|
|
326
337
|
if (!extendedSecret) {
|
|
327
338
|
this.logger.warn(`Computing a tagging secret for invalid recipient ${recipient} - returning no secret`, {
|
|
@@ -354,12 +365,6 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
354
365
|
return index;
|
|
355
366
|
}
|
|
356
367
|
|
|
357
|
-
async #calculateAppTaggingSecret(contractAddress: AztecAddress, sender: AztecAddress, recipient: AztecAddress) {
|
|
358
|
-
const senderCompleteAddress = await this.getCompleteAddressOrFail(sender);
|
|
359
|
-
const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
|
|
360
|
-
return AppTaggingSecret.computeViaEcdh(senderCompleteAddress, senderIvsk, recipient, contractAddress, recipient);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
368
|
async #getIndexToUseForSecret(secret: AppTaggingSecret): Promise<number> {
|
|
364
369
|
// If we have the tagging index in the cache, we use it. If not we obtain it from the execution data provider.
|
|
365
370
|
const lastUsedIndexInTx = this.taggingIndexCache.getLastUsedIndex(secret);
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
type Capsule,
|
|
36
36
|
type IndexedTxEffect,
|
|
37
37
|
type OffchainEffect,
|
|
38
|
+
type TxEffect,
|
|
38
39
|
type TxHash,
|
|
39
40
|
} from '@aztec/stdlib/tx';
|
|
40
41
|
|
|
@@ -48,6 +49,7 @@ import { TxResolverService } from '../../messages/tx_resolver_service.js';
|
|
|
48
49
|
import { NoteService } from '../../notes/note_service.js';
|
|
49
50
|
import { ORACLE_VERSION_MAJOR } from '../../oracle_version.js';
|
|
50
51
|
import type { AddressStore } from '../../storage/address_store/address_store.js';
|
|
52
|
+
import { assertAllowedScope } from '../../storage/allowed_scopes.js';
|
|
51
53
|
import type { CapsuleService } from '../../storage/capsule_store/capsule_service.js';
|
|
52
54
|
import { FactCollectionKey, FactCollectionTypeKey, anchoredTipBlockNumbers } from '../../storage/fact_store/index.js';
|
|
53
55
|
import type { FactService, OriginBlock } from '../../storage/fact_store/index.js';
|
|
@@ -612,6 +614,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
612
614
|
this.recipientTaggingStore,
|
|
613
615
|
this.taggingSecretSourcesStore,
|
|
614
616
|
this.addressStore,
|
|
617
|
+
this.scopes,
|
|
615
618
|
this.jobId,
|
|
616
619
|
this.logger.getBindings(),
|
|
617
620
|
);
|
|
@@ -683,21 +686,25 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
683
686
|
throw new Error('Invalid tx hash passed into aztec_utl_getTxEffect oracle handler');
|
|
684
687
|
}
|
|
685
688
|
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
+
return await this.#getTxEffectOption(txHash);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/** Fetches transaction effects for all hashes, preserving request order. */
|
|
693
|
+
public async getTxEffects(txHashes: EphemeralArray<TxHash>): Promise<EphemeralArray<Option<TxEffectData>>> {
|
|
694
|
+
const hashes = txHashes.readAll(this.ephemeralArrayService);
|
|
695
|
+
const invalidHash = hashes.find(txHash => txHash.hash.isZero());
|
|
696
|
+
if (invalidHash) {
|
|
697
|
+
throw new Error('Invalid tx hash passed into aztec_utl_getTxEffects oracle handler');
|
|
689
698
|
}
|
|
690
699
|
|
|
691
|
-
const
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
})),
|
|
700
|
-
});
|
|
700
|
+
const uniqueTxHashes = uniqueBy(hashes, h => h.toString());
|
|
701
|
+
const options = await Promise.all(uniqueTxHashes.map(txHash => this.#getTxEffectOption(txHash)));
|
|
702
|
+
const optionsByHash = new Map(uniqueTxHashes.map((txHash, i) => [txHash.toString(), options[i]]));
|
|
703
|
+
|
|
704
|
+
return EphemeralArray.fromValues(
|
|
705
|
+
this.ephemeralArrayService,
|
|
706
|
+
hashes.map(txHash => optionsByHash.get(txHash.toString())!),
|
|
707
|
+
);
|
|
701
708
|
}
|
|
702
709
|
|
|
703
710
|
public setCapsule(contractAddress: AztecAddress, slot: Fr, capsule: Fr[], scope: AztecAddress): void {
|
|
@@ -852,13 +859,17 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
852
859
|
// TODO(#11849): consider replacing this oracle with a pure Noir implementation of aes decryption.
|
|
853
860
|
public async decryptAes128(
|
|
854
861
|
ciphertext: BoundedVec<number>,
|
|
855
|
-
iv:
|
|
856
|
-
symKey:
|
|
862
|
+
iv: number[],
|
|
863
|
+
symKey: number[],
|
|
857
864
|
): Promise<Option<BoundedVec<number>>> {
|
|
858
865
|
const capacity = ciphertext.maxLength;
|
|
859
866
|
try {
|
|
860
867
|
const aes128 = new Aes128();
|
|
861
|
-
const plaintext = await aes128.decryptBufferCBC(
|
|
868
|
+
const plaintext = await aes128.decryptBufferCBC(
|
|
869
|
+
Buffer.from(ciphertext.data),
|
|
870
|
+
Buffer.from(iv),
|
|
871
|
+
Buffer.from(symKey),
|
|
872
|
+
);
|
|
862
873
|
return Option.some(BoundedVec.from<number>({ data: [...plaintext], maxLength: capacity }));
|
|
863
874
|
} catch {
|
|
864
875
|
return Option.none({ maxLength: capacity });
|
|
@@ -871,7 +882,8 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
871
882
|
* @param ephPks - Ephemeral array containing the serialized Points.
|
|
872
883
|
* @param contractAddress - The contract address for app-siloing (validated against execution context).
|
|
873
884
|
* @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
|
|
885
|
+
* hold the keys for `address`.
|
|
886
|
+
* @throws If `address` is not in the execution's allowed scopes.
|
|
875
887
|
*/
|
|
876
888
|
public async getSharedSecrets(
|
|
877
889
|
address: AztecAddress,
|
|
@@ -883,6 +895,11 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
883
895
|
`getSharedSecrets called with contract address ${contractAddress}, expected ${this.contractAddress}`,
|
|
884
896
|
);
|
|
885
897
|
}
|
|
898
|
+
|
|
899
|
+
assertAllowedScope(address, this.scopes);
|
|
900
|
+
|
|
901
|
+
// An address can be in scope without the PXE holding its keys (e.g. syncing a registered but non-owned account),
|
|
902
|
+
// in which case no secrets can be derived and we return an empty array rather than failing.
|
|
886
903
|
const recipientCompleteAddress = await this.addressStore.getCompleteAddress(address);
|
|
887
904
|
if (!recipientCompleteAddress) {
|
|
888
905
|
this.logger.warn(
|
|
@@ -1119,6 +1136,27 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
1119
1136
|
);
|
|
1120
1137
|
}
|
|
1121
1138
|
|
|
1139
|
+
async #getTxEffectOption(txHash: TxHash): Promise<Option<TxEffectData>> {
|
|
1140
|
+
const receipt = await this.aztecNodeReadCache.getTxReceiptWithEffect(txHash);
|
|
1141
|
+
if (!receipt.isMined() || !receipt.txEffect || receipt.blockNumber > this.anchorBlockHeader.getBlockNumber()) {
|
|
1142
|
+
return Option.none();
|
|
1143
|
+
}
|
|
1144
|
+
return Option.some(this.#toTxEffectData(receipt.txEffect));
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
#toTxEffectData(txEffect: TxEffect): TxEffectData {
|
|
1148
|
+
return {
|
|
1149
|
+
...txEffect,
|
|
1150
|
+
revertCode: txEffect.revertCode.getCode(),
|
|
1151
|
+
publicLogs: FlatPublicLogs.fromLogs(txEffect.publicLogs),
|
|
1152
|
+
contractClassLogs: txEffect.contractClassLogs.map(log => ({
|
|
1153
|
+
contractAddress: log.contractAddress,
|
|
1154
|
+
fields: log.fields.toFields(),
|
|
1155
|
+
emittedLength: log.emittedLength,
|
|
1156
|
+
})),
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1122
1160
|
/** Runs a query concurrently with a validation that the block hash is not ahead of the anchor block. */
|
|
1123
1161
|
async #queryWithBlockHashNotAfterAnchor<T>(blockHash: BlockHash, query: () => Promise<T>): Promise<T> {
|
|
1124
1162
|
// Most contracts query state at the "current" block, which is the anchor. Skip the validation when we can.
|
|
@@ -1,6 +1,5 @@
|
|
|
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/sqlite-opfs';
|
|
4
3
|
import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/providers/bundle';
|
|
5
4
|
import { WASMSimulator } from '@aztec/simulator/client';
|
|
6
5
|
import { getStandardAuthRegistry } from '@aztec/standard-contracts/auth-registry';
|
|
@@ -12,6 +11,7 @@ import type { PXEConfig } from '../../../config/index.js';
|
|
|
12
11
|
import { PXE } from '../../../pxe.js';
|
|
13
12
|
import { PXE_DATA_SCHEMA_VERSION } from '../../../storage/metadata.js';
|
|
14
13
|
import { type PXECreationOptions, isPrivateKernelProver } from '../../pxe_creation_options.js';
|
|
14
|
+
import { openBrowserStore } from '../store.js';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Create and start an PXE instance with the given AztecNode.
|
|
@@ -31,16 +31,28 @@ export async function createPXE(
|
|
|
31
31
|
const actor = options.loggerActorLabel;
|
|
32
32
|
const loggers = options.loggers ?? {};
|
|
33
33
|
|
|
34
|
-
const l1ContractAddresses = await aztecNode.
|
|
34
|
+
const { l1ChainId, l1ContractAddresses, rollupVersion } = await aztecNode.getNodeInfo();
|
|
35
35
|
const configWithContracts = {
|
|
36
36
|
...config,
|
|
37
37
|
...l1ContractAddresses,
|
|
38
|
+
l1ChainId,
|
|
39
|
+
rollupVersion,
|
|
38
40
|
} as PXEConfig;
|
|
39
41
|
|
|
40
42
|
const storeLogger = loggers.store ?? createLogger('pxe:data', { actor });
|
|
41
43
|
|
|
42
44
|
const store =
|
|
43
|
-
options.store ??
|
|
45
|
+
options.store ??
|
|
46
|
+
(await openBrowserStore(
|
|
47
|
+
'pxe_data',
|
|
48
|
+
PXE_DATA_SCHEMA_VERSION,
|
|
49
|
+
{
|
|
50
|
+
l1ChainId,
|
|
51
|
+
rollupAddress: l1ContractAddresses.rollupAddress,
|
|
52
|
+
dataStoreMapSizeKb: configWithContracts.dataStoreMapSizeKb,
|
|
53
|
+
},
|
|
54
|
+
storeLogger,
|
|
55
|
+
));
|
|
44
56
|
|
|
45
57
|
const simulator = options.simulator ?? new WASMSimulator();
|
|
46
58
|
const proverLogger = loggers.prover ?? createLogger('pxe:bb:wasm:bundle', { actor });
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { BBLazyPrivateKernelProver } from '@aztec/bb-prover/client/lazy';
|
|
2
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
-
import { createStore } from '@aztec/kv-store/sqlite-opfs';
|
|
4
3
|
import { LazyProtocolContractsProvider } from '@aztec/protocol-contracts/providers/lazy';
|
|
5
4
|
import { WASMSimulator } from '@aztec/simulator/client';
|
|
6
5
|
import { getStandardAuthRegistry } from '@aztec/standard-contracts/auth-registry/lazy';
|
|
@@ -12,6 +11,7 @@ import type { PXEConfig } from '../../../config/index.js';
|
|
|
12
11
|
import { PXE } from '../../../pxe.js';
|
|
13
12
|
import { PXE_DATA_SCHEMA_VERSION } from '../../../storage/metadata.js';
|
|
14
13
|
import { type PXECreationOptions, isPrivateKernelProver } from '../../pxe_creation_options.js';
|
|
14
|
+
import { openBrowserStore } from '../store.js';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Create and start an PXE instance with the given AztecNode.
|
|
@@ -29,10 +29,12 @@ export async function createPXE(
|
|
|
29
29
|
) {
|
|
30
30
|
const actor = options.loggerActorLabel;
|
|
31
31
|
|
|
32
|
-
const l1ContractAddresses = await aztecNode.
|
|
32
|
+
const { l1ChainId, l1ContractAddresses, rollupVersion } = await aztecNode.getNodeInfo();
|
|
33
33
|
const configWithContracts = {
|
|
34
34
|
...config,
|
|
35
35
|
...l1ContractAddresses,
|
|
36
|
+
l1ChainId,
|
|
37
|
+
rollupVersion,
|
|
36
38
|
} as PXEConfig;
|
|
37
39
|
|
|
38
40
|
const loggers = options.loggers ?? {};
|
|
@@ -40,7 +42,17 @@ export async function createPXE(
|
|
|
40
42
|
const storeLogger = loggers.store ?? createLogger('pxe:data', { actor });
|
|
41
43
|
|
|
42
44
|
const store =
|
|
43
|
-
options.store ??
|
|
45
|
+
options.store ??
|
|
46
|
+
(await openBrowserStore(
|
|
47
|
+
'pxe_data',
|
|
48
|
+
PXE_DATA_SCHEMA_VERSION,
|
|
49
|
+
{
|
|
50
|
+
l1ChainId,
|
|
51
|
+
rollupAddress: l1ContractAddresses.rollupAddress,
|
|
52
|
+
dataStoreMapSizeKb: configWithContracts.dataStoreMapSizeKb,
|
|
53
|
+
},
|
|
54
|
+
storeLogger,
|
|
55
|
+
));
|
|
44
56
|
|
|
45
57
|
const simulator = options.simulator ?? new WASMSimulator();
|
|
46
58
|
const proverLogger = loggers.prover ?? createLogger('pxe:bb:wasm:bundle', { actor });
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
+
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
3
|
+
import {
|
|
4
|
+
AztecSQLiteOPFSStore,
|
|
5
|
+
SqliteCorruptionError,
|
|
6
|
+
deleteStore,
|
|
7
|
+
storePoolDirectory,
|
|
8
|
+
} from '@aztec/kv-store/sqlite-opfs';
|
|
9
|
+
|
|
10
|
+
import { assertStoreIdentity, effectiveStoreName } from '../../storage/store_identity.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Opens the persistent browser (sqlite-opfs) store selected by `name` and identity `(config.l1ChainId,
|
|
14
|
+
* config.rollupAddress, schemaVersion)` triple. A store exists per identity: reopening with the same identity returns
|
|
15
|
+
* the same data, a different identity selects a different (possibly fresh) store.
|
|
16
|
+
*/
|
|
17
|
+
export async function openBrowserStore(
|
|
18
|
+
name: string,
|
|
19
|
+
schemaVersion: number,
|
|
20
|
+
config: { l1ChainId: number; rollupAddress: EthAddress; dataStoreMapSizeKb?: number },
|
|
21
|
+
log: Logger = createLogger('pxe:data'),
|
|
22
|
+
): Promise<AztecSQLiteOPFSStore> {
|
|
23
|
+
const identity = { l1ChainId: config.l1ChainId, rollupAddress: config.rollupAddress, schemaVersion };
|
|
24
|
+
const storeName = effectiveStoreName(name, identity);
|
|
25
|
+
log.info(`Creating ${storeName} SQLite-OPFS data store`, {
|
|
26
|
+
storeName,
|
|
27
|
+
dataStoreMapSizeKb: config.dataStoreMapSizeKb,
|
|
28
|
+
});
|
|
29
|
+
const openStore = () =>
|
|
30
|
+
AztecSQLiteOPFSStore.open(createLogger('kv-store:sqlite-opfs'), storeName, false, storePoolDirectory(storeName));
|
|
31
|
+
|
|
32
|
+
let store: AztecSQLiteOPFSStore;
|
|
33
|
+
try {
|
|
34
|
+
store = await openStore();
|
|
35
|
+
} catch (err) {
|
|
36
|
+
if (!(err instanceof SqliteCorruptionError)) {
|
|
37
|
+
throw err;
|
|
38
|
+
}
|
|
39
|
+
// A corrupt image is unrecoverable — no retry against the same bytes helps. Wipe the store's OPFS directory
|
|
40
|
+
// (safe: the failed open left no SAH-pool lock behind) and reopen a fresh, empty one, so the browser self-heals
|
|
41
|
+
// into a normal first-run rather than dead-ending on "database disk image is malformed" every load.
|
|
42
|
+
log.warn(`${storeName} store is corrupt (${err.message}); wiping and reopening fresh`);
|
|
43
|
+
await deleteStore(storeName);
|
|
44
|
+
store = await openStore();
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
await assertStoreIdentity(store, storeName, identity);
|
|
48
|
+
} catch (err) {
|
|
49
|
+
// The store handle owns a worker and OPFS locks; release them before surfacing the refusal.
|
|
50
|
+
await store.close().catch(() => {});
|
|
51
|
+
throw err;
|
|
52
|
+
}
|
|
53
|
+
return store;
|
|
54
|
+
}
|
|
@@ -6,6 +6,7 @@ export * from '../../config/index.js';
|
|
|
6
6
|
export * from '../../error_enriching.js';
|
|
7
7
|
export * from '../../storage/index.js';
|
|
8
8
|
export * from './utils.js';
|
|
9
|
+
export * from './store.js';
|
|
9
10
|
export { NoteService } from '../../notes/note_service.js';
|
|
10
11
|
export { ORACLE_VERSION_MAJOR, ORACLE_VERSION_MINOR } from '../../oracle_version.js';
|
|
11
12
|
export { type PXECreationOptions } from '../pxe_creation_options.js';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
+
import { type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
3
|
+
import { type AztecLMDBStoreV2, openStoreAt } from '@aztec/kv-store/lmdb-v2';
|
|
4
|
+
|
|
5
|
+
import { mkdir } from 'fs/promises';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
|
|
8
|
+
import { storeIdentitySlug } from '../../storage/store_identity.js';
|
|
9
|
+
|
|
10
|
+
/** Location and identity inputs for opening an identity-partitioned PXE-side store. */
|
|
11
|
+
export type IdentityStoreConfig = {
|
|
12
|
+
dataDirectory: string;
|
|
13
|
+
/** Maximum LMDB map size in KB. When omitted, the kv-store default map size applies. */
|
|
14
|
+
dataStoreMapSizeKb?: number;
|
|
15
|
+
l1ChainId: number;
|
|
16
|
+
rollupAddress: EthAddress;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Opens the persistent LMDB store selected by `name` and identity triple `(l1ChainId, rollupAddress, schemaVersion)`.
|
|
21
|
+
* A store exists per identity: reopening with the same identity returns the same data, a different identity selects
|
|
22
|
+
* a different (possibly fresh) store. Callers wanting an ephemeral store use `openTmpStore` explicitly instead.
|
|
23
|
+
*/
|
|
24
|
+
export async function openStore(
|
|
25
|
+
name: string,
|
|
26
|
+
schemaVersion: number,
|
|
27
|
+
config: IdentityStoreConfig,
|
|
28
|
+
bindings?: LoggerBindings,
|
|
29
|
+
): Promise<AztecLMDBStoreV2> {
|
|
30
|
+
// Stores live under `<dataDirectory>/<name>-stores/<l1ChainId>-<rollupAddress>-v<schemaVersion>`, a sibling of the
|
|
31
|
+
// legacy `<dataDirectory>/<name>` directory: older binaries reset the legacy directory on a rollup mismatch, so
|
|
32
|
+
// per-identity stores must not nest inside it.
|
|
33
|
+
const subDir = join(
|
|
34
|
+
config.dataDirectory,
|
|
35
|
+
`${name}-stores`,
|
|
36
|
+
storeIdentitySlug({ l1ChainId: config.l1ChainId, rollupAddress: config.rollupAddress, schemaVersion }),
|
|
37
|
+
);
|
|
38
|
+
await mkdir(subDir, { recursive: true });
|
|
39
|
+
|
|
40
|
+
createLogger(`pxe:data:${name}`, bindings).info(`Opening ${name} data store (LMDB v2)`, {
|
|
41
|
+
storeName: name,
|
|
42
|
+
subDir,
|
|
43
|
+
dataStoreMapSizeKb: config.dataStoreMapSizeKb,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
return openStoreAt(subDir, config.dataStoreMapSizeKb, undefined, bindings);
|
|
47
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BBBundlePrivateKernelProver } from '@aztec/bb-prover/client/bundle';
|
|
2
2
|
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
|
-
import {
|
|
4
|
+
import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
|
|
5
5
|
import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/providers/bundle';
|
|
6
6
|
import { WASMSimulator } from '@aztec/simulator/client';
|
|
7
7
|
import { MemoryCircuitRecorder, SimulatorRecorderWrapper } from '@aztec/simulator/server';
|
|
@@ -15,6 +15,7 @@ import type { PXEConfig } from '../../config/index.js';
|
|
|
15
15
|
import { PXE } from '../../pxe.js';
|
|
16
16
|
import { PXE_DATA_SCHEMA_VERSION } from '../../storage/index.js';
|
|
17
17
|
import { type PXECreationOptions, isPrivateKernelProver } from '../pxe_creation_options.js';
|
|
18
|
+
import { openStore } from './store.js';
|
|
18
19
|
|
|
19
20
|
type PXEConfigWithoutDefaults = Omit<
|
|
20
21
|
PXEConfig,
|
|
@@ -46,12 +47,25 @@ export async function createPXE(
|
|
|
46
47
|
|
|
47
48
|
if (!options.store) {
|
|
48
49
|
const storeLogger = loggers.store ?? createLogger('pxe:data:lmdb', { actor });
|
|
49
|
-
options.store =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
options.store = configWithContracts.dataDirectory
|
|
51
|
+
? await openStore(
|
|
52
|
+
'pxe_data',
|
|
53
|
+
PXE_DATA_SCHEMA_VERSION,
|
|
54
|
+
{
|
|
55
|
+
dataDirectory: configWithContracts.dataDirectory,
|
|
56
|
+
dataStoreMapSizeKb: configWithContracts.dataStoreMapSizeKb,
|
|
57
|
+
l1ChainId,
|
|
58
|
+
rollupAddress: l1ContractAddresses.rollupAddress,
|
|
59
|
+
},
|
|
60
|
+
storeLogger.getBindings(),
|
|
61
|
+
)
|
|
62
|
+
: await openTmpStore(
|
|
63
|
+
'pxe_data',
|
|
64
|
+
true,
|
|
65
|
+
configWithContracts.dataStoreMapSizeKb,
|
|
66
|
+
undefined,
|
|
67
|
+
storeLogger.getBindings(),
|
|
68
|
+
);
|
|
55
69
|
}
|
|
56
70
|
const proverLogger = loggers.prover ?? createLogger('pxe:bb:native', { actor });
|
|
57
71
|
|
package/src/logs/log_service.ts
CHANGED
|
@@ -22,8 +22,8 @@ import {
|
|
|
22
22
|
} from '../contract_function_simulator/noir-structs/log_retrieval_request.js';
|
|
23
23
|
import type { LogRetrievalResponse } from '../contract_function_simulator/noir-structs/log_retrieval_response.js';
|
|
24
24
|
import type { PendingTaggedLog } from '../contract_function_simulator/noir-structs/pending_tagged_log.js';
|
|
25
|
-
import { ResolvedTx } from '../contract_function_simulator/noir-structs/resolved_tx.js';
|
|
26
25
|
import { AddressStore } from '../storage/address_store/address_store.js';
|
|
26
|
+
import { assertAllowedScope } from '../storage/allowed_scopes.js';
|
|
27
27
|
import type { RecipientTaggingStore } from '../storage/tagging_store/recipient_tagging_store.js';
|
|
28
28
|
import type { TaggingSecretSourcesStore } from '../storage/tagging_store/tagging_secret_sources_store.js';
|
|
29
29
|
import {
|
|
@@ -47,6 +47,7 @@ export class LogService {
|
|
|
47
47
|
private readonly recipientTaggingStore: RecipientTaggingStore,
|
|
48
48
|
private readonly taggingSecretSourcesStore: TaggingSecretSourcesStore,
|
|
49
49
|
private readonly addressStore: AddressStore,
|
|
50
|
+
private readonly scopes: AztecAddress[],
|
|
50
51
|
private readonly jobId: string,
|
|
51
52
|
bindings?: LoggerBindings,
|
|
52
53
|
) {
|
|
@@ -189,6 +190,8 @@ export class LogService {
|
|
|
189
190
|
recipient: AztecAddress,
|
|
190
191
|
providedSecrets: AppTaggingSecret[],
|
|
191
192
|
): Promise<PendingTaggedLog[]> {
|
|
193
|
+
assertAllowedScope(recipient, this.scopes);
|
|
194
|
+
|
|
192
195
|
this.log.verbose(
|
|
193
196
|
`Fetching tagged logs for contract ${contractAddress.toString()} and recipient ${recipient.toString()}`,
|
|
194
197
|
);
|
|
@@ -221,7 +224,13 @@ export class LogService {
|
|
|
221
224
|
}
|
|
222
225
|
return {
|
|
223
226
|
log: log.logData,
|
|
224
|
-
context:
|
|
227
|
+
context: {
|
|
228
|
+
txHash: log.txHash,
|
|
229
|
+
uniqueNoteHashesInTx: noteHashes,
|
|
230
|
+
firstNullifierInTx: nullifiers[0],
|
|
231
|
+
blockNumber: log.blockNumber,
|
|
232
|
+
blockHash: log.blockHash.toFr(),
|
|
233
|
+
},
|
|
225
234
|
};
|
|
226
235
|
});
|
|
227
236
|
}
|
|
@@ -3,7 +3,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
|
|
|
3
3
|
import type { AztecNode } from '@aztec/stdlib/interfaces/server';
|
|
4
4
|
import { type IndexedTxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
5
5
|
|
|
6
|
-
import { ResolvedTx } from '../contract_function_simulator/noir-structs/resolved_tx.js';
|
|
6
|
+
import type { ResolvedTx } from '../contract_function_simulator/noir-structs/resolved_tx.js';
|
|
7
7
|
|
|
8
8
|
/** Resolves transaction hashes into their on-chain context (note hashes, first nullifier, and mined block). */
|
|
9
9
|
export class TxResolverService {
|
|
@@ -57,13 +57,13 @@ export class TxResolverService {
|
|
|
57
57
|
throw new Error(`Tx effect for ${txHash} has no nullifiers`);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
return
|
|
61
|
-
data.txHash,
|
|
62
|
-
data.noteHashes,
|
|
63
|
-
data.nullifiers[0],
|
|
64
|
-
txEffect.l2BlockNumber,
|
|
65
|
-
txEffect.l2BlockHash.toFr(),
|
|
66
|
-
|
|
60
|
+
return {
|
|
61
|
+
txHash: data.txHash,
|
|
62
|
+
uniqueNoteHashesInTx: data.noteHashes,
|
|
63
|
+
firstNullifierInTx: data.nullifiers[0],
|
|
64
|
+
blockNumber: txEffect.l2BlockNumber,
|
|
65
|
+
blockHash: txEffect.l2BlockHash.toFr(),
|
|
66
|
+
};
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
}
|
|
@@ -26,7 +26,7 @@ export class NoteService {
|
|
|
26
26
|
*
|
|
27
27
|
* @param owner - The owner of the notes. If undefined, returns notes for all known owners.
|
|
28
28
|
* @param status - The status of notes to fetch.
|
|
29
|
-
* @param scopes - The accounts whose notes we can access in this call.
|
|
29
|
+
* @param scopes - The accounts whose notes we can access in this call. An empty list matches no notes.
|
|
30
30
|
*/
|
|
31
31
|
public async getNotes(
|
|
32
32
|
contractAddress: AztecAddress,
|
package/src/oracle_version.ts
CHANGED
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
/// if AZTEC_NR_MINOR > PXE_MINOR because if a contract is updated to use a newer Aztec.nr dependency without actually
|
|
12
12
|
/// using any of the new oracles then there is no reason to throw.
|
|
13
13
|
export const ORACLE_VERSION_MAJOR = 30;
|
|
14
|
-
export const ORACLE_VERSION_MINOR =
|
|
14
|
+
export const ORACLE_VERSION_MINOR = 8;
|
|
15
15
|
|
|
16
|
-
/// This hash is computed from
|
|
16
|
+
/// This hash is computed from `ORACLE_REGISTRY` (each oracle's name, ordered parameter names and
|
|
17
17
|
/// types, and return type) and is used to detect when the oracle interface changes. When it does, you need to either:
|
|
18
18
|
/// - increment `ORACLE_VERSION_MAJOR` and reset `ORACLE_VERSION_MINOR` to zero if the change is breaking, or
|
|
19
19
|
/// - increment only `ORACLE_VERSION_MINOR` if the change is additive (a new oracle was added).
|
|
20
20
|
///
|
|
21
21
|
/// These constants must be kept in sync between this file and `noir-projects/aztec-nr/aztec/src/oracle/version.nr`.
|
|
22
|
-
export const ORACLE_INTERFACE_HASH = '
|
|
22
|
+
export const ORACLE_INTERFACE_HASH = 'fec4d3a95fc57a62a20bfeb659bb3bfd91b31cd93e07f8cf97b368f9f55cc67b';
|