Add attester slashing support to block processing

At spec v0.2.0
This commit is contained in:
Paul Hauner 2019-03-03 11:18:12 +11:00
parent 59128f842a
commit 76a0ba2d6c
No known key found for this signature in database
GPG Key ID: D362883A9218FCC6
2 changed files with 80 additions and 1 deletions

View File

@ -1,3 +1,4 @@
use self::verify_slashable_attestation::verify_slashable_attestation;
use crate::SlotProcessingError; use crate::SlotProcessingError;
use hashing::hash; use hashing::hash;
use int_to_bytes::int_to_bytes32; use int_to_bytes::int_to_bytes32;
@ -5,6 +6,8 @@ use log::{debug, trace};
use ssz::{ssz_encode, TreeHash}; use ssz::{ssz_encode, TreeHash};
use types::*; use types::*;
mod verify_slashable_attestation;
const PHASE_0_CUSTODY_BIT: bool = false; const PHASE_0_CUSTODY_BIT: bool = false;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -23,7 +26,9 @@ pub enum Error {
BadRandaoSignature, BadRandaoSignature,
MaxProposerSlashingsExceeded, MaxProposerSlashingsExceeded,
BadProposerSlashing, BadProposerSlashing,
MaxAttesterSlashingsExceed,
MaxAttestationsExceeded, MaxAttestationsExceeded,
BadAttesterSlashing,
InvalidAttestation(AttestationValidationError), InvalidAttestation(AttestationValidationError),
NoBlockRoot, NoBlockRoot,
MaxDepositsExceeded, MaxDepositsExceeded,
@ -82,7 +87,7 @@ impl BlockProcessable for BeaconState {
} }
fn per_block_processing_signature_optional( fn per_block_processing_signature_optional(
state: &mut BeaconState, mut state: &mut BeaconState,
block: &BeaconBlock, block: &BeaconBlock,
verify_block_signature: bool, verify_block_signature: bool,
spec: &ChainSpec, spec: &ChainSpec,
@ -205,6 +210,17 @@ fn per_block_processing_signature_optional(
state.penalize_validator(proposer_slashing.proposer_index as usize, spec)?; state.penalize_validator(proposer_slashing.proposer_index as usize, spec)?;
} }
/*
* Attester slashings
*/
ensure!(
block.body.attester_slashings.len() as u64 <= spec.max_attester_slashings,
Error::MaxAttesterSlashingsExceed
);
for attester_slashing in &block.body.attester_slashings {
verify_slashable_attestation(&mut state, &attester_slashing, spec)?;
}
/* /*
* Attestations * Attestations
*/ */

View File

@ -0,0 +1,63 @@
use super::Error;
use log::error;
use types::*;
macro_rules! ensure {
($condition: expr, $result: expr) => {
if !$condition {
return Err($result);
}
};
}
pub fn verify_slashable_attestation(
state: &mut BeaconState,
attester_slashing: &AttesterSlashing,
spec: &ChainSpec,
) -> Result<(), Error> {
let slashable_attestation_1 = &attester_slashing.slashable_attestation_1;
let slashable_attestation_2 = &attester_slashing.slashable_attestation_2;
ensure!(
slashable_attestation_1.data != slashable_attestation_2.data,
Error::BadAttesterSlashing
);
ensure!(
slashable_attestation_1.is_double_vote(slashable_attestation_2, spec)
| slashable_attestation_1.is_surround_vote(slashable_attestation_2, spec),
Error::BadAttesterSlashing
);
error!("this a");
ensure!(
state.verify_slashable_attestation(&slashable_attestation_1, spec),
Error::BadAttesterSlashing
);
error!("this b");
ensure!(
state.verify_slashable_attestation(&slashable_attestation_2, spec),
Error::BadAttesterSlashing
);
error!("this c");
let mut slashable_indices = vec![];
for i in &slashable_attestation_1.validator_indices {
let validator = state
.validator_registry
.get(*i as usize)
.ok_or_else(|| Error::BadAttesterSlashing)?;
if slashable_attestation_1.validator_indices.contains(&i)
& !validator.is_penalized_at(state.current_epoch(spec))
{
slashable_indices.push(i);
}
}
ensure!(slashable_indices.len() >= 1, Error::BadAttesterSlashing);
for i in slashable_indices {
state.penalize_validator(*i as usize, spec)?;
}
Ok(())
}