mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-07 16:55:46 +00:00
test fixes
This commit is contained in:
@@ -178,6 +178,11 @@ pub enum InvalidAttestation {
|
|||||||
/// A same-slot attestation has a non-zero index, indicating a payload attestation during the
|
/// A same-slot attestation has a non-zero index, indicating a payload attestation during the
|
||||||
/// same slot as the block. Payload attestations must only arrive in subsequent slots.
|
/// same slot as the block. Payload attestations must only arrive in subsequent slots.
|
||||||
PayloadAttestationDuringSameSlot { slot: Slot },
|
PayloadAttestationDuringSameSlot { slot: Slot },
|
||||||
|
/// A gossip payload attestation must be for the current slot.
|
||||||
|
PayloadAttestationNotCurrentSlot {
|
||||||
|
attestation_slot: Slot,
|
||||||
|
current_slot: Slot,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<String> for Error<T> {
|
impl<T> From<String> for Error<T> {
|
||||||
@@ -1139,7 +1144,7 @@ where
|
|||||||
fn validate_on_payload_attestation(
|
fn validate_on_payload_attestation(
|
||||||
&self,
|
&self,
|
||||||
indexed_payload_attestation: &IndexedPayloadAttestation<E>,
|
indexed_payload_attestation: &IndexedPayloadAttestation<E>,
|
||||||
_is_from_block: bool,
|
is_from_block: bool,
|
||||||
) -> Result<(), InvalidAttestation> {
|
) -> Result<(), InvalidAttestation> {
|
||||||
if indexed_payload_attestation.attesting_indices.is_empty() {
|
if indexed_payload_attestation.attesting_indices.is_empty() {
|
||||||
return Err(InvalidAttestation::EmptyAggregationBitfield);
|
return Err(InvalidAttestation::EmptyAggregationBitfield);
|
||||||
@@ -1159,6 +1164,17 @@ where
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gossip payload attestations must be for the current slot.
|
||||||
|
// https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/fork-choice.md
|
||||||
|
if !is_from_block
|
||||||
|
&& indexed_payload_attestation.data.slot != self.fc_store.get_current_slot()
|
||||||
|
{
|
||||||
|
return Err(InvalidAttestation::PayloadAttestationNotCurrentSlot {
|
||||||
|
attestation_slot: indexed_payload_attestation.data.slot,
|
||||||
|
current_slot: self.fc_store.get_current_slot(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if self.fc_store.get_current_slot() == block.slot
|
if self.fc_store.get_current_slot() == block.slot
|
||||||
&& indexed_payload_attestation.data.payload_present
|
&& indexed_payload_attestation.data.payload_present
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1047,10 +1047,10 @@ async fn payload_attestation_for_previous_slot_is_accepted_at_next_slot() {
|
|||||||
assert!(latest_message.payload_present);
|
assert!(latest_message.payload_present);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Non-block payload attestations at slot S+1 for data.slot S are delayed; they are not applied
|
/// Gossip payload attestations must be for the current slot. A payload attestation for slot S
|
||||||
/// until a later slot.
|
/// received at slot S+1 should be rejected per the spec.
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn non_block_payload_attestation_at_next_slot_is_delayed() {
|
async fn non_block_payload_attestation_for_previous_slot_is_rejected() {
|
||||||
let test = ForkChoiceTest::new()
|
let test = ForkChoiceTest::new()
|
||||||
.apply_blocks_without_new_attestations(1)
|
.apply_blocks_without_new_attestations(1)
|
||||||
.await;
|
.await;
|
||||||
@@ -1062,7 +1062,6 @@ async fn non_block_payload_attestation_at_next_slot_is_delayed() {
|
|||||||
.expect("block A should exist");
|
.expect("block A should exist");
|
||||||
let block_a_root = block_a.canonical_root();
|
let block_a_root = block_a.canonical_root();
|
||||||
let s_plus_1 = block_a.slot().saturating_add(1_u64);
|
let s_plus_1 = block_a.slot().saturating_add(1_u64);
|
||||||
let s_plus_2 = block_a.slot().saturating_add(2_u64);
|
|
||||||
|
|
||||||
let payload_attestation = IndexedPayloadAttestation::<E> {
|
let payload_attestation = IndexedPayloadAttestation::<E> {
|
||||||
attesting_indices: vec![0_u64].try_into().expect("valid attesting indices"),
|
attesting_indices: vec![0_u64].try_into().expect("valid attesting indices"),
|
||||||
@@ -1080,34 +1079,15 @@ async fn non_block_payload_attestation_at_next_slot_is_delayed() {
|
|||||||
.fork_choice_write_lock()
|
.fork_choice_write_lock()
|
||||||
.on_payload_attestation(s_plus_1, &payload_attestation, false);
|
.on_payload_attestation(s_plus_1, &payload_attestation, false);
|
||||||
assert!(
|
assert!(
|
||||||
result.is_ok(),
|
matches!(
|
||||||
"payload attestation should be accepted for queueing"
|
result,
|
||||||
|
Err(ForkChoiceError::InvalidAttestation(
|
||||||
|
InvalidAttestation::PayloadAttestationNotCurrentSlot { .. }
|
||||||
|
))
|
||||||
|
),
|
||||||
|
"gossip payload attestation for previous slot should be rejected, got: {:?}",
|
||||||
|
result
|
||||||
);
|
);
|
||||||
|
|
||||||
// Vote should not be applied yet; message remains unset.
|
|
||||||
let latest_before = chain
|
|
||||||
.canonical_head
|
|
||||||
.fork_choice_read_lock()
|
|
||||||
.latest_message(0);
|
|
||||||
assert!(
|
|
||||||
latest_before.is_none(),
|
|
||||||
"non-block payload attestation at S+1 should not apply immediately"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Advance fork choice time to S+2, queue should now be processed.
|
|
||||||
chain
|
|
||||||
.canonical_head
|
|
||||||
.fork_choice_write_lock()
|
|
||||||
.update_time(s_plus_2)
|
|
||||||
.expect("update_time should succeed");
|
|
||||||
|
|
||||||
let latest_after = chain
|
|
||||||
.canonical_head
|
|
||||||
.fork_choice_read_lock()
|
|
||||||
.latest_message(0)
|
|
||||||
.expect("latest message should exist after delay");
|
|
||||||
assert_eq!(latest_after.slot, s_plus_2);
|
|
||||||
assert!(latest_after.payload_present);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specification v0.12.1:
|
/// Specification v0.12.1:
|
||||||
|
|||||||
@@ -659,7 +659,7 @@ impl ProtoArrayForkChoice {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Only re-org a single slot. This prevents cascading failures during asynchrony.
|
// Only re-org a single slot. This prevents cascading failures during asynchrony.
|
||||||
let head_slot_ok = info.head_node.slot() + 1 == current_slot;
|
let head_slot_ok = info.head_node.slot().saturating_add(1_u64) == current_slot;
|
||||||
if !head_slot_ok {
|
if !head_slot_ok {
|
||||||
return Err(DoNotReOrg::HeadDistance.into());
|
return Err(DoNotReOrg::HeadDistance.into());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user