mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
Merge branch 'interop' into validator-post-fns.
This commit is contained in:
@@ -19,6 +19,7 @@ eth2_config = { path = "../eth2/utils/eth2_config" }
|
||||
tree_hash = "0.1"
|
||||
clap = "2.32.0"
|
||||
lighthouse_bootstrap = { path = "../eth2/utils/lighthouse_bootstrap" }
|
||||
eth2_interop_keypairs = { path = "../eth2/utils/eth2_interop_keypairs" }
|
||||
grpcio = { version = "0.4", default-features = false, features = ["protobuf-codec"] }
|
||||
protos = { path = "../protos" }
|
||||
slot_clock = { path = "../eth2/utils/slot_clock" }
|
||||
@@ -26,7 +27,7 @@ types = { path = "../eth2/types" }
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "^1.0"
|
||||
slog = "^2.2.3"
|
||||
slog = { version = "^2.2.3" , features = ["max_level_trace", "release_max_level_trace"] }
|
||||
slog-async = "^2.3.0"
|
||||
slog-json = "^2.3"
|
||||
slog-term = "^2.4.0"
|
||||
|
||||
@@ -50,9 +50,12 @@ impl<'a, B: BeaconNodeAttestation, S: Signer, E: EthSpec> AttestationProducer<'a
|
||||
/// Handle outputs and results from attestation production.
|
||||
pub fn handle_produce_attestation(&mut self, log: slog::Logger) {
|
||||
match self.produce_attestation() {
|
||||
Ok(ValidatorEvent::AttestationProduced(_slot)) => {
|
||||
info!(log, "Attestation produced"; "Validator" => format!("{}", self.signer))
|
||||
}
|
||||
Ok(ValidatorEvent::AttestationProduced(slot)) => info!(
|
||||
log,
|
||||
"Attestation produced";
|
||||
"validator" => format!("{}", self.signer),
|
||||
"slot" => slot,
|
||||
),
|
||||
Err(e) => error!(log, "Attestation production error"; "Error" => format!("{:?}", e)),
|
||||
Ok(ValidatorEvent::SignerRejection(_slot)) => {
|
||||
error!(log, "Attestation production error"; "Error" => "Signer could not sign the attestation".to_string())
|
||||
|
||||
@@ -62,10 +62,13 @@ 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) {
|
||||
match self.produce_block() {
|
||||
Ok(ValidatorEvent::BlockProduced(_slot)) => {
|
||||
info!(self.log, "Block produced"; "Validator" => format!("{}", self.signer))
|
||||
}
|
||||
Err(e) => error!(self.log, "Block production error"; "Error" => format!("{:?}", e)),
|
||||
Ok(ValidatorEvent::BlockProduced(slot)) => info!(
|
||||
log,
|
||||
"Block produced";
|
||||
"validator" => format!("{}", self.signer),
|
||||
"slot" => slot,
|
||||
),
|
||||
Err(e) => error!(log, "Block production error"; "Error" => format!("{:?}", e)),
|
||||
Ok(ValidatorEvent::SignerRejection(_slot)) => {
|
||||
error!(self.log, "Block production error"; "Error" => "Signer Could not sign the block".to_string())
|
||||
}
|
||||
@@ -115,12 +118,13 @@ impl<'a, B: BeaconNodeBlock, S: Signer, E: EthSpec> BlockProducer<'a, B, S, E> {
|
||||
.produce_beacon_block(self.slot, &randao_reveal)?
|
||||
{
|
||||
if self.safe_to_produce(&block) {
|
||||
let slot = block.slot;
|
||||
let domain = self
|
||||
.spec
|
||||
.get_domain(epoch, Domain::BeaconProposer, &self.fork);
|
||||
if let Some(block) = self.sign_block(block, domain) {
|
||||
self.beacon_node.publish_beacon_block(block)?;
|
||||
Ok(ValidatorEvent::BlockProduced(self.slot))
|
||||
Ok(ValidatorEvent::BlockProduced(slot))
|
||||
} else {
|
||||
Ok(ValidatorEvent::SignerRejection(self.slot))
|
||||
}
|
||||
|
||||
@@ -8,7 +8,10 @@ use std::io::{Error, ErrorKind};
|
||||
use std::ops::Range;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Mutex;
|
||||
use types::{test_utils::generate_deterministic_keypair, EthSpec, MainnetEthSpec};
|
||||
use types::{
|
||||
test_utils::{generate_deterministic_keypair, load_keypairs_from_yaml},
|
||||
EthSpec, MainnetEthSpec,
|
||||
};
|
||||
|
||||
pub const DEFAULT_SERVER: &str = "localhost";
|
||||
pub const DEFAULT_SERVER_GRPC_PORT: &str = "5051";
|
||||
@@ -20,6 +23,8 @@ pub enum KeySource {
|
||||
Disk,
|
||||
/// Generate the keypairs (insecure, generates predictable keys).
|
||||
TestingKeypairRange(Range<usize>),
|
||||
/// Load testing keypairs from YAML
|
||||
YamlKeypairs(PathBuf),
|
||||
}
|
||||
|
||||
impl Default for KeySource {
|
||||
@@ -227,9 +232,21 @@ impl Config {
|
||||
let keypairs = match &self.key_source {
|
||||
KeySource::Disk => self.fetch_keys_from_disk(log)?,
|
||||
KeySource::TestingKeypairRange(range) => {
|
||||
warn!(log, "Using insecure private keys");
|
||||
warn!(
|
||||
log,
|
||||
"Using insecure interop private keys";
|
||||
"range" => format!("{:?}", range)
|
||||
);
|
||||
self.fetch_testing_keypairs(range.clone())?
|
||||
}
|
||||
KeySource::YamlKeypairs(path) => {
|
||||
warn!(
|
||||
log,
|
||||
"Private keys are stored insecurely (plain text). Testing use only."
|
||||
);
|
||||
|
||||
load_keypairs_from_yaml(path.to_path_buf())?
|
||||
}
|
||||
};
|
||||
|
||||
// Check if it's an empty vector, and return none.
|
||||
|
||||
@@ -16,6 +16,7 @@ use eth2_config::Eth2Config;
|
||||
use lighthouse_bootstrap::Bootstrapper;
|
||||
use protos::services_grpc::ValidatorServiceClient;
|
||||
use slog::{crit, error, info, o, Drain, Level, Logger};
|
||||
use std::path::PathBuf;
|
||||
use types::{InteropEthSpec, Keypair, MainnetEthSpec, MinimalEthSpec};
|
||||
|
||||
pub const DEFAULT_SPEC: &str = "minimal";
|
||||
@@ -80,7 +81,8 @@ fn main() {
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("server-grpc-port")
|
||||
.long("g")
|
||||
.long("server-grpc-port")
|
||||
.short("g")
|
||||
.value_name("PORT")
|
||||
.help("Port to use for gRPC API connection to the server.")
|
||||
.default_value(DEFAULT_SERVER_GRPC_PORT)
|
||||
@@ -88,7 +90,8 @@ fn main() {
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("server-http-port")
|
||||
.long("h")
|
||||
.long("server-http-port")
|
||||
.short("h")
|
||||
.value_name("PORT")
|
||||
.help("Port to use for HTTP API connection to the server.")
|
||||
.default_value(DEFAULT_SERVER_HTTP_PORT)
|
||||
@@ -102,7 +105,7 @@ fn main() {
|
||||
.help("The title of the spec constants for chain config.")
|
||||
.takes_value(true)
|
||||
.possible_values(&["info", "debug", "trace", "warn", "error", "crit"])
|
||||
.default_value("info"),
|
||||
.default_value("trace"),
|
||||
)
|
||||
/*
|
||||
* The "testnet" sub-command.
|
||||
@@ -130,6 +133,14 @@ fn main() {
|
||||
.required(true)
|
||||
.help("The number of validators."))
|
||||
)
|
||||
.subcommand(SubCommand::with_name("interop-yaml")
|
||||
.about("Loads plain-text secret keys from YAML files. Expects the interop format defined
|
||||
in the ethereum/eth2.0-pm repo.")
|
||||
.arg(Arg::with_name("path")
|
||||
.value_name("PATH")
|
||||
.required(true)
|
||||
.help("Path to a YAML file."))
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("sign_block")
|
||||
.about("Connects to the beacon server, requests a new block (after providing reveal),\
|
||||
@@ -151,8 +162,10 @@ fn main() {
|
||||
Some("crit") => drain.filter_level(Level::Critical),
|
||||
_ => unreachable!("guarded by clap"),
|
||||
};
|
||||
let log = slog::Logger::root(drain.fuse(), o!());
|
||||
let (client_config, eth2_config) = match get_configs(&matches, &log) {
|
||||
|
||||
let mut log = slog::Logger::root(drain.fuse(), o!());
|
||||
|
||||
let (client_config, eth2_config) = match get_configs(&matches, &mut log) {
|
||||
Ok(tuple) => tuple,
|
||||
Err(e) => {
|
||||
crit!(
|
||||
@@ -203,9 +216,14 @@ fn main() {
|
||||
/// Parses the CLI arguments and attempts to load the client and eth2 configuration.
|
||||
///
|
||||
/// This is not a pure function, it reads from disk and may contact network servers.
|
||||
pub fn get_configs(cli_args: &ArgMatches, log: &Logger) -> Result<(ClientConfig, Eth2Config)> {
|
||||
pub fn get_configs(
|
||||
cli_args: &ArgMatches,
|
||||
mut log: &mut Logger,
|
||||
) -> Result<(ClientConfig, Eth2Config)> {
|
||||
let mut client_config = ClientConfig::default();
|
||||
|
||||
client_config.apply_cli_args(&cli_args, &mut log)?;
|
||||
|
||||
if let Some(server) = cli_args.value_of("server") {
|
||||
client_config.server = server.to_string();
|
||||
}
|
||||
@@ -223,14 +241,14 @@ pub fn get_configs(cli_args: &ArgMatches, log: &Logger) -> Result<(ClientConfig,
|
||||
}
|
||||
|
||||
info!(
|
||||
log,
|
||||
*log,
|
||||
"Beacon node connection info";
|
||||
"grpc_port" => client_config.server_grpc_port,
|
||||
"http_port" => client_config.server_http_port,
|
||||
"server" => &client_config.server,
|
||||
);
|
||||
|
||||
match cli_args.subcommand() {
|
||||
let (client_config, eth2_config) = match cli_args.subcommand() {
|
||||
("testnet", Some(sub_cli_args)) => {
|
||||
if cli_args.is_present("eth2-config") && sub_cli_args.is_present("bootstrap") {
|
||||
return Err(
|
||||
@@ -242,7 +260,9 @@ pub fn get_configs(cli_args: &ArgMatches, log: &Logger) -> Result<(ClientConfig,
|
||||
process_testnet_subcommand(sub_cli_args, client_config, log)
|
||||
}
|
||||
_ => return Err("You must use the testnet command. See '--help'.".into()),
|
||||
}
|
||||
}?;
|
||||
|
||||
Ok((client_config, eth2_config))
|
||||
}
|
||||
|
||||
/// Parses the `testnet` CLI subcommand.
|
||||
@@ -304,6 +324,21 @@ fn process_testnet_subcommand(
|
||||
|
||||
KeySource::TestingKeypairRange(first..first + count)
|
||||
}
|
||||
("interop-yaml", Some(sub_cli_args)) => {
|
||||
let path = sub_cli_args
|
||||
.value_of("path")
|
||||
.ok_or_else(|| "No yaml path supplied")?
|
||||
.parse::<PathBuf>()
|
||||
.map_err(|e| format!("Unable to parse yaml path: {:?}", e))?;
|
||||
|
||||
info!(
|
||||
log,
|
||||
"Loading keypairs from interop YAML format";
|
||||
"path" => format!("{:?}", path),
|
||||
);
|
||||
|
||||
KeySource::YamlKeypairs(path)
|
||||
}
|
||||
_ => KeySource::Disk,
|
||||
};
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ use protos::services_grpc::{
|
||||
AttestationServiceClient, BeaconBlockServiceClient, BeaconNodeServiceClient,
|
||||
ValidatorServiceClient,
|
||||
};
|
||||
use slog::{crit, error, info, warn};
|
||||
use slog::{crit, error, info, trace, warn};
|
||||
use slot_clock::{SlotClock, SystemTimeSlotClock};
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
@@ -289,6 +289,11 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static, E: EthSpec> Service<B,
|
||||
/* process any required duties for validators */
|
||||
self.process_duties();
|
||||
|
||||
trace!(
|
||||
self.log,
|
||||
"Per slot execution finished";
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -328,6 +333,13 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static, E: EthSpec> Service<B,
|
||||
.current_slot
|
||||
.expect("The current slot must be updated before checking for duties")
|
||||
.epoch(self.slots_per_epoch);
|
||||
|
||||
trace!(
|
||||
self.log,
|
||||
"Checking for duties";
|
||||
"epoch" => current_epoch
|
||||
);
|
||||
|
||||
// spawn a new thread separate to the runtime
|
||||
// TODO: Handle thread termination/timeout
|
||||
// TODO: Add duties thread back in, with channel to process duties in duty change.
|
||||
@@ -345,6 +357,12 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static, E: EthSpec> Service<B,
|
||||
self.current_slot
|
||||
.expect("The current slot must be updated before processing duties"),
|
||||
) {
|
||||
trace!(
|
||||
self.log,
|
||||
"Processing duties";
|
||||
"work_items" => work.len()
|
||||
);
|
||||
|
||||
for (signer_index, work_type) in work {
|
||||
if work_type.produce_block {
|
||||
// we need to produce a block
|
||||
@@ -359,7 +377,12 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static, E: EthSpec> Service<B,
|
||||
let log = self.log.clone();
|
||||
let slots_per_epoch = self.slots_per_epoch;
|
||||
std::thread::spawn(move || {
|
||||
info!(log, "Producing a block"; "Validator"=> format!("{}", signers[signer_index]));
|
||||
info!(
|
||||
log,
|
||||
"Producing a block";
|
||||
"validator"=> format!("{}", signers[signer_index]),
|
||||
"slot"=> slot
|
||||
);
|
||||
let signer = &signers[signer_index];
|
||||
let mut block_producer = BlockProducer {
|
||||
fork,
|
||||
@@ -377,6 +400,9 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static, E: EthSpec> Service<B,
|
||||
if work_type.attestation_duty.is_some() {
|
||||
// we need to produce an attestation
|
||||
// spawns a thread to produce and sign an attestation
|
||||
let slot = self
|
||||
.current_slot
|
||||
.expect("The current slot must be updated before processing duties");
|
||||
let signers = self.duties_manager.signers.clone(); // this is an arc
|
||||
let fork = self.fork.clone();
|
||||
let spec = self.spec.clone();
|
||||
@@ -384,7 +410,12 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static, E: EthSpec> Service<B,
|
||||
let log = self.log.clone();
|
||||
let slots_per_epoch = self.slots_per_epoch;
|
||||
std::thread::spawn(move || {
|
||||
info!(log, "Producing an attestation"; "Validator"=> format!("{}", signers[signer_index]));
|
||||
info!(
|
||||
log,
|
||||
"Producing an attestation";
|
||||
"validator"=> format!("{}", signers[signer_index]),
|
||||
"slot"=> slot
|
||||
);
|
||||
let signer = &signers[signer_index];
|
||||
let mut attestation_producer = AttestationProducer {
|
||||
fork,
|
||||
|
||||
Reference in New Issue
Block a user