From 07bfd7e97da0e268a975ac59588e8c513d878626 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Tue, 2 Oct 2018 09:47:45 +1000 Subject: [PATCH] Add tests for attestation_validation --- lighthouse/main.rs | 2 - tests/attestation_validation/helpers.rs | 17 +++- tests/attestation_validation/tests.rs | 121 +++++++++++++++++++++--- tests/block_validation/tests.rs | 9 +- 4 files changed, 127 insertions(+), 22 deletions(-) diff --git a/lighthouse/main.rs b/lighthouse/main.rs index 33edddd556..c90bcdaea5 100644 --- a/lighthouse/main.rs +++ b/lighthouse/main.rs @@ -1,5 +1,3 @@ -#![feature(test)] - #[macro_use] extern crate slog; extern crate slog_term; diff --git a/tests/attestation_validation/helpers.rs b/tests/attestation_validation/helpers.rs index a93d8d531e..3a42db9e1b 100644 --- a/tests/attestation_validation/helpers.rs +++ b/tests/attestation_validation/helpers.rs @@ -10,7 +10,6 @@ use super::db::stores::{ use super::state::attestation_record::{ AttestationRecord, AttestationValidationContext, - AttestationValidationError, }; use super::state::block::validation::AttesterMap; use super::bls::{ @@ -48,6 +47,13 @@ impl TestStore { } } +pub struct TestRig { + pub attestation: AttestationRecord, + pub context: AttestationValidationContext, + pub stores: TestStore, + pub attester_count: usize, +} + fn generate_message_hash(slot: u64, parent_hashes: &[Hash256], shard_id: u16, @@ -121,7 +127,7 @@ pub fn generate_attestation(shard_id: u16, } pub fn setup_attestation_validation_test(shard_id: u16, attester_count: usize) - -> (AttestationRecord, AttestationValidationContext, TestStore) + -> TestRig { let stores = TestStore::new(); @@ -177,5 +183,10 @@ pub fn setup_attestation_validation_test(shard_id: u16, attester_count: usize) &parent_hashes.clone(), &signing_keys); - (attestation, context, stores) + TestRig { + attestation, + context, + stores, + attester_count, + } } diff --git a/tests/attestation_validation/tests.rs b/tests/attestation_validation/tests.rs index 6ea3d722b6..f486cab37c 100644 --- a/tests/attestation_validation/tests.rs +++ b/tests/attestation_validation/tests.rs @@ -1,36 +1,127 @@ use std::sync::Arc; use super::helpers::{ - TestStore, + TestRig, setup_attestation_validation_test, }; use super::state::attestation_record::{ - AttestationRecord, - AttestationValidationContext, AttestationValidationError, }; use super::state::block::validation::AttesterMap; use super::bls::{ AggregateSignature, - Keypair, -}; -use super::db::{ - MemoryDB, -}; -use super::db::stores::{ - BlockStore, - ValidatorStore, }; use super::utils::types::{ Hash256, - Bitfield, }; +fn generic_rig() -> TestRig { + let shard_id = 10; + let validator_count = 2; + setup_attestation_validation_test(shard_id, validator_count) +} + #[test] fn test_attestation_validation_valid() { - let (a, c, _stores) = setup_attestation_validation_test(10, 2); + let rig = generic_rig(); - let result = c.validate_attestation(&a); + let result = rig.context.validate_attestation(&rig.attestation); - assert!(result.unwrap().is_some()); + let voter_map = result.unwrap(); + assert_eq!(voter_map.len(), 2); +} + +#[test] +fn test_attestation_validation_invalid_slot_too_high() { + let mut rig = generic_rig(); + + rig.attestation.slot = rig.context.block_slot + 1; + + let result = rig.context.validate_attestation(&rig.attestation); + assert_eq!(result, Err(AttestationValidationError::SlotTooHigh)); +} + +#[test] +fn test_attestation_validation_invalid_slot_too_low() { + let mut rig = generic_rig(); + + rig.attestation.slot = rig.context.block_slot - u64::from(rig.context.cycle_length) - 2; + let result = rig.context.validate_attestation(&rig.attestation); + assert_eq!(result, Err(AttestationValidationError::SlotTooLow)); +} + +#[test] +fn test_attestation_validation_invalid_justified_slot_incorrect() { + let mut rig = generic_rig(); + + let original = rig.attestation.justified_slot; + rig.attestation.justified_slot = original - 1; + let result = rig.context.validate_attestation(&rig.attestation); + assert_eq!(result, Err(AttestationValidationError::JustifiedSlotIncorrect)); + + rig.attestation.justified_slot = original + 1; + let result = rig.context.validate_attestation(&rig.attestation); + assert_eq!(result, Err(AttestationValidationError::JustifiedSlotIncorrect)); +} + +#[test] +fn test_attestation_validation_invalid_too_many_oblique() { + let mut rig = generic_rig(); + + let obliques: Vec = (0..(rig.context.cycle_length + 1)) + .map(|i| Hash256::from((i * 2) as u64)) + .collect(); + + rig.attestation.oblique_parent_hashes = obliques; + + let result = rig.context.validate_attestation(&rig.attestation); + assert_eq!(result, Err(AttestationValidationError::TooManyObliqueHashes)); +} + +#[test] +fn test_attestation_validation_invalid_bad_attester_map() { + let mut rig = generic_rig(); + + rig.context.attester_map = Arc::new(AttesterMap::new()); + + let result = rig.context.validate_attestation(&rig.attestation); + assert_eq!(result, Err(AttestationValidationError::BadAttesterMap)); +} + +#[test] +fn test_attestation_validation_invalid_bad_bitfield_length() { + let mut rig = generic_rig(); + + /* + * Extend the bitfield by one byte + * + * This is a little hacky and makes assumptions about the internals + * of the bitfield. + */ + let one_byte_higher = rig.attester_count + 8; + rig.attestation.attester_bitfield.set_bit(one_byte_higher, true); + rig.attestation.attester_bitfield.set_bit(one_byte_higher, false); + + let result = rig.context.validate_attestation(&rig.attestation); + assert_eq!(result, Err(AttestationValidationError::BadBitfieldLength)); +} + +#[test] +fn test_attestation_validation_invalid_unknown_justfied_block_hash() { + let mut rig = generic_rig(); + + rig.attestation.justified_block_hash = Hash256::from("unknown block hash".as_bytes()); + + let result = rig.context.validate_attestation(&rig.attestation); + assert_eq!(result, Err(AttestationValidationError::UnknownJustifiedBlock)); +} + +#[test] +fn test_attestation_validation_invalid_empty_signature() { + let mut rig = generic_rig(); + + rig.attestation.aggregate_sig = AggregateSignature::new(); + + let result = rig.context.validate_attestation(&rig.attestation); + assert_eq!(result, Err(AttestationValidationError::BadAggregateSignature)); } diff --git a/tests/block_validation/tests.rs b/tests/block_validation/tests.rs index 6adf026b0f..d3c18af849 100644 --- a/tests/block_validation/tests.rs +++ b/tests/block_validation/tests.rs @@ -16,6 +16,9 @@ use super::state::block::validation::{ BlockStatus, ProposerMap, }; +use super::state::attestation_record::{ + AttestationValidationError, +}; use super::utils::hash::canonical_hash; use super::utils::types::{ Hash256, @@ -177,7 +180,8 @@ fn test_block_validation_invalid_1st_attestation_signature() { ¶ms, mutator); - assert_eq!(status, Err(SszBlockValidationError::FirstAttestationSignatureFailed)); + assert_eq!(status, Err(SszBlockValidationError::AttestationValidationError( + AttestationValidationError::BadAggregateSignature))); } #[test] @@ -236,5 +240,6 @@ fn test_block_validation_invalid_2nd_attestation_signature() { ¶ms, mutator); - assert_eq!(status, Err(SszBlockValidationError::AttestationSignatureFailed)); + assert_eq!(status, Err(SszBlockValidationError::AttestationValidationError( + AttestationValidationError::BadAggregateSignature))); }