mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-09 03:31:45 +00:00
De-duplicate attestations in the slasher (#2767)
## Issue Addressed
Closes https://github.com/sigp/lighthouse/issues/2112
Closes https://github.com/sigp/lighthouse/issues/1861
## Proposed Changes
Collect attestations by validator index in the slasher, and use the magic of reference counting to automatically discard redundant attestations. This results in us storing only 1-2% of the attestations observed when subscribed to all subnets, which carries over to a 50-100x reduction in data stored 🎉
## Additional Info
There's some nuance to the configuration of the `slot-offset`. It has a profound effect on the effictiveness of de-duplication, see the docs added to the book for an explanation: 5442e695e5/book/src/slasher.md (slot-offset)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use crate::metrics::{self, SLASHER_COMPRESSION_RATIO, SLASHER_NUM_CHUNKS_UPDATED};
|
||||
use crate::{AttesterRecord, AttesterSlashingStatus, Config, Error, SlasherDB};
|
||||
use crate::{AttesterSlashingStatus, Config, Error, IndexedAttesterRecord, SlasherDB};
|
||||
use flate2::bufread::{ZlibDecoder, ZlibEncoder};
|
||||
use lmdb::{RwTransaction, Transaction};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
@@ -486,7 +486,7 @@ pub fn update<E: EthSpec>(
|
||||
db: &SlasherDB<E>,
|
||||
txn: &mut RwTransaction<'_>,
|
||||
validator_chunk_index: usize,
|
||||
batch: Vec<Arc<(IndexedAttestation<E>, AttesterRecord)>>,
|
||||
batch: Vec<Arc<IndexedAttesterRecord<E>>>,
|
||||
current_epoch: Epoch,
|
||||
config: &Config,
|
||||
) -> Result<HashSet<AttesterSlashing<E>>, Error> {
|
||||
@@ -496,7 +496,7 @@ pub fn update<E: EthSpec>(
|
||||
let mut chunk_attestations = BTreeMap::new();
|
||||
for attestation in batch {
|
||||
chunk_attestations
|
||||
.entry(config.chunk_index(attestation.0.data.source.epoch))
|
||||
.entry(config.chunk_index(attestation.indexed.data.source.epoch))
|
||||
.or_insert_with(Vec::new)
|
||||
.push(attestation);
|
||||
}
|
||||
@@ -573,7 +573,7 @@ pub fn update_array<E: EthSpec, T: TargetArrayChunk>(
|
||||
db: &SlasherDB<E>,
|
||||
txn: &mut RwTransaction<'_>,
|
||||
validator_chunk_index: usize,
|
||||
chunk_attestations: &BTreeMap<usize, Vec<Arc<(IndexedAttestation<E>, AttesterRecord)>>>,
|
||||
chunk_attestations: &BTreeMap<usize, Vec<Arc<IndexedAttesterRecord<E>>>>,
|
||||
current_epoch: Epoch,
|
||||
config: &Config,
|
||||
) -> Result<HashSet<AttesterSlashing<E>>, Error> {
|
||||
@@ -597,7 +597,7 @@ pub fn update_array<E: EthSpec, T: TargetArrayChunk>(
|
||||
for attestations in chunk_attestations.values() {
|
||||
for attestation in attestations {
|
||||
for validator_index in
|
||||
config.attesting_validators_in_chunk(&attestation.0, validator_chunk_index)
|
||||
config.attesting_validators_in_chunk(&attestation.indexed, validator_chunk_index)
|
||||
{
|
||||
let slashing_status = apply_attestation_for_validator::<E, T>(
|
||||
db,
|
||||
@@ -605,11 +605,11 @@ pub fn update_array<E: EthSpec, T: TargetArrayChunk>(
|
||||
&mut updated_chunks,
|
||||
validator_chunk_index,
|
||||
validator_index,
|
||||
&attestation.0,
|
||||
&attestation.indexed,
|
||||
current_epoch,
|
||||
config,
|
||||
)?;
|
||||
if let Some(slashing) = slashing_status.into_slashing(&attestation.0) {
|
||||
if let Some(slashing) = slashing_status.into_slashing(&attestation.indexed) {
|
||||
slashings.insert(slashing);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user