@lodestar/api
Version:
A Typescript REST client for the Ethereum Consensus API
285 lines • 11.9 kB
JavaScript
import { ContainerType } from "@chainsafe/ssz";
import { ArrayOf, ssz, } from "@lodestar/types";
import { EmptyRequestCodec, EmptyResponseCodec, JsonOnlyResponseCodec, WithVersion, } from "../../utils/codecs.js";
import { toForkName } from "../../utils/fork.js";
import { fromHeaders } from "../../utils/headers.js";
import { Schema } from "../../utils/index.js";
import { ExecutionOptimisticFinalizedAndVersionCodec, MetaHeader, VersionCodec, } from "../../utils/metadata.js";
const HistoricalSummariesResponseType = new ContainerType({
slot: ssz.Slot,
historicalSummaries: ssz.capella.HistoricalSummaries,
proof: ArrayOf(ssz.Bytes8),
}, { jsonCase: "eth2" });
export function getDefinitions(config) {
function assertBlocksMatchFork(signedBlocks, expectedFork) {
for (const block of signedBlocks) {
const blockFork = config.getForkName(block.message.slot);
if (blockFork !== expectedFork) {
throw new Error(`Block at slot ${block.message.slot} is from fork ${blockFork}, expected ${expectedFork}`);
}
}
}
return {
writeHeapdump: {
url: "/eth/v1/lodestar/write_heapdump",
method: "POST",
req: {
writeReq: ({ thread, dirpath }) => ({ query: { thread, dirpath } }),
parseReq: ({ query }) => ({ thread: query.thread, dirpath: query.dirpath }),
schema: { query: { thread: Schema.String, dirpath: Schema.String } },
},
resp: JsonOnlyResponseCodec,
},
writeProfile: {
url: "/eth/v1/lodestar/write_profile",
method: "POST",
req: {
writeReq: ({ thread, duration, dirpath }) => ({ query: { thread, duration, dirpath } }),
parseReq: ({ query }) => ({ thread: query.thread, duration: query.duration, dirpath: query.dirpath }),
schema: { query: { thread: Schema.String, duration: Schema.Uint, dirpath: Schema.String } },
},
resp: JsonOnlyResponseCodec,
},
getLatestWeakSubjectivityCheckpointEpoch: {
url: "/eth/v1/lodestar/ws_epoch",
method: "GET",
req: EmptyRequestCodec,
resp: JsonOnlyResponseCodec,
},
getSyncChainsDebugState: {
url: "/eth/v1/lodestar/sync_chains_debug_state",
method: "GET",
req: EmptyRequestCodec,
resp: JsonOnlyResponseCodec,
},
getGossipQueueItems: {
url: "/eth/v1/lodestar/gossip_queue_items/:gossipType",
method: "GET",
req: {
writeReq: ({ gossipType }) => ({ params: { gossipType } }),
parseReq: ({ params }) => ({ gossipType: params.gossipType }),
schema: { params: { gossipType: Schema.StringRequired } },
},
resp: JsonOnlyResponseCodec,
},
getRegenQueueItems: {
url: "/eth/v1/lodestar/regen_queue_items",
method: "GET",
req: EmptyRequestCodec,
resp: JsonOnlyResponseCodec,
},
getBlockProcessorQueueItems: {
url: "/eth/v1/lodestar/block_processor_queue_items",
method: "GET",
req: EmptyRequestCodec,
resp: JsonOnlyResponseCodec,
},
getStateCacheItems: {
url: "/eth/v1/lodestar/state_cache_items",
method: "GET",
req: EmptyRequestCodec,
resp: JsonOnlyResponseCodec,
},
getGossipPeerScoreStats: {
url: "/eth/v1/lodestar/gossip_peer_score_stats",
method: "GET",
req: EmptyRequestCodec,
resp: JsonOnlyResponseCodec,
},
getLodestarPeerScoreStats: {
url: "/eth/v1/lodestar/lodestar_peer_score_stats",
method: "GET",
req: EmptyRequestCodec,
resp: JsonOnlyResponseCodec,
},
runGC: {
url: "/eth/v1/lodestar/gc",
method: "POST",
req: EmptyRequestCodec,
resp: EmptyResponseCodec,
},
dropStateCache: {
url: "/eth/v1/lodestar/drop_state_cache",
method: "POST",
req: EmptyRequestCodec,
resp: EmptyResponseCodec,
},
connectPeer: {
url: "/eth/v1/lodestar/connect_peer",
method: "POST",
req: {
writeReq: ({ peerId, multiaddrs }) => ({ query: { peerId, multiaddr: multiaddrs } }),
parseReq: ({ query }) => ({ peerId: query.peerId, multiaddrs: query.multiaddr }),
schema: { query: { peerId: Schema.StringRequired, multiaddr: Schema.StringArray } },
},
resp: EmptyResponseCodec,
},
disconnectPeer: {
url: "/eth/v1/lodestar/disconnect_peer",
method: "POST",
req: {
writeReq: ({ peerId }) => ({ query: { peerId } }),
parseReq: ({ query }) => ({ peerId: query.peerId }),
schema: { query: { peerId: Schema.StringRequired } },
},
resp: EmptyResponseCodec,
},
addDirectPeer: {
url: "/eth/v1/lodestar/direct_peers",
method: "POST",
req: {
writeReq: ({ peer }) => ({ query: { peer } }),
parseReq: ({ query }) => ({ peer: query.peer }),
schema: { query: { peer: Schema.StringRequired } },
},
resp: JsonOnlyResponseCodec,
},
removeDirectPeer: {
url: "/eth/v1/lodestar/direct_peers",
method: "DELETE",
req: {
writeReq: ({ peerId }) => ({ query: { peerId } }),
parseReq: ({ query }) => ({ peerId: query.peerId }),
schema: { query: { peerId: Schema.StringRequired } },
},
resp: JsonOnlyResponseCodec,
},
getDirectPeers: {
url: "/eth/v1/lodestar/direct_peers",
method: "GET",
req: EmptyRequestCodec,
resp: JsonOnlyResponseCodec,
},
getPeers: {
url: "/eth/v1/lodestar/peers",
method: "GET",
req: {
writeReq: ({ state, direction }) => ({ query: { state, direction } }),
parseReq: ({ query }) => ({ state: query.state, direction: query.direction }),
schema: { query: { state: Schema.StringArray, direction: Schema.StringArray } },
},
resp: JsonOnlyResponseCodec,
},
getBlacklistedBlocks: {
url: "/eth/v1/lodestar/blacklisted_blocks",
method: "GET",
req: EmptyRequestCodec,
resp: JsonOnlyResponseCodec,
},
getHistoricalSummaries: {
url: "/eth/v1/lodestar/states/{state_id}/historical_summaries",
method: "GET",
req: {
writeReq: ({ stateId }) => ({ params: { state_id: stateId.toString() } }),
parseReq: ({ params }) => ({ stateId: params.state_id }),
schema: {
params: { state_id: Schema.StringRequired },
},
},
resp: {
data: HistoricalSummariesResponseType,
meta: ExecutionOptimisticFinalizedAndVersionCodec,
},
},
// TODO GLOAS: this endpoint needs to be updated because post-gloas there could be two variants of the persisted checkpoint state (empty or full).
// Either add a an additional parameter `payloadPresent`, or return one or both variants of state.
getPersistedCheckpointState: {
url: "/eth/v1/lodestar/persisted_checkpoint_state",
method: "GET",
req: {
writeReq: ({ checkpointId }) => ({ query: { checkpoint_id: checkpointId } }),
parseReq: ({ query }) => ({ checkpointId: query.checkpoint_id }),
schema: {
query: { checkpoint_id: Schema.String },
},
},
resp: {
data: WithVersion((fork) => ssz[fork].BeaconState),
meta: VersionCodec,
},
init: {
// Default timeout is not sufficient to download state
timeoutMs: 5 * 60 * 1000,
},
},
getMonitoredValidatorIndices: {
url: "/eth/v1/lodestar/monitored_validators",
method: "GET",
req: EmptyRequestCodec,
resp: JsonOnlyResponseCodec,
},
discv5GetKadValues: {
url: "/eth/v1/debug/discv5_kad_values",
method: "GET",
req: EmptyRequestCodec,
resp: JsonOnlyResponseCodec,
},
dumpDbBucketKeys: {
url: "/eth/v1/debug/dump_db_bucket_keys/:bucket",
method: "GET",
req: {
writeReq: ({ bucket }) => ({ params: { bucket } }),
parseReq: ({ params }) => ({ bucket: params.bucket }),
schema: { params: { bucket: Schema.String } },
},
resp: JsonOnlyResponseCodec,
},
dumpDbStateIndex: {
url: "/eth/v1/debug/dump_db_state_index",
method: "GET",
req: EmptyRequestCodec,
resp: JsonOnlyResponseCodec,
},
getCustodyInfo: {
url: "/eth/v1/lodestar/custody_info",
method: "GET",
req: EmptyRequestCodec,
resp: JsonOnlyResponseCodec,
},
getAttesterSlashingsFromBlocks: {
url: "/eth/v1/lodestar/blocks/attester_slashings",
method: "POST",
req: {
writeReqJson: ({ signedBlocks }) => {
if (signedBlocks.length === 0)
throw new Error("No blocks provided.");
const fork = config.getForkName(signedBlocks[0].message.slot);
return {
body: ArrayOf(ssz[fork].SignedBeaconBlock).toJson(signedBlocks),
headers: { [MetaHeader.Version]: fork },
};
},
parseReqJson: ({ body, headers }) => {
const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
const signedBlocks = ArrayOf(ssz[fork].SignedBeaconBlock).fromJson(body);
assertBlocksMatchFork(signedBlocks, fork);
return { signedBlocks };
},
writeReqSsz: ({ signedBlocks }) => {
if (signedBlocks.length === 0)
throw new Error("No blocks provided.");
const fork = config.getForkName(signedBlocks[0].message.slot);
return {
body: ArrayOf(ssz[fork].SignedBeaconBlock).serialize(signedBlocks),
headers: { [MetaHeader.Version]: fork },
};
},
parseReqSsz: ({ body, headers }) => {
const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
const signedBlocks = ArrayOf(ssz[fork].SignedBeaconBlock).deserialize(body);
assertBlocksMatchFork(signedBlocks, fork);
return { signedBlocks };
},
schema: {
body: Schema.ObjectArray,
headers: { [MetaHeader.Version]: Schema.String },
},
},
resp: {
data: WithVersion((fork) => ArrayOf(ssz[fork].AttesterSlashing)),
meta: VersionCodec,
},
},
};
}
//# sourceMappingURL=lodestar.js.map