Fix invalid attestation verification condition (#1321)

* Fix bug with attestation target

* Change comment wording
This commit is contained in:
Paul Hauner 2020-07-01 12:45:34 +10:00 committed by GitHub
parent 314c077870
commit ac89bb190a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 2 deletions

View File

@ -608,10 +608,20 @@ where
beacon_block_root: indexed_attestation.data.beacon_block_root, beacon_block_root: indexed_attestation.data.beacon_block_root,
})?; })?;
if block.target_root != target.root { // If an attestation points to a block that is from an earlier slot than the attestation,
// then all slots between the block and attestation must be skipped. Therefore if the block
// is from a prior epoch to the attestation, then the target root must be equal to the root
// of the block that is being attested to.
let expected_target = if target.epoch > block.slot.epoch(E::slots_per_epoch()) {
indexed_attestation.data.beacon_block_root
} else {
block.target_root
};
if expected_target != target.root {
return Err(InvalidAttestation::InvalidTarget { return Err(InvalidAttestation::InvalidTarget {
attestation: target.root, attestation: target.root,
local: block.target_root, local: expected_target,
}); });
} }

View File

@ -106,6 +106,14 @@ impl ForkChoiceTest {
self self
} }
/// Skips `count` slots, without producing a block.
pub fn skip_slots(self, count: usize) -> Self {
for _ in 0..count {
self.harness.advance_slot();
}
self
}
/// Build the chain whilst `predicate` returns `true`. /// Build the chain whilst `predicate` returns `true`.
pub fn apply_blocks_while<F>(self, mut predicate: F) -> Self pub fn apply_blocks_while<F>(self, mut predicate: F) -> Self
where where
@ -810,3 +818,22 @@ fn invalid_attestation_delayed_slot() {
.skip_slot() .skip_slot()
.inspect_queued_attestations(|queue| assert_eq!(queue.len(), 0)); .inspect_queued_attestations(|queue| assert_eq!(queue.len(), 0));
} }
/// Tests that the correct target root is used when the attested-to block is in a prior epoch to
/// the attestation.
#[test]
fn valid_attestation_skip_across_epoch() {
ForkChoiceTest::new()
.apply_blocks(E::slots_per_epoch() as usize - 1)
.skip_slots(2)
.apply_attestation_to_chain(
MutationDelay::NoDelay,
|attestation, _chain| {
assert_eq!(
attestation.data.target.root,
attestation.data.beacon_block_root
)
},
|result| result.unwrap(),
);
}