diff --git a/validator_client/Cargo.toml b/validator_client/Cargo.toml index 2000f5409b..706b28f86a 100644 --- a/validator_client/Cargo.toml +++ b/validator_client/Cargo.toml @@ -25,6 +25,7 @@ slot_clock = { path = "../eth2/utils/slot_clock" } types = { path = "../eth2/types" } serde = "1.0" serde_derive = "1.0" +serde_json = "^1.0" slog = "^2.2.3" slog-async = "^2.3.0" slog-json = "^2.3" diff --git a/validator_client/src/block_producer/mod.rs b/validator_client/src/block_producer/mod.rs index ca1e3a1d87..f61cde1461 100644 --- a/validator_client/src/block_producer/mod.rs +++ b/validator_client/src/block_producer/mod.rs @@ -6,7 +6,8 @@ pub use self::beacon_node_block::{BeaconNodeError, PublishOutcome}; pub use self::grpc::BeaconBlockGrpcClient; use crate::signer::Signer; use core::marker::PhantomData; -use slog::{error, info, warn}; +use serde_json; +use slog::{error, info, trace, warn}; use std::sync::Arc; use tree_hash::{SignedRoot, TreeHash}; use types::{BeaconBlock, ChainSpec, Domain, EthSpec, Fork, Slot}; @@ -53,27 +54,29 @@ pub struct BlockProducer<'a, B: BeaconNodeBlock, S: Signer, E: EthSpec> { pub slots_per_epoch: u64, /// Mere vessel for E. pub _phantom: PhantomData, + /// The logger, for logging + pub log: slog::Logger, } impl<'a, B: BeaconNodeBlock, S: Signer, E: EthSpec> BlockProducer<'a, B, S, E> { /// Handle outputs and results from block production. - pub fn handle_produce_block(&mut self, log: slog::Logger) { + pub fn handle_produce_block(&mut self) { match self.produce_block() { Ok(ValidatorEvent::BlockProduced(_slot)) => { - info!(log, "Block produced"; "Validator" => format!("{}", self.signer)) + info!(self.log, "Block produced"; "Validator" => format!("{}", self.signer)) } - Err(e) => error!(log, "Block production error"; "Error" => format!("{:?}", e)), + Err(e) => error!(self.log, "Block production error"; "Error" => format!("{:?}", e)), Ok(ValidatorEvent::SignerRejection(_slot)) => { - error!(log, "Block production error"; "Error" => "Signer Could not sign the block".to_string()) + error!(self.log, "Block production error"; "Error" => "Signer Could not sign the block".to_string()) } Ok(ValidatorEvent::SlashableBlockNotProduced(_slot)) => { - error!(log, "Block production error"; "Error" => "Rejected the block as it could have been slashed".to_string()) + error!(self.log, "Block production error"; "Error" => "Rejected the block as it could have been slashed".to_string()) } Ok(ValidatorEvent::BeaconNodeUnableToProduceBlock(_slot)) => { - error!(log, "Block production error"; "Error" => "Beacon node was unable to produce a block".to_string()) + error!(self.log, "Block production error"; "Error" => "Beacon node was unable to produce a block".to_string()) } Ok(v) => { - warn!(log, "Unknown result for block production"; "Error" => format!("{:?}",v)) + warn!(self.log, "Unknown result for block production"; "Error" => format!("{:?}",v)) } } } @@ -90,14 +93,21 @@ impl<'a, B: BeaconNodeBlock, S: Signer, E: EthSpec> BlockProducer<'a, B, S, E> { /// slashing. pub fn produce_block(&mut self) -> Result { let epoch = self.slot.epoch(self.slots_per_epoch); + trace!(self.log, "Producing block"; "epoch" => epoch); let message = epoch.tree_hash_root(); let randao_reveal = match self.signer.sign_message( &message, self.spec.get_domain(epoch, Domain::Randao, &self.fork), ) { - None => return Ok(ValidatorEvent::SignerRejection(self.slot)), - Some(signature) => signature, + None => { + warn!(self.log, "Signing rejected"; "message" => format!("{:?}", message)); + return Ok(ValidatorEvent::SignerRejection(self.slot)); + } + Some(signature) => { + info!(self.log, "Signed tree_hash_root for randao_reveal"; "message" => format!("{:?}", message), "signature" => serde_json::to_string(&signature).expect("We should always be able to serialize a signature as JSON.")); + signature + } }; if let Some(block) = self diff --git a/validator_client/src/main.rs b/validator_client/src/main.rs index 39b2e3eaee..bb791aa20b 100644 --- a/validator_client/src/main.rs +++ b/validator_client/src/main.rs @@ -54,7 +54,6 @@ fn main() { ) .arg( Arg::with_name("spec") - .short("s") .long("spec") .value_name("TITLE") .help("Specifies the default eth2 spec type.") @@ -132,6 +131,15 @@ fn main() { .help("The number of validators.")) ) ) + .subcommand(SubCommand::with_name("sign_block") + .about("Connects to the beacon server, requests a new block (after providing reveal),\ + and prints the signed block to standard out") + .arg(Arg::with_name("validator") + .value_name("VALIDATOR") + .required(true) + .help("The pubkey of the validator that should sign the block.") + ) + ) .get_matches(); let drain = match matches.value_of("debug-level") { diff --git a/validator_client/src/service.rs b/validator_client/src/service.rs index 5169f67f87..4fe744ea2d 100644 --- a/validator_client/src/service.rs +++ b/validator_client/src/service.rs @@ -369,8 +369,9 @@ impl Service, + log, }; - block_producer.handle_produce_block(log); + block_producer.handle_produce_block(); }); } if work_type.attestation_duty.is_some() {