From 9f9af746eaa255d11bca18e17368cbacb3666d22 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Thu, 8 Aug 2019 10:29:27 +1000 Subject: [PATCH] Add non-compiling half finished changes --- .../src/per_block_processing.rs | 14 ++- .../verify_attestation.rs | 113 +++++++----------- 2 files changed, 54 insertions(+), 73 deletions(-) diff --git a/eth2/state_processing/src/per_block_processing.rs b/eth2/state_processing/src/per_block_processing.rs index 3c89215550..3acadfde26 100644 --- a/eth2/state_processing/src/per_block_processing.rs +++ b/eth2/state_processing/src/per_block_processing.rs @@ -14,10 +14,7 @@ pub use self::verify_proposer_slashing::verify_proposer_slashing; pub use is_valid_indexed_attestation::{ is_valid_indexed_attestation, is_valid_indexed_attestation_without_signature, }; -pub use verify_attestation::{ - verify_attestation, verify_attestation_time_independent_only, - verify_attestation_without_signature, -}; +pub use verify_attestation::{verify_attestation_for_block, verify_attestation_for_state}; pub use verify_deposit::{ get_existing_validator_index, verify_deposit_merkle_proof, verify_deposit_signature, }; @@ -37,6 +34,12 @@ mod verify_exit; mod verify_proposer_slashing; mod verify_transfer; +#[derive(PartialEq)] +pub enum VerifySignatures { + True, + False, +} + /// Updates the state for a new block, whilst validating that the block is valid. /// /// Returns `Ok(())` if the block is valid and the state was successfully updated. Otherwise @@ -312,7 +315,8 @@ pub fn process_attestations( .par_iter() .enumerate() .try_for_each(|(i, attestation)| { - verify_attestation(state, attestation, spec).map_err(|e| e.into_with_index(i)) + verify_attestation_for_block(state, attestation, spec, VerifySignatures::True) + .map_err(|e| e.into_with_index(i)) })?; // Update the state in series. diff --git a/eth2/state_processing/src/per_block_processing/verify_attestation.rs b/eth2/state_processing/src/per_block_processing/verify_attestation.rs index af25300457..bca6a90854 100644 --- a/eth2/state_processing/src/per_block_processing/verify_attestation.rs +++ b/eth2/state_processing/src/per_block_processing/verify_attestation.rs @@ -1,4 +1,5 @@ use super::errors::{AttestationInvalid as Invalid, AttestationValidationError as Error}; +use super::VerifySignatures; use crate::common::get_indexed_attestation; use crate::per_block_processing::{ is_valid_indexed_attestation, is_valid_indexed_attestation_without_signature, @@ -6,67 +7,23 @@ use crate::per_block_processing::{ use tree_hash::TreeHash; use types::*; -/// Indicates if an `Attestation` is valid to be included in a block in the current epoch of the -/// given state. -/// -/// Returns `Ok(())` if the `Attestation` is valid, otherwise indicates the reason for invalidity. -/// -/// Spec v0.8.0 -pub fn verify_attestation( - state: &BeaconState, - attestation: &Attestation, - spec: &ChainSpec, -) -> Result<(), Error> { - verify_attestation_parametric(state, attestation, spec, true, false) -} - -/// Like `verify_attestation` but doesn't run checks which may become true in future states. -pub fn verify_attestation_time_independent_only( - state: &BeaconState, - attestation: &Attestation, - spec: &ChainSpec, -) -> Result<(), Error> { - verify_attestation_parametric(state, attestation, spec, true, true) -} - -/// Indicates if an `Attestation` is valid to be included in a block in the current epoch of the -/// given state, without validating the aggregate signature. -/// -/// Returns `Ok(())` if the `Attestation` is valid, otherwise indicates the reason for invalidity. -/// -/// Spec v0.8.0 -pub fn verify_attestation_without_signature( - state: &BeaconState, - attestation: &Attestation, - spec: &ChainSpec, -) -> Result<(), Error> { - verify_attestation_parametric(state, attestation, spec, false, false) -} - /// Indicates if an `Attestation` is valid to be included in a block in the current epoch of the /// given state, optionally validating the aggregate signature. /// -/// /// Spec v0.8.0 -fn verify_attestation_parametric( +pub fn verify_attestation_for_block( state: &BeaconState, attestation: &Attestation, spec: &ChainSpec, - verify_signature: bool, - time_independent_only: bool, + verify_signatures: VerifySignatures, ) -> Result<(), Error> { let data = &attestation.data; - verify!( - data.crosslink.shard < T::ShardCount::to_u64(), - Invalid::BadShard - ); // Check attestation slot. let attestation_slot = state.get_attestation_data_slot(&data)?; verify!( - time_independent_only - || attestation_slot + spec.min_attestation_inclusion_delay <= state.slot, + attestation_slot + spec.min_attestation_inclusion_delay <= state.slot, Invalid::IncludedTooEarly { state: state.slot, delay: spec.min_attestation_inclusion_delay, @@ -81,27 +38,47 @@ fn verify_attestation_parametric( } ); - // Verify the Casper FFG vote and crosslink data. - if !time_independent_only { - let parent_crosslink = verify_casper_ffg_vote(attestation, state)?; + verify_attestation_for_state(state, attestation, spec, verify_signatures) +} - verify!( - data.crosslink.parent_root == Hash256::from_slice(&parent_crosslink.tree_hash_root()), - Invalid::BadParentCrosslinkHash - ); - verify!( - data.crosslink.start_epoch == parent_crosslink.end_epoch, - Invalid::BadParentCrosslinkStartEpoch - ); - verify!( - data.crosslink.end_epoch - == std::cmp::min( - data.target.epoch, - parent_crosslink.end_epoch + spec.max_epochs_per_crosslink - ), - Invalid::BadParentCrosslinkEndEpoch - ); - } +/// Returns `Ok(())` if `attestation` is a valid attestation to the chain that preceeds the given +/// `state`. +/// +/// Returns a descriptive `Err` if the attestation is malformed or does not accurately reflect the +/// prior blocks in `state`. +/// +/// Spec v0.8.0 +pub fn verify_attestation_for_state( + state: &BeaconState, + attestation: &Attestation, + spec: &ChainSpec, + verify_signature: VerifySignatures, +) -> Result<(), Error> { + let data = &attestation.data; + verify!( + data.crosslink.shard < T::ShardCount::to_u64(), + Invalid::BadShard + ); + + // Verify the Casper FFG vote and crosslink data. + let parent_crosslink = verify_casper_ffg_vote(attestation, state)?; + + verify!( + data.crosslink.parent_root == Hash256::from_slice(&parent_crosslink.tree_hash_root()), + Invalid::BadParentCrosslinkHash + ); + verify!( + data.crosslink.start_epoch == parent_crosslink.end_epoch, + Invalid::BadParentCrosslinkStartEpoch + ); + verify!( + data.crosslink.end_epoch + == std::cmp::min( + data.target.epoch, + parent_crosslink.end_epoch + spec.max_epochs_per_crosslink + ), + Invalid::BadParentCrosslinkEndEpoch + ); // Crosslink data root is zero (to be removed in phase 1). verify!( @@ -111,7 +88,7 @@ fn verify_attestation_parametric( // Check signature and bitfields let indexed_attestation = get_indexed_attestation(state, attestation)?; - if verify_signature { + if verify_signature == VerifySignatures::True { is_valid_indexed_attestation(state, &indexed_attestation, spec)?; } else { is_valid_indexed_attestation_without_signature(state, &indexed_attestation, spec)?;