Attempt fix for addr parsing

This commit is contained in:
Paul Hauner
2019-11-23 15:20:29 +11:00
parent 466eb0420f
commit 68942318a7
4 changed files with 111 additions and 153 deletions

View File

@@ -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 <contact@sigmaprime.io>")
.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")

View File

@@ -69,137 +69,129 @@ impl<T: EthSpec> ProductionValidatorClient<T> {
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<T> = 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<T> = 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> {