@aztec/validator-ha-signer 0.0.1-commit.23b0eb0 → 0.0.1-commit.27d773e65
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/README.md +10 -0
- package/dest/db/postgres.d.ts +15 -1
- package/dest/db/postgres.d.ts.map +1 -1
- package/dest/db/postgres.js +24 -3
- package/dest/db/schema.d.ts +13 -6
- package/dest/db/schema.d.ts.map +1 -1
- package/dest/db/schema.js +14 -5
- package/dest/db/types.d.ts +4 -16
- package/dest/db/types.d.ts.map +1 -1
- package/dest/db/types.js +5 -15
- package/dest/factory.d.ts +2 -2
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +11 -1
- package/dest/metrics.d.ts +51 -0
- package/dest/metrics.d.ts.map +1 -0
- package/dest/metrics.js +103 -0
- package/dest/slashing_protection_service.d.ts +19 -6
- package/dest/slashing_protection_service.d.ts.map +1 -1
- package/dest/slashing_protection_service.js +51 -11
- package/dest/types.d.ts +28 -72
- package/dest/types.d.ts.map +1 -1
- package/dest/types.js +3 -20
- package/dest/validator_ha_signer.d.ts +13 -5
- package/dest/validator_ha_signer.d.ts.map +1 -1
- package/dest/validator_ha_signer.js +18 -6
- package/package.json +7 -5
- package/src/db/postgres.ts +25 -2
- package/src/db/schema.ts +16 -5
- package/src/db/types.ts +5 -15
- package/src/factory.ts +13 -2
- package/src/metrics.ts +138 -0
- package/src/slashing_protection_service.ts +65 -15
- package/src/types.ts +45 -107
- package/src/validator_ha_signer.ts +35 -9
- package/dest/config.d.ts +0 -96
- package/dest/config.d.ts.map +0 -1
- package/dest/config.js +0 -86
- package/src/config.ts +0 -141
package/README.md
CHANGED
|
@@ -178,6 +178,16 @@ All signing operations require a `SigningContext` that includes:
|
|
|
178
178
|
|
|
179
179
|
Note: `AUTH_REQUEST` duties bypass HA protection since signing multiple times is safe for authentication requests.
|
|
180
180
|
|
|
181
|
+
## Important Limitations
|
|
182
|
+
|
|
183
|
+
### Database Isolation Per Rollup Version
|
|
184
|
+
|
|
185
|
+
**You cannot use the same database to provide slashing protection for validator nodes running on different rollup versions** (e.g., current rollup and old rollup simultaneously).
|
|
186
|
+
|
|
187
|
+
When the HA signer performs background cleanup via `cleanupOutdatedRollupDuties()`, it removes all duties where the rollup address doesn't match the current rollup address. If two validators running on different rollup versions share the same database, they will delete each other's duties during cleanup.
|
|
188
|
+
|
|
189
|
+
**Solution**: Use separate databases for validators running on different rollup versions. Each rollup version requires its own isolated slashing protection database.
|
|
190
|
+
|
|
181
191
|
## Development
|
|
182
192
|
|
|
183
193
|
```bash
|
package/dest/db/postgres.d.ts
CHANGED
|
@@ -66,5 +66,19 @@ export declare class PostgresSlashingProtectionDatabase implements SlashingProte
|
|
|
66
66
|
* @returns the number of duties cleaned up
|
|
67
67
|
*/
|
|
68
68
|
cleanupOwnStuckDuties(nodeId: string, maxAgeMs: number): Promise<number>;
|
|
69
|
+
/**
|
|
70
|
+
* Cleanup duties with outdated rollup address.
|
|
71
|
+
* Removes all duties where the rollup address doesn't match the current one.
|
|
72
|
+
* Used after a rollup upgrade to clean up duties for the old rollup.
|
|
73
|
+
* @returns the number of duties cleaned up
|
|
74
|
+
*/
|
|
75
|
+
cleanupOutdatedRollupDuties(currentRollupAddress: EthAddress): Promise<number>;
|
|
76
|
+
/**
|
|
77
|
+
* Cleanup old signed duties.
|
|
78
|
+
* Removes only signed duties older than the specified age.
|
|
79
|
+
* Does not remove 'signing' duties as they may be in progress.
|
|
80
|
+
* @returns the number of duties cleaned up
|
|
81
|
+
*/
|
|
82
|
+
cleanupOldDuties(maxAgeMs: number): Promise<number>;
|
|
69
83
|
}
|
|
70
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
84
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9zdGdyZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYi9wb3N0Z3Jlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE9BQU8sRUFBZSxVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUUxRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFJM0QsT0FBTyxLQUFLLEVBQUUsV0FBVyxFQUFFLGNBQWMsRUFBRSxNQUFNLElBQUksQ0FBQztBQUV0RCxPQUFPLEtBQUssRUFBRSwwQkFBMEIsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQVVwRixPQUFPLEtBQUssRUFBRSxvQkFBb0IsRUFBVyxRQUFRLEVBQXVDLE1BQU0sWUFBWSxDQUFDO0FBRy9HOzs7R0FHRztBQUNILE1BQU0sV0FBVyxhQUFhO0lBQzVCLEtBQUssQ0FBQyxDQUFDLFNBQVMsY0FBYyxHQUFHLEdBQUcsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3RixHQUFHLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0NBQ3RCO0FBRUQ7O0dBRUc7QUFDSCxxQkFBYSxrQ0FBbUMsWUFBVywwQkFBMEI7SUFHdkUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJO0lBRmpDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFTO0lBRTdCLFlBQTZCLElBQUksRUFBRSxhQUFhLEVBRS9DO0lBRUQ7Ozs7O09BS0c7SUFDRyxVQUFVLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQWdDaEM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNHLHNCQUFzQixDQUFDLE1BQU0sRUFBRSxvQkFBb0IsR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FvRHhGO0lBRUQ7Ozs7O09BS0c7SUFDRyxnQkFBZ0IsQ0FDcEIsYUFBYSxFQUFFLFVBQVUsRUFDekIsZ0JBQWdCLEVBQUUsVUFBVSxFQUM1QixJQUFJLEVBQUUsVUFBVSxFQUNoQixRQUFRLEVBQUUsUUFBUSxFQUNsQixTQUFTLEVBQUUsTUFBTSxFQUNqQixTQUFTLEVBQUUsTUFBTSxFQUNqQiwwQkFBMEIsRUFBRSxNQUFNLEdBQ2pDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FzQmxCO0lBRUQ7Ozs7OztPQU1HO0lBQ0csVUFBVSxDQUNkLGFBQWEsRUFBRSxVQUFVLEVBQ3pCLGdCQUFnQixFQUFFLFVBQVUsRUFDNUIsSUFBSSxFQUFFLFVBQVUsRUFDaEIsUUFBUSxFQUFFLFFBQVEsRUFDbEIsU0FBUyxFQUFFLE1BQU0sRUFDakIsMEJBQTBCLEVBQUUsTUFBTSxHQUNqQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBcUJsQjtJQUVEOztPQUVHO0lBQ0gsT0FBTyxDQUFDLFdBQVc7SUFtQm5COztPQUVHO0lBQ0csS0FBSyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FHM0I7SUFFRDs7O09BR0c7SUFDRyxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUc3RTtJQUVEOzs7OztPQUtHO0lBQ0csMkJBQTJCLENBQUMsb0JBQW9CLEVBQUUsVUFBVSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FHbkY7SUFFRDs7Ozs7T0FLRztJQUNHLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUd4RDtDQUNGIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/db/postgres.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAe,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAI3D,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AAEtD,OAAO,KAAK,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/db/postgres.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAe,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAI3D,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AAEtD,OAAO,KAAK,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAUpF,OAAO,KAAK,EAAE,oBAAoB,EAAW,QAAQ,EAAuC,MAAM,YAAY,CAAC;AAG/G;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,CAAC,SAAS,cAAc,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7F,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,kCAAmC,YAAW,0BAA0B;IAGvE,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B,YAA6B,IAAI,EAAE,aAAa,EAE/C;IAED;;;;;OAKG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAgChC;IAED;;;;;;;;OAQG;IACG,sBAAsB,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAoDxF;IAED;;;;;OAKG;IACG,gBAAgB,CACpB,aAAa,EAAE,UAAU,EACzB,gBAAgB,EAAE,UAAU,EAC5B,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,0BAA0B,EAAE,MAAM,GACjC,OAAO,CAAC,OAAO,CAAC,CAsBlB;IAED;;;;;;OAMG;IACG,UAAU,CACd,aAAa,EAAE,UAAU,EACzB,gBAAgB,EAAE,UAAU,EAC5B,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,0BAA0B,EAAE,MAAM,GACjC,OAAO,CAAC,OAAO,CAAC,CAqBlB;IAED;;OAEG;IACH,OAAO,CAAC,WAAW;IAmBnB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3B;IAED;;;OAGG;IACG,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG7E;IAED;;;;;OAKG;IACG,2BAA2B,CAAC,oBAAoB,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAGnF;IAED;;;;;OAKG;IACG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGxD;CACF"}
|
package/dest/db/postgres.js
CHANGED
|
@@ -5,7 +5,7 @@ import { randomBytes } from '@aztec/foundation/crypto/random';
|
|
|
5
5
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
6
6
|
import { createLogger } from '@aztec/foundation/log';
|
|
7
7
|
import { makeBackoff, retry } from '@aztec/foundation/retry';
|
|
8
|
-
import { CLEANUP_OWN_STUCK_DUTIES, DELETE_DUTY, INSERT_OR_GET_DUTY, SCHEMA_VERSION, UPDATE_DUTY_SIGNED } from './schema.js';
|
|
8
|
+
import { CLEANUP_OLD_DUTIES, CLEANUP_OUTDATED_ROLLUP_DUTIES, CLEANUP_OWN_STUCK_DUTIES, DELETE_DUTY, INSERT_OR_GET_DUTY, SCHEMA_VERSION, UPDATE_DUTY_SIGNED } from './schema.js';
|
|
9
9
|
import { getBlockIndexFromDutyIdentifier } from './types.js';
|
|
10
10
|
/**
|
|
11
11
|
* PostgreSQL implementation of the slashing protection database
|
|
@@ -177,10 +177,31 @@ import { getBlockIndexFromDutyIdentifier } from './types.js';
|
|
|
177
177
|
* Cleanup own stuck duties
|
|
178
178
|
* @returns the number of duties cleaned up
|
|
179
179
|
*/ async cleanupOwnStuckDuties(nodeId, maxAgeMs) {
|
|
180
|
-
const cutoff = new Date(Date.now() - maxAgeMs);
|
|
181
180
|
const result = await this.pool.query(CLEANUP_OWN_STUCK_DUTIES, [
|
|
182
181
|
nodeId,
|
|
183
|
-
|
|
182
|
+
maxAgeMs
|
|
183
|
+
]);
|
|
184
|
+
return result.rowCount ?? 0;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Cleanup duties with outdated rollup address.
|
|
188
|
+
* Removes all duties where the rollup address doesn't match the current one.
|
|
189
|
+
* Used after a rollup upgrade to clean up duties for the old rollup.
|
|
190
|
+
* @returns the number of duties cleaned up
|
|
191
|
+
*/ async cleanupOutdatedRollupDuties(currentRollupAddress) {
|
|
192
|
+
const result = await this.pool.query(CLEANUP_OUTDATED_ROLLUP_DUTIES, [
|
|
193
|
+
currentRollupAddress.toString()
|
|
194
|
+
]);
|
|
195
|
+
return result.rowCount ?? 0;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Cleanup old signed duties.
|
|
199
|
+
* Removes only signed duties older than the specified age.
|
|
200
|
+
* Does not remove 'signing' duties as they may be in progress.
|
|
201
|
+
* @returns the number of duties cleaned up
|
|
202
|
+
*/ async cleanupOldDuties(maxAgeMs) {
|
|
203
|
+
const result = await this.pool.query(CLEANUP_OLD_DUTIES, [
|
|
204
|
+
maxAgeMs
|
|
184
205
|
]);
|
|
185
206
|
return result.rowCount ?? 0;
|
|
186
207
|
}
|
package/dest/db/schema.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export declare const SCHEMA_VERSION = 1;
|
|
|
12
12
|
/**
|
|
13
13
|
* SQL to create the validator_duties table
|
|
14
14
|
*/
|
|
15
|
-
export declare const CREATE_VALIDATOR_DUTIES_TABLE = "\nCREATE TABLE IF NOT EXISTS validator_duties (\n rollup_address VARCHAR(42) NOT NULL,\n validator_address VARCHAR(42) NOT NULL,\n slot BIGINT NOT NULL,\n block_number BIGINT NOT NULL,\n block_index_within_checkpoint INTEGER NOT NULL DEFAULT 0,\n duty_type VARCHAR(30) NOT NULL CHECK (duty_type IN ('BLOCK_PROPOSAL', 'CHECKPOINT_PROPOSAL', 'ATTESTATION', 'ATTESTATIONS_AND_SIGNERS', 'GOVERNANCE_VOTE', 'SLASHING_VOTE')),\n status VARCHAR(20) NOT NULL CHECK (status IN ('signing', 'signed'
|
|
15
|
+
export declare const CREATE_VALIDATOR_DUTIES_TABLE = "\nCREATE TABLE IF NOT EXISTS validator_duties (\n rollup_address VARCHAR(42) NOT NULL,\n validator_address VARCHAR(42) NOT NULL,\n slot BIGINT NOT NULL,\n block_number BIGINT NOT NULL,\n block_index_within_checkpoint INTEGER NOT NULL DEFAULT 0,\n duty_type VARCHAR(30) NOT NULL CHECK (duty_type IN ('BLOCK_PROPOSAL', 'CHECKPOINT_PROPOSAL', 'ATTESTATION', 'ATTESTATIONS_AND_SIGNERS', 'GOVERNANCE_VOTE', 'SLASHING_VOTE')),\n status VARCHAR(20) NOT NULL CHECK (status IN ('signing', 'signed')),\n message_hash VARCHAR(66) NOT NULL,\n signature VARCHAR(132),\n node_id VARCHAR(255) NOT NULL,\n lock_token VARCHAR(64) NOT NULL,\n started_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n completed_at TIMESTAMP,\n error_message TEXT,\n\n PRIMARY KEY (rollup_address, validator_address, slot, duty_type, block_index_within_checkpoint),\n CHECK (completed_at IS NULL OR completed_at >= started_at)\n);\n";
|
|
16
16
|
/**
|
|
17
17
|
* SQL to create index on status and started_at for cleanup queries
|
|
18
18
|
*/
|
|
@@ -32,7 +32,7 @@ export declare const INSERT_SCHEMA_VERSION = "\nINSERT INTO schema_version (vers
|
|
|
32
32
|
/**
|
|
33
33
|
* Complete schema setup - all statements in order
|
|
34
34
|
*/
|
|
35
|
-
export declare const SCHEMA_SETUP: readonly ["\nCREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER PRIMARY KEY,\n applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n);\n", "\nCREATE TABLE IF NOT EXISTS validator_duties (\n rollup_address VARCHAR(42) NOT NULL,\n validator_address VARCHAR(42) NOT NULL,\n slot BIGINT NOT NULL,\n block_number BIGINT NOT NULL,\n block_index_within_checkpoint INTEGER NOT NULL DEFAULT 0,\n duty_type VARCHAR(30) NOT NULL CHECK (duty_type IN ('BLOCK_PROPOSAL', 'CHECKPOINT_PROPOSAL', 'ATTESTATION', 'ATTESTATIONS_AND_SIGNERS', 'GOVERNANCE_VOTE', 'SLASHING_VOTE')),\n status VARCHAR(20) NOT NULL CHECK (status IN ('signing', 'signed'
|
|
35
|
+
export declare const SCHEMA_SETUP: readonly ["\nCREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER PRIMARY KEY,\n applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n);\n", "\nCREATE TABLE IF NOT EXISTS validator_duties (\n rollup_address VARCHAR(42) NOT NULL,\n validator_address VARCHAR(42) NOT NULL,\n slot BIGINT NOT NULL,\n block_number BIGINT NOT NULL,\n block_index_within_checkpoint INTEGER NOT NULL DEFAULT 0,\n duty_type VARCHAR(30) NOT NULL CHECK (duty_type IN ('BLOCK_PROPOSAL', 'CHECKPOINT_PROPOSAL', 'ATTESTATION', 'ATTESTATIONS_AND_SIGNERS', 'GOVERNANCE_VOTE', 'SLASHING_VOTE')),\n status VARCHAR(20) NOT NULL CHECK (status IN ('signing', 'signed')),\n message_hash VARCHAR(66) NOT NULL,\n signature VARCHAR(132),\n node_id VARCHAR(255) NOT NULL,\n lock_token VARCHAR(64) NOT NULL,\n started_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n completed_at TIMESTAMP,\n error_message TEXT,\n\n PRIMARY KEY (rollup_address, validator_address, slot, duty_type, block_index_within_checkpoint),\n CHECK (completed_at IS NULL OR completed_at >= started_at)\n);\n", "\nCREATE INDEX IF NOT EXISTS idx_validator_duties_status\nON validator_duties(status, started_at);\n", "\nCREATE INDEX IF NOT EXISTS idx_validator_duties_node\nON validator_duties(node_id, started_at);\n"];
|
|
36
36
|
/**
|
|
37
37
|
* Query to get current schema version
|
|
38
38
|
*/
|
|
@@ -65,14 +65,21 @@ export declare const DELETE_DUTY = "\nDELETE FROM validator_duties\nWHERE rollup
|
|
|
65
65
|
export declare const CLEANUP_OLD_SIGNED_DUTIES = "\nDELETE FROM validator_duties\nWHERE status = 'signed'\n AND completed_at < $1;\n";
|
|
66
66
|
/**
|
|
67
67
|
* Query to clean up old duties (for maintenance)
|
|
68
|
-
* Removes duties older than a specified
|
|
68
|
+
* Removes SIGNED duties older than a specified age (in milliseconds)
|
|
69
69
|
*/
|
|
70
|
-
export declare const CLEANUP_OLD_DUTIES = "\nDELETE FROM validator_duties\nWHERE status
|
|
70
|
+
export declare const CLEANUP_OLD_DUTIES = "\nDELETE FROM validator_duties\nWHERE status = 'signed'\n AND started_at < CURRENT_TIMESTAMP - ($1 || ' milliseconds')::INTERVAL;\n";
|
|
71
71
|
/**
|
|
72
72
|
* Query to cleanup own stuck duties
|
|
73
73
|
* Removes duties in 'signing' status for a specific node that are older than maxAgeMs
|
|
74
|
+
* Uses DB's CURRENT_TIMESTAMP to avoid clock skew issues between nodes
|
|
74
75
|
*/
|
|
75
|
-
export declare const CLEANUP_OWN_STUCK_DUTIES = "\nDELETE FROM validator_duties\nWHERE node_id = $1\n AND status = 'signing'\n AND started_at < $2;\n";
|
|
76
|
+
export declare const CLEANUP_OWN_STUCK_DUTIES = "\nDELETE FROM validator_duties\nWHERE node_id = $1\n AND status = 'signing'\n AND started_at < CURRENT_TIMESTAMP - ($2 || ' milliseconds')::INTERVAL;\n";
|
|
77
|
+
/**
|
|
78
|
+
* Query to cleanup duties with outdated rollup address
|
|
79
|
+
* Removes all duties where the rollup address doesn't match the current one
|
|
80
|
+
* Used after a rollup upgrade to clean up duties for the old rollup
|
|
81
|
+
*/
|
|
82
|
+
export declare const CLEANUP_OUTDATED_ROLLUP_DUTIES = "\nDELETE FROM validator_duties\nWHERE rollup_address != $1;\n";
|
|
76
83
|
/**
|
|
77
84
|
* SQL to drop the validator_duties table
|
|
78
85
|
*/
|
|
@@ -86,4 +93,4 @@ export declare const DROP_SCHEMA_VERSION_TABLE = "DROP TABLE IF EXISTS schema_ve
|
|
|
86
93
|
* Returns duties in 'signing' status that have been stuck for too long
|
|
87
94
|
*/
|
|
88
95
|
export declare const GET_STUCK_DUTIES = "\nSELECT\n rollup_address,\n validator_address,\n slot,\n block_number,\n block_index_within_checkpoint,\n duty_type,\n status,\n message_hash,\n node_id,\n started_at,\n EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - started_at)) as age_seconds\nFROM validator_duties\nWHERE status = 'signing'\n AND started_at < $1\nORDER BY started_at ASC;\n";
|
|
89
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
96
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGIvc2NoZW1hLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVIOztHQUVHO0FBQ0gsZUFBTyxNQUFNLGNBQWMsSUFBSSxDQUFDO0FBRWhDOztHQUVHO0FBQ0gsZUFBTyxNQUFNLDZCQUE2QixzNUJBb0J6QyxDQUFDO0FBRUY7O0dBRUc7QUFDSCxlQUFPLE1BQU0sbUJBQW1CLHlHQUcvQixDQUFDO0FBRUY7O0dBRUc7QUFDSCxlQUFPLE1BQU0saUJBQWlCLHdHQUc3QixDQUFDO0FBRUY7O0dBRUc7QUFDSCxlQUFPLE1BQU0sMkJBQTJCLG1KQUt2QyxDQUFDO0FBRUY7O0dBRUc7QUFDSCxlQUFPLE1BQU0scUJBQXFCLDZGQUlqQyxDQUFDO0FBRUY7O0dBRUc7QUFDSCxlQUFPLE1BQU0sWUFBWSxpd0NBS2YsQ0FBQztBQUVYOztHQUVHO0FBQ0gsZUFBTyxNQUFNLGtCQUFrQiwwRUFFOUIsQ0FBQztBQUVGOzs7Ozs7Ozs7O0dBVUc7QUFDSCxlQUFPLE1BQU0sa0JBQWtCLDZ1Q0EwRDlCLENBQUM7QUFFRjs7R0FFRztBQUNILGVBQU8sTUFBTSxrQkFBa0IsK1NBWTlCLENBQUM7QUFFRjs7O0dBR0c7QUFDSCxlQUFPLE1BQU0sV0FBVyxpT0FTdkIsQ0FBQztBQUVGOzs7R0FHRztBQUNILGVBQU8sTUFBTSx5QkFBeUIsd0ZBSXJDLENBQUM7QUFFRjs7O0dBR0c7QUFDSCxlQUFPLE1BQU0sa0JBQWtCLHlJQUk5QixDQUFDO0FBRUY7Ozs7R0FJRztBQUNILGVBQU8sTUFBTSx3QkFBd0IsOEpBS3BDLENBQUM7QUFFRjs7OztHQUlHO0FBQ0gsZUFBTyxNQUFNLDhCQUE4QixrRUFHMUMsQ0FBQztBQUVGOztHQUVHO0FBQ0gsZUFBTyxNQUFNLDJCQUEyQiwyQ0FBMkMsQ0FBQztBQUVwRjs7R0FFRztBQUNILGVBQU8sTUFBTSx5QkFBeUIseUNBQXlDLENBQUM7QUFFaEY7OztHQUdHO0FBQ0gsZUFBTyxNQUFNLGdCQUFnQixrV0FpQjVCLENBQUMifQ==
|
package/dest/db/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC;;GAEG;AACH,eAAO,MAAM,6BAA6B,
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC;;GAEG;AACH,eAAO,MAAM,6BAA6B,s5BAoBzC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,yGAG/B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,wGAG7B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,2BAA2B,mJAKvC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,6FAIjC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,iwCAKf,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,kBAAkB,0EAE9B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,6uCA0D9B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,+SAY9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,iOASvB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,wFAIrC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,yIAI9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,8JAKpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,kEAG1C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,2BAA2B,2CAA2C,CAAC;AAEpF;;GAEG;AACH,eAAO,MAAM,yBAAyB,yCAAyC,CAAC;AAEhF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,kWAiB5B,CAAC"}
|
package/dest/db/schema.js
CHANGED
|
@@ -17,7 +17,7 @@ CREATE TABLE IF NOT EXISTS validator_duties (
|
|
|
17
17
|
block_number BIGINT NOT NULL,
|
|
18
18
|
block_index_within_checkpoint INTEGER NOT NULL DEFAULT 0,
|
|
19
19
|
duty_type VARCHAR(30) NOT NULL CHECK (duty_type IN ('BLOCK_PROPOSAL', 'CHECKPOINT_PROPOSAL', 'ATTESTATION', 'ATTESTATIONS_AND_SIGNERS', 'GOVERNANCE_VOTE', 'SLASHING_VOTE')),
|
|
20
|
-
status VARCHAR(20) NOT NULL CHECK (status IN ('signing', 'signed'
|
|
20
|
+
status VARCHAR(20) NOT NULL CHECK (status IN ('signing', 'signed')),
|
|
21
21
|
message_hash VARCHAR(66) NOT NULL,
|
|
22
22
|
signature VARCHAR(132),
|
|
23
23
|
node_id VARCHAR(255) NOT NULL,
|
|
@@ -177,20 +177,29 @@ WHERE status = 'signed'
|
|
|
177
177
|
`;
|
|
178
178
|
/**
|
|
179
179
|
* Query to clean up old duties (for maintenance)
|
|
180
|
-
* Removes duties older than a specified
|
|
180
|
+
* Removes SIGNED duties older than a specified age (in milliseconds)
|
|
181
181
|
*/ export const CLEANUP_OLD_DUTIES = `
|
|
182
182
|
DELETE FROM validator_duties
|
|
183
|
-
WHERE status
|
|
184
|
-
AND started_at < $1;
|
|
183
|
+
WHERE status = 'signed'
|
|
184
|
+
AND started_at < CURRENT_TIMESTAMP - ($1 || ' milliseconds')::INTERVAL;
|
|
185
185
|
`;
|
|
186
186
|
/**
|
|
187
187
|
* Query to cleanup own stuck duties
|
|
188
188
|
* Removes duties in 'signing' status for a specific node that are older than maxAgeMs
|
|
189
|
+
* Uses DB's CURRENT_TIMESTAMP to avoid clock skew issues between nodes
|
|
189
190
|
*/ export const CLEANUP_OWN_STUCK_DUTIES = `
|
|
190
191
|
DELETE FROM validator_duties
|
|
191
192
|
WHERE node_id = $1
|
|
192
193
|
AND status = 'signing'
|
|
193
|
-
AND started_at < $2;
|
|
194
|
+
AND started_at < CURRENT_TIMESTAMP - ($2 || ' milliseconds')::INTERVAL;
|
|
195
|
+
`;
|
|
196
|
+
/**
|
|
197
|
+
* Query to cleanup duties with outdated rollup address
|
|
198
|
+
* Removes all duties where the rollup address doesn't match the current one
|
|
199
|
+
* Used after a rollup upgrade to clean up duties for the old rollup
|
|
200
|
+
*/ export const CLEANUP_OUTDATED_ROLLUP_DUTIES = `
|
|
201
|
+
DELETE FROM validator_duties
|
|
202
|
+
WHERE rollup_address != $1;
|
|
194
203
|
`;
|
|
195
204
|
/**
|
|
196
205
|
* SQL to drop the validator_duties table
|
package/dest/db/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BlockNumber, CheckpointNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import type { 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
|
*/
|
|
@@ -26,19 +27,6 @@ export interface DutyRow {
|
|
|
26
27
|
export interface InsertOrGetRow extends DutyRow {
|
|
27
28
|
is_new: boolean;
|
|
28
29
|
}
|
|
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
30
|
/**
|
|
43
31
|
* Status of a duty in the database
|
|
44
32
|
*/
|
|
@@ -46,6 +34,7 @@ export declare enum DutyStatus {
|
|
|
46
34
|
SIGNING = "signing",
|
|
47
35
|
SIGNED = "signed"
|
|
48
36
|
}
|
|
37
|
+
export { DutyType };
|
|
49
38
|
/**
|
|
50
39
|
* Record of a validator duty in the database
|
|
51
40
|
*/
|
|
@@ -76,7 +65,7 @@ export interface ValidatorDutyRecord {
|
|
|
76
65
|
startedAt: Date;
|
|
77
66
|
/** When the duty signing was completed (success or failure) */
|
|
78
67
|
completedAt?: Date;
|
|
79
|
-
/** Error message
|
|
68
|
+
/** Error message (currently unused) */
|
|
80
69
|
errorMessage?: string;
|
|
81
70
|
}
|
|
82
71
|
/**
|
|
@@ -162,5 +151,4 @@ interface DeleteDutyExtra {
|
|
|
162
151
|
* Uses intersection with DutyIdentifier to preserve the discriminated union.
|
|
163
152
|
*/
|
|
164
153
|
export type DeleteDutyParams = DutyIdentifier & DeleteDutyExtra;
|
|
165
|
-
|
|
166
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYi90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUscUJBQXFCLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDeEgsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFakU7O0dBRUc7QUFDSCxNQUFNLFdBQVcsT0FBTztJQUN0QixjQUFjLEVBQUUsTUFBTSxDQUFDO0lBQ3ZCLGlCQUFpQixFQUFFLE1BQU0sQ0FBQztJQUMxQixJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ2IsWUFBWSxFQUFFLE1BQU0sQ0FBQztJQUNyQiw2QkFBNkIsRUFBRSxNQUFNLENBQUM7SUFDdEMsU0FBUyxFQUFFLFFBQVEsQ0FBQztJQUNwQixNQUFNLEVBQUUsVUFBVSxDQUFDO0lBQ25CLFlBQVksRUFBRSxNQUFNLENBQUM7SUFDckIsU0FBUyxFQUFFLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDekIsT0FBTyxFQUFFLE1BQU0sQ0FBQztJQUNoQixVQUFVLEVBQUUsTUFBTSxDQUFDO0lBQ25CLFVBQVUsRUFBRSxJQUFJLENBQUM7SUFDakIsWUFBWSxFQUFFLElBQUksR0FBRyxJQUFJLENBQUM7SUFDMUIsYUFBYSxFQUFFLE1BQU0sR0FBRyxJQUFJLENBQUM7Q0FDOUI7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyxjQUFlLFNBQVEsT0FBTztJQUM3QyxNQUFNLEVBQUUsT0FBTyxDQUFDO0NBQ2pCO0FBRUQ7O0dBRUc7QUFDSCxvQkFBWSxRQUFRO0lBQ2xCLGNBQWMsbUJBQW1CO0lBQ2pDLG1CQUFtQix3QkFBd0I7SUFDM0MsV0FBVyxnQkFBZ0I7SUFDM0Isd0JBQXdCLDZCQUE2QjtJQUNyRCxlQUFlLG9CQUFvQjtJQUNuQyxhQUFhLGtCQUFrQjtJQUMvQixZQUFZLGlCQUFpQjtJQUM3QixHQUFHLFFBQVE7Q0FDWjtBQUVEOztHQUVHO0FBQ0gsb0JBQVksVUFBVTtJQUNwQixPQUFPLFlBQVk7SUFDbkIsTUFBTSxXQUFXO0NBQ2xCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsbUJBQW1CO0lBQ2xDLDhDQUE4QztJQUM5QyxhQUFhLEVBQUUsVUFBVSxDQUFDO0lBQzFCLHdDQUF3QztJQUN4QyxnQkFBZ0IsRUFBRSxVQUFVLENBQUM7SUFDN0IsZ0NBQWdDO0lBQ2hDLElBQUksRUFBRSxVQUFVLENBQUM7SUFDakIsaUNBQWlDO0lBQ2pDLFdBQVcsRUFBRSxXQUFXLENBQUM7SUFDekIsOEZBQThGO0lBQzlGLDBCQUEwQixFQUFFLE1BQU0sQ0FBQztJQUNuQyxtQ0FBbUM7SUFDbkMsUUFBUSxFQUFFLFFBQVEsQ0FBQztJQUNuQixpQ0FBaUM7SUFDakMsTUFBTSxFQUFFLFVBQVUsQ0FBQztJQUNuQiw0Q0FBNEM7SUFDNUMsV0FBVyxFQUFFLE1BQU0sQ0FBQztJQUNwQix5REFBeUQ7SUFDekQsU0FBUyxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ25CLDREQUE0RDtJQUM1RCxNQUFNLEVBQUUsTUFBTSxDQUFDO0lBQ2YsNERBQTREO0lBQzVELFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsd0NBQXdDO0lBQ3hDLFNBQVMsRUFBRSxJQUFJLENBQUM7SUFDaEIsK0RBQStEO0lBQy9ELFdBQVcsQ0FBQyxFQUFFLElBQUksQ0FBQztJQUNuQiwwQ0FBMEM7SUFDMUMsWUFBWSxDQUFDLEVBQUUsTUFBTSxDQUFDO0NBQ3ZCO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxXQUFXLDJCQUEyQjtJQUMxQyxhQUFhLEVBQUUsVUFBVSxDQUFDO0lBQzFCLGdCQUFnQixFQUFFLFVBQVUsQ0FBQztJQUM3QixJQUFJLEVBQUUsVUFBVSxDQUFDO0lBQ2pCLGdGQUFnRjtJQUNoRiwwQkFBMEIsRUFBRSxxQkFBcUIsQ0FBQztJQUNsRCxRQUFRLEVBQUUsUUFBUSxDQUFDLGNBQWMsQ0FBQztDQUNuQztBQUVEOzs7R0FHRztBQUNILE1BQU0sV0FBVyxtQkFBbUI7SUFDbEMsYUFBYSxFQUFFLFVBQVUsQ0FBQztJQUMxQixnQkFBZ0IsRUFBRSxVQUFVLENBQUM7SUFDN0IsSUFBSSxFQUFFLFVBQVUsQ0FBQztJQUNqQixRQUFRLEVBQ0osUUFBUSxDQUFDLG1CQUFtQixHQUM1QixRQUFRLENBQUMsV0FBVyxHQUNwQixRQUFRLENBQUMsd0JBQXdCLEdBQ2pDLFFBQVEsQ0FBQyxlQUFlLEdBQ3hCLFFBQVEsQ0FBQyxhQUFhLEdBQ3RCLFFBQVEsQ0FBQyxZQUFZLEdBQ3JCLFFBQVEsQ0FBQyxHQUFHLENBQUM7Q0FDbEI7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sTUFBTSxjQUFjLEdBQUcsMkJBQTJCLEdBQUcsbUJBQW1CLENBQUM7QUFFL0U7Ozs7OztHQU1HO0FBQ0gsd0JBQWdCLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxHQUFHLFNBQVMsR0FBRyxNQUFNLENBYzlHO0FBRUQ7Ozs7R0FJRztBQUNILHdCQUFnQiwrQkFBK0IsQ0FBQyxJQUFJLEVBQUUsY0FBYyxHQUFHLE1BQU0sQ0FLNUU7QUFFRDs7R0FFRztBQUNILFVBQVUsbUJBQW1CO0lBQzNCLGlDQUFpQztJQUNqQyxXQUFXLEVBQUUsV0FBVyxHQUFHLGdCQUFnQixDQUFDO0lBQzVDLDRDQUE0QztJQUM1QyxXQUFXLEVBQUUsTUFBTSxDQUFDO0lBQ3BCLHFEQUFxRDtJQUNyRCxNQUFNLEVBQUUsTUFBTSxDQUFDO0NBQ2hCO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxNQUFNLG9CQUFvQixHQUFHLGNBQWMsR0FBRyxtQkFBbUIsQ0FBQztBQUV4RTs7R0FFRztBQUNILFVBQVUsa0JBQWtCO0lBQzFCLFNBQVMsRUFBRSxTQUFTLENBQUM7SUFDckIsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUNmLFNBQVMsRUFBRSxNQUFNLENBQUM7Q0FDbkI7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLE1BQU0sbUJBQW1CLEdBQUcsY0FBYyxHQUFHLGtCQUFrQixDQUFDO0FBRXRFOztHQUVHO0FBQ0gsVUFBVSxlQUFlO0lBQ3ZCLFNBQVMsRUFBRSxNQUFNLENBQUM7Q0FDbkI7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLE1BQU0sZ0JBQWdCLEdBQUcsY0FBYyxHQUFHLGVBQWUsQ0FBQyJ9
|
|
154
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYi90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUscUJBQXFCLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDeEgsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDakUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRXBEOztHQUVHO0FBQ0gsTUFBTSxXQUFXLE9BQU87SUFDdEIsY0FBYyxFQUFFLE1BQU0sQ0FBQztJQUN2QixpQkFBaUIsRUFBRSxNQUFNLENBQUM7SUFDMUIsSUFBSSxFQUFFLE1BQU0sQ0FBQztJQUNiLFlBQVksRUFBRSxNQUFNLENBQUM7SUFDckIsNkJBQTZCLEVBQUUsTUFBTSxDQUFDO0lBQ3RDLFNBQVMsRUFBRSxRQUFRLENBQUM7SUFDcEIsTUFBTSxFQUFFLFVBQVUsQ0FBQztJQUNuQixZQUFZLEVBQUUsTUFBTSxDQUFDO0lBQ3JCLFNBQVMsRUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBQ3pCLE9BQU8sRUFBRSxNQUFNLENBQUM7SUFDaEIsVUFBVSxFQUFFLE1BQU0sQ0FBQztJQUNuQixVQUFVLEVBQUUsSUFBSSxDQUFDO0lBQ2pCLFlBQVksRUFBRSxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQzFCLGFBQWEsRUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDO0NBQzlCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsY0FBZSxTQUFRLE9BQU87SUFDN0MsTUFBTSxFQUFFLE9BQU8sQ0FBQztDQUNqQjtBQUVEOztHQUVHO0FBQ0gsb0JBQVksVUFBVTtJQUNwQixPQUFPLFlBQVk7SUFDbkIsTUFBTSxXQUFXO0NBQ2xC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
|
package/dest/db/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/db/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACxH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;
|
|
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,4 @@
|
|
|
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 { DutyType } from '@aztec/stdlib/ha-signing';
|
|
14
2
|
/**
|
|
15
3
|
* Status of a duty in the database
|
|
16
4
|
*/ export var DutyStatus = /*#__PURE__*/ function(DutyStatus) {
|
|
@@ -18,6 +6,8 @@
|
|
|
18
6
|
DutyStatus["SIGNED"] = "signed";
|
|
19
7
|
return DutyStatus;
|
|
20
8
|
}({});
|
|
9
|
+
// Re-export DutyType from stdlib
|
|
10
|
+
export { DutyType };
|
|
21
11
|
/**
|
|
22
12
|
* Validates and normalizes the block index for a duty.
|
|
23
13
|
* - BLOCK_PROPOSAL: validates blockIndexWithinCheckpoint is provided and >= 0
|
|
@@ -25,7 +15,7 @@
|
|
|
25
15
|
*
|
|
26
16
|
* @throws Error if BLOCK_PROPOSAL is missing blockIndexWithinCheckpoint or has invalid value
|
|
27
17
|
*/ export function normalizeBlockIndex(dutyType, blockIndexWithinCheckpoint) {
|
|
28
|
-
if (dutyType ===
|
|
18
|
+
if (dutyType === DutyType.BLOCK_PROPOSAL) {
|
|
29
19
|
if (blockIndexWithinCheckpoint === undefined) {
|
|
30
20
|
throw new Error('BLOCK_PROPOSAL duties require blockIndexWithinCheckpoint to be specified');
|
|
31
21
|
}
|
|
@@ -42,7 +32,7 @@
|
|
|
42
32
|
* - BLOCK_PROPOSAL: returns the blockIndexWithinCheckpoint
|
|
43
33
|
* - Other duty types: returns -1
|
|
44
34
|
*/ export function getBlockIndexFromDutyIdentifier(duty) {
|
|
45
|
-
if (duty.dutyType ===
|
|
35
|
+
if (duty.dutyType === DutyType.BLOCK_PROPOSAL) {
|
|
46
36
|
return duty.blockIndexWithinCheckpoint;
|
|
47
37
|
}
|
|
48
38
|
return -1;
|
package/dest/factory.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ValidatorHASignerConfig } from '
|
|
1
|
+
import type { ValidatorHASignerConfig } from '@aztec/stdlib/ha-signing';
|
|
2
2
|
import type { CreateHASignerDeps, SlashingProtectionDatabase } from './types.js';
|
|
3
3
|
import { ValidatorHASigner } from './validator_ha_signer.js';
|
|
4
4
|
/**
|
|
@@ -39,4 +39,4 @@ export declare function createHASigner(config: ValidatorHASignerConfig, deps?: C
|
|
|
39
39
|
signer: ValidatorHASigner;
|
|
40
40
|
db: SlashingProtectionDatabase;
|
|
41
41
|
}>;
|
|
42
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
42
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxLQUFLLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQU94RSxPQUFPLEtBQUssRUFBRSxrQkFBa0IsRUFBRSwwQkFBMEIsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUNqRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUU3RDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUNHO0FBQ0gsd0JBQXNCLGNBQWMsQ0FDbEMsTUFBTSxFQUFFLHVCQUF1QixFQUMvQixJQUFJLENBQUMsRUFBRSxrQkFBa0IsR0FDeEIsT0FBTyxDQUFDO0lBQ1QsTUFBTSxFQUFFLGlCQUFpQixDQUFDO0lBQzFCLEVBQUUsRUFBRSwwQkFBMEIsQ0FBQztDQUNoQyxDQUFDLENBc0NEIn0=
|
package/dest/factory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAOxE,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,CAsCD"}
|
package/dest/factory.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Factory functions for creating validator HA signers
|
|
3
|
-
*/ import {
|
|
3
|
+
*/ import { DateProvider } from '@aztec/foundation/timer';
|
|
4
|
+
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
5
|
+
import { Pool } from 'pg';
|
|
4
6
|
import { PostgresSlashingProtectionDatabase } from './db/postgres.js';
|
|
7
|
+
import { HASignerMetrics } from './metrics.js';
|
|
5
8
|
import { ValidatorHASigner } from './validator_ha_signer.js';
|
|
6
9
|
/**
|
|
7
10
|
* Create a validator HA signer with PostgreSQL backend
|
|
@@ -41,6 +44,8 @@ import { ValidatorHASigner } from './validator_ha_signer.js';
|
|
|
41
44
|
if (!databaseUrl) {
|
|
42
45
|
throw new Error('databaseUrl is required for createHASigner');
|
|
43
46
|
}
|
|
47
|
+
const telemetryClient = deps?.telemetryClient ?? getTelemetryClient();
|
|
48
|
+
const dateProvider = deps?.dateProvider ?? new DateProvider();
|
|
44
49
|
// Create connection pool (or use provided pool)
|
|
45
50
|
let pool;
|
|
46
51
|
if (!deps?.pool) {
|
|
@@ -58,10 +63,15 @@ import { ValidatorHASigner } from './validator_ha_signer.js';
|
|
|
58
63
|
const db = new PostgresSlashingProtectionDatabase(pool);
|
|
59
64
|
// Verify database schema is initialized and version matches
|
|
60
65
|
await db.initialize();
|
|
66
|
+
// Create metrics
|
|
67
|
+
const metrics = new HASignerMetrics(telemetryClient, signerConfig.nodeId);
|
|
61
68
|
// Create signer
|
|
62
69
|
const signer = new ValidatorHASigner(db, {
|
|
63
70
|
...signerConfig,
|
|
64
71
|
databaseUrl
|
|
72
|
+
}, {
|
|
73
|
+
metrics,
|
|
74
|
+
dateProvider
|
|
65
75
|
});
|
|
66
76
|
return {
|
|
67
77
|
signer,
|
|
@@ -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==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,eAAe,EAGrB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,KAAK,GAAG,iBAAiB,CAAC;AAEhE;;GAEG;AACH,qBAAa,eAAe;IAkBxB,OAAO,CAAC,MAAM;IAhBhB,OAAO,CAAC,eAAe,CAAY;IACnC,OAAO,CAAC,mBAAmB,CAAgB;IAC3C,OAAO,CAAC,sBAAsB,CAAgB;IAC9C,OAAO,CAAC,uBAAuB,CAAgB;IAC/C,OAAO,CAAC,iBAAiB,CAAgB;IAGzC,OAAO,CAAC,iBAAiB,CAAgB;IAGzC,OAAO,CAAC,uBAAuB,CAAgB;IAC/C,OAAO,CAAC,qBAAqB,CAAgB;IAC7C,OAAO,CAAC,gCAAgC,CAAgB;IAExD,YACE,MAAM,EAAE,eAAe,EACf,MAAM,EAAE,MAAM,EACtB,IAAI,SAAoB,EAqBzB;IAED;;;;OAIG;IACI,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAOtE;IAED;;;OAGG;IACI,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAMrD;IAED;;;OAGG;IACI,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAMtD;IAED;;;OAGG;IACI,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAMhD;IAED;;;OAGG;IACI,iBAAiB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAOhD;IAED;;;;OAIG;IACI,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAY7D;CACF"}
|
package/dest/metrics.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Attributes, Metrics, createUpDownCounterWithDefault } from '@aztec/telemetry-client';
|
|
2
|
+
/**
|
|
3
|
+
* Metrics for HA signer tracking signing operations, lock acquisition, and cleanup.
|
|
4
|
+
*/ export class HASignerMetrics {
|
|
5
|
+
nodeId;
|
|
6
|
+
// Signing lifecycle metrics
|
|
7
|
+
signingDuration;
|
|
8
|
+
signingSuccessCount;
|
|
9
|
+
dutyAlreadySignedCount;
|
|
10
|
+
slashingProtectionCount;
|
|
11
|
+
signingErrorCount;
|
|
12
|
+
// Lock acquisition metrics
|
|
13
|
+
lockAcquiredCount;
|
|
14
|
+
// Cleanup metrics
|
|
15
|
+
cleanupStuckDutiesCount;
|
|
16
|
+
cleanupOldDutiesCount;
|
|
17
|
+
cleanupOutdatedRollupDutiesCount;
|
|
18
|
+
constructor(client, nodeId, name = 'HASignerMetrics'){
|
|
19
|
+
this.nodeId = nodeId;
|
|
20
|
+
const meter = client.getMeter(name);
|
|
21
|
+
// Signing lifecycle
|
|
22
|
+
this.signingDuration = meter.createHistogram(Metrics.HA_SIGNER_SIGNING_DURATION);
|
|
23
|
+
this.signingSuccessCount = createUpDownCounterWithDefault(meter, Metrics.HA_SIGNER_SIGNING_SUCCESS_COUNT);
|
|
24
|
+
this.dutyAlreadySignedCount = createUpDownCounterWithDefault(meter, Metrics.HA_SIGNER_DUTY_ALREADY_SIGNED_COUNT);
|
|
25
|
+
this.slashingProtectionCount = createUpDownCounterWithDefault(meter, Metrics.HA_SIGNER_SLASHING_PROTECTION_COUNT);
|
|
26
|
+
this.signingErrorCount = createUpDownCounterWithDefault(meter, Metrics.HA_SIGNER_SIGNING_ERROR_COUNT);
|
|
27
|
+
// Lock acquisition
|
|
28
|
+
this.lockAcquiredCount = createUpDownCounterWithDefault(meter, Metrics.HA_SIGNER_LOCK_ACQUIRED_COUNT);
|
|
29
|
+
// Cleanup
|
|
30
|
+
this.cleanupStuckDutiesCount = createUpDownCounterWithDefault(meter, Metrics.HA_SIGNER_CLEANUP_STUCK_DUTIES_COUNT);
|
|
31
|
+
this.cleanupOldDutiesCount = createUpDownCounterWithDefault(meter, Metrics.HA_SIGNER_CLEANUP_OLD_DUTIES_COUNT);
|
|
32
|
+
this.cleanupOutdatedRollupDutiesCount = createUpDownCounterWithDefault(meter, Metrics.HA_SIGNER_CLEANUP_OUTDATED_ROLLUP_DUTIES_COUNT);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Record a successful signing operation.
|
|
36
|
+
* @param dutyType - The type of duty signed
|
|
37
|
+
* @param durationMs - Duration from start of signWithProtection to completion
|
|
38
|
+
*/ recordSigningSuccess(dutyType, durationMs) {
|
|
39
|
+
const attributes = {
|
|
40
|
+
[Attributes.HA_DUTY_TYPE]: dutyType,
|
|
41
|
+
[Attributes.HA_NODE_ID]: this.nodeId
|
|
42
|
+
};
|
|
43
|
+
this.signingSuccessCount.add(1, attributes);
|
|
44
|
+
this.signingDuration.record(durationMs, attributes);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Record a DutyAlreadySignedError (expected in HA; another node signed first).
|
|
48
|
+
* @param dutyType - The type of duty
|
|
49
|
+
*/ recordDutyAlreadySigned(dutyType) {
|
|
50
|
+
const attributes = {
|
|
51
|
+
[Attributes.HA_DUTY_TYPE]: dutyType,
|
|
52
|
+
[Attributes.HA_NODE_ID]: this.nodeId
|
|
53
|
+
};
|
|
54
|
+
this.dutyAlreadySignedCount.add(1, attributes);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Record a SlashingProtectionError (attempted to sign different data for same duty).
|
|
58
|
+
* @param dutyType - The type of duty
|
|
59
|
+
*/ recordSlashingProtection(dutyType) {
|
|
60
|
+
const attributes = {
|
|
61
|
+
[Attributes.HA_DUTY_TYPE]: dutyType,
|
|
62
|
+
[Attributes.HA_NODE_ID]: this.nodeId
|
|
63
|
+
};
|
|
64
|
+
this.slashingProtectionCount.add(1, attributes);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Record a signing function failure (lock will be deleted for retry).
|
|
68
|
+
* @param dutyType - The type of duty
|
|
69
|
+
*/ recordSigningError(dutyType) {
|
|
70
|
+
const attributes = {
|
|
71
|
+
[Attributes.HA_DUTY_TYPE]: dutyType,
|
|
72
|
+
[Attributes.HA_NODE_ID]: this.nodeId
|
|
73
|
+
};
|
|
74
|
+
this.signingErrorCount.add(1, attributes);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Record lock acquisition.
|
|
78
|
+
* @param acquired - Whether a new lock was acquired (true) or existing record found (false)
|
|
79
|
+
*/ recordLockAcquire(acquired) {
|
|
80
|
+
if (acquired) {
|
|
81
|
+
const attributes = {
|
|
82
|
+
[Attributes.HA_NODE_ID]: this.nodeId
|
|
83
|
+
};
|
|
84
|
+
this.lockAcquiredCount.add(1, attributes);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Record cleanup metrics.
|
|
89
|
+
* @param type - Type of cleanup
|
|
90
|
+
* @param count - Number of duties cleaned up
|
|
91
|
+
*/ recordCleanup(type, count) {
|
|
92
|
+
const attributes = {
|
|
93
|
+
[Attributes.HA_NODE_ID]: this.nodeId
|
|
94
|
+
};
|
|
95
|
+
if (type === 'stuck') {
|
|
96
|
+
this.cleanupStuckDutiesCount.add(count, attributes);
|
|
97
|
+
} else if (type === 'old') {
|
|
98
|
+
this.cleanupOldDutiesCount.add(count, attributes);
|
|
99
|
+
} else if (type === 'outdated_rollup') {
|
|
100
|
+
this.cleanupOutdatedRollupDutiesCount.add(count, attributes);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
import type { DateProvider } from '@aztec/foundation/timer';
|
|
2
|
+
import type { ValidatorHASignerConfig } from '@aztec/stdlib/ha-signing';
|
|
1
3
|
import { type CheckAndRecordParams, type DeleteDutyParams, type RecordSuccessParams } from './db/types.js';
|
|
2
|
-
import type {
|
|
4
|
+
import type { HASignerMetrics } from './metrics.js';
|
|
5
|
+
import type { SlashingProtectionDatabase } from './types.js';
|
|
6
|
+
export interface SlashingProtectionServiceDeps {
|
|
7
|
+
metrics: HASignerMetrics;
|
|
8
|
+
dateProvider: DateProvider;
|
|
9
|
+
}
|
|
3
10
|
/**
|
|
4
11
|
* Slashing Protection Service
|
|
5
12
|
*
|
|
@@ -22,8 +29,11 @@ export declare class SlashingProtectionService {
|
|
|
22
29
|
private readonly pollingIntervalMs;
|
|
23
30
|
private readonly signingTimeoutMs;
|
|
24
31
|
private readonly maxStuckDutiesAgeMs;
|
|
32
|
+
private readonly metrics;
|
|
33
|
+
private readonly dateProvider;
|
|
25
34
|
private cleanupRunningPromise;
|
|
26
|
-
|
|
35
|
+
private lastOldDutiesCleanupAtMs?;
|
|
36
|
+
constructor(db: SlashingProtectionDatabase, config: ValidatorHASignerConfig, deps: SlashingProtectionServiceDeps);
|
|
27
37
|
/**
|
|
28
38
|
* Check if a duty can be performed and acquire the lock if so.
|
|
29
39
|
*
|
|
@@ -33,7 +43,6 @@ export declare class SlashingProtectionService {
|
|
|
33
43
|
* 2. If insert succeeds, we acquired the lock - return the lockToken
|
|
34
44
|
* 3. If a record exists, handle based on status:
|
|
35
45
|
* - SIGNED: Throw appropriate error (already signed or slashing protection)
|
|
36
|
-
* - FAILED: Delete the failed record
|
|
37
46
|
* - SIGNING: Wait and poll until status changes, then handle result
|
|
38
47
|
*
|
|
39
48
|
* @returns The lockToken that must be used for recordSuccess/deleteDuty
|
|
@@ -65,7 +74,11 @@ export declare class SlashingProtectionService {
|
|
|
65
74
|
* Start running tasks.
|
|
66
75
|
* Cleanup runs immediately on start to recover from any previous crashes.
|
|
67
76
|
*/
|
|
68
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Start the background cleanup task.
|
|
79
|
+
* Also performs one-time cleanup of duties with outdated rollup addresses.
|
|
80
|
+
*/
|
|
81
|
+
start(): Promise<void>;
|
|
69
82
|
/**
|
|
70
83
|
* Stop the background cleanup task.
|
|
71
84
|
*/
|
|
@@ -75,6 +88,6 @@ export declare class SlashingProtectionService {
|
|
|
75
88
|
* Should be called after stop() during graceful shutdown.
|
|
76
89
|
*/
|
|
77
90
|
close(): Promise<void>;
|
|
78
|
-
private
|
|
91
|
+
private cleanup;
|
|
79
92
|
}
|
|
80
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
93
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hpbmdfcHJvdGVjdGlvbl9zZXJ2aWNlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2xhc2hpbmdfcHJvdGVjdGlvbl9zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVNBLE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzVELE9BQU8sS0FBSyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFeEUsT0FBTyxFQUNMLEtBQUssb0JBQW9CLEVBQ3pCLEtBQUssZ0JBQWdCLEVBRXJCLEtBQUssbUJBQW1CLEVBRXpCLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNwRCxPQUFPLEtBQUssRUFBRSwwQkFBMEIsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUU3RCxNQUFNLFdBQVcsNkJBQTZCO0lBQzVDLE9BQU8sRUFBRSxlQUFlLENBQUM7SUFDekIsWUFBWSxFQUFFLFlBQVksQ0FBQztDQUM1QjtBQUVEOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gscUJBQWEseUJBQXlCO0lBYWxDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRTtJQUNuQixPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU07SUFiekIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQVM7SUFDN0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBUztJQUMzQyxPQUFPLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFTO0lBQzFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQVM7SUFFN0MsT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQWtCO0lBQzFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFlO0lBRTVDLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBaUI7SUFDOUMsT0FBTyxDQUFDLHdCQUF3QixDQUFDLENBQVM7SUFFMUMsWUFDbUIsRUFBRSxFQUFFLDBCQUEwQixFQUM5QixNQUFNLEVBQUUsdUJBQXVCLEVBQ2hELElBQUksRUFBRSw2QkFBNkIsRUFXcEM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7T0FjRztJQUNHLGNBQWMsQ0FBQyxNQUFNLEVBQUUsb0JBQW9CLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQXFFbEU7SUFFRDs7Ozs7O09BTUc7SUFDRyxhQUFhLENBQUMsTUFBTSxFQUFFLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0EyQmpFO0lBRUQ7Ozs7OztPQU1HO0lBQ0csVUFBVSxDQUFDLE1BQU0sRUFBRSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBd0IzRDtJQUVEOztPQUVHO0lBQ0gsSUFBSSxNQUFNLElBQUksTUFBTSxDQUVuQjtJQUVEOzs7T0FHRztJQUNIOzs7T0FHRztJQUNHLEtBQUssa0JBWVY7SUFFRDs7T0FFRztJQUNHLElBQUksa0JBR1Q7SUFFRDs7O09BR0c7SUFDRyxLQUFLLGtCQUdWO1lBTWEsT0FBTztDQStCdEIifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slashing_protection_service.d.ts","sourceRoot":"","sources":["../src/slashing_protection_service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"slashing_protection_service.d.ts","sourceRoot":"","sources":["../src/slashing_protection_service.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAExE,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EAErB,KAAK,mBAAmB,EAEzB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAE7D,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,eAAe,CAAC;IACzB,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,yBAAyB;IAalC,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAbzB,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,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAE5C,OAAO,CAAC,qBAAqB,CAAiB;IAC9C,OAAO,CAAC,wBAAwB,CAAC,CAAS;IAE1C,YACmB,EAAE,EAAE,0BAA0B,EAC9B,MAAM,EAAE,uBAAuB,EAChD,IAAI,EAAE,6BAA6B,EAWpC;IAED;;;;;;;;;;;;;;OAcG;IACG,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqElE;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,kBAYV;IAED;;OAEG;IACG,IAAI,kBAGT;IAED;;;OAGG;IACG,KAAK,kBAGV;YAMa,OAAO;CA+BtB"}
|