diff --git a/protos/src/services.proto b/protos/src/services.proto index 80d512c54..bcfd353c7 100644 --- a/protos/src/services.proto +++ b/protos/src/services.proto @@ -27,7 +27,8 @@ service BeaconBlockService { //its public keys service ValidatorService { rpc ProposeBlockSlot(ProposeBlockSlotRequest) returns (ProposeBlockSlotResponse); - rpc ValidatorIndex(PublicKey) returns (IndexResponse); + /// Given a set of public keys, returns their respective indicies + rpc ValidatorIndex(PublicKeys) returns (Indicies); // rpc ValidatorAssignment(ValidatorAssignmentRequest) returns (ValidatorAssignmentResponse); } @@ -110,12 +111,12 @@ message ValidatorAssignment { // Validator Assignment -message PublicKey { - bytes public_key = 1; +message PublicKeys { + repeated bytes public_key = 1; } -message IndexResponse { - uint64 index = 1; +message Indicies { + repeated uint64 index = 1; } @@ -123,16 +124,26 @@ message IndexResponse { message ProposeBlockSlotRequest { uint64 epoch = 1; - uint64 validator_index = 2; + repeated uint64 validator_index = 2; } -message ProposeBlockSlotResponse { - oneof slot_oneof { +message GetDutiesResponse { + repeated oneof slot_oneof { bool none = 1; - uint64 slot = 2; + ValidatorDuty duty = 2; } } +ValidatorDuty { + oneof block_oneof { + bool none = 1; + uint64 block_produce_slot = 2; + } + uint64 committee_slot = 1; + uint64 committee_shard = 2; + uint64 committee_index = 3; +} + /* * Attestation Service Messages diff --git a/validator_client/src/duties/grpc.rs b/validator_client/src/duties/grpc.rs index 94f843b63..1f7297f0e 100644 --- a/validator_client/src/duties/grpc.rs +++ b/validator_client/src/duties/grpc.rs @@ -1,6 +1,6 @@ use super::traits::{BeaconNode, BeaconNodeError}; use super::EpochDuties; -use protos::services::{ProposeBlockSlotRequest, PublicKey as IndexRequest}; +use protos::services::{ProposeBlockSlotRequest, PublicKeys as IndexRequest}; use protos::services_grpc::ValidatorServiceClient; use ssz::ssz_encode; use types::{Epoch, PublicKey, Slot}; @@ -15,12 +15,14 @@ impl BeaconNode for ValidatorServiceClient { fn request_shuffling( &self, epoch: Epoch, - public_key: &PublicKey, + pubkeys: &[PublicKey], ) -> Result, BeaconNodeError> { - // Lookup the validator index for the supplied public key. - let validator_index = { + // Lookup the validator indexes for all the supplied public keys. + let validator_indices = { let mut req = IndexRequest::new(); - req.set_public_key(ssz_encode(public_key).to_vec()); + for public_key in pubkeys { + req.mut_public_key().push(ssz_encode(public_key)); + } let resp = self .validator_index(&req) .map_err(|err| BeaconNodeError::RemoteFailure(format!("{:?}", err)))?; diff --git a/validator_client/src/duties/mod.rs b/validator_client/src/duties/mod.rs index 185f80d6d..77d6d43b6 100644 --- a/validator_client/src/duties/mod.rs +++ b/validator_client/src/duties/mod.rs @@ -10,9 +10,8 @@ use self::traits::{BeaconNode, BeaconNodeError}; use bls::PublicKey; use futures::Async; use slog::{debug, error, info}; -use slot_clock::SlotClock; use std::sync::Arc; -use types::{ChainSpec, Epoch, Slot}; +use types::{Epoch, Slot}; #[derive(Debug, PartialEq, Clone, Copy)] pub enum UpdateOutcome { @@ -30,8 +29,6 @@ pub enum UpdateOutcome { #[derive(Debug, PartialEq)] pub enum Error { - SlotClockError, - SlotUnknowable, EpochMapPoisoned, BeaconNodeError(BeaconNodeError), } @@ -40,27 +37,23 @@ pub enum Error { /// Node. /// /// This keeps track of all validator keys and required voting slots. -pub struct DutiesManager { +pub struct DutiesManager { pub duties_map: Arc, /// A list of all public keys known to the validator service. pub pubkeys: Vec, - pub spec: Arc, - pub slot_clock: Arc, + pub slots_per_epoch: u64, pub beacon_node: Arc, } -impl DutiesManager { +impl DutiesManager { /// Check the Beacon Node for `EpochDuties`. /// /// The present `epoch` will be learned from the supplied `SlotClock`. In production this will /// be a wall-clock (e.g., system time, remote server time, etc.). fn update(&self, slot: Slot) -> Result { - let epoch = slot.epoch(self.spec.slots_per_epoch); + let epoch = slot.epoch(self.slots_per_epoch); - if let Some(duties) = self - .beacon_node - .request_shuffling(epoch, &self.pubkeys[0])? - { + if let Some(duties) = self.beacon_node.request_shuffling(epoch, &self.pubkeys)? { // If these duties were known, check to see if they're updates or identical. let result = if let Some(known_duties) = self.duties_map.get(epoch)? { if known_duties == duties { diff --git a/validator_client/src/duties/traits.rs b/validator_client/src/duties/traits.rs index 5bf7da1fd..a3dcade4b 100644 --- a/validator_client/src/duties/traits.rs +++ b/validator_client/src/duties/traits.rs @@ -1,6 +1,5 @@ use super::EpochDuties; -use bls::PublicKey; -use types::Epoch; +use types::{Epoch, PublicKey}; #[derive(Debug, PartialEq, Clone)] pub enum BeaconNodeError { @@ -15,6 +14,6 @@ pub trait BeaconNode: Send + Sync { fn request_shuffling( &self, epoch: Epoch, - public_key: &PublicKey, + pubkeys: &[PublicKey], ) -> Result, BeaconNodeError>; } diff --git a/validator_client/src/service.rs b/validator_client/src/service.rs index 9ca591b92..e32271299 100644 --- a/validator_client/src/service.rs +++ b/validator_client/src/service.rs @@ -222,11 +222,11 @@ impl Service { // build requisite objects to pass to core thread. let duties_map = Arc::new(EpochDutiesMap::new(config.spec.slots_per_epoch)); let epoch_map_for_attester = Arc::new(EpochMap::new(config.spec.slots_per_epoch)); + let manager = Arc::new(DutiesManager { duties_map, pubkeys: keypairs.iter().map(|keypair| keypair.pk.clone()).collect(), - spec: Arc::new(config.spec), - slot_clock: service.slot_clock.clone(), + slots_per_epoch: config.spec.slots_per_epoch.clone(), beacon_node: service.validator_client.clone(), }); @@ -234,6 +234,7 @@ impl Service { runtime .block_on(interval.for_each(move |_| { let log = service.log.clone(); + // get the current slot let current_slot = match service.slot_clock.present_slot() { Err(e) => { @@ -250,24 +251,24 @@ impl Service { info!(log, "Processing slot: {}", current_slot.as_u64()); - let cloned_manager = manager.clone(); - // check for new duties + let cloned_manager = manager.clone(); tokio::spawn(futures::future::poll_fn(move || { cloned_manager.run_update(current_slot.clone(), log.clone()) })); + + // execute any specified duties + Ok(()) })) .map_err(|e| format!("Service thread failed: {:?}", e))?; + + // completed a slot process Ok(()) } /* - let duties_map = Arc::new(EpochDutiesMap::new(spec.slots_per_epoch)); - let epoch_map_for_attester = Arc::new(EpochMap::new(spec.slots_per_epoch)); - - for keypair in keypairs { info!(self.log, "Starting validator services"; "validator" => keypair.pk.concatenated_hex_id());