Update verify_exit to spec v0.6.1

This commit is contained in:
Paul Hauner 2019-05-22 11:41:15 +10:00
parent bb7ee642d8
commit 04791dfc58
No known key found for this signature in database
GPG Key ID: 5E2CFF9B75FA63DF
3 changed files with 19 additions and 13 deletions

View File

@ -1,4 +1,4 @@
use crate::common::slash_validator; use crate::common::{initiate_validator_exit, slash_validator};
use errors::{BlockInvalid as Invalid, BlockProcessingError as Error, IntoWithIndex}; use errors::{BlockInvalid as Invalid, BlockProcessingError as Error, IntoWithIndex};
use rayon::prelude::*; use rayon::prelude::*;
use tree_hash::{SignedRoot, TreeHash}; use tree_hash::{SignedRoot, TreeHash};
@ -448,7 +448,7 @@ pub fn process_exits<T: EthSpec>(
// Update the state in series. // Update the state in series.
for exit in voluntary_exits { for exit in voluntary_exits {
state.initiate_validator_exit(exit.validator_index as usize); initiate_validator_exit(state, exit.validator_index as usize, spec)?;
} }
Ok(()) Ok(())

View File

@ -348,6 +348,8 @@ pub enum ExitValidationError {
/// Describes why an object is invalid. /// Describes why an object is invalid.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum ExitInvalid { pub enum ExitInvalid {
/// The specified validator is not active.
NotActive(u64),
/// The specified validator is not in the state's validator registry. /// The specified validator is not in the state's validator registry.
ValidatorUnknown(u64), ValidatorUnknown(u64),
/// The specified validator has a non-maximum exit epoch. /// The specified validator has a non-maximum exit epoch.

View File

@ -7,7 +7,7 @@ use types::*;
/// ///
/// Returns `Ok(())` if the `Exit` is valid, otherwise indicates the reason for invalidity. /// Returns `Ok(())` if the `Exit` is valid, otherwise indicates the reason for invalidity.
/// ///
/// Spec v0.5.1 /// Spec v0.6.1
pub fn verify_exit<T: EthSpec>( pub fn verify_exit<T: EthSpec>(
state: &BeaconState<T>, state: &BeaconState<T>,
exit: &VoluntaryExit, exit: &VoluntaryExit,
@ -17,6 +17,8 @@ pub fn verify_exit<T: EthSpec>(
} }
/// Like `verify_exit` but doesn't run checks which may become true in future states. /// Like `verify_exit` but doesn't run checks which may become true in future states.
///
/// Spec v0.6.1
pub fn verify_exit_time_independent_only<T: EthSpec>( pub fn verify_exit_time_independent_only<T: EthSpec>(
state: &BeaconState<T>, state: &BeaconState<T>,
exit: &VoluntaryExit, exit: &VoluntaryExit,
@ -26,6 +28,8 @@ pub fn verify_exit_time_independent_only<T: EthSpec>(
} }
/// Parametric version of `verify_exit` that skips some checks if `time_independent_only` is true. /// Parametric version of `verify_exit` that skips some checks if `time_independent_only` is true.
///
/// Spec v0.6.1
fn verify_exit_parametric<T: EthSpec>( fn verify_exit_parametric<T: EthSpec>(
state: &BeaconState<T>, state: &BeaconState<T>,
exit: &VoluntaryExit, exit: &VoluntaryExit,
@ -37,18 +41,18 @@ fn verify_exit_parametric<T: EthSpec>(
.get(exit.validator_index as usize) .get(exit.validator_index as usize)
.ok_or_else(|| Error::Invalid(Invalid::ValidatorUnknown(exit.validator_index)))?; .ok_or_else(|| Error::Invalid(Invalid::ValidatorUnknown(exit.validator_index)))?;
// Verify the validator is active.
verify!(
validator.is_active_at(state.current_epoch()),
Invalid::NotActive(exit.validator_index)
);
// Verify that the validator has not yet exited. // Verify that the validator has not yet exited.
verify!( verify!(
validator.exit_epoch == spec.far_future_epoch, validator.exit_epoch == spec.far_future_epoch,
Invalid::AlreadyExited(exit.validator_index) Invalid::AlreadyExited(exit.validator_index)
); );
// Verify that the validator has not yet initiated.
verify!(
!validator.initiated_exit,
Invalid::AlreadyInitiatedExited(exit.validator_index)
);
// Exits must specify an epoch when they become valid; they are not valid before then. // Exits must specify an epoch when they become valid; they are not valid before then.
verify!( verify!(
time_independent_only || state.current_epoch() >= exit.epoch, time_independent_only || state.current_epoch() >= exit.epoch,
@ -58,8 +62,8 @@ fn verify_exit_parametric<T: EthSpec>(
} }
); );
// Must have been in the validator set long enough. // Verify the validator has been active long enough.
let lifespan = state.slot.epoch(spec.slots_per_epoch) - validator.activation_epoch; let lifespan = state.current_epoch() - validator.activation_epoch;
verify!( verify!(
lifespan >= spec.persistent_committee_period, lifespan >= spec.persistent_committee_period,
Invalid::TooYoungToLeave { Invalid::TooYoungToLeave {
@ -68,9 +72,9 @@ fn verify_exit_parametric<T: EthSpec>(
} }
); );
// Verify signature.
let message = exit.signed_root(); let message = exit.signed_root();
let domain = spec.get_domain(exit.epoch, Domain::Exit, &state.fork); let domain = spec.get_domain(exit.epoch, Domain::VoluntaryExit, &state.fork);
verify!( verify!(
exit.signature exit.signature
.verify(&message[..], domain, &validator.pubkey), .verify(&message[..], domain, &validator.pubkey),