lighthouse/eth2/state_processing/tests/tests.rs
Paul Hauner bcffe42712
Bulk signature verification (#507)
* Add basic block processing benches

* Start reviving state processing benches

* Fix old block builders

* Add optimization for faster pubkey add

* Tidy benches, add another

* Add extra block processing bench

* Start working on faster BLS scheme

* Add partially complete sig verify optimization

* Add .gitignore to state processing

* Add progress on faster signature verification

* Fix SignatureSet for fake_crypto

* Tidy attester slashings sig set

* Tidy bulk signature verifier

* Refactor signature sets to be cleaner

* Start threading SignatureStrategy through code

* Add (empty) test dir

* Move BenchingBlockBuilder

* Add initial block signature verification tests

* Add tests for bulk signature verification

* Start threading SignatureStrategy in block proc.

* Refactor per_block_processing errors

* Use sig set tuples instead of lists of two

* Remove dead code

* Thread VerifySignatures through per_block_processing

* Add bulk signature verification

* Introduce parallel bulk signature verification

* Expand state processing benches

* Fix additional compile errors

* Fix issue where par iter chunks is 0

* Update milagro_bls dep

* Remove debugs, code fragment in beacon chain

* Tidy, add comments to block sig verifier

* Fix various PR comments

* Add block_root option to per_block_processing

* Fix comment in block signature verifier

* Fix comments from PR review

* Remove old comment

* Fix comment
2019-08-29 11:34:25 +10:00

209 lines
5.3 KiB
Rust

use state_processing::{
per_block_processing, test_utils::BlockBuilder, BlockProcessingError, BlockSignatureStrategy,
};
use types::{
AggregateSignature, BeaconBlock, BeaconState, ChainSpec, EthSpec, Keypair, MinimalEthSpec,
Signature, Slot,
};
const VALIDATOR_COUNT: usize = 64;
fn get_block<T, F>(mut mutate_builder: F) -> (BeaconBlock<T>, BeaconState<T>)
where
T: EthSpec,
F: FnMut(&mut BlockBuilder<T>),
{
let spec = T::default_spec();
let mut builder: BlockBuilder<T> = BlockBuilder::new(VALIDATOR_COUNT, &spec);
builder.set_slot(Slot::from(T::slots_per_epoch() * 3 - 2));
builder.build_caches(&spec);
mutate_builder(&mut builder);
builder.build(&spec)
}
fn test_scenario<T: EthSpec, F, G>(mutate_builder: F, mut invalidate_block: G, spec: &ChainSpec)
where
T: EthSpec,
F: FnMut(&mut BlockBuilder<T>),
G: FnMut(&mut BeaconBlock<T>),
{
let (mut block, state) = get_block::<T, _>(mutate_builder);
/*
* Control check to ensure the valid block should pass verification.
*/
assert_eq!(
per_block_processing(
&mut state.clone(),
&block,
None,
BlockSignatureStrategy::VerifyIndividual,
spec
),
Ok(()),
"valid block should pass with verify individual"
);
assert_eq!(
per_block_processing(
&mut state.clone(),
&block,
None,
BlockSignatureStrategy::VerifyBulk,
spec
),
Ok(()),
"valid block should pass with verify bulk"
);
invalidate_block(&mut block);
/*
* Check to ensure the invalid block fails.
*/
assert!(
per_block_processing(
&mut state.clone(),
&block,
None,
BlockSignatureStrategy::VerifyIndividual,
spec
)
.is_err(),
"invalid block should fail with verify individual"
);
assert_eq!(
per_block_processing(
&mut state.clone(),
&block,
None,
BlockSignatureStrategy::VerifyBulk,
spec
),
Err(BlockProcessingError::BulkSignatureVerificationFailed),
"invalid block should fail with verify bulk"
);
}
// TODO: use lazy static
fn agg_sig() -> AggregateSignature {
let mut agg_sig = AggregateSignature::new();
agg_sig.add(&sig());
agg_sig
}
// TODO: use lazy static
fn sig() -> Signature {
let keypair = Keypair::random();
Signature::new(&[42, 42], 12, &keypair.sk)
}
type TestEthSpec = MinimalEthSpec;
mod signatures_minimal {
use super::*;
#[test]
fn block_proposal() {
let spec = &TestEthSpec::default_spec();
test_scenario::<TestEthSpec, _, _>(|_| {}, |block| block.signature = sig(), spec);
}
#[test]
fn randao() {
let spec = &TestEthSpec::default_spec();
test_scenario::<TestEthSpec, _, _>(|_| {}, |block| block.body.randao_reveal = sig(), spec);
}
#[test]
fn proposer_slashing() {
let spec = &TestEthSpec::default_spec();
test_scenario::<TestEthSpec, _, _>(
|mut builder| {
builder.num_proposer_slashings = 1;
},
|block| block.body.proposer_slashings[0].header_1.signature = sig(),
spec,
);
test_scenario::<TestEthSpec, _, _>(
|mut builder| {
builder.num_proposer_slashings = 1;
},
|block| block.body.proposer_slashings[0].header_2.signature = sig(),
spec,
);
}
#[test]
fn attester_slashing() {
let spec = &TestEthSpec::default_spec();
test_scenario::<TestEthSpec, _, _>(
|mut builder| {
builder.num_attester_slashings = 1;
},
|block| block.body.attester_slashings[0].attestation_1.signature = agg_sig(),
spec,
);
test_scenario::<TestEthSpec, _, _>(
|mut builder| {
builder.num_attester_slashings = 1;
},
|block| block.body.attester_slashings[0].attestation_2.signature = agg_sig(),
spec,
);
}
#[test]
fn attestation() {
let spec = &TestEthSpec::default_spec();
test_scenario::<TestEthSpec, _, _>(
|mut builder| {
builder.num_attestations = 1;
},
|block| block.body.attestations[0].signature = agg_sig(),
spec,
);
}
#[test]
// TODO: fix fail by making valid merkle proofs.
#[should_panic]
fn deposit() {
let spec = &TestEthSpec::default_spec();
test_scenario::<TestEthSpec, _, _>(
|mut builder| {
builder.num_deposits = 1;
},
|block| block.body.deposits[0].data.signature = sig().into(),
spec,
);
}
#[test]
fn exit() {
let mut spec = &mut TestEthSpec::default_spec();
// Allows the test to pass.
spec.persistent_committee_period = 0;
test_scenario::<TestEthSpec, _, _>(
|mut builder| {
builder.num_exits = 1;
},
|block| block.body.voluntary_exits[0].signature = sig(),
spec,
);
}
// Cannot test transfers because their length is zero.
}