@lodestar/beacon-node
Version:
A Typescript implementation of the beacon chain
68 lines • 3.49 kB
JavaScript
import { computeEpochAtSlot } from "@lodestar/state-transition";
import { toRootHex } from "@lodestar/utils";
import { prettyPrintPeerId } from "../../util.js";
import { handleColumnSidecarUnavailability, validateRequestedDataColumns, } from "../utils/dataColumnResponseValidation.js";
export async function* onDataColumnSidecarsByRoot(requestBody, chain, db, peerId, peerClient) {
// SPEC: minimum_request_epoch = max(current_epoch - MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS, FULU_FORK_EPOCH)
const currentEpoch = chain.clock.currentEpoch;
const minimumRequestEpoch = Math.max(currentEpoch - chain.config.MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS, chain.config.FULU_FORK_EPOCH);
for (const dataColumnsByRootIdentifier of requestBody) {
const { blockRoot, columns: requestedColumns } = dataColumnsByRootIdentifier;
const availableColumns = validateRequestedDataColumns(chain, requestedColumns);
if (availableColumns.length === 0) {
return;
}
const blockRootHex = toRootHex(blockRoot);
const block = chain.forkChoice.getBlockHexDefaultStatus(blockRootHex);
// If the block is not in fork choice, it may be finalized. Attempt to find its slot in block archive
const slot = block ? block.slot : await db.blockArchive.getSlotByRoot(blockRoot);
if (slot === null) {
// We haven't seen the block
continue;
}
if (slot < chain.earliestAvailableSlot) {
chain.logger.verbose("Peer did not respect earliestAvailableSlot for DataColumnSidecarsByRoot", {
peer: prettyPrintPeerId(peerId),
client: peerClient,
});
continue;
}
const requestedEpoch = computeEpochAtSlot(slot);
// SPEC: Clients MUST support requesting sidecars since minimum_request_epoch.
// If any root in the request content references a block earlier than minimum_request_epoch, peers MAY respond with
// error code 3: ResourceUnavailable or not include the data column sidecar in the response.
// https://github.com/ethereum/consensus-specs/blob/v1.6.0-alpha.5/specs/fulu/p2p-interface.md#datacolumnsidecarsbyroot-v1
if (requestedEpoch < minimumRequestEpoch) {
continue;
}
const dataColumns = await chain.getSerializedDataColumnSidecars(slot, blockRootHex, availableColumns);
const unavailableColumnIndices = [];
for (let i = 0; i < dataColumns.length; i++) {
const dataColumnBytes = dataColumns[i];
if (dataColumnBytes) {
yield {
data: dataColumnBytes,
boundary: chain.config.getForkBoundaryAtEpoch(requestedEpoch),
};
}
// TODO: Check blobs for that block and respond resource_unavailable
// After we have consensus from other teams on the specs
else {
unavailableColumnIndices.push(availableColumns[i]);
}
}
if (unavailableColumnIndices.length) {
await handleColumnSidecarUnavailability({
chain,
db,
metrics: chain.metrics,
slot,
blockRoot,
unavailableColumnIndices,
requestedColumns,
availableColumns,
});
}
}
}
//# sourceMappingURL=dataColumnSidecarsByRoot.js.map