From bfe54d25def3e72705c6fa027549878d7e69f996 Mon Sep 17 00:00:00 2001 From: NC <17676176+ensi321@users.noreply.github.com> Date: Wed, 18 Dec 2024 16:45:51 -0800 Subject: [PATCH 1/3] feat: add blob sidecar index check (#7313) Validate blobSidecar index --- .../beacon-node/src/chain/errors/blobSidecarError.ts | 2 ++ packages/beacon-node/src/chain/validation/blobSidecar.ts | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/packages/beacon-node/src/chain/errors/blobSidecarError.ts b/packages/beacon-node/src/chain/errors/blobSidecarError.ts index 71118d8b8f9..216ad9206db 100644 --- a/packages/beacon-node/src/chain/errors/blobSidecarError.ts +++ b/packages/beacon-node/src/chain/errors/blobSidecarError.ts @@ -2,6 +2,7 @@ import {RootHex, Slot, ValidatorIndex} from "@lodestar/types"; import {GossipActionError} from "./gossipValidation.js"; export enum BlobSidecarErrorCode { + INDEX_TOO_LARGE = "BLOB_SIDECAR_ERROR_INDEX_TOO_LARGE", INVALID_INDEX = "BLOB_SIDECAR_ERROR_INVALID_INDEX", /** !bls.KeyValidate(block.body.blob_kzg_commitments[i]) */ INVALID_KZG = "BLOB_SIDECAR_ERROR_INVALID_KZG", @@ -26,6 +27,7 @@ export enum BlobSidecarErrorCode { } export type BlobSidecarErrorType = + | {code: BlobSidecarErrorCode.INDEX_TOO_LARGE; blobIdx: number; maxBlobsPerBlock: number} | {code: BlobSidecarErrorCode.INVALID_INDEX; blobIdx: number; subnet: number} | {code: BlobSidecarErrorCode.INVALID_KZG; blobIdx: number} | {code: BlobSidecarErrorCode.INVALID_KZG_TXS} diff --git a/packages/beacon-node/src/chain/validation/blobSidecar.ts b/packages/beacon-node/src/chain/validation/blobSidecar.ts index e2f4ed267d0..4aeff0f23ff 100644 --- a/packages/beacon-node/src/chain/validation/blobSidecar.ts +++ b/packages/beacon-node/src/chain/validation/blobSidecar.ts @@ -18,6 +18,15 @@ export async function validateGossipBlobSidecar( ): Promise { const blobSlot = blobSidecar.signedBlockHeader.message.slot; + // [REJECT] The sidecar's index is consistent with `MAX_BLOBS_PER_BLOCK` -- i.e. `blob_sidecar.index < MAX_BLOBS_PER_BLOCK`. + if (blobSidecar.index < chain.config.MAX_BLOBS_PER_BLOCK) { + throw new BlobSidecarGossipError(GossipAction.REJECT, { + code: BlobSidecarErrorCode.INDEX_TOO_LARGE, + blobIdx: blobSidecar.index, + maxBlobsPerBlock: chain.config.MAX_BLOBS_PER_BLOCK, + }); + } + // [REJECT] The sidecar is for the correct subnet -- i.e. `compute_subnet_for_blob_sidecar(sidecar.index) == subnet_id`. if (computeSubnetForBlobSidecar(blobSidecar.index, chain.config) !== subnet) { throw new BlobSidecarGossipError(GossipAction.REJECT, { From 1f38c8b1751c810e267ceab4d56d06735ac3445c Mon Sep 17 00:00:00 2001 From: NC <17676176+ensi321@users.noreply.github.com> Date: Wed, 18 Dec 2024 17:31:22 -0800 Subject: [PATCH 2/3] fix: fix blob sidecar index check (#7315) Fix index check --- packages/beacon-node/src/chain/validation/blobSidecar.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/beacon-node/src/chain/validation/blobSidecar.ts b/packages/beacon-node/src/chain/validation/blobSidecar.ts index 4aeff0f23ff..b79db77e393 100644 --- a/packages/beacon-node/src/chain/validation/blobSidecar.ts +++ b/packages/beacon-node/src/chain/validation/blobSidecar.ts @@ -19,7 +19,7 @@ export async function validateGossipBlobSidecar( const blobSlot = blobSidecar.signedBlockHeader.message.slot; // [REJECT] The sidecar's index is consistent with `MAX_BLOBS_PER_BLOCK` -- i.e. `blob_sidecar.index < MAX_BLOBS_PER_BLOCK`. - if (blobSidecar.index < chain.config.MAX_BLOBS_PER_BLOCK) { + if (blobSidecar.index >= chain.config.MAX_BLOBS_PER_BLOCK) { throw new BlobSidecarGossipError(GossipAction.REJECT, { code: BlobSidecarErrorCode.INDEX_TOO_LARGE, blobIdx: blobSidecar.index, From 8c7eaf8c57b56aa9294dcb8607f334b5500de237 Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Thu, 19 Dec 2024 09:35:23 +0000 Subject: [PATCH 3/3] chore: fix format of printed graffiti from hex to utf-8 (#7306) * chore: fix format of printed graffiti from hex to utf-8 * Use Buffer.from no copy with offset --- .../beacon-node/src/chain/produceBlock/produceBlockBody.ts | 3 ++- packages/beacon-node/src/util/graffiti.ts | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts b/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts index 0b7797828c9..d7b36e06abc 100644 --- a/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts +++ b/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts @@ -37,6 +37,7 @@ import {ZERO_HASH, ZERO_HASH_HEX} from "../../constants/index.js"; import {IEth1ForBlockProduction} from "../../eth1/index.js"; import {numToQuantity} from "../../eth1/provider/utils.js"; import {IExecutionBuilder, IExecutionEngine, PayloadAttributes, PayloadId} from "../../execution/index.js"; +import {fromGraffitiBuffer} from "../../util/graffiti.js"; import type {BeaconChain} from "../chain.js"; import {CommonBlockBody} from "../interface.js"; import {validateBlobsAndKzgCommitments} from "./validateBlobsAndKzgCommitments.js"; @@ -154,7 +155,7 @@ export async function produceBlockBody( } = blockBody; Object.assign(logMeta, { - graffiti, + graffiti: fromGraffitiBuffer(graffiti), attestations: attestations.length, deposits: deposits.length, voluntaryExits: voluntaryExits.length, diff --git a/packages/beacon-node/src/util/graffiti.ts b/packages/beacon-node/src/util/graffiti.ts index 9a4bc3d9689..fb5c30aca3d 100644 --- a/packages/beacon-node/src/util/graffiti.ts +++ b/packages/beacon-node/src/util/graffiti.ts @@ -8,6 +8,13 @@ export function toGraffitiBuffer(graffiti: string): Buffer { return Buffer.concat([Buffer.from(graffiti, "utf8"), Buffer.alloc(GRAFFITI_SIZE, 0)], GRAFFITI_SIZE); } +/** + * Converts a graffiti from 32 bytes buffer back to a UTF-8 string + */ +export function fromGraffitiBuffer(graffiti: Uint8Array): string { + return Buffer.from(graffiti.buffer, graffiti.byteOffset, graffiti.byteLength).toString("utf8"); +} + export function getDefaultGraffiti( consensusClientVersion: ClientVersion, executionClientVersion: ClientVersion | null | undefined,