diff --git a/core/src/gossip_service.rs b/core/src/gossip_service.rs index d0ba4be36c..0972c905c8 100644 --- a/core/src/gossip_service.rs +++ b/core/src/gossip_service.rs @@ -107,7 +107,7 @@ pub fn discover( ); Err(std::io::Error::new( std::io::ErrorKind::Other, - "Failed to converge", + "Discover failed", )) } diff --git a/gossip/src/main.rs b/gossip/src/main.rs index 28f5c7b45c..e982418cdc 100644 --- a/gossip/src/main.rs +++ b/gossip/src/main.rs @@ -3,7 +3,10 @@ #[macro_use] extern crate solana; -use clap::{crate_description, crate_name, crate_version, App, AppSettings, Arg, SubCommand}; +use clap::{ + crate_description, crate_name, crate_version, value_t_or_exit, App, AppSettings, Arg, + SubCommand, +}; use solana::contact_info::ContactInfo; use solana::gossip_service::discover; use solana_client::rpc_client::RpcClient; @@ -38,6 +41,19 @@ fn main() -> Result<(), Box> { .global(true) .help("Rendezvous with the cluster at this entry point"), ) + .subcommand( + SubCommand::with_name("get-rpc-url") + .about("Get an RPC URL for the cluster") + .arg( + Arg::with_name("timeout") + .long("timeout") + .value_name("SECONDS") + .takes_value(true) + .default_value("5") + .help("Timeout in seconds"), + ) + .setting(AppSettings::DisableVersion), + ) .subcommand( SubCommand::with_name("spy") .about("Monitor the gossip entrypoint") @@ -49,7 +65,7 @@ fn main() -> Result<(), Box> { .value_name("NUM") .takes_value(true) .conflicts_with("num_nodes_exactly") - .help("Wait for at least NUM nodes to converge"), + .help("Wait for at least NUM nodes to be visible"), ) .arg( Arg::with_name("num_nodes_exactly") @@ -57,7 +73,7 @@ fn main() -> Result<(), Box> { .long("num-nodes-exactly") .value_name("NUM") .takes_value(true) - .help("Wait for exactly NUM nodes to converge"), + .help("Wait for exactly NUM nodes to be visible"), ) .arg( Arg::with_name("node_pubkey") @@ -71,11 +87,9 @@ fn main() -> Result<(), Box> { .arg( Arg::with_name("timeout") .long("timeout") - .value_name("SECS") + .value_name("SECONDS") .takes_value(true) - .help( - "Maximum time to wait for cluster to converge [default: wait forever]", - ), + .help("Maximum time to wait in seconds [default: wait forever]"), ), ) .subcommand( @@ -99,6 +113,18 @@ fn main() -> Result<(), Box> { exit(1) }); } + + let gossip_addr = { + let mut addr = socketaddr_any!(); + addr.set_ip( + solana_netutil::get_public_ip_addr(&entrypoint_addr).unwrap_or_else(|err| { + eprintln!("failed to contact {}: {}", entrypoint_addr, err); + exit(1) + }), + ); + Some(addr) + }; + match matches.subcommand() { ("spy", Some(matches)) => { let num_nodes_exactly = matches @@ -115,17 +141,6 @@ fn main() -> Result<(), Box> { .value_of("node_pubkey") .map(|pubkey_str| pubkey_str.parse::().unwrap()); - let gossip_addr = { - let mut addr = socketaddr_any!(); - addr.set_ip( - solana_netutil::get_public_ip_addr(&entrypoint_addr).unwrap_or_else(|err| { - eprintln!("failed to contact {}: {}", entrypoint_addr, err); - exit(1) - }), - ); - Some(addr) - }; - let (nodes, _replicators) = discover( &entrypoint_addr, num_nodes, @@ -161,13 +176,42 @@ fn main() -> Result<(), Box> { ); } } + ("get-rpc-url", Some(matches)) => { + let timeout = value_t_or_exit!(matches, "timeout", u64); + let (nodes, _replicators) = discover( + &entrypoint_addr, + Some(1), + Some(timeout), + None, + gossip_addr.as_ref(), + )?; + + let rpc_addr = nodes + .iter() + .filter_map(ContactInfo::valid_client_facing_addr) + .map(|addrs| addrs.0) + .find(|rpc_addr| rpc_addr.ip() == entrypoint_addr.ip()); + + if rpc_addr.is_none() { + eprintln!("No RPC URL found"); + exit(1); + } + + println!("http://{}", rpc_addr.unwrap()); + } ("stop", Some(matches)) => { let pubkey = matches .value_of("node_pubkey") .unwrap() .parse::() .unwrap(); - let (nodes, _replicators) = discover(&entrypoint_addr, None, None, Some(pubkey), None)?; + let (nodes, _replicators) = discover( + &entrypoint_addr, + None, + None, + Some(pubkey), + gossip_addr.as_ref(), + )?; let node = nodes.iter().find(|x| x.id == pubkey).unwrap(); if !ContactInfo::is_valid_address(&node.rpc) { diff --git a/multinode-demo/replicator.sh b/multinode-demo/replicator.sh index 386741dc65..b21b73abfa 100755 --- a/multinode-demo/replicator.sh +++ b/multinode-demo/replicator.sh @@ -56,7 +56,7 @@ done : "${storage_keypair:="$SOLANA_ROOT"/farf/replicator-storage-keypair"$label".json}" ledger="$SOLANA_ROOT"/farf/replicator-ledger"$label" -rpc_url=$("$here"/rpc-url.sh "$entrypoint") +rpc_url=$($solana_gossip get-rpc-url --entrypoint "$entrypoint") if [[ ! -r $identity_keypair ]]; then $solana_keygen new -o "$identity_keypair" diff --git a/multinode-demo/rpc-url.sh b/multinode-demo/rpc-url.sh deleted file mode 100755 index 0d865c4cf6..0000000000 --- a/multinode-demo/rpc-url.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -# -# Given a gossip entrypoint derive the entrypoint's RPC address -# - -entrypoint_address=$1 -if [[ -z $entrypoint_address ]]; then - echo "Error: entrypoint address not specified" >&2 - exit 1 -fi - -# TODO: Rather than hard coding, add a `solana-gossip rpc-address` command that -# actually asks the entrypoint itself for its RPC address -echo "http://${entrypoint_address%:*}:8899" diff --git a/multinode-demo/validator.sh b/multinode-demo/validator.sh index 8d58110120..fcad0e6846 100755 --- a/multinode-demo/validator.sh +++ b/multinode-demo/validator.sh @@ -175,7 +175,7 @@ else gossip_entrypoint="$entrypoint_hostname":8001 fi fi -rpc_url=$("$here"/rpc-url.sh "$gossip_entrypoint") + drone_address="${gossip_entrypoint%:*}":9900 : "${identity_keypair_path:=$ledger_dir/identity-keypair.json}" @@ -291,6 +291,7 @@ setup_validator_accounts() { } while true; do + rpc_url=$($solana_gossip get-rpc-url --entrypoint "$gossip_entrypoint") if new_genesis_block; then # If the genesis block has changed remove the now stale ledger and start all # over again