Add skip rate to `solana validators`
This commit is contained in:
parent
542d88929f
commit
d640ac143b
|
@ -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",
|
||||
"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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue