diff --git a/validator_client/Cargo.toml b/validator_client/Cargo.toml index f76772f28f..cdde71774f 100644 --- a/validator_client/Cargo.toml +++ b/validator_client/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" [dependencies] block_proposer = { path = "../eth2/block_proposer" } +attester = { path = "../eth2/attester" } bls = { path = "../eth2/utils/bls" } clap = "2.32.0" dirs = "1.0.3" diff --git a/validator_client/src/attester_service/mod.rs b/validator_client/src/attester_service/mod.rs new file mode 100644 index 0000000000..fbf8bd005a --- /dev/null +++ b/validator_client/src/attester_service/mod.rs @@ -0,0 +1,51 @@ +use attester::{Attester, BeaconNode, DutiesReader, PollOutcome as AttesterPollOutcome, Signer}; +use slog::Logger; +use slot_clock::SlotClock; +use std::time::Duration; + +pub struct AttesterService { + pub attester: Attester, + pub poll_interval_millis: u64, + pub log: Logger, +} + +impl AttesterService { + /// Run a loop which polls the Attester each `poll_interval_millis` millseconds. + /// + /// Logs the results of the polls. + pub fn run(&mut self) { + loop { + match self.attester.poll() { + Err(error) => { + error!(self.log, "Attester poll error"; "error" => format!("{:?}", error)) + } + Ok(AttesterPollOutcome::AttestationProduced(slot)) => { + info!(self.log, "Produced Attestation"; "slot" => slot) + } + Ok(AttesterPollOutcome::SlashableAttestationNotProduced(slot)) => { + warn!(self.log, "Slashable attestation was not produced"; "slot" => slot) + } + Ok(AttesterPollOutcome::AttestationNotRequired(slot)) => { + info!(self.log, "Attestation not required"; "slot" => slot) + } + Ok(AttesterPollOutcome::ProducerDutiesUnknown(slot)) => { + error!(self.log, "Attestation duties unknown"; "slot" => slot) + } + Ok(AttesterPollOutcome::SlotAlreadyProcessed(slot)) => { + warn!(self.log, "Attempted to re-process slot"; "slot" => slot) + } + Ok(AttesterPollOutcome::BeaconNodeUnableToProduceAttestation(slot)) => { + error!(self.log, "Beacon node unable to produce attestation"; "slot" => slot) + } + Ok(AttesterPollOutcome::SignerRejection(slot)) => { + error!(self.log, "The cryptographic signer refused to sign the attestation"; "slot" => slot) + } + Ok(AttesterPollOutcome::ValidatorIsUnknown(slot)) => { + error!(self.log, "The Beacon Node does not recognise the validator"; "slot" => slot) + } + }; + + std::thread::sleep(Duration::from_millis(self.poll_interval_millis)); + } + } +} diff --git a/validator_client/src/main.rs b/validator_client/src/main.rs index ebab8538c5..2e432ceffc 100644 --- a/validator_client/src/main.rs +++ b/validator_client/src/main.rs @@ -1,7 +1,9 @@ use self::block_producer_service::{BeaconBlockGrpcClient, BlockProducerService}; use self::duties::{DutiesManager, DutiesManagerService, EpochDutiesMap}; +use crate::attester_service::AttesterService; use crate::config::ClientConfig; -use block_proposer::{test_utils::LocalSigner, BlockProducer}; +use attester::{test_utils::LocalSigner as AttesterLocalSigner, Attester}; +use block_proposer::{test_utils::LocalSigner as BlockProposerLocalSigner, BlockProducer}; use bls::Keypair; use clap::{App, Arg}; use grpcio::{ChannelBuilder, EnvBuilder}; @@ -13,7 +15,9 @@ use std::sync::Arc; use std::thread; use types::ChainSpec; +mod attester_service; mod block_producer_service; + mod config; mod duties; @@ -160,7 +164,7 @@ fn main() { // Spawn a new thread to perform block production for the validator. let producer_thread = { let spec = spec.clone(); - let signer = Arc::new(LocalSigner::new(keypair.clone())); + let signer = Arc::new(BlockProposerLocalSigner::new(keypair.clone())); let duties_map = duties_map.clone(); let slot_clock = slot_clock.clone(); let log = log.clone(); @@ -178,6 +182,27 @@ fn main() { }) }; + //Spawn a new thread for attestation for the validator. + let attester_thread = { + let signer = Arc::new(AttesterLocalSigner::new(keypair.clone())); + let duties_map = duties_map.clone(); + let slot_clock = slot_clock.clone(); + let log = log.clone(); + //TODO: this is wrong, I assume this has to be AttesterGrpcClient, which has to be defined analogous + // to beacon_block_grpc_client.rs + let client = Arc::new(BeaconBlockGrpcClient::new(beacon_block_grpc_client.clone())); + thread::spawn(move || { + let attester = Attester::new(duties_map, slot_clock, client, signer); + let mut attester_service = AttesterService { + attester, + poll_interval_millis, + log, + }; + + block_producer_service.run(); + }) + }; + threads.push((duties_manager_thread, producer_thread)); }