UNPKG

@lodestar/beacon-node

Version:

A Typescript implementation of the beacon chain

42 lines 2.64 kB
import { BLOBSIDECAR_FIXED_SIZE } from "@lodestar/params"; import { RespStatus, ResponseError } from "@lodestar/reqresp"; import { computeEpochAtSlot } from "@lodestar/state-transition"; import { fromHex, toRootHex } from "@lodestar/utils"; import { BLOB_SIDECARS_IN_WRAPPER_INDEX } from "../../../db/repositories/blobSidecars.js"; export async function* onBlobSidecarsByRoot(requestBody, chain, db) { const finalizedSlot = chain.forkChoice.getFinalizedBlock().slot; // In sidecars by root request, it can be expected that sidecar requests will be come // clustured by blockroots, and this helps us save db lookups once we load sidecars // for a root let lastFetchedSideCars = null; for (const blobIdentifier of requestBody) { const { blockRoot, index } = blobIdentifier; const blockRootHex = toRootHex(blockRoot); const block = chain.forkChoice.getBlockHex(blockRootHex); // NOTE: Only support non-finalized blocks. // SPEC: Clients MUST support requesting blocks and sidecars since the latest finalized epoch. // https://github.com/ethereum/consensus-specs/blob/11a037fd9227e29ee809c9397b09f8cc3383a8c0/specs/eip4844/p2p-interface.md#beaconblockandblobssidecarbyroot-v1 if (!block || block.slot <= finalizedSlot) { continue; } // Check if we need to load sidecars for a new block root if (lastFetchedSideCars === null || lastFetchedSideCars.blockRoot !== blockRootHex) { const blobSideCarsBytesWrapped = await db.blobSidecars.getBinary(fromHex(block.blockRoot)); if (!blobSideCarsBytesWrapped) { // Handle the same to onBeaconBlocksByRange throw new ResponseError(RespStatus.SERVER_ERROR, `No item for root ${block.blockRoot} slot ${block.slot}`); } const blobSideCarsBytes = blobSideCarsBytesWrapped.slice(BLOB_SIDECARS_IN_WRAPPER_INDEX); lastFetchedSideCars = { blockRoot: blockRootHex, bytes: blobSideCarsBytes }; } const blobSidecarBytes = lastFetchedSideCars.bytes.slice(index * BLOBSIDECAR_FIXED_SIZE, (index + 1) * BLOBSIDECAR_FIXED_SIZE); if (blobSidecarBytes.length !== BLOBSIDECAR_FIXED_SIZE) { throw Error(`Inconsistent state, blobSidecar blockRoot=${blockRootHex} index=${index} blobSidecarBytes=${blobSidecarBytes.length} expected=${BLOBSIDECAR_FIXED_SIZE}`); } yield { data: blobSidecarBytes, boundary: chain.config.getForkBoundaryAtEpoch(computeEpochAtSlot(block.slot)), }; } } //# sourceMappingURL=blobSidecarsByRoot.js.map