mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-22 14:24:44 +00:00
Anchor pre-PR: Modularize validator store (#6771)
* pass slots_per_epoch at runtime * remove generic E from unrequired types * move `validator_store` to `lighthouse_validator_store` * make validator_store into a trait * further reduce dependencies * remove `environment` dependency on `beacon_node_fallback` * Manually pull in some changes from tracing-integration (thanks sayan!) Co-authored-by: ThreeHrSleep <threehrsleep@gmail.com> * remove `environment` from `validator_services` * unify boost factor accessors * add builder for DutiesService * Manually merge tracing PR for beacon_node_fallback Co-authored-by: ThreeHrSleep <threehrsleep@gmail.com> * Fix chain_spec for BlockService * address review * remove PhantomData from SyncDutiesMap * fix tests * correct test * Add `E` to `ValidatorStore` as associated type * fix tests * derive Clone for ValidatorStore's Error and required sub-errors * switch to enum for block signing to allow differing types --------- Co-authored-by: João Oliveira <hello@jxs.pt> Co-authored-by: ThreeHrSleep <threehrsleep@gmail.com> Co-authored-by: Jimmy Chen <jimmy@sigmaprime.io>
This commit is contained in:
@@ -41,68 +41,7 @@ use std::sync::Arc;
|
||||
use task_executor::ShutdownReason;
|
||||
use tokio::time::sleep;
|
||||
use types::{Epoch, EthSpec, PublicKeyBytes, Slot};
|
||||
|
||||
/// A wrapper around `PublicKeyBytes` which encodes information about the status of a validator
|
||||
/// pubkey with regards to doppelganger protection.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum DoppelgangerStatus {
|
||||
/// Doppelganger protection has approved this for signing.
|
||||
///
|
||||
/// This is because the service has waited some period of time to
|
||||
/// detect other instances of this key on the network.
|
||||
SigningEnabled(PublicKeyBytes),
|
||||
/// Doppelganger protection is still waiting to detect other instances.
|
||||
///
|
||||
/// Do not use this pubkey for signing slashable messages!!
|
||||
///
|
||||
/// However, it can safely be used for other non-slashable operations (e.g., collecting duties
|
||||
/// or subscribing to subnets).
|
||||
SigningDisabled(PublicKeyBytes),
|
||||
/// This pubkey is unknown to the doppelganger service.
|
||||
///
|
||||
/// This represents a serious internal error in the program. This validator will be permanently
|
||||
/// disabled!
|
||||
UnknownToDoppelganger(PublicKeyBytes),
|
||||
}
|
||||
|
||||
impl DoppelgangerStatus {
|
||||
/// Only return a pubkey if it is explicitly safe for doppelganger protection.
|
||||
///
|
||||
/// If `Some(pubkey)` is returned, doppelganger has declared it safe for signing.
|
||||
///
|
||||
/// ## Note
|
||||
///
|
||||
/// "Safe" is only best-effort by doppelganger. There is no guarantee that a doppelganger
|
||||
/// doesn't exist.
|
||||
pub fn only_safe(self) -> Option<PublicKeyBytes> {
|
||||
match self {
|
||||
DoppelgangerStatus::SigningEnabled(pubkey) => Some(pubkey),
|
||||
DoppelgangerStatus::SigningDisabled(_) => None,
|
||||
DoppelgangerStatus::UnknownToDoppelganger(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a key regardless of whether or not doppelganger has approved it. Such a key might be
|
||||
/// used for signing non-slashable messages, duties collection or other activities.
|
||||
///
|
||||
/// If the validator is unknown to doppelganger then `None` will be returned.
|
||||
pub fn ignored(self) -> Option<PublicKeyBytes> {
|
||||
match self {
|
||||
DoppelgangerStatus::SigningEnabled(pubkey) => Some(pubkey),
|
||||
DoppelgangerStatus::SigningDisabled(pubkey) => Some(pubkey),
|
||||
DoppelgangerStatus::UnknownToDoppelganger(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Only return a pubkey if it will not be used for signing due to doppelganger detection.
|
||||
pub fn only_unsafe(self) -> Option<PublicKeyBytes> {
|
||||
match self {
|
||||
DoppelgangerStatus::SigningEnabled(_) => None,
|
||||
DoppelgangerStatus::SigningDisabled(pubkey) => Some(pubkey),
|
||||
DoppelgangerStatus::UnknownToDoppelganger(pubkey) => Some(pubkey),
|
||||
}
|
||||
}
|
||||
}
|
||||
use validator_store::{DoppelgangerStatus, ValidatorStore};
|
||||
|
||||
struct LivenessResponses {
|
||||
current_epoch_responses: Vec<LivenessResponseData>,
|
||||
@@ -113,13 +52,6 @@ struct LivenessResponses {
|
||||
/// validators on the network.
|
||||
pub const DEFAULT_REMAINING_DETECTION_EPOCHS: u64 = 1;
|
||||
|
||||
/// This crate cannot depend on ValidatorStore as validator_store depends on this crate and
|
||||
/// initialises the doppelganger protection. For this reason, we abstract the validator store
|
||||
/// functions this service needs through the following trait
|
||||
pub trait DoppelgangerValidatorStore {
|
||||
fn get_validator_index(&self, pubkey: &PublicKeyBytes) -> Option<u64>;
|
||||
}
|
||||
|
||||
/// Store the per-validator status of doppelganger checking.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct DoppelgangerState {
|
||||
@@ -162,8 +94,8 @@ impl DoppelgangerState {
|
||||
/// If the BN fails to respond to either of these requests, simply return an empty response.
|
||||
/// This behaviour is to help prevent spurious failures on the BN from needlessly preventing
|
||||
/// doppelganger progression.
|
||||
async fn beacon_node_liveness<'a, T: 'static + SlotClock, E: EthSpec>(
|
||||
beacon_nodes: Arc<BeaconNodeFallback<T, E>>,
|
||||
async fn beacon_node_liveness<'a, T: 'static + SlotClock>(
|
||||
beacon_nodes: Arc<BeaconNodeFallback<T>>,
|
||||
log: Logger,
|
||||
current_epoch: Epoch,
|
||||
validator_indices: Vec<u64>,
|
||||
@@ -290,16 +222,16 @@ impl DoppelgangerService {
|
||||
service: Arc<Self>,
|
||||
context: RuntimeContext<E>,
|
||||
validator_store: Arc<V>,
|
||||
beacon_nodes: Arc<BeaconNodeFallback<T, E>>,
|
||||
beacon_nodes: Arc<BeaconNodeFallback<T>>,
|
||||
slot_clock: T,
|
||||
) -> Result<(), String>
|
||||
where
|
||||
E: EthSpec,
|
||||
T: 'static + SlotClock,
|
||||
V: DoppelgangerValidatorStore + Send + Sync + 'static,
|
||||
V: ValidatorStore<E = E> + Send + Sync + 'static,
|
||||
{
|
||||
// Define the `get_index` function as one that uses the validator store.
|
||||
let get_index = move |pubkey| validator_store.get_validator_index(&pubkey);
|
||||
let get_index = move |pubkey| validator_store.validator_index(&pubkey);
|
||||
|
||||
// Define the `get_liveness` function as one that queries the beacon node API.
|
||||
let log = service.log.clone();
|
||||
@@ -704,6 +636,7 @@ mod test {
|
||||
test_utils::{SeedableRng, TestRandom, XorShiftRng},
|
||||
MainnetEthSpec,
|
||||
};
|
||||
use validator_store::DoppelgangerStatus;
|
||||
|
||||
const DEFAULT_VALIDATORS: usize = 8;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user