@aztec/validator-ha-signer 0.0.1-commit.a072138 → 0.0.1-commit.aada20e3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/config.d.ts +23 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +19 -0
- package/dest/db/postgres.d.ts +17 -3
- package/dest/db/postgres.d.ts.map +1 -1
- package/dest/db/postgres.js +32 -3
- package/dest/db/schema.d.ts +15 -9
- package/dest/db/schema.d.ts.map +1 -1
- package/dest/db/schema.js +36 -20
- package/dest/db/types.d.ts +7 -2
- package/dest/db/types.d.ts.map +1 -1
- package/dest/slashing_protection_service.d.ts +8 -4
- package/dest/slashing_protection_service.d.ts.map +1 -1
- package/dest/slashing_protection_service.js +41 -12
- package/dest/types.d.ts +18 -5
- package/dest/types.d.ts.map +1 -1
- package/dest/validator_ha_signer.d.ts +4 -3
- package/dest/validator_ha_signer.d.ts.map +1 -1
- package/dest/validator_ha_signer.js +8 -3
- package/package.json +3 -2
- package/src/config.ts +24 -0
- package/src/db/postgres.ts +33 -0
- package/src/db/schema.ts +38 -20
- package/src/db/types.ts +6 -1
- package/src/slashing_protection_service.ts +52 -15
- package/src/types.ts +19 -0
- package/src/validator_ha_signer.ts +8 -3
|
@@ -23,6 +23,7 @@ export declare class SlashingProtectionService {
|
|
|
23
23
|
private readonly signingTimeoutMs;
|
|
24
24
|
private readonly maxStuckDutiesAgeMs;
|
|
25
25
|
private cleanupRunningPromise;
|
|
26
|
+
private lastOldDutiesCleanupAtMs?;
|
|
26
27
|
constructor(db: SlashingProtectionDatabase, config: ValidatorHASignerConfig);
|
|
27
28
|
/**
|
|
28
29
|
* Check if a duty can be performed and acquire the lock if so.
|
|
@@ -33,7 +34,6 @@ export declare class SlashingProtectionService {
|
|
|
33
34
|
* 2. If insert succeeds, we acquired the lock - return the lockToken
|
|
34
35
|
* 3. If a record exists, handle based on status:
|
|
35
36
|
* - SIGNED: Throw appropriate error (already signed or slashing protection)
|
|
36
|
-
* - FAILED: Delete the failed record
|
|
37
37
|
* - SIGNING: Wait and poll until status changes, then handle result
|
|
38
38
|
*
|
|
39
39
|
* @returns The lockToken that must be used for recordSuccess/deleteDuty
|
|
@@ -65,7 +65,11 @@ export declare class SlashingProtectionService {
|
|
|
65
65
|
* Start running tasks.
|
|
66
66
|
* Cleanup runs immediately on start to recover from any previous crashes.
|
|
67
67
|
*/
|
|
68
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Start the background cleanup task.
|
|
70
|
+
* Also performs one-time cleanup of duties with outdated rollup addresses.
|
|
71
|
+
*/
|
|
72
|
+
start(): Promise<void>;
|
|
69
73
|
/**
|
|
70
74
|
* Stop the background cleanup task.
|
|
71
75
|
*/
|
|
@@ -75,6 +79,6 @@ export declare class SlashingProtectionService {
|
|
|
75
79
|
* Should be called after stop() during graceful shutdown.
|
|
76
80
|
*/
|
|
77
81
|
close(): Promise<void>;
|
|
78
|
-
private
|
|
82
|
+
private cleanup;
|
|
79
83
|
}
|
|
80
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
84
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hpbmdfcHJvdGVjdGlvbl9zZXJ2aWNlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2xhc2hpbmdfcHJvdGVjdGlvbl9zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVVBLE9BQU8sRUFDTCxLQUFLLG9CQUFvQixFQUN6QixLQUFLLGdCQUFnQixFQUVyQixLQUFLLG1CQUFtQixFQUV6QixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEtBQUssRUFBRSwwQkFBMEIsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV0Rjs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILHFCQUFhLHlCQUF5QjtJQVVsQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUU7SUFDbkIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNO0lBVnpCLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFTO0lBQzdCLE9BQU8sQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQVM7SUFDM0MsT0FBTyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBUztJQUMxQyxPQUFPLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFTO0lBRTdDLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBaUI7SUFDOUMsT0FBTyxDQUFDLHdCQUF3QixDQUFDLENBQVM7SUFFMUMsWUFDbUIsRUFBRSxFQUFFLDBCQUEwQixFQUM5QixNQUFNLEVBQUUsdUJBQXVCLEVBU2pEO0lBRUQ7Ozs7Ozs7Ozs7Ozs7O09BY0c7SUFDRyxjQUFjLENBQUMsTUFBTSxFQUFFLG9CQUFvQixHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FpRWxFO0lBRUQ7Ozs7OztPQU1HO0lBQ0csYUFBYSxDQUFDLE1BQU0sRUFBRSxtQkFBbUIsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBMkJqRTtJQUVEOzs7Ozs7T0FNRztJQUNHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQXdCM0Q7SUFFRDs7T0FFRztJQUNILElBQUksTUFBTSxJQUFJLE1BQU0sQ0FFbkI7SUFFRDs7O09BR0c7SUFDSDs7O09BR0c7SUFDRyxLQUFLLGtCQVdWO0lBRUQ7O09BRUc7SUFDRyxJQUFJLGtCQUdUO0lBRUQ7OztPQUdHO0lBQ0csS0FBSyxrQkFHVjtZQU1hLE9BQU87Q0E2QnRCIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slashing_protection_service.d.ts","sourceRoot":"","sources":["../src/slashing_protection_service.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EAErB,KAAK,mBAAmB,EAEzB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAEtF;;;;;;;;;;;;;;GAcG;AACH,qBAAa,yBAAyB;
|
|
1
|
+
{"version":3,"file":"slashing_protection_service.d.ts","sourceRoot":"","sources":["../src/slashing_protection_service.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EAErB,KAAK,mBAAmB,EAEzB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAEtF;;;;;;;;;;;;;;GAcG;AACH,qBAAa,yBAAyB;IAUlC,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAVzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAE7C,OAAO,CAAC,qBAAqB,CAAiB;IAC9C,OAAO,CAAC,wBAAwB,CAAC,CAAS;IAE1C,YACmB,EAAE,EAAE,0BAA0B,EAC9B,MAAM,EAAE,uBAAuB,EASjD;IAED;;;;;;;;;;;;;;OAcG;IACG,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiElE;IAED;;;;;;OAMG;IACG,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CA2BjE;IAED;;;;;;OAMG;IACG,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAwB3D;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;OAGG;IACH;;;OAGG;IACG,KAAK,kBAWV;IAED;;OAEG;IACG,IAAI,kBAGT;IAED;;;OAGG;IACG,KAAK,kBAGV;YAMa,OAAO;CA6BtB"}
|
|
@@ -30,6 +30,7 @@ import { DutyAlreadySignedError, SlashingProtectionError } from './errors.js';
|
|
|
30
30
|
signingTimeoutMs;
|
|
31
31
|
maxStuckDutiesAgeMs;
|
|
32
32
|
cleanupRunningPromise;
|
|
33
|
+
lastOldDutiesCleanupAtMs;
|
|
33
34
|
constructor(db, config){
|
|
34
35
|
this.db = db;
|
|
35
36
|
this.config = config;
|
|
@@ -38,7 +39,7 @@ import { DutyAlreadySignedError, SlashingProtectionError } from './errors.js';
|
|
|
38
39
|
this.signingTimeoutMs = config.signingTimeoutMs;
|
|
39
40
|
// Default to 144s (2x 72s Aztec slot duration) if not explicitly configured
|
|
40
41
|
this.maxStuckDutiesAgeMs = config.maxStuckDutiesAgeMs ?? 144_000;
|
|
41
|
-
this.cleanupRunningPromise = new RunningPromise(this.
|
|
42
|
+
this.cleanupRunningPromise = new RunningPromise(this.cleanup.bind(this), this.log, this.maxStuckDutiesAgeMs);
|
|
42
43
|
}
|
|
43
44
|
/**
|
|
44
45
|
* Check if a duty can be performed and acquire the lock if so.
|
|
@@ -49,7 +50,6 @@ import { DutyAlreadySignedError, SlashingProtectionError } from './errors.js';
|
|
|
49
50
|
* 2. If insert succeeds, we acquired the lock - return the lockToken
|
|
50
51
|
* 3. If a record exists, handle based on status:
|
|
51
52
|
* - SIGNED: Throw appropriate error (already signed or slashing protection)
|
|
52
|
-
* - FAILED: Delete the failed record
|
|
53
53
|
* - SIGNING: Wait and poll until status changes, then handle result
|
|
54
54
|
*
|
|
55
55
|
* @returns The lockToken that must be used for recordSuccess/deleteDuty
|
|
@@ -116,9 +116,9 @@ import { DutyAlreadySignedError, SlashingProtectionError } from './errors.js';
|
|
|
116
116
|
*
|
|
117
117
|
* @returns true if the update succeeded, false if token didn't match
|
|
118
118
|
*/ async recordSuccess(params) {
|
|
119
|
-
const { validatorAddress, slot, dutyType, signature, nodeId, lockToken } = params;
|
|
119
|
+
const { rollupAddress, validatorAddress, slot, dutyType, signature, nodeId, lockToken } = params;
|
|
120
120
|
const blockIndexWithinCheckpoint = getBlockIndexFromDutyIdentifier(params);
|
|
121
|
-
const success = await this.db.updateDutySigned(validatorAddress, slot, dutyType, signature.toString(), lockToken, blockIndexWithinCheckpoint);
|
|
121
|
+
const success = await this.db.updateDutySigned(rollupAddress, validatorAddress, slot, dutyType, signature.toString(), lockToken, blockIndexWithinCheckpoint);
|
|
122
122
|
if (success) {
|
|
123
123
|
this.log.info(`Recorded successful signing for duty ${dutyType} at slot ${slot}`, {
|
|
124
124
|
validatorAddress: validatorAddress.toString(),
|
|
@@ -139,9 +139,9 @@ import { DutyAlreadySignedError, SlashingProtectionError } from './errors.js';
|
|
|
139
139
|
*
|
|
140
140
|
* @returns true if the delete succeeded, false if token didn't match
|
|
141
141
|
*/ async deleteDuty(params) {
|
|
142
|
-
const { validatorAddress, slot, dutyType, lockToken } = params;
|
|
142
|
+
const { rollupAddress, validatorAddress, slot, dutyType, lockToken } = params;
|
|
143
143
|
const blockIndexWithinCheckpoint = getBlockIndexFromDutyIdentifier(params);
|
|
144
|
-
const success = await this.db.deleteDuty(validatorAddress, slot, dutyType, lockToken, blockIndexWithinCheckpoint);
|
|
144
|
+
const success = await this.db.deleteDuty(rollupAddress, validatorAddress, slot, dutyType, lockToken, blockIndexWithinCheckpoint);
|
|
145
145
|
if (success) {
|
|
146
146
|
this.log.info(`Deleted duty ${dutyType} at slot ${slot} to allow retry`, {
|
|
147
147
|
validatorAddress: validatorAddress.toString()
|
|
@@ -161,7 +161,17 @@ import { DutyAlreadySignedError, SlashingProtectionError } from './errors.js';
|
|
|
161
161
|
/**
|
|
162
162
|
* Start running tasks.
|
|
163
163
|
* Cleanup runs immediately on start to recover from any previous crashes.
|
|
164
|
-
*/
|
|
164
|
+
*/ /**
|
|
165
|
+
* Start the background cleanup task.
|
|
166
|
+
* Also performs one-time cleanup of duties with outdated rollup addresses.
|
|
167
|
+
*/ async start() {
|
|
168
|
+
// One-time cleanup at startup: remove duties from previous rollup versions
|
|
169
|
+
const numOutdatedRollupDuties = await this.db.cleanupOutdatedRollupDuties(this.config.l1Contracts.rollupAddress);
|
|
170
|
+
if (numOutdatedRollupDuties > 0) {
|
|
171
|
+
this.log.info(`Cleaned up ${numOutdatedRollupDuties} duties with outdated rollup address at startup`, {
|
|
172
|
+
currentRollupAddress: this.config.l1Contracts.rollupAddress.toString()
|
|
173
|
+
});
|
|
174
|
+
}
|
|
165
175
|
this.cleanupRunningPromise.start();
|
|
166
176
|
this.log.info('Slashing protection service started', {
|
|
167
177
|
nodeId: this.config.nodeId
|
|
@@ -183,14 +193,33 @@ import { DutyAlreadySignedError, SlashingProtectionError } from './errors.js';
|
|
|
183
193
|
this.log.info('Slashing protection database connection closed');
|
|
184
194
|
}
|
|
185
195
|
/**
|
|
186
|
-
*
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
196
|
+
* Periodic cleanup of stuck duties and optionally old signed duties.
|
|
197
|
+
* Runs in the background via RunningPromise.
|
|
198
|
+
*/ async cleanup() {
|
|
199
|
+
// 1. Clean up stuck duties (our own node's duties that got stuck in 'signing' status)
|
|
200
|
+
const numStuckDuties = await this.db.cleanupOwnStuckDuties(this.config.nodeId, this.maxStuckDutiesAgeMs);
|
|
201
|
+
if (numStuckDuties > 0) {
|
|
202
|
+
this.log.verbose(`Cleaned up ${numStuckDuties} stuck duties`, {
|
|
191
203
|
nodeId: this.config.nodeId,
|
|
192
204
|
maxStuckDutiesAgeMs: this.maxStuckDutiesAgeMs
|
|
193
205
|
});
|
|
194
206
|
}
|
|
207
|
+
// 2. Clean up old signed duties if configured
|
|
208
|
+
// we shouldn't run this as often as stuck duty cleanup.
|
|
209
|
+
if (this.config.cleanupOldDutiesAfterHours !== undefined) {
|
|
210
|
+
const maxAgeMs = this.config.cleanupOldDutiesAfterHours * 60 * 60 * 1000;
|
|
211
|
+
const nowMs = Date.now();
|
|
212
|
+
const shouldRun = this.lastOldDutiesCleanupAtMs === undefined || nowMs - this.lastOldDutiesCleanupAtMs >= maxAgeMs;
|
|
213
|
+
if (shouldRun) {
|
|
214
|
+
const numOldDuties = await this.db.cleanupOldDuties(maxAgeMs);
|
|
215
|
+
this.lastOldDutiesCleanupAtMs = nowMs;
|
|
216
|
+
if (numOldDuties > 0) {
|
|
217
|
+
this.log.verbose(`Cleaned up ${numOldDuties} old signed duties`, {
|
|
218
|
+
cleanupOldDutiesAfterHours: this.config.cleanupOldDutiesAfterHours,
|
|
219
|
+
maxAgeMs
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
195
224
|
}
|
|
196
225
|
}
|
package/dest/types.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { BlockNumber, type CheckpointNumber, type IndexWithinCheckpoint, type Sl
|
|
|
2
2
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
3
|
import type { Pool } from 'pg';
|
|
4
4
|
import type { ValidatorHASignerConfig } from './config.js';
|
|
5
|
-
import { type BlockProposalDutyIdentifier, type CheckAndRecordParams, type DeleteDutyParams, type DutyIdentifier, DutyType, type OtherDutyIdentifier, type RecordSuccessParams, type ValidatorDutyRecord } from './db/types.js';
|
|
6
|
-
export type { BlockProposalDutyIdentifier, CheckAndRecordParams, DeleteDutyParams, DutyIdentifier, OtherDutyIdentifier, RecordSuccessParams, ValidatorDutyRecord, ValidatorHASignerConfig, };
|
|
5
|
+
import { type BlockProposalDutyIdentifier, type CheckAndRecordParams, type DeleteDutyParams, type DutyIdentifier, type DutyRow, DutyType, type OtherDutyIdentifier, type RecordSuccessParams, type ValidatorDutyRecord } from './db/types.js';
|
|
6
|
+
export type { BlockProposalDutyIdentifier, CheckAndRecordParams, DeleteDutyParams, DutyIdentifier, DutyRow, OtherDutyIdentifier, RecordSuccessParams, ValidatorDutyRecord, ValidatorHASignerConfig, };
|
|
7
7
|
export { DutyStatus, DutyType, getBlockIndexFromDutyIdentifier, normalizeBlockIndex } from './db/types.js';
|
|
8
8
|
/**
|
|
9
9
|
* Result of tryInsertOrGetExisting operation
|
|
@@ -116,7 +116,7 @@ export interface SlashingProtectionDatabase {
|
|
|
116
116
|
*
|
|
117
117
|
* @returns true if the update succeeded, false if token didn't match or duty not found
|
|
118
118
|
*/
|
|
119
|
-
updateDutySigned(validatorAddress: EthAddress, slot: SlotNumber, dutyType: DutyType, signature: string, lockToken: string, blockIndexWithinCheckpoint: number): Promise<boolean>;
|
|
119
|
+
updateDutySigned(rollupAddress: EthAddress, validatorAddress: EthAddress, slot: SlotNumber, dutyType: DutyType, signature: string, lockToken: string, blockIndexWithinCheckpoint: number): Promise<boolean>;
|
|
120
120
|
/**
|
|
121
121
|
* Delete a duty record.
|
|
122
122
|
* Only succeeds if the lockToken matches (caller must be the one who created the duty).
|
|
@@ -124,16 +124,29 @@ export interface SlashingProtectionDatabase {
|
|
|
124
124
|
*
|
|
125
125
|
* @returns true if the delete succeeded, false if token didn't match or duty not found
|
|
126
126
|
*/
|
|
127
|
-
deleteDuty(validatorAddress: EthAddress, slot: SlotNumber, dutyType: DutyType, lockToken: string, blockIndexWithinCheckpoint: number): Promise<boolean>;
|
|
127
|
+
deleteDuty(rollupAddress: EthAddress, validatorAddress: EthAddress, slot: SlotNumber, dutyType: DutyType, lockToken: string, blockIndexWithinCheckpoint: number): Promise<boolean>;
|
|
128
128
|
/**
|
|
129
129
|
* Cleanup own stuck duties
|
|
130
130
|
* @returns the number of duties cleaned up
|
|
131
131
|
*/
|
|
132
132
|
cleanupOwnStuckDuties(nodeId: string, maxAgeMs: number): Promise<number>;
|
|
133
|
+
/**
|
|
134
|
+
* Cleanup duties with outdated rollup address.
|
|
135
|
+
* Removes all duties where the rollup address doesn't match the current one.
|
|
136
|
+
* Used after a rollup upgrade to clean up duties for the old rollup.
|
|
137
|
+
* @returns the number of duties cleaned up
|
|
138
|
+
*/
|
|
139
|
+
cleanupOutdatedRollupDuties(currentRollupAddress: EthAddress): Promise<number>;
|
|
140
|
+
/**
|
|
141
|
+
* Cleanup old signed duties.
|
|
142
|
+
* Removes only signed duties older than the specified age.
|
|
143
|
+
* @returns the number of duties cleaned up
|
|
144
|
+
*/
|
|
145
|
+
cleanupOldDuties(maxAgeMs: number): Promise<number>;
|
|
133
146
|
/**
|
|
134
147
|
* Close the database connection.
|
|
135
148
|
* Should be called during graceful shutdown.
|
|
136
149
|
*/
|
|
137
150
|
close(): Promise<void>;
|
|
138
151
|
}
|
|
139
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
152
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsV0FBVyxFQUNYLEtBQUssZ0JBQWdCLEVBQ3JCLEtBQUsscUJBQXFCLEVBQzFCLEtBQUssVUFBVSxFQUNoQixNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRWhFLE9BQU8sS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLElBQUksQ0FBQztBQUUvQixPQUFPLEtBQUssRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUMzRCxPQUFPLEVBQ0wsS0FBSywyQkFBMkIsRUFDaEMsS0FBSyxvQkFBb0IsRUFDekIsS0FBSyxnQkFBZ0IsRUFDckIsS0FBSyxjQUFjLEVBQ25CLEtBQUssT0FBTyxFQUNaLFFBQVEsRUFDUixLQUFLLG1CQUFtQixFQUN4QixLQUFLLG1CQUFtQixFQUN4QixLQUFLLG1CQUFtQixFQUN6QixNQUFNLGVBQWUsQ0FBQztBQUV2QixZQUFZLEVBQ1YsMkJBQTJCLEVBQzNCLG9CQUFvQixFQUNwQixnQkFBZ0IsRUFDaEIsY0FBYyxFQUNkLE9BQU8sRUFDUCxtQkFBbUIsRUFDbkIsbUJBQW1CLEVBQ25CLG1CQUFtQixFQUNuQix1QkFBdUIsR0FDeEIsQ0FBQztBQUNGLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLCtCQUErQixFQUFFLG1CQUFtQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNHOztHQUVHO0FBQ0gsTUFBTSxXQUFXLG9CQUFvQjtJQUNuQywyRUFBMkU7SUFDM0UsS0FBSyxFQUFFLE9BQU8sQ0FBQztJQUNmLHFEQUFxRDtJQUNyRCxNQUFNLEVBQUUsbUJBQW1CLENBQUM7Q0FDN0I7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyxrQkFBa0I7SUFDakM7OztPQUdHO0lBQ0gsSUFBSSxD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
|
package/dest/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* node will sign for a given duty (slot + duty type).
|
|
7
7
|
*/
|
|
8
8
|
import type { Buffer32 } from '@aztec/foundation/buffer';
|
|
9
|
-
import
|
|
9
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
10
10
|
import type { Signature } from '@aztec/foundation/eth-signature';
|
|
11
11
|
import type { ValidatorHASignerConfig } from './config.js';
|
|
12
12
|
import { type HAProtectedSigningContext, type SlashingProtectionDatabase } from './types.js';
|
|
@@ -33,6 +33,7 @@ export declare class ValidatorHASigner {
|
|
|
33
33
|
private readonly config;
|
|
34
34
|
private readonly log;
|
|
35
35
|
private readonly slashingProtection;
|
|
36
|
+
private readonly rollupAddress;
|
|
36
37
|
constructor(db: SlashingProtectionDatabase, config: ValidatorHASignerConfig);
|
|
37
38
|
/**
|
|
38
39
|
* Sign a message with slashing protection.
|
|
@@ -60,11 +61,11 @@ export declare class ValidatorHASigner {
|
|
|
60
61
|
* Start the HA signer background tasks (cleanup of stuck duties).
|
|
61
62
|
* Should be called after construction and before signing operations.
|
|
62
63
|
*/
|
|
63
|
-
start(): void
|
|
64
|
+
start(): Promise<void>;
|
|
64
65
|
/**
|
|
65
66
|
* Stop the HA signer background tasks and close database connection.
|
|
66
67
|
* Should be called during graceful shutdown.
|
|
67
68
|
*/
|
|
68
69
|
stop(): Promise<void>;
|
|
69
70
|
}
|
|
70
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
71
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9yX2hhX3NpZ25lci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3ZhbGlkYXRvcl9oYV9zaWduZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBQ0gsT0FBTyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDekQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzNELE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBR2pFLE9BQU8sS0FBSyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRzNELE9BQU8sRUFDTCxLQUFLLHlCQUF5QixFQUM5QixLQUFLLDBCQUEwQixFQUVoQyxNQUFNLFlBQVksQ0FBQztBQUVwQjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBQ0gscUJBQWEsaUJBQWlCO0lBTzFCLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTTtJQU56QixPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBUztJQUM3QixPQUFPLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUE0QjtJQUMvRCxPQUFPLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBYTtJQUUzQyxZQUNFLEVBQUUsRUFBRSwwQkFBMEIsRUFDYixNQUFNLEVBQUUsdUJBQXVCLEVBa0JqRDtJQUVEOzs7Ozs7Ozs7Ozs7Ozs7O09BZ0JHO0lBQ0csa0JBQWtCLENBQ3RCLGdCQUFnQixFQUFFLFVBQVUsRUFDNUIsV0FBVyxFQUFFLFFBQVEsRUFDckIsT0FBTyxFQUFFLHlCQUF5QixFQUNsQyxNQUFNLEVBQUUsQ0FBQyxXQUFXLEVBQUUsUUFBUSxLQUFLLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FDcEQsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQStDcEI7SUFFRDs7T0FFRztJQUNILElBQUksTUFBTSxJQUFJLE1BQU0sQ0FFbkI7SUFFRDs7O09BR0c7SUFDRyxLQUFLLGtCQUVWO0lBRUQ7OztPQUdHO0lBQ0csSUFBSSxrQkFHVDtDQUNGIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator_ha_signer.d.ts","sourceRoot":"","sources":["../src/validator_ha_signer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,
|
|
1
|
+
{"version":3,"file":"validator_ha_signer.d.ts","sourceRoot":"","sources":["../src/validator_ha_signer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAGjE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAG3D,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAEhC,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,iBAAiB;IAO1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IANzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA4B;IAC/D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAa;IAE3C,YACE,EAAE,EAAE,0BAA0B,EACb,MAAM,EAAE,uBAAuB,EAkBjD;IAED;;;;;;;;;;;;;;;;OAgBG;IACG,kBAAkB,CACtB,gBAAgB,EAAE,UAAU,EAC5B,WAAW,EAAE,QAAQ,EACrB,OAAO,EAAE,yBAAyB,EAClC,MAAM,EAAE,CAAC,WAAW,EAAE,QAAQ,KAAK,OAAO,CAAC,SAAS,CAAC,GACpD,OAAO,CAAC,SAAS,CAAC,CA+CpB;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;OAGG;IACG,KAAK,kBAEV;IAED;;;OAGG;IACG,IAAI,kBAGT;CACF"}
|
|
@@ -30,6 +30,7 @@ import { getBlockNumberFromSigningContext } from './types.js';
|
|
|
30
30
|
config;
|
|
31
31
|
log;
|
|
32
32
|
slashingProtection;
|
|
33
|
+
rollupAddress;
|
|
33
34
|
constructor(db, config){
|
|
34
35
|
this.config = config;
|
|
35
36
|
this.log = createLogger('validator-ha-signer');
|
|
@@ -40,9 +41,11 @@ import { getBlockNumberFromSigningContext } from './types.js';
|
|
|
40
41
|
if (!config.nodeId || config.nodeId === '') {
|
|
41
42
|
throw new Error('NODE_ID is required for high-availability setups');
|
|
42
43
|
}
|
|
44
|
+
this.rollupAddress = config.l1Contracts.rollupAddress;
|
|
43
45
|
this.slashingProtection = new SlashingProtectionService(db, config);
|
|
44
46
|
this.log.info('Validator HA Signer initialized with slashing protection', {
|
|
45
|
-
nodeId: config.nodeId
|
|
47
|
+
nodeId: config.nodeId,
|
|
48
|
+
rollupAddress: this.rollupAddress.toString()
|
|
46
49
|
});
|
|
47
50
|
}
|
|
48
51
|
/**
|
|
@@ -65,6 +68,7 @@ import { getBlockNumberFromSigningContext } from './types.js';
|
|
|
65
68
|
let dutyIdentifier;
|
|
66
69
|
if (context.dutyType === DutyType.BLOCK_PROPOSAL) {
|
|
67
70
|
dutyIdentifier = {
|
|
71
|
+
rollupAddress: this.rollupAddress,
|
|
68
72
|
validatorAddress,
|
|
69
73
|
slot: context.slot,
|
|
70
74
|
blockIndexWithinCheckpoint: context.blockIndexWithinCheckpoint,
|
|
@@ -72,6 +76,7 @@ import { getBlockNumberFromSigningContext } from './types.js';
|
|
|
72
76
|
};
|
|
73
77
|
} else {
|
|
74
78
|
dutyIdentifier = {
|
|
79
|
+
rollupAddress: this.rollupAddress,
|
|
75
80
|
validatorAddress,
|
|
76
81
|
slot: context.slot,
|
|
77
82
|
dutyType: context.dutyType
|
|
@@ -114,8 +119,8 @@ import { getBlockNumberFromSigningContext } from './types.js';
|
|
|
114
119
|
/**
|
|
115
120
|
* Start the HA signer background tasks (cleanup of stuck duties).
|
|
116
121
|
* Should be called after construction and before signing operations.
|
|
117
|
-
*/ start() {
|
|
118
|
-
this.slashingProtection.start();
|
|
122
|
+
*/ async start() {
|
|
123
|
+
await this.slashingProtection.start();
|
|
119
124
|
}
|
|
120
125
|
/**
|
|
121
126
|
* Stop the HA signer background tasks and close database connection.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/validator-ha-signer",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.aada20e3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./config": "./dest/config.js",
|
|
@@ -74,7 +74,8 @@
|
|
|
74
74
|
]
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
|
-
"@aztec/
|
|
77
|
+
"@aztec/ethereum": "0.0.1-commit.aada20e3",
|
|
78
|
+
"@aztec/foundation": "0.0.1-commit.aada20e3",
|
|
78
79
|
"node-pg-migrate": "^8.0.4",
|
|
79
80
|
"pg": "^8.11.3",
|
|
80
81
|
"tslib": "^2.4.0",
|
package/src/config.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
1
2
|
import {
|
|
2
3
|
type ConfigMappingsType,
|
|
3
4
|
booleanConfigHelper,
|
|
@@ -6,6 +7,7 @@ import {
|
|
|
6
7
|
numberConfigHelper,
|
|
7
8
|
optionalNumberConfigHelper,
|
|
8
9
|
} from '@aztec/foundation/config';
|
|
10
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
9
11
|
import type { ZodFor } from '@aztec/foundation/schemas';
|
|
10
12
|
|
|
11
13
|
import { z } from 'zod';
|
|
@@ -19,6 +21,8 @@ import { z } from 'zod';
|
|
|
19
21
|
export interface ValidatorHASignerConfig {
|
|
20
22
|
/** Whether HA signing / slashing protection is enabled */
|
|
21
23
|
haSigningEnabled: boolean;
|
|
24
|
+
/** L1 contract addresses (rollup address required) */
|
|
25
|
+
l1Contracts: Pick<L1ContractAddresses, 'rollupAddress'>;
|
|
22
26
|
/** Unique identifier for this node */
|
|
23
27
|
nodeId: string;
|
|
24
28
|
/** How long to wait between polls when a duty is being signed (ms) */
|
|
@@ -27,6 +31,8 @@ export interface ValidatorHASignerConfig {
|
|
|
27
31
|
signingTimeoutMs: number;
|
|
28
32
|
/** Maximum age of a stuck duty in ms (defaults to 2x hardcoded Aztec slot duration if not set) */
|
|
29
33
|
maxStuckDutiesAgeMs?: number;
|
|
34
|
+
/** Optional: clean up old duties after this many hours (disabled if not set) */
|
|
35
|
+
cleanupOldDutiesAfterHours?: number;
|
|
30
36
|
/**
|
|
31
37
|
* PostgreSQL connection string
|
|
32
38
|
* Format: postgresql://user:password@host:port/database
|
|
@@ -51,6 +57,15 @@ export const validatorHASignerConfigMappings: ConfigMappingsType<ValidatorHASign
|
|
|
51
57
|
description: 'Whether HA signing / slashing protection is enabled',
|
|
52
58
|
...booleanConfigHelper(false),
|
|
53
59
|
},
|
|
60
|
+
l1Contracts: {
|
|
61
|
+
description: 'L1 contract addresses (rollup address required)',
|
|
62
|
+
nested: {
|
|
63
|
+
rollupAddress: {
|
|
64
|
+
description: 'The Ethereum address of the rollup contract (must be set programmatically)',
|
|
65
|
+
parseEnv: (val: string) => EthAddress.fromString(val),
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
54
69
|
nodeId: {
|
|
55
70
|
env: 'VALIDATOR_HA_NODE_ID',
|
|
56
71
|
description: 'The unique identifier for this node',
|
|
@@ -71,6 +86,11 @@ export const validatorHASignerConfigMappings: ConfigMappingsType<ValidatorHASign
|
|
|
71
86
|
description: 'The maximum age of a stuck duty in ms (defaults to 2x Aztec slot duration)',
|
|
72
87
|
...optionalNumberConfigHelper(),
|
|
73
88
|
},
|
|
89
|
+
cleanupOldDutiesAfterHours: {
|
|
90
|
+
env: 'VALIDATOR_HA_OLD_DUTIES_MAX_AGE_H',
|
|
91
|
+
description: 'Optional: clean up old duties after this many hours (disabled if not set)',
|
|
92
|
+
...optionalNumberConfigHelper(),
|
|
93
|
+
},
|
|
74
94
|
databaseUrl: {
|
|
75
95
|
env: 'VALIDATOR_HA_DATABASE_URL',
|
|
76
96
|
description:
|
|
@@ -113,10 +133,14 @@ export function getConfigEnvVars(): ValidatorHASignerConfig {
|
|
|
113
133
|
|
|
114
134
|
export const ValidatorHASignerConfigSchema = z.object({
|
|
115
135
|
haSigningEnabled: z.boolean(),
|
|
136
|
+
l1Contracts: z.object({
|
|
137
|
+
rollupAddress: z.instanceof(EthAddress),
|
|
138
|
+
}),
|
|
116
139
|
nodeId: z.string(),
|
|
117
140
|
pollingIntervalMs: z.number().min(0),
|
|
118
141
|
signingTimeoutMs: z.number().min(0),
|
|
119
142
|
maxStuckDutiesAgeMs: z.number().min(0).optional(),
|
|
143
|
+
cleanupOldDutiesAfterHours: z.number().min(0).optional(),
|
|
120
144
|
databaseUrl: z.string().optional(),
|
|
121
145
|
poolMaxCount: z.number().min(0).optional(),
|
|
122
146
|
poolMinCount: z.number().min(0).optional(),
|
package/src/db/postgres.ts
CHANGED
|
@@ -11,6 +11,8 @@ import type { QueryResult, QueryResultRow } from 'pg';
|
|
|
11
11
|
|
|
12
12
|
import type { SlashingProtectionDatabase, TryInsertOrGetResult } from '../types.js';
|
|
13
13
|
import {
|
|
14
|
+
CLEANUP_OLD_DUTIES,
|
|
15
|
+
CLEANUP_OUTDATED_ROLLUP_DUTIES,
|
|
14
16
|
CLEANUP_OWN_STUCK_DUTIES,
|
|
15
17
|
DELETE_DUTY,
|
|
16
18
|
INSERT_OR_GET_DUTY,
|
|
@@ -101,6 +103,7 @@ export class PostgresSlashingProtectionDatabase implements SlashingProtectionDat
|
|
|
101
103
|
const result = await retry<QueryResult<InsertOrGetRow>>(
|
|
102
104
|
async () => {
|
|
103
105
|
const queryResult: QueryResult<InsertOrGetRow> = await this.pool.query(INSERT_OR_GET_DUTY, [
|
|
106
|
+
params.rollupAddress.toString(),
|
|
104
107
|
params.validatorAddress.toString(),
|
|
105
108
|
params.slot.toString(),
|
|
106
109
|
params.blockNumber.toString(),
|
|
@@ -148,6 +151,7 @@ export class PostgresSlashingProtectionDatabase implements SlashingProtectionDat
|
|
|
148
151
|
* @returns true if the update succeeded, false if token didn't match or duty not found
|
|
149
152
|
*/
|
|
150
153
|
async updateDutySigned(
|
|
154
|
+
rollupAddress: EthAddress,
|
|
151
155
|
validatorAddress: EthAddress,
|
|
152
156
|
slot: SlotNumber,
|
|
153
157
|
dutyType: DutyType,
|
|
@@ -157,6 +161,7 @@ export class PostgresSlashingProtectionDatabase implements SlashingProtectionDat
|
|
|
157
161
|
): Promise<boolean> {
|
|
158
162
|
const result = await this.pool.query(UPDATE_DUTY_SIGNED, [
|
|
159
163
|
signature,
|
|
164
|
+
rollupAddress.toString(),
|
|
160
165
|
validatorAddress.toString(),
|
|
161
166
|
slot.toString(),
|
|
162
167
|
dutyType,
|
|
@@ -166,6 +171,7 @@ export class PostgresSlashingProtectionDatabase implements SlashingProtectionDat
|
|
|
166
171
|
|
|
167
172
|
if (result.rowCount === 0) {
|
|
168
173
|
this.log.warn('Failed to update duty to signed status: invalid token or duty not found', {
|
|
174
|
+
rollupAddress: rollupAddress.toString(),
|
|
169
175
|
validatorAddress: validatorAddress.toString(),
|
|
170
176
|
slot: slot.toString(),
|
|
171
177
|
dutyType,
|
|
@@ -184,6 +190,7 @@ export class PostgresSlashingProtectionDatabase implements SlashingProtectionDat
|
|
|
184
190
|
* @returns true if the delete succeeded, false if token didn't match or duty not found
|
|
185
191
|
*/
|
|
186
192
|
async deleteDuty(
|
|
193
|
+
rollupAddress: EthAddress,
|
|
187
194
|
validatorAddress: EthAddress,
|
|
188
195
|
slot: SlotNumber,
|
|
189
196
|
dutyType: DutyType,
|
|
@@ -191,6 +198,7 @@ export class PostgresSlashingProtectionDatabase implements SlashingProtectionDat
|
|
|
191
198
|
blockIndexWithinCheckpoint: number,
|
|
192
199
|
): Promise<boolean> {
|
|
193
200
|
const result = await this.pool.query(DELETE_DUTY, [
|
|
201
|
+
rollupAddress.toString(),
|
|
194
202
|
validatorAddress.toString(),
|
|
195
203
|
slot.toString(),
|
|
196
204
|
dutyType,
|
|
@@ -200,6 +208,7 @@ export class PostgresSlashingProtectionDatabase implements SlashingProtectionDat
|
|
|
200
208
|
|
|
201
209
|
if (result.rowCount === 0) {
|
|
202
210
|
this.log.warn('Failed to delete duty: invalid token or duty not found', {
|
|
211
|
+
rollupAddress: rollupAddress.toString(),
|
|
203
212
|
validatorAddress: validatorAddress.toString(),
|
|
204
213
|
slot: slot.toString(),
|
|
205
214
|
dutyType,
|
|
@@ -215,6 +224,7 @@ export class PostgresSlashingProtectionDatabase implements SlashingProtectionDat
|
|
|
215
224
|
*/
|
|
216
225
|
private rowToRecord(row: DutyRow): ValidatorDutyRecord {
|
|
217
226
|
return {
|
|
227
|
+
rollupAddress: EthAddress.fromString(row.rollup_address),
|
|
218
228
|
validatorAddress: EthAddress.fromString(row.validator_address),
|
|
219
229
|
slot: SlotNumber.fromString(row.slot),
|
|
220
230
|
blockNumber: BlockNumber.fromString(row.block_number),
|
|
@@ -248,4 +258,27 @@ export class PostgresSlashingProtectionDatabase implements SlashingProtectionDat
|
|
|
248
258
|
const result = await this.pool.query(CLEANUP_OWN_STUCK_DUTIES, [nodeId, cutoff]);
|
|
249
259
|
return result.rowCount ?? 0;
|
|
250
260
|
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Cleanup duties with outdated rollup address.
|
|
264
|
+
* Removes all duties where the rollup address doesn't match the current one.
|
|
265
|
+
* Used after a rollup upgrade to clean up duties for the old rollup.
|
|
266
|
+
* @returns the number of duties cleaned up
|
|
267
|
+
*/
|
|
268
|
+
async cleanupOutdatedRollupDuties(currentRollupAddress: EthAddress): Promise<number> {
|
|
269
|
+
const result = await this.pool.query(CLEANUP_OUTDATED_ROLLUP_DUTIES, [currentRollupAddress.toString()]);
|
|
270
|
+
return result.rowCount ?? 0;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Cleanup old signed duties.
|
|
275
|
+
* Removes only signed duties older than the specified age.
|
|
276
|
+
* Does not remove 'signing' duties as they may be in progress.
|
|
277
|
+
* @returns the number of duties cleaned up
|
|
278
|
+
*/
|
|
279
|
+
async cleanupOldDuties(maxAgeMs: number): Promise<number> {
|
|
280
|
+
const cutoff = new Date(Date.now() - maxAgeMs);
|
|
281
|
+
const result = await this.pool.query(CLEANUP_OLD_DUTIES, [cutoff]);
|
|
282
|
+
return result.rowCount ?? 0;
|
|
283
|
+
}
|
|
251
284
|
}
|