lighthouse/slasher/src/test_utils.rs
Wink Saville 58870fc6d3 Add test_logger as feature to logging (#2586)
## Issue Addressed

Fix #2585

## Proposed Changes

Provide a canonical version of test_logger that can be used
throughout lighthouse.

## Additional Info

This allows tests to conditionally emit logging data by adding
test_logger as the default logger. And then when executing
`cargo test --features logging/test_logger` log output
will be visible:

  wink@3900x:~/lighthouse/common/logging/tests/test-feature-test_logger (Add-test_logger-as-feature-to-logging)
  $ cargo test --features logging/test_logger
      Finished test [unoptimized + debuginfo] target(s) in 0.02s
       Running unittests (target/debug/deps/test_logger-e20115db6a5e3714)

  running 1 test
  Sep 10 12:53:45.212 INFO hi, module: test_logger:8
  test tests::test_fn_with_logging ... ok

  test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Doc-tests test-logger

  running 0 tests

  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

Or, in normal scenarios where logging isn't needed, executing
`cargo test` the log output will not be visible:

  wink@3900x:~/lighthouse/common/logging/tests/test-feature-test_logger (Add-test_logger-as-feature-to-logging)
  $ cargo test
      Finished test [unoptimized + debuginfo] target(s) in 0.02s
       Running unittests (target/debug/deps/test_logger-02e02f8d41e8cf8a)

  running 1 test
  test tests::test_fn_with_logging ... ok

  test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Doc-tests test-logger

  running 0 tests

  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
2021-10-06 00:46:07 +00:00

108 lines
3.1 KiB
Rust

use std::collections::HashSet;
use types::{
AggregateSignature, AttestationData, AttesterSlashing, BeaconBlockHeader, Checkpoint, Epoch,
Hash256, IndexedAttestation, MainnetEthSpec, Signature, SignedBeaconBlockHeader, Slot,
};
pub type E = MainnetEthSpec;
pub fn indexed_att(
attesting_indices: impl AsRef<[u64]>,
source_epoch: u64,
target_epoch: u64,
target_root: u64,
) -> IndexedAttestation<E> {
IndexedAttestation {
attesting_indices: attesting_indices.as_ref().to_vec().into(),
data: AttestationData {
slot: Slot::new(0),
index: 0,
beacon_block_root: Hash256::zero(),
source: Checkpoint {
epoch: Epoch::new(source_epoch),
root: Hash256::from_low_u64_be(0),
},
target: Checkpoint {
epoch: Epoch::new(target_epoch),
root: Hash256::from_low_u64_be(target_root),
},
},
signature: AggregateSignature::empty(),
}
}
pub fn att_slashing(
attestation_1: &IndexedAttestation<E>,
attestation_2: &IndexedAttestation<E>,
) -> AttesterSlashing<E> {
AttesterSlashing {
attestation_1: attestation_1.clone(),
attestation_2: attestation_2.clone(),
}
}
pub fn hashset_intersection(
attestation_1_indices: &[u64],
attestation_2_indices: &[u64],
) -> HashSet<u64> {
&attestation_1_indices
.iter()
.copied()
.collect::<HashSet<u64>>()
& &attestation_2_indices
.iter()
.copied()
.collect::<HashSet<u64>>()
}
pub fn slashed_validators_from_slashings(slashings: &HashSet<AttesterSlashing<E>>) -> HashSet<u64> {
slashings
.iter()
.flat_map(|slashing| {
let att1 = &slashing.attestation_1;
let att2 = &slashing.attestation_2;
assert!(
att1.is_double_vote(att2) || att1.is_surround_vote(att2),
"invalid slashing: {:#?}",
slashing
);
hashset_intersection(&att1.attesting_indices, &att2.attesting_indices)
})
.collect()
}
pub fn slashed_validators_from_attestations(
attestations: &[IndexedAttestation<E>],
) -> HashSet<u64> {
let mut slashed_validators = HashSet::new();
// O(n^2) code, watch out.
for att1 in attestations {
for att2 in attestations {
if att1 == att2 {
continue;
}
if att1.is_double_vote(att2) || att1.is_surround_vote(att2) {
slashed_validators.extend(hashset_intersection(
&att1.attesting_indices,
&att2.attesting_indices,
));
}
}
}
slashed_validators
}
pub fn block(slot: u64, proposer_index: u64, block_root: u64) -> SignedBeaconBlockHeader {
SignedBeaconBlockHeader {
message: BeaconBlockHeader {
slot: Slot::new(slot),
proposer_index,
parent_root: Hash256::zero(),
state_root: Hash256::zero(),
body_root: Hash256::from_low_u64_be(block_root),
},
signature: Signature::empty(),
}
}