diff --git a/packages/beacon-node/src/chain/errors/payloadAttestation.ts b/packages/beacon-node/src/chain/errors/payloadAttestation.ts index c9f15a2b657d..f6aa7f99dd52 100644 --- a/packages/beacon-node/src/chain/errors/payloadAttestation.ts +++ b/packages/beacon-node/src/chain/errors/payloadAttestation.ts @@ -5,6 +5,7 @@ export enum PayloadAttestationErrorCode { NOT_CURRENT_SLOT = "PAYLOAD_ATTESTATION_ERROR_NOT_CURRENT_SLOT", PAYLOAD_ATTESTATION_ALREADY_KNOWN = "PAYLOAD_ATTESTATION_ERROR_PAYLOAD_ATTESTATION_ALREADY_KNOWN", UNKNOWN_BLOCK_ROOT = "PAYLOAD_ATTESTATION_ERROR_UNKNOWN_BLOCK_ROOT", + INVALID_BLOCK_SLOT = "PAYLOAD_ATTESTATION_ERROR_INVALID_BLOCK_SLOT", INVALID_BLOCK = "PAYLOAD_ATTESTATION_ERROR_INVALID_BLOCK", INVALID_ATTESTER = "PAYLOAD_ATTESTATION_ERROR_INVALID_ATTESTER", INVALID_SIGNATURE = "PAYLOAD_ATTESTATION_ERROR_INVALID_SIGNATURE", @@ -18,6 +19,7 @@ export type PayloadAttestationErrorType = blockRoot: RootHex; } | {code: PayloadAttestationErrorCode.UNKNOWN_BLOCK_ROOT; blockRoot: RootHex} + | {code: PayloadAttestationErrorCode.INVALID_BLOCK_SLOT; blockRoot: RootHex; blockSlot: Slot; slot: Slot} | {code: PayloadAttestationErrorCode.INVALID_BLOCK; blockRoot: RootHex} | {code: PayloadAttestationErrorCode.INVALID_ATTESTER; attesterIndex: ValidatorIndex} | {code: PayloadAttestationErrorCode.INVALID_SIGNATURE}; diff --git a/packages/beacon-node/src/chain/validation/payloadAttestationMessage.ts b/packages/beacon-node/src/chain/validation/payloadAttestationMessage.ts index 089fe743f820..48e639017d7e 100644 --- a/packages/beacon-node/src/chain/validation/payloadAttestationMessage.ts +++ b/packages/beacon-node/src/chain/validation/payloadAttestationMessage.ts @@ -70,6 +70,17 @@ async function validatePayloadAttestationMessage( }); } + // [IGNORE] The block referenced by `data.beacon_block_root` is at slot `data.slot`, + // i.e. the block has `block.slot == data.slot`. + if (block.slot !== data.slot) { + throw new PayloadAttestationError(GossipAction.IGNORE, { + code: PayloadAttestationErrorCode.INVALID_BLOCK_SLOT, + blockRoot: toRootHex(data.beaconBlockRoot), + blockSlot: block.slot, + slot: data.slot, + }); + } + // [REJECT] The message's block `data.beacon_block_root` passes validation. // TODO GLOAS: implement this. Technically if we cannot get proto block from fork choice, // it is possible that the block didn't pass the validation