solana ping: add --blockhash and --print-timestamp (#13980)

* solana ping: add --blockhash and --print-timestamp

* fix typo in hash...
This commit is contained in:
Ryo Onodera
2020-12-07 21:10:50 +09:00
committed by GitHub
parent 9da3de5861
commit 26df122386
2 changed files with 82 additions and 10 deletions

View File

@ -128,6 +128,8 @@ pub enum CliCommand {
interval: Duration, interval: Duration,
count: Option<u64>, count: Option<u64>,
timeout: Duration, timeout: Duration,
blockhash: Option<Hash>,
print_timestamp: bool,
}, },
ShowBlockProduction { ShowBlockProduction {
epoch: Option<Epoch>, epoch: Option<Epoch>,
@ -1570,7 +1572,18 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
interval, interval,
count, count,
timeout, timeout,
} => process_ping(&rpc_client, config, *lamports, interval, count, timeout), blockhash,
print_timestamp,
} => process_ping(
&rpc_client,
config,
*lamports,
interval,
count,
timeout,
blockhash,
*print_timestamp,
),
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)
} }

View File

@ -11,6 +11,7 @@ use solana_clap_utils::{
input_parsers::*, input_parsers::*,
input_validators::*, input_validators::*,
keypair::DefaultSigner, keypair::DefaultSigner,
offline::{blockhash_arg, BLOCKHASH_ARG},
}; };
use solana_cli_output::{ use solana_cli_output::{
display::{ display::{
@ -36,6 +37,7 @@ use solana_sdk::{
clock::{self, Clock, Slot}, clock::{self, Clock, Slot},
commitment_config::CommitmentConfig, commitment_config::CommitmentConfig,
epoch_schedule::Epoch, epoch_schedule::Epoch,
hash::Hash,
message::Message, message::Message,
native_token::lamports_to_sol, native_token::lamports_to_sol,
pubkey::{self, Pubkey}, pubkey::{self, Pubkey},
@ -56,7 +58,7 @@ use std::{
Arc, Arc,
}, },
thread::sleep, thread::sleep,
time::{Duration, Instant}, time::{Duration, Instant, SystemTime, UNIX_EPOCH},
}; };
static CHECK_MARK: Emoji = Emoji("", ""); static CHECK_MARK: Emoji = Emoji("", "");
@ -212,6 +214,13 @@ impl ClusterQuerySubCommands for App<'_, '_> {
.takes_value(true) .takes_value(true)
.help("Stop after submitting count transactions"), .help("Stop after submitting count transactions"),
) )
.arg(
Arg::with_name("print_timestamp")
.short("D")
.long("print-timestamp")
.takes_value(false)
.help("Print timestamp (unix time + microseconds as in gettimeofday) before each line"),
)
.arg( .arg(
Arg::with_name("lamports") Arg::with_name("lamports")
.long("lamports") .long("lamports")
@ -230,6 +239,7 @@ impl ClusterQuerySubCommands for App<'_, '_> {
.default_value("15") .default_value("15")
.help("Wait up to timeout seconds for transaction confirmation"), .help("Wait up to timeout seconds for transaction confirmation"),
) )
.arg(blockhash_arg())
.arg(commitment_arg()), .arg(commitment_arg()),
) )
.subcommand( .subcommand(
@ -385,12 +395,16 @@ pub fn parse_cluster_ping(
None None
}; };
let timeout = Duration::from_secs(value_t_or_exit!(matches, "timeout", u64)); let timeout = Duration::from_secs(value_t_or_exit!(matches, "timeout", u64));
let blockhash = value_of(matches, BLOCKHASH_ARG.name);
let print_timestamp = matches.is_present("print_timestamp");
Ok(CliCommandInfo { Ok(CliCommandInfo {
command: CliCommand::Ping { command: CliCommand::Ping {
lamports, lamports,
interval, interval,
count, count,
timeout, timeout,
blockhash,
print_timestamp,
}, },
signers: vec![default_signer.signer_from_path(matches, wallet_manager)?], signers: vec![default_signer.signer_from_path(matches, wallet_manager)?],
}) })
@ -1060,6 +1074,8 @@ pub fn process_ping(
interval: &Duration, interval: &Duration,
count: &Option<u64>, count: &Option<u64>,
timeout: &Duration, timeout: &Duration,
fixed_blockhash: &Option<Hash>,
print_timestamp: bool,
) -> ProcessResult { ) -> ProcessResult {
println_name_value("Source Account:", &config.signers[0].pubkey().to_string()); println_name_value("Source Account:", &config.signers[0].pubkey().to_string());
println!(); println!();
@ -1077,9 +1093,21 @@ pub fn process_ping(
let (mut blockhash, mut fee_calculator) = rpc_client.get_recent_blockhash()?; let (mut blockhash, mut fee_calculator) = rpc_client.get_recent_blockhash()?;
let mut blockhash_transaction_count = 0; let mut blockhash_transaction_count = 0;
let mut blockhash_acquired = Instant::now(); let mut blockhash_acquired = Instant::now();
if let Some(fixed_blockhash) = fixed_blockhash {
let blockhash_origin = if *fixed_blockhash != Hash::default() {
blockhash = *fixed_blockhash;
"supplied from cli arguments"
} else {
"fetched from cluster"
};
println!(
"Fixed blockhash is used: {} ({})",
blockhash, blockhash_origin
);
}
'mainloop: for seq in 0..count.unwrap_or(std::u64::MAX) { 'mainloop: for seq in 0..count.unwrap_or(std::u64::MAX) {
let now = Instant::now(); let now = Instant::now();
if now.duration_since(blockhash_acquired).as_secs() > 60 { if fixed_blockhash.is_none() && now.duration_since(blockhash_acquired).as_secs() > 60 {
// Fetch a new blockhash every minute // Fetch a new blockhash every minute
let (new_blockhash, new_fee_calculator) = rpc_client.get_new_blockhash(&blockhash)?; let (new_blockhash, new_fee_calculator) = rpc_client.get_new_blockhash(&blockhash)?;
blockhash = new_blockhash; blockhash = new_blockhash;
@ -1110,6 +1138,18 @@ pub fn process_ping(
let mut tx = Transaction::new_unsigned(message); let mut tx = Transaction::new_unsigned(message);
tx.try_sign(&config.signers, blockhash)?; tx.try_sign(&config.signers, blockhash)?;
let timestamp = || {
let micros = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_micros();
if print_timestamp {
format!("[{}.{:06}] ", micros / 1_000_000, micros % 1_000_000)
} else {
format!("")
}
};
match rpc_client.send_transaction(&tx) { match rpc_client.send_transaction(&tx) {
Ok(signature) => { Ok(signature) => {
let transaction_sent = Instant::now(); let transaction_sent = Instant::now();
@ -1123,15 +1163,20 @@ pub fn process_ping(
let elapsed_time_millis = elapsed_time.as_millis() as u64; let elapsed_time_millis = elapsed_time.as_millis() as u64;
confirmation_time.push_back(elapsed_time_millis); confirmation_time.push_back(elapsed_time_millis);
println!( println!(
"{}{} lamport(s) transferred: seq={:<3} time={:>4}ms signature={}", "{}{}{} lamport(s) transferred: seq={:<3} time={:>4}ms signature={}",
timestamp(),
CHECK_MARK, lamports, seq, elapsed_time_millis, signature CHECK_MARK, lamports, seq, elapsed_time_millis, signature
); );
confirmed_count += 1; confirmed_count += 1;
} }
Err(err) => { Err(err) => {
println!( println!(
"{}Transaction failed: seq={:<3} error={:?} signature={}", "{}{}Transaction failed: seq={:<3} error={:?} signature={}",
CROSS_MARK, seq, err, signature timestamp(),
CROSS_MARK,
seq,
err,
signature
); );
} }
} }
@ -1140,8 +1185,11 @@ pub fn process_ping(
if elapsed_time >= *timeout { if elapsed_time >= *timeout {
println!( println!(
"{}Confirmation timeout: seq={:<3} signature={}", "{}{}Confirmation timeout: seq={:<3} signature={}",
CROSS_MARK, seq, signature timestamp(),
CROSS_MARK,
seq,
signature
); );
break; break;
} }
@ -1159,8 +1207,11 @@ pub fn process_ping(
} }
Err(err) => { Err(err) => {
println!( println!(
"{}Submit failed: seq={:<3} error={:?}", "{}{}Submit failed: seq={:<3} error={:?}",
CROSS_MARK, seq, err timestamp(),
CROSS_MARK,
seq,
err
); );
} }
} }
@ -1663,6 +1714,7 @@ mod tests {
use super::*; use super::*;
use crate::cli::{app, parse_command}; use crate::cli::{app, parse_command};
use solana_sdk::signature::{write_keypair, Keypair}; use solana_sdk::signature::{write_keypair, Keypair};
use std::str::FromStr;
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
fn make_tmp_file() -> (String, NamedTempFile) { fn make_tmp_file() -> (String, NamedTempFile) {
@ -1798,8 +1850,11 @@ mod tests {
"2", "2",
"-t", "-t",
"3", "3",
"-D",
"--commitment", "--commitment",
"max", "max",
"--blockhash",
"4CCNp28j6AhGq7PkjPDP4wbQWBS8LLbQin2xV5n8frKX",
]); ]);
assert_eq!( assert_eq!(
parse_command(&test_ping, &default_signer, &mut None).unwrap(), parse_command(&test_ping, &default_signer, &mut None).unwrap(),
@ -1809,6 +1864,10 @@ mod tests {
interval: Duration::from_secs(1), interval: Duration::from_secs(1),
count: Some(2), count: Some(2),
timeout: Duration::from_secs(3), timeout: Duration::from_secs(3),
blockhash: Some(
Hash::from_str("4CCNp28j6AhGq7PkjPDP4wbQWBS8LLbQin2xV5n8frKX").unwrap()
),
print_timestamp: true,
}, },
signers: vec![default_keypair.into()], signers: vec![default_keypair.into()],
} }