invalid block signature test

This commit is contained in:
Darren Langley 2019-04-15 10:38:13 +10:00
parent bb0500f11d
commit d76246e600
4 changed files with 50 additions and 241 deletions

View File

@ -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;

View File

@ -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<u64> = 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)
}

View File

@ -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

View File

@ -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;