mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-15 02:42:38 +00:00
Merges in validator client branch
This commit is contained in:
@@ -2,8 +2,8 @@ use protos::services_grpc::AttestationServiceClient;
|
||||
use std::sync::Arc;
|
||||
|
||||
use attester::{BeaconNode, BeaconNodeError, PublishOutcome};
|
||||
use protos::services::ProduceAttestationRequest;
|
||||
use types::{AttestationData, FreeAttestation, Slot};
|
||||
use protos::services::ProduceAttestationDataRequest;
|
||||
use types::{Attestation, AttestationData, Slot};
|
||||
|
||||
pub struct AttestationGrpcClient {
|
||||
client: Arc<AttestationServiceClient>,
|
||||
@@ -14,20 +14,20 @@ impl AttestationGrpcClient {
|
||||
Self { client }
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl BeaconNode for AttestationGrpcClient {
|
||||
fn produce_attestation(
|
||||
fn produce_attestation_data(
|
||||
&self,
|
||||
slot: Slot,
|
||||
shard: u64,
|
||||
) -> Result<Option<AttestationData>, BeaconNodeError> {
|
||||
let mut req = ProduceAttestationRequest::new();
|
||||
let mut req = ProduceAttestationDataRequest::new();
|
||||
req.set_slot(slot.as_u64());
|
||||
req.set_shard(shard);
|
||||
|
||||
let reply = self
|
||||
.client
|
||||
.produce_attestation(&req)
|
||||
.produce_attestation_data(&req)
|
||||
.map_err(|err| BeaconNodeError::RemoteFailure(format!("{:?}", err)))?;
|
||||
|
||||
// TODO: return correct Attestation
|
||||
@@ -36,9 +36,10 @@ impl BeaconNode for AttestationGrpcClient {
|
||||
|
||||
fn publish_attestation(
|
||||
&self,
|
||||
free_attestation: FreeAttestation,
|
||||
attestation: Attestation,
|
||||
) -> Result<PublishOutcome, BeaconNodeError> {
|
||||
// TODO: return correct PublishOutcome
|
||||
Err(BeaconNodeError::DecodeFailure)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -6,18 +6,22 @@ use std::time::Duration;
|
||||
|
||||
pub use self::attestation_grpc_client::AttestationGrpcClient;
|
||||
|
||||
pub struct AttesterService<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> {
|
||||
pub attester: Attester<T, U, V, W>,
|
||||
pub struct AttesterService {}
|
||||
/*
|
||||
pub struct AttesterService<U: BeaconNode, W: Signer> {
|
||||
// pub attester: Attester<U, W>,
|
||||
pub poll_interval_millis: u64,
|
||||
pub log: Logger,
|
||||
}
|
||||
|
||||
impl<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> AttesterService<T, U, V, W> {
|
||||
|
||||
impl<U: BeaconNode, W: Signer> AttesterService<U, W> {
|
||||
/// Run a loop which polls the Attester each `poll_interval_millis` millseconds.
|
||||
///
|
||||
/// Logs the results of the polls.
|
||||
pub fn run(&mut self) {
|
||||
loop {
|
||||
/* We don't do the polling any more...
|
||||
match self.attester.poll() {
|
||||
Err(error) => {
|
||||
error!(self.log, "Attester poll error"; "error" => format!("{:?}", error))
|
||||
@@ -47,8 +51,10 @@ impl<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> AttesterService<T,
|
||||
error!(self.log, "The Beacon Node does not recognise the validator"; "slot" => slot)
|
||||
}
|
||||
};
|
||||
|
||||
std::thread::sleep(Duration::from_millis(self.poll_interval_millis));
|
||||
}
|
||||
}
|
||||
*/
|
||||
println!("Legacy polling still happening...");
|
||||
std::thread::sleep(Duration::from_millis(self.poll_interval_millis));
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::EpochDuties;
|
||||
use types::{Epoch, PublicKey};
|
||||
use types::{Epoch, Keypair};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum BeaconNodeDutiesError {
|
||||
@@ -15,6 +15,6 @@ pub trait BeaconNodeDuties: Send + Sync {
|
||||
fn request_duties(
|
||||
&self,
|
||||
epoch: Epoch,
|
||||
pubkeys: &[PublicKey],
|
||||
signers: &[Keypair],
|
||||
) -> Result<EpochDuties, BeaconNodeDutiesError>;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use types::{AttestationDuty, Epoch, PublicKey, Slot};
|
||||
use types::{AttestationDuty, Epoch, Keypair, Slot};
|
||||
|
||||
/// When work needs to be performed by a validator, this type is given back to the main service
|
||||
/// which indicates all the information that required to process the work.
|
||||
@@ -71,8 +71,8 @@ impl fmt::Display for EpochDuty {
|
||||
}
|
||||
}
|
||||
|
||||
/// Maps a list of public keys (many validators) to an EpochDuty.
|
||||
pub type EpochDuties = HashMap<PublicKey, Option<EpochDuty>>;
|
||||
/// Maps a list of keypairs (many validators) to an EpochDuty.
|
||||
pub type EpochDuties = HashMap<Keypair, Option<EpochDuty>>;
|
||||
|
||||
pub enum EpochDutiesMapError {
|
||||
UnknownEpoch,
|
||||
@@ -113,7 +113,7 @@ impl EpochDutiesMap {
|
||||
pub fn is_work_slot(
|
||||
&self,
|
||||
slot: Slot,
|
||||
pubkey: &PublicKey,
|
||||
signer: &Keypair,
|
||||
) -> Result<Option<WorkInfo>, EpochDutiesMapError> {
|
||||
let epoch = slot.epoch(self.slots_per_epoch);
|
||||
|
||||
@@ -121,7 +121,7 @@ impl EpochDutiesMap {
|
||||
.map
|
||||
.get(&epoch)
|
||||
.ok_or_else(|| EpochDutiesMapError::UnknownEpoch)?;
|
||||
if let Some(epoch_duty) = epoch_duties.get(pubkey) {
|
||||
if let Some(epoch_duty) = epoch_duties.get(signer) {
|
||||
if let Some(duty) = epoch_duty {
|
||||
// Retrieves the duty for a validator at a given slot
|
||||
return Ok(duty.is_work_slot(slot));
|
||||
|
||||
@@ -6,21 +6,21 @@ use protos::services_grpc::ValidatorServiceClient;
|
||||
use ssz::ssz_encode;
|
||||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
use types::{Epoch, PublicKey, Slot};
|
||||
use types::{Epoch, Keypair, Slot};
|
||||
|
||||
impl BeaconNodeDuties for ValidatorServiceClient {
|
||||
/// Requests all duties (block signing and committee attesting) from the Beacon Node (BN).
|
||||
fn request_duties(
|
||||
&self,
|
||||
epoch: Epoch,
|
||||
pubkeys: &[PublicKey],
|
||||
signers: &[Keypair],
|
||||
) -> Result<EpochDuties, BeaconNodeDutiesError> {
|
||||
// Get the required duties from all validators
|
||||
// build the request
|
||||
let mut req = GetDutiesRequest::new();
|
||||
req.set_epoch(epoch.as_u64());
|
||||
let mut validators = Validators::new();
|
||||
validators.set_public_keys(pubkeys.iter().map(|v| ssz_encode(v)).collect());
|
||||
validators.set_public_keys(signers.iter().map(|v| ssz_encode(&v.pk)).collect());
|
||||
req.set_validators(validators);
|
||||
|
||||
// set a timeout for requests
|
||||
@@ -31,11 +31,11 @@ impl BeaconNodeDuties for ValidatorServiceClient {
|
||||
.get_validator_duties(&req)
|
||||
.map_err(|err| BeaconNodeDutiesError::RemoteFailure(format!("{:?}", err)))?;
|
||||
|
||||
let mut epoch_duties: HashMap<PublicKey, Option<EpochDuty>> = HashMap::new();
|
||||
let mut epoch_duties: HashMap<Keypair, Option<EpochDuty>> = HashMap::new();
|
||||
for (index, validator_duty) in reply.get_active_validators().iter().enumerate() {
|
||||
if !validator_duty.has_duty() {
|
||||
// validator is inactive
|
||||
epoch_duties.insert(pubkeys[index].clone(), None);
|
||||
epoch_duties.insert(signers[index].clone(), None);
|
||||
continue;
|
||||
}
|
||||
// active validator
|
||||
@@ -53,7 +53,7 @@ impl BeaconNodeDuties for ValidatorServiceClient {
|
||||
attestation_shard: active_duty.get_attestation_shard(),
|
||||
committee_index: active_duty.get_committee_index(),
|
||||
};
|
||||
epoch_duties.insert(pubkeys[index].clone(), Some(epoch_duty));
|
||||
epoch_duties.insert(signers[index].clone(), Some(epoch_duty));
|
||||
}
|
||||
Ok(epoch_duties)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use futures::Async;
|
||||
use slog::{debug, error, info};
|
||||
use std::sync::Arc;
|
||||
use std::sync::RwLock;
|
||||
use types::{Epoch, PublicKey, Slot};
|
||||
use types::{Epoch, Keypair, Slot};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum UpdateOutcome {
|
||||
@@ -40,8 +40,9 @@ pub enum Error {
|
||||
/// This keeps track of all validator keys and required voting slots.
|
||||
pub struct DutiesManager<U: BeaconNodeDuties> {
|
||||
pub duties_map: RwLock<EpochDutiesMap>,
|
||||
/// A list of all public keys known to the validator service.
|
||||
pub pubkeys: Vec<PublicKey>,
|
||||
/// A list of all signer objects known to the validator service.
|
||||
// TODO: Generalise the signers, so that they're not just keypairs
|
||||
pub signers: Arc<Vec<Keypair>>,
|
||||
pub beacon_node: Arc<U>,
|
||||
}
|
||||
|
||||
@@ -50,7 +51,7 @@ impl<U: BeaconNodeDuties> DutiesManager<U> {
|
||||
///
|
||||
/// be a wall-clock (e.g., system time, remote server time, etc.).
|
||||
fn update(&self, epoch: Epoch) -> Result<UpdateOutcome, Error> {
|
||||
let duties = self.beacon_node.request_duties(epoch, &self.pubkeys)?;
|
||||
let duties = self.beacon_node.request_duties(epoch, &self.signers)?;
|
||||
{
|
||||
// If these duties were known, check to see if they're updates or identical.
|
||||
if let Some(known_duties) = self.duties_map.read()?.get(&epoch) {
|
||||
@@ -91,17 +92,18 @@ impl<U: BeaconNodeDuties> DutiesManager<U> {
|
||||
|
||||
/// Returns a list of (Public, WorkInfo) indicating all the validators that have work to perform
|
||||
/// this slot.
|
||||
pub fn get_current_work(&self, slot: Slot) -> Option<Vec<(PublicKey, WorkInfo)>> {
|
||||
let mut current_work: Vec<(PublicKey, WorkInfo)> = Vec::new();
|
||||
pub fn get_current_work(&self, slot: Slot) -> Option<Vec<(Keypair, WorkInfo)>> {
|
||||
let mut current_work: Vec<(Keypair, WorkInfo)> = Vec::new();
|
||||
|
||||
// if the map is poisoned, return None
|
||||
let duties = self.duties_map.read().ok()?;
|
||||
|
||||
for validator_pk in &self.pubkeys {
|
||||
match duties.is_work_slot(slot, &validator_pk) {
|
||||
Ok(Some(work_type)) => current_work.push((validator_pk.clone(), work_type)),
|
||||
for validator_signer in self.signers.iter() {
|
||||
match duties.is_work_slot(slot, &validator_signer) {
|
||||
Ok(Some(work_type)) => current_work.push((validator_signer.clone(), work_type)),
|
||||
Ok(None) => {} // No work for this validator
|
||||
Err(_) => {} // Unknown epoch or validator, no work
|
||||
//TODO: This should really log an error, as we shouldn't end up with an err here.
|
||||
Err(_) => {} // Unknown epoch or validator, no work
|
||||
}
|
||||
}
|
||||
if current_work.is_empty() {
|
||||
@@ -136,9 +138,9 @@ impl From<EpochDutiesMapError> for Error {
|
||||
fn print_duties(log: &slog::Logger, duties: EpochDuties) {
|
||||
for (pk, duty) in duties.iter() {
|
||||
if let Some(display_duty) = duty {
|
||||
info!(log, "Validator: {}",pk; "Duty" => format!("{}",display_duty));
|
||||
info!(log, "Validator: {:?}",pk; "Duty" => format!("{}",display_duty));
|
||||
} else {
|
||||
info!(log, "Validator: {}",pk; "Duty" => "None");
|
||||
info!(log, "Validator: {:?}",pk; "Duty" => "None");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ use slog::{debug, error, info, warn};
|
||||
use slot_clock::{SlotClock, SystemTimeSlotClock};
|
||||
use std::sync::Arc;
|
||||
use std::sync::RwLock;
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant, SystemTime};
|
||||
use tokio::prelude::*;
|
||||
use tokio::runtime::Builder;
|
||||
@@ -37,6 +38,8 @@ use types::{ChainSpec, Epoch, Fork, Slot};
|
||||
|
||||
//TODO: This service should be simplified in the future. Can be made more steamlined.
|
||||
|
||||
const POLL_INTERVAL_MILLIS: u64 = 100;
|
||||
|
||||
/// The validator service. This is the main thread that executes and maintains validator
|
||||
/// duties.
|
||||
//TODO: Generalize the BeaconNode types to use testing
|
||||
@@ -180,7 +183,7 @@ impl<B: BeaconNodeDuties + 'static> Service<B> {
|
||||
// and can check when a validator needs to perform a task.
|
||||
let duties_manager = Arc::new(DutiesManager {
|
||||
duties_map,
|
||||
pubkeys: keypairs.iter().map(|keypair| keypair.pk.clone()).collect(),
|
||||
signers: keypairs,
|
||||
beacon_node: validator_client,
|
||||
});
|
||||
|
||||
@@ -314,8 +317,21 @@ impl<B: BeaconNodeDuties + 'static> Service<B> {
|
||||
}
|
||||
if work_type.attestation_duty.is_some() {
|
||||
// available AttestationDuty info
|
||||
let attestation_duty = work_type.attestation_duty.expect("Cannot be None");
|
||||
//TODO: Produce an attestation in a new thread
|
||||
/*
|
||||
let attestation_duty =
|
||||
work_type.attestation_duty.expect("Cannot be None");
|
||||
let attester_grpc_client = Arc::new(AttestationGrpcClient::new(
|
||||
service.attester_client.clone(),
|
||||
));
|
||||
let signer = Arc::new(AttesterLocalSigner::new(keypair.clone()));
|
||||
let attester = Attester::new(attester_grpc_client, signer);
|
||||
let mut attester_service = AttesterService {
|
||||
attester,
|
||||
poll_interval_millis: POLL_INTERVAL_MILLIS,
|
||||
log: log.clone(),
|
||||
};
|
||||
attester_service.run();
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user