Add show-stake-history command to cli (#6541)

This commit is contained in:
Justin Starry 2019-10-25 12:20:08 -04:00 committed by GitHub
parent 3879109e4c
commit 71ff269780
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 91 additions and 15 deletions

View File

@ -73,6 +73,9 @@ pub enum CliCommand {
DeactivateStake(Pubkey), DeactivateStake(Pubkey),
DelegateStake(Pubkey, Pubkey, bool), DelegateStake(Pubkey, Pubkey, bool),
RedeemVoteCredits(Pubkey, Pubkey), RedeemVoteCredits(Pubkey, Pubkey),
ShowStakeHistory {
use_lamports_unit: bool,
},
ShowStakeAccount { ShowStakeAccount {
pubkey: Pubkey, pubkey: Pubkey,
use_lamports_unit: bool, use_lamports_unit: bool,
@ -252,6 +255,7 @@ pub fn parse_command(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, Box<dyn
} }
("redeem-vote-credits", Some(matches)) => parse_redeem_vote_credits(matches), ("redeem-vote-credits", Some(matches)) => parse_redeem_vote_credits(matches),
("show-stake-account", Some(matches)) => parse_show_stake_account(matches), ("show-stake-account", Some(matches)) => parse_show_stake_account(matches),
("show-stake-history", Some(matches)) => parse_show_stake_history(matches),
// Storage Commands // Storage Commands
("create-archiver-storage-account", Some(matches)) => { ("create-archiver-storage-account", Some(matches)) => {
parse_storage_create_archiver_account(matches) parse_storage_create_archiver_account(matches)
@ -486,7 +490,7 @@ fn process_airdrop(
) -> ProcessResult { ) -> ProcessResult {
println!( println!(
"Requesting airdrop of {} from {}", "Requesting airdrop of {} from {}",
build_balance_message(lamports, use_lamports_unit), build_balance_message(lamports, use_lamports_unit, true),
drone_addr drone_addr
); );
let previous_balance = match rpc_client.retry_get_balance(&config.keypair.pubkey(), 5)? { let previous_balance = match rpc_client.retry_get_balance(&config.keypair.pubkey(), 5)? {
@ -505,7 +509,11 @@ fn process_airdrop(
.retry_get_balance(&config.keypair.pubkey(), 5)? .retry_get_balance(&config.keypair.pubkey(), 5)?
.unwrap_or(previous_balance); .unwrap_or(previous_balance);
Ok(build_balance_message(current_balance, use_lamports_unit)) Ok(build_balance_message(
current_balance,
use_lamports_unit,
true,
))
} }
fn process_balance( fn process_balance(
@ -517,7 +525,7 @@ fn process_balance(
let pubkey = pubkey.unwrap_or(config.keypair.pubkey()); let pubkey = pubkey.unwrap_or(config.keypair.pubkey());
let balance = rpc_client.retry_get_balance(&pubkey, 5)?; let balance = rpc_client.retry_get_balance(&pubkey, 5)?;
match balance { match balance {
Some(lamports) => Ok(build_balance_message(lamports, use_lamports_unit)), Some(lamports) => Ok(build_balance_message(lamports, use_lamports_unit, true)),
None => Err( None => Err(
CliError::RpcRequestError("Received result of an unexpected type".to_string()).into(), CliError::RpcRequestError("Received result of an unexpected type".to_string()).into(),
), ),
@ -553,7 +561,7 @@ fn process_show_account(
println_name_value("Public Key:", &account_pubkey.to_string()); println_name_value("Public Key:", &account_pubkey.to_string());
println_name_value( println_name_value(
"Balance:", "Balance:",
&build_balance_message(account.lamports, use_lamports_unit), &build_balance_message(account.lamports, use_lamports_unit, true),
); );
println_name_value("Owner:", &account.owner.to_string()); println_name_value("Owner:", &account.owner.to_string());
println_name_value("Executable:", &account.executable.to_string()); println_name_value("Executable:", &account.executable.to_string());
@ -877,6 +885,9 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
&stake_account_pubkey, &stake_account_pubkey,
*use_lamports_unit, *use_lamports_unit,
), ),
CliCommand::ShowStakeHistory { use_lamports_unit } => {
process_show_stake_history(&rpc_client, config, *use_lamports_unit)
}
CliCommand::StakeAuthorize( CliCommand::StakeAuthorize(
stake_account_pubkey, stake_account_pubkey,
new_authorized_pubkey, new_authorized_pubkey,
@ -1151,15 +1162,25 @@ where
} }
} }
pub(crate) fn build_balance_message(lamports: u64, use_lamports_unit: bool) -> String { pub(crate) fn build_balance_message(
lamports: u64,
use_lamports_unit: bool,
show_unit: bool,
) -> String {
if use_lamports_unit { if use_lamports_unit {
let ess = if lamports == 1 { "" } else { "s" }; let ess = if lamports == 1 { "" } else { "s" };
format!("{:?} lamport{}", lamports, ess) let unit = if show_unit {
format!(" lamport{}", ess)
} else {
"".to_string()
};
format!("{:?}{}", lamports, unit)
} else { } else {
let sol = lamports_to_sol(lamports); let sol = lamports_to_sol(lamports);
let sol_str = format!("{:.8}", sol); let sol_str = format!("{:.8}", sol);
let pretty_sol = sol_str.trim_end_matches('0').trim_end_matches('.'); let pretty_sol = sol_str.trim_end_matches('0').trim_end_matches('.');
format!("{} SOL", pretty_sol) let unit = if show_unit { " SOL" } else { "" };
format!("{}{}", pretty_sol, unit)
} }
} }

View File

@ -320,14 +320,14 @@ pub fn process_show_validators(rpc_client: &RpcClient, use_lamports_unit: bool)
println_name_value( println_name_value(
"Active Stake:", "Active Stake:",
&build_balance_message(total_active_stake as u64, use_lamports_unit), &build_balance_message(total_active_stake as u64, use_lamports_unit, true),
); );
if total_deliquent_stake > 0. { if total_deliquent_stake > 0. {
println_name_value( println_name_value(
"Current Stake:", "Current Stake:",
&format!( &format!(
"{} ({:0.2}%)", "{} ({:0.2}%)",
&build_balance_message(total_current_stake as u64, use_lamports_unit), &build_balance_message(total_current_stake as u64, use_lamports_unit, true),
100. * total_current_stake / total_active_stake 100. * total_current_stake / total_active_stake
), ),
); );
@ -335,7 +335,7 @@ pub fn process_show_validators(rpc_client: &RpcClient, use_lamports_unit: bool)
"Delinquent Stake:", "Delinquent Stake:",
&format!( &format!(
"{} ({:0.2}%)", "{} ({:0.2}%)",
&build_balance_message(total_deliquent_stake as u64, use_lamports_unit), &build_balance_message(total_deliquent_stake as u64, use_lamports_unit, true),
100. * total_deliquent_stake / total_active_stake 100. * total_deliquent_stake / total_active_stake
), ),
); );
@ -385,7 +385,7 @@ pub fn process_show_validators(rpc_client: &RpcClient, use_lamports_unit: bool)
if vote_account.activated_stake > 0 { if vote_account.activated_stake > 0 {
format!( format!(
"{} ({:.2}%)", "{} ({:.2}%)",
build_balance_message(vote_account.activated_stake, use_lamports_unit), build_balance_message(vote_account.activated_stake, use_lamports_unit, true),
100. * vote_account.activated_stake as f64 / total_active_stake 100. * vote_account.activated_stake as f64 / total_active_stake
) )
} else { } else {

View File

@ -8,9 +8,14 @@ use crate::{
input_validators::*, input_validators::*,
}; };
use clap::{App, Arg, ArgMatches, SubCommand}; use clap::{App, Arg, ArgMatches, SubCommand};
use console::style;
use solana_client::rpc_client::RpcClient; use solana_client::rpc_client::RpcClient;
use solana_sdk::{ use solana_sdk::{
account_utils::State, pubkey::Pubkey, signature::KeypairUtil, system_instruction::SystemError, account_utils::State,
pubkey::Pubkey,
signature::KeypairUtil,
system_instruction::SystemError,
sysvar::stake_history::{self, StakeHistory},
transaction::Transaction, transaction::Transaction,
}; };
use solana_stake_api::{ use solana_stake_api::{
@ -18,6 +23,7 @@ use solana_stake_api::{
stake_state::{Authorized, Lockup, StakeAuthorize, StakeState}, stake_state::{Authorized, Lockup, StakeAuthorize, StakeState},
}; };
use solana_vote_api::vote_state::VoteState; use solana_vote_api::vote_state::VoteState;
use std::ops::Deref;
pub trait StakeSubCommands { pub trait StakeSubCommands {
fn stake_subcommands(self) -> Self; fn stake_subcommands(self) -> Self;
@ -249,6 +255,16 @@ impl StakeSubCommands for App<'_, '_> {
.help("Display balance in lamports instead of SOL") .help("Display balance in lamports instead of SOL")
) )
) )
.subcommand(
SubCommand::with_name("show-stake-history")
.about("Show the stake history")
.arg(
Arg::with_name("lamports")
.long("lamports")
.takes_value(false)
.help("Display balance in lamports instead of SOL")
)
)
} }
} }
@ -344,6 +360,14 @@ pub fn parse_show_stake_account(matches: &ArgMatches<'_>) -> Result<CliCommandIn
}) })
} }
pub fn parse_show_stake_history(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let use_lamports_unit = matches.is_present("lamports");
Ok(CliCommandInfo {
command: CliCommand::ShowStakeHistory { use_lamports_unit },
require_keypair: false,
})
}
pub fn process_create_stake_account( pub fn process_create_stake_account(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &CliConfig, config: &CliConfig,
@ -527,12 +551,12 @@ pub fn process_show_stake_account(
Ok(StakeState::Stake(authorized, lockup, stake)) => { Ok(StakeState::Stake(authorized, lockup, stake)) => {
println!( println!(
"total stake: {}", "total stake: {}",
build_balance_message(stake_account.lamports, use_lamports_unit) build_balance_message(stake_account.lamports, use_lamports_unit, true)
); );
println!("credits observed: {}", stake.credits_observed); println!("credits observed: {}", stake.credits_observed);
println!( println!(
"delegated stake: {}", "delegated stake: {}",
build_balance_message(stake.stake, use_lamports_unit) build_balance_message(stake.stake, use_lamports_unit, true)
); );
if stake.voter_pubkey != Pubkey::default() { if stake.voter_pubkey != Pubkey::default() {
println!("delegated voter pubkey: {}", stake.voter_pubkey); println!("delegated voter pubkey: {}", stake.voter_pubkey);
@ -567,6 +591,37 @@ pub fn process_show_stake_account(
} }
} }
pub fn process_show_stake_history(
rpc_client: &RpcClient,
_config: &CliConfig,
use_lamports_unit: bool,
) -> ProcessResult {
let stake_history_account = rpc_client.get_account(&stake_history::id())?;
let stake_history = StakeHistory::from_account(&stake_history_account).unwrap();
println!();
println!(
"{}",
style(format!(
" {:<5} {:>15} {:>16} {:>18}",
"Epoch", "Effective Stake", "Activating Stake", "Deactivating Stake",
))
.bold()
);
for (epoch, entry) in stake_history.deref() {
println!(
" {:>5} {:>15} {:>16} {:>18} {}",
epoch,
build_balance_message(entry.effective, use_lamports_unit, false),
build_balance_message(entry.activating, use_lamports_unit, false),
build_balance_message(entry.deactivating, use_lamports_unit, false),
if use_lamports_unit { "lamports" } else { "SOL" }
);
}
Ok("".to_string())
}
pub fn process_delegate_stake( pub fn process_delegate_stake(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &CliConfig, config: &CliConfig,

View File

@ -334,7 +334,7 @@ pub fn process_show_vote_account(
println!( println!(
"account balance: {}", "account balance: {}",
build_balance_message(vote_account.lamports, use_lamports_unit) build_balance_message(vote_account.lamports, use_lamports_unit, true)
); );
println!("node id: {}", vote_state.node_pubkey); println!("node id: {}", vote_state.node_pubkey);
println!("authorized voter: {}", vote_state.authorized_voter); println!("authorized voter: {}", vote_state.authorized_voter);