Implement slasher (#1567)

This is an implementation of a slasher that lives inside the BN and can be enabled via `lighthouse bn --slasher`.

Features included in this PR:

- [x] Detection of attester slashing conditions (double votes, surrounds existing, surrounded by existing)
- [x] Integration into Lighthouse's attestation verification flow
- [x] Detection of proposer slashing conditions
- [x] Extraction of attestations from blocks as they are verified
- [x] Compression of chunks
- [x] Configurable history length
- [x] Pruning of old attestations and blocks
- [x] More tests

Future work:

* Focus on a slice of history separate from the most recent N epochs (e.g. epochs `current - K` to `current - M`)
* Run out-of-process
* Ingest attestations from the chain without a resync

Design notes are here https://hackmd.io/@sproul/HJSEklmPL
This commit is contained in:
Michael Sproul
2020-11-23 03:43:22 +00:00
parent 59b2247ab8
commit 5828ff1204
44 changed files with 3662 additions and 87 deletions

View File

@@ -359,6 +359,80 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
.value_name("NUM_SLOTS")
.takes_value(true)
)
/*
* Slasher.
*/
.arg(
Arg::with_name("slasher")
.long("slasher")
.help(
"Run a slasher alongside the beacon node. It is currently only recommended for \
expert users because of the immaturity of the slasher UX and the extra \
resources required."
)
.takes_value(false)
)
.arg(
Arg::with_name("slasher-dir")
.long("slasher-dir")
.help(
"Set the slasher's database directory."
)
.value_name("PATH")
.takes_value(true)
.requires("slasher")
)
.arg(
Arg::with_name("slasher-update-period")
.long("slasher-update-period")
.help(
"Configure how often the slasher runs batch processing."
)
.value_name("SECONDS")
.requires("slasher")
.takes_value(true)
)
.arg(
Arg::with_name("slasher-history-length")
.long("slasher-history-length")
.help(
"Configure how many epochs of history the slasher keeps. Immutable after \
initialization."
)
.value_name("EPOCHS")
.requires("slasher")
.takes_value(true)
)
.arg(
Arg::with_name("slasher-max-db-size")
.long("slasher-max-db-size")
.help(
"Maximum size of the LMDB database used by the slasher."
)
.value_name("GIGABYTES")
.requires("slasher")
.takes_value(true)
)
.arg(
Arg::with_name("slasher-chunk-size")
.long("slasher-chunk-size")
.help(
"Number of epochs per validator per chunk stored on disk."
)
.value_name("EPOCHS")
.requires("slasher")
.takes_value(true)
)
.arg(
Arg::with_name("slasher-validator-chunk-size")
.long("slasher-validator-chunk-size")
.help(
"Number of validators per chunk stored on disk."
)
.value_name("NUM_VALIDATORS")
.requires("slasher")
.takes_value(true)
)
.arg(
Arg::with_name("wss-checkpoint")
.long("wss-checkpoint")