use crate::types::*;
use crate::{BeaconState, Config, BLSConfig};
use bm_le::tree_root;
impl<C: Config> BeaconState<C> {
pub fn is_valid_indexed_attestation<BLS: BLSConfig>(
&self,
indexed_attestation: &IndexedAttestation<C>
) -> bool {
let bit_0_indices = &indexed_attestation.custody_bit_0_indices;
let bit_1_indices = &indexed_attestation.custody_bit_1_indices;
if bit_1_indices.len() > 0 {
return false
}
let total_len =
(bit_0_indices.len() + bit_1_indices.len()) as u64;
if !(total_len <= C::max_validators_per_committee()) {
return false
}
for index in bit_0_indices.as_ref() {
if bit_1_indices.contains(index) {
return false
}
}
if !bit_0_indices.windows(2).all(|w| w[0] <= w[1]) {
return false
}
if !bit_1_indices.windows(2).all(|w| w[0] <= w[1]) {
return false
}
BLS::verify_multiple(
&[
BLS::aggregate_pubkeys(
&bit_0_indices
.iter()
.map(|i| self.validators[*i as usize].pubkey)
.collect::<Vec<_>>()[..]
),
BLS::aggregate_pubkeys(
&bit_1_indices
.iter()
.map(|i| self.validators[*i as usize].pubkey)
.collect::<Vec<_>>()[..]
),
],
&[
tree_root::<C::Digest, _>(&AttestationDataAndCustodyBit {
data: indexed_attestation.data.clone(),
custody_bit: false,
}),
tree_root::<C::Digest, _>(&AttestationDataAndCustodyBit {
data: indexed_attestation.data.clone(),
custody_bit: true,
}),
],
&indexed_attestation.signature,
self.domain(
C::domain_attestation(),
Some(indexed_attestation.data.target.epoch)
)
)
}
}