Skip to content

Commit

Permalink
Merge branch 'unstable' into nflaig/type-safe-metric-labels
Browse files Browse the repository at this point in the history
  • Loading branch information
nflaig committed Dec 25, 2023
2 parents 4cb239f + 21851b2 commit ae8b6d0
Show file tree
Hide file tree
Showing 70 changed files with 754 additions and 1,023 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,9 @@ jobs:
key: ${{ runner.os }}-node-${{ matrix.node }}-${{ github.sha }}
fail-on-cache-miss: true
- name: Install Chrome browser
run: npx @puppeteer/browsers install chrome
run: npx @puppeteer/browsers install chromedriver@latest --path /tmp
- name: Install Firefox browser
run: npx @puppeteer/browsers install firefox
run: npx @puppeteer/browsers install firefox@latest --path /tmp
- name: Browser tests
run: |
export DISPLAY=':99.0'
Expand Down
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@
"@types/sinon-chai": "^3.2.9",
"@typescript-eslint/eslint-plugin": "6.7.2",
"@typescript-eslint/parser": "6.7.2",
"@vitest/coverage-v8": "^1.0.1",
"@vitest/browser": "^1.0.1",
"@vitest/coverage-v8": "^1.1.0",
"@vitest/browser": "^1.1.0",
"c8": "^8.0.1",
"chai": "^4.3.8",
"chai-as-promised": "^7.1.1",
Expand Down Expand Up @@ -97,17 +97,18 @@
"ts-node": "^10.9.1",
"typescript": "^5.2.2",
"typescript-docs-verifier": "^2.5.0",
"vite-plugin-node-polyfills": "^0.17.0",
"vite-plugin-top-level-await": "^1.3.1",
"vitest": "^1.0.2",
"vite-plugin-node-polyfills": "^0.18.0",
"vite-plugin-top-level-await": "^1.4.1",
"vitest": "^1.1.0",
"vitest-when": "^0.3.0",
"wait-port": "^1.1.0",
"webdriverio": "^8.24.12",
"webdriverio": "^8.27.0",
"webpack": "^5.88.2"
},
"resolutions": {
"dns-over-http-resolver": "^2.1.1",
"chai": "^4.3.10",
"loupe": "^2.3.6"
"loupe": "^2.3.6",
"vite": "^5.0.0"
}
}
40 changes: 10 additions & 30 deletions packages/api/src/beacon/routes/beacon/block.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
import {ContainerType} from "@chainsafe/ssz";
import {ForkName} from "@lodestar/params";
import {ChainForkConfig} from "@lodestar/config";
import {
phase0,
allForks,
Slot,
Root,
ssz,
RootHex,
deneb,
isSignedBlockContents,
isSignedBlindedBlockContents,
} from "@lodestar/types";
import {phase0, allForks, Slot, Root, ssz, RootHex, deneb, isSignedBlockContents} from "@lodestar/types";

import {
RoutesData,
Expand All @@ -30,10 +20,7 @@ import {
import {HttpStatusCode} from "../../../utils/client/httpStatusCode.js";
import {parseAcceptHeader, writeAcceptHeader} from "../../../utils/acceptHeader.js";
import {ApiClientResponse, ResponseFormat} from "../../../interfaces.js";
import {
allForksSignedBlockContentsReqSerializer,
allForksSignedBlindedBlockContentsReqSerializer,
} from "../../../utils/routes.js";
import {allForksSignedBlockContentsReqSerializer} from "../../../utils/routes.js";

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

Expand Down Expand Up @@ -207,7 +194,7 @@ export type Api = {
* Publish a signed blinded block by submitting it to the mev relay and patching in the block
* transactions beacon node gets in response.
*/
publishBlindedBlock(blindedBlockOrContents: allForks.SignedBlindedBeaconBlockOrContents): Promise<
publishBlindedBlock(blindedBlock: allForks.SignedBlindedBeaconBlock): Promise<
ApiClientResponse<
{
[HttpStatusCode.OK]: void;
Expand All @@ -218,7 +205,7 @@ export type Api = {
>;

publishBlindedBlockV2(
blindedBlockOrContents: allForks.SignedBlindedBeaconBlockOrContents,
blindedBlockOrContents: allForks.SignedBlindedBeaconBlock,
opts: {broadcastValidation?: BroadcastValidation}
): Promise<
ApiClientResponse<
Expand Down Expand Up @@ -315,16 +302,9 @@ export function getReqSerializers(config: ChainForkConfig): ReqSerializers<Api,
): allForks.AllForksBlindedSSZTypes["SignedBeaconBlock"] =>
config.getBlindedForkTypes(data.message.slot).SignedBeaconBlock;

const AllForksSignedBlindedBlockOrContents: TypeJson<allForks.SignedBlindedBeaconBlockOrContents> = {
toJson: (data) =>
isSignedBlindedBlockContents(data)
? allForksSignedBlindedBlockContentsReqSerializer(getSignedBlindedBeaconBlockType).toJson(data)
: getSignedBlindedBeaconBlockType(data).toJson(data),

fromJson: (data) =>
(data as {signed_blinded_block: unknown}).signed_blinded_block !== undefined
? allForksSignedBlindedBlockContentsReqSerializer(getSignedBlindedBeaconBlockType).fromJson(data)
: getSignedBlindedBeaconBlockType(data as allForks.SignedBlindedBeaconBlock).fromJson(data),
const AllForksSignedBlindedBlock: TypeJson<allForks.SignedBlindedBeaconBlock> = {
toJson: (data) => getSignedBlindedBeaconBlockType(data).toJson(data),
fromJson: (data) => getSignedBlindedBeaconBlockType(data as allForks.SignedBlindedBeaconBlock).fromJson(data),
};

return {
Expand Down Expand Up @@ -353,14 +333,14 @@ export function getReqSerializers(config: ChainForkConfig): ReqSerializers<Api,
query: {broadcast_validation: Schema.String},
},
},
publishBlindedBlock: reqOnlyBody(AllForksSignedBlindedBlockOrContents, Schema.Object),
publishBlindedBlock: reqOnlyBody(AllForksSignedBlindedBlock, Schema.Object),
publishBlindedBlockV2: {
writeReq: (item, {broadcastValidation}) => ({
body: AllForksSignedBlindedBlockOrContents.toJson(item),
body: AllForksSignedBlindedBlock.toJson(item),
query: {broadcast_validation: broadcastValidation},
}),
parseReq: ({body, query}) => [
AllForksSignedBlindedBlockOrContents.fromJson(body),
AllForksSignedBlindedBlock.fromJson(body),
{broadcastValidation: query.broadcast_validation as BroadcastValidation},
],
schema: {
Expand Down
32 changes: 15 additions & 17 deletions packages/api/src/beacon/routes/validator.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {ContainerType, fromHexString, toHexString, Type} from "@chainsafe/ssz";
import {ForkName, ForkBlobs, isForkBlobs, isForkExecution, ForkPreBlobs} from "@lodestar/params";
import {ForkName, ForkBlobs, isForkBlobs, isForkExecution, ForkPreBlobs, ForkExecution} from "@lodestar/params";
import {
allForks,
altair,
Expand Down Expand Up @@ -37,7 +37,7 @@ import {
TypeJson,
} from "../../utils/index.js";
import {fromU64Str, fromGraffitiHex, toU64Str, U64Str, toGraffitiHex} from "../../utils/serdes.js";
import {allForksBlockContentsResSerializer, allForksBlindedBlockContentsResSerializer} from "../../utils/routes.js";
import {allForksBlockContentsResSerializer} from "../../utils/routes.js";
import {ExecutionOptimistic} from "./beacon/block.js";

export enum BuilderSelection {
Expand All @@ -59,14 +59,14 @@ export type ProduceBlockOrContentsRes = {executionPayloadValue: Wei; consensusBl
| {data: allForks.BeaconBlock; version: ForkPreBlobs}
| {data: allForks.BlockContents; version: ForkBlobs}
);
export type ProduceBlindedBlockOrContentsRes = {executionPayloadValue: Wei; consensusBlockValue: Gwei} & (
| {data: allForks.BlindedBeaconBlock; version: ForkPreBlobs}
| {data: allForks.BlindedBlockContents; version: ForkBlobs}
);
export type ProduceBlindedBlockRes = {executionPayloadValue: Wei; consensusBlockValue: Gwei} & {
data: allForks.BlindedBeaconBlock;
version: ForkExecution;
};

export type ProduceFullOrBlindedBlockOrContentsRes =
| (ProduceBlockOrContentsRes & {executionPayloadBlinded: false})
| (ProduceBlindedBlockOrContentsRes & {executionPayloadBlinded: true});
| (ProduceBlindedBlockRes & {executionPayloadBlinded: true});

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

Expand Down Expand Up @@ -287,7 +287,7 @@ export type Api = {
): Promise<
ApiClientResponse<
{
[HttpStatusCode.OK]: ProduceBlindedBlockOrContentsRes;
[HttpStatusCode.OK]: ProduceBlindedBlockRes;
},
HttpStatusCode.BAD_REQUEST | HttpStatusCode.SERVICE_UNAVAILABLE
>
Expand Down Expand Up @@ -721,13 +721,11 @@ export function getReturnTypes(): ReturnTypes<Api> {
isForkBlobs(fork) ? allForksBlockContentsResSerializer(fork) : ssz[fork].BeaconBlock
)
) as TypeJson<ProduceBlockOrContentsRes>;
const produceBlindedBlockOrContents = WithBlockValues(
WithVersion<allForks.BlindedBeaconBlockOrContents>((fork: ForkName) =>
isForkBlobs(fork)
? allForksBlindedBlockContentsResSerializer(fork)
: ssz.allForksBlinded[isForkExecution(fork) ? fork : ForkName.bellatrix].BeaconBlock
const produceBlindedBlock = WithBlockValues(
WithVersion<allForks.BlindedBeaconBlock>(
(fork: ForkName) => ssz.allForksBlinded[isForkExecution(fork) ? fork : ForkName.bellatrix].BeaconBlock
)
) as TypeJson<ProduceBlindedBlockOrContentsRes>;
) as TypeJson<ProduceBlindedBlockRes>;

return {
getAttesterDuties: WithDependentRootExecutionOptimistic(ArrayOf(AttesterDuty)),
Expand All @@ -741,7 +739,7 @@ export function getReturnTypes(): ReturnTypes<Api> {
if (data.executionPayloadBlinded) {
return {
execution_payload_blinded: true,
...(produceBlindedBlockOrContents.toJson(data) as Record<string, unknown>),
...(produceBlindedBlock.toJson(data) as Record<string, unknown>),
};
} else {
return {
Expand All @@ -752,13 +750,13 @@ export function getReturnTypes(): ReturnTypes<Api> {
},
fromJson: (data) => {
if ((data as {execution_payload_blinded: true}).execution_payload_blinded) {
return {executionPayloadBlinded: true, ...produceBlindedBlockOrContents.fromJson(data)};
return {executionPayloadBlinded: true, ...produceBlindedBlock.fromJson(data)};
} else {
return {executionPayloadBlinded: false, ...produceBlockOrContents.fromJson(data)};
}
},
},
produceBlindedBlock: produceBlindedBlockOrContents,
produceBlindedBlock,

produceAttestationData: ContainerData(ssz.phase0.AttestationData),
produceSyncCommitteeContribution: ContainerData(ssz.altair.SyncCommitteeContribution),
Expand Down
26 changes: 24 additions & 2 deletions packages/api/src/beacon/server/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,28 @@ import {ServerRoutes, getGenericJsonServer} from "../../utils/server/index.js";
import {ServerApi} from "../../interfaces.js";

export function getRoutes(config: ChainForkConfig, api: ServerApi<Api>): ServerRoutes<Api, ReqTypes> {
// All routes return JSON, use a server auto-generator
return getGenericJsonServer<ServerApi<Api>, ReqTypes>({routesData, getReturnTypes, getReqSerializers}, config, api);
const reqSerializers = getReqSerializers();
const returnTypes = getReturnTypes();

// Most of routes return JSON, use a server auto-generator
const serverRoutes = getGenericJsonServer<ServerApi<Api>, ReqTypes>(
{routesData, getReturnTypes, getReqSerializers},
config,
api
);
return {
...serverRoutes,
produceBlockV3: {
...serverRoutes.produceBlockV3,
handler: async (req, res) => {
const response = await api.produceBlockV3(...reqSerializers.produceBlockV3.parseReq(req));
void res.header("Eth-Consensus-Version", response.version);
void res.header("Eth-Execution-Payload-Blinded", response.executionPayloadBlinded);
void res.header("Eth-Execution-Payload-Value", response.executionPayloadValue);
void res.header("Eth-Consensus-Block-Value", response.consensusBlockValue);

return returnTypes.produceBlockV3.toJson(response);
},
},
};
}
2 changes: 1 addition & 1 deletion packages/api/src/builder/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export type Api = {
HttpStatusCode.NOT_FOUND | HttpStatusCode.BAD_REQUEST
>
>;
submitBlindedBlock(signedBlock: allForks.SignedBlindedBeaconBlockOrContents): Promise<
submitBlindedBlock(signedBlock: allForks.SignedBlindedBeaconBlock): Promise<
ApiClientResponse<
{
[HttpStatusCode.OK]: {
Expand Down
49 changes: 10 additions & 39 deletions packages/api/src/utils/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ export function allForksSignedBlockContentsReqSerializer(
return {
toJson: (data) => ({
signed_block: blockSerializer(data.signedBlock).toJson(data.signedBlock),
signed_blob_sidecars: ssz.deneb.SignedBlobSidecars.toJson(data.signedBlobSidecars),
kzg_proofs: ssz.deneb.KZGProofs.toJson(data.kzgProofs),
blobs: ssz.deneb.Blobs.toJson(data.blobs),
}),

fromJson: (data: {signed_block: unknown; signed_blob_sidecars: unknown}) => ({
fromJson: (data: {signed_block: unknown; kzg_proofs: unknown; blobs: unknown}) => ({
signedBlock: blockSerializer(data.signed_block as allForks.SignedBeaconBlock).fromJson(data.signed_block),
signedBlobSidecars: ssz.deneb.SignedBlobSidecars.fromJson(data.signed_blob_sidecars),
kzgProofs: ssz.deneb.KZGProofs.fromJson(data.kzg_proofs),
blobs: ssz.deneb.Blobs.fromJson(data.blobs),
}),
};
}
Expand All @@ -25,44 +27,13 @@ export function allForksBlockContentsResSerializer(fork: ForkBlobs): TypeJson<al
return {
toJson: (data) => ({
block: (ssz.allForks[fork].BeaconBlock as allForks.AllForksSSZTypes["BeaconBlock"]).toJson(data.block),
blob_sidecars: ssz.deneb.BlobSidecars.toJson(data.blobSidecars),
kzg_proofs: ssz.deneb.KZGProofs.toJson(data.kzgProofs),
blobs: ssz.deneb.Blobs.toJson(data.blobs),
}),
fromJson: (data: {block: unknown; blob_sidecars: unknown}) => ({
fromJson: (data: {block: unknown; blob_sidecars: unknown; kzg_proofs: unknown; blobs: unknown}) => ({
block: ssz.allForks[fork].BeaconBlock.fromJson(data.block),
blobSidecars: ssz.deneb.BlobSidecars.fromJson(data.blob_sidecars),
}),
};
}

export function allForksSignedBlindedBlockContentsReqSerializer(
blockSerializer: (data: allForks.SignedBlindedBeaconBlock) => TypeJson<allForks.SignedBlindedBeaconBlock>
): TypeJson<allForks.SignedBlindedBlockContents> {
return {
toJson: (data) => ({
signed_blinded_block: blockSerializer(data.signedBlindedBlock).toJson(data.signedBlindedBlock),
signed_blinded_blob_sidecars: ssz.deneb.SignedBlindedBlobSidecars.toJson(data.signedBlindedBlobSidecars),
}),

fromJson: (data: {signed_blinded_block: unknown; signed_blinded_blob_sidecars: unknown}) => ({
signedBlindedBlock: blockSerializer(data.signed_blinded_block as allForks.SignedBlindedBeaconBlock).fromJson(
data.signed_blinded_block
),
signedBlindedBlobSidecars: ssz.deneb.SignedBlindedBlobSidecars.fromJson(data.signed_blinded_blob_sidecars),
}),
};
}

export function allForksBlindedBlockContentsResSerializer(fork: ForkBlobs): TypeJson<allForks.BlindedBlockContents> {
return {
toJson: (data) => ({
blinded_block: (ssz.allForksBlinded[fork].BeaconBlock as allForks.AllForksBlindedSSZTypes["BeaconBlock"]).toJson(
data.blindedBlock
),
blinded_blob_sidecars: ssz.deneb.BlindedBlobSidecars.toJson(data.blindedBlobSidecars),
}),
fromJson: (data: {blinded_block: unknown; blinded_blob_sidecars: unknown}) => ({
blindedBlock: ssz.allForksBlinded[fork].BeaconBlock.fromJson(data.blinded_block),
blindedBlobSidecars: ssz.deneb.BlindedBlobSidecars.fromJson(data.blinded_blob_sidecars),
kzgProofs: ssz.deneb.KZGProofs.fromJson(data.kzg_proofs),
blobs: ssz.deneb.Blobs.fromJson(data.blobs),
}),
};
}
Loading

0 comments on commit ae8b6d0

Please sign in to comment.