Add individual processing for ef tests (#745)

* Add Individual signature verification for ef tests

* Add clone state to avoid errors in ef tests

* Add state verification for VerifyIndividual in ef tests

* Add Clone derive for errors

* Update comments
This commit is contained in:
pscott 2020-01-08 00:24:44 +01:00 committed by Michael Sproul
parent 95cc5dd22f
commit 8e1e6838d2
6 changed files with 47 additions and 23 deletions

View File

@ -7,7 +7,7 @@ use types::*;
/// Any of the `...Error` variants indicate that at some point during block (and block operation)
/// verification, there was an error. There is no indication as to _where_ that error happened
/// (e.g., when processing attestations instead of when processing deposits).
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum BlockProcessingError {
RandaoSignatureInvalid,
BulkSignatureVerificationFailed,
@ -122,7 +122,7 @@ pub type AttestationValidationError = BlockOperationError<AttestationInvalid>;
pub type DepositValidationError = BlockOperationError<DepositInvalid>;
pub type ExitValidationError = BlockOperationError<ExitInvalid>;
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum BlockOperationError<T> {
Invalid(T),
BeaconStateError(BeaconStateError),
@ -153,7 +153,7 @@ impl<T> From<ssz_types::Error> for BlockOperationError<T> {
}
}
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum HeaderInvalid {
ProposalSignatureInvalid,
StateSlotMismatch,
@ -161,7 +161,7 @@ pub enum HeaderInvalid {
ProposerSlashed(usize),
}
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum ProposerSlashingInvalid {
/// The proposer index is not a known validator.
ProposerUnknown(u64),
@ -179,7 +179,7 @@ pub enum ProposerSlashingInvalid {
BadProposal2Signature,
}
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum AttesterSlashingInvalid {
/// The attestations were not in conflict.
NotSlashable,
@ -196,7 +196,7 @@ pub enum AttesterSlashingInvalid {
}
/// Describes why an object is invalid.
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum AttestationInvalid {
/// Commmittee index exceeds number of committees in that slot.
BadCommitteeIndex,
@ -251,7 +251,7 @@ impl From<BlockOperationError<IndexedAttestationInvalid>>
}
}
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum IndexedAttestationInvalid {
/// The number of indices exceeds the global maximum.
///
@ -270,7 +270,7 @@ pub enum IndexedAttestationInvalid {
SignatureSetError(SignatureSetError),
}
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum DepositInvalid {
/// The signature (proof-of-possession) does not match the given pubkey.
BadSignature,
@ -281,7 +281,7 @@ pub enum DepositInvalid {
BadMerkleProof,
}
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum ExitInvalid {
/// The specified validator is not active.
NotActive(u64),

View File

@ -14,7 +14,7 @@ use types::{
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum Error {
/// Signature verification failed. The block is invalid.
SignatureInvalid,

View File

@ -28,7 +28,7 @@ mod tests;
pub const CACHED_EPOCHS: usize = 3;
const MAX_RANDOM_BYTE: u64 = (1 << 8) - 1;
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum Error {
EpochOutOfBounds,
SlotOutOfBounds,

View File

@ -10,7 +10,7 @@ pub use crate::multi_cache::MultiTreeHashCache;
use ethereum_types::H256 as Hash256;
use tree_hash::TreeHash;
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum Error {
/// Attempting to provide more than 2^depth leaves to a Merkle tree is disallowed.
TooManyLeaves,

View File

@ -53,7 +53,7 @@ pub mod length {
}
/// Returned when an item encounters an error.
#[derive(PartialEq, Debug)]
#[derive(PartialEq, Debug, Clone)]
pub enum Error {
OutOfBounds {
i: usize,

View File

@ -61,41 +61,65 @@ impl<E: EthSpec> Case for SanityBlocks<E> {
fn result(&self, _case_index: usize) -> Result<(), Error> {
self.metadata.bls_setting.unwrap_or_default().check()?;
let mut state = self.pre.clone();
let mut bulk_state = self.pre.clone();
let mut expected = self.post.clone();
let spec = &E::default_spec();
// Processing requires the epoch cache.
state.build_all_caches(spec).unwrap();
bulk_state.build_all_caches(spec).unwrap();
let mut result = self
// Spawning a second state to call the VerifyIndiviual strategy to avoid bitrot.
// See https://github.com/sigp/lighthouse/issues/742.
let mut indiv_state = bulk_state.clone();
let result = self
.blocks
.iter()
.try_for_each(|block| {
while state.slot < block.slot {
per_slot_processing(&mut state, None, spec).unwrap();
while bulk_state.slot < block.slot {
per_slot_processing(&mut bulk_state, None, spec).unwrap();
per_slot_processing(&mut indiv_state, None, spec).unwrap();
}
state
bulk_state
.build_committee_cache(RelativeEpoch::Current, spec)
.unwrap();
indiv_state
.build_committee_cache(RelativeEpoch::Current, spec)
.unwrap();
per_block_processing(
&mut state,
&mut indiv_state,
block,
None,
BlockSignatureStrategy::VerifyIndividual,
spec,
)?;
per_block_processing(
&mut bulk_state,
block,
None,
BlockSignatureStrategy::VerifyBulk,
spec,
)?;
if block.state_root == state.canonical_root() {
if block.state_root == bulk_state.canonical_root()
&& block.state_root == indiv_state.canonical_root()
{
Ok(())
} else {
Err(BlockProcessingError::StateRootMismatch)
}
})
.map(|_| state);
.map(|_| (bulk_state, indiv_state));
compare_beacon_state_results_without_caches(&mut result, &mut expected)
let (mut bulk_result, mut indiv_result) = match result {
Err(e) => (Err(e.clone()), Err(e)),
Ok(res) => (Ok(res.0), Ok(res.1)),
};
compare_beacon_state_results_without_caches(&mut indiv_result, &mut expected)?;
compare_beacon_state_results_without_caches(&mut bulk_result, &mut expected)
}
}