@aztec/validator-ha-signer 0.0.1-commit.a89ec08 → 0.0.1-commit.aa0c64f

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 (62) hide show
  1. package/README.md +2 -4
  2. package/dest/db/index.d.ts +2 -1
  3. package/dest/db/index.d.ts.map +1 -1
  4. package/dest/db/index.js +1 -0
  5. package/dest/db/lmdb.d.ts +70 -0
  6. package/dest/db/lmdb.d.ts.map +1 -0
  7. package/dest/db/lmdb.js +223 -0
  8. package/dest/db/migrations/1_initial-schema.d.ts +4 -2
  9. package/dest/db/migrations/1_initial-schema.d.ts.map +1 -1
  10. package/dest/db/migrations/1_initial-schema.js +34 -4
  11. package/dest/db/migrations/2_add-checkpoint-number.d.ts +7 -0
  12. package/dest/db/migrations/2_add-checkpoint-number.d.ts.map +1 -0
  13. package/dest/db/migrations/2_add-checkpoint-number.js +17 -0
  14. package/dest/db/postgres.d.ts +4 -2
  15. package/dest/db/postgres.d.ts.map +1 -1
  16. package/dest/db/postgres.js +15 -13
  17. package/dest/db/schema.d.ts +6 -6
  18. package/dest/db/schema.d.ts.map +1 -1
  19. package/dest/db/schema.js +9 -4
  20. package/dest/db/types.d.ts +46 -21
  21. package/dest/db/types.d.ts.map +1 -1
  22. package/dest/db/types.js +31 -15
  23. package/dest/errors.d.ts +14 -1
  24. package/dest/errors.d.ts.map +1 -1
  25. package/dest/errors.js +15 -0
  26. package/dest/factory.d.ts +28 -8
  27. package/dest/factory.d.ts.map +1 -1
  28. package/dest/factory.js +93 -22
  29. package/dest/metrics.d.ts +51 -0
  30. package/dest/metrics.d.ts.map +1 -0
  31. package/dest/metrics.js +103 -0
  32. package/dest/slashing_protection_service.d.ts +15 -4
  33. package/dest/slashing_protection_service.d.ts.map +1 -1
  34. package/dest/slashing_protection_service.js +26 -12
  35. package/dest/types.d.ts +18 -70
  36. package/dest/types.d.ts.map +1 -1
  37. package/dest/types.js +4 -20
  38. package/dest/validator_ha_signer.d.ts +13 -4
  39. package/dest/validator_ha_signer.d.ts.map +1 -1
  40. package/dest/validator_ha_signer.js +48 -15
  41. package/package.json +11 -7
  42. package/src/db/index.ts +1 -0
  43. package/src/db/lmdb.ts +308 -0
  44. package/src/db/migrations/1_initial-schema.ts +35 -4
  45. package/src/db/migrations/2_add-checkpoint-number.ts +19 -0
  46. package/src/db/postgres.ts +15 -11
  47. package/src/db/schema.ts +9 -4
  48. package/src/db/types.ts +66 -19
  49. package/src/errors.ts +21 -0
  50. package/src/factory.ts +123 -21
  51. package/src/metrics.ts +138 -0
  52. package/src/slashing_protection_service.ts +39 -13
  53. package/src/types.ts +38 -104
  54. package/src/validator_ha_signer.ts +78 -17
  55. package/dest/config.d.ts +0 -101
  56. package/dest/config.d.ts.map +0 -1
  57. package/dest/config.js +0 -92
  58. package/dest/db/in_memory.d.ts +0 -20
  59. package/dest/db/in_memory.d.ts.map +0 -1
  60. package/dest/db/in_memory.js +0 -73
  61. package/src/config.ts +0 -149
  62. package/src/db/in_memory.ts +0 -107
package/dest/db/schema.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * slot, and duty type combination.
7
7
  */ /**
8
8
  * Current schema version
9
- */ export const SCHEMA_VERSION = 1;
9
+ */ export const SCHEMA_VERSION = 2;
10
10
  /**
11
11
  * SQL to create the validator_duties table
12
12
  */ export const CREATE_VALIDATOR_DUTIES_TABLE = `
@@ -15,6 +15,7 @@ CREATE TABLE IF NOT EXISTS validator_duties (
15
15
  validator_address VARCHAR(42) NOT NULL,
16
16
  slot BIGINT NOT NULL,
17
17
  block_number BIGINT NOT NULL,
18
+ checkpoint_number BIGINT NOT NULL DEFAULT 0,
18
19
  block_index_within_checkpoint INTEGER NOT NULL DEFAULT 0,
19
20
  duty_type VARCHAR(30) NOT NULL CHECK (duty_type IN ('BLOCK_PROPOSAL', 'CHECKPOINT_PROPOSAL', 'ATTESTATION', 'ATTESTATIONS_AND_SIGNERS', 'GOVERNANCE_VOTE', 'SLASHING_VOTE')),
20
21
  status VARCHAR(20) NOT NULL CHECK (status IN ('signing', 'signed')),
@@ -87,6 +88,7 @@ WITH inserted AS (
87
88
  validator_address,
88
89
  slot,
89
90
  block_number,
91
+ checkpoint_number,
90
92
  block_index_within_checkpoint,
91
93
  duty_type,
92
94
  status,
@@ -94,13 +96,14 @@ WITH inserted AS (
94
96
  node_id,
95
97
  lock_token,
96
98
  started_at
97
- ) VALUES ($1, $2, $3, $4, $5, $6, 'signing', $7, $8, $9, CURRENT_TIMESTAMP)
99
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, 'signing', $8, $9, $10, CURRENT_TIMESTAMP)
98
100
  ON CONFLICT (rollup_address, validator_address, slot, duty_type, block_index_within_checkpoint) DO NOTHING
99
101
  RETURNING
100
102
  rollup_address,
101
103
  validator_address,
102
104
  slot,
103
105
  block_number,
106
+ checkpoint_number,
104
107
  block_index_within_checkpoint,
105
108
  duty_type,
106
109
  status,
@@ -120,6 +123,7 @@ SELECT
120
123
  validator_address,
121
124
  slot,
122
125
  block_number,
126
+ checkpoint_number,
123
127
  block_index_within_checkpoint,
124
128
  duty_type,
125
129
  status,
@@ -135,8 +139,8 @@ FROM validator_duties
135
139
  WHERE rollup_address = $1
136
140
  AND validator_address = $2
137
141
  AND slot = $3
138
- AND duty_type = $6
139
- AND block_index_within_checkpoint = $5
142
+ AND duty_type = $7
143
+ AND block_index_within_checkpoint = $6
140
144
  AND NOT EXISTS (SELECT 1 FROM inserted);
141
145
  `;
142
146
  /**
@@ -216,6 +220,7 @@ SELECT
216
220
  validator_address,
217
221
  slot,
218
222
  block_number,
223
+ checkpoint_number,
219
224
  block_index_within_checkpoint,
220
225
  duty_type,
221
226
  status,
@@ -1,6 +1,7 @@
1
- import type { BlockNumber, CheckpointNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types';
2
- import type { EthAddress } from '@aztec/foundation/eth-address';
1
+ import { BlockNumber, CheckpointNumber, type IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types';
2
+ import { EthAddress } from '@aztec/foundation/eth-address';
3
3
  import type { Signature } from '@aztec/foundation/eth-signature';
4
+ import { DutyType } from '@aztec/stdlib/ha-signing';
4
5
  /**
5
6
  * Row type from PostgreSQL query
6
7
  */
@@ -9,6 +10,7 @@ export interface DutyRow {
9
10
  validator_address: string;
10
11
  slot: string;
11
12
  block_number: string;
13
+ checkpoint_number: string;
12
14
  block_index_within_checkpoint: number;
13
15
  duty_type: DutyType;
14
16
  status: DutyStatus;
@@ -20,25 +22,36 @@ export interface DutyRow {
20
22
  completed_at: Date | null;
21
23
  error_message: string | null;
22
24
  }
25
+ /**
26
+ * Plain-primitive representation of a duty record suitable for serialization
27
+ * (e.g. msgpackr for LMDB). All domain types are stored as their string/number
28
+ * equivalents. Timestamps are Unix milliseconds.
29
+ */
30
+ export interface StoredDutyRecord {
31
+ rollupAddress: string;
32
+ validatorAddress: string;
33
+ slot: string;
34
+ blockNumber: string;
35
+ checkpointNumber: string;
36
+ blockIndexWithinCheckpoint: number;
37
+ dutyType: DutyType;
38
+ status: DutyStatus;
39
+ messageHash: string;
40
+ signature?: string;
41
+ nodeId: string;
42
+ lockToken: string;
43
+ /** Unix timestamp in milliseconds when signing started */
44
+ startedAtMs: number;
45
+ /** Unix timestamp in milliseconds when signing completed */
46
+ completedAtMs?: number;
47
+ errorMessage?: string;
48
+ }
23
49
  /**
24
50
  * Row type from INSERT_OR_GET_DUTY query (includes is_new flag)
25
51
  */
26
52
  export interface InsertOrGetRow extends DutyRow {
27
53
  is_new: boolean;
28
54
  }
29
- /**
30
- * Type of validator duty being performed
31
- */
32
- export declare enum DutyType {
33
- BLOCK_PROPOSAL = "BLOCK_PROPOSAL",
34
- CHECKPOINT_PROPOSAL = "CHECKPOINT_PROPOSAL",
35
- ATTESTATION = "ATTESTATION",
36
- ATTESTATIONS_AND_SIGNERS = "ATTESTATIONS_AND_SIGNERS",
37
- GOVERNANCE_VOTE = "GOVERNANCE_VOTE",
38
- SLASHING_VOTE = "SLASHING_VOTE",
39
- AUTH_REQUEST = "AUTH_REQUEST",
40
- TXS = "TXS"
41
- }
42
55
  /**
43
56
  * Status of a duty in the database
44
57
  */
@@ -46,8 +59,10 @@ export declare enum DutyStatus {
46
59
  SIGNING = "signing",
47
60
  SIGNED = "signed"
48
61
  }
62
+ export { DutyType };
49
63
  /**
50
- * Record of a validator duty in the database
64
+ * Rich representation of a validator duty, with branded types and Date objects.
65
+ * This is the common output type returned by all SlashingProtectionDatabase implementations.
51
66
  */
52
67
  export interface ValidatorDutyRecord {
53
68
  /** Ethereum address of the rollup contract */
@@ -56,8 +71,10 @@ export interface ValidatorDutyRecord {
56
71
  validatorAddress: EthAddress;
57
72
  /** Slot number for this duty */
58
73
  slot: SlotNumber;
59
- /** Block number for this duty */
74
+ /** Block number for this duty (0 for non-block-proposal duties) */
60
75
  blockNumber: BlockNumber;
76
+ /** Checkpoint number for this duty (0 for attestation and vote duties) */
77
+ checkpointNumber: CheckpointNumber;
61
78
  /** Block index within checkpoint (0, 1, 2... for block proposals, -1 for other duty types) */
62
79
  blockIndexWithinCheckpoint: number;
63
80
  /** Type of duty being performed */
@@ -79,6 +96,13 @@ export interface ValidatorDutyRecord {
79
96
  /** Error message (currently unused) */
80
97
  errorMessage?: string;
81
98
  }
99
+ /**
100
+ * Convert a {@link StoredDutyRecord} (plain-primitive wire format) to a
101
+ * {@link ValidatorDutyRecord} (rich domain type).
102
+ *
103
+ * Shared by LMDB and any future non-Postgres backend implementations.
104
+ */
105
+ export declare function recordFromFields(stored: StoredDutyRecord): ValidatorDutyRecord;
82
106
  /**
83
107
  * Duty identifier for block proposals.
84
108
  * blockIndexWithinCheckpoint is REQUIRED and must be >= 0.
@@ -126,8 +150,10 @@ export declare function getBlockIndexFromDutyIdentifier(duty: DutyIdentifier): n
126
150
  * Additional parameters for checking and recording a new duty
127
151
  */
128
152
  interface CheckAndRecordExtra {
129
- /** Block number for this duty */
130
- blockNumber: BlockNumber | CheckpointNumber;
153
+ /** Block number for this duty (0 for non-block-proposal duties) */
154
+ blockNumber: BlockNumber;
155
+ /** Checkpoint number for this duty (0 for attestation and vote duties) */
156
+ checkpointNumber: CheckpointNumber;
131
157
  /** The signing root (hash) for this duty */
132
158
  messageHash: string;
133
159
  /** Identifier for the node that acquired the lock */
@@ -162,5 +188,4 @@ interface DeleteDutyExtra {
162
188
  * Uses intersection with DutyIdentifier to preserve the discriminated union.
163
189
  */
164
190
  export type DeleteDutyParams = DutyIdentifier & DeleteDutyExtra;
165
- export {};
166
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYi90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUscUJBQXFCLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDeEgsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFakU7O0dBRUc7QUFDSCxNQUFNLFdBQVcsT0FBTztJQUN0QixjQUFjLEVBQUUsTUFBTSxDQUFDO0lBQ3ZCLGlCQUFpQixFQUFFLE1BQU0sQ0FBQztJQUMxQixJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ2IsWUFBWSxFQUFFLE1BQU0sQ0FBQztJQUNyQiw2QkFBNkIsRUFBRSxNQUFNLENBQUM7SUFDdEMsU0FBUyxFQUFFLFFBQVEsQ0FBQztJQUNwQixNQUFNLEVBQUUsVUFBVSxDQUFDO0lBQ25CLFlBQVksRUFBRSxNQUFNLENBQUM7SUFDckIsU0FBUyxFQUFFLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDekIsT0FBTyxFQUFFLE1BQU0sQ0FBQztJQUNoQixVQUFVLEVBQUUsTUFBTSxDQUFDO0lBQ25CLFVBQVUsRUFBRSxJQUFJLENBQUM7SUFDakIsWUFBWSxFQUFFLElBQUksR0FBRyxJQUFJLENBQUM7SUFDMUIsYUFBYSxFQUFFLE1BQU0sR0FBRyxJQUFJLENBQUM7Q0FDOUI7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyxjQUFlLFNBQVEsT0FBTztJQUM3QyxNQUFNLEVBQUUsT0FBTyxDQUFDO0NBQ2pCO0FBRUQ7O0dBRUc7QUFDSCxvQkFBWSxRQUFRO0lBQ2xCLGNBQWMsbUJBQW1CO0lBQ2pDLG1CQUFtQix3QkFBd0I7SUFDM0MsV0FBVyxnQkFBZ0I7SUFDM0Isd0JBQXdCLDZCQUE2QjtJQUNy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
191
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYi90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLGdCQUFnQixFQUFFLEtBQUsscUJBQXFCLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDeEgsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzNELE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUVwRDs7R0FFRztBQUNILE1BQU0sV0FBVyxPQUFPO0lBQ3RCLGNBQWMsRUFBRSxNQUFNLENBQUM7SUFDdkIsaUJBQWlCLEVBQUUsTUFBTSxDQUFDO0lBQzFCLElBQUksRUFBRSxNQUFNLENBQUM7SUFDYixZQUFZLEVBQUUsTUFBTSxDQUFDO0lBQ3JCLGlCQUFpQixFQUFFLE1BQU0sQ0FBQztJQUMxQiw2QkFBNkIsRUFBRSxNQUFNLENBQUM7SUFDdEMsU0FBUyxFQUFFLFFBQVEsQ0FBQztJQUNwQixNQUFNLEVBQUUsVUFBVSxDQUFDO0lBQ25CLFlBQVksRUFBRSxNQUFNLENBQUM7SUFDckIsU0FBUyxFQUFFLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDekIsT0FBTyxFQUFFLE1BQU0sQ0FBQztJQUNoQixVQUFVLEVBQUUsTUFBTSxDQUFDO0lBQ25CLFVBQVUsRUFBRSxJQUFJLENBQUM7SUFDakIsWUFBWSxFQUFFLElBQUksR0FBRyxJQUFJLENBQUM7SUFDMUIsYUFBYSxFQUFFLE1BQU0sR0FBRyxJQUFJLENBQUM7Q0FDOUI7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxXQUFXLGdCQUFnQjtJQUMvQixhQUFhLEVBQUUsTUFBTSxDQUFDO0lBQ3RCLGdCQUFnQixFQUFFLE1BQU0sQ0FBQztJQUN6QixJQUFJLEVBQUUsTUFBTSxDQUFD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
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/db/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/db/types.ts"],"names":[],"mappings":"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"}
package/dest/db/types.js CHANGED
@@ -1,16 +1,6 @@
1
- /**
2
- * Type of validator duty being performed
3
- */ export var DutyType = /*#__PURE__*/ function(DutyType) {
4
- DutyType["BLOCK_PROPOSAL"] = "BLOCK_PROPOSAL";
5
- DutyType["CHECKPOINT_PROPOSAL"] = "CHECKPOINT_PROPOSAL";
6
- DutyType["ATTESTATION"] = "ATTESTATION";
7
- DutyType["ATTESTATIONS_AND_SIGNERS"] = "ATTESTATIONS_AND_SIGNERS";
8
- DutyType["GOVERNANCE_VOTE"] = "GOVERNANCE_VOTE";
9
- DutyType["SLASHING_VOTE"] = "SLASHING_VOTE";
10
- DutyType["AUTH_REQUEST"] = "AUTH_REQUEST";
11
- DutyType["TXS"] = "TXS";
12
- return DutyType;
13
- }({});
1
+ import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
2
+ import { EthAddress } from '@aztec/foundation/eth-address';
3
+ import { DutyType } from '@aztec/stdlib/ha-signing';
14
4
  /**
15
5
  * Status of a duty in the database
16
6
  */ export var DutyStatus = /*#__PURE__*/ function(DutyStatus) {
@@ -18,6 +8,32 @@
18
8
  DutyStatus["SIGNED"] = "signed";
19
9
  return DutyStatus;
20
10
  }({});
11
+ // Re-export DutyType from stdlib
12
+ export { DutyType };
13
+ /**
14
+ * Convert a {@link StoredDutyRecord} (plain-primitive wire format) to a
15
+ * {@link ValidatorDutyRecord} (rich domain type).
16
+ *
17
+ * Shared by LMDB and any future non-Postgres backend implementations.
18
+ */ export function recordFromFields(stored) {
19
+ return {
20
+ rollupAddress: EthAddress.fromString(stored.rollupAddress),
21
+ validatorAddress: EthAddress.fromString(stored.validatorAddress),
22
+ slot: SlotNumber.fromString(stored.slot),
23
+ blockNumber: BlockNumber.fromString(stored.blockNumber),
24
+ checkpointNumber: CheckpointNumber.fromString(stored.checkpointNumber),
25
+ blockIndexWithinCheckpoint: stored.blockIndexWithinCheckpoint,
26
+ dutyType: stored.dutyType,
27
+ status: stored.status,
28
+ messageHash: stored.messageHash,
29
+ signature: stored.signature,
30
+ nodeId: stored.nodeId,
31
+ lockToken: stored.lockToken,
32
+ startedAt: new Date(stored.startedAtMs),
33
+ completedAt: stored.completedAtMs !== undefined ? new Date(stored.completedAtMs) : undefined,
34
+ errorMessage: stored.errorMessage
35
+ };
36
+ }
21
37
  /**
22
38
  * Validates and normalizes the block index for a duty.
23
39
  * - BLOCK_PROPOSAL: validates blockIndexWithinCheckpoint is provided and >= 0
@@ -25,7 +41,7 @@
25
41
  *
26
42
  * @throws Error if BLOCK_PROPOSAL is missing blockIndexWithinCheckpoint or has invalid value
27
43
  */ export function normalizeBlockIndex(dutyType, blockIndexWithinCheckpoint) {
28
- if (dutyType === "BLOCK_PROPOSAL") {
44
+ if (dutyType === DutyType.BLOCK_PROPOSAL) {
29
45
  if (blockIndexWithinCheckpoint === undefined) {
30
46
  throw new Error('BLOCK_PROPOSAL duties require blockIndexWithinCheckpoint to be specified');
31
47
  }
@@ -42,7 +58,7 @@
42
58
  * - BLOCK_PROPOSAL: returns the blockIndexWithinCheckpoint
43
59
  * - Other duty types: returns -1
44
60
  */ export function getBlockIndexFromDutyIdentifier(duty) {
45
- if (duty.dutyType === "BLOCK_PROPOSAL") {
61
+ if (duty.dutyType === DutyType.BLOCK_PROPOSAL) {
46
62
  return duty.blockIndexWithinCheckpoint;
47
63
  }
48
64
  return -1;
package/dest/errors.d.ts CHANGED
@@ -15,6 +15,19 @@ export declare class DutyAlreadySignedError extends Error {
15
15
  readonly signedByNode: string;
16
16
  constructor(slot: SlotNumber, dutyType: DutyType, blockIndexWithinCheckpoint: number, signedByNode: string);
17
17
  }
18
+ /**
19
+ * Thrown when the slashing-protection record for an in-flight signing operation can no longer be
20
+ * updated because it is no longer owned by this node - for example, the stuck-duty cleanup loop
21
+ * deleted the SIGNING row while the remote signer was slow. The produced signature must be
22
+ * discarded rather than broadcast: with no protection record in place, a later attempt for the
23
+ * same duty with different data would sign freely, which is slashable equivocation.
24
+ */
25
+ export declare class SigningLockLostError extends Error {
26
+ readonly slot: SlotNumber;
27
+ readonly dutyType: DutyType;
28
+ readonly nodeId: string;
29
+ constructor(slot: SlotNumber, dutyType: DutyType, nodeId: string);
30
+ }
18
31
  /**
19
32
  * Thrown when attempting to sign data that conflicts with an already-signed duty.
20
33
  * This means the same validator tried to sign DIFFERENT data for the same slot.
@@ -31,4 +44,4 @@ export declare class SlashingProtectionError extends Error {
31
44
  readonly signedByNode: string;
32
45
  constructor(slot: SlotNumber, dutyType: DutyType, blockIndexWithinCheckpoint: number, existingMessageHash: string, attemptedMessageHash: string, signedByNode: string);
33
46
  }
34
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZXJyb3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFbEUsT0FBTyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTlDOzs7O0dBSUc7QUFDSCxxQkFBYSxzQkFBdUIsU0FBUSxLQUFLO2FBRTdCLElBQUksRUFBRSxVQUFVO2FBQ2hCLFFBQVEsRUFBRSxRQUFRO2FBQ2xCLDBCQUEwQixFQUFFLE1BQU07YUFDbEMsWUFBWSxFQUFFLE1BQU07SUFKdEMsWUFDa0IsSUFBSSxFQUFFLFVBQVUsRUFDaEIsUUFBUSxFQUFFLFFBQVEsRUFDbEIsMEJBQTBCLEVBQUUsTUFBTSxFQUNsQyxZQUFZLEVBQUUsTUFBTSxFQUlyQztDQUNGO0FBRUQ7Ozs7OztHQU1HO0FBQ0gscUJBQWEsdUJBQXdCLFNBQVEsS0FBSzthQUU5QixJQUFJLEVBQUUsVUFBVTthQUNoQixRQUFRLEVBQUUsUUFBUTthQUNsQiwwQkFBMEIsRUFBRSxNQUFNO2FBQ2xDLG1CQUFtQixFQUFFLE1BQU07YUFDM0Isb0JBQW9CLEVBQUUsTUFBTTthQUM1QixZQUFZLEVBQUUsTUFBTTtJQU50QyxZQUNrQixJQUFJLEVBQUUsVUFBVSxFQUNoQixRQUFRLEVBQUUsUUFBUSxFQUNsQiwwQkFBMEIsRUFBRSxNQUFNLEVBQ2xDLG1CQUFtQixFQUFFLE1BQU0sRUFDM0Isb0JBQW9CLEVBQUUsTUFBTSxFQUM1QixZQUFZLEVBQUUsTUFBTSxFQU9yQztDQUNGIn0=
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZXJyb3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFbEUsT0FBTyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTlDOzs7O0dBSUc7QUFDSCxxQkFBYSxzQkFBdUIsU0FBUSxLQUFLO2FBRTdCLElBQUksRUFBRSxVQUFVO2FBQ2hCLFFBQVEsRUFBRSxRQUFRO2FBQ2xCLDBCQUEwQixFQUFFLE1BQU07YUFDbEMsWUFBWSxFQUFFLE1BQU07SUFKdEMsWUFDa0IsSUFBSSxFQUFFLFVBQVUsRUFDaEIsUUFBUSxFQUFFLFFBQVEsRUFDbEIsMEJBQTBCLEVBQUUsTUFBTSxFQUNsQyxZQUFZLEVBQUUsTUFBTSxFQUlyQztDQUNGO0FBRUQ7Ozs7OztHQU1HO0FBQ0gscUJBQWEsb0JBQXFCLFNBQVEsS0FBSzthQUUzQixJQUFJLEVBQUUsVUFBVTthQUNoQixRQUFRLEVBQUUsUUFBUTthQUNsQixNQUFNLEVBQUUsTUFBTTtJQUhoQyxZQUNrQixJQUFJLEVBQUUsVUFBVSxFQUNoQixRQUFRLEVBQUUsUUFBUSxFQUNsQixNQUFNLEVBQUUsTUFBTSxFQU8vQjtDQUNGO0FBRUQ7Ozs7OztHQU1HO0FBQ0gscUJBQWEsdUJBQXdCLFNBQVEsS0FBSzthQUU5QixJQUFJLEVBQUUsVUFBVTthQUNoQixRQUFRLEVBQUUsUUFBUTthQUNsQiwwQkFBMEIsRUFBRSxNQUFNO2FBQ2xDLG1CQUFtQixFQUFFLE1BQU07YUFDM0Isb0JBQW9CLEVBQUUsTUFBTTthQUM1QixZQUFZLEVBQUUsTUFBTTtJQU50QyxZQUNrQixJQUFJLEVBQUUsVUFBVSxFQUNoQixRQUFRLEVBQUUsUUFBUSxFQUNsQiwwQkFBMEIsRUFBRSxNQUFNLEVBQ2xDLG1CQUFtQixFQUFFLE1BQU0sRUFDM0Isb0JBQW9CLEVBQUUsTUFBTSxFQUM1QixZQUFZLEVBQUUsTUFBTSxFQU9yQztDQUNGIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;aAE7B,IAAI,EAAE,UAAU;aAChB,QAAQ,EAAE,QAAQ;aAClB,0BAA0B,EAAE,MAAM;aAClC,YAAY,EAAE,MAAM;IAJtC,YACkB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,0BAA0B,EAAE,MAAM,EAClC,YAAY,EAAE,MAAM,EAIrC;CACF;AAED;;;;;;GAMG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;aAE9B,IAAI,EAAE,UAAU;aAChB,QAAQ,EAAE,QAAQ;aAClB,0BAA0B,EAAE,MAAM;aAClC,mBAAmB,EAAE,MAAM;aAC3B,oBAAoB,EAAE,MAAM;aAC5B,YAAY,EAAE,MAAM;IANtC,YACkB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,0BAA0B,EAAE,MAAM,EAClC,mBAAmB,EAAE,MAAM,EAC3B,oBAAoB,EAAE,MAAM,EAC5B,YAAY,EAAE,MAAM,EAOrC;CACF"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;aAE7B,IAAI,EAAE,UAAU;aAChB,QAAQ,EAAE,QAAQ;aAClB,0BAA0B,EAAE,MAAM;aAClC,YAAY,EAAE,MAAM;IAJtC,YACkB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,0BAA0B,EAAE,MAAM,EAClC,YAAY,EAAE,MAAM,EAIrC;CACF;AAED;;;;;;GAMG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;aAE3B,IAAI,EAAE,UAAU;aAChB,QAAQ,EAAE,QAAQ;aAClB,MAAM,EAAE,MAAM;IAHhC,YACkB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EAO/B;CACF;AAED;;;;;;GAMG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;aAE9B,IAAI,EAAE,UAAU;aAChB,QAAQ,EAAE,QAAQ;aAClB,0BAA0B,EAAE,MAAM;aAClC,mBAAmB,EAAE,MAAM;aAC3B,oBAAoB,EAAE,MAAM;aAC5B,YAAY,EAAE,MAAM;IANtC,YACkB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,0BAA0B,EAAE,MAAM,EAClC,mBAAmB,EAAE,MAAM,EAC3B,oBAAoB,EAAE,MAAM,EAC5B,YAAY,EAAE,MAAM,EAOrC;CACF"}
package/dest/errors.js CHANGED
@@ -14,6 +14,21 @@
14
14
  this.name = 'DutyAlreadySignedError';
15
15
  }
16
16
  }
17
+ /**
18
+ * Thrown when the slashing-protection record for an in-flight signing operation can no longer be
19
+ * updated because it is no longer owned by this node - for example, the stuck-duty cleanup loop
20
+ * deleted the SIGNING row while the remote signer was slow. The produced signature must be
21
+ * discarded rather than broadcast: with no protection record in place, a later attempt for the
22
+ * same duty with different data would sign freely, which is slashable equivocation.
23
+ */ export class SigningLockLostError extends Error {
24
+ slot;
25
+ dutyType;
26
+ nodeId;
27
+ constructor(slot, dutyType, nodeId){
28
+ super(`Slashing protection record for ${dutyType} at slot ${slot} was lost before signing completed ` + `(node ${nodeId}); discarding signature`), this.slot = slot, this.dutyType = dutyType, this.nodeId = nodeId;
29
+ this.name = 'SigningLockLostError';
30
+ }
31
+ }
17
32
  /**
18
33
  * Thrown when attempting to sign data that conflicts with an already-signed duty.
19
34
  * This means the same validator tried to sign DIFFERENT data for the same slot.
package/dest/factory.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import type { ValidatorHASignerConfig } from './config.js';
2
- import type { CreateHASignerDeps, SlashingProtectionDatabase } from './types.js';
1
+ import { DateProvider } from '@aztec/foundation/timer';
2
+ import type { LocalSignerConfig, ValidatorHASignerConfig } from '@aztec/stdlib/ha-signing';
3
+ import type { CreateHASignerDeps, CreateLocalSignerWithProtectionDeps, SlashingProtectionDatabase } from './types.js';
3
4
  import { ValidatorHASigner } from './validator_ha_signer.js';
4
5
  /**
5
6
  * Create a validator HA signer with PostgreSQL backend
@@ -16,10 +17,9 @@ import { ValidatorHASigner } from './validator_ha_signer.js';
16
17
  * ```typescript
17
18
  * const { signer, db } = await createHASigner({
18
19
  * databaseUrl: process.env.DATABASE_URL,
19
- * haSigningEnabled: true,
20
20
  * nodeId: 'validator-node-1',
21
21
  * pollingIntervalMs: 100,
22
- * signingTimeoutMs: 3000,
22
+ * peerSigningTimeoutMs: 3000,
23
23
  * });
24
24
  * signer.start(); // Start background cleanup
25
25
  *
@@ -40,16 +40,36 @@ export declare function createHASigner(config: ValidatorHASignerConfig, deps?: C
40
40
  db: SlashingProtectionDatabase;
41
41
  }>;
42
42
  /**
43
- * Create an in-memory SlashingProtectionDatabase that can be shared across
43
+ * Create a local (single-node) signing protection signer backed by LMDB.
44
+ *
45
+ * This provides double-signing protection for nodes that are NOT running in a
46
+ * high-availability (multi-node) setup. It prevents a proposer from sending two
47
+ * proposals for the same slot if the node crashes and restarts mid-proposal.
48
+ *
49
+ * `config.dataDirectory` is required so the protection database is persisted to disk and survives
50
+ * crashes/restarts. Booting without it throws, since an ephemeral store silently drops all
51
+ * double-signing protection across restarts. Set `config.allowEphemeralSigningProtection` to opt
52
+ * into the ephemeral store anyway (dev/test networks only) — a loud warning is logged in that case.
53
+ *
54
+ * @param config - Local signer config
55
+ * @param deps - Optional dependencies (telemetry, date provider).
56
+ * @returns An object containing the signer and database instances.
57
+ */
58
+ export declare function createLocalSignerWithProtection(config: LocalSignerConfig, deps?: CreateLocalSignerWithProtectionDeps): Promise<{
59
+ signer: ValidatorHASigner;
60
+ db: SlashingProtectionDatabase;
61
+ }>;
62
+ /**
63
+ * Create an in-memory LMDB-backed SlashingProtectionDatabase that can be shared across
44
64
  * multiple validator nodes in the same process. Used for testing HA setups.
45
65
  */
46
- export declare function createSharedSlashingProtectionDb(): SlashingProtectionDatabase;
66
+ export declare function createSharedSlashingProtectionDb(dateProvider?: DateProvider): Promise<SlashingProtectionDatabase>;
47
67
  /**
48
68
  * Create a ValidatorHASigner backed by a pre-existing SlashingProtectionDatabase.
49
69
  * Used for testing HA setups where multiple nodes share the same protection database.
50
70
  */
51
- export declare function createSignerFromSharedDb(db: SlashingProtectionDatabase, config: Pick<ValidatorHASignerConfig, 'nodeId' | 'pollingIntervalMs' | 'signingTimeoutMs' | 'maxStuckDutiesAgeMs' | 'l1Contracts'>): {
71
+ export declare function createSignerFromSharedDb(db: SlashingProtectionDatabase, config: Pick<ValidatorHASignerConfig, 'nodeId' | 'pollingIntervalMs' | 'peerSigningTimeoutMs' | 'maxStuckDutiesAgeMs' | 'rollupAddress'>, deps?: CreateLocalSignerWithProtectionDeps): {
52
72
  signer: ValidatorHASigner;
53
73
  db: SlashingProtectionDatabase;
54
74
  };
55
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBS0EsT0FBTyxLQUFLLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFHM0QsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDakYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFN0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWlDRztBQUNILHdCQUFzQixjQUFjLENBQ2xDLE1BQU0sRUFBRSx1QkFBdUIsRUFDL0IsSUFBSSxDQUFDLEVBQUUsa0JBQWtCLEdBQ3hCLE9BQU8sQ0FBQztJQUNULE1BQU0sRUFBRSxpQkFBaUIsQ0FBQztJQUMxQixFQUFFLEVBQUUsMEJBQTBCLENBQUM7Q0FDaEMsQ0FBQyxDQStCRDtBQUVEOzs7R0FHRztBQUNILHdCQUFnQixnQ0FBZ0MsSUFBSSwwQkFBMEIsQ0FFN0U7QUFFRDs7O0dBR0c7QUFDSCx3QkFBZ0Isd0JBQXdCLENBQ3RDLEVBQUUsRUFBRSwwQkFBMEIsRUFDOUIsTUFBTSxFQUFFLElBQUksQ0FDVix1QkFBdUIsRUFDdkIsUUFBUSxHQUFHLG1CQUFtQixHQUFHLGtCQUFrQixHQUFHLHFCQUFxQixHQUFHLGFBQWEsQ0FDNUYsR0FDQTtJQUFFLE1BQU0sRUFBRSxpQkFBaUIsQ0FBQztJQUFDLEVBQUUsRUFBRSwwQkFBMEIsQ0FBQTtDQUFFLENBVy9EIn0=
75
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXZELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLHVCQUF1QixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFRM0YsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsbUNBQW1DLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDdEgsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFN0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NHO0FBQ0gsd0JBQXNCLGNBQWMsQ0FDbEMsTUFBTSxFQUFFLHVCQUF1QixFQUMvQixJQUFJLENBQUMsRUFBRSxrQkFBa0IsR0FDeEIsT0FBTyxDQUFDO0lBQ1QsTUFBTSxFQUFFLGlCQUFpQixDQUFDO0lBQzFCLEVBQUUsRUFBRSwwQkFBMEIsQ0FBQztDQUNoQyxDQUFDLENBaUREO0FBRUQ7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsd0JBQXNCLCtCQUErQixDQUNuRCxNQUFNLEVBQUUsaUJBQWlCLEVBQ3pCLElBQUksQ0FBQyxFQUFFLG1DQUFtQyxHQUN6QyxPQUFPLENBQUM7SUFDVCxNQUFNLEVBQUUsaUJBQWlCLENBQUM7SUFDMUIsRUFBRSxFQUFFLDBCQUEwQixDQUFDO0NBQ2hDLENBQUMsQ0FzREQ7QUFFRDs7O0dBR0c7QUFDSCx3QkFBc0IsZ0NBQWdDLENBQ3BELFlBQVksR0FBRSxZQUFpQyxHQUM5QyxPQUFPLENBQUMsMEJBQTBCLENBQUMsQ0FLckM7QUFFRDs7O0dBR0c7QUFDSCx3QkFBZ0Isd0JBQXdCLENBQ3RDLEVBQUUsRUFBRSwwQkFBMEIsRUFDOUIsTUFBTSxFQUFFLElBQUksQ0FDVix1QkFBdUIsRUFDdkIsUUFBUSxHQUFHLG1CQUFtQixHQUFHLHNCQUFzQixHQUFHLHFCQUFxQixHQUFHLGVBQWUsQ0FDbEcsRUFDRCxJQUFJLENBQUMsRUFBRSxtQ0FBbUMsR0FDekM7SUFBRSxNQUFNLEVBQUUsaUJBQWlCLENBQUM7SUFBQyxFQUFFLEVBQUUsMEJBQTBCLENBQUE7Q0FBRSxDQU0vRCJ9
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAG3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,uBAAuB,EAC/B,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC;IACT,MAAM,EAAE,iBAAiB,CAAC;IAC1B,EAAE,EAAE,0BAA0B,CAAC;CAChC,CAAC,CA+BD;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,IAAI,0BAA0B,CAE7E;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,0BAA0B,EAC9B,MAAM,EAAE,IAAI,CACV,uBAAuB,EACvB,QAAQ,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,qBAAqB,GAAG,aAAa,CAC5F,GACA;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,EAAE,EAAE,0BAA0B,CAAA;CAAE,CAW/D"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAQ3F,OAAO,KAAK,EAAE,kBAAkB,EAAE,mCAAmC,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AACtH,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,uBAAuB,EAC/B,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC;IACT,MAAM,EAAE,iBAAiB,CAAC;IAC1B,EAAE,EAAE,0BAA0B,CAAC;CAChC,CAAC,CAiDD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,iBAAiB,EACzB,IAAI,CAAC,EAAE,mCAAmC,GACzC,OAAO,CAAC;IACT,MAAM,EAAE,iBAAiB,CAAC;IAC1B,EAAE,EAAE,0BAA0B,CAAC;CAChC,CAAC,CAsDD;AAED;;;GAGG;AACH,wBAAsB,gCAAgC,CACpD,YAAY,GAAE,YAAiC,GAC9C,OAAO,CAAC,0BAA0B,CAAC,CAKrC;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,0BAA0B,EAC9B,MAAM,EAAE,IAAI,CACV,uBAAuB,EACvB,QAAQ,GAAG,mBAAmB,GAAG,sBAAsB,GAAG,qBAAqB,GAAG,eAAe,CAClG,EACD,IAAI,CAAC,EAAE,mCAAmC,GACzC;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,EAAE,EAAE,0BAA0B,CAAA;CAAE,CAM/D"}
package/dest/factory.js CHANGED
@@ -1,8 +1,13 @@
1
1
  /**
2
2
  * Factory functions for creating validator HA signers
3
- */ import { Pool } from 'pg';
4
- import { InMemorySlashingProtectionDatabase } from './db/in_memory.js';
3
+ */ import { createLogger } from '@aztec/foundation/log';
4
+ import { DateProvider } from '@aztec/foundation/timer';
5
+ import { createStore } from '@aztec/kv-store/lmdb-v2';
6
+ import { getTelemetryClient } from '@aztec/telemetry-client';
7
+ import { Pool } from 'pg';
8
+ import { LmdbSlashingProtectionDatabase, migrateLmdbSlashingProtectionDatabase } from './db/lmdb.js';
5
9
  import { PostgresSlashingProtectionDatabase } from './db/postgres.js';
10
+ import { HASignerMetrics } from './metrics.js';
6
11
  import { ValidatorHASigner } from './validator_ha_signer.js';
7
12
  /**
8
13
  * Create a validator HA signer with PostgreSQL backend
@@ -19,10 +24,9 @@ import { ValidatorHASigner } from './validator_ha_signer.js';
19
24
  * ```typescript
20
25
  * const { signer, db } = await createHASigner({
21
26
  * databaseUrl: process.env.DATABASE_URL,
22
- * haSigningEnabled: true,
23
27
  * nodeId: 'validator-node-1',
24
28
  * pollingIntervalMs: 100,
25
- * signingTimeoutMs: 3000,
29
+ * peerSigningTimeoutMs: 3000,
26
30
  * });
27
31
  * signer.start(); // Start background cleanup
28
32
  *
@@ -39,14 +43,17 @@ import { ValidatorHASigner } from './validator_ha_signer.js';
39
43
  * @returns An object containing the signer and database instances
40
44
  */ export async function createHASigner(config, deps) {
41
45
  const { databaseUrl, poolMaxCount, poolMinCount, poolIdleTimeoutMs, poolConnectionTimeoutMs, ...signerConfig } = config;
42
- if (!databaseUrl) {
46
+ const databaseUrlValue = databaseUrl?.getValue();
47
+ if (!databaseUrlValue) {
43
48
  throw new Error('databaseUrl is required for createHASigner');
44
49
  }
50
+ const telemetryClient = deps?.telemetryClient ?? getTelemetryClient();
51
+ const dateProvider = deps?.dateProvider ?? new DateProvider();
45
52
  // Create connection pool (or use provided pool)
46
53
  let pool;
47
54
  if (!deps?.pool) {
48
55
  pool = new Pool({
49
- connectionString: databaseUrl,
56
+ connectionString: databaseUrlValue,
50
57
  max: poolMaxCount ?? 10,
51
58
  min: poolMinCount ?? 0,
52
59
  idleTimeoutMillis: poolIdleTimeoutMs ?? 10_000,
@@ -55,14 +62,77 @@ import { ValidatorHASigner } from './validator_ha_signer.js';
55
62
  } else {
56
63
  pool = deps.pool;
57
64
  }
65
+ // pg re-emits idle-client errors (e.g. a Postgres restart severing an idle connection) on the
66
+ // pool. Without an 'error' listener, Node escalates these to an uncaughtException and crashes the
67
+ // process - taking down every HA replica sharing the DB at once. pg destroys and replaces the
68
+ // errored client itself, so logging is the only action needed. Log just message/code, never the
69
+ // raw error object (it can carry connection metadata).
70
+ const log = createLogger('validator-ha-signer:factory');
71
+ pool.on('error', (err)=>{
72
+ log.warn('Postgres pool error on idle client', {
73
+ message: err.message,
74
+ code: err.code
75
+ });
76
+ });
58
77
  // Create database instance
59
78
  const db = new PostgresSlashingProtectionDatabase(pool);
60
79
  // Verify database schema is initialized and version matches
61
80
  await db.initialize();
81
+ // Create metrics
82
+ const metrics = new HASignerMetrics(telemetryClient, signerConfig.nodeId);
62
83
  // Create signer
63
- const signer = new ValidatorHASigner(db, {
64
- ...signerConfig,
65
- databaseUrl
84
+ const signer = new ValidatorHASigner(db, signerConfig, {
85
+ metrics,
86
+ dateProvider
87
+ });
88
+ return {
89
+ signer,
90
+ db
91
+ };
92
+ }
93
+ /**
94
+ * Create a local (single-node) signing protection signer backed by LMDB.
95
+ *
96
+ * This provides double-signing protection for nodes that are NOT running in a
97
+ * high-availability (multi-node) setup. It prevents a proposer from sending two
98
+ * proposals for the same slot if the node crashes and restarts mid-proposal.
99
+ *
100
+ * `config.dataDirectory` is required so the protection database is persisted to disk and survives
101
+ * crashes/restarts. Booting without it throws, since an ephemeral store silently drops all
102
+ * double-signing protection across restarts. Set `config.allowEphemeralSigningProtection` to opt
103
+ * into the ephemeral store anyway (dev/test networks only) — a loud warning is logged in that case.
104
+ *
105
+ * @param config - Local signer config
106
+ * @param deps - Optional dependencies (telemetry, date provider).
107
+ * @returns An object containing the signer and database instances.
108
+ */ export async function createLocalSignerWithProtection(config, deps) {
109
+ const telemetryClient = deps?.telemetryClient ?? getTelemetryClient();
110
+ const dateProvider = deps?.dateProvider ?? new DateProvider();
111
+ const log = createLogger('validator-ha-signer:factory');
112
+ if (!config.dataDirectory) {
113
+ if (!config.allowEphemeralSigningProtection) {
114
+ throw new Error('Local signing protection requires a persistent data directory, but none was configured. ' + 'Set DATA_DIRECTORY so double-signing protection survives restarts, or explicitly opt into an ' + 'ephemeral store (dev/test only) with VALIDATOR_ALLOW_EPHEMERAL_SIGNING_PROTECTION=true.');
115
+ }
116
+ log.warn('Local signing protection is running with an EPHEMERAL store: no data directory is configured. ' + 'Double-signing protection will NOT survive a restart. This is unsafe for production validators.');
117
+ }
118
+ const kvStore = await createStore('signing-protection', LmdbSlashingProtectionDatabase.SCHEMA_VERSION, {
119
+ dataDirectory: config.dataDirectory,
120
+ dataStoreMapSizeKb: config.signingProtectionMapSizeKb ?? config.dataStoreMapSizeKb,
121
+ rollupAddress: config.rollupAddress
122
+ }, undefined, {
123
+ onUpgrade: (dataDirectory, currentVersion, latestVersion)=>migrateLmdbSlashingProtectionDatabase(dataDirectory, currentVersion, latestVersion, config.signingProtectionMapSizeKb ?? config.dataStoreMapSizeKb),
124
+ schemaVersionMismatchPolicy: 'throw',
125
+ versionFileReadFailurePolicy: 'throw'
126
+ });
127
+ const db = new LmdbSlashingProtectionDatabase(kvStore, dateProvider);
128
+ const signerConfig = {
129
+ ...config,
130
+ nodeId: config.nodeId || 'local'
131
+ };
132
+ const metrics = new HASignerMetrics(telemetryClient, signerConfig.nodeId, 'LocalSigningProtectionMetrics');
133
+ const signer = new ValidatorHASigner(db, signerConfig, {
134
+ metrics,
135
+ dateProvider
66
136
  });
67
137
  return {
68
138
  signer,
@@ -70,24 +140,25 @@ import { ValidatorHASigner } from './validator_ha_signer.js';
70
140
  };
71
141
  }
72
142
  /**
73
- * Create an in-memory SlashingProtectionDatabase that can be shared across
143
+ * Create an in-memory LMDB-backed SlashingProtectionDatabase that can be shared across
74
144
  * multiple validator nodes in the same process. Used for testing HA setups.
75
- */ export function createSharedSlashingProtectionDb() {
76
- return new InMemorySlashingProtectionDatabase();
145
+ */ export async function createSharedSlashingProtectionDb(dateProvider = new DateProvider()) {
146
+ const kvStore = await createStore('shared-signing-protection', LmdbSlashingProtectionDatabase.SCHEMA_VERSION, {
147
+ dataStoreMapSizeKb: 1024 * 1024
148
+ });
149
+ return new LmdbSlashingProtectionDatabase(kvStore, dateProvider);
77
150
  }
78
151
  /**
79
152
  * Create a ValidatorHASigner backed by a pre-existing SlashingProtectionDatabase.
80
153
  * Used for testing HA setups where multiple nodes share the same protection database.
81
- */ export function createSignerFromSharedDb(db, config) {
82
- const signerConfig = {
83
- haSigningEnabled: true,
84
- l1Contracts: config.l1Contracts,
85
- nodeId: config.nodeId || `shared-${Date.now()}`,
86
- pollingIntervalMs: config.pollingIntervalMs ?? 100,
87
- signingTimeoutMs: config.signingTimeoutMs ?? 3000,
88
- maxStuckDutiesAgeMs: config.maxStuckDutiesAgeMs
89
- };
90
- const signer = new ValidatorHASigner(db, signerConfig);
154
+ */ export function createSignerFromSharedDb(db, config, deps) {
155
+ const telemetryClient = deps?.telemetryClient ?? getTelemetryClient();
156
+ const dateProvider = deps?.dateProvider ?? new DateProvider();
157
+ const metrics = new HASignerMetrics(telemetryClient, config.nodeId, 'SharedSigningProtectionMetrics');
158
+ const signer = new ValidatorHASigner(db, config, {
159
+ metrics,
160
+ dateProvider
161
+ });
91
162
  return {
92
163
  signer,
93
164
  db
@@ -0,0 +1,51 @@
1
+ import { type TelemetryClient } from '@aztec/telemetry-client';
2
+ export type HACleanupType = 'stuck' | 'old' | 'outdated_rollup';
3
+ /**
4
+ * Metrics for HA signer tracking signing operations, lock acquisition, and cleanup.
5
+ */
6
+ export declare class HASignerMetrics {
7
+ private nodeId;
8
+ private signingDuration;
9
+ private signingSuccessCount;
10
+ private dutyAlreadySignedCount;
11
+ private slashingProtectionCount;
12
+ private signingErrorCount;
13
+ private lockAcquiredCount;
14
+ private cleanupStuckDutiesCount;
15
+ private cleanupOldDutiesCount;
16
+ private cleanupOutdatedRollupDutiesCount;
17
+ constructor(client: TelemetryClient, nodeId: string, name?: string);
18
+ /**
19
+ * Record a successful signing operation.
20
+ * @param dutyType - The type of duty signed
21
+ * @param durationMs - Duration from start of signWithProtection to completion
22
+ */
23
+ recordSigningSuccess(dutyType: string, durationMs: number): void;
24
+ /**
25
+ * Record a DutyAlreadySignedError (expected in HA; another node signed first).
26
+ * @param dutyType - The type of duty
27
+ */
28
+ recordDutyAlreadySigned(dutyType: string): void;
29
+ /**
30
+ * Record a SlashingProtectionError (attempted to sign different data for same duty).
31
+ * @param dutyType - The type of duty
32
+ */
33
+ recordSlashingProtection(dutyType: string): void;
34
+ /**
35
+ * Record a signing function failure (lock will be deleted for retry).
36
+ * @param dutyType - The type of duty
37
+ */
38
+ recordSigningError(dutyType: string): void;
39
+ /**
40
+ * Record lock acquisition.
41
+ * @param acquired - Whether a new lock was acquired (true) or existing record found (false)
42
+ */
43
+ recordLockAcquire(acquired: boolean): void;
44
+ /**
45
+ * Record cleanup metrics.
46
+ * @param type - Type of cleanup
47
+ * @param count - Number of duties cleaned up
48
+ */
49
+ recordCleanup(type: HACleanupType, count: number): void;
50
+ }
51
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0cmljcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL21ldHJpY3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUlMLEtBQUssZUFBZSxFQUdyQixNQUFNLHlCQUF5QixDQUFDO0FBRWpDLE1BQU0sTUFBTSxhQUFhLEdBQUcsT0FBTyxHQUFHLEtBQUssR0FBRyxpQkFBaUIsQ0FBQztBQUVoRTs7R0FFRztBQUNILHFCQUFhLGVBQWU7SUFrQnhCLE9BQU8sQ0FBQyxNQUFNO0lBaEJoQixPQUFPLENBQUMsZUFBZSxDQUFZO0lBQ25DLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBZ0I7SUFDM0MsT0FBTyxDQUFDLHNCQUFzQixDQUFnQjtJQUM5QyxPQUFPLENBQUMsdUJBQXVCLENBQWdCO0lBQy9DLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBZ0I7SUFHekMsT0FBTyxDQUFDLGlCQUFpQixDQUFnQjtJQUd6QyxPQUFPLENBQUMsdUJBQXVCLENBQWdCO0lBQy9DLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBZ0I7SUFDN0MsT0FBTyxDQUFDLGdDQUFnQyxDQUFnQjtJQUV4RCxZQUNFLE1BQU0sRUFBRSxlQUFlLEVBQ2YsTUFBTSxFQUFFLE1BQU0sRUFDdEIsSUFBSSxTQUFvQixFQXFCekI7SUFFRDs7OztPQUlHO0lBQ0ksb0JBQW9CLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FPdEU7SUFFRDs7O09BR0c7SUFDSSx1QkFBdUIsQ0FBQyxRQUFRLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FNckQ7SUFFRDs7O09BR0c7SUFDSSx3QkFBd0IsQ0FBQyxRQUFRLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FNdEQ7SUFFRDs7O09BR0c7SUFDSSxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FNaEQ7SUFFRDs7O09BR0c7SUFDSSxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsT0FBTyxHQUFHLElBQUksQ0FPaEQ7SUFFRDs7OztPQUlHO0lBQ0ksYUFBYSxDQUFDLElBQUksRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLE1BQU0sR0FBRyxJQUFJLENBWTdEO0NBQ0YifQ==