Skip to content

Commit

Permalink
Merge 1d66a43 into db9450b
Browse files Browse the repository at this point in the history
  • Loading branch information
dapplion committed Aug 15, 2022
2 parents db9450b + 1d66a43 commit 3cb8e39
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 3 deletions.
21 changes: 21 additions & 0 deletions packages/api/src/beacon/routes/lodestar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@ export type Api = {

/** Dump Discv5 Kad values */
discv5GetKadValues(): Promise<{data: string[]}>;

/**
* Dump level-db entry keys for a given Bucket declared in code, or for all buckets.
* @param bucket must be the string name of a bucket entry: `allForks_blockArchive`
*/
dumpDbBucketKeys(bucket: string): Promise<string[]>;

/** Return all entries in the StateArchive index with bucket index_stateArchiveRootIndex */
dumpDbStateIndex(): Promise<{root: RootHex; slot: Slot}[]>;
};

/**
Expand All @@ -111,6 +120,8 @@ export const routesData: RoutesData<Api> = {
disconnectPeer: {url: "/eth/v1/lodestar/disconnect_peer", method: "POST"},
getPeers: {url: "/eth/v1/lodestar/peers", method: "GET"},
discv5GetKadValues: {url: "/eth/v1/debug/discv5-kad-values", method: "GET"},
dumpDbBucketKeys: {url: "/eth/v1/debug/dump-db-bucket-keys/:bucket", method: "GET"},
dumpDbStateIndex: {url: "/eth/v1/debug/dump-db-state-index", method: "GET"},
};

export type ReqTypes = {
Expand All @@ -129,6 +140,8 @@ export type ReqTypes = {
disconnectPeer: {query: {peerId: string}};
getPeers: {query: {state?: PeerState[]; direction?: PeerDirection[]}};
discv5GetKadValues: ReqEmpty;
dumpDbBucketKeys: {params: {bucket: string}};
dumpDbStateIndex: ReqEmpty;
};

export function getReqSerializers(): ReqSerializers<Api, ReqTypes> {
Expand Down Expand Up @@ -168,6 +181,12 @@ export function getReqSerializers(): ReqSerializers<Api, ReqTypes> {
schema: {query: {state: Schema.StringArray, direction: Schema.StringArray}},
},
discv5GetKadValues: reqEmpty,
dumpDbBucketKeys: {
writeReq: (bucket) => ({params: {bucket}}),
parseReq: ({params}) => [params.bucket],
schema: {params: {bucket: Schema.String}},
},
dumpDbStateIndex: reqEmpty,
};
}

Expand All @@ -185,5 +204,7 @@ export function getReturnTypes(): ReturnTypes<Api> {
getGossipPeerScoreStats: jsonType("snake"),
getPeers: jsonType("snake"),
discv5GetKadValues: jsonType("snake"),
dumpDbBucketKeys: sameType(),
dumpDbStateIndex: sameType(),
};
}
36 changes: 35 additions & 1 deletion packages/beacon-node/src/api/impl/lodestar/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import PeerId from "peer-id";
import {Multiaddr} from "multiaddr";
import {routes} from "@lodestar/api";
import {Bucket, Repository} from "@lodestar/db";
import {toHex} from "@lodestar/utils";
import {getLatestWeakSubjectivityCheckpointEpoch} from "@lodestar/state-transition";
import {toHexString} from "@chainsafe/ssz";
import {IChainForkConfig} from "@lodestar/config";
import {ssz} from "@lodestar/types";
import {BeaconChain} from "../../../chain/index.js";
import {QueuedStateRegenerator, RegenRequest} from "../../../chain/regen/index.js";
import {GossipType} from "../../../network/index.js";
import {IBeaconDb} from "../../../db/interface.js";
import {ApiModules} from "../types.js";
import {formatNodePeer} from "../node/utils.js";

export function getLodestarApi({
chain,
config,
db,
network,
sync,
}: Pick<ApiModules, "chain" | "config" | "network" | "sync">): routes.lodestar.Api {
}: Pick<ApiModules, "chain" | "config" | "db" | "network" | "sync">): routes.lodestar.Api {
let writingHeapdump = false;

return {
Expand Down Expand Up @@ -153,6 +157,23 @@ export function getLodestarApi({
data: network.discv5?.kadValues().map((enr) => enr.encodeTxt()) ?? [],
};
},

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) {
return stringifyKeys(await repo.keys());
}
}
}

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

async dumpDbStateIndex() {
return db.stateArchive.dumpRootIndexEntries();
},
};
}

Expand Down Expand Up @@ -181,3 +202,16 @@ function regenRequestToJson(config: IChainForkConfig, 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) {
return toHex(key);
} else {
return `${key}`;
}
});
}
15 changes: 13 additions & 2 deletions packages/beacon-node/src/db/repositories/stateArchive.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {BeaconStateAllForks} from "@lodestar/state-transition";
import {Epoch, Root, Slot, ssz} from "@lodestar/types";
import {Epoch, Root, RootHex, Slot, ssz} from "@lodestar/types";
import {IChainForkConfig} from "@lodestar/config";
import {bytesToInt} from "@lodestar/utils";
import {bytesToInt, toHex} from "@lodestar/utils";
import {Db, Bucket, Repository} from "@lodestar/db";
import {getStateTypeFromBytes} from "../../util/multifork.js";
import {getRootIndexKey, storeRootIndex} from "./stateArchiveIndex.js";
Expand Down Expand Up @@ -50,6 +50,17 @@ export class StateArchiveRepository extends Repository<Slot, BeaconStateAllForks
return null;
}

async dumpRootIndexEntries(): Promise<{root: RootHex; slot: Slot}[]> {
const entries = await this.db.entries({
lte: getRootIndexKey(Buffer.alloc(32, 0xff)),
gte: getRootIndexKey(Buffer.alloc(32, 0x00)),
});
return entries.map((entry) => ({
root: toHex(entry.key),
slot: bytesToInt(entry.value, "be"),
}));
}

private async getSlotByRoot(root: Root): Promise<Slot | null> {
const value = await this.db.get(getRootIndexKey(root));
return value && bytesToInt(value, "be");
Expand Down

0 comments on commit 3cb8e39

Please sign in to comment.