Update block and attestation validation code

This commit is contained in:
Paul Hauner 2018-10-02 09:46:14 +10:00
parent 8e094b358f
commit 6b7677a206
No known key found for this signature in database
GPG Key ID: 303E4494BB28068C
2 changed files with 14 additions and 39 deletions

View File

@ -27,7 +27,7 @@ use super::signature_verification::{
pub enum AttestationValidationError { pub enum AttestationValidationError {
SlotTooHigh, SlotTooHigh,
SlotTooLow, SlotTooLow,
JustifiedSlotTooHigh, JustifiedSlotIncorrect,
UnknownJustifiedBlock, UnknownJustifiedBlock,
TooManyObliqueHashes, TooManyObliqueHashes,
BadCurrentHashes, BadCurrentHashes,
@ -41,7 +41,7 @@ pub enum AttestationValidationError {
InvalidBitfieldEndBits, InvalidBitfieldEndBits,
NoSignatures, NoSignatures,
NonZeroTrailingBits, NonZeroTrailingBits,
AggregateSignatureFail, BadAggregateSignature,
DBError(String), DBError(String),
} }
@ -61,7 +61,7 @@ impl<T> AttestationValidationContext<T>
where T: ClientDB where T: ClientDB
{ {
pub fn validate_attestation(&self, a: &AttestationRecord) pub fn validate_attestation(&self, a: &AttestationRecord)
-> Result<Option<HashSet<usize>>, AttestationValidationError> -> Result<HashSet<usize>, AttestationValidationError>
{ {
/* /*
* The attesation slot must not be higher than the block that contained it. * The attesation slot must not be higher than the block that contained it.
@ -73,8 +73,6 @@ impl<T> AttestationValidationContext<T>
/* /*
* The slot of this attestation must not be more than cycle_length + 1 distance * The slot of this attestation must not be more than cycle_length + 1 distance
* from the block that contained it. * from the block that contained it.
*
* The below code stays overflow-safe as long as cycle length is a < 64 bit integer.
*/ */
if a.slot < self.block_slot if a.slot < self.block_slot
.saturating_sub(u64::from(self.cycle_length).saturating_add(1)) { .saturating_sub(u64::from(self.cycle_length).saturating_add(1)) {
@ -85,8 +83,8 @@ impl<T> AttestationValidationContext<T>
* The attestation must indicate that its last justified slot is the same as the last justified * The attestation must indicate that its last justified slot is the same as the last justified
* slot known to us. * slot known to us.
*/ */
if a.justified_slot > self.last_justified_slot { if a.justified_slot != self.last_justified_slot {
return Err(AttestationValidationError::JustifiedSlotTooHigh); return Err(AttestationValidationError::JustifiedSlotIncorrect);
} }
/* /*
@ -123,10 +121,7 @@ impl<T> AttestationValidationContext<T>
* Allow extra set bits would permit mutliple different byte layouts (and therefore hashes) to * Allow extra set bits would permit mutliple different byte layouts (and therefore hashes) to
* refer to the same AttesationRecord. * refer to the same AttesationRecord.
*/ */
let last_byte = if a.attester_bitfield.len() > attestation_indices.len() {
a.attester_bitfield.get_byte(a.attester_bitfield.num_bytes() - 1)
.ok_or(AttestationValidationError::InvalidBitfield)?;
if any_of_last_n_bits_are_set(*last_byte, a.attester_bitfield.len() % 8) {
return Err(AttestationValidationError::InvalidBitfieldEndBits) return Err(AttestationValidationError::InvalidBitfieldEndBits)
} }
@ -160,7 +155,13 @@ impl<T> AttestationValidationContext<T>
&a.attester_bitfield, &a.attester_bitfield,
&self.validator_store)?; &self.validator_store)?;
Ok(voted_hashmap) /*
* If the hashmap of voters is None, the signature verification failed.
*/
match voted_hashmap {
None => Err(AttestationValidationError::BadAggregateSignature),
Some(hashmap) => Ok(hashmap),
}
} }
} }
@ -168,16 +169,6 @@ fn bytes_for_bits(bits: usize) -> usize {
(bits.saturating_sub(1) / 8) + 1 (bits.saturating_sub(1) / 8) + 1
} }
fn any_of_last_n_bits_are_set(byte: u8, n: usize) -> bool {
for i in 0..n {
let mask = 1_u8 >> 7_usize.saturating_sub(i as usize);
if byte & mask > 0 {
return true
}
}
false
}
impl From<ParentHashesError> for AttestationValidationError { impl From<ParentHashesError> for AttestationValidationError {
fn from(e: ParentHashesError) -> Self { fn from(e: ParentHashesError) -> Self {
match e { match e {

View File

@ -55,7 +55,6 @@ pub enum SszBlockValidationError {
BadAttestationSsz, BadAttestationSsz,
AttestationValidationError(AttestationValidationError), AttestationValidationError(AttestationValidationError),
AttestationSignatureFailed, AttestationSignatureFailed,
FirstAttestationSignatureFailed,
ProposerAttestationHasObliqueHashes, ProposerAttestationHasObliqueHashes,
NoProposerSignature, NoProposerSignature,
BadProposerMap, BadProposerMap,
@ -198,13 +197,6 @@ impl<T> BlockValidationContext<T>
let attestation_voters = attestation_validation_context let attestation_voters = attestation_validation_context
.validate_attestation(&first_attestation)?; .validate_attestation(&first_attestation)?;
/*
* If the set of voters is None, the attestation was invalid.
*/
let attestation_voters = attestation_voters
.ok_or(SszBlockValidationError::
FirstAttestationSignatureFailed)?;
/* /*
* Read the parent hash from the block we are validating then attempt to load * Read the parent hash from the block we are validating then attempt to load
* the parent block ssz from the database. If that parent doesn't exist in * the parent block ssz from the database. If that parent doesn't exist in
@ -285,14 +277,6 @@ impl<T> BlockValidationContext<T>
*failure = Some(SszBlockValidationError::from(e)); *failure = Some(SszBlockValidationError::from(e));
None None
} }
/*
* Attestation validation failed due to a bad signature.
*/
Ok(None) => {
let mut failure = failure.write().unwrap();
*failure = Some(SszBlockValidationError::AttestationSignatureFailed);
None
}
/* /*
* Attestation validation succeded. * Attestation validation succeded.
*/ */