Updated validator client to do better logging, including of JSON serialised signatures and such, for debugging purposes.

This commit is contained in:
Luke Anderson 2019-09-10 10:55:46 +10:00
parent ca9094e79a
commit 476cbae577
No known key found for this signature in database
GPG Key ID: 44408169EC61E228
4 changed files with 32 additions and 12 deletions

View File

@ -25,6 +25,7 @@ slot_clock = { path = "../eth2/utils/slot_clock" }
types = { path = "../eth2/types" } types = { path = "../eth2/types" }
serde = "1.0" serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
serde_json = "^1.0"
slog = "^2.2.3" slog = "^2.2.3"
slog-async = "^2.3.0" slog-async = "^2.3.0"
slog-json = "^2.3" slog-json = "^2.3"

View File

@ -6,7 +6,8 @@ pub use self::beacon_node_block::{BeaconNodeError, PublishOutcome};
pub use self::grpc::BeaconBlockGrpcClient; pub use self::grpc::BeaconBlockGrpcClient;
use crate::signer::Signer; use crate::signer::Signer;
use core::marker::PhantomData; use core::marker::PhantomData;
use slog::{error, info, warn}; use serde_json;
use slog::{error, info, trace, warn};
use std::sync::Arc; use std::sync::Arc;
use tree_hash::{SignedRoot, TreeHash}; use tree_hash::{SignedRoot, TreeHash};
use types::{BeaconBlock, ChainSpec, Domain, EthSpec, Fork, Slot}; 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, pub slots_per_epoch: u64,
/// Mere vessel for E. /// Mere vessel for E.
pub _phantom: PhantomData<E>, pub _phantom: PhantomData<E>,
/// The logger, for logging
pub log: slog::Logger,
} }
impl<'a, B: BeaconNodeBlock, S: Signer, E: EthSpec> BlockProducer<'a, B, S, E> { impl<'a, B: BeaconNodeBlock, S: Signer, E: EthSpec> BlockProducer<'a, B, S, E> {
/// Handle outputs and results from block production. /// 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() { match self.produce_block() {
Ok(ValidatorEvent::BlockProduced(_slot)) => { 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)) => { 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)) => { 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)) => { 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) => { 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. /// slashing.
pub fn produce_block(&mut self) -> Result<ValidatorEvent, Error> { pub fn produce_block(&mut self) -> Result<ValidatorEvent, Error> {
let epoch = self.slot.epoch(self.slots_per_epoch); let epoch = self.slot.epoch(self.slots_per_epoch);
trace!(self.log, "Producing block"; "epoch" => epoch);
let message = epoch.tree_hash_root(); let message = epoch.tree_hash_root();
let randao_reveal = match self.signer.sign_message( let randao_reveal = match self.signer.sign_message(
&message, &message,
self.spec.get_domain(epoch, Domain::Randao, &self.fork), self.spec.get_domain(epoch, Domain::Randao, &self.fork),
) { ) {
None => return Ok(ValidatorEvent::SignerRejection(self.slot)), None => {
Some(signature) => signature, 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 if let Some(block) = self

View File

@ -54,7 +54,6 @@ fn main() {
) )
.arg( .arg(
Arg::with_name("spec") Arg::with_name("spec")
.short("s")
.long("spec") .long("spec")
.value_name("TITLE") .value_name("TITLE")
.help("Specifies the default eth2 spec type.") .help("Specifies the default eth2 spec type.")
@ -132,6 +131,15 @@ fn main() {
.help("The number of validators.")) .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(); .get_matches();
let drain = match matches.value_of("debug-level") { let drain = match matches.value_of("debug-level") {

View File

@ -369,8 +369,9 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static, E: EthSpec> Service<B,
signer, signer,
slots_per_epoch, slots_per_epoch,
_phantom: PhantomData::<E>, _phantom: PhantomData::<E>,
log,
}; };
block_producer.handle_produce_block(log); block_producer.handle_produce_block();
}); });
} }
if work_type.attestation_duty.is_some() { if work_type.attestation_duty.is_some() {