From 3726358f51a6b9bce3b38844ebf9bd3aedd72e90 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Tue, 16 Mar 2021 02:35:27 -0600 Subject: [PATCH] Cli: better estimate of epoch time elapsed/remaining (#15893) * Add rpc_client api for getRecentPerformanceSamples * Prep fn for variable avg slot time * Use recent-perf-samples to more-accurately estimate epoch completed times * Spell out average --- cli-output/src/cli_output.rs | 20 ++++++++------------ cli/src/cluster_query.rs | 19 ++++++++++++++++--- client/src/rpc_client.rs | 7 +++++++ client/src/rpc_request.rs | 2 ++ 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/cli-output/src/cli_output.rs b/cli-output/src/cli_output.rs index e1884ec6d3..af104d80a7 100644 --- a/cli-output/src/cli_output.rs +++ b/cli-output/src/cli_output.rs @@ -19,7 +19,7 @@ use { RpcVoteAccountInfo, }, solana_sdk::{ - clock::{self, Epoch, Slot, UnixTimestamp}, + clock::{Epoch, Slot, UnixTimestamp}, epoch_info::EpochInfo, hash::Hash, native_token::lamports_to_sol, @@ -231,12 +231,8 @@ pub struct CliSlotStatus { pub struct CliEpochInfo { #[serde(flatten)] pub epoch_info: EpochInfo, -} - -impl From for CliEpochInfo { - fn from(epoch_info: EpochInfo) -> Self { - Self { epoch_info } - } + #[serde(skip)] + pub average_slot_time_ms: u64, } impl QuietDisplay for CliEpochInfo {} @@ -286,16 +282,16 @@ impl fmt::Display for CliEpochInfo { "Epoch Completed Time:", &format!( "{}/{} ({} remaining)", - slot_to_human_time(self.epoch_info.slot_index), - slot_to_human_time(self.epoch_info.slots_in_epoch), - slot_to_human_time(remaining_slots_in_epoch) + slot_to_human_time(self.epoch_info.slot_index, self.average_slot_time_ms), + slot_to_human_time(self.epoch_info.slots_in_epoch, self.average_slot_time_ms), + slot_to_human_time(remaining_slots_in_epoch, self.average_slot_time_ms) ), ) } } -fn slot_to_human_time(slot: Slot) -> String { - humantime::format_duration(Duration::from_millis(slot * clock::DEFAULT_MS_PER_SLOT)).to_string() +fn slot_to_human_time(slot: Slot, slot_time_ms: u64) -> String { + humantime::format_duration(Duration::from_secs((slot * slot_time_ms) / 1000)).to_string() } #[derive(Serialize, Deserialize, Default)] diff --git a/cli/src/cluster_query.rs b/cli/src/cluster_query.rs index 7c54b82688..d725769bbb 100644 --- a/cli/src/cluster_query.rs +++ b/cli/src/cluster_query.rs @@ -993,7 +993,20 @@ pub fn process_get_epoch(rpc_client: &RpcClient, _config: &CliConfig) -> Process } pub fn process_get_epoch_info(rpc_client: &RpcClient, config: &CliConfig) -> ProcessResult { - let epoch_info: CliEpochInfo = rpc_client.get_epoch_info()?.into(); + let epoch_info = rpc_client.get_epoch_info()?; + let average_slot_time_ms = rpc_client + .get_recent_performance_samples(Some(60)) + .map(|samples| { + let (slots, secs) = samples.iter().fold((0, 0), |(slots, secs), sample| { + (slots + sample.num_slots, secs + sample.sample_period_secs) + }); + (secs as u64 * 1000) / slots + }) + .unwrap_or(clock::DEFAULT_MS_PER_SLOT); + let epoch_info = CliEpochInfo { + epoch_info, + average_slot_time_ms, + }; Ok(config.output_format.formatted_string(&epoch_info)) } @@ -1008,8 +1021,8 @@ pub fn process_get_slot(rpc_client: &RpcClient, _config: &CliConfig) -> ProcessR } pub fn process_get_block_height(rpc_client: &RpcClient, _config: &CliConfig) -> ProcessResult { - let epoch_info: CliEpochInfo = rpc_client.get_epoch_info()?.into(); - Ok(epoch_info.epoch_info.block_height.to_string()) + let epoch_info = rpc_client.get_epoch_info()?; + Ok(epoch_info.block_height.to_string()) } pub fn parse_show_block_production(matches: &ArgMatches<'_>) -> Result { diff --git a/client/src/rpc_client.rs b/client/src/rpc_client.rs index 5d880fd168..2ba50e51c7 100644 --- a/client/src/rpc_client.rs +++ b/client/src/rpc_client.rs @@ -644,6 +644,13 @@ impl RpcClient { self.send(RpcRequest::GetEpochSchedule, Value::Null) } + pub fn get_recent_performance_samples( + &self, + limit: Option, + ) -> ClientResult> { + self.send(RpcRequest::GetRecentPerformanceSamples, json!([limit])) + } + pub fn get_identity(&self) -> ClientResult { let rpc_identity: RpcIdentity = self.send(RpcRequest::GetIdentity, Value::Null)?; diff --git a/client/src/rpc_request.rs b/client/src/rpc_request.rs index 9a8ec8ba43..5a73e427fb 100644 --- a/client/src/rpc_request.rs +++ b/client/src/rpc_request.rs @@ -34,6 +34,7 @@ pub enum RpcRequest { GetMultipleAccounts, GetProgramAccounts, GetRecentBlockhash, + GetRecentPerformanceSamples, GetSnapshotSlot, GetSignatureStatuses, GetSlot, @@ -90,6 +91,7 @@ impl fmt::Display for RpcRequest { RpcRequest::GetMultipleAccounts => "getMultipleAccounts", RpcRequest::GetProgramAccounts => "getProgramAccounts", RpcRequest::GetRecentBlockhash => "getRecentBlockhash", + RpcRequest::GetRecentPerformanceSamples => "getRecentPerformanceSamples", RpcRequest::GetSnapshotSlot => "getSnapshotSlot", RpcRequest::GetSignatureStatuses => "getSignatureStatuses", RpcRequest::GetSlot => "getSlot",