mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-20 21:34:46 +00:00
Optimize attester slashing (#1745)
## Issue Addressed Closes #1548 ## Proposed Changes Optimizes attester slashing choice by choosing the ones that cover the most amount of validators slashed, with the highest effective balances ## Additional Info Initial pass, need to write a test for it
This commit is contained in:
71
beacon_node/operation_pool/src/attester_slashing.rs
Normal file
71
beacon_node/operation_pool/src/attester_slashing.rs
Normal file
@@ -0,0 +1,71 @@
|
||||
use crate::max_cover::MaxCover;
|
||||
use state_processing::per_block_processing::get_slashable_indices_modular;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use types::{AttesterSlashing, BeaconState, ChainSpec, EthSpec};
|
||||
|
||||
pub struct AttesterSlashingMaxCover<'a, T: EthSpec> {
|
||||
slashing: &'a AttesterSlashing<T>,
|
||||
effective_balances: HashMap<u64, u64>,
|
||||
}
|
||||
|
||||
impl<'a, T: EthSpec> AttesterSlashingMaxCover<'a, T> {
|
||||
pub fn new(
|
||||
slashing: &'a AttesterSlashing<T>,
|
||||
proposer_slashing_indices: &HashSet<u64>,
|
||||
state: &BeaconState<T>,
|
||||
spec: &ChainSpec,
|
||||
) -> Option<Self> {
|
||||
let mut effective_balances: HashMap<u64, u64> = HashMap::new();
|
||||
let epoch = state.current_epoch();
|
||||
|
||||
let slashable_validators =
|
||||
get_slashable_indices_modular(state, slashing, |index, validator| {
|
||||
validator.is_slashable_at(epoch) && !proposer_slashing_indices.contains(&index)
|
||||
});
|
||||
|
||||
if let Ok(validators) = slashable_validators {
|
||||
for vd in &validators {
|
||||
let eff_balance = state.get_effective_balance(*vd as usize, spec).ok()?;
|
||||
effective_balances.insert(*vd, eff_balance);
|
||||
}
|
||||
|
||||
Some(Self {
|
||||
slashing,
|
||||
effective_balances,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: EthSpec> MaxCover for AttesterSlashingMaxCover<'a, T> {
|
||||
/// The result type, of which we would eventually like a collection of maximal quality.
|
||||
type Object = AttesterSlashing<T>;
|
||||
/// The type used to represent sets.
|
||||
type Set = HashMap<u64, u64>;
|
||||
|
||||
/// Extract an object for inclusion in a solution.
|
||||
fn object(&self) -> AttesterSlashing<T> {
|
||||
self.slashing.clone()
|
||||
}
|
||||
|
||||
/// Get the set of elements covered.
|
||||
fn covering_set(&self) -> &HashMap<u64, u64> {
|
||||
&self.effective_balances
|
||||
}
|
||||
/// Update the set of items covered, for the inclusion of some object in the solution.
|
||||
fn update_covering_set(
|
||||
&mut self,
|
||||
_best_slashing: &AttesterSlashing<T>,
|
||||
covered_validator_indices: &HashMap<u64, u64>,
|
||||
) {
|
||||
self.effective_balances
|
||||
.retain(|k, _| !covered_validator_indices.contains_key(k));
|
||||
}
|
||||
|
||||
/// The quality of this item's covering set, usually its cardinality.
|
||||
fn score(&self) -> usize {
|
||||
self.effective_balances.values().sum::<u64>() as usize
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user