@aztec/stdlib 0.0.1-commit.96dac018d → 0.0.1-commit.993d52e

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 (120) hide show
  1. package/dest/abi/decoder.d.ts +1 -1
  2. package/dest/abi/decoder.d.ts.map +1 -1
  3. package/dest/abi/decoder.js +1 -4
  4. package/dest/abi/encoder.d.ts +1 -1
  5. package/dest/abi/encoder.d.ts.map +1 -1
  6. package/dest/abi/encoder.js +9 -5
  7. package/dest/avm/avm.d.ts +300 -300
  8. package/dest/avm/avm_proving_request.d.ts +166 -166
  9. package/dest/avm/revert_code.d.ts +16 -1
  10. package/dest/avm/revert_code.d.ts.map +1 -1
  11. package/dest/avm/revert_code.js +15 -5
  12. package/dest/block/l2_block_stream/l2_block_stream.d.ts +1 -1
  13. package/dest/block/l2_block_stream/l2_block_stream.d.ts.map +1 -1
  14. package/dest/block/l2_block_stream/l2_block_stream.js +10 -0
  15. package/dest/config/sequencer-config.d.ts +5 -3
  16. package/dest/config/sequencer-config.d.ts.map +1 -1
  17. package/dest/config/sequencer-config.js +7 -0
  18. package/dest/interfaces/aztec-node-admin.d.ts +10 -4
  19. package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
  20. package/dest/interfaces/configs.d.ts +11 -1
  21. package/dest/interfaces/configs.d.ts.map +1 -1
  22. package/dest/interfaces/configs.js +2 -0
  23. package/dest/interfaces/p2p.d.ts +3 -8
  24. package/dest/interfaces/p2p.d.ts.map +1 -1
  25. package/dest/interfaces/validator.d.ts +6 -3
  26. package/dest/interfaces/validator.d.ts.map +1 -1
  27. package/dest/interfaces/validator.js +2 -1
  28. package/dest/kernel/hints/build_note_hash_read_request_hints.d.ts +3 -3
  29. package/dest/kernel/hints/build_note_hash_read_request_hints.d.ts.map +1 -1
  30. package/dest/kernel/hints/build_note_hash_read_request_hints.js +10 -13
  31. package/dest/kernel/hints/build_nullifier_read_request_hints.d.ts +3 -3
  32. package/dest/kernel/hints/build_nullifier_read_request_hints.d.ts.map +1 -1
  33. package/dest/kernel/hints/build_nullifier_read_request_hints.js +10 -13
  34. package/dest/kernel/hints/build_transient_data_hints.d.ts +2 -5
  35. package/dest/kernel/hints/build_transient_data_hints.d.ts.map +1 -1
  36. package/dest/kernel/hints/build_transient_data_hints.js +3 -9
  37. package/dest/logs/extended_directional_app_tagging_secret.d.ts +47 -0
  38. package/dest/logs/extended_directional_app_tagging_secret.d.ts.map +1 -0
  39. package/dest/logs/{directional_app_tagging_secret.js → extended_directional_app_tagging_secret.js} +23 -15
  40. package/dest/logs/index.d.ts +2 -2
  41. package/dest/logs/index.d.ts.map +1 -1
  42. package/dest/logs/index.js +1 -1
  43. package/dest/logs/pre_tag.d.ts +16 -11
  44. package/dest/logs/pre_tag.d.ts.map +1 -1
  45. package/dest/logs/pre_tag.js +2 -2
  46. package/dest/logs/siloed_tag.d.ts +5 -3
  47. package/dest/logs/siloed_tag.d.ts.map +1 -1
  48. package/dest/logs/siloed_tag.js +6 -1
  49. package/dest/logs/tag.js +1 -1
  50. package/dest/p2p/block_proposal.d.ts +2 -2
  51. package/dest/p2p/block_proposal.d.ts.map +1 -1
  52. package/dest/p2p/block_proposal.js +1 -1
  53. package/dest/p2p/checkpoint_proposal.d.ts +2 -2
  54. package/dest/p2p/checkpoint_proposal.d.ts.map +1 -1
  55. package/dest/p2p/checkpoint_proposal.js +1 -1
  56. package/dest/p2p/client_type.d.ts +2 -5
  57. package/dest/p2p/client_type.d.ts.map +1 -1
  58. package/dest/p2p/client_type.js +0 -7
  59. package/dest/p2p/index.d.ts +1 -2
  60. package/dest/p2p/index.d.ts.map +1 -1
  61. package/dest/p2p/index.js +0 -1
  62. package/dest/p2p/topic_type.d.ts +3 -4
  63. package/dest/p2p/topic_type.d.ts.map +1 -1
  64. package/dest/p2p/topic_type.js +7 -24
  65. package/dest/tests/factories.d.ts +3 -1
  66. package/dest/tests/factories.d.ts.map +1 -1
  67. package/dest/tests/factories.js +8 -0
  68. package/dest/update-checker/index.d.ts +3 -2
  69. package/dest/update-checker/index.d.ts.map +1 -1
  70. package/dest/update-checker/index.js +2 -1
  71. package/dest/update-checker/package_version.d.ts +3 -0
  72. package/dest/update-checker/package_version.d.ts.map +1 -0
  73. package/dest/update-checker/package_version.js +11 -0
  74. package/dest/update-checker/version_checker.d.ts +25 -0
  75. package/dest/update-checker/version_checker.d.ts.map +1 -0
  76. package/dest/update-checker/version_checker.js +50 -0
  77. package/package.json +10 -10
  78. package/src/abi/decoder.ts +1 -4
  79. package/src/abi/encoder.ts +8 -5
  80. package/src/avm/revert_code.ts +15 -0
  81. package/src/block/l2_block_stream/l2_block_stream.ts +21 -0
  82. package/src/config/sequencer-config.ts +10 -2
  83. package/src/interfaces/configs.ts +6 -0
  84. package/src/interfaces/p2p.ts +2 -13
  85. package/src/interfaces/validator.ts +3 -2
  86. package/src/kernel/hints/build_note_hash_read_request_hints.ts +18 -14
  87. package/src/kernel/hints/build_nullifier_read_request_hints.ts +18 -15
  88. package/src/kernel/hints/build_transient_data_hints.ts +2 -17
  89. package/src/logs/{directional_app_tagging_secret.ts → extended_directional_app_tagging_secret.ts} +24 -16
  90. package/src/logs/index.ts +1 -1
  91. package/src/logs/pre_tag.ts +5 -5
  92. package/src/logs/siloed_tag.ts +8 -2
  93. package/src/logs/tag.ts +1 -1
  94. package/src/p2p/block_proposal.ts +1 -1
  95. package/src/p2p/checkpoint_proposal.ts +1 -1
  96. package/src/p2p/client_type.ts +0 -6
  97. package/src/p2p/index.ts +0 -1
  98. package/src/p2p/topic_type.ts +8 -15
  99. package/src/tests/factories.ts +9 -0
  100. package/src/update-checker/index.ts +2 -1
  101. package/src/update-checker/package_version.ts +17 -0
  102. package/src/update-checker/version_checker.ts +65 -0
  103. package/dest/ha-signing/config.d.ts +0 -101
  104. package/dest/ha-signing/config.d.ts.map +0 -1
  105. package/dest/ha-signing/config.js +0 -92
  106. package/dest/ha-signing/index.d.ts +0 -3
  107. package/dest/ha-signing/index.d.ts.map +0 -1
  108. package/dest/ha-signing/index.js +0 -2
  109. package/dest/ha-signing/types.d.ts +0 -85
  110. package/dest/ha-signing/types.d.ts.map +0 -1
  111. package/dest/ha-signing/types.js +0 -32
  112. package/dest/logs/directional_app_tagging_secret.d.ts +0 -40
  113. package/dest/logs/directional_app_tagging_secret.d.ts.map +0 -1
  114. package/dest/update-checker/update-checker.d.ts +0 -49
  115. package/dest/update-checker/update-checker.d.ts.map +0 -1
  116. package/dest/update-checker/update-checker.js +0 -130
  117. package/src/ha-signing/config.ts +0 -149
  118. package/src/ha-signing/index.ts +0 -18
  119. package/src/ha-signing/types.ts +0 -112
  120. package/src/update-checker/update-checker.ts +0 -166
@@ -15,12 +15,12 @@ import type {
15
15
  } from '@aztec/stdlib/p2p';
16
16
  import type { CheckpointHeader } from '@aztec/stdlib/rollup';
17
17
  import type { BlockHeader, Tx } from '@aztec/stdlib/tx';
18
+ import { type ValidatorHASignerConfig, ValidatorHASignerConfigSchema } from '@aztec/validator-ha-signer/config';
18
19
 
19
20
  import type { PeerId } from '@libp2p/interface';
20
21
  import { z } from 'zod';
21
22
 
22
23
  import type { CommitteeAttestationsAndSigners } from '../block/index.js';
23
- import { type ValidatorHASignerConfig, ValidatorHASignerConfigSchema } from '../ha-signing/index.js';
24
24
  import { AllowedElementSchema } from './allowed_element.js';
25
25
 
26
26
  /**
@@ -62,7 +62,7 @@ export type ValidatorClientConfig = ValidatorHASignerConfig & {
62
62
  };
63
63
 
64
64
  export type ValidatorClientFullConfig = ValidatorClientConfig &
65
- Pick<SequencerConfig, 'txPublicSetupAllowList' | 'broadcastInvalidBlockProposal'> &
65
+ Pick<SequencerConfig, 'txPublicSetupAllowList' | 'broadcastInvalidBlockProposal' | 'maxTxsPerBlock'> &
66
66
  Pick<
67
67
  SlasherConfig,
68
68
  'slashBroadcastedInvalidBlockPenalty' | 'slashDuplicateProposalPenalty' | 'slashDuplicateAttestationPenalty'
@@ -93,6 +93,7 @@ export const ValidatorClientFullConfigSchema = zodFor<Omit<ValidatorClientFullCo
93
93
  ValidatorClientConfigSchema.extend({
94
94
  txPublicSetupAllowList: z.array(AllowedElementSchema).optional(),
95
95
  broadcastInvalidBlockProposal: z.boolean().optional(),
96
+ maxTxsPerBlock: z.number().optional(),
96
97
  slashBroadcastedInvalidBlockPenalty: schemas.BigInt,
97
98
  slashDuplicateProposalPenalty: schemas.BigInt,
98
99
  slashDuplicateAttestationPenalty: schemas.BigInt,
@@ -11,6 +11,7 @@ import type { ScopedNoteHash } from '../note_hash.js';
11
11
  import { NoteHashReadRequestHintsBuilder } from './note_hash_read_request_hints.js';
12
12
  import type { ScopedReadRequest } from './read_request.js';
13
13
  import { PendingReadHint, ReadRequestActionEnum, ReadRequestResetActions } from './read_request_hints.js';
14
+ import { ScopedValueCache } from './scoped_value_cache.js';
14
15
 
15
16
  export function isValidNoteHashReadRequest(readRequest: ScopedReadRequest, noteHash: ScopedNoteHash) {
16
17
  return (
@@ -23,6 +24,7 @@ export function isValidNoteHashReadRequest(readRequest: ScopedReadRequest, noteH
23
24
  export function getNoteHashReadRequestResetActions(
24
25
  noteHashReadRequests: ClaimedLengthArray<ScopedReadRequest, typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX>,
25
26
  noteHashes: ClaimedLengthArray<ScopedNoteHash, typeof MAX_NOTE_HASHES_PER_TX>,
27
+ futureNoteHashes: ScopedNoteHash[],
26
28
  ): ReadRequestResetActions<typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX> {
27
29
  const resetActions = ReadRequestResetActions.empty(MAX_NOTE_HASH_READ_REQUESTS_PER_TX);
28
30
 
@@ -34,23 +36,24 @@ export function getNoteHashReadRequestResetActions(
34
36
  noteHashMap.set(value, arr);
35
37
  });
36
38
 
39
+ const futureNoteHashMap = new ScopedValueCache(futureNoteHashes);
40
+
37
41
  for (let i = 0; i < noteHashReadRequests.claimedLength; ++i) {
38
42
  const readRequest = noteHashReadRequests.array[i];
39
43
 
40
- if (readRequest.contractAddress.isZero()) {
41
- // Settled read: empty contract address means resolve against the note hash tree.
44
+ const pendingNoteHash = noteHashMap
45
+ .get(readRequest.value.toBigInt())
46
+ ?.find(n => isValidNoteHashReadRequest(readRequest, n.noteHash));
47
+
48
+ if (pendingNoteHash !== undefined) {
49
+ resetActions.actions[i] = ReadRequestActionEnum.READ_AS_PENDING;
50
+ resetActions.pendingReadHints.push(new PendingReadHint(i, pendingNoteHash.index));
51
+ } else if (
52
+ !futureNoteHashMap
53
+ .get(readRequest)
54
+ .find(futureNoteHash => isValidNoteHashReadRequest(readRequest, futureNoteHash))
55
+ ) {
42
56
  resetActions.actions[i] = ReadRequestActionEnum.READ_AS_SETTLED;
43
- } else {
44
- // Pending read: non-empty contract address means match against a pending note hash.
45
- const pendingNoteHash = noteHashMap
46
- .get(readRequest.value.toBigInt())
47
- ?.find(n => isValidNoteHashReadRequest(readRequest, n.noteHash));
48
-
49
- if (pendingNoteHash) {
50
- resetActions.actions[i] = ReadRequestActionEnum.READ_AS_PENDING;
51
- resetActions.pendingReadHints.push(new PendingReadHint(i, pendingNoteHash.index));
52
- }
53
- // Otherwise, the read request may be resolved by a future note hash. Leave as NOOP.
54
57
  }
55
58
  }
56
59
 
@@ -112,10 +115,11 @@ export async function buildNoteHashReadRequestHints<PENDING extends number, SETT
112
115
  },
113
116
  noteHashReadRequests: ClaimedLengthArray<ScopedReadRequest, typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX>,
114
117
  noteHashes: ClaimedLengthArray<ScopedNoteHash, typeof MAX_NOTE_HASHES_PER_TX>,
118
+ futureNoteHashes: ScopedNoteHash[],
115
119
  maxPending: PENDING = MAX_NOTE_HASH_READ_REQUESTS_PER_TX as PENDING,
116
120
  maxSettled: SETTLED = MAX_NOTE_HASH_READ_REQUESTS_PER_TX as SETTLED,
117
121
  ) {
118
- const resetActions = getNoteHashReadRequestResetActions(noteHashReadRequests, noteHashes);
122
+ const resetActions = getNoteHashReadRequestResetActions(noteHashReadRequests, noteHashes, futureNoteHashes);
119
123
  return await buildNoteHashReadRequestHintsFromResetActions(
120
124
  oracle,
121
125
  noteHashReadRequests,
@@ -12,6 +12,7 @@ import type { ScopedNullifier } from '../nullifier.js';
12
12
  import { NullifierReadRequestHintsBuilder } from './nullifier_read_request_hints.js';
13
13
  import { ScopedReadRequest } from './read_request.js';
14
14
  import { PendingReadHint, ReadRequestActionEnum, ReadRequestResetActions } from './read_request_hints.js';
15
+ import { ScopedValueCache } from './scoped_value_cache.js';
15
16
 
16
17
  export function isValidNullifierReadRequest(readRequest: ScopedReadRequest, nullifier: ScopedNullifier) {
17
18
  return (
@@ -29,6 +30,7 @@ interface NullifierMembershipWitnessWithPreimage {
29
30
  export function getNullifierReadRequestResetActions(
30
31
  nullifierReadRequests: ClaimedLengthArray<ScopedReadRequest, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>,
31
32
  nullifiers: ClaimedLengthArray<ScopedNullifier, typeof MAX_NULLIFIERS_PER_TX>,
33
+ futureNullifiers: ScopedNullifier[],
32
34
  ): ReadRequestResetActions<typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX> {
33
35
  const resetActions = ReadRequestResetActions.empty(MAX_NULLIFIER_READ_REQUESTS_PER_TX);
34
36
 
@@ -40,23 +42,23 @@ export function getNullifierReadRequestResetActions(
40
42
  nullifierMap.set(value, arr);
41
43
  });
42
44
 
45
+ const futureNullifiersMap = new ScopedValueCache(futureNullifiers);
46
+
43
47
  for (let i = 0; i < nullifierReadRequests.claimedLength; ++i) {
44
48
  const readRequest = nullifierReadRequests.array[i];
45
-
46
- if (readRequest.contractAddress.isZero()) {
47
- // Settled read: empty contract address means resolve against the nullifier tree.
49
+ const pendingNullifier = nullifierMap
50
+ .get(readRequest.value.toBigInt())
51
+ ?.find(({ nullifier }) => isValidNullifierReadRequest(readRequest, nullifier));
52
+
53
+ if (pendingNullifier !== undefined) {
54
+ resetActions.actions[i] = ReadRequestActionEnum.READ_AS_PENDING;
55
+ resetActions.pendingReadHints.push(new PendingReadHint(i, pendingNullifier.index));
56
+ } else if (
57
+ !futureNullifiersMap
58
+ .get(readRequest)
59
+ .some(futureNullifier => isValidNullifierReadRequest(readRequest, futureNullifier))
60
+ ) {
48
61
  resetActions.actions[i] = ReadRequestActionEnum.READ_AS_SETTLED;
49
- } else {
50
- // Pending read: non-empty contract address means match against a pending nullifier.
51
- const pendingNullifier = nullifierMap
52
- .get(readRequest.value.toBigInt())
53
- ?.find(({ nullifier }) => isValidNullifierReadRequest(readRequest, nullifier));
54
-
55
- if (pendingNullifier) {
56
- resetActions.actions[i] = ReadRequestActionEnum.READ_AS_PENDING;
57
- resetActions.pendingReadHints.push(new PendingReadHint(i, pendingNullifier.index));
58
- }
59
- // Otherwise, the read request may be resolved by a future nullifier. Leave as NOOP.
60
62
  }
61
63
  }
62
64
 
@@ -109,10 +111,11 @@ export async function buildNullifierReadRequestHints<PENDING extends number, SET
109
111
  },
110
112
  nullifierReadRequests: ClaimedLengthArray<ScopedReadRequest, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>,
111
113
  nullifiers: ClaimedLengthArray<ScopedNullifier, typeof MAX_NULLIFIERS_PER_TX>,
114
+ futureNullifiers: ScopedNullifier[],
112
115
  maxPending: PENDING = MAX_NULLIFIER_READ_REQUESTS_PER_TX as PENDING,
113
116
  maxSettled: SETTLED = MAX_NULLIFIER_READ_REQUESTS_PER_TX as SETTLED,
114
117
  ) {
115
- const resetActions = getNullifierReadRequestResetActions(nullifierReadRequests, nullifiers);
118
+ const resetActions = getNullifierReadRequestResetActions(nullifierReadRequests, nullifiers, futureNullifiers);
116
119
  return await buildNullifierReadRequestHintsFromResetActions(
117
120
  oracle,
118
121
  nullifierReadRequests,
@@ -4,7 +4,6 @@ import type { Tuple } from '@aztec/foundation/serialize';
4
4
  import type { ClaimedLengthArray } from '../claimed_length_array.js';
5
5
  import type { ScopedNoteHash } from '../note_hash.js';
6
6
  import type { ScopedNullifier } from '../nullifier.js';
7
- import type { PrivateLogData, ScopedPrivateLogData } from '../private_log_data.js';
8
7
  import { isValidNoteHashReadRequest } from './build_note_hash_read_request_hints.js';
9
8
  import { isValidNullifierReadRequest } from './build_nullifier_read_request_hints.js';
10
9
  import type { ScopedReadRequest } from './read_request.js';
@@ -16,13 +15,11 @@ export function buildTransientDataHints<NOTE_HASHES_LEN extends number, NULLIFIE
16
15
  nullifiers: ClaimedLengthArray<ScopedNullifier, NULLIFIERS_LEN>,
17
16
  futureNoteHashReads: ScopedReadRequest[],
18
17
  futureNullifierReads: ScopedReadRequest[],
19
- futureLogs: PrivateLogData[],
20
18
  noteHashNullifierCounterMap: Map<number, number>,
21
19
  splitCounter: number,
22
20
  ): { numTransientData: number; hints: Tuple<TransientDataSquashingHint, NULLIFIERS_LEN> } {
23
21
  const futureNoteHashReadsMap = new ScopedValueCache(futureNoteHashReads);
24
22
  const futureNullifierReadsMap = new ScopedValueCache(futureNullifierReads);
25
- const futureLogNoteHashCounters = new Set(futureLogs.filter(l => l.noteHashCounter > 0).map(l => l.noteHashCounter));
26
23
 
27
24
  const nullifierIndexMap: Map<number, number> = new Map();
28
25
  nullifiers.getActiveItems().forEach((n, i) => nullifierIndexMap.set(n.counter, i));
@@ -31,12 +28,10 @@ export function buildTransientDataHints<NOTE_HASHES_LEN extends number, NULLIFIE
31
28
  for (let noteHashIndex = 0; noteHashIndex < noteHashes.claimedLength; noteHashIndex++) {
32
29
  const noteHash = noteHashes.array[noteHashIndex];
33
30
  const noteHashNullifierCounter = noteHashNullifierCounterMap.get(noteHash.counter);
34
- // The note hash might not be linked to a nullifier, or it might be read in the future, or a future log might be
35
- // linked to it.
31
+ // The note hash might not be linked to a nullifier or it might be read in the future
36
32
  if (
37
33
  !noteHashNullifierCounter ||
38
- futureNoteHashReadsMap.get(noteHash).find(read => isValidNoteHashReadRequest(read, noteHash)) ||
39
- futureLogNoteHashCounters.has(noteHash.counter)
34
+ futureNoteHashReadsMap.get(noteHash).find(read => isValidNoteHashReadRequest(read, noteHash))
40
35
  ) {
41
36
  continue;
42
37
  }
@@ -82,13 +77,3 @@ export function buildTransientDataHints<NOTE_HASHES_LEN extends number, NULLIFIE
82
77
  hints: padArrayEnd(hints, noActionHint, nullifiers.array.length as NULLIFIERS_LEN),
83
78
  };
84
79
  }
85
-
86
- /** Counts private logs that are linked to squashed note hashes and would be removed along with them. */
87
- export function countSquashedLogs<NOTE_HASHES_LEN extends number, LOGS_LEN extends number>(
88
- noteHashes: ClaimedLengthArray<ScopedNoteHash, NOTE_HASHES_LEN>,
89
- privateLogs: ClaimedLengthArray<ScopedPrivateLogData, LOGS_LEN>,
90
- squashingHints: TransientDataSquashingHint[],
91
- ): number {
92
- const squashedNoteHashCounters = new Set(squashingHints.map(h => noteHashes.array[h.noteHashIndex].counter));
93
- return privateLogs.getActiveItems().filter(l => squashedNoteHashCounters.has(l.inner.noteHashCounter)).length;
94
- }
@@ -5,22 +5,28 @@ import type { Point } from '@aztec/foundation/curves/grumpkin';
5
5
 
6
6
  import { z } from 'zod';
7
7
 
8
- import type { AztecAddress } from '../aztec-address/index.js';
8
+ import { AztecAddress } from '../aztec-address/index.js';
9
9
  import type { CompleteAddress } from '../contract/complete_address.js';
10
10
  import { computeAddressSecret, computePreaddress } from '../keys/derivation.js';
11
11
 
12
12
  /**
13
- * Directional application tagging secret used for log tagging.
13
+ * Extended directional application tagging secret used for log tagging.
14
14
  *
15
- * "Directional" because the derived secret is bound to the recipient
16
- * address: A→B differs from B→A even with the same participants and app.
15
+ * "Extended" because it bundles the directional app tagging secret with the app (contract) address. This bundling was
16
+ * done because where this type is used we commonly need access to both the secret and the address.
17
17
  *
18
- * Note: It's a bit unfortunate that this type resides in `stdlib` as the rest of the tagging functionality resides
19
- * in `pxe/src/tagging`. We need to use this type in `PreTag` that in turn is used by other types
20
- * in stdlib hence there doesn't seem to be a good way around this.
18
+ * "Directional" because the derived secret is bound to the recipient address: A→B differs from B→A even with the same
19
+ * participants and app.
20
+ *
21
+ * Note: It's a bit unfortunate that this type resides in `stdlib` as the rest of the tagging functionality resides in
22
+ * `pxe/src/tagging`. We need to use this type in `PreTag` that in turn is used by other types in stdlib hence there
23
+ * doesn't seem to be a good way around this.
21
24
  */
22
- export class DirectionalAppTaggingSecret {
23
- private constructor(public readonly value: Fr) {}
25
+ export class ExtendedDirectionalAppTaggingSecret {
26
+ private constructor(
27
+ public readonly secret: Fr,
28
+ public readonly app: AztecAddress,
29
+ ) {}
24
30
 
25
31
  /**
26
32
  * Derives shared tagging secret and from that, the app address and recipient derives the directional app tagging
@@ -39,20 +45,21 @@ export class DirectionalAppTaggingSecret {
39
45
  externalAddress: AztecAddress,
40
46
  app: AztecAddress,
41
47
  recipient: AztecAddress,
42
- ): Promise<DirectionalAppTaggingSecret> {
48
+ ): Promise<ExtendedDirectionalAppTaggingSecret> {
43
49
  const taggingSecretPoint = await computeSharedTaggingSecret(localAddress, localIvsk, externalAddress);
44
50
  const appTaggingSecret = await poseidon2Hash([taggingSecretPoint.x, taggingSecretPoint.y, app]);
45
51
  const directionalAppTaggingSecret = await poseidon2Hash([appTaggingSecret, recipient]);
46
52
 
47
- return new DirectionalAppTaggingSecret(directionalAppTaggingSecret);
53
+ return new ExtendedDirectionalAppTaggingSecret(directionalAppTaggingSecret, app);
48
54
  }
49
55
 
50
56
  toString(): string {
51
- return this.value.toString();
57
+ return `${this.secret.toString()}:${this.app.toString()}`;
52
58
  }
53
59
 
54
- static fromString(str: string): DirectionalAppTaggingSecret {
55
- return new DirectionalAppTaggingSecret(Fr.fromString(str));
60
+ static fromString(str: string): ExtendedDirectionalAppTaggingSecret {
61
+ const [secretStr, appStr] = str.split(':');
62
+ return new ExtendedDirectionalAppTaggingSecret(Fr.fromString(secretStr), AztecAddress.fromString(appStr));
56
63
  }
57
64
  }
58
65
 
@@ -74,6 +81,7 @@ async function computeSharedTaggingSecret(
74
81
  return Grumpkin.mul(externalAddressPoint, await computeAddressSecret(knownPreaddress, localIvsk));
75
82
  }
76
83
 
77
- export const DirectionalAppTaggingSecretSchema = z.object({
78
- value: Fr.schema,
84
+ export const ExtendedDirectionalAppTaggingSecretSchema = z.object({
85
+ secret: Fr.schema,
86
+ app: AztecAddress.schema,
79
87
  });
package/src/logs/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from './directional_app_tagging_secret.js';
1
+ export * from './extended_directional_app_tagging_secret.js';
2
2
  export * from './pre_tag.js';
3
3
  export * from './contract_class_log.js';
4
4
  export * from './public_log.js';
@@ -3,9 +3,9 @@ import { schemas } from '@aztec/foundation/schemas';
3
3
  import { z } from 'zod';
4
4
 
5
5
  import {
6
- type DirectionalAppTaggingSecret,
7
- DirectionalAppTaggingSecretSchema,
8
- } from './directional_app_tagging_secret.js';
6
+ type ExtendedDirectionalAppTaggingSecret,
7
+ ExtendedDirectionalAppTaggingSecretSchema,
8
+ } from './extended_directional_app_tagging_secret.js';
9
9
 
10
10
  /**
11
11
  * Represents a preimage of a private log tag (see `Tag` in `pxe/src/tagging`).
@@ -15,11 +15,11 @@ import {
15
15
  * around this.
16
16
  */
17
17
  export type PreTag = {
18
- secret: DirectionalAppTaggingSecret;
18
+ extendedSecret: ExtendedDirectionalAppTaggingSecret;
19
19
  index: number;
20
20
  };
21
21
 
22
22
  export const PreTagSchema = z.object({
23
- secret: DirectionalAppTaggingSecretSchema,
23
+ extendedSecret: ExtendedDirectionalAppTaggingSecretSchema,
24
24
  index: schemas.Integer,
25
25
  });
@@ -4,7 +4,8 @@ import type { ZodFor } from '@aztec/foundation/schemas';
4
4
  import type { AztecAddress } from '../aztec-address/index.js';
5
5
  import { computeSiloedPrivateLogFirstField } from '../hash/hash.js';
6
6
  import { schemas } from '../schemas/schemas.js';
7
- import type { Tag } from './tag.js';
7
+ import type { PreTag } from './pre_tag.js';
8
+ import { Tag } from './tag.js';
8
9
 
9
10
  /* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */
10
11
 
@@ -21,7 +22,12 @@ export interface SiloedTag {
21
22
  export class SiloedTag {
22
23
  constructor(public readonly value: Fr) {}
23
24
 
24
- static async compute(tag: Tag, app: AztecAddress): Promise<SiloedTag> {
25
+ static async compute(preTag: PreTag): Promise<SiloedTag> {
26
+ const tag = await Tag.compute(preTag);
27
+ return SiloedTag.computeFromTagAndApp(tag, preTag.extendedSecret.app);
28
+ }
29
+
30
+ static async computeFromTagAndApp(tag: Tag, app: AztecAddress): Promise<SiloedTag> {
25
31
  const siloedTag = await computeSiloedPrivateLogFirstField(app, tag.value);
26
32
  return new SiloedTag(siloedTag);
27
33
  }
package/src/logs/tag.ts CHANGED
@@ -20,7 +20,7 @@ export class Tag {
20
20
  constructor(public readonly value: Fr) {}
21
21
 
22
22
  static async compute(preTag: PreTag): Promise<Tag> {
23
- const tag = await poseidon2Hash([preTag.secret.value, preTag.index]);
23
+ const tag = await poseidon2Hash([preTag.extendedSecret.secret, preTag.index]);
24
24
  return new Tag(tag);
25
25
  }
26
26
 
@@ -6,11 +6,11 @@ import { Fr } from '@aztec/foundation/curves/bn254';
6
6
  import type { EthAddress } from '@aztec/foundation/eth-address';
7
7
  import { Signature } from '@aztec/foundation/eth-signature';
8
8
  import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
9
+ import { DutyType, type SigningContext } from '@aztec/validator-ha-signer/types';
9
10
 
10
11
  import type { L2Block } from '../block/l2_block.js';
11
12
  import type { L2BlockInfo } from '../block/l2_block_info.js';
12
13
  import { MAX_TXS_PER_BLOCK } from '../deserialization/index.js';
13
- import { DutyType, type SigningContext } from '../ha-signing/index.js';
14
14
  import { BlockHeader } from '../tx/block_header.js';
15
15
  import { TxHash } from '../tx/index.js';
16
16
  import type { Tx } from '../tx/tx.js';
@@ -6,10 +6,10 @@ import { Fr } from '@aztec/foundation/curves/bn254';
6
6
  import type { EthAddress } from '@aztec/foundation/eth-address';
7
7
  import { Signature } from '@aztec/foundation/eth-signature';
8
8
  import { BufferReader, serializeSignedBigInt, serializeToBuffer } from '@aztec/foundation/serialize';
9
+ import { DutyType, type SigningContext } from '@aztec/validator-ha-signer/types';
9
10
 
10
11
  import type { L2BlockInfo } from '../block/l2_block_info.js';
11
12
  import { MAX_TXS_PER_BLOCK } from '../deserialization/index.js';
12
- import { DutyType, type SigningContext } from '../ha-signing/index.js';
13
13
  import { CheckpointHeader } from '../rollup/checkpoint_header.js';
14
14
  import { BlockHeader } from '../tx/block_header.js';
15
15
  import { TxHash } from '../tx/index.js';
@@ -1,6 +0,0 @@
1
- export enum P2PClientType {
2
- // Full p2p clients will subscribe to all gossip topics
3
- Full,
4
- // Prove p2p clients will only subscribe to transaction and proving topics
5
- Prover,
6
- }
package/src/p2p/index.ts CHANGED
@@ -8,7 +8,6 @@ export * from './interface.js';
8
8
  export * from './signature_utils.js';
9
9
  export * from './signed_txs.js';
10
10
  export * from './topic_type.js';
11
- export * from './client_type.js';
12
11
  export * from './message_validator.js';
13
12
  export * from './peer_error.js';
14
13
  export * from './constants.js';
@@ -1,5 +1,3 @@
1
- import { P2PClientType } from './client_type.js';
2
-
3
1
  /**
4
2
  * Creates the topic channel identifier string from a given topic type
5
3
  */
@@ -27,19 +25,14 @@ export enum TopicType {
27
25
  checkpoint_attestation = 'checkpoint_attestation',
28
26
  }
29
27
 
30
- export function getTopicTypeForClientType(clientType: P2PClientType) {
31
- if (clientType === P2PClientType.Full) {
32
- return [TopicType.tx, TopicType.block_proposal, TopicType.checkpoint_proposal, TopicType.checkpoint_attestation];
33
- } else if (clientType === P2PClientType.Prover) {
34
- return [TopicType.tx, TopicType.block_proposal, TopicType.checkpoint_proposal];
35
- } else {
36
- const _: never = clientType;
37
- return [TopicType.tx];
38
- }
39
- }
40
-
41
- export function getTopicsForClientAndConfig(clientType: P2PClientType, disableTransactions: boolean) {
42
- const topics = getTopicTypeForClientType(clientType);
28
+ /** Returns all gossip topics, optionally filtering out transactions. */
29
+ export function getTopicsForConfig(disableTransactions: boolean) {
30
+ const topics = [
31
+ TopicType.tx,
32
+ TopicType.block_proposal,
33
+ TopicType.checkpoint_proposal,
34
+ TopicType.checkpoint_attestation,
35
+ ];
43
36
  if (disableTransactions) {
44
37
  return topics.filter(topic => topic !== TopicType.tx);
45
38
  }
@@ -128,6 +128,7 @@ import {
128
128
  PublicCallRequestArrayLengths,
129
129
  } from '../kernel/public_call_request.js';
130
130
  import { PublicKeys, computeAddress } from '../keys/index.js';
131
+ import { ExtendedDirectionalAppTaggingSecret } from '../logs/extended_directional_app_tagging_secret.js';
131
132
  import { ContractClassLog, ContractClassLogFields } from '../logs/index.js';
132
133
  import { PrivateLog } from '../logs/private_log.js';
133
134
  import { FlatPublicLogs, PublicLog } from '../logs/public_log.js';
@@ -1757,3 +1758,11 @@ export function makeL2Tips(
1757
1758
  },
1758
1759
  };
1759
1760
  }
1761
+
1762
+ export async function randomExtendedDirectionalAppTaggingSecret(): Promise<ExtendedDirectionalAppTaggingSecret> {
1763
+ const resolvedApp = await AztecAddress.random();
1764
+ // Using the fromString method like this is messy as it leaks the underlying serialization format but I don't want to
1765
+ // expose the type's constructor just for tests since in prod the secret is always constructed via compute. Also this
1766
+ // method is tested in extended_directional_app_tagging_secret.test.ts hence all should be fine.
1767
+ return ExtendedDirectionalAppTaggingSecret.fromString(`${Fr.random().toString()}:${resolvedApp.toString()}`);
1768
+ }
@@ -1 +1,2 @@
1
- export { UpdateChecker, getPackageVersion } from './update-checker.js';
1
+ export * from './package_version.js';
2
+ export * from './version_checker.js';
@@ -0,0 +1,17 @@
1
+ import { fileURLToPath } from '@aztec/foundation/url';
2
+
3
+ import { readFileSync } from 'fs';
4
+ import { dirname, resolve } from 'path';
5
+
6
+ /** Returns the package version from the release-please manifest, or undefined if not found. */
7
+ export function getPackageVersion(): string | undefined {
8
+ try {
9
+ const releasePleaseManifestPath = resolve(
10
+ dirname(fileURLToPath(import.meta.url)),
11
+ '../../../../.release-please-manifest.json',
12
+ );
13
+ return JSON.parse(readFileSync(releasePleaseManifestPath).toString())['.'];
14
+ } catch {
15
+ return undefined;
16
+ }
17
+ }
@@ -0,0 +1,65 @@
1
+ import { createLogger } from '@aztec/foundation/log';
2
+ import { RunningPromise } from '@aztec/foundation/promise';
3
+
4
+ import { EventEmitter } from 'node:events';
5
+
6
+ export type EventMap = {
7
+ newVersion: [{ name: string; currentVersion: string; latestVersion: string }];
8
+ };
9
+
10
+ export type VersionCheck = {
11
+ name: string;
12
+ currentVersion: string;
13
+ getLatestVersion: () => Promise<string | undefined>;
14
+ };
15
+
16
+ export class VersionChecker extends EventEmitter<EventMap> {
17
+ private runningPromise: RunningPromise;
18
+ constructor(
19
+ private checks: Array<VersionCheck>,
20
+ intervalCheckMs = 60_000,
21
+ private logger = createLogger('version_checker'),
22
+ ) {
23
+ super();
24
+ this.runningPromise = new RunningPromise(this.run, logger, intervalCheckMs);
25
+ }
26
+
27
+ public start(): void {
28
+ if (this.runningPromise.isRunning()) {
29
+ this.logger.warn('VersionChecker is already running');
30
+ return;
31
+ }
32
+
33
+ this.runningPromise.start();
34
+ this.logger.info('Version check started');
35
+ }
36
+
37
+ public trigger(): Promise<void> {
38
+ return this.runningPromise.trigger();
39
+ }
40
+
41
+ public async stop(): Promise<void> {
42
+ if (!this.runningPromise.isRunning()) {
43
+ this.logger.warn('VersionChecker is not running');
44
+ return;
45
+ }
46
+
47
+ await this.runningPromise.stop();
48
+ this.logger.info('Version checker stopped');
49
+ }
50
+
51
+ private run = async () => {
52
+ await Promise.allSettled(this.checks.map(check => this.checkVersion(check)));
53
+ };
54
+
55
+ private async checkVersion({ name, currentVersion, getLatestVersion }: VersionCheck): Promise<void> {
56
+ try {
57
+ const latestVersion = await getLatestVersion();
58
+ if (latestVersion && latestVersion !== currentVersion) {
59
+ this.emit('newVersion', { name, latestVersion, currentVersion });
60
+ }
61
+ } catch (err) {
62
+ this.logger.warn(`Error checking for new ${name} versions: ${err}`, { err });
63
+ }
64
+ }
65
+ }
@@ -1,101 +0,0 @@
1
- import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
2
- import { type ConfigMappingsType } from '@aztec/foundation/config';
3
- import { EthAddress } from '@aztec/foundation/eth-address';
4
- import { z } from 'zod';
5
- /**
6
- * Configuration for the Validator HA Signer
7
- *
8
- * This config is used for distributed locking and slashing protection
9
- * when running multiple validator nodes in a high-availability setup.
10
- */
11
- export interface ValidatorHASignerConfig {
12
- /** Whether HA signing / slashing protection is enabled */
13
- haSigningEnabled: boolean;
14
- /** L1 contract addresses (rollup address required) */
15
- l1Contracts: Pick<L1ContractAddresses, 'rollupAddress'>;
16
- /** Unique identifier for this node */
17
- nodeId: string;
18
- /** How long to wait between polls when a duty is being signed (ms) */
19
- pollingIntervalMs: number;
20
- /** Maximum time to wait for a duty being signed to complete (ms) */
21
- signingTimeoutMs: number;
22
- /** Maximum age of a stuck duty in ms (defaults to 2x hardcoded Aztec slot duration if not set) */
23
- maxStuckDutiesAgeMs?: number;
24
- /** Optional: clean up old duties after this many hours (disabled if not set) */
25
- cleanupOldDutiesAfterHours?: number;
26
- /**
27
- * PostgreSQL connection string
28
- * Format: postgresql://user:password@host:port/database
29
- */
30
- databaseUrl?: string;
31
- /**
32
- * PostgreSQL connection pool configuration
33
- */
34
- /** Maximum number of clients in the pool (default: 10) */
35
- poolMaxCount?: number;
36
- /** Minimum number of clients in the pool (default: 0) */
37
- poolMinCount?: number;
38
- /** Idle timeout in milliseconds (default: 10000) */
39
- poolIdleTimeoutMs?: number;
40
- /** Connection timeout in milliseconds (default: 0, no timeout) */
41
- poolConnectionTimeoutMs?: number;
42
- }
43
- export declare const validatorHASignerConfigMappings: ConfigMappingsType<ValidatorHASignerConfig>;
44
- export declare const defaultValidatorHASignerConfig: ValidatorHASignerConfig;
45
- /**
46
- * Returns the validator HA signer configuration from environment variables.
47
- * Note: If an environment variable is not set, the default value is used.
48
- * @returns The validator HA signer configuration.
49
- */
50
- export declare function getConfigEnvVars(): ValidatorHASignerConfig;
51
- export declare const ValidatorHASignerConfigSchema: z.ZodObject<{
52
- haSigningEnabled: z.ZodBoolean;
53
- l1Contracts: z.ZodObject<{
54
- rollupAddress: z.ZodType<EthAddress, z.ZodTypeDef, EthAddress>;
55
- }, "strip", z.ZodTypeAny, {
56
- rollupAddress: EthAddress;
57
- }, {
58
- rollupAddress: EthAddress;
59
- }>;
60
- nodeId: z.ZodString;
61
- pollingIntervalMs: z.ZodNumber;
62
- signingTimeoutMs: z.ZodNumber;
63
- maxStuckDutiesAgeMs: z.ZodOptional<z.ZodNumber>;
64
- cleanupOldDutiesAfterHours: z.ZodOptional<z.ZodNumber>;
65
- databaseUrl: z.ZodOptional<z.ZodString>;
66
- poolMaxCount: z.ZodOptional<z.ZodNumber>;
67
- poolMinCount: z.ZodOptional<z.ZodNumber>;
68
- poolIdleTimeoutMs: z.ZodOptional<z.ZodNumber>;
69
- poolConnectionTimeoutMs: z.ZodOptional<z.ZodNumber>;
70
- }, "strip", z.ZodTypeAny, {
71
- haSigningEnabled: boolean;
72
- l1Contracts: {
73
- rollupAddress: EthAddress;
74
- };
75
- nodeId: string;
76
- pollingIntervalMs: number;
77
- signingTimeoutMs: number;
78
- maxStuckDutiesAgeMs?: number | undefined;
79
- cleanupOldDutiesAfterHours?: number | undefined;
80
- databaseUrl?: string | undefined;
81
- poolMaxCount?: number | undefined;
82
- poolMinCount?: number | undefined;
83
- poolIdleTimeoutMs?: number | undefined;
84
- poolConnectionTimeoutMs?: number | undefined;
85
- }, {
86
- haSigningEnabled: boolean;
87
- l1Contracts: {
88
- rollupAddress: EthAddress;
89
- };
90
- nodeId: string;
91
- pollingIntervalMs: number;
92
- signingTimeoutMs: number;
93
- maxStuckDutiesAgeMs?: number | undefined;
94
- cleanupOldDutiesAfterHours?: number | undefined;
95
- databaseUrl?: string | undefined;
96
- poolMaxCount?: number | undefined;
97
- poolMinCount?: number | undefined;
98
- poolIdleTimeoutMs?: number | undefined;
99
- poolConnectionTimeoutMs?: number | undefined;
100
- }>;
101
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaGEtc2lnbmluZy9jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUNqRixPQUFPLEVBQ0wsS0FBSyxrQkFBa0IsRUFNeEIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFHM0QsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUV4Qjs7Ozs7R0FLRztBQUNILE1BQU0sV0FBVyx1QkFBdUI7SUFDdEMsMERBQTBEO0lBQzFELGdCQUFnQixFQUFFLE9BQU8sQ0FBQztJQUMxQixzREFBc0Q7SUFDdEQsV0FBVyxFQUFFLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxlQUFlLENBQUMsQ0FBQztJQUN4RCxzQ0FBc0M7SUFDdEMsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUNmLHNFQUFzRTtJQUN0RSxpQkFBaUIsRUFBRSxNQUFNLENBQUM7SUFDMUIsb0VBQW9FO0lBQ3BFLGdCQUFnQixFQUFFLE1BQU0sQ0FBQztJQUN6QixrR0FBa0c7SUFDbEcsbUJBQW1CLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDN0IsZ0ZBQWdGO0lBQ2hGLDBCQUEwQixDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ3BDOzs7T0FHRztJQUNILFdBQVcsQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNyQjs7T0FFRztJQUNILDBEQUEwRDtJQUMxRCxZQUFZLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDdEIseURBQXlEO0lBQ3pELFlBQVksQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUN0QixvREFBb0Q7SUFDcEQsaUJBQWlCLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDM0Isa0VBQWtFO0lBQ2xFLHVCQUF1QixDQUFDLEVBQUUsTUFBTSxDQUFDO0NBQ2xDO0FBRUQsZUFBTyxNQUFNLCtCQUErQixFQUFFLGtCQUFrQixDQUFDLHVCQUF1QixDQWlFdkYsQ0FBQztBQUVGLGVBQU8sTUFBTSw4QkFBOEIsRUFBRSx1QkFFNUMsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCx3QkFBZ0IsZ0JBQWdCLElBQUksdUJBQXVCLENBRTFEO0FBRUQsZUFBTyxNQUFNLDZCQUE2Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztFQWVFLENBQUMifQ==