Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Refine and test slashing protection semantics #1885

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 54 additions & 6 deletions account_manager/src/validator/slashing_protection.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use clap::{App, Arg, ArgMatches};
use environment::Environment;
use slashing_protection::{
interchange::Interchange, SlashingDatabase, SLASHING_PROTECTION_FILENAME,
interchange::Interchange, InterchangeImportOutcome, SlashingDatabase,
SLASHING_PROTECTION_FILENAME,
};
use std::fs::File;
use std::path::PathBuf;
use types::{BeaconState, EthSpec};
use types::{BeaconState, Epoch, EthSpec, Slot};

pub const CMD: &str = "slashing-protection";
pub const IMPORT_CMD: &str = "import";
Expand Down Expand Up @@ -84,17 +85,64 @@ pub fn cli_run<T: EthSpec>(
)
})?;

slashing_protection_database
.import_interchange_info(&interchange, genesis_validators_root)
let outcomes = slashing_protection_database
.import_interchange_info(interchange, genesis_validators_root)
.map_err(|e| {
format!(
"Error during import, no data imported: {:?}\n\
"Error during import: {:?}\n\
IT IS NOT SAFE TO START VALIDATING",
e
)
})?;

eprintln!("Import completed successfully");
let display_slot = |slot: Option<Slot>| {
slot.map_or("none".to_string(), |slot| format!("{}", slot.as_u64()))
};
let display_epoch = |epoch: Option<Epoch>| {
epoch.map_or("?".to_string(), |epoch| format!("{}", epoch.as_u64()))
};
let display_attestation = |source, target| match (source, target) {
(None, None) => "none".to_string(),
(source, target) => format!("{}=>{}", display_epoch(source), display_epoch(target)),
};

let mut num_failed = 0;

for outcome in &outcomes {
match outcome {
InterchangeImportOutcome::Success { pubkey, summary } => {
eprintln!("- {:?} SUCCESS min block: {}, max block: {}, min attestation: {}, max attestation: {}",
pubkey,
display_slot(summary.min_block_slot),
display_slot(summary.max_block_slot),
display_attestation(summary.min_attestation_source, summary.min_attestation_target),
display_attestation(summary.max_attestation_source,
summary.max_attestation_target),
);
}
InterchangeImportOutcome::Failure { pubkey, error } => {
eprintln!("- {:?} ERROR: {:?}", pubkey, error);
num_failed += 1;
}
}
}

if num_failed == 0 {
eprintln!("Import completed successfully.");
eprintln!(
"Please double-check that the minimum and maximum blocks and slots above \
match your expectations."
);
} else {
eprintln!(
"WARNING: history was NOT imported for {} of {} records",
num_failed,
outcomes.len()
);
eprintln!("IT IS NOT SAFE TO START VALIDATING");
eprintln!("Please see https://lighthouse-book.sigmaprime.io/slashing-protection.html#slashable-data-in-import");
return Err("Partial import".to_string());
}

Ok(())
}
Expand Down
48 changes: 43 additions & 5 deletions book/src/slashing-protection.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ Examples where it is **ineffective** are:

## Import and Export

Lighthouse supports v5 of the slashing protection interchange format described
[here][interchange-spec]. An interchange file is a record of all blocks and attestations
signing by a set of validator keys – basically a portable slashing protection database!
Lighthouse supports the slashing protection interchange format described in [EIP-3076][]. An
interchange file is a record of blocks and attestations signed by a set of validator keys –
basically a portable slashing protection database!

With your validator client stopped, you can import a `.json` interchange file from another client
using this command:
Expand All @@ -86,9 +86,10 @@ You can export Lighthouse's database for use with another client with this comma
lighthouse account validator slashing-protection export <lighthouse_interchange.json>
```

The validator client needs to be stopped in order to export.
The validator client needs to be stopped in order to export, to guarantee that the data exported is
up to date.

[interchange-spec]: https://hackmd.io/@sproul/Bk0Y0qdGD
[EIP-3076]: https://eips.ethereum.org/EIPS/eip-3076

## Troubleshooting

Expand Down Expand Up @@ -134,6 +135,43 @@ Sep 29 15:15:05.303 CRIT Not signing slashable attestation error: InvalidA
This log is still marked as `CRIT` because in general it should occur only very rarely,
and _could_ indicate a serious error or misconfiguration (see [Avoiding Slashing](#avoiding-slashing)).

### Slashable Data in Import

If you receive a warning when trying to import an [interchange file](#import-and-export) about
the file containing slashable data, then you must carefully consider whether you want to continue.

There are several potential causes for this warning, each of which require a different reaction. If
you have seen the warning for multiple validator keys, the cause could be different for each of them.

1. Your validator has actually signed slashable data. If this is the case, you should assess
whether your validator has been slashed (or is likely to be slashed). It's up to you
whether you'd like to continue.
2. You have exported data from Lighthouse to another client, and then back to Lighthouse,
_in a way that didn't preserve the signing roots_. A message with no signing roots
is considered slashable with respect to _any_ other message at the same slot/epoch,
so even if it was signed by Lighthouse originally, Lighthouse has no way of knowing this.
If you're sure you haven't run Lighthouse and the other client simultaneously, you
can [drop Lighthouse's DB in favour of the interchange file](#drop-and-re-import).
3. You have imported the same interchange file (which lacks signing roots) twice, e.g. from Teku.
It might be safe to continue as-is, or you could consider a [Drop and
Re-import](#drop-and-re-import).

#### Drop and Re-import

If you'd like to prioritize an interchange file over any existing database stored by Lighthouse
then you can _move_ (not delete) Lighthouse's database and replace it like so:

```bash
mv $datadir/validators/slashing_protection.sqlite ~/slashing_protection_backup.sqlite
```

```
lighthouse account validator slashing-protection import <my_interchange.json>
```

If your interchange file doesn't cover all of your validators, you shouldn't do this. Please reach
out on Discord if you need help.

## Limitation of Liability

The Lighthouse developers do not guarantee the perfect functioning of this software, or accept
Expand Down
2 changes: 1 addition & 1 deletion validator_client/slashing_protection/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
TESTS_TAG := 359085be9da6e5e19644977aa45947bcec5d99de
TESTS_TAG := b8413ca42dc92308019d0d4db52c87e9e125c4e9
GENERATE_DIR := generated-tests
OUTPUT_DIR := interchange-tests
TARBALL := $(OUTPUT_DIR)-$(TESTS_TAG).tar.gz
Expand Down
Loading