Avoid some allocations in BlockSignatureVerifier (#1922)

## Issue Addressed

NA

## Proposed Changes

Avoids growing/allocating some `Vec`s.

## Additional Info

NA
This commit is contained in:
Paul Hauner 2020-11-17 06:31:01 +00:00
parent 5114aee5cf
commit ecff8807a5

View File

@ -1,6 +1,6 @@
#![allow(clippy::integer_arithmetic)] #![allow(clippy::integer_arithmetic)]
use super::signature_sets::{Error as SignatureSetError, Result as SignatureSetResult, *}; use super::signature_sets::{Error as SignatureSetError, *};
use crate::common::get_indexed_attestation; use crate::common::get_indexed_attestation;
use crate::per_block_processing::errors::{AttestationInvalid, BlockOperationError}; use crate::per_block_processing::errors::{AttestationInvalid, BlockOperationError};
use bls::{verify_signature_sets, PublicKey, SignatureSet}; use bls::{verify_signature_sets, PublicKey, SignatureSet};
@ -203,31 +203,34 @@ where
/// Includes all signatures in `self.block.body.proposer_slashings` for verification. /// Includes all signatures in `self.block.body.proposer_slashings` for verification.
pub fn include_proposer_slashings(&mut self, block: &'a SignedBeaconBlock<T>) -> Result<()> { pub fn include_proposer_slashings(&mut self, block: &'a SignedBeaconBlock<T>) -> Result<()> {
let mut sets: Vec<SignatureSet> = block self.sets
.reserve(block.message.body.proposer_slashings.len() * 2);
block
.message .message
.body .body
.proposer_slashings .proposer_slashings
.iter() .iter()
.map(|proposer_slashing| { .try_for_each(|proposer_slashing| {
let (set_1, set_2) = proposer_slashing_signature_set( let (set_1, set_2) = proposer_slashing_signature_set(
self.state, self.state,
self.get_pubkey.clone(), self.get_pubkey.clone(),
proposer_slashing, proposer_slashing,
self.spec, self.spec,
)?; )?;
Ok(vec![set_1, set_2])
})
.collect::<SignatureSetResult<Vec<Vec<SignatureSet>>>>()?
.into_iter()
.flatten()
.collect();
self.sets.append(&mut sets); self.sets.push(set_1);
Ok(()) self.sets.push(set_2);
Ok(())
})
} }
/// Includes all signatures in `self.block.body.attester_slashings` for verification. /// Includes all signatures in `self.block.body.attester_slashings` for verification.
pub fn include_attester_slashings(&mut self, block: &'a SignedBeaconBlock<T>) -> Result<()> { pub fn include_attester_slashings(&mut self, block: &'a SignedBeaconBlock<T>) -> Result<()> {
self.sets
.reserve(block.message.body.attester_slashings.len() * 2);
block block
.message .message
.body .body
@ -253,44 +256,54 @@ where
&mut self, &mut self,
block: &'a SignedBeaconBlock<T>, block: &'a SignedBeaconBlock<T>,
) -> Result<Vec<IndexedAttestation<T>>> { ) -> Result<Vec<IndexedAttestation<T>>> {
self.sets.reserve(block.message.body.attestations.len());
block block
.message .message
.body .body
.attestations .attestations
.iter() .iter()
.map(|attestation| { .try_fold(
let committee = self Vec::with_capacity(block.message.body.attestations.len()),
.state |mut vec, attestation| {
.get_beacon_committee(attestation.data.slot, attestation.data.index)?; let committee = self
let indexed_attestation = .state
get_indexed_attestation(committee.committee, attestation)?; .get_beacon_committee(attestation.data.slot, attestation.data.index)?;
let indexed_attestation =
get_indexed_attestation(committee.committee, attestation)?;
self.sets.push(indexed_attestation_signature_set( self.sets.push(indexed_attestation_signature_set(
&self.state, &self.state,
self.get_pubkey.clone(), self.get_pubkey.clone(),
&attestation.signature, &attestation.signature,
&indexed_attestation, &indexed_attestation,
&self.spec, &self.spec,
)?); )?);
Ok(indexed_attestation) vec.push(indexed_attestation);
})
.collect::<Result<_>>() Ok(vec)
.map_err(Into::into) },
)
.map_err(Error::into)
} }
/// Includes all signatures in `self.block.body.voluntary_exits` for verification. /// Includes all signatures in `self.block.body.voluntary_exits` for verification.
pub fn include_exits(&mut self, block: &'a SignedBeaconBlock<T>) -> Result<()> { pub fn include_exits(&mut self, block: &'a SignedBeaconBlock<T>) -> Result<()> {
let mut sets = block self.sets.reserve(block.message.body.voluntary_exits.len());
block
.message .message
.body .body
.voluntary_exits .voluntary_exits
.iter() .iter()
.map(|exit| exit_signature_set(&self.state, self.get_pubkey.clone(), exit, &self.spec)) .try_for_each(|exit| {
.collect::<SignatureSetResult<_>>()?; let exit =
exit_signature_set(&self.state, self.get_pubkey.clone(), exit, &self.spec)?;
self.sets.append(&mut sets); self.sets.push(exit);
Ok(()) Ok(())
})
} }
} }