mirror of
https://gitlab.com/pulsechaincom/lighthouse-pulse.git
synced 2024-12-25 13:07:18 +00:00
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,
|
||||
};
|
||||
|
||||
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;
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user