Update validation as per new spec
- Block -> BeaconBlock - Updates to SszBeaconBlock
This commit is contained in:
		
							parent
							
								
									c45e05ca02
								
							
						
					
					
						commit
						c3d88a7e80
					
				| @ -13,8 +13,8 @@ use super::db::{ | ||||
|     DBError | ||||
| }; | ||||
| use super::db::stores::{ | ||||
|     BlockStore, | ||||
|     BlockAtSlotError, | ||||
|     BeaconBlockStore, | ||||
|     BeaconBlockAtSlotError, | ||||
|     ValidatorStore, | ||||
| }; | ||||
| use super::types::{ | ||||
| @ -64,7 +64,7 @@ pub struct AttestationValidationContext<T> | ||||
|     /// A vec of the hashes of the blocks preceeding the present slot.
 | ||||
|     pub parent_hashes: Arc<Vec<Hash256>>, | ||||
|     /// The store containing block information.
 | ||||
|     pub block_store: Arc<BlockStore<T>>, | ||||
|     pub block_store: Arc<BeaconBlockStore<T>>, | ||||
|     /// The store containing validator information.
 | ||||
|     pub validator_store: Arc<ValidatorStore<T>>, | ||||
|     /// A map of (slot, shard_id) to the attestation set of validation indices.
 | ||||
| @ -223,10 +223,10 @@ impl From<ParentHashesError> for AttestationValidationError { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<BlockAtSlotError> for AttestationValidationError { | ||||
|     fn from(e: BlockAtSlotError) -> Self { | ||||
| impl From<BeaconBlockAtSlotError> for AttestationValidationError { | ||||
|     fn from(e: BeaconBlockAtSlotError) -> Self { | ||||
|         match e { | ||||
|             BlockAtSlotError::DBError(s) => AttestationValidationError::DBError(s), | ||||
|             BeaconBlockAtSlotError::DBError(s) => AttestationValidationError::DBError(s), | ||||
|             _ => AttestationValidationError::InvalidJustifiedBlockHash | ||||
| 
 | ||||
|         } | ||||
|  | ||||
| @ -13,7 +13,7 @@ use super::attestation_validation::{ | ||||
| use super::types::{ | ||||
|     AttestationRecord, | ||||
|     AttesterMap, | ||||
|     Block, | ||||
|     BeaconBlock, | ||||
|     ProposerMap, | ||||
| }; | ||||
| use super::ssz_helpers::attestation_ssz_splitter::{ | ||||
| @ -21,16 +21,16 @@ use super::ssz_helpers::attestation_ssz_splitter::{ | ||||
|     split_all_attestations, | ||||
|     AttestationSplitError, | ||||
| }; | ||||
| use super::ssz_helpers::ssz_block::{ | ||||
|     SszBlock, | ||||
|     SszBlockError, | ||||
| use super::ssz_helpers::ssz_beacon_block::{ | ||||
|     SszBeaconBlock, | ||||
|     SszBeaconBlockError, | ||||
| }; | ||||
| use super::db::{ | ||||
|     ClientDB, | ||||
|     DBError, | ||||
| }; | ||||
| use super::db::stores::{ | ||||
|     BlockStore, | ||||
|     BeaconBlockStore, | ||||
|     PoWChainStore, | ||||
|     ValidatorStore, | ||||
| }; | ||||
| @ -41,18 +41,20 @@ use super::ssz::{ | ||||
| use super::types::Hash256; | ||||
| 
 | ||||
| #[derive(Debug, PartialEq)] | ||||
| pub enum BlockStatus { | ||||
| pub enum BeaconBlockStatus { | ||||
|     NewBlock, | ||||
|     KnownBlock, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, PartialEq)] | ||||
| pub enum SszBlockValidationError { | ||||
| pub enum SszBeaconBlockValidationError { | ||||
|     FutureSlot, | ||||
|     SlotAlreadyFinalized, | ||||
|     UnknownPoWChainRef, | ||||
|     UnknownParentHash, | ||||
|     BadAttestationSsz, | ||||
|     BadAncestorHashesSsz, | ||||
|     BadSpecialsSsz, | ||||
|     ParentSlotHigherThanBlockSlot, | ||||
|     AttestationValidationError(AttestationValidationError), | ||||
|     AttestationSignatureFailed, | ||||
| @ -64,7 +66,7 @@ pub enum SszBlockValidationError { | ||||
| } | ||||
| 
 | ||||
| /// The context against which a block should be validated.
 | ||||
| pub struct BlockValidationContext<T> | ||||
| pub struct BeaconBlockValidationContext<T> | ||||
|     where T: ClientDB + Sized | ||||
| { | ||||
|     /// The slot as determined by the system time.
 | ||||
| @ -84,20 +86,20 @@ pub struct BlockValidationContext<T> | ||||
|     /// A map of (slot, shard_id) to the attestation set of validation indices.
 | ||||
|     pub attester_map: Arc<AttesterMap>, | ||||
|     /// The store containing block information.
 | ||||
|     pub block_store: Arc<BlockStore<T>>, | ||||
|     pub block_store: Arc<BeaconBlockStore<T>>, | ||||
|     /// The store containing validator information.
 | ||||
|     pub validator_store: Arc<ValidatorStore<T>>, | ||||
|     /// The store containing information about the proof-of-work chain.
 | ||||
|     pub pow_store: Arc<PoWChainStore<T>>, | ||||
| } | ||||
| 
 | ||||
| impl<T> BlockValidationContext<T> | ||||
| impl<T> BeaconBlockValidationContext<T> | ||||
|     where T: ClientDB | ||||
| { | ||||
|     /// Validate some SszBlock against a block validation context. An SszBlock varies from a Block in
 | ||||
|     /// Validate some SszBeaconBlock against a block validation context. An SszBeaconBlock varies from a BeaconBlock 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
 | ||||
|     /// The reason to validate an SzzBeaconBlock 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.
 | ||||
|     ///
 | ||||
| @ -107,8 +109,8 @@ impl<T> BlockValidationContext<T> | ||||
|     /// Note: this function does not implement randao_reveal checking as it is not in the
 | ||||
|     /// specification.
 | ||||
|     #[allow(dead_code)] | ||||
|     pub fn validate_ssz_block(&self, b: &SszBlock) | ||||
|         -> Result<(BlockStatus, Option<Block>), SszBlockValidationError> | ||||
|     pub fn validate_ssz_block(&self, b: &SszBeaconBlock) | ||||
|         -> Result<(BeaconBlockStatus, Option<BeaconBlock>), SszBeaconBlockValidationError> | ||||
|         where T: ClientDB + Sized | ||||
|     { | ||||
| 
 | ||||
| @ -118,7 +120,7 @@ impl<T> BlockValidationContext<T> | ||||
|          */ | ||||
|         let block_hash = &b.block_hash(); | ||||
|         if self.block_store.block_exists(&block_hash)? { | ||||
|             return Ok((BlockStatus::KnownBlock, None)); | ||||
|             return Ok((BeaconBlockStatus::KnownBlock, None)); | ||||
|         } | ||||
| 
 | ||||
|         /* | ||||
| @ -127,9 +129,9 @@ impl<T> BlockValidationContext<T> | ||||
|          * It is up to the calling fn to determine what should be done with "future" blocks (e.g., | ||||
|          * cache or discard). | ||||
|          */ | ||||
|         let block_slot = b.slot_number(); | ||||
|         let block_slot = b.slot(); | ||||
|         if block_slot > self.present_slot { | ||||
|             return Err(SszBlockValidationError::FutureSlot); | ||||
|             return Err(SszBeaconBlockValidationError::FutureSlot); | ||||
|         } | ||||
| 
 | ||||
|         /* | ||||
| @ -143,7 +145,7 @@ impl<T> BlockValidationContext<T> | ||||
|          * `last_finalized_block` in it's chain. | ||||
|          */ | ||||
|         if block_slot <= self.last_finalized_slot { | ||||
|             return Err(SszBlockValidationError::SlotAlreadyFinalized); | ||||
|             return Err(SszBeaconBlockValidationError::SlotAlreadyFinalized); | ||||
|         } | ||||
| 
 | ||||
|         /* | ||||
| @ -155,15 +157,15 @@ impl<T> BlockValidationContext<T> | ||||
|          * "sufficienty deep in the canonical PoW chain". This should be clarified as the spec | ||||
|          * crystallizes. | ||||
|          */ | ||||
|         let pow_chain_ref = b.pow_chain_ref(); | ||||
|         if !self.pow_store.block_hash_exists(b.pow_chain_ref())? { | ||||
|             return Err(SszBlockValidationError::UnknownPoWChainRef); | ||||
|         let pow_chain_reference = b.pow_chain_reference(); | ||||
|         if !self.pow_store.block_hash_exists(b.pow_chain_reference())? { | ||||
|             return Err(SszBeaconBlockValidationError::UnknownPoWChainRef); | ||||
|         } | ||||
| 
 | ||||
|         /* | ||||
|          * Store a slice of the serialized attestations from the block SSZ. | ||||
|          */ | ||||
|         let attestations_ssz = &b.attestations(); | ||||
|         let attestations_ssz = &b.attestations_without_length(); | ||||
| 
 | ||||
|         /* | ||||
|          * Get a slice of the first serialized attestation (the 0'th) and decode it into | ||||
| @ -185,7 +187,7 @@ impl<T> BlockValidationContext<T> | ||||
|          * of the previous block is attesting to some other block than the one they produced. | ||||
|          */ | ||||
|         if first_attestation.oblique_parent_hashes.len() > 0 { | ||||
|             return Err(SszBlockValidationError::ProposerAttestationHasObliqueHashes); | ||||
|             return Err(SszBeaconBlockValidationError::ProposerAttestationHasObliqueHashes); | ||||
|         } | ||||
| 
 | ||||
|         /* | ||||
| @ -196,12 +198,13 @@ impl<T> BlockValidationContext<T> | ||||
|          * | ||||
|          * Also, read the slot from the parent block for later use. | ||||
|          */ | ||||
|         let parent_hash = b.parent_hash(); | ||||
|         let parent_hash = b.parent_hash() | ||||
|             .ok_or(SszBeaconBlockValidationError::BadAncestorHashesSsz)?; | ||||
|         let parent_block_slot = match self.block_store.get_serialized_block(&parent_hash)? { | ||||
|             None => return Err(SszBlockValidationError::UnknownParentHash), | ||||
|             None => return Err(SszBeaconBlockValidationError::UnknownParentHash), | ||||
|             Some(ssz) => { | ||||
|                 let parent_block = SszBlock::from_slice(&ssz[..])?; | ||||
|                 parent_block.slot_number() | ||||
|                 let parent_block = SszBeaconBlock::from_slice(&ssz[..])?; | ||||
|                 parent_block.slot() | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
| @ -211,7 +214,7 @@ impl<T> BlockValidationContext<T> | ||||
|          * In other words, the parent must come before the child. | ||||
|          */ | ||||
|         if parent_block_slot >= block_slot { | ||||
|             return Err(SszBlockValidationError::ParentSlotHigherThanBlockSlot); | ||||
|             return Err(SszBeaconBlockValidationError::ParentSlotHigherThanBlockSlot); | ||||
|         } | ||||
| 
 | ||||
|         /* | ||||
| @ -242,9 +245,9 @@ impl<T> BlockValidationContext<T> | ||||
|          * attestation of this block, reject the block. | ||||
|          */ | ||||
|         let parent_block_proposer = self.proposer_map.get(&parent_block_slot) | ||||
|             .ok_or(SszBlockValidationError::BadProposerMap)?; | ||||
|             .ok_or(SszBeaconBlockValidationError::BadProposerMap)?; | ||||
|         if !attestation_voters.contains(&parent_block_proposer) { | ||||
|             return Err(SszBlockValidationError::NoProposerSignature); | ||||
|             return Err(SszBeaconBlockValidationError::NoProposerSignature); | ||||
|         } | ||||
| 
 | ||||
|         /* | ||||
| @ -265,7 +268,7 @@ impl<T> BlockValidationContext<T> | ||||
|          * validation. This is so all attestation validation is halted if a single bad attestation | ||||
|          * is found. | ||||
|          */ | ||||
|         let failure: RwLock<Option<SszBlockValidationError>> = RwLock::new(None); | ||||
|         let failure: RwLock<Option<SszBeaconBlockValidationError>> = RwLock::new(None); | ||||
|         let mut deserialized_attestations: Vec<AttestationRecord> = other_attestations | ||||
|             .par_iter() | ||||
|             .filter_map(|attestation_ssz| { | ||||
| @ -286,7 +289,7 @@ impl<T> BlockValidationContext<T> | ||||
|                      */ | ||||
|                     Err(e) => { | ||||
|                         let mut failure = failure.write().unwrap(); | ||||
|                         *failure = Some(SszBlockValidationError::from(e)); | ||||
|                         *failure = Some(SszBeaconBlockValidationError::from(e)); | ||||
|                         None | ||||
|                     } | ||||
|                     /* | ||||
| @ -299,7 +302,7 @@ impl<T> BlockValidationContext<T> | ||||
|                              */ | ||||
|                             Err(e) => { | ||||
|                                 let mut failure = failure.write().unwrap(); | ||||
|                                 *failure = Some(SszBlockValidationError::from(e)); | ||||
|                                 *failure = Some(SszBeaconBlockValidationError::from(e)); | ||||
|                                 None | ||||
|                             } | ||||
|                             /* | ||||
| @ -313,7 +316,7 @@ impl<T> BlockValidationContext<T> | ||||
|             .collect(); | ||||
| 
 | ||||
|         match failure.into_inner() { | ||||
|             Err(_) => return Err(SszBlockValidationError::RwLockPoisoned), | ||||
|             Err(_) => return Err(SszBeaconBlockValidationError::RwLockPoisoned), | ||||
|             Ok(failure) => { | ||||
|                 match failure { | ||||
|                     Some(error) => return Err(error), | ||||
| @ -329,63 +332,69 @@ impl<T> BlockValidationContext<T> | ||||
|          */ | ||||
|         deserialized_attestations.insert(0, first_attestation); | ||||
| 
 | ||||
|         let (ancestor_hashes, _) = Decodable::ssz_decode(&b.ancestor_hashes(), 0) | ||||
|             .map_err(|_| SszBeaconBlockValidationError::BadAncestorHashesSsz)?; | ||||
|         let (specials, _) = Decodable::ssz_decode(&b.specials(), 0) | ||||
|             .map_err(|_| SszBeaconBlockValidationError::BadSpecialsSsz)?; | ||||
| 
 | ||||
|         /* | ||||
|          * If we have reached this point, the block is a new valid block that is worthy of | ||||
|          * processing. | ||||
|          */ | ||||
|         let block = Block { | ||||
|             parent_hash: Hash256::from(parent_hash), | ||||
|             slot_number: block_slot, | ||||
|         let block = BeaconBlock { | ||||
|             slot: block_slot, | ||||
|             randao_reveal: Hash256::from(b.randao_reveal()), | ||||
|             attestations: deserialized_attestations, | ||||
|             pow_chain_ref: Hash256::from(pow_chain_ref), | ||||
|             pow_chain_reference: Hash256::from(pow_chain_reference), | ||||
|             ancestor_hashes, | ||||
|             active_state_root: Hash256::from(b.act_state_root()), | ||||
|             crystallized_state_root: Hash256::from(b.cry_state_root()), | ||||
|             attestations: deserialized_attestations, | ||||
|             specials, | ||||
|         }; | ||||
|         Ok((BlockStatus::NewBlock, Some(block))) | ||||
|         Ok((BeaconBlockStatus::NewBlock, Some(block))) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<DBError> for SszBlockValidationError { | ||||
| impl From<DBError> for SszBeaconBlockValidationError { | ||||
|     fn from(e: DBError) -> Self { | ||||
|         SszBlockValidationError::DBError(e.message) | ||||
|         SszBeaconBlockValidationError::DBError(e.message) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<AttestationSplitError> for SszBlockValidationError { | ||||
| impl From<AttestationSplitError> for SszBeaconBlockValidationError { | ||||
|     fn from(e: AttestationSplitError) -> Self { | ||||
|         match e { | ||||
|             AttestationSplitError::TooShort => | ||||
|                 SszBlockValidationError::BadAttestationSsz | ||||
|                 SszBeaconBlockValidationError::BadAttestationSsz | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<SszBlockError> for SszBlockValidationError { | ||||
|     fn from(e: SszBlockError) -> Self { | ||||
| impl From<SszBeaconBlockError> for SszBeaconBlockValidationError { | ||||
|     fn from(e: SszBeaconBlockError) -> Self { | ||||
|         match e { | ||||
|             SszBlockError::TooShort => | ||||
|                 SszBlockValidationError::DBError("Bad parent block in db.".to_string()), | ||||
|             SszBlockError::TooLong => | ||||
|                 SszBlockValidationError::DBError("Bad parent block in db.".to_string()), | ||||
|             SszBeaconBlockError::TooShort => | ||||
|                 SszBeaconBlockValidationError::DBError("Bad parent block in db.".to_string()), | ||||
|             SszBeaconBlockError::TooLong => | ||||
|                 SszBeaconBlockValidationError::DBError("Bad parent block in db.".to_string()), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<DecodeError> for SszBlockValidationError { | ||||
| impl From<DecodeError> for SszBeaconBlockValidationError { | ||||
|     fn from(e: DecodeError) -> Self { | ||||
|         match e { | ||||
|             DecodeError::TooShort => | ||||
|                 SszBlockValidationError::BadAttestationSsz, | ||||
|                 SszBeaconBlockValidationError::BadAttestationSsz, | ||||
|             DecodeError::TooLong => | ||||
|                 SszBlockValidationError::BadAttestationSsz, | ||||
|                 SszBeaconBlockValidationError::BadAttestationSsz, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<AttestationValidationError> for SszBlockValidationError { | ||||
| impl From<AttestationValidationError> for SszBeaconBlockValidationError { | ||||
|     fn from(e: AttestationValidationError) -> Self { | ||||
|         SszBlockValidationError::AttestationValidationError(e) | ||||
|         SszBeaconBlockValidationError::AttestationValidationError(e) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -5,13 +5,13 @@ use super::db::{ | ||||
| }; | ||||
| use super::db::stores::{ | ||||
|     ValidatorStore, | ||||
|     BlockStore, | ||||
|     BeaconBlockStore, | ||||
| }; | ||||
| use super::types::{ | ||||
|     AttestationRecord, | ||||
|     AttesterMap, | ||||
|     Bitfield, | ||||
|     Block, | ||||
|     BeaconBlock, | ||||
|     Hash256, | ||||
| }; | ||||
| use super::validation::attestation_validation::{ | ||||
| @ -32,14 +32,14 @@ use super::hashing::{ | ||||
| pub struct TestStore { | ||||
|     pub db: Arc<MemoryDB>, | ||||
|     pub validator: Arc<ValidatorStore<MemoryDB>>, | ||||
|     pub block: Arc<BlockStore<MemoryDB>>, | ||||
|     pub block: Arc<BeaconBlockStore<MemoryDB>>, | ||||
| } | ||||
| 
 | ||||
| impl TestStore { | ||||
|     pub fn new() -> Self { | ||||
|         let db = Arc::new(MemoryDB::open()); | ||||
|         let validator = Arc::new(ValidatorStore::new(db.clone())); | ||||
|         let block = Arc::new(BlockStore::new(db.clone())); | ||||
|         let block = Arc::new(BeaconBlockStore::new(db.clone())); | ||||
|         Self { | ||||
|             db, | ||||
|             validator, | ||||
| @ -81,7 +81,7 @@ pub fn generate_attestation(shard_id: u16, | ||||
|                             cycle_length: u8, | ||||
|                             parent_hashes: &[Hash256], | ||||
|                             signing_keys: &[Option<SecretKey>], | ||||
|                             block_store: &BlockStore<MemoryDB>) | ||||
|                             block_store: &BeaconBlockStore<MemoryDB>) | ||||
|     -> AttestationRecord | ||||
| { | ||||
|     let mut attester_bitfield = Bitfield::new(); | ||||
| @ -136,10 +136,10 @@ pub fn generate_attestation(shard_id: u16, | ||||
| /// Create a minimum viable block at some slot.
 | ||||
| ///
 | ||||
| /// Allows the validation function to read the block and verify its slot.
 | ||||
| pub fn create_block_at_slot(block_store: &BlockStore<MemoryDB>, hash: &Hash256, slot: u64) { | ||||
|     let mut justified_block = Block::zero(); | ||||
| pub fn create_block_at_slot(block_store: &BeaconBlockStore<MemoryDB>, hash: &Hash256, slot: u64) { | ||||
|     let mut justified_block = BeaconBlock::zero(); | ||||
|     justified_block.attestations.push(AttestationRecord::zero()); | ||||
|     justified_block.slot_number = slot; | ||||
|     justified_block.slot = slot; | ||||
|     let mut s = SszStream::new(); | ||||
|     s.append(&justified_block); | ||||
|     let justified_block_ssz = s.drain(); | ||||
|  | ||||
| @ -11,29 +11,29 @@ use super::db::{ | ||||
|     MemoryDB, | ||||
| }; | ||||
| use super::db::stores::{ | ||||
|     BlockStore, | ||||
|     BeaconBlockStore, | ||||
|     PoWChainStore, | ||||
|     ValidatorStore, | ||||
| }; | ||||
| use super::types::{ | ||||
|     AttestationRecord, | ||||
|     AttesterMap, | ||||
|     Block, | ||||
|     BeaconBlock, | ||||
|     Hash256, | ||||
|     ProposerMap, | ||||
| }; | ||||
| use super::ssz_helpers::ssz_block::SszBlock; | ||||
| use super::ssz_helpers::ssz_beacon_block::SszBeaconBlock; | ||||
| use super::validation::block_validation::{ | ||||
|     BlockValidationContext, | ||||
|     SszBlockValidationError, | ||||
|     BlockStatus, | ||||
|     BeaconBlockValidationContext, | ||||
|     SszBeaconBlockValidationError, | ||||
|     BeaconBlockStatus, | ||||
| }; | ||||
| use super::ssz::{ | ||||
|     SszStream, | ||||
| }; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct BlockTestParams { | ||||
| pub struct BeaconBlockTestParams { | ||||
|     pub total_validators: usize, | ||||
|     pub cycle_length: u8, | ||||
|     pub shard_count: u16, | ||||
| @ -50,7 +50,7 @@ pub struct BlockTestParams { | ||||
| 
 | ||||
| pub struct TestStore { | ||||
|     pub db: Arc<MemoryDB>, | ||||
|     pub block: Arc<BlockStore<MemoryDB>>, | ||||
|     pub block: Arc<BeaconBlockStore<MemoryDB>>, | ||||
|     pub pow_chain: Arc<PoWChainStore<MemoryDB>>, | ||||
|     pub validator: Arc<ValidatorStore<MemoryDB>>, | ||||
| } | ||||
| @ -58,7 +58,7 @@ pub struct TestStore { | ||||
| impl TestStore { | ||||
|     pub fn new() -> Self { | ||||
|         let db = Arc::new(MemoryDB::open()); | ||||
|         let block = Arc::new(BlockStore::new(db.clone())); | ||||
|         let block = Arc::new(BeaconBlockStore::new(db.clone())); | ||||
|         let pow_chain = Arc::new(PoWChainStore::new(db.clone())); | ||||
|         let validator = Arc::new(ValidatorStore::new(db.clone())); | ||||
|         Self { | ||||
| @ -74,8 +74,8 @@ type ParentHashes = Vec<Hash256>; | ||||
| 
 | ||||
| /// Setup for a block validation function, without actually executing the
 | ||||
| /// block validation function.
 | ||||
| pub fn setup_block_validation_scenario(params: &BlockTestParams) | ||||
|     -> (Block, ParentHashes, AttesterMap, ProposerMap, TestStore) | ||||
| pub fn setup_block_validation_scenario(params: &BeaconBlockTestParams) | ||||
|     -> (BeaconBlock, ParentHashes, AttesterMap, ProposerMap, TestStore) | ||||
| { | ||||
|     let stores = TestStore::new(); | ||||
| 
 | ||||
| @ -89,6 +89,7 @@ pub fn setup_block_validation_scenario(params: &BlockTestParams) | ||||
|         .map(|i| Hash256::from(i as u64)) | ||||
|         .collect(); | ||||
|     let parent_hash = Hash256::from("parent_hash".as_bytes()); | ||||
|     let ancestor_hashes = vec![parent_hash.clone(); 32]; | ||||
|     let randao_reveal = Hash256::from("randao_reveal".as_bytes()); | ||||
|     let justified_block_hash = Hash256::from("justified_hash".as_bytes()); | ||||
|     let pow_chain_ref = Hash256::from("pow_chain".as_bytes()); | ||||
| @ -104,16 +105,16 @@ pub fn setup_block_validation_scenario(params: &BlockTestParams) | ||||
|     /* | ||||
|      * Generate a minimum viable parent block and store it in the database. | ||||
|      */ | ||||
|     let mut parent_block = Block::zero(); | ||||
|     let mut parent_block = BeaconBlock::zero(); | ||||
|     let parent_attestation = AttestationRecord::zero(); | ||||
|     parent_block.slot_number = block_slot - 1; | ||||
|     parent_block.slot = block_slot - 1; | ||||
|     parent_block.attestations.push(parent_attestation); | ||||
|     let parent_block_ssz = serialize_block(&parent_block); | ||||
|     stores.block.put_serialized_block(parent_hash.as_ref(), &parent_block_ssz).unwrap(); | ||||
| 
 | ||||
|     let proposer_map = { | ||||
|         let mut proposer_map = ProposerMap::new(); | ||||
|         proposer_map.insert(parent_block.slot_number, params.parent_proposer_index); | ||||
|         proposer_map.insert(parent_block.slot, params.parent_proposer_index); | ||||
|         proposer_map | ||||
|     }; | ||||
| 
 | ||||
| @ -168,14 +169,15 @@ pub fn setup_block_validation_scenario(params: &BlockTestParams) | ||||
|         (attester_map, attestations, keypairs) | ||||
|     }; | ||||
| 
 | ||||
|     let block = Block { | ||||
|         parent_hash, | ||||
|         slot_number: block_slot, | ||||
|     let block = BeaconBlock { | ||||
|         slot: block_slot, | ||||
|         randao_reveal, | ||||
|         attestations, | ||||
|         pow_chain_ref, | ||||
|         pow_chain_reference: pow_chain_ref, | ||||
|         ancestor_hashes, | ||||
|         active_state_root, | ||||
|         crystallized_state_root, | ||||
|         attestations, | ||||
|         specials: vec![], | ||||
|     }; | ||||
| 
 | ||||
|     (block, | ||||
| @ -185,8 +187,8 @@ pub fn setup_block_validation_scenario(params: &BlockTestParams) | ||||
|      stores) | ||||
| } | ||||
| 
 | ||||
| /// Helper function to take some Block and SSZ serialize it.
 | ||||
| pub fn serialize_block(b: &Block) -> Vec<u8> { | ||||
| /// Helper function to take some BeaconBlock and SSZ serialize it.
 | ||||
| pub fn serialize_block(b: &BeaconBlock) -> Vec<u8> { | ||||
|     let mut stream = SszStream::new(); | ||||
|     stream.append(b); | ||||
|     stream.drain() | ||||
| @ -196,11 +198,11 @@ pub fn serialize_block(b: &Block) -> Vec<u8> { | ||||
| ///
 | ||||
| /// Returns the Result returned from the block validation function.
 | ||||
| pub fn run_block_validation_scenario<F>( | ||||
|     params: &BlockTestParams, | ||||
|     params: &BeaconBlockTestParams, | ||||
|     mutator_func: F) | ||||
|     -> Result<(BlockStatus, Option<Block>), SszBlockValidationError> | ||||
|     where F: FnOnce(Block, AttesterMap, ProposerMap, TestStore) | ||||
|                 -> (Block, AttesterMap, ProposerMap, TestStore) | ||||
|     -> Result<(BeaconBlockStatus, Option<BeaconBlock>), SszBeaconBlockValidationError> | ||||
|     where F: FnOnce(BeaconBlock, AttesterMap, ProposerMap, TestStore) | ||||
|                 -> (BeaconBlock, AttesterMap, ProposerMap, TestStore) | ||||
| { | ||||
|     let (block, | ||||
|      parent_hashes, | ||||
| @ -214,10 +216,10 @@ pub fn run_block_validation_scenario<F>( | ||||
|          stores) = mutator_func(block, attester_map, proposer_map, stores); | ||||
| 
 | ||||
|     let ssz_bytes = serialize_block(&block); | ||||
|     let ssz_block = SszBlock::from_slice(&ssz_bytes[..]) | ||||
|     let ssz_block = SszBeaconBlock::from_slice(&ssz_bytes[..]) | ||||
|         .unwrap(); | ||||
| 
 | ||||
|     let context = BlockValidationContext { | ||||
|     let context = BeaconBlockValidationContext { | ||||
|         present_slot: params.validation_context_slot, | ||||
|         cycle_length: params.cycle_length, | ||||
|         last_justified_slot: params.validation_context_justified_slot, | ||||
|  | ||||
| @ -2,27 +2,27 @@ use super::bls::{ | ||||
|     AggregateSignature, | ||||
| }; | ||||
| use super::helpers::{ | ||||
|     BlockTestParams, | ||||
|     BeaconBlockTestParams, | ||||
|     TestStore, | ||||
|     run_block_validation_scenario, | ||||
|     serialize_block, | ||||
| }; | ||||
| use super::types::{ | ||||
|     Block, | ||||
|     BeaconBlock, | ||||
|     Hash256, | ||||
|     ProposerMap, | ||||
| }; | ||||
| use super::ssz_helpers::ssz_block::SszBlock; | ||||
| use super::ssz_helpers::ssz_beacon_block::SszBeaconBlock; | ||||
| use super::validation::block_validation::{ | ||||
|     SszBlockValidationError, | ||||
|     BlockStatus, | ||||
|     SszBeaconBlockValidationError, | ||||
|     BeaconBlockStatus, | ||||
| }; | ||||
| use super::validation::attestation_validation::{ | ||||
|     AttestationValidationError, | ||||
| }; | ||||
| use super::hashing::canonical_hash; | ||||
| 
 | ||||
| fn get_simple_params() -> BlockTestParams { | ||||
| fn get_simple_params() -> BeaconBlockTestParams { | ||||
|     let validators_per_shard: usize = 5; | ||||
|     let cycle_length: u8 = 2; | ||||
|     let shard_count: u16 = 4; | ||||
| @ -37,7 +37,7 @@ fn get_simple_params() -> BlockTestParams { | ||||
|     let validation_context_justified_block_hash = Hash256::from("justified_hash".as_bytes()); | ||||
|     let validation_context_finalized_slot = 0; | ||||
| 
 | ||||
|     BlockTestParams { | ||||
|     BeaconBlockTestParams { | ||||
|         total_validators, | ||||
|         cycle_length, | ||||
|         shard_count, | ||||
| @ -59,7 +59,7 @@ fn get_simple_params() -> BlockTestParams { | ||||
| fn test_block_validation_valid() { | ||||
|     let params = get_simple_params(); | ||||
| 
 | ||||
|     let mutator = |block: Block, attester_map, proposer_map, stores| { | ||||
|     let mutator = |block: BeaconBlock, attester_map, proposer_map, stores| { | ||||
|         /* | ||||
|          * Do not mutate | ||||
|          */ | ||||
| @ -70,14 +70,14 @@ fn test_block_validation_valid() { | ||||
|         ¶ms, | ||||
|         mutator); | ||||
| 
 | ||||
|     assert_eq!(status.unwrap().0, BlockStatus::NewBlock); | ||||
|     assert_eq!(status.unwrap().0, BeaconBlockStatus::NewBlock); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_block_validation_valid_known_block() { | ||||
|     let params = get_simple_params(); | ||||
| 
 | ||||
|     let mutator = |block: Block, attester_map, proposer_map, stores: TestStore| { | ||||
|     let mutator = |block: BeaconBlock, attester_map, proposer_map, stores: TestStore| { | ||||
|         /* | ||||
|          * Pre-store the block in the database | ||||
|          */ | ||||
| @ -91,15 +91,15 @@ fn test_block_validation_valid_known_block() { | ||||
|         ¶ms, | ||||
|         mutator); | ||||
| 
 | ||||
|     assert_eq!(status.unwrap(), (BlockStatus::KnownBlock, None)); | ||||
|     assert_eq!(status.unwrap(), (BeaconBlockStatus::KnownBlock, None)); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_block_validation_parent_slot_too_high() { | ||||
|     let params = get_simple_params(); | ||||
| 
 | ||||
|     let mutator = |mut block: Block, attester_map, proposer_map, stores| { | ||||
|         block.slot_number = params.validation_context_justified_slot + 1; | ||||
|     let mutator = |mut block: BeaconBlock, attester_map, proposer_map, stores| { | ||||
|         block.slot = params.validation_context_justified_slot + 1; | ||||
|         (block, attester_map, proposer_map, stores) | ||||
|     }; | ||||
| 
 | ||||
| @ -107,15 +107,15 @@ fn test_block_validation_parent_slot_too_high() { | ||||
|         ¶ms, | ||||
|         mutator); | ||||
| 
 | ||||
|     assert_eq!(status, Err(SszBlockValidationError::ParentSlotHigherThanBlockSlot)); | ||||
|     assert_eq!(status, Err(SszBeaconBlockValidationError::ParentSlotHigherThanBlockSlot)); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_block_validation_invalid_future_slot() { | ||||
|     let params = get_simple_params(); | ||||
| 
 | ||||
|     let mutator = |mut block: Block, attester_map, proposer_map, stores| { | ||||
|         block.slot_number = block.slot_number + 1; | ||||
|     let mutator = |mut block: BeaconBlock, attester_map, proposer_map, stores| { | ||||
|         block.slot = block.slot + 1; | ||||
|         (block, attester_map, proposer_map, stores) | ||||
|     }; | ||||
| 
 | ||||
| @ -123,7 +123,7 @@ fn test_block_validation_invalid_future_slot() { | ||||
|         ¶ms, | ||||
|         mutator); | ||||
| 
 | ||||
|     assert_eq!(status, Err(SszBlockValidationError::FutureSlot)); | ||||
|     assert_eq!(status, Err(SszBeaconBlockValidationError::FutureSlot)); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| @ -145,15 +145,15 @@ fn test_block_validation_invalid_slot_already_finalized() { | ||||
|         ¶ms, | ||||
|         mutator); | ||||
| 
 | ||||
|     assert_eq!(status, Err(SszBlockValidationError::SlotAlreadyFinalized)); | ||||
|     assert_eq!(status, Err(SszBeaconBlockValidationError::SlotAlreadyFinalized)); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_block_validation_invalid_unknown_pow_hash() { | ||||
|     let params = get_simple_params(); | ||||
| 
 | ||||
|     let mutator = |mut block: Block, attester_map, proposer_map, stores| { | ||||
|         block.pow_chain_ref = Hash256::from("unknown pow hash".as_bytes()); | ||||
|     let mutator = |mut block: BeaconBlock, attester_map, proposer_map, stores| { | ||||
|         block.pow_chain_reference = Hash256::from("unknown pow hash".as_bytes()); | ||||
|         (block, attester_map, proposer_map, stores) | ||||
|     }; | ||||
| 
 | ||||
| @ -161,15 +161,15 @@ fn test_block_validation_invalid_unknown_pow_hash() { | ||||
|         ¶ms, | ||||
|         mutator); | ||||
| 
 | ||||
|     assert_eq!(status, Err(SszBlockValidationError::UnknownPoWChainRef)); | ||||
|     assert_eq!(status, Err(SszBeaconBlockValidationError::UnknownPoWChainRef)); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_block_validation_invalid_unknown_parent_hash() { | ||||
|     let params = get_simple_params(); | ||||
| 
 | ||||
|     let mutator = |mut block: Block, attester_map, proposer_map, stores| { | ||||
|         block.parent_hash = Hash256::from("unknown parent block".as_bytes()); | ||||
|     let mutator = |mut block: BeaconBlock, attester_map, proposer_map, stores| { | ||||
|         block.ancestor_hashes[0] = Hash256::from("unknown parent block".as_bytes()); | ||||
|         (block, attester_map, proposer_map, stores) | ||||
|     }; | ||||
| 
 | ||||
| @ -177,14 +177,14 @@ fn test_block_validation_invalid_unknown_parent_hash() { | ||||
|         ¶ms, | ||||
|         mutator); | ||||
| 
 | ||||
|     assert_eq!(status, Err(SszBlockValidationError::UnknownParentHash)); | ||||
|     assert_eq!(status, Err(SszBeaconBlockValidationError::UnknownParentHash)); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_block_validation_invalid_1st_attestation_signature() { | ||||
|     let params = get_simple_params(); | ||||
| 
 | ||||
|     let mutator = |mut block: Block, attester_map, proposer_map, stores| { | ||||
|     let mutator = |mut block: BeaconBlock, attester_map, proposer_map, stores| { | ||||
|         /* | ||||
|          * Set the second attestaion record to have an invalid signature. | ||||
|          */ | ||||
| @ -196,7 +196,7 @@ fn test_block_validation_invalid_1st_attestation_signature() { | ||||
|         ¶ms, | ||||
|         mutator); | ||||
| 
 | ||||
|     assert_eq!(status, Err(SszBlockValidationError::AttestationValidationError( | ||||
|     assert_eq!(status, Err(SszBeaconBlockValidationError::AttestationValidationError( | ||||
|                 AttestationValidationError::BadAggregateSignature))); | ||||
| } | ||||
| 
 | ||||
| @ -204,12 +204,15 @@ fn test_block_validation_invalid_1st_attestation_signature() { | ||||
| fn test_block_validation_invalid_no_parent_proposer_signature() { | ||||
|     let params = get_simple_params(); | ||||
| 
 | ||||
|     let mutator = |block: Block, attester_map, mut proposer_map: ProposerMap, stores: TestStore| { | ||||
|     let mutator = |block: BeaconBlock, attester_map, mut proposer_map: ProposerMap, stores: TestStore| { | ||||
|         /* | ||||
|          * Set the proposer for this slot to be a validator that does not exist. | ||||
|          */ | ||||
|         let ssz = stores.block.get_serialized_block(&block.parent_hash.as_ref()).unwrap().unwrap(); | ||||
|         let parent_block_slot = SszBlock::from_slice(&ssz[..]).unwrap().slot_number(); | ||||
|         let ssz = { | ||||
|             let parent_hash = block.parent_hash().unwrap().as_ref(); | ||||
|             stores.block.get_serialized_block(parent_hash).unwrap().unwrap() | ||||
|         }; | ||||
|         let parent_block_slot = SszBeaconBlock::from_slice(&ssz[..]).unwrap().slot(); | ||||
|         proposer_map.insert(parent_block_slot, params.total_validators + 1); | ||||
|         (block, attester_map, proposer_map, stores) | ||||
|     }; | ||||
| @ -218,7 +221,7 @@ fn test_block_validation_invalid_no_parent_proposer_signature() { | ||||
|         ¶ms, | ||||
|         mutator); | ||||
| 
 | ||||
|     assert_eq!(status, Err(SszBlockValidationError::NoProposerSignature)); | ||||
|     assert_eq!(status, Err(SszBeaconBlockValidationError::NoProposerSignature)); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| @ -237,14 +240,14 @@ fn test_block_validation_invalid_bad_proposer_map() { | ||||
|         ¶ms, | ||||
|         mutator); | ||||
| 
 | ||||
|     assert_eq!(status, Err(SszBlockValidationError::BadProposerMap)); | ||||
|     assert_eq!(status, Err(SszBeaconBlockValidationError::BadProposerMap)); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_block_validation_invalid_2nd_attestation_signature() { | ||||
|     let params = get_simple_params(); | ||||
| 
 | ||||
|     let mutator = |mut block: Block, attester_map, proposer_map, stores| { | ||||
|     let mutator = |mut block: BeaconBlock, attester_map, proposer_map, stores| { | ||||
|         /* | ||||
|          * Set the second attestaion record to have an invalid signature. | ||||
|          */ | ||||
| @ -256,6 +259,6 @@ fn test_block_validation_invalid_2nd_attestation_signature() { | ||||
|         ¶ms, | ||||
|         mutator); | ||||
| 
 | ||||
|     assert_eq!(status, Err(SszBlockValidationError::AttestationValidationError( | ||||
|     assert_eq!(status, Err(SszBeaconBlockValidationError::AttestationValidationError( | ||||
|                 AttestationValidationError::BadAggregateSignature))); | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user