CLI: Add calculate-rent
subcommand
This commit is contained in:
committed by
Trent Nelson
parent
2820d0a23d
commit
12410541a4
@ -123,6 +123,10 @@ pub enum CliCommand {
|
|||||||
blockhash: Option<Hash>,
|
blockhash: Option<Hash>,
|
||||||
print_timestamp: bool,
|
print_timestamp: bool,
|
||||||
},
|
},
|
||||||
|
Rent {
|
||||||
|
data_length: usize,
|
||||||
|
use_lamports_unit: bool,
|
||||||
|
},
|
||||||
ShowBlockProduction {
|
ShowBlockProduction {
|
||||||
epoch: Option<Epoch>,
|
epoch: Option<Epoch>,
|
||||||
slot_limit: Option<u64>,
|
slot_limit: Option<u64>,
|
||||||
@ -864,6 +868,17 @@ pub fn parse_command(
|
|||||||
signers: signer_info.signers,
|
signers: signer_info.signers,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
("rent", Some(matches)) => {
|
||||||
|
let data_length = value_of(matches, "data_length").unwrap();
|
||||||
|
let use_lamports_unit = matches.is_present("lamports");
|
||||||
|
Ok(CliCommandInfo {
|
||||||
|
command: CliCommand::Rent {
|
||||||
|
data_length,
|
||||||
|
use_lamports_unit,
|
||||||
|
},
|
||||||
|
signers: vec![],
|
||||||
|
})
|
||||||
|
}
|
||||||
//
|
//
|
||||||
("", None) => {
|
("", None) => {
|
||||||
eprintln!("{}", matches.usage());
|
eprintln!("{}", matches.usage());
|
||||||
@ -1172,7 +1187,6 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
|
|||||||
// Cluster Query Commands
|
// Cluster Query Commands
|
||||||
// Get address of this client
|
// Get address of this client
|
||||||
CliCommand::Address => Ok(format!("{}", config.pubkey()?)),
|
CliCommand::Address => Ok(format!("{}", config.pubkey()?)),
|
||||||
|
|
||||||
// Return software version of solana-cli and cluster entrypoint node
|
// Return software version of solana-cli and cluster entrypoint node
|
||||||
CliCommand::Catchup {
|
CliCommand::Catchup {
|
||||||
node_pubkey,
|
node_pubkey,
|
||||||
@ -1237,6 +1251,10 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
|
|||||||
blockhash,
|
blockhash,
|
||||||
*print_timestamp,
|
*print_timestamp,
|
||||||
),
|
),
|
||||||
|
CliCommand::Rent {
|
||||||
|
data_length,
|
||||||
|
use_lamports_unit,
|
||||||
|
} => process_calculate_rent(&rpc_client, config, *data_length, *use_lamports_unit),
|
||||||
CliCommand::ShowBlockProduction { epoch, slot_limit } => {
|
CliCommand::ShowBlockProduction { epoch, slot_limit } => {
|
||||||
process_show_block_production(&rpc_client, config, *epoch, *slot_limit)
|
process_show_block_production(&rpc_client, config, *epoch, *slot_limit)
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ use crate::{
|
|||||||
use chrono::{Local, TimeZone};
|
use chrono::{Local, TimeZone};
|
||||||
use clap::{value_t, value_t_or_exit, App, AppSettings, Arg, ArgMatches, SubCommand};
|
use clap::{value_t, value_t_or_exit, App, AppSettings, Arg, ArgMatches, SubCommand};
|
||||||
use console::{style, Emoji};
|
use console::{style, Emoji};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use solana_clap_utils::{
|
use solana_clap_utils::{
|
||||||
input_parsers::*,
|
input_parsers::*,
|
||||||
input_validators::*,
|
input_validators::*,
|
||||||
@ -14,7 +15,8 @@ use solana_clap_utils::{
|
|||||||
};
|
};
|
||||||
use solana_cli_output::{
|
use solana_cli_output::{
|
||||||
display::{
|
display::{
|
||||||
format_labeled_address, new_spinner_progress_bar, println_name_value, println_transaction,
|
build_balance_message, format_labeled_address, new_spinner_progress_bar,
|
||||||
|
println_name_value, println_transaction, writeln_name_value,
|
||||||
},
|
},
|
||||||
*,
|
*,
|
||||||
};
|
};
|
||||||
@ -40,6 +42,7 @@ use solana_sdk::{
|
|||||||
message::Message,
|
message::Message,
|
||||||
native_token::lamports_to_sol,
|
native_token::lamports_to_sol,
|
||||||
pubkey::{self, Pubkey},
|
pubkey::{self, Pubkey},
|
||||||
|
rent::Rent,
|
||||||
rpc_port::DEFAULT_RPC_PORT_STR,
|
rpc_port::DEFAULT_RPC_PORT_STR,
|
||||||
signature::Signature,
|
signature::Signature,
|
||||||
system_instruction, system_program,
|
system_instruction, system_program,
|
||||||
@ -47,11 +50,13 @@ use solana_sdk::{
|
|||||||
self,
|
self,
|
||||||
stake_history::{self},
|
stake_history::{self},
|
||||||
},
|
},
|
||||||
|
timing,
|
||||||
transaction::Transaction,
|
transaction::Transaction,
|
||||||
};
|
};
|
||||||
use solana_transaction_status::UiTransactionEncoding;
|
use solana_transaction_status::UiTransactionEncoding;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeMap, HashMap, VecDeque},
|
collections::{BTreeMap, HashMap, VecDeque},
|
||||||
|
fmt,
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicBool, Ordering},
|
atomic::{AtomicBool, Ordering},
|
||||||
@ -376,6 +381,23 @@ impl ClusterQuerySubCommands for App<'_, '_> {
|
|||||||
.index(1),
|
.index(1),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.subcommand(
|
||||||
|
SubCommand::with_name("rent")
|
||||||
|
.about("Calculate per-epoch and rent-exempt-minimum values for a given account data length.")
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("data_length")
|
||||||
|
.index(1)
|
||||||
|
.value_name("DATA_LENGTH")
|
||||||
|
.required(true)
|
||||||
|
.help("Length of data in the account to calculate rent for"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("lamports")
|
||||||
|
.long("lamports")
|
||||||
|
.takes_value(false)
|
||||||
|
.help("Display rent in lamports instead of SOL"),
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1827,6 +1849,62 @@ pub fn process_transaction_history(
|
|||||||
Ok(transactions_found)
|
Ok(transactions_found)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct CliRentCalculation {
|
||||||
|
pub lamports_per_byte_year: u64,
|
||||||
|
pub lamports_per_epoch: u64,
|
||||||
|
pub rent_exempt_minimum_lamports: u64,
|
||||||
|
#[serde(skip)]
|
||||||
|
pub use_lamports_unit: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CliRentCalculation {
|
||||||
|
fn build_balance_message(&self, lamports: u64) -> String {
|
||||||
|
build_balance_message(lamports, self.use_lamports_unit, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for CliRentCalculation {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let per_byte_year = self.build_balance_message(self.lamports_per_byte_year);
|
||||||
|
let per_epoch = self.build_balance_message(self.lamports_per_epoch);
|
||||||
|
let exempt_minimum = self.build_balance_message(self.rent_exempt_minimum_lamports);
|
||||||
|
writeln_name_value(f, "Rent per byte-year:", &per_byte_year)?;
|
||||||
|
writeln_name_value(f, "Rent per epoch:", &per_epoch)?;
|
||||||
|
writeln_name_value(f, "Rent-exempt minimum:", &exempt_minimum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QuietDisplay for CliRentCalculation {}
|
||||||
|
impl VerboseDisplay for CliRentCalculation {}
|
||||||
|
|
||||||
|
pub fn process_calculate_rent(
|
||||||
|
rpc_client: &RpcClient,
|
||||||
|
config: &CliConfig,
|
||||||
|
data_length: usize,
|
||||||
|
use_lamports_unit: bool,
|
||||||
|
) -> ProcessResult {
|
||||||
|
let epoch_schedule = rpc_client.get_epoch_schedule()?;
|
||||||
|
let rent_account = rpc_client.get_account(&sysvar::rent::id())?;
|
||||||
|
let rent: Rent = rent_account.deserialize_data()?;
|
||||||
|
let rent_exempt_minimum_lamports = rent.minimum_balance(data_length);
|
||||||
|
let seconds_per_tick = Duration::from_secs_f64(1.0 / clock::DEFAULT_TICKS_PER_SECOND as f64);
|
||||||
|
let slots_per_year =
|
||||||
|
timing::years_as_slots(1.0, &seconds_per_tick, clock::DEFAULT_TICKS_PER_SLOT);
|
||||||
|
let slots_per_epoch = epoch_schedule.slots_per_epoch as f64;
|
||||||
|
let years_per_epoch = slots_per_epoch / slots_per_year;
|
||||||
|
let (lamports_per_epoch, _) = rent.due(0, data_length, years_per_epoch);
|
||||||
|
let cli_rent_calculation = CliRentCalculation {
|
||||||
|
lamports_per_byte_year: rent.lamports_per_byte_year,
|
||||||
|
lamports_per_epoch,
|
||||||
|
rent_exempt_minimum_lamports,
|
||||||
|
use_lamports_unit,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(config.output_format.formatted_string(&cli_rent_calculation))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
Reference in New Issue
Block a user