From 31f86158e8e4ae846bf80b9e12410b161dbb3da2 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2019 22:53:47 -0700 Subject: [PATCH] Add get-epoch-info command (#6161) (#6173) automerge --- cli/src/wallet.rs | 38 +++++++++++++++++++++++++++- client/src/lib.rs | 3 +++ client/src/rpc_client.rs | 52 ++++++++++++++++++++++++++++----------- client/src/rpc_request.rs | 22 +++++++++++++++++ core/src/rpc.rs | 17 +------------ 5 files changed, 100 insertions(+), 32 deletions(-) diff --git a/cli/src/wallet.rs b/cli/src/wallet.rs index fb2519ee1f..623fb25905 100644 --- a/cli/src/wallet.rs +++ b/cli/src/wallet.rs @@ -16,7 +16,7 @@ use solana_drone::drone::request_airdrop_transaction; use solana_drone::drone_mock::request_airdrop_transaction; use solana_sdk::{ account_utils::State, - bpf_loader, + bpf_loader, clock, fee_calculator::FeeCalculator, hash::Hash, instruction::InstructionError, @@ -97,6 +97,7 @@ pub enum WalletCommand { ShowStorageAccount(Pubkey), Deploy(String), GetSlot, + GetEpochInfo, GetTransactionCount, GetVersion, Pay { @@ -343,6 +344,7 @@ pub fn parse_command( .to_string(), )), ("get-slot", Some(_matches)) => Ok(WalletCommand::GetSlot), + ("get-epoch-info", Some(_matches)) => Ok(WalletCommand::GetEpochInfo), ("get-transaction-count", Some(_matches)) => Ok(WalletCommand::GetTransactionCount), ("pay", Some(pay_matches)) => { let lamports = parse_amount_lamports( @@ -1077,6 +1079,35 @@ fn process_get_slot(rpc_client: &RpcClient) -> ProcessResult { Ok(slot.to_string()) } +fn process_get_epoch_info(rpc_client: &RpcClient) -> ProcessResult { + let epoch_info = rpc_client.get_epoch_info()?; + println!(); + println_name_value("Current epoch:", &epoch_info.epoch.to_string()); + println_name_value("Current slot:", &epoch_info.absolute_slot.to_string()); + println_name_value( + "Total slots in current epoch:", + &epoch_info.slots_in_epoch.to_string(), + ); + let remaining_slots_in_epoch = epoch_info.slots_in_epoch - epoch_info.slot_index; + println_name_value( + "Remaining slots in current epoch:", + &remaining_slots_in_epoch.to_string(), + ); + + let remaining_time_in_epoch = Duration::from_secs( + remaining_slots_in_epoch * clock::DEFAULT_TICKS_PER_SLOT / clock::DEFAULT_TICKS_PER_SECOND, + ); + println_name_value( + "Time remaining in current epoch:", + &format!( + "{} minutes, {} seconds", + remaining_time_in_epoch.as_secs() / 60, + remaining_time_in_epoch.as_secs() % 60 + ), + ); + Ok("".to_string()) +} + fn process_get_transaction_count(rpc_client: &RpcClient) -> ProcessResult { let transaction_count = rpc_client.get_transaction_count()?; Ok(transaction_count.to_string()) @@ -1459,6 +1490,7 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult { } WalletCommand::GetSlot => process_get_slot(&rpc_client), + WalletCommand::GetEpochInfo => process_get_epoch_info(&rpc_client), WalletCommand::GetTransactionCount => process_get_transaction_count(&rpc_client), // If client has positive balance, pay lamports to another address @@ -2156,6 +2188,10 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, ' SubCommand::with_name("get-slot") .about("Get current slot"), ) + .subcommand( + SubCommand::with_name("get-epoch-info") + .about("Get information about the current epoch"), + ) .subcommand( SubCommand::with_name("get-transaction-count") .about("Get current transaction count"), diff --git a/client/src/lib.rs b/client/src/lib.rs index 011095b88a..004223994b 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1,3 +1,6 @@ +#[macro_use] +extern crate serde_derive; + pub mod client_error; mod generic_rpc_client_request; pub mod mock_rpc_client_request; diff --git a/client/src/rpc_client.rs b/client/src/rpc_client.rs index 7f06717065..5ce767609f 100644 --- a/client/src/rpc_client.rs +++ b/client/src/rpc_client.rs @@ -2,23 +2,26 @@ use crate::client_error::ClientError; use crate::generic_rpc_client_request::GenericRpcClientRequest; use crate::mock_rpc_client_request::MockRpcClientRequest; use crate::rpc_client_request::RpcClientRequest; -use crate::rpc_request::RpcRequest; +use crate::rpc_request::{RpcEpochInfo, RpcRequest}; use bincode::serialize; use log::*; use serde_json::{json, Value}; -use solana_sdk::account::Account; -use solana_sdk::clock::{DEFAULT_TICKS_PER_SECOND, DEFAULT_TICKS_PER_SLOT}; -use solana_sdk::fee_calculator::FeeCalculator; -use solana_sdk::hash::Hash; -use solana_sdk::inflation::Inflation; -use solana_sdk::pubkey::Pubkey; -use solana_sdk::signature::{KeypairUtil, Signature}; -use solana_sdk::transaction::{self, Transaction, TransactionError}; -use std::error; -use std::io; -use std::net::SocketAddr; -use std::thread::sleep; -use std::time::{Duration, Instant}; +use solana_sdk::{ + account::Account, + clock::{Slot, DEFAULT_TICKS_PER_SECOND, DEFAULT_TICKS_PER_SLOT}, + fee_calculator::FeeCalculator, + hash::Hash, + inflation::Inflation, + pubkey::Pubkey, + signature::{KeypairUtil, Signature}, + transaction::{self, Transaction, TransactionError}, +}; +use std::{ + error, io, + net::SocketAddr, + thread::sleep, + time::{Duration, Instant}, +}; pub struct RpcClient { client: Box, @@ -76,7 +79,7 @@ impl RpcClient { Ok(result) } - pub fn get_slot(&self) -> io::Result { + pub fn get_slot(&self) -> io::Result { let response = self .client .send(&RpcRequest::GetSlot, None, 0) @@ -95,6 +98,25 @@ impl RpcClient { }) } + pub fn get_epoch_info(&self) -> io::Result { + let response = self + .client + .send(&RpcRequest::GetEpochInfo, None, 0) + .map_err(|err| { + io::Error::new( + io::ErrorKind::Other, + format!("GetEpochInfo request failure: {:?}", err), + ) + })?; + + serde_json::from_value(response).map_err(|err| { + io::Error::new( + io::ErrorKind::Other, + format!("GetEpochInfo parse failure: {}", err), + ) + }) + } + pub fn get_inflation(&self) -> io::Result { let response = self .client diff --git a/client/src/rpc_request.rs b/client/src/rpc_request.rs index c0b0cdeb59..d206e41ef3 100644 --- a/client/src/rpc_request.rs +++ b/client/src/rpc_request.rs @@ -1,6 +1,22 @@ use serde_json::{json, Value}; use std::{error, fmt}; +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct RpcEpochInfo { + /// The current epoch + pub epoch: u64, + + /// The current slot, relative to the start of the current epoch + pub slot_index: u64, + + /// The number of slots in this epoch + pub slots_in_epoch: u64, + + /// The absolute current slot + pub absolute_slot: u64, +} + #[derive(Debug, PartialEq)] pub enum RpcRequest { ConfirmTransaction, @@ -9,6 +25,7 @@ pub enum RpcRequest { GetAccountInfo, GetBalance, GetClusterNodes, + GetEpochInfo, GetGenesisBlockhash, GetInflation, GetNumBlocksSinceSignatureConfirmation, @@ -40,6 +57,7 @@ impl RpcRequest { RpcRequest::GetAccountInfo => "getAccountInfo", RpcRequest::GetBalance => "getBalance", RpcRequest::GetClusterNodes => "getClusterNodes", + RpcRequest::GetEpochInfo => "getEpochInfo", RpcRequest::GetGenesisBlockhash => "getGenesisBlockhash", RpcRequest::GetInflation => "getInflation", RpcRequest::GetNumBlocksSinceSignatureConfirmation => { @@ -112,6 +130,10 @@ mod tests { let request = test_request.build_request_json(1, Some(addr)); assert_eq!(request["method"], "getBalance"); + let test_request = RpcRequest::GetEpochInfo; + let request = test_request.build_request_json(1, None); + assert_eq!(request["method"], "getEpochInfo"); + let test_request = RpcRequest::GetInflation; let request = test_request.build_request_json(1, None); assert_eq!(request["method"], "getInflation"); diff --git a/core/src/rpc.rs b/core/src/rpc.rs index a52ab23772..e94c97bf71 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -10,6 +10,7 @@ use crate::version::VERSION; use bincode::{deserialize, serialize}; use jsonrpc_core::{Error, Metadata, Result}; use jsonrpc_derive::rpc; +use solana_client::rpc_request::RpcEpochInfo; use solana_drone::drone::request_airdrop_transaction; use solana_runtime::bank::Bank; use solana_sdk::account::Account; @@ -267,22 +268,6 @@ pub struct RpcVoteAccountInfo { pub last_vote: u64, } -#[derive(Serialize, Deserialize, Clone, Debug)] -#[serde(rename_all = "camelCase")] -pub struct RpcEpochInfo { - /// The current epoch - pub epoch: u64, - - /// The current slot, relative to the start of the current epoch - pub slot_index: u64, - - /// The number of slots in this epoch - pub slots_in_epoch: u64, - - /// The absolute current slot - pub absolute_slot: u64, -} - #[derive(Serialize, Deserialize, Clone, Debug)] #[serde(rename_all = "kebab-case")] pub struct RpcVersionInfo {