UNPKG

@lodestar/beacon-node

Version:

A Typescript implementation of the beacon chain

110 lines (94 loc) 3.21 kB
import {routes} from "@lodestar/api"; import {ApplicationMethods} from "@lodestar/api/server"; import {ClientCode, ClientVersion} from "../../../execution/index.js"; import {getLodestarClientVersion} from "../../../util/metadata.js"; import {ApiOptions} from "../../options.js"; import {ApiError} from "../errors.js"; import {ApiModules} from "../types.js"; export function getNodeApi( opts: ApiOptions, {network, sync, chain}: Pick<ApiModules, "network" | "sync" | "chain"> ): ApplicationMethods<routes.node.Endpoints> { return { async getNetworkIdentity() { return { data: await network.getNetworkIdentity(), }; }, async getPeer({peerId}) { const peer = await network.dumpPeer(peerId); if (!peer) { throw new ApiError(404, "Node has not seen this peer"); } return {data: peer}; }, async getPeers({state, direction}) { const peers = (await network.dumpPeers()).filter( (nodePeer) => (!state || state.length === 0 || state.includes(nodePeer.state)) && (!direction || direction.length === 0 || (nodePeer.direction && direction.includes(nodePeer.direction))) ); return { data: peers, meta: {count: peers.length}, }; }, async getPeerCount() { // TODO: Implement disconnect count with on-disk persistence const data = { disconnected: 0, connecting: 0, connected: 0, disconnecting: 0, }; for (const peer of await network.dumpPeers()) { data[peer.state]++; } return { data, }; }, async getNodeVersion() { return { data: { version: `Lodestar/${opts.version || "dev"}`, }, }; }, async getNodeVersionV2() { const {clientVersion} = chain.executionEngine; return { data: { beaconNode: toSpecClientVersion(getLodestarClientVersion(opts)), executionClient: clientVersion != null && clientVersion.code !== ClientCode.XX ? toSpecClientVersion(clientVersion) : undefined, }, }; }, async getSyncingStatus() { return {data: sync.getSyncStatus()}; }, async getHealth({syncingStatus}) { if (syncingStatus != null && (syncingStatus < 100 || syncingStatus > 599)) { throw new ApiError(400, `Invalid syncing status code: ${syncingStatus}`); } const {isSyncing, isOptimistic, elOffline} = sync.getSyncStatus(); if (isSyncing || isOptimistic || elOffline) { // 206: Node is syncing but can serve incomplete data return {status: syncingStatus ?? routes.node.NodeHealth.SYNCING}; } // 200: Node is ready return {status: routes.node.NodeHealth.READY}; // else { // 503: Node not initialized or having issues // NOTE: Lodestar does not start its API until fully initialized, so this status can never be served // } }, }; } /** Prefix commit with 0x as required by the beacon-APIs spec */ function toSpecClientVersion(cv: ClientVersion): routes.node.ClientVersion { return {...cv, commit: `0x${cv.commit}`}; }