Files
lodestar/packages/light-client/test/lightclientApiServer.ts
Lion - dapplion de1e1210b4 Separate lodestar-api package (#2568)
* Refactor REST API definitions

* Simplify REST testing

* Bump to fastify 3.x.x

* Return {} in fastify handler to trigger send

* Move REST server to lodestar-api

* Improve REST tests

* Add eventstream test

* Clean up

* Bump versions

* Fix query string format

* Add extra debug routes

* Consume lodestar-api package

* Fix tests

* Revert package.json change

* Add HttpClient test

* Destroy all active requests immediately on close

* Fastify hook handlers must resolve

* Fix fastify hook config args

* Fix parsing of ValidatorId

* Remove e2e script test

* Add docs

* Simplify req declarations

* Review PR

* Update license
2021-05-27 12:17:49 -05:00

87 lines
2.6 KiB
TypeScript

import fastify, {FastifyInstance} from "fastify";
import {Api} from "@chainsafe/lodestar-api";
import {registerRoutes} from "@chainsafe/lodestar-api/server";
import {ILogger} from "@chainsafe/lodestar-utils";
import fastifyCors from "fastify-cors";
import querystring from "querystring";
import {IBeaconConfig} from "@chainsafe/lodestar-config";
import {LightClientUpdater} from "../src/server/LightClientUpdater";
import {TreeBacked} from "@chainsafe/ssz";
import {altair} from "@chainsafe/lodestar-types";
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
const maxPeriodsPerRequest = 128;
export type IStateRegen = {
getStateByRoot(stateRoot: string): Promise<TreeBacked<altair.BeaconState>>;
};
export type ServerOpts = {
port: number;
host: string;
};
export type ServerModules = {
config: IBeaconConfig;
lightClientUpdater: LightClientUpdater;
logger: ILogger;
stateRegen: IStateRegen;
};
export async function startLightclientApiServer(opts: ServerOpts, modules: ServerModules): Promise<FastifyInstance> {
const server = fastify({
logger: false,
ajv: {customOptions: {coerceTypes: "array"}},
querystringParser: querystring.parse,
});
const lightclientApi = getLightclientServerApi(modules);
registerRoutes(server, modules.config, {lightclient: lightclientApi} as Api, ["lightclient"]);
void server.register(fastifyCors, {origin: "*"});
await server.listen(opts.port, opts.host);
return server;
}
function getLightclientServerApi(modules: ServerModules): Api["lightclient"] {
const {config, lightClientUpdater, stateRegen} = modules;
return {
async getStateProof(stateId, paths) {
const state = await stateRegen.getStateByRoot(stateId);
const tree = config.types.altair.BeaconState.createTreeBackedFromStruct(state);
return {data: tree.createProof(paths)};
},
async getBestUpdates(from, to) {
const periods = linspace(from, to);
if (periods.length > maxPeriodsPerRequest) {
throw Error("Too many periods requested");
}
return {data: await lightClientUpdater.getBestUpdates(periods)};
},
async getLatestUpdateFinalized() {
const data = await lightClientUpdater.getLatestUpdateFinalized();
if (!data) throw Error("No update available");
return {data};
},
async getLatestUpdateNonFinalized() {
const data = await lightClientUpdater.getLatestUpdateNonFinalized();
if (!data) throw Error("No update available");
return {data};
},
};
}
function linspace(from: number, to: number): number[] {
const arr: number[] = [];
for (let i = from; i <= to; i++) {
arr.push(i);
}
return arr;
}