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

Sub function getting vetted RPC nodes #30946

Merged
merged 2 commits into from
Mar 29, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 81 additions & 59 deletions validator/src/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,78 @@ pub fn attempt_download_genesis_and_snapshot(
Ok(())
}

// Populates `vetted_rpc_nodes` with a list of RPC nodes that are ready to be
// used for downloading latest snapshots and/or the genesis block. Guaranteed to
// find at least one viable node or terminate the process.
fn get_vetted_rpc_nodes(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And similarly to the previous comment, it'd be nice if this function returned the vetted rpc nodes, instead of mutating them internally. Nothing to do for this PR (maybe future ones though)!

vetted_rpc_nodes: &mut Vec<(ContactInfo, Option<SnapshotHash>, RpcClient)>,
gossip: &Option<(Arc<ClusterInfo>, Arc<AtomicBool>, GossipService)>,
bw-solana marked this conversation as resolved.
Show resolved Hide resolved
cluster_entrypoints: &[ContactInfo],
validator_config: &ValidatorConfig,
blacklisted_rpc_nodes: &RwLock<HashSet<Pubkey>>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well... this is unfortunate... I wish get_rpc_node() and fail_rpc_node() didn't modify blacklisted_rpc_nodes. I think for this PR the refactoring here is fine. Maybe future PRs can help clean this up!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked into this. Unfortunately, there is a place we might clear blacklisted_rpc_nodes that is deep in the depths of the call stack. Going to be really difficult to allow blacklisted_rpc_nodes to be immutable at this level.

Tried to improve things slightly by stripping the RwLock from blacklisted_rpc_nodes here: #30987

bootstrap_config: &RpcBootstrapConfig,
) {
while vetted_rpc_nodes.is_empty() {
let rpc_node_details = match get_rpc_nodes(
&gossip.as_ref().unwrap().0,
cluster_entrypoints,
validator_config,
&mut blacklisted_rpc_nodes.write().unwrap(),
bootstrap_config,
) {
Ok(rpc_node_details) => rpc_node_details,
Err(err) => {
error!(
"Failed to get RPC nodes: {err}. Consider checking system \
clock, removing `--no-port-check`, or adjusting \
`--known-validator ...` arguments as applicable"
);
exit(1);
}
};

vetted_rpc_nodes.extend(
rpc_node_details
.into_par_iter()
.map(|rpc_node_details| {
let GetRpcNodeResult {
rpc_contact_info,
snapshot_hash,
} = rpc_node_details;

info!(
"Using RPC service from node {}: {:?}",
rpc_contact_info.id, rpc_contact_info.rpc
);
let rpc_client = RpcClient::new_socket_with_timeout(
rpc_contact_info.rpc,
Duration::from_secs(5),
);

(rpc_contact_info, snapshot_hash, rpc_client)
})
.filter(|(rpc_contact_info, _snapshot_hash, rpc_client)| {
match rpc_client.get_version() {
Ok(rpc_version) => {
info!("RPC node version: {}", rpc_version.solana_core);
true
}
Err(err) => {
fail_rpc_node(
format!("Failed to get RPC node version: {err}"),
&validator_config.known_validators,
&rpc_contact_info.id,
&mut blacklisted_rpc_nodes.write().unwrap(),
);
false
}
}
})
.collect::<Vec<(ContactInfo, Option<SnapshotHash>, RpcClient)>>(),
);
}
}

#[allow(clippy::too_many_arguments)]
pub fn rpc_bootstrap(
node: &Node,
Expand Down Expand Up @@ -515,7 +587,7 @@ pub fn rpc_bootstrap(

let blacklisted_rpc_nodes = RwLock::new(HashSet::new());
let mut gossip = None;
let mut vetted_rpc_nodes: Vec<(ContactInfo, Option<SnapshotHash>, RpcClient)> = vec![];
let mut vetted_rpc_nodes = vec![];
let mut download_abort_count = 0;
loop {
if gossip.is_none() {
Expand All @@ -537,64 +609,14 @@ pub fn rpc_bootstrap(
));
}

while vetted_rpc_nodes.is_empty() {
let rpc_node_details = match get_rpc_nodes(
&gossip.as_ref().unwrap().0,
cluster_entrypoints,
validator_config,
&mut blacklisted_rpc_nodes.write().unwrap(),
&bootstrap_config,
) {
Ok(rpc_node_details) => rpc_node_details,
Err(err) => {
error!(
"Failed to get RPC nodes: {err}. Consider checking system \
clock, removing `--no-port-check`, or adjusting \
`--known-validator ...` arguments as applicable"
);
exit(1);
}
};

vetted_rpc_nodes = rpc_node_details
.into_par_iter()
.map(|rpc_node_details| {
let GetRpcNodeResult {
rpc_contact_info,
snapshot_hash,
} = rpc_node_details;

info!(
"Using RPC service from node {}: {:?}",
rpc_contact_info.id, rpc_contact_info.rpc
);
let rpc_client = RpcClient::new_socket_with_timeout(
rpc_contact_info.rpc,
Duration::from_secs(5),
);

(rpc_contact_info, snapshot_hash, rpc_client)
})
.filter(|(rpc_contact_info, _snapshot_hash, rpc_client)| {
match rpc_client.get_version() {
Ok(rpc_version) => {
info!("RPC node version: {}", rpc_version.solana_core);
true
}
Err(err) => {
fail_rpc_node(
format!("Failed to get RPC node version: {err}"),
&validator_config.known_validators,
&rpc_contact_info.id,
&mut blacklisted_rpc_nodes.write().unwrap(),
);
false
}
}
})
.collect();
}

get_vetted_rpc_nodes(
&mut vetted_rpc_nodes,
&gossip,
cluster_entrypoints,
validator_config,
&blacklisted_rpc_nodes,
&bootstrap_config,
);
let (rpc_contact_info, snapshot_hash, rpc_client) = vetted_rpc_nodes.pop().unwrap();

match attempt_download_genesis_and_snapshot(
Expand Down