From 68942318a75895643dc73c2b353e8dfadc158244 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Sat, 23 Nov 2019 15:20:29 +1100 Subject: [PATCH] Attempt fix for addr parsing --- beacon_node/src/cli.rs | 8 - eth2/utils/remote_beacon_node/src/lib.rs | 5 +- validator_client/src/cli.rs | 31 +--- validator_client/src/lib.rs | 220 +++++++++++------------ 4 files changed, 111 insertions(+), 153 deletions(-) diff --git a/beacon_node/src/cli.rs b/beacon_node/src/cli.rs index eb7bd41beb..e7f727b305 100644 --- a/beacon_node/src/cli.rs +++ b/beacon_node/src/cli.rs @@ -9,14 +9,6 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { /* * Configuration directory locations. */ - .arg( - Arg::with_name("datadir") - .long("datadir") - .value_name("DIR") - .help("Data directory for keys and databases.") - .takes_value(true) - .global(true) - ) .arg( Arg::with_name("network-dir") .long("network-dir") diff --git a/eth2/utils/remote_beacon_node/src/lib.rs b/eth2/utils/remote_beacon_node/src/lib.rs index 48ebc7c59c..e42fbda27f 100644 --- a/eth2/utils/remote_beacon_node/src/lib.rs +++ b/eth2/utils/remote_beacon_node/src/lib.rs @@ -12,7 +12,6 @@ use reqwest::{ use serde::{de::DeserializeOwned, Deserialize, Serialize}; use ssz::Encode; use std::marker::PhantomData; -use std::net::SocketAddr; use std::time::Duration; use types::{ Attestation, BeaconBlock, BeaconState, CommitteeIndex, Epoch, EthSpec, Fork, Hash256, @@ -36,9 +35,9 @@ pub struct RemoteBeaconNode { } impl RemoteBeaconNode { - pub fn new(http_endpoint: SocketAddr) -> Result { + pub fn new(http_endpoint: String) -> Result { Ok(Self { - http: HttpClient::new(format!("http://{}", http_endpoint.to_string())) + http: HttpClient::new(http_endpoint) .map_err(|e| format!("Unable to create http client: {:?}", e))?, }) } diff --git a/validator_client/src/cli.rs b/validator_client/src/cli.rs index a630147c2e..6c1f192a8b 100644 --- a/validator_client/src/cli.rs +++ b/validator_client/src/cli.rs @@ -15,34 +15,9 @@ lazy_static! { } pub fn cli_app<'a, 'b>() -> App<'a, 'b> { - App::new("Validator Client") - .visible_aliases(&["v", "vc", "validator", "validator_client"]) - .version("0.0.1") - .author("Sigma Prime ") - .about("Eth 2.0 Validator Client") - .arg( - Arg::with_name("datadir") - .long("datadir") - .short("d") - .value_name("DIR") - .help("Data directory for keys and databases.") - .takes_value(true), - ) - .arg( - Arg::with_name("logfile") - .long("logfile") - .value_name("logfile") - .help("File path where output will be written.") - .takes_value(true), - ) - .arg( - Arg::with_name("eth2-config") - .long("eth2-config") - .short("e") - .value_name("TOML_FILE") - .help("Path to Ethereum 2.0 config and specification file (e.g., eth2_spec.toml).") - .takes_value(true), - ) + App::new("validator_client") + .visible_aliases(&["v", "vc", "validator"]) + .about("Ethereum 2.0 Validator Client") .arg( Arg::with_name("server") .long("server") diff --git a/validator_client/src/lib.rs b/validator_client/src/lib.rs index 035197cb08..ecc370ce56 100644 --- a/validator_client/src/lib.rs +++ b/validator_client/src/lib.rs @@ -69,137 +69,129 @@ impl ProductionValidatorClient { let log_2 = context.log.clone(); let log_3 = context.log.clone(); + let http_server_addr = format!( + "http://{}:{}", + client_config.server, client_config.server_http_port + ); + info!( log_1, "Starting validator client"; + "beacon_node" => &http_server_addr, "datadir" => format!("{:?}", client_config.data_dir), ); - format!( - "{}:{}", - client_config.server, client_config.server_http_port - ) - .parse() - .map_err(|e| format!("Unable to parse server address: {:?}", e)) - .into_future() - .and_then(move |http_server_addr| { - info!( - log_1, - "Beacon node connection info"; - "http_server" => format!("{}", http_server_addr), - ); + RemoteBeaconNode::new(http_server_addr) + .map_err(|e| format!("Unable to init beacon node http client: {}", e)) + .into_future() + .and_then(move |beacon_node| wait_for_node(beacon_node, log_2)) + .and_then(|beacon_node| { + beacon_node + .http + .spec() + .get_eth2_config() + .map(|eth2_config| (beacon_node, eth2_config)) + .map_err(|e| format!("Unable to read eth2 config from beacon node: {:?}", e)) + }) + .and_then(|(beacon_node, eth2_config)| { + beacon_node + .http + .beacon() + .get_genesis_time() + .map(|genesis_time| (beacon_node, eth2_config, genesis_time)) + .map_err(|e| format!("Unable to read genesis time from beacon node: {:?}", e)) + }) + .and_then(move |(beacon_node, remote_eth2_config, genesis_time)| { + // Do not permit a connection to a beacon node using different spec constants. + if context.eth2_config.spec_constants != remote_eth2_config.spec_constants { + return Err(format!( + "Beacon node is using an incompatible spec. Got {}, expected {}", + remote_eth2_config.spec_constants, context.eth2_config.spec_constants + )); + } - RemoteBeaconNode::new(http_server_addr) - .map_err(|e| format!("Unable to init beacon node http client: {}", e)) - }) - .and_then(move |beacon_node| wait_for_node(beacon_node, log_2)) - .and_then(|beacon_node| { - beacon_node - .http - .spec() - .get_eth2_config() - .map(|eth2_config| (beacon_node, eth2_config)) - .map_err(|e| format!("Unable to read eth2 config from beacon node: {:?}", e)) - }) - .and_then(|(beacon_node, eth2_config)| { - beacon_node - .http - .beacon() - .get_genesis_time() - .map(|genesis_time| (beacon_node, eth2_config, genesis_time)) - .map_err(|e| format!("Unable to read genesis time from beacon node: {:?}", e)) - }) - .and_then(move |(beacon_node, remote_eth2_config, genesis_time)| { - // Do not permit a connection to a beacon node using different spec constants. - if context.eth2_config.spec_constants != remote_eth2_config.spec_constants { - return Err(format!( - "Beacon node is using an incompatible spec. Got {}, expected {}", - remote_eth2_config.spec_constants, context.eth2_config.spec_constants - )); - } - - // Note: here we just assume the spec variables of the remote node. This is very useful - // for testnets, but perhaps a security issue when it comes to mainnet. - // - // A damaging attack would be for a beacon node to convince the validator client of a - // different `SLOTS_PER_EPOCH` variable. This could result in slashable messages being - // produced. We are safe from this because `SLOTS_PER_EPOCH` is a type-level constant - // for Lighthouse. - context.eth2_config = remote_eth2_config; - - let slot_clock = SystemTimeSlotClock::new( - context.eth2_config.spec.genesis_slot, - Duration::from_secs(genesis_time), - Duration::from_millis(context.eth2_config.spec.milliseconds_per_slot), - ); - - let validator_store: ValidatorStore = match &client_config.key_source { - // Load pre-existing validators from the data dir. + // Note: here we just assume the spec variables of the remote node. This is very useful + // for testnets, but perhaps a security issue when it comes to mainnet. // - // Use the `account_manager` to generate these files. - KeySource::Disk => ValidatorStore::load_from_disk( - client_config.data_dir.clone(), - context.eth2_config.spec.clone(), - log_3.clone(), - )?, - // Generate ephemeral insecure keypairs for testing purposes. - // - // Do not use in production. - KeySource::TestingKeypairRange(range) => { - ValidatorStore::insecure_ephemeral_validators( - range.clone(), + // A damaging attack would be for a beacon node to convince the validator client of a + // different `SLOTS_PER_EPOCH` variable. This could result in slashable messages being + // produced. We are safe from this because `SLOTS_PER_EPOCH` is a type-level constant + // for Lighthouse. + context.eth2_config = remote_eth2_config; + + let slot_clock = SystemTimeSlotClock::new( + context.eth2_config.spec.genesis_slot, + Duration::from_secs(genesis_time), + Duration::from_millis(context.eth2_config.spec.milliseconds_per_slot), + ); + + let validator_store: ValidatorStore = match &client_config.key_source { + // Load pre-existing validators from the data dir. + // + // Use the `account_manager` to generate these files. + KeySource::Disk => ValidatorStore::load_from_disk( + client_config.data_dir.clone(), context.eth2_config.spec.clone(), log_3.clone(), - )? - } - }; + )?, + // Generate ephemeral insecure keypairs for testing purposes. + // + // Do not use in production. + KeySource::TestingKeypairRange(range) => { + ValidatorStore::insecure_ephemeral_validators( + range.clone(), + context.eth2_config.spec.clone(), + log_3.clone(), + )? + } + }; - info!( - log_3, - "Loaded validator keypair store"; - "voting_validators" => validator_store.num_voting_validators() - ); + info!( + log_3, + "Loaded validator keypair store"; + "voting_validators" => validator_store.num_voting_validators() + ); - let duties_service = DutiesServiceBuilder::new() - .slot_clock(slot_clock.clone()) - .validator_store(validator_store.clone()) - .beacon_node(beacon_node.clone()) - .runtime_context(context.service_context("duties")) - .build()?; + let duties_service = DutiesServiceBuilder::new() + .slot_clock(slot_clock.clone()) + .validator_store(validator_store.clone()) + .beacon_node(beacon_node.clone()) + .runtime_context(context.service_context("duties")) + .build()?; - let fork_service = ForkServiceBuilder::new() - .slot_clock(slot_clock.clone()) - .beacon_node(beacon_node.clone()) - .runtime_context(context.service_context("fork")) - .build()?; + let fork_service = ForkServiceBuilder::new() + .slot_clock(slot_clock.clone()) + .beacon_node(beacon_node.clone()) + .runtime_context(context.service_context("fork")) + .build()?; - let block_service = BlockServiceBuilder::new() - .duties_service(duties_service.clone()) - .fork_service(fork_service.clone()) - .slot_clock(slot_clock.clone()) - .validator_store(validator_store.clone()) - .beacon_node(beacon_node.clone()) - .runtime_context(context.service_context("block")) - .build()?; + let block_service = BlockServiceBuilder::new() + .duties_service(duties_service.clone()) + .fork_service(fork_service.clone()) + .slot_clock(slot_clock.clone()) + .validator_store(validator_store.clone()) + .beacon_node(beacon_node.clone()) + .runtime_context(context.service_context("block")) + .build()?; - let attestation_service = AttestationServiceBuilder::new() - .duties_service(duties_service.clone()) - .fork_service(fork_service.clone()) - .slot_clock(slot_clock) - .validator_store(validator_store) - .beacon_node(beacon_node) - .runtime_context(context.service_context("attestation")) - .build()?; + let attestation_service = AttestationServiceBuilder::new() + .duties_service(duties_service.clone()) + .fork_service(fork_service.clone()) + .slot_clock(slot_clock) + .validator_store(validator_store) + .beacon_node(beacon_node) + .runtime_context(context.service_context("attestation")) + .build()?; - Ok(Self { - context, - duties_service, - fork_service, - block_service, - attestation_service, - exit_signals: Arc::new(RwLock::new(vec![])), + Ok(Self { + context, + duties_service, + fork_service, + block_service, + attestation_service, + exit_signals: Arc::new(RwLock::new(vec![])), + }) }) - }) } pub fn start_service(&self) -> Result<(), String> {