* Allow nodes to advertise a different rpc address over gossip
* Feedback
(cherry picked from commit 8b0242a5d8
)
Co-authored-by: Justin Starry <justin@solana.com>
This commit is contained in:
@ -1267,14 +1267,16 @@ pub fn process_show_gossip(rpc_client: &RpcClient, config: &CliConfig) -> Proces
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|node| {
|
.map(|node| {
|
||||||
format!(
|
format!(
|
||||||
"{:15} | {:44} | {:6} | {:5} | {:5} | {}",
|
"{:15} | {:44} | {:6} | {:5} | {:21} | {}",
|
||||||
node.gossip
|
node.gossip
|
||||||
.map(|addr| addr.ip().to_string())
|
.map(|addr| addr.ip().to_string())
|
||||||
.unwrap_or_else(|| "none".to_string()),
|
.unwrap_or_else(|| "none".to_string()),
|
||||||
format_labeled_address(&node.pubkey, &config.address_labels),
|
format_labeled_address(&node.pubkey, &config.address_labels),
|
||||||
format_port(node.gossip),
|
format_port(node.gossip),
|
||||||
format_port(node.tpu),
|
format_port(node.tpu),
|
||||||
format_port(node.rpc),
|
node.rpc
|
||||||
|
.map(|addr| addr.to_string())
|
||||||
|
.unwrap_or_else(|| "none".to_string()),
|
||||||
node.version.unwrap_or_else(|| "unknown".to_string()),
|
node.version.unwrap_or_else(|| "unknown".to_string()),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -1282,9 +1284,9 @@ pub fn process_show_gossip(rpc_client: &RpcClient, config: &CliConfig) -> Proces
|
|||||||
|
|
||||||
Ok(format!(
|
Ok(format!(
|
||||||
"IP Address | Node identifier \
|
"IP Address | Node identifier \
|
||||||
| Gossip | TPU | RPC | Version\n\
|
| Gossip | TPU | RPC Address | Version\n\
|
||||||
----------------+----------------------------------------------+\
|
----------------+----------------------------------------------+\
|
||||||
--------+-------+-------+----------------\n\
|
--------+-------+-----------------------+----------------\n\
|
||||||
{}\n\
|
{}\n\
|
||||||
Nodes: {}",
|
Nodes: {}",
|
||||||
s.join("\n"),
|
s.join("\n"),
|
||||||
|
@ -530,6 +530,70 @@ impl ClusterInfo {
|
|||||||
.unwrap_or_else(|| EpochSlots::new(self.id(), timestamp()))
|
.unwrap_or_else(|| EpochSlots::new(self.id(), timestamp()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rpc_info_trace(&self) -> String {
|
||||||
|
let now = timestamp();
|
||||||
|
let my_pubkey = self.id();
|
||||||
|
let my_shred_version = self.my_shred_version();
|
||||||
|
let nodes: Vec<_> = self
|
||||||
|
.all_peers()
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|(node, last_updated)| {
|
||||||
|
if !ContactInfo::is_valid_address(&node.rpc) {
|
||||||
|
info!("invalid rpc: {}", node.rpc.to_string());
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let node_version = self.get_node_version(&node.id);
|
||||||
|
if my_shred_version != 0
|
||||||
|
&& (node.shred_version != 0 && node.shred_version != my_shred_version)
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn addr_to_string(default_ip: &IpAddr, addr: &SocketAddr) -> String {
|
||||||
|
if ContactInfo::is_valid_address(addr) {
|
||||||
|
if &addr.ip() == default_ip {
|
||||||
|
addr.port().to_string()
|
||||||
|
} else {
|
||||||
|
addr.to_string()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
"none".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let rpc_addr = node.rpc.ip();
|
||||||
|
Some(format!(
|
||||||
|
"{:15} {:2}| {:5} | {:44} |{:^9}| {:5}| {:5}| {:5}| {}\n",
|
||||||
|
rpc_addr.to_string(),
|
||||||
|
if node.id == my_pubkey { "me" } else { "" }.to_string(),
|
||||||
|
now.saturating_sub(last_updated),
|
||||||
|
node.id.to_string(),
|
||||||
|
if let Some(node_version) = node_version {
|
||||||
|
node_version.to_string()
|
||||||
|
} else {
|
||||||
|
"-".to_string()
|
||||||
|
},
|
||||||
|
addr_to_string(&rpc_addr, &node.rpc),
|
||||||
|
addr_to_string(&rpc_addr, &node.rpc_pubsub),
|
||||||
|
addr_to_string(&rpc_addr, &node.rpc_banks),
|
||||||
|
node.shred_version,
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
format!(
|
||||||
|
"RPC Address |Age(ms)| Node identifier \
|
||||||
|
| Version | RPC |PubSub| Banks|ShredVer\n\
|
||||||
|
------------------+-------+----------------------------------------------+---------+\
|
||||||
|
------+------+------+--------\n\
|
||||||
|
{}\
|
||||||
|
RPC Enabled Nodes: {}",
|
||||||
|
nodes.join(""),
|
||||||
|
nodes.len(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn contact_info_trace(&self) -> String {
|
pub fn contact_info_trace(&self) -> String {
|
||||||
let now = timestamp();
|
let now = timestamp();
|
||||||
let mut spy_nodes = 0;
|
let mut spy_nodes = 0;
|
||||||
@ -562,7 +626,7 @@ impl ClusterInfo {
|
|||||||
}
|
}
|
||||||
let ip_addr = node.gossip.ip();
|
let ip_addr = node.gossip.ip();
|
||||||
Some(format!(
|
Some(format!(
|
||||||
"{:15} {:2}| {:5} | {:44} |{:^9}| {:5}| {:5}| {:5}| {:5}| {:5}| {:5}| {:5}| {:5}| {:5}| {:5}| {}\n",
|
"{:15} {:2}| {:5} | {:44} |{:^9}| {:5}| {:5}| {:5}| {:5}| {:5}| {:5}| {:5}| {}\n",
|
||||||
if ContactInfo::is_valid_address(&node.gossip) {
|
if ContactInfo::is_valid_address(&node.gossip) {
|
||||||
ip_addr.to_string()
|
ip_addr.to_string()
|
||||||
} else {
|
} else {
|
||||||
@ -583,9 +647,6 @@ impl ClusterInfo {
|
|||||||
addr_to_string(&ip_addr, &node.tvu_forwards),
|
addr_to_string(&ip_addr, &node.tvu_forwards),
|
||||||
addr_to_string(&ip_addr, &node.repair),
|
addr_to_string(&ip_addr, &node.repair),
|
||||||
addr_to_string(&ip_addr, &node.serve_repair),
|
addr_to_string(&ip_addr, &node.serve_repair),
|
||||||
addr_to_string(&ip_addr, &node.rpc),
|
|
||||||
addr_to_string(&ip_addr, &node.rpc_pubsub),
|
|
||||||
addr_to_string(&ip_addr, &node.rpc_banks),
|
|
||||||
node.shred_version,
|
node.shred_version,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -594,9 +655,9 @@ impl ClusterInfo {
|
|||||||
|
|
||||||
format!(
|
format!(
|
||||||
"IP Address |Age(ms)| Node identifier \
|
"IP Address |Age(ms)| Node identifier \
|
||||||
| Version |Gossip| TPU |TPUfwd| TVU |TVUfwd|Repair|ServeR| RPC |PubSub|ShredVer\n\
|
| Version |Gossip| TPU |TPUfwd| TVU |TVUfwd|Repair|ServeR|ShredVer\n\
|
||||||
------------------+-------+----------------------------------------------+---------+\
|
------------------+-------+----------------------------------------------+---------+\
|
||||||
------+------+------+------+------+------+------+------+------+--------\n\
|
------+------+------+------+------+------+------+--------\n\
|
||||||
{}\
|
{}\
|
||||||
Nodes: {}{}{}",
|
Nodes: {}{}{}",
|
||||||
nodes.join(""),
|
nodes.join(""),
|
||||||
@ -1580,7 +1641,11 @@ impl ClusterInfo {
|
|||||||
thread_mem_usage::datapoint("solana-gossip");
|
thread_mem_usage::datapoint("solana-gossip");
|
||||||
if start - last_contact_info_trace > 10000 {
|
if start - last_contact_info_trace > 10000 {
|
||||||
// Log contact info every 10 seconds
|
// Log contact info every 10 seconds
|
||||||
info!("\n{}", self.contact_info_trace());
|
info!(
|
||||||
|
"\n{}\n\n{}",
|
||||||
|
self.contact_info_trace(),
|
||||||
|
self.rpc_info_trace()
|
||||||
|
);
|
||||||
last_contact_info_trace = start;
|
last_contact_info_trace = start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,11 +386,10 @@ impl Validator {
|
|||||||
if let Some((rpc_addr, rpc_pubsub_addr, rpc_banks_addr)) = config.rpc_addrs {
|
if let Some((rpc_addr, rpc_pubsub_addr, rpc_banks_addr)) = config.rpc_addrs {
|
||||||
if ContactInfo::is_valid_address(&node.info.rpc) {
|
if ContactInfo::is_valid_address(&node.info.rpc) {
|
||||||
assert!(ContactInfo::is_valid_address(&node.info.rpc_pubsub));
|
assert!(ContactInfo::is_valid_address(&node.info.rpc_pubsub));
|
||||||
assert_eq!(rpc_addr.port(), node.info.rpc.port());
|
assert!(ContactInfo::is_valid_address(&node.info.rpc_banks));
|
||||||
assert_eq!(rpc_pubsub_addr.port(), node.info.rpc_pubsub.port());
|
|
||||||
assert_eq!(rpc_banks_addr.port(), node.info.rpc_banks.port());
|
|
||||||
} else {
|
} else {
|
||||||
assert!(!ContactInfo::is_valid_address(&node.info.rpc_pubsub));
|
assert!(!ContactInfo::is_valid_address(&node.info.rpc_pubsub));
|
||||||
|
assert!(!ContactInfo::is_valid_address(&node.info.rpc_banks));
|
||||||
}
|
}
|
||||||
let tpu_address = cluster_info.my_contact_info().tpu;
|
let tpu_address = cluster_info.my_contact_info().tpu;
|
||||||
let (bank_notification_sender, bank_notification_receiver) = unbounded();
|
let (bank_notification_sender, bank_notification_receiver) = unbounded();
|
||||||
|
@ -154,7 +154,7 @@ fn get_rpc_node(
|
|||||||
let mut retry_reason = None;
|
let mut retry_reason = None;
|
||||||
loop {
|
loop {
|
||||||
sleep(Duration::from_secs(1));
|
sleep(Duration::from_secs(1));
|
||||||
info!("\n{}", cluster_info.contact_info_trace());
|
info!("\n{}", cluster_info.rpc_info_trace());
|
||||||
|
|
||||||
let shred_version = validator_config
|
let shred_version = validator_config
|
||||||
.expected_shred_version
|
.expected_shred_version
|
||||||
@ -1058,6 +1058,17 @@ pub fn main() {
|
|||||||
.help("IP address for the node to advertise in gossip when \
|
.help("IP address for the node to advertise in gossip when \
|
||||||
--entrypoint is not provided [default: 127.0.0.1]"),
|
--entrypoint is not provided [default: 127.0.0.1]"),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("public_rpc_addr")
|
||||||
|
.long("public-rpc-address")
|
||||||
|
.value_name("HOST:PORT")
|
||||||
|
.takes_value(true)
|
||||||
|
.conflicts_with("private_rpc")
|
||||||
|
.validator(solana_net_utils::is_host_port)
|
||||||
|
.help("RPC address for the node to advertise publicly in gossip. \
|
||||||
|
Useful for nodes running behind a load balancer or proxy \
|
||||||
|
[default: use --rpc-bind-address / --rpc-port]"),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("dynamic_port_range")
|
Arg::with_name("dynamic_port_range")
|
||||||
.long("dynamic-port-range")
|
.long("dynamic-port-range")
|
||||||
@ -1593,6 +1604,13 @@ pub fn main() {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let public_rpc_addr = matches.value_of("public_rpc_addr").map(|addr| {
|
||||||
|
solana_net_utils::parse_host_port(addr).unwrap_or_else(|e| {
|
||||||
|
eprintln!("failed to parse public rpc address: {}", e);
|
||||||
|
exit(1);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
let logfile = {
|
let logfile = {
|
||||||
let logfile = matches
|
let logfile = matches
|
||||||
.value_of("logfile")
|
.value_of("logfile")
|
||||||
@ -1668,7 +1686,12 @@ pub fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !private_rpc {
|
if !private_rpc {
|
||||||
if let Some((rpc_addr, rpc_pubsub_addr, rpc_banks_addr)) = validator_config.rpc_addrs {
|
if let Some(public_rpc_addr) = public_rpc_addr {
|
||||||
|
node.info.rpc = public_rpc_addr;
|
||||||
|
node.info.rpc_pubsub = public_rpc_addr;
|
||||||
|
node.info.rpc_banks = public_rpc_addr;
|
||||||
|
} else if let Some((rpc_addr, rpc_pubsub_addr, rpc_banks_addr)) = validator_config.rpc_addrs
|
||||||
|
{
|
||||||
node.info.rpc = SocketAddr::new(node.info.gossip.ip(), rpc_addr.port());
|
node.info.rpc = SocketAddr::new(node.info.gossip.ip(), rpc_addr.port());
|
||||||
node.info.rpc_pubsub = SocketAddr::new(node.info.gossip.ip(), rpc_pubsub_addr.port());
|
node.info.rpc_pubsub = SocketAddr::new(node.info.gossip.ip(), rpc_pubsub_addr.port());
|
||||||
node.info.rpc_banks = SocketAddr::new(node.info.gossip.ip(), rpc_banks_addr.port());
|
node.info.rpc_banks = SocketAddr::new(node.info.gossip.ip(), rpc_banks_addr.port());
|
||||||
|
Reference in New Issue
Block a user