/** * LMDB implementation of SlashingProtectionDatabase * * Provides local (single-node) double-signing protection using LMDB as the backend. * Suitable for nodes that do NOT run in a high-availability multi-node setup. * * The LMDB store is single-writer, making setIfNotExists inherently atomic. * This means we get crash-restart protection without needing an external database. */ import { SlotNumber } from '@aztec/foundation/branded-types'; import { EthAddress } from '@aztec/foundation/eth-address'; import type { DateProvider } from '@aztec/foundation/timer'; import type { AztecAsyncKVStore } from '@aztec/kv-store'; import type { SlashingProtectionDatabase, TryInsertOrGetResult } from '../types.js'; import { type CheckAndRecordParams, DutyType } from './types.js'; /** * Migrates local slashing-protection duties from schema 1 to schema 2. */ export declare function migrateLmdbSlashingProtectionDatabase(dataDirectory: string, currentVersion: number, latestVersion: number, dbMapSizeKb?: number): Promise; /** * LMDB-backed implementation of SlashingProtectionDatabase. * * Provides single-node double-signing protection that survives crashes and restarts. * Does not provide cross-node coordination (that requires the PostgreSQL implementation). */ export declare class LmdbSlashingProtectionDatabase implements SlashingProtectionDatabase { private readonly store; private readonly dateProvider; static readonly SCHEMA_VERSION = 2; private readonly duties; private readonly log; constructor(store: AztecAsyncKVStore, dateProvider: DateProvider); /** * Atomically try to insert a new duty record, or get the existing one if present. * * LMDB is single-writer so the read-then-write inside transactionAsync is naturally atomic. */ tryInsertOrGetExisting(params: CheckAndRecordParams): Promise; /** * Update a duty to 'signed' status with the signature. * Only succeeds if the lockToken matches. */ updateDutySigned(rollupAddress: EthAddress, validatorAddress: EthAddress, slot: SlotNumber, dutyType: DutyType, signature: string, lockToken: string, blockIndexWithinCheckpoint: number): Promise; /** * Delete a duty record. * Only succeeds if the lockToken matches. */ deleteDuty(rollupAddress: EthAddress, validatorAddress: EthAddress, slot: SlotNumber, dutyType: DutyType, lockToken: string, blockIndexWithinCheckpoint: number): Promise; /** * Cleanup own stuck duties (SIGNING status older than maxAgeMs). */ cleanupOwnStuckDuties(nodeId: string, maxAgeMs: number): Promise; /** * Cleanup duties with outdated rollup address. * * This is always a no-op for the LMDB implementation: the underlying store is created via * DatabaseVersionManager (in factory.ts), which already resets the entire data directory at * startup whenever the rollup address changes. */ cleanupOutdatedRollupDuties(_currentRollupAddress: EthAddress): Promise; /** * Cleanup old signed duties older than maxAgeMs. */ cleanupOldDuties(maxAgeMs: number): Promise; /** * Close the underlying LMDB store. */ close(): Promise; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG1kYi5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RiL2xtZGIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7O0dBUUc7QUFDSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFN0QsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzVELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFpQixNQUFNLGlCQUFpQixDQUFDO0FBR3hFLE9BQU8sS0FBSyxFQUFFLDBCQUEwQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3BGLE9BQU8sRUFDTCxLQUFLLG9CQUFvQixFQUV6QixRQUFRLEVBSVQsTUFBTSxZQUFZLENBQUM7QUFZcEI7O0dBRUc7QUFDSCx3QkFBc0IscUNBQXFDLENBQ3pELGFBQWEsRUFBRSxNQUFNLEVBQ3JCLGNBQWMsRUFBRSxNQUFNLEVBQ3RCLGFBQWEsRUFBRSxNQUFNLEVBQ3JCLFdBQVcsQ0FBQyxFQUFFLE1BQU0sR0FDbkIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQXNCZjtBQVlEOzs7OztHQUtHO0FBQ0gscUJBQWEsOEJBQStCLFlBQVcsMEJBQTBCO0lBTzdFLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSztJQUN0QixPQUFPLENBQUMsUUFBUSxDQUFDLFlBQVk7SUFQL0IsZ0JBQXVCLGNBQWMsS0FBSztJQUUxQyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBMEM7SUFDakUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQVM7SUFFN0IsWUFDbUIsS0FBSyxFQUFFLGlCQUFpQixFQUN4QixZQUFZLEVBQUUsWUFBWSxFQUk1QztJQUVEOzs7O09BSUc7SUFDVSxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsb0JBQW9CLEdBQUcsT0FBTyxDQUFDLG9CQUFvQixDQUFDLENBNkMvRjtJQUVEOzs7T0FHRztJQUNJLGdCQUFnQixDQUNyQixhQUFhLEVBQUUsVUFBVSxFQUN6QixnQkFBZ0IsRUFBRSxVQUFVLEVBQzVCLElBQUksRUFBRSxVQUFVLEVBQ2hCLFFBQVEsRUFBRSxRQUFRLEVBQ2xCLFNBQVMsRUFBRSxNQUFNLEVBQ2pCLFNBQVMsRUFBRSxNQUFNLEVBQ2pCLDBCQUEwQixFQUFFLE1BQU0sR0FDakMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQTBDbEI7SUFFRDs7O09BR0c7SUFDSSxVQUFVLENBQ2YsYUFBYSxFQUFFLFVBQVUsRUFDekIsZ0JBQWdCLEVBQUUsVUFBVSxFQUM1QixJQUFJLEVBQUUsVUFBVSxFQUNoQixRQUFRLEVBQUUsUUFBUSxFQUNsQixTQUFTLEVBQUUsTUFBTSxFQUNqQiwwQkFBMEIsRUFBRSxNQUFNLEdBQ2pDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0F5QmxCO0lBRUQ7O09BRUc7SUFDSSxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQWU5RTtJQUVEOzs7Ozs7T0FNRztJQUNJLDJCQUEyQixDQUFDLHFCQUFxQixFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBRXJGO0lBRUQ7O09BRUc7SUFDSSxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FtQnpEO0lBRUQ7O09BRUc7SUFDVSxLQUFLLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUdsQztDQUNGIn0=