2020-09-30 20:17:29 -07:00
|
|
|
use crate::cli::{CliCommand, CliCommandInfo, CliConfig, CliError, ProcessResult};
|
2021-04-08 09:57:33 -07:00
|
|
|
use clap::{App, Arg, ArgMatches, SubCommand};
|
|
|
|
use solana_clap_utils::{
|
|
|
|
input_parsers::{pubkeys_of, value_of},
|
|
|
|
input_validators::is_valid_pubkey,
|
|
|
|
keypair::*,
|
|
|
|
};
|
|
|
|
use solana_cli_output::{
|
|
|
|
CliEpochRewardshMetadata, CliInflation, CliKeyedEpochReward, CliKeyedEpochRewards,
|
|
|
|
};
|
2020-09-30 20:17:29 -07:00
|
|
|
use solana_client::rpc_client::RpcClient;
|
|
|
|
use solana_remote_wallet::remote_wallet::RemoteWalletManager;
|
2021-04-08 09:57:33 -07:00
|
|
|
use solana_sdk::{clock::Epoch, pubkey::Pubkey};
|
2020-09-30 20:17:29 -07:00
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum InflationCliCommand {
|
|
|
|
Show,
|
2021-04-08 09:57:33 -07:00
|
|
|
Rewards(Vec<Pubkey>, Option<Epoch>),
|
2020-09-30 20:17:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait InflationSubCommands {
|
|
|
|
fn inflation_subcommands(self) -> Self;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl InflationSubCommands for App<'_, '_> {
|
|
|
|
fn inflation_subcommands(self) -> Self {
|
2021-04-08 09:57:33 -07:00
|
|
|
self.subcommand(
|
|
|
|
SubCommand::with_name("inflation")
|
|
|
|
.about("Show inflation information")
|
|
|
|
.subcommand(
|
|
|
|
SubCommand::with_name("rewards")
|
|
|
|
.about("Show inflation rewards for a set of addresses")
|
|
|
|
.arg(pubkey!(
|
|
|
|
Arg::with_name("addresses")
|
|
|
|
.value_name("ADDRESS")
|
|
|
|
.index(1)
|
|
|
|
.multiple(true)
|
|
|
|
.required(true),
|
|
|
|
"Address of account to query for rewards. "
|
|
|
|
))
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("rewards_epoch")
|
|
|
|
.long("rewards-epoch")
|
|
|
|
.takes_value(true)
|
|
|
|
.value_name("EPOCH")
|
|
|
|
.help("Display rewards for specific epoch [default: latest epoch]"),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
)
|
2020-09-30 20:17:29 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn parse_inflation_subcommand(
|
2021-04-08 09:57:33 -07:00
|
|
|
matches: &ArgMatches<'_>,
|
2020-09-30 20:17:29 -07:00
|
|
|
_default_signer: &DefaultSigner,
|
|
|
|
_wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
|
|
|
|
) -> Result<CliCommandInfo, CliError> {
|
2021-04-08 09:57:33 -07:00
|
|
|
let command = match matches.subcommand() {
|
|
|
|
("rewards", Some(matches)) => {
|
|
|
|
let addresses = pubkeys_of(matches, "addresses").unwrap();
|
|
|
|
let rewards_epoch = value_of(matches, "rewards_epoch");
|
|
|
|
InflationCliCommand::Rewards(addresses, rewards_epoch)
|
|
|
|
}
|
|
|
|
_ => InflationCliCommand::Show,
|
|
|
|
};
|
2020-09-30 20:17:29 -07:00
|
|
|
Ok(CliCommandInfo {
|
2021-04-08 09:57:33 -07:00
|
|
|
command: CliCommand::Inflation(command),
|
2020-09-30 20:17:29 -07:00
|
|
|
signers: vec![],
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn process_inflation_subcommand(
|
|
|
|
rpc_client: &RpcClient,
|
2021-01-09 16:02:22 -08:00
|
|
|
config: &CliConfig,
|
2020-09-30 20:17:29 -07:00
|
|
|
inflation_subcommand: &InflationCliCommand,
|
|
|
|
) -> ProcessResult {
|
2021-04-08 09:57:33 -07:00
|
|
|
match inflation_subcommand {
|
|
|
|
InflationCliCommand::Show => process_show(rpc_client, config),
|
|
|
|
InflationCliCommand::Rewards(ref addresses, rewards_epoch) => {
|
|
|
|
process_rewards(rpc_client, config, addresses, *rewards_epoch)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-09-30 20:17:29 -07:00
|
|
|
|
2021-04-08 09:57:33 -07:00
|
|
|
fn process_show(rpc_client: &RpcClient, config: &CliConfig) -> ProcessResult {
|
2020-09-30 20:17:29 -07:00
|
|
|
let governor = rpc_client.get_inflation_governor()?;
|
2021-01-09 16:02:22 -08:00
|
|
|
let current_rate = rpc_client.get_inflation_rate()?;
|
2020-09-30 20:17:29 -07:00
|
|
|
|
2021-01-09 16:02:22 -08:00
|
|
|
let inflation = CliInflation {
|
|
|
|
governor,
|
|
|
|
current_rate,
|
|
|
|
};
|
2020-09-30 20:17:29 -07:00
|
|
|
|
2021-01-09 16:02:22 -08:00
|
|
|
Ok(config.output_format.formatted_string(&inflation))
|
2020-09-30 20:17:29 -07:00
|
|
|
}
|
2021-04-08 09:57:33 -07:00
|
|
|
|
|
|
|
fn process_rewards(
|
|
|
|
rpc_client: &RpcClient,
|
|
|
|
config: &CliConfig,
|
|
|
|
addresses: &[Pubkey],
|
|
|
|
rewards_epoch: Option<Epoch>,
|
|
|
|
) -> ProcessResult {
|
|
|
|
let rewards = rpc_client
|
2021-06-18 06:34:46 -07:00
|
|
|
.get_inflation_reward(addresses, rewards_epoch)
|
2021-04-08 09:57:33 -07:00
|
|
|
.map_err(|err| {
|
|
|
|
if let Some(epoch) = rewards_epoch {
|
|
|
|
format!("Rewards not available for epoch {}", epoch)
|
|
|
|
} else {
|
|
|
|
format!("Rewards not available {}", err)
|
|
|
|
}
|
|
|
|
})?;
|
|
|
|
let epoch_schedule = rpc_client.get_epoch_schedule()?;
|
|
|
|
|
|
|
|
let mut epoch_rewards: Vec<CliKeyedEpochReward> = vec![];
|
|
|
|
let epoch_metadata = if let Some(Some(first_reward)) = rewards.iter().find(|&v| v.is_some()) {
|
|
|
|
let (epoch_start_time, epoch_end_time) =
|
|
|
|
crate::stake::get_epoch_boundary_timestamps(rpc_client, first_reward, &epoch_schedule)?;
|
|
|
|
for (reward, address) in rewards.iter().zip(addresses) {
|
|
|
|
let cli_reward = reward.as_ref().and_then(|reward| {
|
|
|
|
crate::stake::make_cli_reward(reward, epoch_start_time, epoch_end_time)
|
|
|
|
});
|
|
|
|
epoch_rewards.push(CliKeyedEpochReward {
|
|
|
|
address: address.to_string(),
|
|
|
|
reward: cli_reward,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
let block_time = rpc_client.get_block_time(first_reward.effective_slot)?;
|
|
|
|
Some(CliEpochRewardshMetadata {
|
|
|
|
epoch: first_reward.epoch,
|
|
|
|
effective_slot: first_reward.effective_slot,
|
|
|
|
block_time,
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
let cli_rewards = CliKeyedEpochRewards {
|
|
|
|
epoch_metadata,
|
|
|
|
rewards: epoch_rewards,
|
|
|
|
};
|
|
|
|
Ok(config.output_format.formatted_string(&cli_rewards))
|
|
|
|
}
|