@aztec/pxe 5.0.0-nightly.20260708 → 5.0.0-nightly.20260710

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.
Files changed (48) hide show
  1. package/dest/contract_function_simulator/aztec_node_read_cache.d.ts +39 -0
  2. package/dest/contract_function_simulator/aztec_node_read_cache.d.ts.map +1 -0
  3. package/dest/contract_function_simulator/aztec_node_read_cache.js +60 -0
  4. package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.d.ts +1 -1
  5. package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.d.ts.map +1 -1
  6. package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.js +7 -0
  7. package/dest/contract_function_simulator/oracle/acir_callback.js +1 -1
  8. package/dest/contract_function_simulator/oracle/legacy_oracle_registry.d.ts +3 -3
  9. package/dest/contract_function_simulator/oracle/legacy_oracle_registry.d.ts.map +1 -1
  10. package/dest/contract_function_simulator/oracle/legacy_oracle_registry.js +34 -1
  11. package/dest/contract_function_simulator/oracle/oracle_registry.d.ts +4 -2
  12. package/dest/contract_function_simulator/oracle/oracle_registry.d.ts.map +1 -1
  13. package/dest/contract_function_simulator/oracle/oracle_registry.js +26 -8
  14. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +1 -1
  15. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  16. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +2 -4
  17. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +9 -6
  18. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  19. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +21 -19
  20. package/dest/hooks/index.d.ts +2 -2
  21. package/dest/hooks/index.d.ts.map +1 -1
  22. package/dest/hooks/index.js +1 -0
  23. package/dest/hooks/resolve_tagging_secret_strategy.d.ts +3 -1
  24. package/dest/hooks/resolve_tagging_secret_strategy.d.ts.map +1 -1
  25. package/dest/hooks/resolve_tagging_secret_strategy.js +3 -3
  26. package/dest/oracle_version.d.ts +2 -2
  27. package/dest/oracle_version.js +2 -2
  28. package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts +1 -1
  29. package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts.map +1 -1
  30. package/dest/storage/backwards_compatibility_tests/schema_tests.js +26 -2
  31. package/dest/storage/metadata.d.ts +1 -1
  32. package/dest/storage/metadata.js +1 -1
  33. package/package.json +17 -17
  34. package/src/contract_function_simulator/aztec_node_read_cache.ts +89 -0
  35. package/src/contract_function_simulator/noir-structs/resolved_tagging_strategy.ts +8 -0
  36. package/src/contract_function_simulator/oracle/acir_callback.ts +1 -1
  37. package/src/contract_function_simulator/oracle/legacy_oracle_registry.ts +30 -3
  38. package/src/contract_function_simulator/oracle/oracle_registry.ts +20 -3
  39. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +5 -5
  40. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +38 -23
  41. package/src/hooks/index.ts +1 -0
  42. package/src/hooks/resolve_tagging_secret_strategy.ts +3 -0
  43. package/src/oracle_version.ts +2 -2
  44. package/src/storage/backwards_compatibility_tests/__snapshots__/RecipientTaggingStore.json +11 -3
  45. package/src/storage/backwards_compatibility_tests/__snapshots__/SenderTaggingStore.json +12 -4
  46. package/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json +1 -1
  47. package/src/storage/backwards_compatibility_tests/schema_tests.ts +30 -1
  48. package/src/storage/metadata.ts +1 -1
@@ -3,6 +3,7 @@ import { ARCHIVE_HEIGHT, NOTE_HASH_TREE_HEIGHT } from '@aztec/constants';
3
3
  import { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import { FieldReader } from '@aztec/foundation/serialize';
5
5
  import { toACVMField } from '@aztec/simulator/client';
6
+ import type { UnsiloedMessageNullifier } from '@aztec/stdlib/messaging';
6
7
 
7
8
  import {
8
9
  ARRAY,
@@ -45,6 +46,7 @@ import {
45
46
  RESOLVED_TAGGING_STRATEGY,
46
47
  RESOLVED_TX,
47
48
  STR,
49
+ STRUCT,
48
50
  TX_EFFECT,
49
51
  TX_HASH,
50
52
  type TypeMapping,
@@ -139,6 +141,14 @@ export const ORACLE_REGISTRY = {
139
141
  returnType: OPTION(MEMBERSHIP_WITNESS(ARCHIVE_HEIGHT)),
140
142
  }),
141
143
 
144
+ aztec_utl_areBlockHashesInArchive: makeEntry({
145
+ params: [
146
+ { name: 'anchorBlockHash', type: BLOCK_HASH },
147
+ { name: 'blockHashes', type: EPHEMERAL_ARRAY(BLOCK_HASH) },
148
+ ],
149
+ returnType: EPHEMERAL_ARRAY(BOOL),
150
+ }),
151
+
142
152
  aztec_utl_getNullifierMembershipWitness: makeEntry({
143
153
  params: [
144
154
  { name: 'blockHash', type: BLOCK_HASH },
@@ -183,11 +193,18 @@ export const ORACLE_REGISTRY = {
183
193
  returnType: BOOL,
184
194
  }),
185
195
 
186
- aztec_utl_getL1ToL2MembershipWitness: makeEntry({
196
+ aztec_utl_getL1ToL2MembershipWitnessV2: makeEntry({
187
197
  params: [
188
- { name: 'contractAddress', type: AZTEC_ADDRESS },
189
198
  { name: 'messageHash', type: FIELD },
190
- { name: 'secret', type: FIELD },
199
+ {
200
+ name: 'nullifier',
201
+ type: OPTION(
202
+ STRUCT<UnsiloedMessageNullifier>([
203
+ { name: 'contractAddress', type: AZTEC_ADDRESS },
204
+ { name: 'nullifier', type: FIELD },
205
+ ]),
206
+ ),
207
+ },
191
208
  ],
192
209
  returnType: MESSAGE_LOAD_ORACLE_INPUTS,
193
210
  }),
@@ -30,9 +30,10 @@ import {
30
30
  } from '@aztec/stdlib/tx';
31
31
 
32
32
  import type { ResolveCustomRequest } from '../../hooks/resolve_custom_request.js';
33
- import type {
34
- ResolveTaggingSecretStrategy,
35
- TaggingSecretStrategy,
33
+ import {
34
+ DEFAULT_TAGGING_SECRET_STRATEGY,
35
+ type ResolveTaggingSecretStrategy,
36
+ type TaggingSecretStrategy,
36
37
  } from '../../hooks/resolve_tagging_secret_strategy.js';
37
38
  import { NoteService } from '../../notes/note_service.js';
38
39
  import type { SenderTaggingStore } from '../../storage/tagging_store/sender_tagging_store.js';
@@ -233,8 +234,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
233
234
  ): Promise<TaggingSecretStrategy> {
234
235
  const hook: ResolveTaggingSecretStrategy | undefined = this.hooks?.resolveTaggingSecretStrategy;
235
236
  if (!hook) {
236
- // With no hook, both delivery modes default to a non-interactive handshake
237
- return { type: 'non-interactive-handshake' };
237
+ return DEFAULT_TAGGING_SECRET_STRATEGY;
238
238
  }
239
239
 
240
240
  const contractClassId = await this.#getCurrentContractClassId(this.contractAddress);
@@ -26,7 +26,7 @@ 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
28
  import { AppTaggingSecret, FlatPublicLogs, appSiloEcdhSharedSecret } from '@aztec/stdlib/logs';
29
- import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
29
+ import { type UnsiloedMessageNullifier, getL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
30
30
  import type { NoteStatus } from '@aztec/stdlib/note';
31
31
  import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
32
32
  import {
@@ -56,6 +56,7 @@ import type { PrivateEventStore } from '../../storage/private_event_store/privat
56
56
  import type { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js';
57
57
  import type { TaggingSecretSourcesStore } from '../../storage/tagging_store/tagging_secret_sources_store.js';
58
58
  import type { AnchoredContractData } from '../anchored_contract_data.js';
59
+ import { AztecNodeReadCache } from '../aztec_node_read_cache.js';
59
60
  import { EphemeralArrayService } from '../ephemeral_array_service.js';
60
61
  import { BoundedVec } from '../noir-structs/bounded_vec.js';
61
62
  import type { EmbeddedCurvePoint } from '../noir-structs/embedded_curve_point.js';
@@ -119,6 +120,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
119
120
  private offchainEffects: OffchainEffect[] = [];
120
121
  private readonly ephemeralArrayService = new EphemeralArrayService();
121
122
  protected readonly transientArrayService: TransientArrayService;
123
+ private readonly aztecNodeReadCache: AztecNodeReadCache;
122
124
 
123
125
  // We store oracle version to be able to show a nice error message when an oracle handler is missing.
124
126
  private contractOracleVersion: { major: number; minor: number } | undefined;
@@ -172,6 +174,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
172
174
  this.hooks = args.hooks;
173
175
  this.utilityExecutor = args.utilityExecutor;
174
176
  this.transientArrayService = args.transientArrayService;
177
+ this.aztecNodeReadCache = new AztecNodeReadCache(args.aztecNode);
175
178
  }
176
179
 
177
180
  public assertCompatibleOracleVersion(major: number, minor: number): void {
@@ -265,11 +268,27 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
265
268
  // hash at all. If the block hash did not exist by the reference block hash, then the node will not return the
266
269
  // membership witness as there is none.
267
270
  const witness = await this.#queryWithBlockHashNotAfterAnchor(referenceBlockHash, () =>
268
- this.aztecNode.getBlockHashMembershipWitness(referenceBlockHash, blockHash),
271
+ this.aztecNodeReadCache.getBlockHashMembershipWitness(referenceBlockHash, blockHash),
269
272
  );
270
273
  return witness ? Option.some(witness) : Option.none();
271
274
  }
272
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
+
273
292
  /**
274
293
  * Returns a nullifier membership witness for a given nullifier at a given block.
275
294
  * @param blockHash - The block hash at which to get the index.
@@ -318,7 +337,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
318
337
  */
319
338
  public async getPublicDataWitness(blockHash: BlockHash, leafSlot: Fr): Promise<PublicDataWitness> {
320
339
  const witness = await this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
321
- this.aztecNode.getPublicDataWitness(blockHash, leafSlot),
340
+ this.aztecNodeReadCache.getPublicDataWitness(blockHash, leafSlot),
322
341
  );
323
342
  if (!witness) {
324
343
  throw new Error(`Public data witness not found for slot ${leafSlot} at block hash ${blockHash.toString()}.`);
@@ -478,19 +497,17 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
478
497
  }
479
498
 
480
499
  /**
481
- * Returns the membership witness of an un-nullified L1 to L2 message.
482
- * @param contractAddress - Address of a contract by which the message was emitted.
500
+ * Returns the membership witness of an L1 to L2 message.
483
501
  * @param messageHash - Hash of the message.
484
- * @param secret - Secret used to compute a nullifier.
485
- * @dev Contract address and secret are only used to compute the nullifier to get non-nullified messages
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.
486
504
  * @returns The l1 to l2 membership witness (index of message in the tree and sibling path).
487
505
  */
488
- public async getL1ToL2MembershipWitness(contractAddress: AztecAddress, messageHash: Fr, secret: Fr) {
489
- const [messageIndex, siblingPath] = await getNonNullifiedL1ToL2MessageWitness(
506
+ public async getL1ToL2MembershipWitnessV2(messageHash: Fr, nullifier: Option<UnsiloedMessageNullifier>) {
507
+ const [messageIndex, siblingPath] = await getL1ToL2MessageWitness(
490
508
  this.aztecNode,
491
- contractAddress,
492
509
  messageHash,
493
- secret,
510
+ nullifier.value,
494
511
  await this.anchorBlockHeader.hash(),
495
512
  );
496
513
 
@@ -511,16 +528,16 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
511
528
  numberOfElements: number,
512
529
  ) {
513
530
  return this.#queryWithBlockHashNotAfterAnchor(blockHash, async () => {
514
- const slots = Array(numberOfElements)
515
- .fill(0)
516
- .map((_, i) => new Fr(startStorageSlot.value + BigInt(i)));
517
-
518
- const values = await Promise.all(
519
- slots.map(storageSlot => this.aztecNode.getPublicStorageAt(blockHash, contractAddress, storageSlot)),
531
+ const values = await this.aztecNodeReadCache.getPublicStorageRange(
532
+ blockHash,
533
+ contractAddress,
534
+ startStorageSlot,
535
+ numberOfElements,
520
536
  );
521
537
 
522
538
  this.logger.debug(
523
- `Oracle storage read: slots=[${slots.map(slot => slot.toString()).join(', ')}] address=${contractAddress.toString()} values=[${values.join(', ')}]`,
539
+ `Oracle storage read: start=${startStorageSlot.toString()} count=${numberOfElements} ` +
540
+ `address=${contractAddress.toString()} values=[${values.join(', ')}]`,
524
541
  );
525
542
 
526
543
  return values;
@@ -666,7 +683,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
666
683
  throw new Error('Invalid tx hash passed into aztec_utl_getTxEffect oracle handler');
667
684
  }
668
685
 
669
- const receipt = await this.aztecNode.getTxReceipt(txHash, { includeTxEffect: true });
686
+ const receipt = await this.aztecNodeReadCache.getTxReceiptWithEffect(txHash);
670
687
  if (!receipt.isMined() || !receipt.txEffect || receipt.blockNumber > this.anchorBlockHeader.getBlockNumber()) {
671
688
  return Option.none();
672
689
  }
@@ -1079,9 +1096,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
1079
1096
  */
1080
1097
  async #fetchTxEffects(txHashes: TxHash[]): Promise<Map<string, IndexedTxEffect>> {
1081
1098
  const uniqueTxHashes = uniqueBy(txHashes, h => h.toString());
1082
- const fetched = await Promise.all(
1083
- uniqueTxHashes.map(h => this.aztecNode.getTxReceipt(h, { includeTxEffect: true })),
1084
- );
1099
+ const fetched = await Promise.all(uniqueTxHashes.map(h => this.aztecNodeReadCache.getTxReceiptWithEffect(h)));
1085
1100
  return new Map(
1086
1101
  uniqueTxHashes
1087
1102
  .map((h, i): [string, IndexedTxEffect | undefined] => {
@@ -1115,7 +1130,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
1115
1130
  const [response] = await Promise.all([
1116
1131
  query(),
1117
1132
  (async () => {
1118
- const block = await this.aztecNode.getBlock(blockHash);
1133
+ const block = await this.aztecNodeReadCache.getBlock(blockHash);
1119
1134
  const header = block?.header;
1120
1135
  if (!header) {
1121
1136
  throw new Error(`Could not find block header for block hash ${blockHash}`);
@@ -6,6 +6,7 @@ export type {
6
6
  export { type ExecutionHooks, composeHooks } from './execution_hooks.js';
7
7
  export { type CustomRequest, type ResolveCustomRequest } from './resolve_custom_request.js';
8
8
  export {
9
+ DEFAULT_TAGGING_SECRET_STRATEGY,
9
10
  type ResolveTaggingSecretStrategy,
10
11
  type TaggingSecretStrategy,
11
12
  type TaggingSecretStrategyRequest,
@@ -39,6 +39,9 @@ export type TaggingSecretStrategy =
39
39
  secret: Point;
40
40
  };
41
41
 
42
+ /** The strategy PXE applies to both delivery modes when no `resolveTaggingSecretStrategy` hook is configured. */
43
+ export const DEFAULT_TAGGING_SECRET_STRATEGY: TaggingSecretStrategy = { type: 'non-interactive-handshake' };
44
+
42
45
  /** Information about the message delivery requesting a tagging secret strategy. */
43
46
  export type TaggingSecretStrategyRequest = {
44
47
  contractAddress: AztecAddress;
@@ -11,7 +11,7 @@
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 = 5;
14
+ export const ORACLE_VERSION_MINOR = 7;
15
15
 
16
16
  /// This hash is computed from the `ORACLE_REGISTRY` declaration (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:
@@ -19,4 +19,4 @@ export const ORACLE_VERSION_MINOR = 5;
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 = 'f71b9662ec851e74593764a87792b0a91c181e1410aac49a4507f0bba949f6be';
22
+ export const ORACLE_INTERFACE_HASH = '416b0e7d3e6dca5803ebe2a65ea93f1e79759dc39ef8ec4c52eeba5e2b0f3fca';
@@ -1,17 +1,25 @@
1
1
  {
2
2
  "highest_aged_index": [
3
3
  {
4
- "key": "utf8:0x0000000000000000000000000000000000000000000000000000000000000002:0x0000000000000000000000000000000000000000000000000000000000000003",
4
+ "key": "utf8:constrained:0x0000000000000000000000000000000000000000000000000000000000000013:0x0000000000000000000000000000000000000000000000000000000000000017",
5
+ "value": "num:13"
6
+ },
7
+ {
8
+ "key": "utf8:unconstrained:0x0000000000000000000000000000000000000000000000000000000000000002:0x0000000000000000000000000000000000000000000000000000000000000003",
5
9
  "value": "num:13"
6
10
  }
7
11
  ],
8
12
  "highest_finalized_index": [
9
13
  {
10
- "key": "utf8:0x0000000000000000000000000000000000000000000000000000000000000002:0x0000000000000000000000000000000000000000000000000000000000000003",
14
+ "key": "utf8:constrained:0x0000000000000000000000000000000000000000000000000000000000000013:0x0000000000000000000000000000000000000000000000000000000000000017",
15
+ "value": "num:11"
16
+ },
17
+ {
18
+ "key": "utf8:unconstrained:0x0000000000000000000000000000000000000000000000000000000000000002:0x0000000000000000000000000000000000000000000000000000000000000003",
11
19
  "value": "num:11"
12
20
  },
13
21
  {
14
- "key": "utf8:0x0000000000000000000000000000000000000000000000000000000000000005:0x0000000000000000000000000000000000000000000000000000000000000007",
22
+ "key": "utf8:unconstrained:0x0000000000000000000000000000000000000000000000000000000000000005:0x0000000000000000000000000000000000000000000000000000000000000007",
15
23
  "value": "num:17"
16
24
  }
17
25
  ]
@@ -1,21 +1,29 @@
1
1
  {
2
2
  "pending_indexes": [
3
3
  {
4
- "key": "utf8:0x0000000000000000000000000000000000000000000000000000000000000002:0x0000000000000000000000000000000000000000000000000000000000000003",
4
+ "key": "utf8:constrained:0x0000000000000000000000000000000000000000000000000000000000000013:0x0000000000000000000000000000000000000000000000000000000000000017",
5
+ "value": "[{\"lowestIndex\":4,\"highestIndex\":7,\"txHash\":\"0x0000000000000000000000000000000000000000000000000000000000000025\"}]"
6
+ },
7
+ {
8
+ "key": "utf8:unconstrained:0x0000000000000000000000000000000000000000000000000000000000000002:0x0000000000000000000000000000000000000000000000000000000000000003",
5
9
  "value": "[{\"lowestIndex\":4,\"highestIndex\":7,\"txHash\":\"0x0000000000000000000000000000000000000000000000000000000000000013\"},{\"lowestIndex\":8,\"highestIndex\":11,\"txHash\":\"0x0000000000000000000000000000000000000000000000000000000000000017\"}]"
6
10
  },
7
11
  {
8
- "key": "utf8:0x000000000000000000000000000000000000000000000000000000000000000b:0x000000000000000000000000000000000000000000000000000000000000000d",
12
+ "key": "utf8:unconstrained:0x000000000000000000000000000000000000000000000000000000000000000b:0x000000000000000000000000000000000000000000000000000000000000000d",
9
13
  "value": "[{\"lowestIndex\":1,\"highestIndex\":9,\"txHash\":\"0x000000000000000000000000000000000000000000000000000000000000001d\"}]"
10
14
  }
11
15
  ],
12
16
  "last_finalized_indexes": [
13
17
  {
14
- "key": "utf8:0x0000000000000000000000000000000000000000000000000000000000000002:0x0000000000000000000000000000000000000000000000000000000000000003",
18
+ "key": "utf8:constrained:0x0000000000000000000000000000000000000000000000000000000000000013:0x0000000000000000000000000000000000000000000000000000000000000017",
19
+ "value": "num:3"
20
+ },
21
+ {
22
+ "key": "utf8:unconstrained:0x0000000000000000000000000000000000000000000000000000000000000002:0x0000000000000000000000000000000000000000000000000000000000000003",
15
23
  "value": "num:3"
16
24
  },
17
25
  {
18
- "key": "utf8:0x0000000000000000000000000000000000000000000000000000000000000005:0x0000000000000000000000000000000000000000000000000000000000000007",
26
+ "key": "utf8:unconstrained:0x0000000000000000000000000000000000000000000000000000000000000005:0x0000000000000000000000000000000000000000000000000000000000000007",
19
27
  "value": "num:5"
20
28
  }
21
29
  ]
@@ -1,5 +1,5 @@
1
1
  {
2
- "schemaVersion": 12,
2
+ "schemaVersion": 13,
3
3
  "stores": [
4
4
  {
5
5
  "name": "capsules",
@@ -18,6 +18,7 @@ import { GasFees } from '@aztec/stdlib/gas';
18
18
  import { PublicKey, PublicKeys, deriveKeys } from '@aztec/stdlib/keys';
19
19
  import {
20
20
  AppTaggingSecret,
21
+ AppTaggingSecretKind,
21
22
  ContractClassLog,
22
23
  ContractClassLogFields,
23
24
  PrivateLog,
@@ -530,10 +531,18 @@ export const SCHEMA_TESTS: readonly SchemaTest[] = [
530
531
  const jobId = 'fixture-job';
531
532
  const secretA = new AppTaggingSecret(new Fr(2n), AztecAddress.fromBigIntUnsafe(3n));
532
533
  const secretB = new AppTaggingSecret(new Fr(5n), AztecAddress.fromBigIntUnsafe(7n));
534
+ // A constrained secret keys under the `constrained:` prefix, so the snapshot pins both kinds side by side.
535
+ const secretConstrained = new AppTaggingSecret(
536
+ new Fr(19n),
537
+ AztecAddress.fromBigIntUnsafe(23n),
538
+ AppTaggingSecretKind.CONSTRAINED,
539
+ );
533
540
 
534
541
  await recipientTaggingStore.updateHighestFinalizedIndex(secretA, 11, jobId);
535
542
  await recipientTaggingStore.updateHighestAgedIndex(secretA, 13, jobId);
536
543
  await recipientTaggingStore.updateHighestFinalizedIndex(secretB, 17, jobId);
544
+ await recipientTaggingStore.updateHighestFinalizedIndex(secretConstrained, 11, jobId);
545
+ await recipientTaggingStore.updateHighestAgedIndex(secretConstrained, 13, jobId);
537
546
  await kvStore.transactionAsync(() => recipientTaggingStore.commit(jobId));
538
547
  },
539
548
  snapshotStore: async kvStore => ({
@@ -584,10 +593,17 @@ export const SCHEMA_TESTS: readonly SchemaTest[] = [
584
593
  const secretA = new AppTaggingSecret(new Fr(2n), AztecAddress.fromBigIntUnsafe(3n));
585
594
  const secretB = new AppTaggingSecret(new Fr(5n), AztecAddress.fromBigIntUnsafe(7n));
586
595
  const secretC = new AppTaggingSecret(new Fr(11n), AztecAddress.fromBigIntUnsafe(13n));
596
+ const secretConstrained = new AppTaggingSecret(
597
+ new Fr(19n),
598
+ AztecAddress.fromBigIntUnsafe(23n),
599
+ AppTaggingSecretKind.CONSTRAINED,
600
+ );
587
601
  const txHashA = TxHash.fromBigInt(17n);
588
602
  const txHashB = TxHash.fromBigInt(19n);
589
603
  const txHashC = TxHash.fromBigInt(23n);
590
604
  const txHashD = TxHash.fromBigInt(29n);
605
+ const txHashE = TxHash.fromBigInt(31n);
606
+ const txHashF = TxHash.fromBigInt(37n);
591
607
 
592
608
  // secretA receives three pending ranges (one per tx); secretB receives one. After finalizing txHashA below,
593
609
  // secretA's array shrinks to two elements (the txHashB and txHashC ranges, both with highestIndex > 3) which
@@ -626,7 +642,20 @@ export const SCHEMA_TESTS: readonly SchemaTest[] = [
626
642
  jobId,
627
643
  );
628
644
 
629
- await senderTaggingStore.finalizePendingIndexes([txHashA], jobId);
645
+ // secretConstrained gets a finalized range (txHashE) plus a surviving higher pending range (txHashF), so the
646
+ // `constrained:` key lands in both pending_indexes and last_finalized_indexes.
647
+ await senderTaggingStore.storePendingIndexes(
648
+ [{ extendedSecret: secretConstrained, lowestIndex: 1, highestIndex: 3 }],
649
+ txHashE,
650
+ jobId,
651
+ );
652
+ await senderTaggingStore.storePendingIndexes(
653
+ [{ extendedSecret: secretConstrained, lowestIndex: 4, highestIndex: 7 }],
654
+ txHashF,
655
+ jobId,
656
+ );
657
+
658
+ await senderTaggingStore.finalizePendingIndexes([txHashA, txHashE], jobId);
630
659
 
631
660
  await kvStore.transactionAsync(() => senderTaggingStore.commit(jobId));
632
661
  },
@@ -1 +1 @@
1
- export const PXE_DATA_SCHEMA_VERSION = 12;
1
+ export const PXE_DATA_SCHEMA_VERSION = 13;