Skip to content

Commit

Permalink
chore: move DB Bucket schema to consumer packages (#5560)
Browse files Browse the repository at this point in the history
* Move db bucket definition to each package

* At overlap test

* Fix type issues

* Fix test types
  • Loading branch information
dapplion authored May 30, 2023
1 parent 16eae96 commit 78bb300
Show file tree
Hide file tree
Showing 38 changed files with 210 additions and 186 deletions.
10 changes: 3 additions & 7 deletions packages/beacon-node/src/api/impl/lodestar/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {routes, ServerApi} from "@lodestar/api";
import {Bucket, Repository} from "@lodestar/db";
import {Repository} from "@lodestar/db";
import {toHex} from "@lodestar/utils";
import {getLatestWeakSubjectivityCheckpointEpoch} from "@lodestar/state-transition";
import {toHexString} from "@chainsafe/ssz";
Expand Down Expand Up @@ -144,14 +144,13 @@ export function getLodestarApi({
async dumpDbBucketKeys(bucketReq) {
for (const repo of Object.values(db) as IBeaconDb[keyof IBeaconDb][]) {
if (repo instanceof Repository) {
const bucket = (repo as RepositoryAny)["bucket"];
if (bucket === bucket || Bucket[bucket] === bucketReq) {
if (String(repo["bucket"]) === bucketReq || repo["bucketId"] === bucketReq) {
return {data: stringifyKeys(await repo.keys())};
}
}
}

throw Error(`Unknown Bucket '${bucketReq}' available: ${Object.keys(Bucket).join(", ")}`);
throw Error(`Unknown Bucket '${bucketReq}'`);
},

async dumpDbStateIndex() {
Expand Down Expand Up @@ -186,9 +185,6 @@ function regenRequestToJson(config: ChainForkConfig, regenRequest: RegenRequest)
}
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
type RepositoryAny = Repository<any, any>;

function stringifyKeys(keys: (Uint8Array | number | string)[]): string[] {
return keys.map((key) => {
if (key instanceof Uint8Array) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import {intToBytes} from "@lodestar/utils";
import {BUCKET_LENGTH} from "./const.js";

// Buckets are separate database namespaces
export enum Bucket {
// beacon chain
Expand Down Expand Up @@ -33,16 +30,6 @@ export enum Bucket {
phase0_proposerSlashing = 14, // ValidatorIndex -> ProposerSlashing
phase0_attesterSlashing = 15, // Root -> AttesterSlashing
capella_blsToExecutionChange = 16, // ValidatorIndex -> SignedBLSToExecutionChange
// validator
// validator = 16, // DEPRECATED on v0.11.0
// lastProposedBlock = 17, // DEPRECATED on v0.11.0
// proposedAttestations = 18, // DEPRECATED on v0.11.0
// validator slashing protection
phase0_slashingProtectionBlockBySlot = 20,
phase0_slashingProtectionAttestationByTarget = 21,
phase0_slashingProtectionAttestationLowerBound = 22,
index_slashingProtectionMinSpanDistance = 23,
index_slashingProtectionMaxSpanDistance = 24,
// allForks_pendingBlock = 25, // Root -> SignedBeaconBlock // DEPRECATED on v0.30.0

index_stateArchiveRootIndex = 26, // State Root -> slot
Expand Down Expand Up @@ -74,42 +61,19 @@ export enum Bucket {
// lightClient_bestLightClientUpdate = 55, // SyncPeriod -> LightClientUpdate // DEPRECATED on v1.5.0
lightClient_bestLightClientUpdate = 56, // SyncPeriod -> [Slot, LightClientUpdate]

validator_metaData = 41,

backfilled_ranges = 42, // Backfilled From to To, inclusive of both From, To
}

export enum Key {
chainHeight = 0,

latestState = 1,
finalizedState = 2,
justifiedState = 3,

finalizedBlock = 4,
justifiedBlock = 5,
}

export const uintLen = 8;

/**
* Prepend a bucket to a key
*/
export function encodeKey(bucket: Bucket, key: Uint8Array | string | number | bigint): Uint8Array {
let buf;
const prefixLength = BUCKET_LENGTH;
//all keys are writen with prefixLength offet
if (typeof key === "string") {
buf = Buffer.alloc(key.length + prefixLength);
buf.write(key, prefixLength);
} else if (typeof key === "number" || typeof key === "bigint") {
buf = Buffer.alloc(uintLen + prefixLength);
intToBytes(BigInt(key), uintLen, "be").copy(buf, prefixLength);
} else {
buf = Buffer.alloc(key.length + prefixLength);
buf.set(key, prefixLength);
export function getBucketNameByValue<T extends Bucket>(enumValue: T): keyof typeof Bucket {
const keys = Object.keys(Bucket).filter((x) => {
if (isNaN(parseInt(x))) {
return Bucket[x as keyof typeof Bucket] == enumValue;
} else {
return false;
}
}) as (keyof typeof Bucket)[];
if (keys.length > 0) {
return keys[0];
}
//bucket prefix on position 0
buf.set(intToBytes(bucket, BUCKET_LENGTH, "le"), 0);
return buf;
throw new Error("Missing bucket for value " + enumValue);
}
6 changes: 4 additions & 2 deletions packages/beacon-node/src/db/repositories/attesterSlashing.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {phase0, ssz, ValidatorIndex} from "@lodestar/types";
import {ChainForkConfig} from "@lodestar/config";
import {Db, Bucket, Repository} from "@lodestar/db";
import {Db, Repository} from "@lodestar/db";
import {Bucket, getBucketNameByValue} from "../buckets.js";

/**
* AttesterSlashing indexed by root
Expand All @@ -10,7 +11,8 @@ import {Db, Bucket, Repository} from "@lodestar/db";
*/
export class AttesterSlashingRepository extends Repository<Uint8Array, phase0.AttesterSlashing> {
constructor(config: ChainForkConfig, db: Db) {
super(config, db, Bucket.phase0_attesterSlashing, ssz.phase0.AttesterSlashing);
const bucket = Bucket.phase0_attesterSlashing;
super(config, db, bucket, ssz.phase0.AttesterSlashing, getBucketNameByValue(bucket));
}

async hasAll(attesterIndices: ValidatorIndex[] = []): Promise<boolean> {
Expand Down
6 changes: 4 additions & 2 deletions packages/beacon-node/src/db/repositories/backfilledRanges.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {ChainForkConfig} from "@lodestar/config";
import {Slot, ssz} from "@lodestar/types";
import {DatabaseController, Bucket, Repository} from "@lodestar/db";
import {DatabaseController, Repository} from "@lodestar/db";
import {bytesToInt} from "@lodestar/utils";
import {Bucket, getBucketNameByValue} from "../buckets.js";

/**
* Slot to slot ranges that ensure that block range is fully backfilled
Expand All @@ -14,7 +15,8 @@ import {bytesToInt} from "@lodestar/utils";
*/
export class BackfilledRanges extends Repository<Slot, Slot> {
constructor(config: ChainForkConfig, db: DatabaseController<Uint8Array, Uint8Array>) {
super(config, db, Bucket.backfilled_ranges, ssz.Slot);
const bucket = Bucket.backfilled_ranges;
super(config, db, bucket, ssz.Slot, getBucketNameByValue(bucket));
}

decodeKey(data: Buffer): number {
Expand Down
6 changes: 4 additions & 2 deletions packages/beacon-node/src/db/repositories/blobSidecars.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {ChainForkConfig} from "@lodestar/config";
import {Bucket, Db, Repository} from "@lodestar/db";
import {Db, Repository} from "@lodestar/db";
import {ssz} from "@lodestar/types";
import {ValueOf, ContainerType} from "@chainsafe/ssz";
import {Bucket, getBucketNameByValue} from "../buckets.js";

export const blobSidecarsWrapperSsz = new ContainerType(
{
Expand All @@ -25,7 +26,8 @@ export const BLOBSIDECAR_FIXED_SIZE = 131256;
*/
export class BlobSidecarsRepository extends Repository<Uint8Array, BlobSidecarsWrapper> {
constructor(config: ChainForkConfig, db: Db) {
super(config, db, Bucket.allForks_blobSidecars, blobSidecarsWrapperSsz);
const bucket = Bucket.allForks_blobSidecars;
super(config, db, bucket, blobSidecarsWrapperSsz, getBucketNameByValue(bucket));
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {ChainForkConfig} from "@lodestar/config";
import {Bucket, Db, Repository} from "@lodestar/db";
import {Db, Repository} from "@lodestar/db";
import {Slot} from "@lodestar/types";
import {bytesToInt} from "@lodestar/utils";

import {Bucket, getBucketNameByValue} from "../buckets.js";
import {blobSidecarsWrapperSsz, BlobSidecarsWrapper} from "./blobSidecars.js";

/**
Expand All @@ -12,7 +12,8 @@ import {blobSidecarsWrapperSsz, BlobSidecarsWrapper} from "./blobSidecars.js";
*/
export class BlobSidecarsArchiveRepository extends Repository<Slot, BlobSidecarsWrapper> {
constructor(config: ChainForkConfig, db: Db) {
super(config, db, Bucket.allForks_blobSidecarsArchive, blobSidecarsWrapperSsz);
const bucket = Bucket.allForks_blobSidecarsArchive;
super(config, db, bucket, blobSidecarsWrapperSsz, getBucketNameByValue(bucket));
}

// Handle key as slot
Expand Down
6 changes: 4 additions & 2 deletions packages/beacon-node/src/db/repositories/blobsSidecar.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {ChainForkConfig} from "@lodestar/config";
import {Bucket, Db, Repository} from "@lodestar/db";
import {Db, Repository} from "@lodestar/db";
import {deneb, ssz} from "@lodestar/types";
import {Bucket, getBucketNameByValue} from "../buckets.js";

/**
* BlobsSidecar by block root (= hash_tree_root(SignedBeaconBlockAndBlobsSidecar.beacon_block.message))
Expand All @@ -9,7 +10,8 @@ import {deneb, ssz} from "@lodestar/types";
*/
export class BlobsSidecarRepository extends Repository<Uint8Array, deneb.BlobsSidecar> {
constructor(config: ChainForkConfig, db: Db) {
super(config, db, Bucket.allForks_blobsSidecar, ssz.deneb.BlobsSidecar);
const bucket = Bucket.allForks_blobsSidecar;
super(config, db, bucket, ssz.deneb.BlobsSidecar, getBucketNameByValue(bucket));
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {ChainForkConfig} from "@lodestar/config";
import {Db, Repository, KeyValue, FilterOptions, Bucket} from "@lodestar/db";
import {Db, Repository, KeyValue, FilterOptions} from "@lodestar/db";
import {Slot, Root, ssz, deneb} from "@lodestar/types";
import {bytesToInt} from "@lodestar/utils";
import {Bucket, getBucketNameByValue} from "../buckets.js";

export interface BlockFilterOptions extends FilterOptions<Slot> {
step?: number;
Expand All @@ -18,7 +19,8 @@ export type BlockArchiveBatchPutBinaryItem = KeyValue<Slot, Uint8Array> & {
*/
export class BlobsSidecarArchiveRepository extends Repository<Slot, deneb.BlobsSidecar> {
constructor(config: ChainForkConfig, db: Db) {
super(config, db, Bucket.allForks_blobsSidecarArchive, ssz.deneb.BlobsSidecar);
const bucket = Bucket.allForks_blobsSidecarArchive;
super(config, db, bucket, ssz.deneb.BlobsSidecar, getBucketNameByValue(bucket));
}

// Handle key as slot
Expand Down
6 changes: 4 additions & 2 deletions packages/beacon-node/src/db/repositories/block.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {ChainForkConfig} from "@lodestar/config";
import {Bucket, Db, Repository} from "@lodestar/db";
import {Db, Repository} from "@lodestar/db";
import {allForks, ssz} from "@lodestar/types";
import {getSignedBlockTypeFromBytes} from "../../util/multifork.js";
import {Bucket, getBucketNameByValue} from "../buckets.js";

/**
* Blocks by root
Expand All @@ -10,8 +11,9 @@ import {getSignedBlockTypeFromBytes} from "../../util/multifork.js";
*/
export class BlockRepository extends Repository<Uint8Array, allForks.SignedBeaconBlock> {
constructor(config: ChainForkConfig, db: Db) {
const bucket = Bucket.allForks_block;
const type = ssz.phase0.SignedBeaconBlock; // Pick some type but won't be used
super(config, db, Bucket.allForks_block, type);
super(config, db, bucket, type, getBucketNameByValue(bucket));
}

/**
Expand Down
6 changes: 4 additions & 2 deletions packages/beacon-node/src/db/repositories/blockArchive.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import all from "it-all";
import {ChainForkConfig} from "@lodestar/config";
import {Db, Repository, KeyValue, FilterOptions, Bucket} from "@lodestar/db";
import {Db, Repository, KeyValue, FilterOptions} from "@lodestar/db";
import {Slot, Root, allForks, ssz} from "@lodestar/types";
import {bytesToInt} from "@lodestar/utils";
import {getSignedBlockTypeFromBytes} from "../../util/multifork.js";
import {Bucket, getBucketNameByValue} from "../buckets.js";
import {getRootIndexKey, getParentRootIndexKey} from "./blockArchiveIndex.js";
import {deleteParentRootIndex, deleteRootIndex, storeParentRootIndex, storeRootIndex} from "./blockArchiveIndex.js";

Expand All @@ -22,8 +23,9 @@ export type BlockArchiveBatchPutBinaryItem = KeyValue<Slot, Uint8Array> & {
*/
export class BlockArchiveRepository extends Repository<Slot, allForks.SignedBeaconBlock> {
constructor(config: ChainForkConfig, db: Db) {
const bucket = Bucket.allForks_blockArchive;
const type = ssz.phase0.SignedBeaconBlock; // Pick some type but won't be used
super(config, db, Bucket.allForks_blockArchive, type);
super(config, db, bucket, type, getBucketNameByValue(bucket));
}

// Overrides for multi-fork
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {Db, encodeKey, Bucket} from "@lodestar/db";
import {Db, encodeKey} from "@lodestar/db";
import {Slot, Root, allForks, ssz} from "@lodestar/types";
import {intToBytes} from "@lodestar/utils";
import {Bucket} from "../buckets.js";

export async function storeRootIndex(db: Db, slot: Slot, blockRoot: Root): Promise<void> {
return db.put(getRootIndexKey(blockRoot), intToBytes(slot, 8, "be"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import {ValidatorIndex} from "@lodestar/types";
import {ChainForkConfig} from "@lodestar/config";
import {Db, Bucket, Repository} from "@lodestar/db";
import {Db, Repository} from "@lodestar/db";
import {SignedBLSToExecutionChangeVersioned, signedBLSToExecutionChangeVersionedType} from "../../util/types.js";
import {Bucket, getBucketNameByValue} from "../buckets.js";

export class BLSToExecutionChangeRepository extends Repository<ValidatorIndex, SignedBLSToExecutionChangeVersioned> {
constructor(config: ChainForkConfig, db: Db) {
super(config, db, Bucket.capella_blsToExecutionChange, signedBLSToExecutionChangeVersionedType);
const bucket = Bucket.capella_blsToExecutionChange;
super(config, db, bucket, signedBLSToExecutionChangeVersionedType, getBucketNameByValue(bucket));
}

getId(value: SignedBLSToExecutionChangeVersioned): ValidatorIndex {
Expand Down
6 changes: 4 additions & 2 deletions packages/beacon-node/src/db/repositories/depositDataRoot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import {ByteVectorType, CompositeViewDU, ListCompositeType} from "@chainsafe/ssz
import {Root, ssz} from "@lodestar/types";
import {ChainForkConfig} from "@lodestar/config";
import {bytesToInt} from "@lodestar/utils";
import {Db, Bucket, Repository, KeyValue} from "@lodestar/db";
import {Db, Repository, KeyValue} from "@lodestar/db";
import {Bucket, getBucketNameByValue} from "../buckets.js";

// TODO: Review where is best to put this type
export type DepositTree = CompositeViewDU<ListCompositeType<ByteVectorType>>;
Expand All @@ -11,7 +12,8 @@ export class DepositDataRootRepository extends Repository<number, Root> {
private depositRootTree?: DepositTree;

constructor(config: ChainForkConfig, db: Db) {
super(config, db, Bucket.index_depositDataRoot, ssz.Root);
const bucket = Bucket.index_depositDataRoot;
super(config, db, bucket, ssz.Root, getBucketNameByValue(bucket));
}

decodeKey(data: Buffer): number {
Expand Down
6 changes: 4 additions & 2 deletions packages/beacon-node/src/db/repositories/depositEvent.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import {ChainForkConfig} from "@lodestar/config";
import {phase0, ssz} from "@lodestar/types";
import {Db, Bucket, Repository} from "@lodestar/db";
import {Db, Repository} from "@lodestar/db";
import {Bucket, getBucketNameByValue} from "../buckets.js";

/**
* DepositData indexed by deposit index
* Removed when included on chain or old
*/
export class DepositEventRepository extends Repository<number, phase0.DepositEvent> {
constructor(config: ChainForkConfig, db: Db) {
super(config, db, Bucket.phase0_depositEvent, ssz.phase0.DepositEvent);
const bucket = Bucket.phase0_depositEvent;
super(config, db, bucket, ssz.phase0.DepositEvent, getBucketNameByValue(bucket));
}

async deleteOld(depositCount: number): Promise<void> {
Expand Down
6 changes: 4 additions & 2 deletions packages/beacon-node/src/db/repositories/eth1Data.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import {phase0, ssz} from "@lodestar/types";
import {ChainForkConfig} from "@lodestar/config";
import {bytesToInt} from "@lodestar/utils";
import {Db, Bucket, Repository} from "@lodestar/db";
import {Db, Repository} from "@lodestar/db";
import {Bucket, getBucketNameByValue} from "../buckets.js";

export class Eth1DataRepository extends Repository<number, phase0.Eth1DataOrdered> {
constructor(config: ChainForkConfig, db: Db) {
super(config, db, Bucket.phase0_eth1Data, ssz.phase0.Eth1DataOrdered);
const bucket = Bucket.phase0_eth1Data;
super(config, db, bucket, ssz.phase0.Eth1DataOrdered, getBucketNameByValue(bucket));
}

decodeKey(data: Buffer): number {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {ChainForkConfig} from "@lodestar/config";
import {Bucket, DatabaseController, Repository} from "@lodestar/db";
import {DatabaseController, Repository} from "@lodestar/db";
import {ssz, SyncPeriod, allForks} from "@lodestar/types";
import {Bucket, getBucketNameByValue} from "../buckets.js";

const SLOT_BYTE_COUNT = 8;

Expand All @@ -12,7 +13,8 @@ const SLOT_BYTE_COUNT = 8;
export class BestLightClientUpdateRepository extends Repository<SyncPeriod, allForks.LightClientUpdate> {
constructor(config: ChainForkConfig, db: DatabaseController<Uint8Array, Uint8Array>) {
// Pick some type but won't be used
super(config, db, Bucket.lightClient_bestLightClientUpdate, ssz.altair.LightClientUpdate);
const bucket = Bucket.lightClient_bestLightClientUpdate;
super(config, db, bucket, ssz.altair.LightClientUpdate, getBucketNameByValue(bucket));
}

// Overrides for multi-fork
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {ChainForkConfig} from "@lodestar/config";
import {Bucket, DatabaseController, Repository} from "@lodestar/db";
import {DatabaseController, Repository} from "@lodestar/db";
import {ssz, allForks} from "@lodestar/types";

import {Bucket, getBucketNameByValue} from "../buckets.js";
import {getLightClientHeaderTypeFromBytes} from "../../util/multifork.js";

/**
Expand All @@ -13,7 +13,8 @@ import {getLightClientHeaderTypeFromBytes} from "../../util/multifork.js";
export class CheckpointHeaderRepository extends Repository<Uint8Array, allForks.LightClientHeader> {
constructor(config: ChainForkConfig, db: DatabaseController<Uint8Array, Uint8Array>) {
// Pick some type but won't be used
super(config, db, Bucket.lightClient_checkpointHeader, ssz.altair.LightClientHeader);
const bucket = Bucket.lightClient_checkpointHeader;
super(config, db, bucket, ssz.altair.LightClientHeader, getBucketNameByValue(bucket));
}

// Overrides for multi-fork
Expand Down
Loading

0 comments on commit 78bb300

Please sign in to comment.