@lodestar/beacon-node
Version:
A Typescript implementation of the beacon chain
104 lines (92 loc) • 3.88 kB
text/typescript
import {ForkName, ForkSeq} from "@lodestar/params";
import {SlotOptionalRoot, SlotRootHex} from "@lodestar/types";
import {
getBeaconBlockRootFromDataColumnSidecarSerialized,
getBlockRootFromBeaconAttestationSerialized,
getBlockRootFromPayloadAttestationMessageSerialized,
getBlockRootFromSignedAggregateAndProofSerialized,
getSlotFromBeaconAttestationSerialized,
getSlotFromBlobSidecarSerialized,
getSlotFromDataColumnSidecarSerialized,
getSlotFromExecutionPayloadEnvelopeSerialized,
getSlotFromPayloadAttestationMessageSerialized,
getSlotFromSignedAggregateAndProofSerialized,
getSlotFromSignedBeaconBlockSerialized,
getSlotFromSignedExecutionPayloadBidSerialized,
} from "../../util/sszBytes.js";
import {GossipType} from "../gossip/index.js";
import {ExtractSlotRootFns} from "./types.js";
/**
* Extract the slot and block root of a gossip message form serialized data.
* Only do it for messages that have a slot and block root, and we want to await the block if the block root is not known.
*/
export function createExtractBlockSlotRootFns(): ExtractSlotRootFns {
return {
[GossipType.beacon_attestation]: (data: Uint8Array, fork: ForkName): SlotRootHex | null => {
const slot = getSlotFromBeaconAttestationSerialized(fork, data);
const root = getBlockRootFromBeaconAttestationSerialized(fork, data);
if (slot === null || root === null) {
return null;
}
return {slot, root};
},
[GossipType.beacon_aggregate_and_proof]: (data: Uint8Array): SlotRootHex | null => {
const slot = getSlotFromSignedAggregateAndProofSerialized(data);
const root = getBlockRootFromSignedAggregateAndProofSerialized(data);
if (slot === null || root === null) {
return null;
}
return {slot, root};
},
[GossipType.beacon_block]: (data: Uint8Array): SlotOptionalRoot | null => {
const slot = getSlotFromSignedBeaconBlockSerialized(data);
if (slot === null) {
return null;
}
return {slot};
},
[GossipType.blob_sidecar]: (data: Uint8Array): SlotOptionalRoot | null => {
const slot = getSlotFromBlobSidecarSerialized(data);
if (slot === null) {
return null;
}
return {slot};
},
[GossipType.data_column_sidecar]: (data: Uint8Array, fork: ForkName): SlotOptionalRoot | null => {
const slot = getSlotFromDataColumnSidecarSerialized(data, fork);
if (slot === null) {
return null;
}
if (ForkSeq[fork] < ForkSeq.gloas) {
return {slot};
}
const root = getBeaconBlockRootFromDataColumnSidecarSerialized(data);
// null root means the message is invalid here and will be ignored in gossip handler later
// returning the slot here helps check the earliest permissable slot in the network processor
return root !== null ? {slot, root} : {slot};
},
[GossipType.execution_payload]: (data: Uint8Array): SlotOptionalRoot | null => {
const slot = getSlotFromExecutionPayloadEnvelopeSerialized(data);
// Do not extract the root here; the network processor will extract it in the 2nd round to trigger block search without awaiting.
if (slot === null) {
return null;
}
return {slot};
},
[GossipType.payload_attestation_message]: (data: Uint8Array): SlotRootHex | null => {
const slot = getSlotFromPayloadAttestationMessageSerialized(data);
const root = getBlockRootFromPayloadAttestationMessageSerialized(data);
if (slot === null || root === null) {
return null;
}
return {slot, root};
},
[GossipType.execution_payload_bid]: (data: Uint8Array): SlotOptionalRoot | null => {
const slot = getSlotFromSignedExecutionPayloadBidSerialized(data);
if (slot === null) {
return null;
}
return {slot};
},
};
}