diff --git a/eth2/state_processing/src/per_block_processing/errors.rs b/eth2/state_processing/src/per_block_processing/errors.rs index c247794599..c21a570645 100644 --- a/eth2/state_processing/src/per_block_processing/errors.rs +++ b/eth2/state_processing/src/per_block_processing/errors.rs @@ -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; pub type DepositValidationError = BlockOperationError; pub type ExitValidationError = BlockOperationError; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub enum BlockOperationError { Invalid(T), BeaconStateError(BeaconStateError), @@ -153,7 +153,7 @@ impl From for BlockOperationError { } } -#[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> } } -#[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), diff --git a/eth2/state_processing/src/per_block_processing/signature_sets.rs b/eth2/state_processing/src/per_block_processing/signature_sets.rs index f765351880..81e61f2602 100644 --- a/eth2/state_processing/src/per_block_processing/signature_sets.rs +++ b/eth2/state_processing/src/per_block_processing/signature_sets.rs @@ -14,7 +14,7 @@ use types::{ pub type Result = std::result::Result; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub enum Error { /// Signature verification failed. The block is invalid. SignatureInvalid, diff --git a/eth2/types/src/beacon_state.rs b/eth2/types/src/beacon_state.rs index a91b26a7ac..1cc148f4fa 100644 --- a/eth2/types/src/beacon_state.rs +++ b/eth2/types/src/beacon_state.rs @@ -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, diff --git a/eth2/utils/cached_tree_hash/src/lib.rs b/eth2/utils/cached_tree_hash/src/lib.rs index cc47ab21f2..135b07050f 100644 --- a/eth2/utils/cached_tree_hash/src/lib.rs +++ b/eth2/utils/cached_tree_hash/src/lib.rs @@ -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, diff --git a/eth2/utils/ssz_types/src/lib.rs b/eth2/utils/ssz_types/src/lib.rs index b4c96eefbd..c4bb3b164e 100644 --- a/eth2/utils/ssz_types/src/lib.rs +++ b/eth2/utils/ssz_types/src/lib.rs @@ -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, diff --git a/tests/ef_tests/src/cases/sanity_blocks.rs b/tests/ef_tests/src/cases/sanity_blocks.rs index 6996b020fb..acd50ab448 100644 --- a/tests/ef_tests/src/cases/sanity_blocks.rs +++ b/tests/ef_tests/src/cases/sanity_blocks.rs @@ -61,41 +61,65 @@ impl Case for SanityBlocks { 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) } }