From d8b599a4a54f8ad7c0289f452dbe6f62bc685f33 Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Mon, 28 Oct 2024 09:16:34 +0000 Subject: [PATCH] feat: forward blinded block ssz bytes to submitBlindedBlock api (#7185) * feat: forward blinded block ssz bytes to submitBlindedBlock api * Add comment * Add WithOptionalBytes --- packages/api/src/builder/routes.ts | 17 ++++++++++------- packages/api/test/unit/builder/testData.ts | 2 +- .../src/api/impl/beacon/blocks/index.ts | 8 ++++++-- .../beacon-node/src/execution/builder/http.ts | 7 +++++-- .../src/execution/builder/interface.ts | 5 ++++- packages/types/src/types.ts | 6 ++++++ 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/packages/api/src/builder/routes.ts b/packages/api/src/builder/routes.ts index a203a93b8afe..3911a515e1c6 100644 --- a/packages/api/src/builder/routes.ts +++ b/packages/api/src/builder/routes.ts @@ -8,6 +8,7 @@ import { ExecutionPayloadAndBlobsBundle, SignedBlindedBeaconBlock, SignedBuilderBid, + WithOptionalBytes, } from "@lodestar/types"; import {ForkName, isForkBlobs} from "@lodestar/params"; import {ChainForkConfig} from "@lodestar/config"; @@ -71,7 +72,7 @@ export type Endpoints = { submitBlindedBlock: Endpoint< "POST", - {signedBlindedBlock: SignedBlindedBeaconBlock}, + {signedBlindedBlock: WithOptionalBytes}, {body: unknown; headers: {[MetaHeader.Version]: string}}, ExecutionPayload | ExecutionPayloadAndBlobsBundle, VersionMeta @@ -124,9 +125,9 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions { - const fork = config.getForkName(signedBlindedBlock.message.slot); + const fork = config.getForkName(signedBlindedBlock.data.message.slot); return { - body: getExecutionForkTypes(fork).SignedBlindedBeaconBlock.toJson(signedBlindedBlock), + body: getExecutionForkTypes(fork).SignedBlindedBeaconBlock.toJson(signedBlindedBlock.data), headers: { [MetaHeader.Version]: fork, }, @@ -135,13 +136,15 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions { const fork = toForkName(fromHeaders(headers, MetaHeader.Version)); return { - signedBlindedBlock: getExecutionForkTypes(fork).SignedBlindedBeaconBlock.fromJson(body), + signedBlindedBlock: {data: getExecutionForkTypes(fork).SignedBlindedBeaconBlock.fromJson(body)}, }; }, writeReqSsz: ({signedBlindedBlock}) => { - const fork = config.getForkName(signedBlindedBlock.message.slot); + const fork = config.getForkName(signedBlindedBlock.data.message.slot); return { - body: getExecutionForkTypes(fork).SignedBlindedBeaconBlock.serialize(signedBlindedBlock), + body: + signedBlindedBlock.bytes ?? + getExecutionForkTypes(fork).SignedBlindedBeaconBlock.serialize(signedBlindedBlock.data), headers: { [MetaHeader.Version]: fork, }, @@ -150,7 +153,7 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions { const fork = toForkName(fromHeaders(headers, MetaHeader.Version)); return { - signedBlindedBlock: getExecutionForkTypes(fork).SignedBlindedBeaconBlock.deserialize(body), + signedBlindedBlock: {data: getExecutionForkTypes(fork).SignedBlindedBeaconBlock.deserialize(body)}, }; }, schema: { diff --git a/packages/api/test/unit/builder/testData.ts b/packages/api/test/unit/builder/testData.ts index a23823702b6d..a807620258df 100644 --- a/packages/api/test/unit/builder/testData.ts +++ b/packages/api/test/unit/builder/testData.ts @@ -23,7 +23,7 @@ export const testData: GenericServerTestCases = { res: {data: ssz.bellatrix.SignedBuilderBid.defaultValue(), meta: {version: ForkName.bellatrix}}, }, submitBlindedBlock: { - args: {signedBlindedBlock: ssz.deneb.SignedBlindedBeaconBlock.defaultValue()}, + args: {signedBlindedBlock: {data: ssz.deneb.SignedBlindedBeaconBlock.defaultValue()}}, res: {data: ssz.bellatrix.ExecutionPayload.defaultValue(), meta: {version: ForkName.bellatrix}}, }, }; diff --git a/packages/beacon-node/src/api/impl/beacon/blocks/index.ts b/packages/beacon-node/src/api/impl/beacon/blocks/index.ts index b54e8752a437..2d36505d822a 100644 --- a/packages/beacon-node/src/api/impl/beacon/blocks/index.ts +++ b/packages/beacon-node/src/api/impl/beacon/blocks/index.ts @@ -15,6 +15,7 @@ import { SignedBeaconBlock, SignedBeaconBlockOrContents, SignedBlindedBeaconBlock, + WithOptionalBytes, } from "@lodestar/types"; import { BlockSource, @@ -269,7 +270,10 @@ export function getBeaconBlockApi({ const source = ProducedBlockSource.builder; chain.logger.debug("Reconstructing signedBlockOrContents", {slot, blockRoot, source}); - const signedBlockOrContents = await reconstructBuilderBlockOrContents(chain, signedBlindedBlock); + const signedBlockOrContents = await reconstructBuilderBlockOrContents(chain, { + data: signedBlindedBlock, + bytes: context?.sszBytes, + }); // the full block is published by relay and it's possible that the block is already known to us // by gossip @@ -507,7 +511,7 @@ export function getBeaconBlockApi({ async function reconstructBuilderBlockOrContents( chain: ApiModules["chain"], - signedBlindedBlock: SignedBlindedBeaconBlock + signedBlindedBlock: WithOptionalBytes ): Promise { const executionBuilder = chain.executionBuilder; if (!executionBuilder) { diff --git a/packages/beacon-node/src/execution/builder/http.ts b/packages/beacon-node/src/execution/builder/http.ts index 0a6018e5e231..b95cfd6a80b9 100644 --- a/packages/beacon-node/src/execution/builder/http.ts +++ b/packages/beacon-node/src/execution/builder/http.ts @@ -9,6 +9,7 @@ import { SignedBlindedBeaconBlock, ExecutionPayloadHeader, electra, + WithOptionalBytes, } from "@lodestar/types"; import {parseExecutionPayloadAndBlobsBundle, reconstructFullBlockOrContents} from "@lodestar/state-transition"; import {ChainForkConfig} from "@lodestar/config"; @@ -160,7 +161,9 @@ export class ExecutionBuilderHttp implements IExecutionBuilder { return {header, executionPayloadValue, blobKzgCommitments, executionRequests}; } - async submitBlindedBlock(signedBlindedBlock: SignedBlindedBeaconBlock): Promise { + async submitBlindedBlock( + signedBlindedBlock: WithOptionalBytes + ): Promise { const res = await this.api.submitBlindedBlock( {signedBlindedBlock}, {retries: 2, requestWireFormat: this.sszSupported ? WireFormat.ssz : WireFormat.json} @@ -174,6 +177,6 @@ export class ExecutionBuilderHttp implements IExecutionBuilder { // probably need diagonis if this block turns out to be invalid because of some bug // const contents = blobsBundle ? {blobs: blobsBundle.blobs, kzgProofs: blobsBundle.proofs} : null; - return reconstructFullBlockOrContents(signedBlindedBlock, {executionPayload, contents}); + return reconstructFullBlockOrContents(signedBlindedBlock.data, {executionPayload, contents}); } } diff --git a/packages/beacon-node/src/execution/builder/interface.ts b/packages/beacon-node/src/execution/builder/interface.ts index 5a6a4eb82f63..19a935a9bf7e 100644 --- a/packages/beacon-node/src/execution/builder/interface.ts +++ b/packages/beacon-node/src/execution/builder/interface.ts @@ -9,6 +9,7 @@ import { ExecutionPayloadHeader, SignedBlindedBeaconBlock, electra, + WithOptionalBytes, } from "@lodestar/types"; import {ForkExecution} from "@lodestar/params"; @@ -39,5 +40,7 @@ export interface IExecutionBuilder { blobKzgCommitments?: deneb.BlobKzgCommitments; executionRequests?: electra.ExecutionRequests; }>; - submitBlindedBlock(signedBlock: SignedBlindedBeaconBlock): Promise; + submitBlindedBlock( + signedBlindedBlock: WithOptionalBytes + ): Promise; } diff --git a/packages/types/src/types.ts b/packages/types/src/types.ts index 08fc06ac6cb9..51fa2b12a28e 100644 --- a/packages/types/src/types.ts +++ b/packages/types/src/types.ts @@ -32,6 +32,12 @@ export enum ProducedBlockSource { engine = "engine", } +export type WithOptionalBytes = { + data: T; + /** SSZ serialized `data` bytes */ + bytes?: Uint8Array | null; +}; + export type SlotRootHex = {slot: Slot; root: RootHex}; export type SlotOptionalRoot = {slot: Slot; root?: RootHex};