Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ packages/state-transition/test-cache
benchmark_data
invalidSszObjects/
packages/beacon-node/mainnet_pubkeys.csv
packages/api/oapi-schemas

# Autogenerated docs
packages/**/docs
Expand Down
1 change: 1 addition & 0 deletions packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"devDependencies": {
"@types/eventsource": "^1.1.5",
"@types/qs": "^6.9.6",
"ajv": "^8.11.0",
"fastify": "3.15.1"
},
"peerDependencies": {
Expand Down
65 changes: 43 additions & 22 deletions packages/api/src/beacon/routes/beacon/block.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {ContainerType} from "@chainsafe/ssz";
import {ForkName} from "@lodestar/params";
import {IChainForkConfig} from "@lodestar/config";
import {phase0, allForks, Slot, Root, ssz, bellatrix} from "@lodestar/types";
import {phase0, allForks, Slot, Root, ssz, bellatrix, RootHex} from "@lodestar/types";

import {
RoutesData,
Expand All @@ -14,11 +14,19 @@ import {
TypeJson,
ReqSerializers,
ReqSerializer,
ContainerDataExecutionOptimistic,
WithExecutionOptimistic,
} from "../../../utils/index.js";

// See /packages/api/src/routes/index.ts for reasoning and instructions to add new routes

export type BlockId = "head" | "genesis" | "finalized" | string | number;
export type BlockId = RootHex | Slot | "head" | "genesis" | "finalized";

/**
* True if the response references an unverified execution payload. Optimistic information may be invalidated at
* a later time. If the field is not present, assume the False value.
*/
export type ExecutionOptimistic = boolean;

export type BlockHeaderResponse = {
root: Root;
Expand All @@ -43,39 +51,45 @@ export type Api = {
* @param blockId Block identifier.
* Can be one of: "head" (canonical head in node's view), "genesis", "finalized", \<slot\>, \<hex encoded blockRoot with 0x prefix\>.
*/
getBlockV2(blockId: BlockId): Promise<{data: allForks.SignedBeaconBlock; version: ForkName}>;
getBlockV2(
blockId: BlockId
): Promise<{executionOptimistic: ExecutionOptimistic; data: allForks.SignedBeaconBlock; version: ForkName}>;

/**
* Get block attestations
* Retrieves attestation included in requested block.
* @param blockId Block identifier.
* Can be one of: "head" (canonical head in node's view), "genesis", "finalized", \<slot\>, \<hex encoded blockRoot with 0x prefix\>.
*/
getBlockAttestations(blockId: BlockId): Promise<{data: phase0.Attestation[]}>;
getBlockAttestations(
blockId: BlockId
): Promise<{executionOptimistic: ExecutionOptimistic; data: phase0.Attestation[]}>;

/**
* Get block header
* Retrieves block header for given block id.
* @param blockId Block identifier.
* Can be one of: "head" (canonical head in node's view), "genesis", "finalized", \<slot\>, \<hex encoded blockRoot with 0x prefix\>.
*/
getBlockHeader(blockId: BlockId): Promise<{data: BlockHeaderResponse}>;
getBlockHeader(blockId: BlockId): Promise<{executionOptimistic: ExecutionOptimistic; data: BlockHeaderResponse}>;

/**
* Get block headers
* Retrieves block headers matching given query. By default it will fetch current head slot blocks.
* @param slot
* @param parentRoot
*/
getBlockHeaders(filters: Partial<{slot: Slot; parentRoot: string}>): Promise<{data: BlockHeaderResponse[]}>;
getBlockHeaders(
filters: Partial<{slot: Slot; parentRoot: string}>
): Promise<{executionOptimistic: ExecutionOptimistic; data: BlockHeaderResponse[]}>;

/**
* Get block root
* Retrieves hashTreeRoot of BeaconBlock/BeaconBlockHeader
* @param blockId Block identifier.
* Can be one of: "head" (canonical head in node's view), "genesis", "finalized", \<slot\>, \<hex encoded blockRoot with 0x prefix\>.
*/
getBlockRoot(blockId: BlockId): Promise<{data: Root}>;
getBlockRoot(blockId: BlockId): Promise<{executionOptimistic: ExecutionOptimistic; data: {root: Root}}>;

/**
* Publish a signed block.
Expand All @@ -101,19 +115,20 @@ export type Api = {
* Define javascript values for each route
*/
export const routesData: RoutesData<Api> = {
getBlock: {url: "/eth/v1/beacon/blocks/:blockId", method: "GET"},
getBlockV2: {url: "/eth/v2/beacon/blocks/:blockId", method: "GET"},
getBlockAttestations: {url: "/eth/v1/beacon/blocks/:blockId/attestations", method: "GET"},
getBlockHeader: {url: "/eth/v1/beacon/headers/:blockId", method: "GET"},
getBlock: {url: "/eth/v1/beacon/blocks/{block_id}", method: "GET"},
getBlockV2: {url: "/eth/v2/beacon/blocks/{block_id}", method: "GET"},
getBlockAttestations: {url: "/eth/v1/beacon/blocks/{block_id}/attestations", method: "GET"},
getBlockHeader: {url: "/eth/v1/beacon/headers/{block_id}", method: "GET"},
getBlockHeaders: {url: "/eth/v1/beacon/headers", method: "GET"},
getBlockRoot: {url: "/eth/v1/beacon/blocks/:blockId/root", method: "GET"},
getBlockRoot: {url: "/eth/v1/beacon/blocks/{block_id}/root", method: "GET"},
publishBlock: {url: "/eth/v1/beacon/blocks", method: "POST"},
publishBlindedBlock: {url: "/eth/v1/beacon/blinded_blocks", method: "POST"},
};

type BlockIdOnlyReq = {params: {blockId: string | number}};

/* eslint-disable @typescript-eslint/naming-convention */

type BlockIdOnlyReq = {params: {block_id: string}};

export type ReqTypes = {
getBlock: BlockIdOnlyReq;
getBlockV2: BlockIdOnlyReq;
Expand All @@ -127,9 +142,9 @@ export type ReqTypes = {

export function getReqSerializers(config: IChainForkConfig): ReqSerializers<Api, ReqTypes> {
const blockIdOnlyReq: ReqSerializer<Api["getBlock"], BlockIdOnlyReq> = {
writeReq: (blockId) => ({params: {blockId}}),
parseReq: ({params}) => [params.blockId],
schema: {params: {blockId: Schema.StringRequired}},
writeReq: (block_id) => ({params: {block_id: String(block_id)}}),
parseReq: ({params}) => [params.block_id],
schema: {params: {block_id: Schema.StringRequired}},
};

// Compute block type from JSON payload. See https://github.com/ethereum/eth2.0-APIs/pull/142
Expand Down Expand Up @@ -164,13 +179,19 @@ export function getReturnTypes(): ReturnTypes<Api> {
header: ssz.phase0.SignedBeaconBlockHeader,
});

const RootContainer = new ContainerType({
root: ssz.Root,
});

return {
getBlock: ContainerData(ssz.phase0.SignedBeaconBlock),
// Teku returns fork as UPPERCASE
getBlockV2: WithVersion((fork: ForkName) => ssz[fork.toLowerCase() as ForkName].SignedBeaconBlock),
getBlockAttestations: ContainerData(ArrayOf(ssz.phase0.Attestation)),
getBlockHeader: ContainerData(BeaconHeaderResType),
getBlockHeaders: ContainerData(ArrayOf(BeaconHeaderResType)),
getBlockRoot: ContainerData(ssz.Root),
getBlockV2: WithExecutionOptimistic(
WithVersion((fork: ForkName) => ssz[fork.toLowerCase() as ForkName].SignedBeaconBlock)
),
getBlockAttestations: ContainerDataExecutionOptimistic(ArrayOf(ssz.phase0.Attestation)),
getBlockHeader: ContainerDataExecutionOptimistic(BeaconHeaderResType),
getBlockHeaders: ContainerDataExecutionOptimistic(ArrayOf(BeaconHeaderResType)),
getBlockRoot: ContainerDataExecutionOptimistic(RootContainer),
};
}
16 changes: 8 additions & 8 deletions packages/api/src/beacon/routes/beacon/pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export type Api = {
* @returns any Success
* @throws ApiError
*/
submitPoolAttesterSlashing(slashing: phase0.AttesterSlashing): Promise<void>;
submitPoolAttesterSlashings(slashing: phase0.AttesterSlashing): Promise<void>;

/**
* Submit ProposerSlashing object to node's pool
Expand All @@ -83,7 +83,7 @@ export type Api = {
* @returns any Success
* @throws ApiError
*/
submitPoolProposerSlashing(slashing: phase0.ProposerSlashing): Promise<void>;
submitPoolProposerSlashings(slashing: phase0.ProposerSlashing): Promise<void>;

/**
* Submit SignedVoluntaryExit object to node's pool
Expand All @@ -109,8 +109,8 @@ export const routesData: RoutesData<Api> = {
getPoolProposerSlashings: {url: "/eth/v1/beacon/pool/proposer_slashings", method: "GET"},
getPoolVoluntaryExits: {url: "/eth/v1/beacon/pool/voluntary_exits", method: "GET"},
submitPoolAttestations: {url: "/eth/v1/beacon/pool/attestations", method: "POST"},
submitPoolAttesterSlashing: {url: "/eth/v1/beacon/pool/attester_slashings", method: "POST"},
submitPoolProposerSlashing: {url: "/eth/v1/beacon/pool/proposer_slashings", method: "POST"},
submitPoolAttesterSlashings: {url: "/eth/v1/beacon/pool/attester_slashings", method: "POST"},
submitPoolProposerSlashings: {url: "/eth/v1/beacon/pool/proposer_slashings", method: "POST"},
submitPoolVoluntaryExit: {url: "/eth/v1/beacon/pool/voluntary_exits", method: "POST"},
submitPoolSyncCommitteeSignatures: {url: "/eth/v1/beacon/pool/sync_committees", method: "POST"},
};
Expand All @@ -122,8 +122,8 @@ export type ReqTypes = {
getPoolProposerSlashings: ReqEmpty;
getPoolVoluntaryExits: ReqEmpty;
submitPoolAttestations: {body: unknown};
submitPoolAttesterSlashing: {body: unknown};
submitPoolProposerSlashing: {body: unknown};
submitPoolAttesterSlashings: {body: unknown};
submitPoolProposerSlashings: {body: unknown};
submitPoolVoluntaryExit: {body: unknown};
submitPoolSyncCommitteeSignatures: {body: unknown};
};
Expand All @@ -139,8 +139,8 @@ export function getReqSerializers(): ReqSerializers<Api, ReqTypes> {
getPoolProposerSlashings: reqEmpty,
getPoolVoluntaryExits: reqEmpty,
submitPoolAttestations: reqOnlyBody(ArrayOf(ssz.phase0.Attestation), Schema.ObjectArray),
submitPoolAttesterSlashing: reqOnlyBody(ssz.phase0.AttesterSlashing, Schema.Object),
submitPoolProposerSlashing: reqOnlyBody(ssz.phase0.ProposerSlashing, Schema.Object),
submitPoolAttesterSlashings: reqOnlyBody(ssz.phase0.AttesterSlashing, Schema.Object),
submitPoolProposerSlashings: reqOnlyBody(ssz.phase0.ProposerSlashing, Schema.Object),
submitPoolVoluntaryExit: reqOnlyBody(ssz.phase0.SignedVoluntaryExit, Schema.Object),
submitPoolSyncCommitteeSignatures: reqOnlyBody(ArrayOf(ssz.altair.SyncCommitteeMessage), Schema.ObjectArray),
};
Expand Down
Loading