@aztec/validator-ha-signer 0.0.1-commit.b2a5d0dd1 → 0.0.1-commit.b3d3157a
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/db/lmdb.d.ts +5 -1
- package/dest/db/lmdb.d.ts.map +1 -1
- package/dest/db/lmdb.js +35 -1
- package/dest/factory.d.ts +2 -2
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +5 -2
- package/dest/slashing_protection_service.js +2 -2
- package/dest/validator_ha_signer.js +1 -1
- package/package.json +7 -7
- package/src/db/lmdb.ts +44 -1
- package/src/factory.ts +22 -7
- package/src/slashing_protection_service.ts +2 -2
- package/src/validator_ha_signer.ts +1 -1
package/dest/db/lmdb.d.ts
CHANGED
|
@@ -13,6 +13,10 @@ import type { DateProvider } from '@aztec/foundation/timer';
|
|
|
13
13
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
14
14
|
import type { SlashingProtectionDatabase, TryInsertOrGetResult } from '../types.js';
|
|
15
15
|
import { type CheckAndRecordParams, DutyType } from './types.js';
|
|
16
|
+
/**
|
|
17
|
+
* Migrates local slashing-protection duties from schema 1 to schema 2.
|
|
18
|
+
*/
|
|
19
|
+
export declare function migrateLmdbSlashingProtectionDatabase(dataDirectory: string, currentVersion: number, latestVersion: number, dbMapSizeKb?: number): Promise<void>;
|
|
16
20
|
/**
|
|
17
21
|
* LMDB-backed implementation of SlashingProtectionDatabase.
|
|
18
22
|
*
|
|
@@ -63,4 +67,4 @@ export declare class LmdbSlashingProtectionDatabase implements SlashingProtectio
|
|
|
63
67
|
*/
|
|
64
68
|
close(): Promise<void>;
|
|
65
69
|
}
|
|
66
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
70
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG1kYi5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RiL2xtZGIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7O0dBUUc7QUFDSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFN0QsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzVELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFpQixNQUFNLGlCQUFpQixDQUFDO0FBR3hFLE9BQU8sS0FBSyxFQUFFLDBCQUEwQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3BGLE9BQU8sRUFDTCxLQUFLLG9CQUFvQixFQUV6QixRQUFRLEVBSVQsTUFBTSxZQUFZLENBQUM7QUFZcEI7O0dBRUc7QUFDSCx3QkFBc0IscUNBQXFDLENBQ3pELGFBQWEsRUFBRSxNQUFNLEVBQ3JCLGNBQWMsRUFBRSxNQUFNLEVBQ3RCLGFBQWEsRUFBRSxNQUFNLEVBQ3JCLFdBQVcsQ0FBQyxFQUFFLE1BQU0sR0FDbkIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQXNCZjtBQVlEOzs7OztHQUtHO0FBQ0gscUJBQWEsOEJBQStCLFlBQVcsMEJBQTBCO0lBTzdFLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSztJQUN0QixPQUFPLENBQUMsUUFBUSxDQUFDLFlBQVk7SUFQL0IsZ0JBQXVCLGNBQWMsS0FBSztJQUUxQyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBMEM7SUFDakUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQVM7SUFFN0IsWUFDbUIsS0FBSyxFQUFFLGlCQUFpQixFQUN4QixZQUFZLEVBQUUsWUFBWSxFQUk1QztJQUVEOzs7O09BSUc7SUFDVSxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsb0JBQW9CLEdBQUcsT0FBTyxDQUFDLG9CQUFvQixDQUFDLENBNkMvRjtJQUVEOzs7T0FHRztJQUNJLGdCQUFnQixDQUNyQixhQUFhLEVBQUUsVUFBVSxFQUN6QixnQkFBZ0IsRUFBRSxVQUFVLEVBQzVCLElBQUksRUFBRSxVQUFVLEVBQ2hCLFFBQVEsRUFBRSxRQUFRLEVBQ2xCLFNBQVMsRUFBRSxNQUFNLEVBQ2pCLFNBQVMsRUFBRSxNQUFNLEVBQ2pCLDBCQUEwQixFQUFFLE1BQU0sR0FDakMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQTBDbEI7SUFFRDs7O09BR0c7SUFDSSxVQUFVLENBQ2YsYUFBYSxFQUFFLFVBQVUsRUFDekIsZ0JBQWdCLEVBQUUsVUFBVSxFQUM1QixJQUFJLEVBQUUsVUFBVSxFQUNoQixRQUFRLEVBQUUsUUFBUSxFQUNsQixTQUFTLEVBQUUsTUFBTSxFQUNqQiwwQkFBMEIsRUFBRSxNQUFNLEdBQ2pDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0F5QmxCO0lBRUQ7O09BRUc7SUFDSSxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQWU5RTtJQUVEOzs7Ozs7T0FNRztJQUNJLDJCQUEyQixDQUFDLHFCQUFxQixFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBRXJGO0lBRUQ7O09BRUc7SUFDSSxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FtQnpEO0lBRUQ7O09BRUc7SUFDVSxLQUFLLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUdsQztDQUNGIn0=
|
package/dest/db/lmdb.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lmdb.d.ts","sourceRoot":"","sources":["../../src/db/lmdb.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"lmdb.d.ts","sourceRoot":"","sources":["../../src/db/lmdb.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AAGxE,OAAO,KAAK,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EACL,KAAK,oBAAoB,EAEzB,QAAQ,EAIT,MAAM,YAAY,CAAC;AAYpB;;GAEG;AACH,wBAAsB,qCAAqC,CACzD,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAsBf;AAYD;;;;;GAKG;AACH,qBAAa,8BAA+B,YAAW,0BAA0B;IAO7E,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAP/B,gBAAuB,cAAc,KAAK;IAE1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IACjE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B,YACmB,KAAK,EAAE,iBAAiB,EACxB,YAAY,EAAE,YAAY,EAI5C;IAED;;;;OAIG;IACU,sBAAsB,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA6C/F;IAED;;;OAGG;IACI,gBAAgB,CACrB,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,CA0ClB;IAED;;;OAGG;IACI,UAAU,CACf,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,CAyBlB;IAED;;OAEG;IACI,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAe9E;IAED;;;;;;OAMG;IACI,2BAA2B,CAAC,qBAAqB,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAErF;IAED;;OAEG;IACI,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBzD;IAED;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAGlC;CACF"}
|
package/dest/db/lmdb.js
CHANGED
|
@@ -8,7 +8,41 @@
|
|
|
8
8
|
* This means we get crash-restart protection without needing an external database.
|
|
9
9
|
*/ import { randomBytes } from '@aztec/foundation/crypto/random';
|
|
10
10
|
import { createLogger } from '@aztec/foundation/log';
|
|
11
|
+
import { openStoreAt } from '@aztec/kv-store/lmdb-v2';
|
|
11
12
|
import { DutyStatus, getBlockIndexFromDutyIdentifier, recordFromFields } from './types.js';
|
|
13
|
+
const DUTIES_MAP_NAME = 'signing-protection-duties';
|
|
14
|
+
const LEGACY_CHECKPOINT_NUMBER = '0';
|
|
15
|
+
function needsCheckpointNumberMigration(record) {
|
|
16
|
+
return record.checkpointNumber === undefined;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Migrates local slashing-protection duties from schema 1 to schema 2.
|
|
20
|
+
*/ export async function migrateLmdbSlashingProtectionDatabase(dataDirectory, currentVersion, latestVersion, dbMapSizeKb) {
|
|
21
|
+
if (currentVersion !== 1 || latestVersion !== LmdbSlashingProtectionDatabase.SCHEMA_VERSION) {
|
|
22
|
+
throw new Error(`Unsupported LMDB slashing-protection migration ${currentVersion} -> ${latestVersion}`);
|
|
23
|
+
}
|
|
24
|
+
const store = await openStoreAt(dataDirectory, dbMapSizeKb);
|
|
25
|
+
try {
|
|
26
|
+
const duties = store.openMap(DUTIES_MAP_NAME);
|
|
27
|
+
const migratedRecords = [];
|
|
28
|
+
for await (const [key, record] of duties.entriesAsync()){
|
|
29
|
+
if (needsCheckpointNumberMigration(record)) {
|
|
30
|
+
migratedRecords.push({
|
|
31
|
+
key,
|
|
32
|
+
value: {
|
|
33
|
+
...record,
|
|
34
|
+
checkpointNumber: LEGACY_CHECKPOINT_NUMBER
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (migratedRecords.length > 0) {
|
|
40
|
+
await duties.setMany(migratedRecords);
|
|
41
|
+
}
|
|
42
|
+
} finally{
|
|
43
|
+
await store.close();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
12
46
|
function dutyKey(rollupAddress, validatorAddress, slot, dutyType, blockIndexWithinCheckpoint) {
|
|
13
47
|
return `${rollupAddress}:${validatorAddress}:${slot}:${dutyType}:${blockIndexWithinCheckpoint}`;
|
|
14
48
|
}
|
|
@@ -27,7 +61,7 @@ function dutyKey(rollupAddress, validatorAddress, slot, dutyType, blockIndexWith
|
|
|
27
61
|
this.store = store;
|
|
28
62
|
this.dateProvider = dateProvider;
|
|
29
63
|
this.log = createLogger('slashing-protection:lmdb');
|
|
30
|
-
this.duties = store.openMap(
|
|
64
|
+
this.duties = store.openMap(DUTIES_MAP_NAME);
|
|
31
65
|
}
|
|
32
66
|
/**
|
|
33
67
|
* Atomically try to insert a new duty record, or get the existing one if present.
|
package/dest/factory.d.ts
CHANGED
|
@@ -70,8 +70,8 @@ export declare function createSharedSlashingProtectionDb(dateProvider?: DateProv
|
|
|
70
70
|
* Create a ValidatorHASigner backed by a pre-existing SlashingProtectionDatabase.
|
|
71
71
|
* Used for testing HA setups where multiple nodes share the same protection database.
|
|
72
72
|
*/
|
|
73
|
-
export declare function createSignerFromSharedDb(db: SlashingProtectionDatabase, config: Pick<ValidatorHASignerConfig, 'nodeId' | 'pollingIntervalMs' | 'signingTimeoutMs' | 'maxStuckDutiesAgeMs' | '
|
|
73
|
+
export declare function createSignerFromSharedDb(db: SlashingProtectionDatabase, config: Pick<ValidatorHASignerConfig, 'nodeId' | 'pollingIntervalMs' | 'signingTimeoutMs' | 'maxStuckDutiesAgeMs' | 'rollupAddress'>, deps?: CreateLocalSignerWithProtectionDeps): {
|
|
74
74
|
signer: ValidatorHASigner;
|
|
75
75
|
db: SlashingProtectionDatabase;
|
|
76
76
|
};
|
|
77
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
77
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFDSCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFdkQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQVEzRixPQUFPLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxtQ0FBbUMsRUFBRSwwQkFBMEIsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN0SCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUU3RDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQ0c7QUFDSCx3QkFBc0IsY0FBYyxDQUNsQyxNQUFNLEVBQUUsdUJBQXVCLEVBQy9CLElBQUksQ0FBQyxFQUFFLGtCQUFrQixHQUN4QixPQUFPLENBQUM7SUFDVCxNQUFNLEVBQUUsaUJBQWlCLENBQUM7SUFDMUIsRUFBRSxFQUFFLDBCQUEwQixDQUFDO0NBQ2hDLENBQUMsQ0F1Q0Q7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILHdCQUFzQiwrQkFBK0IsQ0FDbkQsTUFBTSxFQUFFLGlCQUFpQixFQUN6QixJQUFJLENBQUMsRUFBRSxtQ0FBbUMsR0FDekMsT0FBTyxDQUFDO0lBQ1QsTUFBTSxFQUFFLGlCQUFpQixDQUFDO0lBQzFCLEVBQUUsRUFBRSwwQkFBMEIsQ0FBQztDQUNoQyxDQUFDLENBcUNEO0FBRUQ7OztHQUdHO0FBQ0gsd0JBQXNCLGdDQUFnQyxDQUNwRCxZQUFZLEdBQUUsWUFBaUMsR0FDOUMsT0FBTyxDQUFDLDBCQUEwQixDQUFDLENBS3JDO0FBRUQ7OztHQUdHO0FBQ0gsd0JBQWdCLHdCQUF3QixDQUN0QyxFQUFFLEVBQUUsMEJBQTBCLEVBQzlCLE1BQU0sRUFBRSxJQUFJLENBQ1YsdUJBQXVCLEVBQ3ZCLFFBQVEsR0FBRyxtQkFBbUIsR0FBRyxrQkFBa0IsR0FBRyxxQkFBcUIsR0FBRyxlQUFlLENBQzlGLEVBQ0QsSUFBSSxDQUFDLEVBQUUsbUNBQW1DLEdBQ3pDO0lBQUUsTUFBTSxFQUFFLGlCQUFpQixDQUFDO0lBQUMsRUFBRSxFQUFFLDBCQUEwQixDQUFBO0NBQUUsQ0FNL0QifQ==
|
package/dest/factory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,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,CAuCD;AAED;;;;;;;;;;;;;;GAcG;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,
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,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,CAuCD;AAED;;;;;;;;;;;;;;GAcG;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,CAqCD;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,kBAAkB,GAAG,qBAAqB,GAAG,eAAe,CAC9F,EACD,IAAI,CAAC,EAAE,mCAAmC,GACzC;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,EAAE,EAAE,0BAA0B,CAAA;CAAE,CAM/D"}
|
package/dest/factory.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { createStore } from '@aztec/kv-store/lmdb-v2';
|
|
5
5
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
6
6
|
import { Pool } from 'pg';
|
|
7
|
-
import { LmdbSlashingProtectionDatabase } from './db/lmdb.js';
|
|
7
|
+
import { LmdbSlashingProtectionDatabase, migrateLmdbSlashingProtectionDatabase } from './db/lmdb.js';
|
|
8
8
|
import { PostgresSlashingProtectionDatabase } from './db/postgres.js';
|
|
9
9
|
import { HASignerMetrics } from './metrics.js';
|
|
10
10
|
import { ValidatorHASigner } from './validator_ha_signer.js';
|
|
@@ -97,7 +97,10 @@ import { ValidatorHASigner } from './validator_ha_signer.js';
|
|
|
97
97
|
const kvStore = await createStore('signing-protection', LmdbSlashingProtectionDatabase.SCHEMA_VERSION, {
|
|
98
98
|
dataDirectory: config.dataDirectory,
|
|
99
99
|
dataStoreMapSizeKb: config.signingProtectionMapSizeKb ?? config.dataStoreMapSizeKb,
|
|
100
|
-
|
|
100
|
+
rollupAddress: config.rollupAddress
|
|
101
|
+
}, undefined, {
|
|
102
|
+
onUpgrade: (dataDirectory, currentVersion, latestVersion)=>migrateLmdbSlashingProtectionDatabase(dataDirectory, currentVersion, latestVersion, config.signingProtectionMapSizeKb ?? config.dataStoreMapSizeKb),
|
|
103
|
+
schemaVersionMismatchPolicy: 'throw'
|
|
101
104
|
});
|
|
102
105
|
const db = new LmdbSlashingProtectionDatabase(kvStore, dateProvider);
|
|
103
106
|
const signerConfig = {
|
|
@@ -174,10 +174,10 @@ import { DutyAlreadySignedError, SlashingProtectionError } from './errors.js';
|
|
|
174
174
|
* Also performs one-time cleanup of duties with outdated rollup addresses.
|
|
175
175
|
*/ async start() {
|
|
176
176
|
// One-time cleanup at startup: remove duties from previous rollup versions
|
|
177
|
-
const numOutdatedRollupDuties = await this.db.cleanupOutdatedRollupDuties(this.config.
|
|
177
|
+
const numOutdatedRollupDuties = await this.db.cleanupOutdatedRollupDuties(this.config.rollupAddress);
|
|
178
178
|
if (numOutdatedRollupDuties > 0) {
|
|
179
179
|
this.log.info(`Cleaned up ${numOutdatedRollupDuties} duties with outdated rollup address at startup`, {
|
|
180
|
-
currentRollupAddress: this.config.
|
|
180
|
+
currentRollupAddress: this.config.rollupAddress.toString()
|
|
181
181
|
});
|
|
182
182
|
this.metrics.recordCleanup('outdated_rollup', numOutdatedRollupDuties);
|
|
183
183
|
}
|
|
@@ -40,7 +40,7 @@ import { SlashingProtectionService } from './slashing_protection_service.js';
|
|
|
40
40
|
if (!config.nodeId || config.nodeId === '') {
|
|
41
41
|
throw new Error('NODE_ID is required for high-availability setups');
|
|
42
42
|
}
|
|
43
|
-
this.rollupAddress = config.
|
|
43
|
+
this.rollupAddress = config.rollupAddress;
|
|
44
44
|
this.slashingProtection = new SlashingProtectionService(db, config, {
|
|
45
45
|
metrics: deps.metrics,
|
|
46
46
|
dateProvider: deps.dateProvider
|
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.b3d3157a",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./db": "./dest/db/index.js",
|
|
@@ -75,15 +75,15 @@
|
|
|
75
75
|
]
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
79
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
80
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
81
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
82
|
-
"@aztec/telemetry-client": "0.0.1-commit.
|
|
78
|
+
"@aztec/ethereum": "0.0.1-commit.b3d3157a",
|
|
79
|
+
"@aztec/foundation": "0.0.1-commit.b3d3157a",
|
|
80
|
+
"@aztec/kv-store": "0.0.1-commit.b3d3157a",
|
|
81
|
+
"@aztec/stdlib": "0.0.1-commit.b3d3157a",
|
|
82
|
+
"@aztec/telemetry-client": "0.0.1-commit.b3d3157a",
|
|
83
83
|
"node-pg-migrate": "^8.0.4",
|
|
84
84
|
"pg": "^8.11.3",
|
|
85
85
|
"tslib": "^2.4.0",
|
|
86
|
-
"zod": "^
|
|
86
|
+
"zod": "^4"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
89
|
"@electric-sql/pglite": "^0.3.14",
|
package/src/db/lmdb.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
13
13
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
14
14
|
import type { DateProvider } from '@aztec/foundation/timer';
|
|
15
15
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
16
|
+
import { openStoreAt } from '@aztec/kv-store/lmdb-v2';
|
|
16
17
|
|
|
17
18
|
import type { SlashingProtectionDatabase, TryInsertOrGetResult } from '../types.js';
|
|
18
19
|
import {
|
|
@@ -24,6 +25,48 @@ import {
|
|
|
24
25
|
recordFromFields,
|
|
25
26
|
} from './types.js';
|
|
26
27
|
|
|
28
|
+
const DUTIES_MAP_NAME = 'signing-protection-duties';
|
|
29
|
+
const LEGACY_CHECKPOINT_NUMBER = '0';
|
|
30
|
+
|
|
31
|
+
type StoredDutyRecordV1 = Omit<StoredDutyRecord, 'checkpointNumber'> & { checkpointNumber?: undefined };
|
|
32
|
+
type MigratableStoredDutyRecord = StoredDutyRecord | StoredDutyRecordV1;
|
|
33
|
+
|
|
34
|
+
function needsCheckpointNumberMigration(record: MigratableStoredDutyRecord): record is StoredDutyRecordV1 {
|
|
35
|
+
return record.checkpointNumber === undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Migrates local slashing-protection duties from schema 1 to schema 2.
|
|
40
|
+
*/
|
|
41
|
+
export async function migrateLmdbSlashingProtectionDatabase(
|
|
42
|
+
dataDirectory: string,
|
|
43
|
+
currentVersion: number,
|
|
44
|
+
latestVersion: number,
|
|
45
|
+
dbMapSizeKb?: number,
|
|
46
|
+
): Promise<void> {
|
|
47
|
+
if (currentVersion !== 1 || latestVersion !== LmdbSlashingProtectionDatabase.SCHEMA_VERSION) {
|
|
48
|
+
throw new Error(`Unsupported LMDB slashing-protection migration ${currentVersion} -> ${latestVersion}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const store = await openStoreAt(dataDirectory, dbMapSizeKb);
|
|
52
|
+
try {
|
|
53
|
+
const duties = store.openMap<string, MigratableStoredDutyRecord>(DUTIES_MAP_NAME);
|
|
54
|
+
const migratedRecords: { key: string; value: StoredDutyRecord }[] = [];
|
|
55
|
+
|
|
56
|
+
for await (const [key, record] of duties.entriesAsync()) {
|
|
57
|
+
if (needsCheckpointNumberMigration(record)) {
|
|
58
|
+
migratedRecords.push({ key, value: { ...record, checkpointNumber: LEGACY_CHECKPOINT_NUMBER } });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (migratedRecords.length > 0) {
|
|
63
|
+
await duties.setMany(migratedRecords);
|
|
64
|
+
}
|
|
65
|
+
} finally {
|
|
66
|
+
await store.close();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
27
70
|
function dutyKey(
|
|
28
71
|
rollupAddress: string,
|
|
29
72
|
validatorAddress: string,
|
|
@@ -51,7 +94,7 @@ export class LmdbSlashingProtectionDatabase implements SlashingProtectionDatabas
|
|
|
51
94
|
private readonly dateProvider: DateProvider,
|
|
52
95
|
) {
|
|
53
96
|
this.log = createLogger('slashing-protection:lmdb');
|
|
54
|
-
this.duties = store.openMap<string, StoredDutyRecord>(
|
|
97
|
+
this.duties = store.openMap<string, StoredDutyRecord>(DUTIES_MAP_NAME);
|
|
55
98
|
}
|
|
56
99
|
|
|
57
100
|
/**
|
package/src/factory.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
|
8
8
|
|
|
9
9
|
import { Pool } from 'pg';
|
|
10
10
|
|
|
11
|
-
import { LmdbSlashingProtectionDatabase } from './db/lmdb.js';
|
|
11
|
+
import { LmdbSlashingProtectionDatabase, migrateLmdbSlashingProtectionDatabase } from './db/lmdb.js';
|
|
12
12
|
import { PostgresSlashingProtectionDatabase } from './db/postgres.js';
|
|
13
13
|
import { HASignerMetrics } from './metrics.js';
|
|
14
14
|
import type { CreateHASignerDeps, CreateLocalSignerWithProtectionDeps, SlashingProtectionDatabase } from './types.js';
|
|
@@ -119,11 +119,26 @@ export async function createLocalSignerWithProtection(
|
|
|
119
119
|
const telemetryClient = deps?.telemetryClient ?? getTelemetryClient();
|
|
120
120
|
const dateProvider = deps?.dateProvider ?? new DateProvider();
|
|
121
121
|
|
|
122
|
-
const kvStore = await createStore(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
122
|
+
const kvStore = await createStore(
|
|
123
|
+
'signing-protection',
|
|
124
|
+
LmdbSlashingProtectionDatabase.SCHEMA_VERSION,
|
|
125
|
+
{
|
|
126
|
+
dataDirectory: config.dataDirectory,
|
|
127
|
+
dataStoreMapSizeKb: config.signingProtectionMapSizeKb ?? config.dataStoreMapSizeKb,
|
|
128
|
+
rollupAddress: config.rollupAddress,
|
|
129
|
+
},
|
|
130
|
+
undefined,
|
|
131
|
+
{
|
|
132
|
+
onUpgrade: (dataDirectory, currentVersion, latestVersion) =>
|
|
133
|
+
migrateLmdbSlashingProtectionDatabase(
|
|
134
|
+
dataDirectory,
|
|
135
|
+
currentVersion,
|
|
136
|
+
latestVersion,
|
|
137
|
+
config.signingProtectionMapSizeKb ?? config.dataStoreMapSizeKb,
|
|
138
|
+
),
|
|
139
|
+
schemaVersionMismatchPolicy: 'throw',
|
|
140
|
+
},
|
|
141
|
+
);
|
|
127
142
|
|
|
128
143
|
const db = new LmdbSlashingProtectionDatabase(kvStore, dateProvider);
|
|
129
144
|
|
|
@@ -160,7 +175,7 @@ export function createSignerFromSharedDb(
|
|
|
160
175
|
db: SlashingProtectionDatabase,
|
|
161
176
|
config: Pick<
|
|
162
177
|
ValidatorHASignerConfig,
|
|
163
|
-
'nodeId' | 'pollingIntervalMs' | 'signingTimeoutMs' | 'maxStuckDutiesAgeMs' | '
|
|
178
|
+
'nodeId' | 'pollingIntervalMs' | 'signingTimeoutMs' | 'maxStuckDutiesAgeMs' | 'rollupAddress'
|
|
164
179
|
>,
|
|
165
180
|
deps?: CreateLocalSignerWithProtectionDeps,
|
|
166
181
|
): { signer: ValidatorHASigner; db: SlashingProtectionDatabase } {
|
|
@@ -241,10 +241,10 @@ export class SlashingProtectionService {
|
|
|
241
241
|
*/
|
|
242
242
|
async start() {
|
|
243
243
|
// One-time cleanup at startup: remove duties from previous rollup versions
|
|
244
|
-
const numOutdatedRollupDuties = await this.db.cleanupOutdatedRollupDuties(this.config.
|
|
244
|
+
const numOutdatedRollupDuties = await this.db.cleanupOutdatedRollupDuties(this.config.rollupAddress);
|
|
245
245
|
if (numOutdatedRollupDuties > 0) {
|
|
246
246
|
this.log.info(`Cleaned up ${numOutdatedRollupDuties} duties with outdated rollup address at startup`, {
|
|
247
|
-
currentRollupAddress: this.config.
|
|
247
|
+
currentRollupAddress: this.config.rollupAddress.toString(),
|
|
248
248
|
});
|
|
249
249
|
this.metrics.recordCleanup('outdated_rollup', numOutdatedRollupDuties);
|
|
250
250
|
}
|
|
@@ -68,7 +68,7 @@ export class ValidatorHASigner {
|
|
|
68
68
|
if (!config.nodeId || config.nodeId === '') {
|
|
69
69
|
throw new Error('NODE_ID is required for high-availability setups');
|
|
70
70
|
}
|
|
71
|
-
this.rollupAddress = config.
|
|
71
|
+
this.rollupAddress = config.rollupAddress;
|
|
72
72
|
this.slashingProtection = new SlashingProtectionService(db, config, {
|
|
73
73
|
metrics: deps.metrics,
|
|
74
74
|
dateProvider: deps.dateProvider,
|