Skip to content

Commit

Permalink
feat: forward blinded block ssz bytes to submitBlindedBlock api (#7185)
Browse files Browse the repository at this point in the history
* feat: forward blinded block ssz bytes to submitBlindedBlock api

* Add comment

* Add WithOptionalBytes
  • Loading branch information
nflaig authored Oct 28, 2024
1 parent bfa7a39 commit d8b599a
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 13 deletions.
17 changes: 10 additions & 7 deletions packages/api/src/builder/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ExecutionPayloadAndBlobsBundle,
SignedBlindedBeaconBlock,
SignedBuilderBid,
WithOptionalBytes,
} from "@lodestar/types";
import {ForkName, isForkBlobs} from "@lodestar/params";
import {ChainForkConfig} from "@lodestar/config";
Expand Down Expand Up @@ -71,7 +72,7 @@ export type Endpoints = {

submitBlindedBlock: Endpoint<
"POST",
{signedBlindedBlock: SignedBlindedBeaconBlock},
{signedBlindedBlock: WithOptionalBytes<SignedBlindedBeaconBlock>},
{body: unknown; headers: {[MetaHeader.Version]: string}},
ExecutionPayload | ExecutionPayloadAndBlobsBundle,
VersionMeta
Expand Down Expand Up @@ -124,9 +125,9 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
method: "POST",
req: {
writeReqJson: ({signedBlindedBlock}) => {
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,
},
Expand All @@ -135,13 +136,15 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
parseReqJson: ({body, headers}) => {
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,
},
Expand All @@ -150,7 +153,7 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
parseReqSsz: ({body, headers}) => {
const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
return {
signedBlindedBlock: getExecutionForkTypes(fork).SignedBlindedBeaconBlock.deserialize(body),
signedBlindedBlock: {data: getExecutionForkTypes(fork).SignedBlindedBeaconBlock.deserialize(body)},
};
},
schema: {
Expand Down
2 changes: 1 addition & 1 deletion packages/api/test/unit/builder/testData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const testData: GenericServerTestCases<Endpoints> = {
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}},
},
};
8 changes: 6 additions & 2 deletions packages/beacon-node/src/api/impl/beacon/blocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
SignedBeaconBlock,
SignedBeaconBlockOrContents,
SignedBlindedBeaconBlock,
WithOptionalBytes,
} from "@lodestar/types";
import {
BlockSource,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -507,7 +511,7 @@ export function getBeaconBlockApi({

async function reconstructBuilderBlockOrContents(
chain: ApiModules["chain"],
signedBlindedBlock: SignedBlindedBeaconBlock
signedBlindedBlock: WithOptionalBytes<SignedBlindedBeaconBlock>
): Promise<SignedBeaconBlockOrContents> {
const executionBuilder = chain.executionBuilder;
if (!executionBuilder) {
Expand Down
7 changes: 5 additions & 2 deletions packages/beacon-node/src/execution/builder/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
SignedBlindedBeaconBlock,
ExecutionPayloadHeader,
electra,
WithOptionalBytes,
} from "@lodestar/types";
import {parseExecutionPayloadAndBlobsBundle, reconstructFullBlockOrContents} from "@lodestar/state-transition";
import {ChainForkConfig} from "@lodestar/config";
Expand Down Expand Up @@ -160,7 +161,9 @@ export class ExecutionBuilderHttp implements IExecutionBuilder {
return {header, executionPayloadValue, blobKzgCommitments, executionRequests};
}

async submitBlindedBlock(signedBlindedBlock: SignedBlindedBeaconBlock): Promise<SignedBeaconBlockOrContents> {
async submitBlindedBlock(
signedBlindedBlock: WithOptionalBytes<SignedBlindedBeaconBlock>
): Promise<SignedBeaconBlockOrContents> {
const res = await this.api.submitBlindedBlock(
{signedBlindedBlock},
{retries: 2, requestWireFormat: this.sszSupported ? WireFormat.ssz : WireFormat.json}
Expand All @@ -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});
}
}
5 changes: 4 additions & 1 deletion packages/beacon-node/src/execution/builder/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ExecutionPayloadHeader,
SignedBlindedBeaconBlock,
electra,
WithOptionalBytes,
} from "@lodestar/types";
import {ForkExecution} from "@lodestar/params";

Expand Down Expand Up @@ -39,5 +40,7 @@ export interface IExecutionBuilder {
blobKzgCommitments?: deneb.BlobKzgCommitments;
executionRequests?: electra.ExecutionRequests;
}>;
submitBlindedBlock(signedBlock: SignedBlindedBeaconBlock): Promise<SignedBeaconBlockOrContents>;
submitBlindedBlock(
signedBlindedBlock: WithOptionalBytes<SignedBlindedBeaconBlock>
): Promise<SignedBeaconBlockOrContents>;
}
6 changes: 6 additions & 0 deletions packages/types/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ export enum ProducedBlockSource {
engine = "engine",
}

export type WithOptionalBytes<T> = {
data: T;
/** SSZ serialized `data` bytes */
bytes?: Uint8Array | null;
};

export type SlotRootHex = {slot: Slot; root: RootHex};
export type SlotOptionalRoot = {slot: Slot; root?: RootHex};

Expand Down

0 comments on commit d8b599a

Please sign in to comment.