Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

validator: Ensure get_rpc_addr() doesn't return a dead RPC address #7843

Closed
mvines opened this issue Jan 16, 2020 · 0 comments · Fixed by #7869
Closed

validator: Ensure get_rpc_addr() doesn't return a dead RPC address #7843

mvines opened this issue Jan 16, 2020 · 0 comments · Fixed by #7869
Assignees

Comments

@mvines
Copy link
Contributor

mvines commented Jan 16, 2020

When a validator joins gossip, there's no guarantee that its ports are truly accessible to all other network participants. This can cause trouble for a validator that is attempting to boot, and selects an advertised RPC address that is blocked.

A recent PR, #7759, improved this situation slightly be we need to do better by checking that a connection can be successfully established to the selected RPC address in

fn get_rpc_addr(
node: &Node,
identity_keypair: &Arc<Keypair>,
entrypoint_gossip: &SocketAddr,
) -> (Pubkey, SocketAddr) {
let mut cluster_info = ClusterInfo::new(node.info.clone(), identity_keypair.clone());
cluster_info.set_entrypoint(ContactInfo::new_gossip_entry_point(entrypoint_gossip));
let cluster_info = Arc::new(RwLock::new(cluster_info));
let exit = Arc::new(AtomicBool::new(false));
let gossip_service = GossipService::new(
&cluster_info.clone(),
None,
None,
node.sockets.gossip.try_clone().unwrap(),
&exit,
);
let (id, rpc_addr) = loop {
info!(
"Searching for RPC service...\n{}",
cluster_info.read().unwrap().contact_info_trace()
);
let (gossip_peers, rpc_peers) = {
let cluster_info = cluster_info.read().unwrap();
(cluster_info.gossip_peers(), cluster_info.rpc_peers())
};
let found_entrypoint = gossip_peers
.iter()
.any(|contact_info| contact_info.gossip == *entrypoint_gossip);
if found_entrypoint & !rpc_peers.is_empty() {
// Prefer the entrypoint's RPC service if present, otherwise pick a node at random
if let Some(contact_info) = rpc_peers
.iter()
.find(|contact_info| contact_info.gossip == *entrypoint_gossip)
{
break (contact_info.id, contact_info.rpc);
}
let i = thread_rng().gen_range(0, rpc_peers.len());
break (rpc_peers[i].id, rpc_peers[i].rpc);
}
sleep(Duration::from_secs(1));
};
exit.store(true, Ordering::Relaxed);
gossip_service.join().unwrap();
(id, rpc_addr)
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant