Export slashing protection per validator (#2674)

## Issue Addressed

Part of https://github.com/sigp/lighthouse/issues/2557

## Proposed Changes

Refactor the slashing protection export so that it can export data for a subset of validators.

This is the last remaining building block required for supporting the standard validator API (which I'll start to build atop this branch)

## Additional Info

Built on and requires #2598
This commit is contained in:
Michael Sproul
2021-10-19 00:30:38 +00:00
parent e75ce534f6
commit 06e310c4eb
5 changed files with 234 additions and 77 deletions

View File

@@ -73,16 +73,6 @@ impl<T> Default for StreamTest<T> {
}
}
impl<T> StreamTest<T> {
/// The number of test cases that are expected to pass processing successfully.
fn num_expected_successes(&self) -> usize {
self.cases
.iter()
.filter(|case| case.expected.is_ok())
.count()
}
}
impl StreamTest<AttestationData> {
pub fn run(&self) {
let dir = tempdir().unwrap();
@@ -93,6 +83,8 @@ impl StreamTest<AttestationData> {
slashing_db.register_validator(*pubkey).unwrap();
}
check_registration_invariants(&slashing_db, &self.registered_validators);
for (i, test) in self.cases.iter().enumerate() {
assert_eq!(
slashing_db.check_and_insert_attestation(&test.pubkey, &test.data, test.domain),
@@ -102,7 +94,7 @@ impl StreamTest<AttestationData> {
);
}
roundtrip_database(&dir, &slashing_db, self.num_expected_successes() == 0);
roundtrip_database(&dir, &slashing_db, self.registered_validators.is_empty());
}
}
@@ -116,6 +108,8 @@ impl StreamTest<BeaconBlockHeader> {
slashing_db.register_validator(*pubkey).unwrap();
}
check_registration_invariants(&slashing_db, &self.registered_validators);
for (i, test) in self.cases.iter().enumerate() {
assert_eq!(
slashing_db.check_and_insert_block_proposal(&test.pubkey, &test.data, test.domain),
@@ -125,7 +119,7 @@ impl StreamTest<BeaconBlockHeader> {
);
}
roundtrip_database(&dir, &slashing_db, self.num_expected_successes() == 0);
roundtrip_database(&dir, &slashing_db, self.registered_validators.is_empty());
}
}
@@ -133,7 +127,7 @@ impl StreamTest<BeaconBlockHeader> {
// the implicit minification done on import.
fn roundtrip_database(dir: &TempDir, db: &SlashingDatabase, is_empty: bool) {
let exported = db
.export_interchange_info(DEFAULT_GENESIS_VALIDATORS_ROOT)
.export_all_interchange_info(DEFAULT_GENESIS_VALIDATORS_ROOT)
.unwrap();
let new_db =
SlashingDatabase::create(&dir.path().join("roundtrip_slashing_protection.sqlite")).unwrap();
@@ -141,7 +135,7 @@ fn roundtrip_database(dir: &TempDir, db: &SlashingDatabase, is_empty: bool) {
.import_interchange_info(exported.clone(), DEFAULT_GENESIS_VALIDATORS_ROOT)
.unwrap();
let reexported = new_db
.export_interchange_info(DEFAULT_GENESIS_VALIDATORS_ROOT)
.export_all_interchange_info(DEFAULT_GENESIS_VALIDATORS_ROOT)
.unwrap();
assert!(exported
@@ -150,3 +144,19 @@ fn roundtrip_database(dir: &TempDir, db: &SlashingDatabase, is_empty: bool) {
.equiv(&reexported.minify().unwrap()));
assert_eq!(is_empty, exported.is_empty());
}
fn check_registration_invariants(
slashing_db: &SlashingDatabase,
registered_validators: &[PublicKeyBytes],
) {
slashing_db
.check_validator_registrations(registered_validators.iter())
.unwrap();
let registered_list = slashing_db
.with_transaction(|txn| slashing_db.list_all_registered_validators(txn))
.unwrap()
.into_iter()
.map(|(_, pubkey)| pubkey)
.collect::<Vec<_>>();
assert_eq!(registered_validators, registered_list);
}