diff --git a/packages/api/src/beacon/routes/lightclient.ts b/packages/api/src/beacon/routes/lightclient.ts index bbd7e9ff3864..7ce91ef7d6cf 100644 --- a/packages/api/src/beacon/routes/lightclient.ts +++ b/packages/api/src/beacon/routes/lightclient.ts @@ -24,7 +24,7 @@ export type Api = { * - Has most bits * - Oldest update */ - getUpdates( + getLightClientUpdatesByRange( startPeriod: SyncPeriod, count: number ): Promise< @@ -39,7 +39,7 @@ export type Api = { * Returns the latest optimistic head update available. Clients should use the SSE type `light_client_optimistic_update` * unless to get the very first head update after syncing, or if SSE are not supported by the server. */ - getOptimisticUpdate(): Promise< + getLightClientOptimisticUpdate(): Promise< ApiClientResponse<{ [HttpStatusCode.OK]: { version: ForkName; @@ -47,7 +47,7 @@ export type Api = { }; }> >; - getFinalityUpdate(): Promise< + getLightClientFinalityUpdate(): Promise< ApiClientResponse<{ [HttpStatusCode.OK]: { version: ForkName; @@ -60,7 +60,7 @@ export type Api = { * The trusted block root should be fetched with similar means to a weak subjectivity checkpoint. * Only block roots for checkpoints are guaranteed to be available. */ - getBootstrap(blockRoot: string): Promise< + getLightClientBootstrap(blockRoot: string): Promise< ApiClientResponse<{ [HttpStatusCode.OK]: { version: ForkName; @@ -71,7 +71,7 @@ export type Api = { /** * Returns an array of sync committee hashes based on the provided period and count */ - getCommitteeRoot( + getLightClientCommitteeRoot( startPeriod: SyncPeriod, count: number ): Promise< @@ -87,39 +87,39 @@ export type Api = { * Define javascript values for each route */ export const routesData: RoutesData = { - getUpdates: {url: "/eth/v1/beacon/light_client/updates", method: "GET"}, - getOptimisticUpdate: {url: "/eth/v1/beacon/light_client/optimistic_update", method: "GET"}, - getFinalityUpdate: {url: "/eth/v1/beacon/light_client/finality_update", method: "GET"}, - getBootstrap: {url: "/eth/v1/beacon/light_client/bootstrap/{block_root}", method: "GET"}, - getCommitteeRoot: {url: "/eth/v0/beacon/light_client/committee_root", method: "GET"}, + getLightClientUpdatesByRange: {url: "/eth/v1/beacon/light_client/updates", method: "GET"}, + getLightClientOptimisticUpdate: {url: "/eth/v1/beacon/light_client/optimistic_update", method: "GET"}, + getLightClientFinalityUpdate: {url: "/eth/v1/beacon/light_client/finality_update", method: "GET"}, + getLightClientBootstrap: {url: "/eth/v1/beacon/light_client/bootstrap/{block_root}", method: "GET"}, + getLightClientCommitteeRoot: {url: "/eth/v0/beacon/light_client/committee_root", method: "GET"}, }; /* eslint-disable @typescript-eslint/naming-convention */ export type ReqTypes = { - getUpdates: {query: {start_period: number; count: number}}; - getOptimisticUpdate: ReqEmpty; - getFinalityUpdate: ReqEmpty; - getBootstrap: {params: {block_root: string}}; - getCommitteeRoot: {query: {start_period: number; count: number}}; + getLightClientUpdatesByRange: {query: {start_period: number; count: number}}; + getLightClientOptimisticUpdate: ReqEmpty; + getLightClientFinalityUpdate: ReqEmpty; + getLightClientBootstrap: {params: {block_root: string}}; + getLightClientCommitteeRoot: {query: {start_period: number; count: number}}; }; export function getReqSerializers(): ReqSerializers { return { - getUpdates: { + getLightClientUpdatesByRange: { writeReq: (start_period, count) => ({query: {start_period, count}}), parseReq: ({query}) => [query.start_period, query.count], schema: {query: {start_period: Schema.UintRequired, count: Schema.UintRequired}}, }, - getOptimisticUpdate: reqEmpty, - getFinalityUpdate: reqEmpty, + getLightClientOptimisticUpdate: reqEmpty, + getLightClientFinalityUpdate: reqEmpty, - getBootstrap: { + getLightClientBootstrap: { writeReq: (block_root) => ({params: {block_root}}), parseReq: ({params}) => [params.block_root], schema: {params: {block_root: Schema.StringRequired}}, }, - getCommitteeRoot: { + getLightClientCommitteeRoot: { writeReq: (start_period, count) => ({query: {start_period, count}}), parseReq: ({query}) => [query.start_period, query.count], schema: {query: {start_period: Schema.UintRequired, count: Schema.UintRequired}}, @@ -128,31 +128,31 @@ export function getReqSerializers(): ReqSerializers { } export function getReturnTypes(): ReturnTypes { - // Form a TypeJson convertor for getUpdates + // Form a TypeJson convertor for getLightClientUpdatesByRange const VersionedUpdate = WithVersion((fork: ForkName) => isForkLightClient(fork) ? ssz.allForksLightClient[fork].LightClientUpdate : ssz.altair.LightClientUpdate ); - const getUpdates = { + const getLightClientUpdatesByRange = { toJson: (updates: {version: ForkName; data: allForks.LightClientUpdate}[]) => updates.map((data) => VersionedUpdate.toJson(data)), fromJson: (updates: unknown[]) => updates.map((data) => VersionedUpdate.fromJson(data)), }; return { - getUpdates, - getOptimisticUpdate: WithVersion((fork: ForkName) => + getLightClientUpdatesByRange, + getLightClientOptimisticUpdate: WithVersion((fork: ForkName) => isForkLightClient(fork) ? ssz.allForksLightClient[fork].LightClientOptimisticUpdate : ssz.altair.LightClientOptimisticUpdate ), - getFinalityUpdate: WithVersion((fork: ForkName) => + getLightClientFinalityUpdate: WithVersion((fork: ForkName) => isForkLightClient(fork) ? ssz.allForksLightClient[fork].LightClientFinalityUpdate : ssz.altair.LightClientFinalityUpdate ), - getBootstrap: WithVersion((fork: ForkName) => + getLightClientBootstrap: WithVersion((fork: ForkName) => isForkLightClient(fork) ? ssz.allForksLightClient[fork].LightClientBootstrap : ssz.altair.LightClientBootstrap ), - getCommitteeRoot: ContainerData(ArrayOf(ssz.Root)), + getLightClientCommitteeRoot: ContainerData(ArrayOf(ssz.Root)), }; } diff --git a/packages/api/test/unit/beacon/testData/lightclient.ts b/packages/api/test/unit/beacon/testData/lightclient.ts index 36947483075c..6701eedc3ba4 100644 --- a/packages/api/test/unit/beacon/testData/lightclient.ts +++ b/packages/api/test/unit/beacon/testData/lightclient.ts @@ -12,15 +12,15 @@ const header = ssz.altair.LightClientHeader.defaultValue(); const signatureSlot = ssz.Slot.defaultValue(); export const testData: GenericServerTestCases = { - getUpdates: { + getLightClientUpdatesByRange: { args: [1, 2], res: [{version: ForkName.bellatrix, data: lightClientUpdate}], }, - getOptimisticUpdate: { + getLightClientOptimisticUpdate: { args: [], res: {version: ForkName.bellatrix, data: {syncAggregate, attestedHeader: header, signatureSlot}}, }, - getFinalityUpdate: { + getLightClientFinalityUpdate: { args: [], res: { version: ForkName.bellatrix, @@ -33,7 +33,7 @@ export const testData: GenericServerTestCases = { }, }, }, - getBootstrap: { + getLightClientBootstrap: { args: [toHexString(root)], res: { version: ForkName.bellatrix, @@ -44,7 +44,7 @@ export const testData: GenericServerTestCases = { }, }, }, - getCommitteeRoot: { + getLightClientCommitteeRoot: { args: [1, 2], res: {data: [Buffer.alloc(32, 0), Buffer.alloc(32, 1)]}, }, diff --git a/packages/beacon-node/src/api/impl/lightclient/index.ts b/packages/beacon-node/src/api/impl/lightclient/index.ts index 52c6ca33c41d..811d75e4fe00 100644 --- a/packages/beacon-node/src/api/impl/lightclient/index.ts +++ b/packages/beacon-node/src/api/impl/lightclient/index.ts @@ -11,7 +11,7 @@ export function getLightclientApi({ config, }: Pick): ServerApi { return { - async getUpdates(startPeriod: SyncPeriod, count: number) { + async getLightClientUpdatesByRange(startPeriod: SyncPeriod, count: number) { const maxAllowedCount = Math.min(MAX_REQUEST_LIGHT_CLIENT_UPDATES, count); const periods = Array.from({length: maxAllowedCount}, (_ignored, i) => i + startPeriod); const updates = await Promise.all(periods.map((period) => chain.lightClientServer.getUpdate(period))); @@ -21,7 +21,7 @@ export function getLightclientApi({ })); }, - async getOptimisticUpdate() { + async getLightClientOptimisticUpdate() { const data = chain.lightClientServer.getOptimisticUpdate(); if (data === null) { throw Error("No optimistic update available"); @@ -29,7 +29,7 @@ export function getLightclientApi({ return {version: config.getForkName(data.attestedHeader.beacon.slot), data}; }, - async getFinalityUpdate() { + async getLightClientFinalityUpdate() { const data = chain.lightClientServer.getFinalityUpdate(); if (data === null) { throw Error("No finality update available"); @@ -37,12 +37,12 @@ export function getLightclientApi({ return {version: config.getForkName(data.attestedHeader.beacon.slot), data}; }, - async getBootstrap(blockRoot) { + async getLightClientBootstrap(blockRoot) { const bootstrapProof = await chain.lightClientServer.getBootstrap(fromHexString(blockRoot)); return {version: config.getForkName(bootstrapProof.header.beacon.slot), data: bootstrapProof}; }, - async getCommitteeRoot(startPeriod: SyncPeriod, count: number) { + async getLightClientCommitteeRoot(startPeriod: SyncPeriod, count: number) { const maxAllowedCount = Math.min(MAX_REQUEST_LIGHT_CLIENT_COMMITTEE_HASHES, count); const periods = Array.from({length: maxAllowedCount}, (_ignored, i) => i + startPeriod); const committeeHashes = await Promise.all( diff --git a/packages/beacon-node/test/e2e/api/impl/lightclient/endpoint.test.ts b/packages/beacon-node/test/e2e/api/impl/lightclient/endpoint.test.ts index e4e767107ecb..f764a9b989fc 100644 --- a/packages/beacon-node/test/e2e/api/impl/lightclient/endpoint.test.ts +++ b/packages/beacon-node/test/e2e/api/impl/lightclient/endpoint.test.ts @@ -82,10 +82,10 @@ describe("lightclient api", function () { await sleep(2 * SECONDS_PER_SLOT * 1000); }; - it("getUpdates()", async function () { + it("getLightClientUpdatesByRange()", async function () { const client = getClient({baseUrl: `http://127.0.0.1:${restPort}`}, {config}).lightclient; await waitForBestUpdate(); - const res = await client.getUpdates(0, 1); + const res = await client.getLightClientUpdatesByRange(0, 1); ApiError.assert(res); const updates = res.response; expect(updates.length).to.be.equal(1); @@ -94,10 +94,10 @@ describe("lightclient api", function () { expect(updates[0].version).to.be.equal(ForkName.altair); }); - it("getOptimisticUpdate()", async function () { + it("getLightClientOptimisticUpdate()", async function () { await waitForBestUpdate(); const client = getClient({baseUrl: `http://127.0.0.1:${restPort}`}, {config}).lightclient; - const res = await client.getOptimisticUpdate(); + const res = await client.getLightClientOptimisticUpdate(); ApiError.assert(res); const update = res.response; const slot = bn.chain.clock.currentSlot; @@ -107,21 +107,21 @@ describe("lightclient api", function () { expect(update.version).to.be.equal(ForkName.altair); }); - it.skip("getFinalityUpdate()", async function () { + it.skip("getLightClientFinalityUpdate()", async function () { // TODO: not sure how this causes subsequent tests failed await waitForEvent(bn.chain.emitter, routes.events.EventType.finalizedCheckpoint, 240000); await sleep(SECONDS_PER_SLOT * 1000); const client = getClient({baseUrl: `http://127.0.0.1:${restPort}`}, {config}).lightclient; - const res = await client.getFinalityUpdate(); + const res = await client.getLightClientFinalityUpdate(); ApiError.assert(res); expect(res.response).to.be.not.undefined; }); - it("getCommitteeRoot() for the 1st period", async function () { + it("getLightClientCommitteeRoot() for the 1st period", async function () { await waitForBestUpdate(); const lightclient = getClient({baseUrl: `http://127.0.0.1:${restPort}`}, {config}).lightclient; - const committeeRes = await lightclient.getCommitteeRoot(0, 1); + const committeeRes = await lightclient.getLightClientCommitteeRoot(0, 1); ApiError.assert(committeeRes); const client = getClient({baseUrl: `http://127.0.0.1:${restPort}`}, {config}).beacon; const validatorResponse = await client.getStateValidators("head"); diff --git a/packages/light-client/src/transport/rest.ts b/packages/light-client/src/transport/rest.ts index 765e55d7f5c5..6fd92cb9ff6d 100644 --- a/packages/light-client/src/transport/rest.ts +++ b/packages/light-client/src/transport/rest.ts @@ -30,25 +30,25 @@ export class LightClientRestTransport extends (EventEmitter as {new (): RestEven data: allForks.LightClientUpdate; }[] > { - const res = await this.api.lightclient.getUpdates(startPeriod, count); + const res = await this.api.lightclient.getLightClientUpdatesByRange(startPeriod, count); ApiError.assert(res); return res.response; } async getOptimisticUpdate(): Promise<{version: ForkName; data: allForks.LightClientOptimisticUpdate}> { - const res = await this.api.lightclient.getOptimisticUpdate(); + const res = await this.api.lightclient.getLightClientOptimisticUpdate(); ApiError.assert(res); return res.response; } async getFinalityUpdate(): Promise<{version: ForkName; data: allForks.LightClientFinalityUpdate}> { - const res = await this.api.lightclient.getFinalityUpdate(); + const res = await this.api.lightclient.getLightClientFinalityUpdate(); ApiError.assert(res); return res.response; } async getBootstrap(blockRoot: string): Promise<{version: ForkName; data: allForks.LightClientBootstrap}> { - const res = await this.api.lightclient.getBootstrap(blockRoot); + const res = await this.api.lightclient.getLightClientBootstrap(blockRoot); ApiError.assert(res); return res.response; } diff --git a/packages/light-client/test/mocks/LightclientServerApiMock.ts b/packages/light-client/test/mocks/LightclientServerApiMock.ts index 941e623ba1c8..1d9c59e02cbb 100644 --- a/packages/light-client/test/mocks/LightclientServerApiMock.ts +++ b/packages/light-client/test/mocks/LightclientServerApiMock.ts @@ -32,7 +32,7 @@ export class LightclientServerApiMock implements ServerApi { + async getLightClientUpdatesByRange(from: SyncPeriod, to: SyncPeriod): Promise { const updates: VersionedLightClientUpdate[] = []; for (let period = parseInt(String(from)); period <= parseInt(String(to)); period++) { const update = this.updates.get(period); @@ -46,23 +46,23 @@ export class LightclientServerApiMock implements ServerApi { + async getLightClientOptimisticUpdate(): Promise<{version: ForkName; data: altair.LightClientOptimisticUpdate}> { if (!this.latestHeadUpdate) throw Error("No latest head update"); return {version: ForkName.bellatrix, data: this.latestHeadUpdate}; } - async getFinalityUpdate(): Promise<{version: ForkName; data: altair.LightClientFinalityUpdate}> { + async getLightClientFinalityUpdate(): Promise<{version: ForkName; data: altair.LightClientFinalityUpdate}> { if (!this.finalized) throw Error("No finalized head update"); return {version: ForkName.bellatrix, data: this.finalized}; } - async getBootstrap(blockRoot: string): Promise<{version: ForkName; data: altair.LightClientBootstrap}> { + async getLightClientBootstrap(blockRoot: string): Promise<{version: ForkName; data: altair.LightClientBootstrap}> { const snapshot = this.snapshots.get(blockRoot); if (!snapshot) throw Error(`snapshot for blockRoot ${blockRoot} not available`); return {version: ForkName.bellatrix, data: snapshot}; } - async getCommitteeRoot(startPeriod: SyncPeriod, count: number): Promise<{data: Uint8Array[]}> { + async getLightClientCommitteeRoot(startPeriod: SyncPeriod, count: number): Promise<{data: Uint8Array[]}> { const periods = Array.from({length: count}, (_ignored, i) => i + startPeriod); const committeeHashes = periods .map((period) => this.updates.get(period)?.nextSyncCommittee.pubkeys)