invalid block signature test
This commit is contained in:
parent
bb0500f11d
commit
d76246e600
@ -20,9 +20,9 @@ pub use verify_transfer::{
|
|||||||
execute_transfer, verify_transfer, verify_transfer_time_independent_only,
|
execute_transfer, verify_transfer, verify_transfer_time_independent_only,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub mod block_processing_builder;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod tests;
|
pub mod tests;
|
||||||
pub mod block_processing_builder;
|
|
||||||
mod validate_attestation;
|
mod validate_attestation;
|
||||||
mod verify_attester_slashing;
|
mod verify_attester_slashing;
|
||||||
mod verify_deposit;
|
mod verify_deposit;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use log::info;
|
|
||||||
use types::test_utils::{TestingBeaconBlockBuilder, TestingBeaconStateBuilder};
|
use types::test_utils::{TestingBeaconBlockBuilder, TestingBeaconStateBuilder};
|
||||||
use types::*;
|
use types::*;
|
||||||
|
|
||||||
@ -7,13 +6,6 @@ pub struct BlockProcessingBuilder {
|
|||||||
pub block_builder: TestingBeaconBlockBuilder,
|
pub block_builder: TestingBeaconBlockBuilder,
|
||||||
|
|
||||||
pub num_validators: usize,
|
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 {
|
impl BlockProcessingBuilder {
|
||||||
@ -26,26 +18,9 @@ impl BlockProcessingBuilder {
|
|||||||
state_builder,
|
state_builder,
|
||||||
block_builder,
|
block_builder,
|
||||||
num_validators: 0,
|
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) {
|
pub fn set_slot(&mut self, slot: Slot, spec: &ChainSpec) {
|
||||||
self.state_builder.teleport_to_slot(slot, &spec);
|
self.state_builder.teleport_to_slot(slot, &spec);
|
||||||
}
|
}
|
||||||
@ -56,119 +31,19 @@ impl BlockProcessingBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(mut self, spec: &ChainSpec) -> (BeaconBlock, BeaconState) {
|
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;
|
let builder = &mut self.block_builder;
|
||||||
|
|
||||||
builder.set_slot(state.slot);
|
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];
|
let keypair = &keypairs[proposer_index];
|
||||||
|
|
||||||
builder.set_randao_reveal(&keypair.sk, &state.fork, spec);
|
builder.set_randao_reveal(&keypair.sk, &state.fork, spec);
|
||||||
|
|
||||||
// Used as a stream of validator indices for use in slashings, exits, etc.
|
let block = self.block_builder.build(&keypair.sk, &state.fork, spec);
|
||||||
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]);
|
|
||||||
|
|
||||||
(block, state)
|
(block, state)
|
||||||
}
|
}
|
||||||
|
@ -1,39 +1,72 @@
|
|||||||
#![cfg(test)]
|
#![cfg(test)]
|
||||||
use crate::per_block_processing;
|
|
||||||
use super::block_processing_builder::BlockProcessingBuilder;
|
use super::block_processing_builder::BlockProcessingBuilder;
|
||||||
use super::errors::*;
|
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;
|
pub const VALIDATOR_COUNT: usize = 10;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn runs_without_error() {
|
fn valid_block_ok() {
|
||||||
let spec = ChainSpec::foundation();
|
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]
|
#[test]
|
||||||
fn process_block_header_invalid_state_slot() {
|
fn invalid_block_header_state_slot() {
|
||||||
let spec = ChainSpec::foundation();
|
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);
|
state.slot = Slot::new(133713);
|
||||||
block.slot = Slot::new(424242);
|
block.slot = Slot::new(424242);
|
||||||
|
|
||||||
let result = per_block_processing(&mut state, &block, &spec);
|
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]
|
#[test]
|
||||||
#[ignore]
|
#[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
|
// 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);
|
let mut builder = BlockProcessingBuilder::new(VALIDATOR_COUNT, &spec);
|
||||||
|
|
||||||
// Set the state and block to be in the last slot of the 4th epoch.
|
// 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.set_slot(last_slot_of_epoch, &spec);
|
||||||
builder.build_caches(&spec);
|
builder.build_caches(&spec);
|
||||||
|
|
||||||
let (block, state) = builder.build(&spec);
|
(builder)
|
||||||
|
|
||||||
(block, state)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,23 +6,11 @@ mod keypair;
|
|||||||
mod public_key;
|
mod public_key;
|
||||||
mod secret_key;
|
mod secret_key;
|
||||||
|
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
mod aggregate_signature;
|
mod aggregate_signature;
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
mod signature;
|
mod signature;
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
pub use crate::aggregate_signature::AggregateSignature;
|
pub use crate::aggregate_signature::AggregateSignature;
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
pub use crate::signature::Signature;
|
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::aggregate_public_key::AggregatePublicKey;
|
||||||
pub use crate::keypair::Keypair;
|
pub use crate::keypair::Keypair;
|
||||||
|
Loading…
Reference in New Issue
Block a user