Update block and attestation validation code
This commit is contained in:
parent
8e094b358f
commit
6b7677a206
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -114,7 +112,7 @@ impl<T> AttestationValidationContext<T>
|
|||||||
bytes_for_bits(attestation_indices.len())
|
bytes_for_bits(attestation_indices.len())
|
||||||
{
|
{
|
||||||
return Err(AttestationValidationError::BadBitfieldLength);
|
return Err(AttestationValidationError::BadBitfieldLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there are excess bits in the bitfield because the number of a validators in not a
|
* If there are excess bits in the bitfield because the number of a validators in not a
|
||||||
@ -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 {
|
||||||
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user