@lodestar/beacon-node
Version:
A Typescript implementation of the beacon chain
63 lines • 3.57 kB
JavaScript
import { RespStatus, ResponseError } from "@lodestar/reqresp";
import { prettyBytes, prettyPrintIndices, toRootHex } from "@lodestar/utils";
import { getBlobKzgCommitmentsCountFromSignedBeaconBlockSerialized } from "../../../util/sszBytes.js";
export async function handleColumnSidecarUnavailability({ chain, db, metrics, unavailableColumnIndices, requestedColumns, availableColumns, slot, blockRoot, }) {
const logData = {
slot,
unavailableColumnIndices: prettyPrintIndices(unavailableColumnIndices),
requestedColumns: prettyPrintIndices(requestedColumns),
availableColumns: prettyPrintIndices(availableColumns),
};
if (blockRoot) {
logData.blockRoot = prettyBytes(blockRoot);
}
chain.logger.debug("dataColumnSidecar requested unavailable", logData);
const blockBytes = blockRoot ? await db.block.getBinary(blockRoot) : await db.blockArchive.getBinary(slot);
if (!blockBytes) {
chain.logger.verbose(`Expected ${blockRoot ? "unfinalized" : "finalized"} block not found while handling unavailable dataColumnSidecar`, {
slot,
blockRoot: blockRoot ? toRootHex(blockRoot) : "unknown",
earliestAvailableSlot: chain.earliestAvailableSlot,
});
return;
}
// Check for blob count in actual block
const blobsCount = getBlobKzgCommitmentsCountFromSignedBeaconBlockSerialized(chain.config, blockBytes);
// There are zero blobs for that column index, so we can safely return without any error
if (blobsCount === 0)
return;
// There are blobs for that column index so we should have synced for it
// We need to inform to peers that we don't have that expected data
metrics?.dataColumns.missingCustodyColumns.inc(unavailableColumnIndices.length);
chain.logger.verbose("dataColumnSidecar requested and within custody but not available", {
unavailableColumnIndices: prettyPrintIndices(unavailableColumnIndices),
blockRoot: blockRoot ? prettyBytes(blockRoot) : "unknown",
});
}
export function validateRequestedDataColumns(chain, requestedColumns) {
if (requestedColumns.length === 0) {
throw new ResponseError(RespStatus.INVALID_REQUEST, "dataColumnSidecar requested without column indices");
}
const custodyColumns = chain.custodyConfig.custodyColumns;
const availableColumns = requestedColumns.filter((c) => custodyColumns.includes(c));
const missingColumns = requestedColumns.filter((c) => !custodyColumns.includes(c));
if (missingColumns.length > 0) {
chain.logger.verbose("Requested dataColumnSidecar for non-custody columns", {
requestedColumns: prettyPrintIndices(requestedColumns),
custodyColumns: prettyPrintIndices(custodyColumns),
availableColumns: prettyPrintIndices(availableColumns),
missingColumns: prettyPrintIndices(missingColumns),
});
// TODO: We should throw error and only respond to valid requests
// A peer must check what we announced in our custody and only ask for those columns
// throw new ResponseError(RespStatus.INVALID_REQUEST, "dataColumnSidecar requested for non-custody columns");
}
if (availableColumns.length === 0) {
chain.logger.verbose("Requested dataColumnSidecars not available", {
requestedColumns: prettyPrintIndices(requestedColumns),
custodyColumns: prettyPrintIndices(custodyColumns),
});
}
return availableColumns;
}
//# sourceMappingURL=dataColumnResponseValidation.js.map