From d76246e6009a4d21f0a8a0447a6860b3fb6deadf Mon Sep 17 00:00:00 2001 From: Darren Langley Date: Mon, 15 Apr 2019 10:38:13 +1000 Subject: [PATCH] invalid block signature test --- .../src/per_block_processing.rs | 2 +- .../block_processing_builder.rs | 135 +---------------- .../src/per_block_processing/tests.rs | 142 ++++++------------ eth2/utils/bls/src/lib.rs | 12 -- 4 files changed, 50 insertions(+), 241 deletions(-) diff --git a/eth2/state_processing/src/per_block_processing.rs b/eth2/state_processing/src/per_block_processing.rs index aac94d55c..ac874d95e 100644 --- a/eth2/state_processing/src/per_block_processing.rs +++ b/eth2/state_processing/src/per_block_processing.rs @@ -20,9 +20,9 @@ pub use verify_transfer::{ execute_transfer, verify_transfer, verify_transfer_time_independent_only, }; +pub mod block_processing_builder; pub mod errors; pub mod tests; -pub mod block_processing_builder; mod validate_attestation; mod verify_attester_slashing; mod verify_deposit; 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 99bbf0944..489684523 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,4 +1,3 @@ -use log::info; use types::test_utils::{TestingBeaconBlockBuilder, TestingBeaconStateBuilder}; use types::*; @@ -7,13 +6,6 @@ pub struct BlockProcessingBuilder { pub block_builder: TestingBeaconBlockBuilder, pub num_validators: usize, - pub num_proposer_slashings: usize, - pub num_attester_slashings: usize, - pub num_indices_per_slashable_vote: usize, - pub num_attestations: usize, - pub num_deposits: usize, - pub num_exits: usize, - pub num_transfers: usize, } impl BlockProcessingBuilder { @@ -26,26 +18,9 @@ impl BlockProcessingBuilder { state_builder, block_builder, num_validators: 0, - num_proposer_slashings: 0, - num_attester_slashings: 0, - num_indices_per_slashable_vote: spec.max_indices_per_slashable_vote as usize, - num_attestations: 0, - num_deposits: 0, - num_exits: 0, - num_transfers: 0, } } - pub fn maximize_block_operations(&mut self, spec: &ChainSpec) { - self.num_proposer_slashings = spec.max_proposer_slashings as usize; - self.num_attester_slashings = spec.max_attester_slashings as usize; - self.num_indices_per_slashable_vote = spec.max_indices_per_slashable_vote as usize; - self.num_attestations = spec.max_attestations as usize; - self.num_deposits = spec.max_deposits as usize; - self.num_exits = spec.max_voluntary_exits as usize; - self.num_transfers = spec.max_transfers as usize; - } - pub fn set_slot(&mut self, slot: Slot, spec: &ChainSpec) { self.state_builder.teleport_to_slot(slot, &spec); } @@ -56,119 +31,19 @@ impl BlockProcessingBuilder { } pub fn build(mut self, spec: &ChainSpec) -> (BeaconBlock, BeaconState) { - let (mut state, keypairs) = self.state_builder.build(); + let (state, keypairs) = self.state_builder.build(); let builder = &mut self.block_builder; builder.set_slot(state.slot); - let proposer_index = state.get_beacon_proposer_index(state.slot, RelativeEpoch::Current, spec).unwrap(); + let proposer_index = state + .get_beacon_proposer_index(state.slot, RelativeEpoch::Current, spec) + .unwrap(); let keypair = &keypairs[proposer_index]; builder.set_randao_reveal(&keypair.sk, &state.fork, spec); - // Used as a stream of validator indices for use in slashings, exits, etc. - let mut validators_iter = (0..keypairs.len() as u64).into_iter(); - - // Insert `ProposerSlashing` objects. - for _ in 0..self.num_proposer_slashings { - let validator_index = validators_iter.next().expect("Insufficient validators."); - - builder.insert_proposer_slashing( - validator_index, - &keypairs[validator_index as usize].sk, - &state.fork, - spec, - ); - } - info!( - "Inserted {} proposer slashings.", - builder.block.body.proposer_slashings.len() - ); - - // Insert `AttesterSlashing` objects - for _ in 0..self.num_attester_slashings { - let mut attesters: Vec = vec![]; - let mut secret_keys: Vec<&SecretKey> = vec![]; - - for _ in 0..self.num_indices_per_slashable_vote { - let validator_index = validators_iter.next().expect("Insufficient validators."); - - attesters.push(validator_index); - secret_keys.push(&keypairs[validator_index as usize].sk); - } - - builder.insert_attester_slashing(&attesters, &secret_keys, &state.fork, spec); - } - info!( - "Inserted {} attester slashings.", - builder.block.body.attester_slashings.len() - ); - - // Insert `Attestation` objects. - let all_secret_keys: Vec<&SecretKey> = keypairs.iter().map(|keypair| &keypair.sk).collect(); - builder - .insert_attestations( - &state, - &all_secret_keys, - self.num_attestations as usize, - spec, - ) - .unwrap(); - info!( - "Inserted {} attestations.", - builder.block.body.attestations.len() - ); - - // Insert `Deposit` objects. - for i in 0..self.num_deposits { - builder.insert_deposit( - 32_000_000_000, - state.deposit_index + (i as u64), - &state, - spec, - ); - } - info!("Inserted {} deposits.", builder.block.body.deposits.len()); - - // Insert the maximum possible number of `Exit` objects. - for _ in 0..self.num_exits { - let validator_index = validators_iter.next().expect("Insufficient validators."); - - builder.insert_exit( - &state, - validator_index, - &keypairs[validator_index as usize].sk, - spec, - ); - } - info!( - "Inserted {} exits.", - builder.block.body.voluntary_exits.len() - ); - - // Insert the maximum possible number of `Transfer` objects. - for _ in 0..self.num_transfers { - let validator_index = validators_iter.next().expect("Insufficient validators."); - - // Manually set the validator to be withdrawn. - state.validator_registry[validator_index as usize].withdrawable_epoch = - state.previous_epoch(spec); - - builder.insert_transfer( - &state, - validator_index, - validator_index, - 1, - keypairs[validator_index as usize].clone(), - spec, - ); - } - info!("Inserted {} transfers.", builder.block.body.transfers.len()); - - let mut block = self.block_builder.build(&keypair.sk, &state.fork, spec); - - // Set the eth1 data to be different from the state. - block.body.eth1_data.block_hash = Hash256::from_slice(&vec![42; 32]); + let block = self.block_builder.build(&keypair.sk, &state.fork, spec); (block, state) } diff --git a/eth2/state_processing/src/per_block_processing/tests.rs b/eth2/state_processing/src/per_block_processing/tests.rs index ac294de69..6fe7e40d2 100644 --- a/eth2/state_processing/src/per_block_processing/tests.rs +++ b/eth2/state_processing/src/per_block_processing/tests.rs @@ -1,39 +1,72 @@ #![cfg(test)] -use crate::per_block_processing; use super::block_processing_builder::BlockProcessingBuilder; use super::errors::*; -use types::*; +use crate::per_block_processing; +use ssz::SignedRoot; +use types::{ChainSpec, Domain, Keypair, Signature, Slot}; pub const VALIDATOR_COUNT: usize = 10; #[test] -fn runs_without_error() { +fn valid_block_ok() { let spec = ChainSpec::foundation(); - let (block, mut state) = get_block_state(&spec); + let builder = get_builder(&spec); + let (block, mut state) = builder.build(&spec); - per_block_processing(&mut state, &block, &spec).unwrap(); + let result = per_block_processing(&mut state, &block, &spec); + + assert_eq!(result, Ok(())); } #[test] -fn process_block_header_invalid_state_slot() { +fn invalid_block_header_state_slot() { let spec = ChainSpec::foundation(); - let (mut block, mut state) = get_block_state(&spec); + let builder = get_builder(&spec); + let (mut block, mut state) = builder.build(&spec); state.slot = Slot::new(133713); block.slot = Slot::new(424242); let result = per_block_processing(&mut state, &block, &spec); - assert_eq!(result, Err(BlockProcessingError::Invalid(BlockInvalid::StateSlotMismatch))); + assert_eq!( + result, + Err(BlockProcessingError::Invalid( + BlockInvalid::StateSlotMismatch + )) + ); } #[test] #[ignore] -fn process_block_header_invalid_parent_block_root() { +fn invalid_parent_block_root() { // this will be changed in spec 0.5.1 to use signed root } -fn get_block_state(spec: &ChainSpec) -> (BeaconBlock, BeaconState) { +#[test] +fn invalid_block_signature() { + let spec = ChainSpec::foundation(); + let builder = get_builder(&spec); + let (mut block, mut state) = builder.build(&spec); + + // sign the block with a keypair that is not the expected proposer + let keypair = Keypair::random(); + let message = block.signed_root(); + let epoch = block.slot.epoch(spec.slots_per_epoch); + let domain = spec.get_domain(epoch, Domain::BeaconBlock, &state.fork); + block.signature = Signature::new(&message, domain, &keypair.sk); + + // process block with invalid block signature + let result = per_block_processing(&mut state, &block, &spec); + + // should get a BadSignature error + assert_eq!( + result, + Err(BlockProcessingError::Invalid(BlockInvalid::BadSignature)) + ); +} + +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. @@ -41,92 +74,5 @@ fn get_block_state(spec: &ChainSpec) -> (BeaconBlock, BeaconState) { builder.set_slot(last_slot_of_epoch, &spec); builder.build_caches(&spec); - let (block, state) = builder.build(&spec); - - (block, state) + (builder) } - -// verify_block_signature -// Invalid::BadSignature - -// process_randao -// Invalid::BadRandaoSignature - -// process_proposer_slashings -// Invalid::MaxProposerSlashingsExceeded -// verify_proposer_slashing -// Invalid::ProposerUnknown -// Invalid::ProposalSlotMismatch -// Invalid::ProposalsIdentical -// Invalid::ProposerAlreadySlashed -// Invalid::ProposerAlreadyWithdrawn -// Invalid::BadProposal1Signature -// Invalid::BadProposal2Signature - -// process_attester_slashings -// Invalid::MaxAttesterSlashingsExceed -// verify_attester_slashing -// Invalid::AttestationDataIdentical -// Invalid::NotSlashable -// Invalid::SlashableAttestation1Invalid -// Invalid::SlashableAttestation2Invalid - -// process_attestations -// Invalid::MaxAttestationsExceeded -// validate_attestation -// Invalid::PreGenesis -// Invalid::IncludedTooLate -// Invalid::IncludedTooEarly -// Invalid::BadPreviousCrosslink -// Invalid::AggregationBitfieldIsEmpty -// Invalid::CustodyBitfieldHasSetBits -// Invalid::NoCommitteeForShard -// Invalid::BadCustodyBitfieldLength -// Invalid::BadAggregationBitfieldLength -// Invalid::ShardBlockRootNotZero -// verify_justified_epoch_and_root -// Invalid::WrongJustifiedEpoch (current) -// Invalid::WrongJustifiedRoot (current) -// Invalid::WrongJustifiedEpoch (previous) -// Invalid::WrongJustifiedRoot (previous) -// verify_attestation_signature -// Invalid::BadAggregationBitfieldLength -// Invalid::BadCustodyBitfieldLength -// BeaconStateError::UnknownValidator -// Invalid::BadSignature - -// process_deposits -// Invalid::MaxDepositsExceeded -// verify_deposit -// Invalid::BadProofOfPossession -// Invalid::BadMerkleProof -// verify_deposit_index -// Invalid::BadIndex - -// process_exits -// Invalid::MaxExitsExceeded -// verify_exit -// Invalid::ValidatorUnknown -// Invalid::AlreadyExited -// Invalid::AlreadyInitiatedExited -// Invalid::FutureEpoch -// Invalid::TooYoungToLeave -// Invalid::BadSignature - -// process_transfers -// Invalid::MaxTransfersExceed -// verify_transfer -// Invalid::FromValidatorUnknown -// Invalid::FeeOverflow -// Invalid::FromBalanceInsufficient (amount) -// Invalid::FromBalanceInsufficient (fee) -// Invalid::InvalidResultingFromBalance -// Invalid::TransferSlotInPast -// Invalid::StateSlotMismatch -// Invalid::FromValidatorUnknown (???) -// Invalid::FromValidatorIneligableForTransfer -// Invalid::WithdrawalCredentialsMismatch -// Invalid::BadSignature - - - diff --git a/eth2/utils/bls/src/lib.rs b/eth2/utils/bls/src/lib.rs index b9a4d5c1d..caf56ae74 100644 --- a/eth2/utils/bls/src/lib.rs +++ b/eth2/utils/bls/src/lib.rs @@ -6,23 +6,11 @@ mod keypair; mod public_key; mod secret_key; -#[cfg(not(debug_assertions))] mod aggregate_signature; -#[cfg(not(debug_assertions))] mod signature; -#[cfg(not(debug_assertions))] pub use crate::aggregate_signature::AggregateSignature; -#[cfg(not(debug_assertions))] pub use crate::signature::Signature; -#[cfg(debug_assertions)] -mod fake_aggregate_signature; -#[cfg(debug_assertions)] -mod fake_signature; -#[cfg(debug_assertions)] -pub use crate::fake_aggregate_signature::FakeAggregateSignature as AggregateSignature; -#[cfg(debug_assertions)] -pub use crate::fake_signature::FakeSignature as Signature; pub use crate::aggregate_public_key::AggregatePublicKey; pub use crate::keypair::Keypair;