spec v0.6.1: verify attester slashing
This commit is contained in:
parent
58481c7119
commit
dab11c1eed
@ -7,30 +7,27 @@ use types::*;
|
|||||||
///
|
///
|
||||||
/// Returns `Ok(())` if the `AttesterSlashing` is valid, otherwise indicates the reason for invalidity.
|
/// Returns `Ok(())` if the `AttesterSlashing` is valid, otherwise indicates the reason for invalidity.
|
||||||
///
|
///
|
||||||
/// Spec v0.5.1
|
/// Spec v0.6.1
|
||||||
pub fn verify_attester_slashing<T: EthSpec>(
|
pub fn verify_attester_slashing<T: EthSpec>(
|
||||||
state: &BeaconState<T>,
|
state: &BeaconState<T>,
|
||||||
attester_slashing: &AttesterSlashing,
|
attester_slashing: &AttesterSlashing,
|
||||||
should_verify_indexed_attestations: bool,
|
should_verify_indexed_attestations: bool,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let indexed_attestation_1 = &attester_slashing.indexed_attestation_1;
|
let attestation_1 = &attester_slashing.attestation_1;
|
||||||
let indexed_attestation_2 = &attester_slashing.indexed_attestation_2;
|
let attestation_2 = &attester_slashing.attestation_2;
|
||||||
|
|
||||||
|
// Spec: is_slashable_attestation_data
|
||||||
verify!(
|
verify!(
|
||||||
indexed_attestation_1.data != indexed_attestation_2.data,
|
attestation_1.is_double_vote(attestation_2, spec)
|
||||||
Invalid::AttestationDataIdentical
|
|| attestation_1.is_surround_vote(attestation_2, spec),
|
||||||
);
|
|
||||||
verify!(
|
|
||||||
indexed_attestation_1.is_double_vote(indexed_attestation_2, spec)
|
|
||||||
| indexed_attestation_1.is_surround_vote(indexed_attestation_2, spec),
|
|
||||||
Invalid::NotSlashable
|
Invalid::NotSlashable
|
||||||
);
|
);
|
||||||
|
|
||||||
if should_verify_indexed_attestations {
|
if should_verify_indexed_attestations {
|
||||||
verify_indexed_attestation(state, &indexed_attestation_1, spec)
|
verify_indexed_attestation(state, &attestation_1, spec)
|
||||||
.map_err(|e| Error::Invalid(Invalid::IndexedAttestation1Invalid(e.into())))?;
|
.map_err(|e| Error::Invalid(Invalid::IndexedAttestation1Invalid(e.into())))?;
|
||||||
verify_indexed_attestation(state, &indexed_attestation_2, spec)
|
verify_indexed_attestation(state, &attestation_2, spec)
|
||||||
.map_err(|e| Error::Invalid(Invalid::IndexedAttestation2Invalid(e.into())))?;
|
.map_err(|e| Error::Invalid(Invalid::IndexedAttestation2Invalid(e.into())))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,8 +38,8 @@ pub fn verify_attester_slashing<T: EthSpec>(
|
|||||||
///
|
///
|
||||||
/// Returns Ok(indices) if `indices.len() > 0`.
|
/// Returns Ok(indices) if `indices.len() > 0`.
|
||||||
///
|
///
|
||||||
/// Spec v0.5.1
|
/// Spec v0.6.1
|
||||||
pub fn gather_attester_slashing_indices<T: EthSpec>(
|
pub fn get_slashable_indices<T: EthSpec>(
|
||||||
state: &BeaconState<T>,
|
state: &BeaconState<T>,
|
||||||
attester_slashing: &AttesterSlashing,
|
attester_slashing: &AttesterSlashing,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
@ -50,47 +47,47 @@ pub fn gather_attester_slashing_indices<T: EthSpec>(
|
|||||||
gather_attester_slashing_indices_modular(
|
gather_attester_slashing_indices_modular(
|
||||||
state,
|
state,
|
||||||
attester_slashing,
|
attester_slashing,
|
||||||
|_, validator| validator.slashed,
|
|_, validator| validator.is_slashable_at(state.current_epoch()),
|
||||||
spec,
|
spec,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as `gather_attester_slashing_indices` but allows the caller to specify the criteria
|
/// Same as `gather_attester_slashing_indices` but allows the caller to specify the criteria
|
||||||
/// for determining whether a given validator should be considered slashed.
|
/// for determining whether a given validator should be considered slashable.
|
||||||
pub fn gather_attester_slashing_indices_modular<F, T: EthSpec>(
|
pub fn get_slashable_indices_modular<F, T: EthSpec>(
|
||||||
state: &BeaconState<T>,
|
state: &BeaconState<T>,
|
||||||
attester_slashing: &AttesterSlashing,
|
attester_slashing: &AttesterSlashing,
|
||||||
is_slashed: F,
|
is_slashable: F,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<Vec<u64>, Error>
|
) -> Result<Vec<u64>, Error>
|
||||||
where
|
where
|
||||||
F: Fn(u64, &Validator) -> bool,
|
F: Fn(u64, &Validator) -> bool,
|
||||||
{
|
{
|
||||||
let indexed_attestation_1 = &attester_slashing.indexed_attestation_1;
|
let attestation_1 = &attester_slashing.attestation_1;
|
||||||
let indexed_attestation_2 = &attester_slashing.indexed_attestation_2;
|
let attestation_2 = &attester_slashing.attestation_2;
|
||||||
|
|
||||||
let mut indexed_indices = Vec::with_capacity(spec.max_indices_per_indexed_vote);
|
let mut attesting_indices_1 = HashSet::new();
|
||||||
for i in &indexed_attestation_1.validator_indices {
|
attesting_indices_1.extend(attestation_1.custody_bit_0_indices.clone());
|
||||||
|
attesting_indices_1.extend(attestation_1.custody_bit_1_indices.clone());
|
||||||
|
|
||||||
|
let mut attesting_indices_2 = HashSet::new();
|
||||||
|
attesting_indices_2.extend(attestation_2.custody_bit_0_indices.clone());
|
||||||
|
attesting_indices_2.extend(attestation_2.custody_bit_1_indices.clone());
|
||||||
|
|
||||||
|
let mut slashable_indices = vec![];
|
||||||
|
|
||||||
|
for index in &attesting_indices_1 & &attesting_indices_2 {
|
||||||
let validator = state
|
let validator = state
|
||||||
.validator_registry
|
.validator_registry
|
||||||
.get(*i as usize)
|
.get(index as usize)
|
||||||
.ok_or_else(|| Error::Invalid(Invalid::UnknownValidator(*i)))?;
|
.ok_or_else(|| Error::Invalid(Invalid::UnknownValidator(index)))?;
|
||||||
|
|
||||||
if indexed_attestation_2.validator_indices.contains(&i) & !is_slashed(*i, validator) {
|
if is_slashable(index, validator) {
|
||||||
// TODO: verify that we should reject any indexed attestation which includes a
|
slashable_indices.push(index);
|
||||||
// withdrawn validator. PH has asked the question on gitter, awaiting response.
|
|
||||||
verify!(
|
|
||||||
validator.withdrawable_epoch > state.slot.epoch(spec.slots_per_epoch),
|
|
||||||
Invalid::ValidatorAlreadyWithdrawn(*i)
|
|
||||||
);
|
|
||||||
|
|
||||||
indexed_indices.push(*i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
verify!(!indexed_indices.is_empty(), Invalid::NoSlashableIndices);
|
verify!(!slashable_indices.is_empty(), Invalid::NoSlashableIndices);
|
||||||
|
|
||||||
indexed_indices.shrink_to_fit();
|
Ok(slashable_indices)
|
||||||
|
|
||||||
Ok(indexed_indices)
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user