mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-18 05:18:30 +00:00
Add slasher broadcast (#2079)
## Issue Addressed Closes #2048 ## Proposed Changes * Broadcast slashings when the `--slasher-broadcast` flag is provided. * In the process of implementing this I refactored the slasher service into its own crate so that it could access the network code without creating a circular dependency. I moved the responsibility for putting slashings into the op pool into the service as well, as it makes sense for it to handle the whole slashing lifecycle.
This commit is contained in:
@@ -39,7 +39,7 @@ use slot_clock::SlotClock;
|
||||
use state_processing::{
|
||||
common::get_indexed_attestation, per_block_processing,
|
||||
per_block_processing::errors::AttestationValidationError, per_slot_processing,
|
||||
BlockSignatureStrategy, SigVerifiedOp, VerifyOperation,
|
||||
BlockSignatureStrategy, SigVerifiedOp,
|
||||
};
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::Ordering;
|
||||
@@ -1125,63 +1125,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
Ok(signed_aggregate)
|
||||
}
|
||||
|
||||
/// Move slashings collected by the slasher into the op pool for block inclusion.
|
||||
fn ingest_slashings_to_op_pool(&self, state: &BeaconState<T::EthSpec>) {
|
||||
if let Some(slasher) = self.slasher.as_ref() {
|
||||
let attester_slashings = slasher.get_attester_slashings();
|
||||
let proposer_slashings = slasher.get_proposer_slashings();
|
||||
|
||||
if !attester_slashings.is_empty() || !proposer_slashings.is_empty() {
|
||||
debug!(
|
||||
self.log,
|
||||
"Ingesting slashings";
|
||||
"num_attester_slashings" => attester_slashings.len(),
|
||||
"num_proposer_slashings" => proposer_slashings.len(),
|
||||
);
|
||||
}
|
||||
|
||||
for slashing in attester_slashings {
|
||||
let verified_slashing = match slashing.clone().validate(state, &self.spec) {
|
||||
Ok(verified) => verified,
|
||||
Err(e) => {
|
||||
error!(
|
||||
self.log,
|
||||
"Attester slashing from slasher failed verification";
|
||||
"error" => format!("{:?}", e),
|
||||
"slashing" => format!("{:?}", slashing),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(e) = self.import_attester_slashing(verified_slashing) {
|
||||
error!(
|
||||
self.log,
|
||||
"Attester slashing from slasher is invalid";
|
||||
"error" => format!("{:?}", e),
|
||||
"slashing" => format!("{:?}", slashing),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for slashing in proposer_slashings {
|
||||
let verified_slashing = match slashing.clone().validate(state, &self.spec) {
|
||||
Ok(verified) => verified,
|
||||
Err(e) => {
|
||||
error!(
|
||||
self.log,
|
||||
"Proposer slashing from slasher failed verification";
|
||||
"error" => format!("{:?}", e),
|
||||
"slashing" => format!("{:?}", slashing),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
self.import_proposer_slashing(verified_slashing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that the shuffling at `block_root` is equal to one of the shufflings of `state`.
|
||||
///
|
||||
/// The `target_epoch` argument determines which shuffling to check compatibility with, it
|
||||
@@ -1876,7 +1819,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
state.latest_block_header.canonical_root()
|
||||
};
|
||||
|
||||
self.ingest_slashings_to_op_pool(&state);
|
||||
let (proposer_slashings, attester_slashings) =
|
||||
self.op_pool.get_slashings(&state, &self.spec);
|
||||
|
||||
@@ -2093,7 +2035,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
if is_epoch_transition || is_reorg {
|
||||
self.persist_head_and_fork_choice()?;
|
||||
self.op_pool.prune_attestations(self.epoch()?);
|
||||
self.ingest_slashings_to_op_pool(&new_head.beacon_state);
|
||||
self.persist_op_pool()?;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,3 +43,4 @@ directory = {path = "../../common/directory"}
|
||||
http_api = { path = "../http_api" }
|
||||
http_metrics = { path = "../http_metrics" }
|
||||
slasher = { path = "../../slasher" }
|
||||
slasher_service = { path = "../../slasher/service" }
|
||||
|
||||
@@ -13,7 +13,8 @@ use eth1::{Config as Eth1Config, Service as Eth1Service};
|
||||
use eth2_libp2p::NetworkGlobals;
|
||||
use genesis::{interop_genesis_state, Eth1GenesisService};
|
||||
use network::{NetworkConfig, NetworkMessage, NetworkService};
|
||||
use slasher::{Slasher, SlasherServer};
|
||||
use slasher::Slasher;
|
||||
use slasher_service::SlasherService;
|
||||
use slog::{debug, info, warn};
|
||||
use ssz::Decode;
|
||||
use std::net::TcpListener;
|
||||
@@ -348,22 +349,21 @@ where
|
||||
/// Immediately start the slasher service.
|
||||
///
|
||||
/// Error if no slasher is configured.
|
||||
pub fn start_slasher_server(&self) -> Result<(), String> {
|
||||
pub fn start_slasher_service(&self) -> Result<(), String> {
|
||||
let beacon_chain = self
|
||||
.beacon_chain
|
||||
.clone()
|
||||
.ok_or("slasher service requires a beacon chain")?;
|
||||
let network_send = self
|
||||
.network_send
|
||||
.clone()
|
||||
.ok_or("slasher service requires a network sender")?;
|
||||
let context = self
|
||||
.runtime_context
|
||||
.as_ref()
|
||||
.ok_or("slasher requires a runtime_context")?
|
||||
.service_context("slasher_server_ctxt".into());
|
||||
let slasher = self
|
||||
.slasher
|
||||
.clone()
|
||||
.ok_or("slasher server requires a slasher")?;
|
||||
let slot_clock = self
|
||||
.slot_clock
|
||||
.clone()
|
||||
.ok_or("slasher server requires a slot clock")?;
|
||||
SlasherServer::run(slasher, slot_clock, &context.executor);
|
||||
Ok(())
|
||||
.service_context("slasher_service_ctxt".into());
|
||||
SlasherService::new(beacon_chain, network_send).run(&context.executor)
|
||||
}
|
||||
|
||||
/// Immediately starts the service that periodically logs information each slot.
|
||||
@@ -470,7 +470,7 @@ where
|
||||
};
|
||||
|
||||
if self.slasher.is_some() {
|
||||
self.start_slasher_server()?;
|
||||
self.start_slasher_service()?;
|
||||
}
|
||||
|
||||
Ok(Client {
|
||||
|
||||
@@ -434,6 +434,13 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
||||
.requires("slasher")
|
||||
.takes_value(true)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("slasher-broadcast")
|
||||
.long("slasher-broadcast")
|
||||
.help("Broadcast slashings found by the slasher to the rest of the network \
|
||||
[disabled by default].")
|
||||
.requires("slasher")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("wss-checkpoint")
|
||||
.long("wss-checkpoint")
|
||||
|
||||
@@ -375,6 +375,8 @@ pub fn get_config<E: EthSpec>(
|
||||
slasher_config.validator_chunk_size = validator_chunk_size;
|
||||
}
|
||||
|
||||
slasher_config.broadcast = cli_args.is_present("slasher-broadcast");
|
||||
|
||||
client_config.slasher = Some(slasher_config);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user