diff --git a/eth2/state_processing/Cargo.toml b/eth2/state_processing/Cargo.toml index 4b031022a..0fc7910c8 100644 --- a/eth2/state_processing/Cargo.toml +++ b/eth2/state_processing/Cargo.toml @@ -29,3 +29,6 @@ tree_hash = { path = "../utils/tree_hash" } tree_hash_derive = { path = "../utils/tree_hash_derive" } types = { path = "../types" } rayon = "1.0" + +[features] +fake_crypto = ["bls/fake_crypto"] \ No newline at end of file diff --git a/eth2/state_processing/src/per_block_processing/block_processing_builder.rs b/eth2/state_processing/src/per_block_processing/block_processing_builder.rs index fb9dbd153..307fc4a3d 100644 --- a/eth2/state_processing/src/per_block_processing/block_processing_builder.rs +++ b/eth2/state_processing/src/per_block_processing/block_processing_builder.rs @@ -1,14 +1,15 @@ use types::test_utils::{TestingBeaconBlockBuilder, TestingBeaconStateBuilder}; use types::*; +use tree_hash::SignedRoot; -pub struct BlockProcessingBuilder { - pub state_builder: TestingBeaconStateBuilder, +pub struct BlockProcessingBuilder { + pub state_builder: TestingBeaconStateBuilder, pub block_builder: TestingBeaconBlockBuilder, pub num_validators: usize, } -impl BlockProcessingBuilder { +impl BlockProcessingBuilder { pub fn new(num_validators: usize, spec: &ChainSpec) -> Self { let state_builder = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(num_validators, &spec); @@ -30,12 +31,17 @@ impl BlockProcessingBuilder { self.state_builder.build_caches(&spec).unwrap(); } - pub fn build(mut self, randao_sk: Option, spec: &ChainSpec) -> (BeaconBlock, BeaconState) { + pub fn build(mut self, randao_sk: Option, previous_block_root: Option, spec: &ChainSpec) -> (BeaconBlock, BeaconState) { let (state, keypairs) = self.state_builder.build(); let builder = &mut self.block_builder; builder.set_slot(state.slot); + match previous_block_root { + Some(root) => builder.set_previous_block_root(root), + None => builder.set_previous_block_root(Hash256::from_slice(&state.latest_block_header.signed_root())), + } + let proposer_index = state .get_beacon_proposer_index(state.slot, RelativeEpoch::Current, spec) .unwrap(); diff --git a/eth2/state_processing/src/per_block_processing/tests.rs b/eth2/state_processing/src/per_block_processing/tests.rs index 6ae7fd872..715c3e852 100644 --- a/eth2/state_processing/src/per_block_processing/tests.rs +++ b/eth2/state_processing/src/per_block_processing/tests.rs @@ -1,17 +1,17 @@ -#![cfg(test)] +#![cfg(all(test, not(feature = "fake_crypto")))] use super::block_processing_builder::BlockProcessingBuilder; use super::errors::*; use crate::per_block_processing; -use ssz::SignedRoot; -use types::{ChainSpec, Domain, Keypair, Signature, Slot}; +use tree_hash::SignedRoot; +use types::*; pub const VALIDATOR_COUNT: usize = 10; #[test] fn valid_block_ok() { - let spec = ChainSpec::foundation(); + let spec = FoundationEthSpec::spec(); let builder = get_builder(&spec); - let (block, mut state) = builder.build(None, &spec); + let (block, mut state) = builder.build(None, None, &spec); let result = per_block_processing(&mut state, &block, &spec); @@ -20,9 +20,9 @@ fn valid_block_ok() { #[test] fn invalid_block_header_state_slot() { - let spec = ChainSpec::foundation(); + let spec = FoundationEthSpec::spec(); let builder = get_builder(&spec); - let (mut block, mut state) = builder.build(None, &spec); + let (mut block, mut state) = builder.build(None, None, &spec); state.slot = Slot::new(133713); block.slot = Slot::new(424242); @@ -38,16 +38,30 @@ fn invalid_block_header_state_slot() { } #[test] -#[ignore] fn invalid_parent_block_root() { - // this will be changed in spec 0.5.1 to use signed root + let spec = FoundationEthSpec::spec(); + let builder = get_builder(&spec); + let invalid_parent_root = Hash256::from([0xAA; 32]); + let (block, mut state) = builder.build(None, Some(invalid_parent_root), &spec); + + let result = per_block_processing(&mut state, &block, &spec); + + assert_eq!( + result, + Err(BlockProcessingError::Invalid( + BlockInvalid::ParentBlockRootMismatch{ + state: Hash256::from_slice(&state.latest_block_header.signed_root()), + block: block.previous_block_root + } + )) + ); } #[test] fn invalid_block_signature() { - let spec = ChainSpec::foundation(); + let spec = FoundationEthSpec::spec(); let builder = get_builder(&spec); - let (mut block, mut state) = builder.build(None, &spec); + let (mut block, mut state) = builder.build(None, None, &spec); // sign the block with a keypair that is not the expected proposer let keypair = Keypair::random(); @@ -68,12 +82,12 @@ fn invalid_block_signature() { #[test] fn invalid_randao_reveal_signature() { - let spec = ChainSpec::foundation(); + let spec = FoundationEthSpec::spec(); let builder = get_builder(&spec); // sign randao reveal with random keypair let keypair = Keypair::random(); - let (block, mut state) = builder.build(Some(keypair.sk), &spec); + let (block, mut state) = builder.build(Some(keypair.sk), None, &spec); let result = per_block_processing(&mut state, &block, &spec); @@ -84,7 +98,7 @@ fn invalid_randao_reveal_signature() { ); } -fn get_builder(spec: &ChainSpec) -> (BlockProcessingBuilder) { +fn get_builder(spec: &ChainSpec) -> (BlockProcessingBuilder) { let mut builder = BlockProcessingBuilder::new(VALIDATOR_COUNT, &spec); // Set the state and block to be in the last slot of the 4th epoch. diff --git a/eth2/types/src/test_utils/testing_beacon_block_builder.rs b/eth2/types/src/test_utils/testing_beacon_block_builder.rs index 9c75bde0e..9dca6222a 100644 --- a/eth2/types/src/test_utils/testing_beacon_block_builder.rs +++ b/eth2/types/src/test_utils/testing_beacon_block_builder.rs @@ -23,6 +23,11 @@ impl TestingBeaconBlockBuilder { } } + /// Set the previous block root + pub fn set_previous_block_root(&mut self, root: Hash256) { + self.block.previous_block_root = root; + } + /// Set the slot of the block. pub fn set_slot(&mut self, slot: Slot) { self.block.slot = slot; diff --git a/eth2/utils/bls/src/fake_signature.rs b/eth2/utils/bls/src/fake_signature.rs index 0bf3d0a25..de16a05f3 100644 --- a/eth2/utils/bls/src/fake_signature.rs +++ b/eth2/utils/bls/src/fake_signature.rs @@ -14,6 +14,7 @@ use tree_hash::tree_hash_ssz_encoding_as_vector; #[derive(Debug, PartialEq, Clone, Eq)] pub struct FakeSignature { bytes: Vec, + is_empty: bool, } impl FakeSignature { @@ -26,6 +27,7 @@ impl FakeSignature { pub fn zero() -> Self { Self { bytes: vec![0; BLS_SIG_BYTE_SIZE], + is_empty: true, } } @@ -59,6 +61,7 @@ impl FakeSignature { } else { Ok(Self { bytes: bytes.to_vec(), + is_empty: false, }) } } @@ -71,6 +74,11 @@ impl FakeSignature { pub fn empty_signature() -> Self { FakeSignature::zero() } + + // Check for empty Signature + pub fn is_empty(&self) -> bool { + self.is_empty + } } impl_ssz!(FakeSignature, BLS_SIG_BYTE_SIZE, "FakeSignature");