mirror of
https://github.com/sigp/lighthouse.git
synced 2026-06-15 09:48:20 +00:00
impl 5281 gossip verification check
This commit is contained in:
@@ -70,13 +70,21 @@ impl<T: BeaconChainTypes> VerifiedPayloadAttestationMessage<T> {
|
||||
// 2. Blocks we've seen that are invalid (REJECT).
|
||||
// Presently both cases return IGNORE.
|
||||
let beacon_block_root = payload_attestation_message.data.beacon_block_root;
|
||||
if ctx
|
||||
let block = ctx
|
||||
.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
.get_block(&beacon_block_root)
|
||||
.is_none()
|
||||
{
|
||||
return Err(Error::UnknownHeadBlock { beacon_block_root });
|
||||
.ok_or(Error::UnknownHeadBlock { beacon_block_root })?;
|
||||
|
||||
// [IGNORE] The block referenced by `data.beacon_block_root` is at slot `data.slot`, i.e.
|
||||
// the block has `block.slot == data.slot`. A PTC member assigned to an empty slot must not
|
||||
// attest, so ignore messages that reference an earlier block.
|
||||
if block.slot != slot {
|
||||
return Err(Error::BlockNotAtSlot {
|
||||
beacon_block_root,
|
||||
block_slot: block.slot,
|
||||
data_slot: slot,
|
||||
});
|
||||
}
|
||||
|
||||
let message_epoch = slot.epoch(T::EthSpec::slots_per_epoch());
|
||||
|
||||
@@ -60,6 +60,19 @@ pub enum Error {
|
||||
/// The attestation points to a block we have not yet imported. It's unclear if the
|
||||
/// attestation is valid or not.
|
||||
UnknownHeadBlock { beacon_block_root: Hash256 },
|
||||
/// The block referenced by `data.beacon_block_root` is not at slot `data.slot`, i.e. the
|
||||
/// PTC member's assigned slot was empty (the message references the last canonical block at
|
||||
/// an earlier slot).
|
||||
///
|
||||
/// ## Peer scoring
|
||||
///
|
||||
/// PTC members should not attest for empty slots, so we
|
||||
/// ignore the message.
|
||||
BlockNotAtSlot {
|
||||
beacon_block_root: Hash256,
|
||||
block_slot: Slot,
|
||||
data_slot: Slot,
|
||||
},
|
||||
/// The validator index is not a member of the PTC for this slot.
|
||||
///
|
||||
/// ## Peer scoring
|
||||
|
||||
@@ -167,6 +167,25 @@ fn unknown_head_block() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block_not_at_slot() {
|
||||
if !fork_name_from_env().is_some_and(|f| f.gloas_enabled()) {
|
||||
return;
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
|
||||
// The genesis block is at slot 0, but the message claims slot 1. A PTC member assigned to an
|
||||
// empty slot must not attest, so this must be ignored (per consensus-specs #5281).
|
||||
let msg = make_payload_attestation(Slot::new(1), 0, ctx.genesis_block_root);
|
||||
let result = VerifiedPayloadAttestationMessage::new(msg, &gossip);
|
||||
assert!(
|
||||
matches!(result, Err(PayloadAttestationError::BlockNotAtSlot { .. })),
|
||||
"expected BlockNotAtSlot, got: {:?}",
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn not_in_ptc() {
|
||||
if !fork_name_from_env().is_some_and(|f| f.gloas_enabled()) {
|
||||
@@ -174,7 +193,9 @@ fn not_in_ptc() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(1);
|
||||
// The genesis block is at slot 0, so attest at slot 0 to satisfy the `block.slot == data.slot`
|
||||
// gossip rule. Slot 0 is still within the propagation range at the current slot.
|
||||
let slot = Slot::new(0);
|
||||
|
||||
let ptc_members = ctx.ptc_members(slot);
|
||||
let non_ptc_validator = (0..NUM_VALIDATORS as u64)
|
||||
@@ -196,7 +217,9 @@ fn invalid_signature() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(1);
|
||||
// The genesis block is at slot 0, so attest at slot 0 to satisfy the `block.slot == data.slot`
|
||||
// gossip rule. Slot 0 is still within the propagation range at the current slot.
|
||||
let slot = Slot::new(0);
|
||||
|
||||
let ptc_members = ctx.ptc_members(slot);
|
||||
let validator_index = ptc_members[0] as u64;
|
||||
@@ -216,7 +239,9 @@ fn valid_payload_attestation() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(1);
|
||||
// The genesis block is at slot 0, so attest at slot 0 to satisfy the `block.slot == data.slot`
|
||||
// gossip rule. Slot 0 is still within the propagation range at the current slot.
|
||||
let slot = Slot::new(0);
|
||||
|
||||
let ptc_members = ctx.ptc_members(slot);
|
||||
let validator_index = ptc_members[0] as u64;
|
||||
@@ -243,7 +268,9 @@ fn duplicate_after_valid() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(1);
|
||||
// The genesis block is at slot 0, so attest at slot 0 to satisfy the `block.slot == data.slot`
|
||||
// gossip rule. Slot 0 is still within the propagation range at the current slot.
|
||||
let slot = Slot::new(0);
|
||||
|
||||
let ptc_members = ctx.ptc_members(slot);
|
||||
let validator_index = ptc_members[0] as u64;
|
||||
|
||||
@@ -4003,6 +4003,14 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
||||
);
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
}
|
||||
PayloadAttestationError::BlockNotAtSlot { .. } => {
|
||||
debug!(
|
||||
%peer_id,
|
||||
%message_slot,
|
||||
"Payload attestation references block at wrong slot"
|
||||
);
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
}
|
||||
PayloadAttestationError::NotInPTC { .. } => {
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Reject);
|
||||
self.gossip_penalize_peer(
|
||||
|
||||
@@ -1539,11 +1539,11 @@ impl ProtoArray {
|
||||
// considered available when either a majority have voted true or not enough votes have
|
||||
// been cast either way.
|
||||
if proto_node.payload_data_availability::<E>(false)? {
|
||||
return Ok(false)
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
|
||||
if proto_node.payload_timeliness::<E>(false)? {
|
||||
return Ok(false)
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
|
||||
Reference in New Issue
Block a user