From 966d891cb53afc75b67bdabfdc0aac19f5445cfa Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Wed, 26 Sep 2018 11:40:28 +1000 Subject: [PATCH] Remove validation fns (will be added in a PR) --- lighthouse/state/attestation_record/mod.rs | 3 - .../validation/attestation_validation.rs | 203 ---------------- .../validation/message_generation.rs | 32 --- .../attestation_record/validation/mod.rs | 16 -- .../validation/signature_verification.rs | 183 -------------- lighthouse/state/block/mod.rs | 3 - lighthouse/state/block/validation/mod.rs | 19 -- lighthouse/state/block/validation/tests.rs | 193 --------------- .../block/validation/validate_ssz_block.rs | 227 ------------------ lighthouse/state/mod.rs | 1 - 10 files changed, 880 deletions(-) delete mode 100644 lighthouse/state/attestation_record/validation/attestation_validation.rs delete mode 100644 lighthouse/state/attestation_record/validation/message_generation.rs delete mode 100644 lighthouse/state/attestation_record/validation/mod.rs delete mode 100644 lighthouse/state/attestation_record/validation/signature_verification.rs delete mode 100644 lighthouse/state/block/validation/mod.rs delete mode 100644 lighthouse/state/block/validation/tests.rs delete mode 100644 lighthouse/state/block/validation/validate_ssz_block.rs diff --git a/lighthouse/state/attestation_record/mod.rs b/lighthouse/state/attestation_record/mod.rs index 447bb5382..d96a451fd 100644 --- a/lighthouse/state/attestation_record/mod.rs +++ b/lighthouse/state/attestation_record/mod.rs @@ -1,13 +1,10 @@ use super::bls; -use super::common; -use super::db; use super::ssz; use super::utils; mod attestation_record; mod ssz_splitter; -pub mod validation; pub use self::attestation_record::{ AttestationRecord, diff --git a/lighthouse/state/attestation_record/validation/attestation_validation.rs b/lighthouse/state/attestation_record/validation/attestation_validation.rs deleted file mode 100644 index 5070ebb44..000000000 --- a/lighthouse/state/attestation_record/validation/attestation_validation.rs +++ /dev/null @@ -1,203 +0,0 @@ -use std::collections::HashSet; -use std::sync::Arc; -use super::attestation_record::AttestationRecord; -use super::AttesterMap; -use super::attestation_parent_hashes::{ - attestation_parent_hashes, - ParentHashesError, -}; -use super::db::{ - ClientDB, - DBError -}; -use super::db::stores::{ - BlockStore, - ValidatorStore, -}; -use super::utils::types::{ - Hash256, -}; -use super::message_generation::generate_signed_message; -use super::signature_verification::{ - verify_aggregate_signature_for_indices, - SignatureVerificationError, -}; - -#[derive(Debug,PartialEq)] -pub enum AttestationValidationError { - SlotTooHigh, - SlotTooLow, - JustifiedSlotTooHigh, - UnknownJustifiedBlock, - TooManyObliqueHashes, - BadCurrentHashes, - BadObliqueHashes, - BadAttesterMap, - IntWrapping, - PublicKeyCorrupt, - NoPublicKeyForValidator, - BadBitfieldLength, - InvalidBitfield, - InvalidBitfieldEndBits, - NoSignatures, - NonZeroTrailingBits, - AggregateSignatureFail, - DBError(String), -} - -fn bytes_for_bits(bits: usize) -> usize { - (bits.saturating_sub(1) / 8) + 1 -} - -fn any_of_last_n_bits_are_set(byte: &u8, n: usize) -> bool { - let shift = 8_u16.saturating_sub(n as u16); - ((!0 << shift) & u16::from(*byte)) > 0 -} - -pub fn validate_attestation(a: &AttestationRecord, - block_slot: u64, - cycle_length: u8, - known_last_justified_slot: u64, - known_parent_hashes: Arc>, - block_store: Arc>, - validator_store: Arc>, - attester_map: Arc) - -> Result>, AttestationValidationError> - where T: ClientDB + Sized -{ - /* - * The attesation slot must not be higher than the block that contained it. - */ - if a.slot > block_slot { - return Err(AttestationValidationError::SlotTooHigh); - } - - /* - * The slot of this attestation must not be more than cycle_length + 1 distance - * from the block that contained it. - * - * The below code stays overflow-safe as long as cycle length is a < 64 bit integer. - */ - if a.slot < block_slot.saturating_sub(u64::from(cycle_length) + 1) { - return Err(AttestationValidationError::SlotTooLow); - } - - /* - * The attestation must indicate that its last justified slot is the same as the last justified - * slot known to us. - */ - if a.justified_slot > known_last_justified_slot { - return Err(AttestationValidationError::JustifiedSlotTooHigh); - } - - /* - * There is no need to include more oblique parents hashes than there are blocks - * in a cycle. - */ - if a.oblique_parent_hashes.len() > usize::from(cycle_length) { - return Err(AttestationValidationError::TooManyObliqueHashes); - } - - /* - * Retrieve the set of attestation indices for this slot and shard id. - * - * This is an array mapping the order that validators will appear in the bitfield to the - * canonincal index of a validator. - */ - let attestation_indices = attester_map.get(&(a.slot, a.shard_id.into())) - .ok_or(AttestationValidationError::BadAttesterMap)?; - - /* - * The bitfield must be no longer than the minimum required to represent each validator in the - * attestation indicies for this slot and shard id. - */ - if a.attester_bitfield.num_bytes() != - bytes_for_bits(attestation_indices.len()) - { - return Err(AttestationValidationError::BadBitfieldLength); - } - - /* - * If there are excess bits in the bitfield because the number of a validators in not a - * multiple of 8, reject this attestation record. - * - * Allow extra set bits would permit mutliple different byte layouts (and therefore hashes) to - * refer to the same AttesationRecord. - */ - let last_byte = - a.attester_bitfield.get_byte(a.attester_bitfield.num_bytes() - 1) - .ok_or(AttestationValidationError::InvalidBitfield)?; - if any_of_last_n_bits_are_set(last_byte, a.attester_bitfield.len() % 8) { - return Err(AttestationValidationError::InvalidBitfieldEndBits) - } - - /* - * The specified justified block hash must be known to us - */ - if !block_store.block_exists(&a.justified_block_hash)? { - return Err(AttestationValidationError::UnknownJustifiedBlock) - } - - let signed_message = { - let parent_hashes = attestation_parent_hashes( - cycle_length, - block_slot, - a.slot, - &known_parent_hashes, - &a.oblique_parent_hashes)?; - generate_signed_message( - a.slot, - &parent_hashes, - a.shard_id, - &a.shard_block_hash, - a.justified_slot) - }; - - let voted_hashmap = - verify_aggregate_signature_for_indices( - &signed_message, - &a.aggregate_sig, - &attestation_indices, - &a.attester_bitfield, - &validator_store)?; - - Ok(voted_hashmap) -} - -impl From for AttestationValidationError { - fn from(e: ParentHashesError) -> Self { - match e { - ParentHashesError::BadCurrentHashes - => AttestationValidationError::BadCurrentHashes, - ParentHashesError::BadObliqueHashes - => AttestationValidationError::BadObliqueHashes, - ParentHashesError::SlotTooLow - => AttestationValidationError::SlotTooLow, - ParentHashesError::SlotTooHigh - => AttestationValidationError::SlotTooHigh, - ParentHashesError::IntWrapping - => AttestationValidationError::IntWrapping - } - } -} - -impl From for AttestationValidationError { - fn from(e: DBError) -> Self { - AttestationValidationError::DBError(e.message) - } -} - -impl From for AttestationValidationError { - fn from(e: SignatureVerificationError) -> Self { - match e { - SignatureVerificationError::BadValidatorIndex - => AttestationValidationError::BadAttesterMap, - SignatureVerificationError::PublicKeyCorrupt - => AttestationValidationError::PublicKeyCorrupt, - SignatureVerificationError::NoPublicKeyForValidator - => AttestationValidationError::NoPublicKeyForValidator, - SignatureVerificationError::DBError(s) - => AttestationValidationError::DBError(s), - } - } -} diff --git a/lighthouse/state/attestation_record/validation/message_generation.rs b/lighthouse/state/attestation_record/validation/message_generation.rs deleted file mode 100644 index 3bcc4c16a..000000000 --- a/lighthouse/state/attestation_record/validation/message_generation.rs +++ /dev/null @@ -1,32 +0,0 @@ -use super::ssz::SszStream; -use super::utils::hash::canonical_hash; -use super::utils::types::Hash256; - -/// Generates the message used to validate the signature provided with an AttestationRecord. -/// -/// Ensures that the signer of the message has a view of the chain that is compatible with ours. -pub fn generate_signed_message(slot: u64, - parent_hashes: &[Hash256], - shard_id: u16, - shard_block_hash: &Hash256, - justified_slot: u64) - -> Vec -{ - /* - * Note: it's a little risky here to use SSZ, because the encoding is not necessarily SSZ - * (for example, SSZ might change whilst this doesn't). - * - * I have suggested switching this to ssz here: - * https://github.com/ethereum/eth2.0-specs/issues/5 - * - * If this doesn't happen, it would be safer to not use SSZ at all. - */ - let mut ssz_stream = SszStream::new(); - ssz_stream.append(&slot); - ssz_stream.append_vec(&parent_hashes.to_vec()); - ssz_stream.append(&shard_id); - ssz_stream.append(shard_block_hash); - ssz_stream.append(&justified_slot); - let bytes = ssz_stream.drain(); - canonical_hash(&bytes) -} diff --git a/lighthouse/state/attestation_record/validation/mod.rs b/lighthouse/state/attestation_record/validation/mod.rs deleted file mode 100644 index e70a16a2a..000000000 --- a/lighthouse/state/attestation_record/validation/mod.rs +++ /dev/null @@ -1,16 +0,0 @@ -use super::common::maps::AttesterMap; -use super::db; -use super::bls; -use super::attestation_record; -use super::ssz; -use super::common::attestation_parent_hashes; -use super::utils; - -mod attestation_validation; -mod signature_verification; -mod message_generation; - -pub use self::attestation_validation::{ - validate_attestation, - AttestationValidationError, -}; diff --git a/lighthouse/state/attestation_record/validation/signature_verification.rs b/lighthouse/state/attestation_record/validation/signature_verification.rs deleted file mode 100644 index c33dc2806..000000000 --- a/lighthouse/state/attestation_record/validation/signature_verification.rs +++ /dev/null @@ -1,183 +0,0 @@ -use std::collections::HashSet; -use super::bls::{ - AggregateSignature, - AggregatePublicKey, -}; -use super::db::ClientDB; -use super::db::stores::{ - ValidatorStore, - ValidatorStoreError, -}; -use super::utils::types::Bitfield; - -#[derive(Debug, PartialEq)] -pub enum SignatureVerificationError { - BadValidatorIndex, - PublicKeyCorrupt, - NoPublicKeyForValidator, - DBError(String), -} - -/// Verify an aggregate signature across the supplied message. -/// -/// The public keys used for verification are collected by mapping -/// each true bitfield bit to canonical ValidatorRecord index through -/// the attestation_indicies map. -/// -/// Each public key is loaded from the store on-demand. -pub fn verify_aggregate_signature_for_indices( - message: &[u8], - agg_sig: &AggregateSignature, - attestation_indices: &[usize], - bitfield: &Bitfield, - validator_store: &ValidatorStore) - -> Result>, SignatureVerificationError> - where T: ClientDB + Sized -{ - let mut voters = HashSet::new(); - let mut agg_pub_key = AggregatePublicKey::new(); - - for i in 0..attestation_indices.len() { - let voted = bitfield.get_bit(i); - if voted { - /* - * De-reference the attestation index into a canonical ValidatorRecord index. - */ - let validator = *attestation_indices.get(i) - .ok_or(SignatureVerificationError::BadValidatorIndex)?; - /* - * Load the validators public key from our store. - */ - let pub_key = validator_store - .get_public_key_by_index(validator)? - .ok_or(SignatureVerificationError::NoPublicKeyForValidator)?; - /* - * Add the validators public key to the aggregate public key. - */ - agg_pub_key.add(&pub_key); - /* - * Add to the validator to the set of voters for this attestation record. - */ - voters.insert(validator); - } - } - /* - * Verify the aggregate public key against the aggregate signature. - * - * This verification will only succeed if the exact set of public keys - * were added to the aggregate public key as those that signed the aggregate signature. - */ - if agg_sig.verify(&message, &agg_pub_key) { - Ok(Some(voters)) - } else { - Ok(None) - } -} - -impl From for SignatureVerificationError { - fn from(error: ValidatorStoreError) -> Self { - match error { - ValidatorStoreError::DBError(s) => - SignatureVerificationError::DBError(s), - ValidatorStoreError::DecodeError => - SignatureVerificationError::PublicKeyCorrupt, - } - } -} - - -#[cfg(test)] -mod tests { - use super::*; - use super::super::bls::{ - Keypair, - Signature, - }; - use super::super::db::MemoryDB; - use std::sync::Arc; - - /* - * Cases that still need testing: - * - * - No signatures. - * - Database failure. - * - Unknown validator index. - * - Extra validator on signature. - */ - - #[test] - fn test_signature_verification() { - let message = "cats".as_bytes(); - let signing_keypairs = vec![ - Keypair::random(), - Keypair::random(), - Keypair::random(), - Keypair::random(), - Keypair::random(), - Keypair::random(), - ]; - let non_signing_keypairs = vec![ - Keypair::random(), - Keypair::random(), - Keypair::random(), - Keypair::random(), - Keypair::random(), - Keypair::random(), - ]; - /* - * Signing keypairs first, then non-signing - */ - let mut all_keypairs = signing_keypairs.clone(); - all_keypairs.append(&mut non_signing_keypairs.clone()); - - let attestation_indices: Vec = (0..all_keypairs.len()) - .collect(); - let mut bitfield = Bitfield::new(); - for i in 0..signing_keypairs.len() { - bitfield.set_bit(i, true); - } - - let db = Arc::new(MemoryDB::open()); - let store = ValidatorStore::new(db); - - for (i, keypair) in all_keypairs.iter().enumerate() { - store.put_public_key_by_index(i, &keypair.pk).unwrap(); - } - - let mut agg_sig = AggregateSignature::new(); - for keypair in &signing_keypairs { - let sig = Signature::new(&message, &keypair.sk); - agg_sig.add(&sig); - } - - /* - * Test using all valid parameters. - */ - let voters = verify_aggregate_signature_for_indices( - &message, - &agg_sig, - &attestation_indices, - &bitfield, - &store).unwrap(); - - let voters = voters.unwrap(); - (0..signing_keypairs.len()) - .for_each(|i| assert!(voters.contains(&i))); - (signing_keypairs.len()..non_signing_keypairs.len()) - .for_each(|i| assert!(!voters.contains(&i))); - - /* - * Add another validator to the bitfield, run validation will all other - * parameters the same and assert that it fails. - */ - bitfield.set_bit(signing_keypairs.len() + 1, true); - let voters = verify_aggregate_signature_for_indices( - &message, - &agg_sig, - &attestation_indices, - &bitfield, - &store).unwrap(); - - assert_eq!(voters, None); - } -} diff --git a/lighthouse/state/block/mod.rs b/lighthouse/state/block/mod.rs index c1279111b..20467eca7 100644 --- a/lighthouse/state/block/mod.rs +++ b/lighthouse/state/block/mod.rs @@ -1,14 +1,11 @@ extern crate blake2_rfc; -use super::common; -use super::db; use super::ssz; use super::utils; use super::attestation_record; mod block; mod ssz_block; -mod validation; pub use self::block::Block; pub use self::ssz_block::SszBlock; diff --git a/lighthouse/state/block/validation/mod.rs b/lighthouse/state/block/validation/mod.rs deleted file mode 100644 index 59aa3fc15..000000000 --- a/lighthouse/state/block/validation/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -mod validate_ssz_block; -#[cfg(test)] -mod tests; - -use super::attestation_record; -use super::SszBlock; -use super::db; -use super::ssz; -use super::utils; - -use super::common::maps::{ - AttesterMap, - ProposerMap, -}; -pub use self::validate_ssz_block::{ - validate_ssz_block, - SszBlockValidationError, - BlockStatus, -}; diff --git a/lighthouse/state/block/validation/tests.rs b/lighthouse/state/block/validation/tests.rs deleted file mode 100644 index e04f16b2a..000000000 --- a/lighthouse/state/block/validation/tests.rs +++ /dev/null @@ -1,193 +0,0 @@ -extern crate ssz; - -use self::ssz::{ - SszStream, -}; -use std::sync::Arc; -use super::{ - validate_ssz_block, - BlockStatus, - AttesterMap, - ProposerMap, -}; -use super::db::stores::{ - BlockStore, - PoWChainStore, - ValidatorStore, -}; -use super::db::{ - MemoryDB, -}; -use super::utils::hash::canonical_hash; -use super::utils::types::{ - Hash256, - Bitfield, -}; -use super::{ - Block, - SszBlock, -}; -use super::super::attestation_record::AttestationRecord; -use super::super::super::bls::{ - Keypair, - Signature, - AggregateSignature, -}; - -struct TestStore { - db: Arc, - block: Arc>, - pow_chain: Arc>, - validator: Arc>, -} - -impl TestStore { - pub fn new() -> Self { - let db = Arc::new(MemoryDB::open()); - let block = Arc::new(BlockStore::new(db.clone())); - let pow_chain = Arc::new(PoWChainStore::new(db.clone())); - let validator = Arc::new(ValidatorStore::new(db.clone())); - Self { - db, - block, - pow_chain, - validator, - } - } -} - -#[test] -fn test_block_validation() { - let stores = TestStore::new(); - - let cycle_length: u8 = 2; - let shard_count: u16 = 2; - let present_slot = u64::from(cycle_length) * 10000; - let justified_slot = present_slot - u64::from(cycle_length); - let justified_block_hash = Hash256::from("justified_hash".as_bytes()); - let shard_block_hash = Hash256::from("shard_hash".as_bytes()); - let parent_hashes: Vec = (0..(cycle_length * 2)) - .map(|i| Hash256::from(i as u64)) - .collect(); - let pow_chain_ref = Hash256::from("pow_chain".as_bytes()); - let active_state_root = Hash256::from("active_state".as_bytes()); - let crystallized_state_root = Hash256::from("cry_state".as_bytes()); - - stores.pow_chain.put_block_hash(pow_chain_ref.as_ref()).unwrap(); - stores.block.put_block(justified_block_hash.as_ref(), &vec![42]).unwrap(); - - let validators_per_shard = 2; - - let block_slot = present_slot; - let validator_index: usize = 0; - let proposer_map = { - let mut proposer_map = ProposerMap::new(); - proposer_map.insert(present_slot, validator_index); - proposer_map - }; - let (attester_map, attestations, _keypairs) = { - let mut i = 0; - let mut attester_map = AttesterMap::new(); - let mut attestations = vec![]; - let mut keypairs = vec![]; - for shard in 0..shard_count { - let mut attesters = vec![]; - let mut attester_bitfield = Bitfield::new(); - let mut aggregate_sig = AggregateSignature::new(); - let attestation_slot = block_slot - 1; - - let parent_hashes_slice = { - let distance: usize = (block_slot - attestation_slot) as usize; - let last: usize = parent_hashes.len() - distance; - let first: usize = last - usize::from(cycle_length); - &parent_hashes[first..last] - }; - - let attestation_message = { - let mut stream = SszStream::new(); - stream.append(&attestation_slot); - stream.append_vec(&parent_hashes_slice.to_vec()); - stream.append(&shard); - stream.append(&shard_block_hash); - stream.append(&justified_slot); - let bytes = stream.drain(); - canonical_hash(&bytes) - }; - - - - for attestation_index in 0..validators_per_shard { - /* - * Add the attester to the attestation indices for this shard. - */ - attesters.push(i); - /* - * Set the voters bit on the bitfield to true. - */ - attester_bitfield.set_bit(attestation_index, true); - /* - * Generate a random keypair for this validatior and clone it into the - * list of keypairs. - */ - let keypair = Keypair::random(); - keypairs.push(keypair.clone()); - /* - * Store the validators public key in the database. - */ - stores.validator.put_public_key_by_index(i, &keypair.pk).unwrap(); - /* - * Generate a new signature and aggregate it on the rolling signature. - */ - let sig = Signature::new(&attestation_message, &keypair.sk); - aggregate_sig.add(&sig); - /* - * Increment the validator counter to monotonically assign validators. - */ - i += 1; - } - - attester_map.insert((attestation_slot, shard), attesters); - let attestation = AttestationRecord { - slot: attestation_slot, - shard_id: shard, - oblique_parent_hashes: vec![], - shard_block_hash, - attester_bitfield, - justified_slot, - justified_block_hash, - aggregate_sig, - }; - attestations.push(attestation); - } - (attester_map, attestations, keypairs) - }; - - let block = Block { - parent_hash: Hash256::from("parent".as_bytes()), - slot_number: block_slot, - randao_reveal: Hash256::from("randao".as_bytes()), - attestations, - pow_chain_ref, - active_state_root, - crystallized_state_root, - }; - - let mut stream = SszStream::new(); - stream.append(&block); - let serialized_block = stream.drain(); - let ssz_block = SszBlock::from_slice(&serialized_block[..]).unwrap(); - - let status = validate_ssz_block( - &ssz_block, - present_slot, - cycle_length, - justified_slot, - Arc::new(parent_hashes), - Arc::new(proposer_map), - Arc::new(attester_map), - stores.block.clone(), - stores.validator.clone(), - stores.pow_chain.clone()).unwrap(); - - assert_eq!(status, BlockStatus::NewBlock); -} diff --git a/lighthouse/state/block/validation/validate_ssz_block.rs b/lighthouse/state/block/validation/validate_ssz_block.rs deleted file mode 100644 index a3f015b41..000000000 --- a/lighthouse/state/block/validation/validate_ssz_block.rs +++ /dev/null @@ -1,227 +0,0 @@ -use std::sync::Arc; -use super::attestation_record::validation::{ - validate_attestation, - AttestationValidationError, -}; -use super::attestation_record::{ - AttestationRecord, - split_one_attestation, - split_all_attestations, - AttestationSplitError, -}; -use super::{ - AttesterMap, - ProposerMap, -}; -use super::SszBlock; -use super::db::{ - ClientDB, - DBError, -}; -use super::db::stores::{ - BlockStore, - PoWChainStore, - ValidatorStore, -}; -use super::ssz::{ - Decodable, - DecodeError, -}; -use super::utils::types::Hash256; - -#[derive(Debug, PartialEq)] -pub enum BlockStatus { - NewBlock, - KnownBlock, -} - -#[derive(Debug, PartialEq)] -pub enum SszBlockValidationError { - FutureSlot, - UnknownPoWChainRef, - BadAttestationSsz, - AttestationValidationError(AttestationValidationError), - AttestationSignatureFailed, - FirstAttestationSignatureFailed, - NoProposerSignature, - BadProposerMap, - DatabaseError(String), -} - -/// Validate some SszBlock. An SszBlock varies from a Block in that is a read-only structure -/// that reads directly from encoded SSZ. -/// -/// The reason to validate an SzzBlock is to avoid decoding it in its entirety if there is -/// a suspicion that the block might be invalid. Such a suspicion should be applied to -/// all blocks coming from the network. -/// -/// Of course, this function will only be more efficient if a block is already serialized. -/// Serializing a complete block and then validating with this function will be less -/// efficient than just validating the original block. -/// -/// This function will determine if the block is new, already known or invalid (either -/// intrinsically or due to some application error.) -#[allow(dead_code)] -pub fn validate_ssz_block(b: &SszBlock, - expected_slot: u64, - cycle_length: u8, - last_justified_slot: u64, - parent_hashes: Arc>, - proposer_map: Arc, - attester_map: Arc, - block_store: Arc>, - validator_store: Arc>, - pow_store: Arc>) - -> Result - where T: ClientDB + Sized -{ - /* - * If this block is already known, return immediately. - */ - if block_store.block_exists(&b.block_hash())? { - return Ok(BlockStatus::KnownBlock); - } - - /* - * Copy the block slot (will be used multiple times) - */ - let block_slot = b.slot_number(); - - /* - * If the block slot corresponds to a slot in the future (according to the local time), - * drop it. - */ - if block_slot > expected_slot { - return Err(SszBlockValidationError::FutureSlot); - } - - /* - * If the PoW chain hash is not known to us, drop it. - * - * We only accept blocks that reference a known PoW hash. - * - * Note: it is not clear what a "known" PoW chain ref is. Likely, - * it means "sufficienty deep in the canonical PoW chain". - */ - if pow_store.block_hash_exists(b.pow_chain_ref())? == false { - return Err(SszBlockValidationError::UnknownPoWChainRef); - } - - /* - * Store a reference to the serialized attestations from the block. - */ - let attestations_ssz = &b.attestations(); - - /* - * Get a slice of the first serialized attestation (the 0th) and decode it into - * a full AttestationRecord object. - */ - let (first_attestation_ssz, next_index) = split_one_attestation( - &attestations_ssz, - 0)?; - let (first_attestation, _) = AttestationRecord::ssz_decode( - &first_attestation_ssz, 0)?; - - /* - * Validate this first attestation. - * - * It is a requirement that the block proposer for this slot - * must have signed the 0th attestation record. - */ - let attestation_voters = validate_attestation( - &first_attestation, - block_slot, - cycle_length, - last_justified_slot, - parent_hashes.clone(), - block_store.clone(), - validator_store.clone(), - attester_map.clone())?; - - /* - * If the set of voters is None, the attestation was invalid. - */ - let attestation_voters = attestation_voters - .ok_or(SszBlockValidationError:: - FirstAttestationSignatureFailed)?; - - /* - * Read the proposer from the map of slot -> validator index. - */ - let proposer = proposer_map.get(&block_slot) - .ok_or(SszBlockValidationError::BadProposerMap)?; - - /* - * If the proposer for this slot was not a voter, reject the block. - */ - if !attestation_voters.contains(&proposer) { - return Err(SszBlockValidationError::NoProposerSignature); - } - - /* - * Split the remaining attestations into a vector of slices, each containing - * a single serialized attestation record. - */ - let other_attestations = split_all_attestations(attestations_ssz, - next_index)?; - - /* - * Verify each other AttestationRecord. - * - * TODO: make this parallelized. - */ - for attestation in other_attestations { - let (a, _) = AttestationRecord::ssz_decode(&attestation, 0)?; - let attestation_voters = validate_attestation( - &a, - block_slot, - cycle_length, - last_justified_slot, - parent_hashes.clone(), - block_store.clone(), - validator_store.clone(), - attester_map.clone())?; - if attestation_voters.is_none() { - return Err(SszBlockValidationError:: - AttestationSignatureFailed); - } - } - - /* - * If we have reached this point, the block is a new valid block that is worthy of - * processing. - */ - Ok(BlockStatus::NewBlock) -} - -impl From for SszBlockValidationError { - fn from(e: DBError) -> Self { - SszBlockValidationError::DatabaseError(e.message) - } -} - -impl From for SszBlockValidationError { - fn from(e: AttestationSplitError) -> Self { - match e { - AttestationSplitError::TooShort => - SszBlockValidationError::BadAttestationSsz - } - } -} - -impl From for SszBlockValidationError { - fn from(e: DecodeError) -> Self { - match e { - DecodeError::TooShort => - SszBlockValidationError::BadAttestationSsz, - DecodeError::TooLong => - SszBlockValidationError::BadAttestationSsz, - } - } -} - -impl From for SszBlockValidationError { - fn from(e: AttestationValidationError) -> Self { - SszBlockValidationError::AttestationValidationError(e) - } -} diff --git a/lighthouse/state/mod.rs b/lighthouse/state/mod.rs index b49ab52cf..1a8d4a2c4 100644 --- a/lighthouse/state/mod.rs +++ b/lighthouse/state/mod.rs @@ -16,5 +16,4 @@ pub mod shard_and_committee; pub mod validator_record; use super::bls; -use super::db; use super::utils;