Add skip rate to `solana validators`

This commit is contained in:
Michael Vines 2021-04-27 17:46:36 -07:00
parent 542d88929f
commit d640ac143b
2 changed files with 73 additions and 7 deletions

View File

@ -311,6 +311,7 @@ pub enum CliValidatorsSortOrder {
Identity,
LastVote,
Root,
SkipRate,
Stake,
VoteAccount,
}
@ -360,7 +361,7 @@ impl fmt::Display for CliValidators {
writeln!(
f,
"{} {:<44} {:<44} {:>3}% {:>14} {:>14} {:>13} {:>7} {}",
"{} {:<44} {:<44} {:>3}% {:>14} {:>14} {:>7} {:>8} {:>7} {}",
if validator.delinquent {
WARNING.to_string()
} else {
@ -371,6 +372,11 @@ impl fmt::Display for CliValidators {
validator.commission,
non_zero_or_dash(validator.last_vote, highest_last_vote),
non_zero_or_dash(validator.root_slot, highest_root),
if let Some(skip_rate) = validator.skip_rate {
format!("{:.2}%", skip_rate)
} else {
"- ".to_string()
},
validator.epoch_credits,
validator.version,
if validator.activated_stake > 0 {
@ -391,14 +397,15 @@ impl fmt::Display for CliValidators {
0
};
let header = style(format!(
"{:padding$} {:<44} {:<38} {} {} {} {:>11} {:^7} {}",
"{:padding$} {:<44} {:<38} {} {} {} {} {} {} {}",
" ",
"Identity",
"Vote Account",
"Commission",
"Last Vote ",
"Root Slot ",
"Epoch Credits",
"Last Vote ",
"Root Slot ",
"Skip Rate",
"Credits",
"Version",
"Active Stake",
padding = padding + 1
@ -429,6 +436,17 @@ impl fmt::Display for CliValidators {
CliValidatorsSortOrder::VoteAccount => {
sorted_validators.sort_by(|a, b| a.vote_account_pubkey.cmp(&b.vote_account_pubkey));
}
CliValidatorsSortOrder::SkipRate => {
sorted_validators.sort_by(|a, b| {
use std::cmp::Ordering;
match (a.skip_rate, b.skip_rate) {
(None, None) => Ordering::Equal,
(None, Some(_)) => Ordering::Greater,
(Some(_), None) => Ordering::Less,
(Some(a), Some(b)) => a.partial_cmp(&b).unwrap_or(Ordering::Equal),
}
});
}
CliValidatorsSortOrder::Stake => {
sorted_validators.sort_by_key(|a| a.activated_stake);
}
@ -537,6 +555,7 @@ pub struct CliValidator {
pub activated_stake: u64,
pub version: String,
pub delinquent: bool,
pub skip_rate: Option<f64>,
}
impl CliValidator {
@ -544,24 +563,41 @@ impl CliValidator {
vote_account: &RpcVoteAccountInfo,
current_epoch: Epoch,
version: String,
skip_rate: Option<f64>,
address_labels: &HashMap<String, String>,
) -> Self {
Self::_new(vote_account, current_epoch, version, address_labels, false)
Self::_new(
vote_account,
current_epoch,
version,
skip_rate,
address_labels,
false,
)
}
pub fn new_delinquent(
vote_account: &RpcVoteAccountInfo,
current_epoch: Epoch,
version: String,
skip_rate: Option<f64>,
address_labels: &HashMap<String, String>,
) -> Self {
Self::_new(vote_account, current_epoch, version, address_labels, true)
Self::_new(
vote_account,
current_epoch,
version,
skip_rate,
address_labels,
true,
)
}
fn _new(
vote_account: &RpcVoteAccountInfo,
current_epoch: Epoch,
version: String,
skip_rate: Option<f64>,
address_labels: &HashMap<String, String>,
delinquent: bool,
) -> Self {
@ -587,6 +623,7 @@ impl CliValidator {
activated_stake: vote_account.activated_stake,
version,
delinquent,
skip_rate,
}
}
}

View File

@ -376,6 +376,7 @@ impl ClusterQuerySubCommands for App<'_, '_> {
"identity",
"last-vote",
"root",
"skip-rate",
"stake",
"vote-account",
])
@ -624,6 +625,7 @@ pub fn parse_show_validators(matches: &ArgMatches<'_>) -> Result<CliCommandInfo,
"identity" => CliValidatorsSortOrder::Identity,
"last-vote" => CliValidatorsSortOrder::LastVote,
"root" => CliValidatorsSortOrder::Root,
"skip-rate" => CliValidatorsSortOrder::SkipRate,
"stake" => CliValidatorsSortOrder::Stake,
"vote-account" => CliValidatorsSortOrder::VoteAccount,
_ => unreachable!(),
@ -1811,9 +1813,32 @@ pub fn process_show_validators(
validators_reverse_sort: bool,
number_validators: bool,
) -> ProcessResult {
let progress_bar = new_spinner_progress_bar();
progress_bar.set_message("Fetching vote accounts...");
let epoch_info = rpc_client.get_epoch_info()?;
let vote_accounts = rpc_client.get_vote_accounts()?;
progress_bar.set_message("Fetching block production...");
let skip_rate: HashMap<_, _> = rpc_client
.get_block_production()
.ok()
.map(|result| {
result
.value
.by_identity
.into_iter()
.map(|(identity, (leader_slots, blocks_produced))| {
(
identity,
100. * (leader_slots.saturating_sub(blocks_produced)) as f64
/ leader_slots as f64,
)
})
.collect()
})
.unwrap_or_default();
progress_bar.set_message("Fetching version information...");
let mut node_version = HashMap::new();
let unknown_version = "unknown".to_string();
for contact_info in rpc_client.get_cluster_nodes()? {
@ -1825,6 +1850,8 @@ pub fn process_show_validators(
);
}
progress_bar.finish_and_clear();
let total_active_stake = vote_accounts
.current
.iter()
@ -1850,6 +1877,7 @@ pub fn process_show_validators(
.get(&vote_account.node_pubkey)
.unwrap_or(&unknown_version)
.clone(),
skip_rate.get(&vote_account.node_pubkey).cloned(),
&config.address_labels,
)
})
@ -1865,6 +1893,7 @@ pub fn process_show_validators(
.get(&vote_account.node_pubkey)
.unwrap_or(&unknown_version)
.clone(),
skip_rate.get(&vote_account.node_pubkey).cloned(),
&config.address_labels,
)
})