UNPKG

@lodestar/beacon-node

Version:

A Typescript implementation of the beacon chain

144 lines (120 loc) 5.09 kB
import {ChainForkConfig} from "@lodestar/config"; import {Db, LevelDbControllerMetrics, encodeKey} from "@lodestar/db"; import {Bucket} from "./buckets.js"; import {IBeaconDb} from "./interface.js"; import {CheckpointStateRepository} from "./repositories/checkpointState.js"; import { AttesterSlashingRepository, BLSToExecutionChangeRepository, BackfilledRanges, BestLightClientUpdateRepository, BlobSidecarsArchiveRepository, BlobSidecarsRepository, BlockArchiveRepository, BlockRepository, CheckpointHeaderRepository, DataColumnSidecarArchiveRepository, DataColumnSidecarRepository, ExecutionPayloadEnvelopeArchiveRepository, ExecutionPayloadEnvelopeRepository, ProposerSlashingRepository, StateArchiveRepository, SyncCommitteeRepository, SyncCommitteeWitnessRepository, VoluntaryExitRepository, } from "./repositories/index.js"; export type BeaconDbModules = { config: ChainForkConfig; db: Db; }; export class BeaconDb implements IBeaconDb { block: BlockRepository; blockArchive: BlockArchiveRepository; blobSidecars: BlobSidecarsRepository; blobSidecarsArchive: BlobSidecarsArchiveRepository; dataColumnSidecar: DataColumnSidecarRepository; dataColumnSidecarArchive: DataColumnSidecarArchiveRepository; executionPayloadEnvelope: ExecutionPayloadEnvelopeRepository; executionPayloadEnvelopeArchive: ExecutionPayloadEnvelopeArchiveRepository; stateArchive: StateArchiveRepository; checkpointState: CheckpointStateRepository; voluntaryExit: VoluntaryExitRepository; proposerSlashing: ProposerSlashingRepository; attesterSlashing: AttesterSlashingRepository; blsToExecutionChange: BLSToExecutionChangeRepository; // lightclient bestLightClientUpdate: BestLightClientUpdateRepository; checkpointHeader: CheckpointHeaderRepository; syncCommittee: SyncCommitteeRepository; syncCommitteeWitness: SyncCommitteeWitnessRepository; backfilledRanges: BackfilledRanges; constructor( config: ChainForkConfig, protected readonly db: Db ) { // Warning: If code is ever run in the constructor, must change this stub to not extend 'packages/beacon-node/test/utils/stub/beaconDb.ts' - this.block = new BlockRepository(config, db); this.blockArchive = new BlockArchiveRepository(config, db); this.blobSidecars = new BlobSidecarsRepository(config, db); this.blobSidecarsArchive = new BlobSidecarsArchiveRepository(config, db); this.dataColumnSidecar = new DataColumnSidecarRepository(config, db); this.dataColumnSidecarArchive = new DataColumnSidecarArchiveRepository(config, db); this.executionPayloadEnvelope = new ExecutionPayloadEnvelopeRepository(config, db); this.executionPayloadEnvelopeArchive = new ExecutionPayloadEnvelopeArchiveRepository(config, db); this.stateArchive = new StateArchiveRepository(config, db); this.checkpointState = new CheckpointStateRepository(config, db); this.voluntaryExit = new VoluntaryExitRepository(config, db); this.blsToExecutionChange = new BLSToExecutionChangeRepository(config, db); this.proposerSlashing = new ProposerSlashingRepository(config, db); this.attesterSlashing = new AttesterSlashingRepository(config, db); // lightclient this.bestLightClientUpdate = new BestLightClientUpdateRepository(config, db); this.checkpointHeader = new CheckpointHeaderRepository(config, db); this.syncCommittee = new SyncCommitteeRepository(config, db); this.syncCommitteeWitness = new SyncCommitteeWitnessRepository(config, db); this.backfilledRanges = new BackfilledRanges(config, db); } close(): Promise<void> { return this.db.close(); } setMetrics(metrics: LevelDbControllerMetrics): void { this.db.setMetrics(metrics); } async pruneHotDb(): Promise<void> { // Prune all hot blobs await this.blobSidecars.batchDelete(await this.blobSidecars.keys()); // Prune all hot blocks // TODO: Enable once it's deemed safe // await this.block.batchDelete(await this.block.keys()); } async deleteDeprecatedEth1Data(): Promise<void> { const deprecatedBuckets = [ Bucket.phase0_eth1Data, Bucket.index_depositDataRoot, Bucket.phase0_depositData, Bucket.phase0_depositEvent, Bucket.phase0_preGenesisState, Bucket.phase0_preGenesisStateLastProcessedBlock, ]; for (const bucket of deprecatedBuckets) { await this.deleteBucketData(bucket); } } private async deleteBucketData(bucket: Bucket): Promise<void> { const minKey = encodeKey(bucket, Buffer.alloc(0)); const maxKey = encodeKey(bucket + 1, Buffer.alloc(0)); // Batch delete to avoid loading all keys into memory at once const BATCH_DELETE_SIZE = 1000; let keysBatch: Uint8Array[] = []; for await (const key of this.db.keysStream({gte: minKey, lt: maxKey})) { keysBatch.push(key); if (keysBatch.length >= BATCH_DELETE_SIZE) { await this.db.batchDelete(keysBatch); keysBatch = []; } } if (keysBatch.length > 0) { await this.db.batchDelete(keysBatch); } } }