Update verify_exit
to spec v0.6.1
This commit is contained in:
parent
bb7ee642d8
commit
04791dfc58
@ -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(())
|
||||||
|
@ -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.
|
||||||
|
@ -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),
|
||||||
|
Loading…
Reference in New Issue
Block a user