UNPKG

@lodestar/beacon-node

Version:

A Typescript implementation of the beacon chain

61 lines 2.96 kB
import { GENESIS_EPOCH, GENESIS_SLOT, isForkPostDeneb } from "@lodestar/params"; import { RespStatus, ResponseError } from "@lodestar/reqresp"; import { computeEpochAtSlot, computeStartSlotAtEpoch } from "@lodestar/state-transition"; import { toRootHex } from "@lodestar/utils"; import { getParentRootFromSignedBeaconBlockSerialized } from "../../../util/sszBytes.js"; import { prettyPrintPeerId } from "../../util.js"; // See https://github.com/ethereum/consensus-specs/pull/5181 export async function* onBeaconBlocksByHead(request, chain, peerId, peerClient) { const currentFork = chain.config.getForkName(chain.clock.currentSlot); const { beaconRoot, count } = validateBeaconBlocksByHeadRequest(currentFork, chain.config, request); const requestedRootHex = toRootHex(beaconRoot); let blockRootHex = requestedRootHex; const minimumRequestEpoch = Math.max(GENESIS_EPOCH, chain.clock.currentEpoch - chain.config.MIN_EPOCHS_FOR_BLOCK_REQUESTS); const minimumRequestSlot = computeStartSlotAtEpoch(minimumRequestEpoch); for (let blocksSent = 0; blocksSent < count; blocksSent++) { const blockBytes = await chain.getSerializedBlockByRoot(blockRootHex); if (!blockBytes) { if (blocksSent === 0) { throw new ResponseError(RespStatus.RESOURCE_UNAVAILABLE, `Unknown block root ${requestedRootHex}`); } return; } if (blockBytes.slot < minimumRequestSlot) { if (blocksSent === 0) { chain.logger.verbose("Peer requested unavailable block for BeaconBlocksByHead", { peer: prettyPrintPeerId(peerId), client: peerClient, requestedRoot: requestedRootHex, slot: blockBytes.slot, minimumRequestSlot, }); } return; } yield { data: blockBytes.block, boundary: chain.config.getForkBoundaryAtEpoch(computeEpochAtSlot(blockBytes.slot)), }; if (blockBytes.slot === GENESIS_SLOT) { return; } const parentRootHex = getParentRootFromSignedBeaconBlockSerialized(blockBytes.block); if (parentRootHex === null) { throw new ResponseError(RespStatus.SERVER_ERROR, `Invalid block bytes for root ${blockRootHex} slot ${blockBytes.slot}`); } blockRootHex = parentRootHex; } } export function validateBeaconBlocksByHeadRequest(fork, config, request) { const { beaconRoot } = request; let { count } = request; if (count < 1) { throw new ResponseError(RespStatus.INVALID_REQUEST, "count < 1"); } const maxRequestBlocks = isForkPostDeneb(fork) ? config.MAX_REQUEST_BLOCKS_DENEB : config.MAX_REQUEST_BLOCKS; if (count > maxRequestBlocks) { count = maxRequestBlocks; } return { beaconRoot, count }; } //# sourceMappingURL=beaconBlocksByHead.js.map