parent
5637f88aff
commit
d50aef8404
|
@ -16,7 +16,7 @@ use solana_drone::drone::request_airdrop_transaction;
|
||||||
use solana_drone::drone_mock::request_airdrop_transaction;
|
use solana_drone::drone_mock::request_airdrop_transaction;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account_utils::State,
|
account_utils::State,
|
||||||
bpf_loader,
|
bpf_loader, clock,
|
||||||
fee_calculator::FeeCalculator,
|
fee_calculator::FeeCalculator,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
instruction::InstructionError,
|
instruction::InstructionError,
|
||||||
|
@ -97,6 +97,7 @@ pub enum WalletCommand {
|
||||||
ShowStorageAccount(Pubkey),
|
ShowStorageAccount(Pubkey),
|
||||||
Deploy(String),
|
Deploy(String),
|
||||||
GetSlot,
|
GetSlot,
|
||||||
|
GetEpochInfo,
|
||||||
GetTransactionCount,
|
GetTransactionCount,
|
||||||
GetVersion,
|
GetVersion,
|
||||||
Pay {
|
Pay {
|
||||||
|
@ -343,6 +344,7 @@ pub fn parse_command(
|
||||||
.to_string(),
|
.to_string(),
|
||||||
)),
|
)),
|
||||||
("get-slot", Some(_matches)) => Ok(WalletCommand::GetSlot),
|
("get-slot", Some(_matches)) => Ok(WalletCommand::GetSlot),
|
||||||
|
("get-epoch-info", Some(_matches)) => Ok(WalletCommand::GetEpochInfo),
|
||||||
("get-transaction-count", Some(_matches)) => Ok(WalletCommand::GetTransactionCount),
|
("get-transaction-count", Some(_matches)) => Ok(WalletCommand::GetTransactionCount),
|
||||||
("pay", Some(pay_matches)) => {
|
("pay", Some(pay_matches)) => {
|
||||||
let lamports = parse_amount_lamports(
|
let lamports = parse_amount_lamports(
|
||||||
|
@ -1089,6 +1091,35 @@ fn process_get_slot(rpc_client: &RpcClient) -> ProcessResult {
|
||||||
Ok(slot.to_string())
|
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 {
|
fn process_get_transaction_count(rpc_client: &RpcClient) -> ProcessResult {
|
||||||
let transaction_count = rpc_client.get_transaction_count()?;
|
let transaction_count = rpc_client.get_transaction_count()?;
|
||||||
Ok(transaction_count.to_string())
|
Ok(transaction_count.to_string())
|
||||||
|
@ -1471,6 +1502,7 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletCommand::GetSlot => process_get_slot(&rpc_client),
|
WalletCommand::GetSlot => process_get_slot(&rpc_client),
|
||||||
|
WalletCommand::GetEpochInfo => process_get_epoch_info(&rpc_client),
|
||||||
WalletCommand::GetTransactionCount => process_get_transaction_count(&rpc_client),
|
WalletCommand::GetTransactionCount => process_get_transaction_count(&rpc_client),
|
||||||
|
|
||||||
// If client has positive balance, pay lamports to another address
|
// If client has positive balance, pay lamports to another address
|
||||||
|
@ -2168,6 +2200,10 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
|
||||||
SubCommand::with_name("get-slot")
|
SubCommand::with_name("get-slot")
|
||||||
.about("Get current slot"),
|
.about("Get current slot"),
|
||||||
)
|
)
|
||||||
|
.subcommand(
|
||||||
|
SubCommand::with_name("get-epoch-info")
|
||||||
|
.about("Get information about the current epoch"),
|
||||||
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("get-transaction-count")
|
SubCommand::with_name("get-transaction-count")
|
||||||
.about("Get current transaction count"),
|
.about("Get current transaction count"),
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
|
||||||
pub mod client_error;
|
pub mod client_error;
|
||||||
mod generic_rpc_client_request;
|
mod generic_rpc_client_request;
|
||||||
pub mod mock_rpc_client_request;
|
pub mod mock_rpc_client_request;
|
||||||
|
|
|
@ -2,23 +2,26 @@ use crate::client_error::ClientError;
|
||||||
use crate::generic_rpc_client_request::GenericRpcClientRequest;
|
use crate::generic_rpc_client_request::GenericRpcClientRequest;
|
||||||
use crate::mock_rpc_client_request::MockRpcClientRequest;
|
use crate::mock_rpc_client_request::MockRpcClientRequest;
|
||||||
use crate::rpc_client_request::RpcClientRequest;
|
use crate::rpc_client_request::RpcClientRequest;
|
||||||
use crate::rpc_request::RpcRequest;
|
use crate::rpc_request::{RpcEpochInfo, RpcRequest};
|
||||||
use bincode::serialize;
|
use bincode::serialize;
|
||||||
use log::*;
|
use log::*;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use solana_sdk::account::Account;
|
use solana_sdk::{
|
||||||
use solana_sdk::clock::{DEFAULT_TICKS_PER_SECOND, DEFAULT_TICKS_PER_SLOT};
|
account::Account,
|
||||||
use solana_sdk::fee_calculator::FeeCalculator;
|
clock::{Slot, DEFAULT_TICKS_PER_SECOND, DEFAULT_TICKS_PER_SLOT},
|
||||||
use solana_sdk::hash::Hash;
|
fee_calculator::FeeCalculator,
|
||||||
use solana_sdk::inflation::Inflation;
|
hash::Hash,
|
||||||
use solana_sdk::pubkey::Pubkey;
|
inflation::Inflation,
|
||||||
use solana_sdk::signature::{KeypairUtil, Signature};
|
pubkey::Pubkey,
|
||||||
use solana_sdk::transaction::{self, Transaction, TransactionError};
|
signature::{KeypairUtil, Signature},
|
||||||
use std::error;
|
transaction::{self, Transaction, TransactionError},
|
||||||
use std::io;
|
};
|
||||||
use std::net::SocketAddr;
|
use std::{
|
||||||
use std::thread::sleep;
|
error, io,
|
||||||
use std::time::{Duration, Instant};
|
net::SocketAddr,
|
||||||
|
thread::sleep,
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
|
|
||||||
pub struct RpcClient {
|
pub struct RpcClient {
|
||||||
client: Box<dyn GenericRpcClientRequest + Send + Sync>,
|
client: Box<dyn GenericRpcClientRequest + Send + Sync>,
|
||||||
|
@ -76,7 +79,7 @@ impl RpcClient {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_slot(&self) -> io::Result<u64> {
|
pub fn get_slot(&self) -> io::Result<Slot> {
|
||||||
let response = self
|
let response = self
|
||||||
.client
|
.client
|
||||||
.send(&RpcRequest::GetSlot, None, 0)
|
.send(&RpcRequest::GetSlot, None, 0)
|
||||||
|
@ -95,6 +98,25 @@ impl RpcClient {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_epoch_info(&self) -> io::Result<RpcEpochInfo> {
|
||||||
|
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<Inflation> {
|
pub fn get_inflation(&self) -> io::Result<Inflation> {
|
||||||
let response = self
|
let response = self
|
||||||
.client
|
.client
|
||||||
|
|
|
@ -1,6 +1,22 @@
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use std::{error, fmt};
|
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)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum RpcRequest {
|
pub enum RpcRequest {
|
||||||
ConfirmTransaction,
|
ConfirmTransaction,
|
||||||
|
@ -9,6 +25,7 @@ pub enum RpcRequest {
|
||||||
GetAccountInfo,
|
GetAccountInfo,
|
||||||
GetBalance,
|
GetBalance,
|
||||||
GetClusterNodes,
|
GetClusterNodes,
|
||||||
|
GetEpochInfo,
|
||||||
GetGenesisBlockhash,
|
GetGenesisBlockhash,
|
||||||
GetInflation,
|
GetInflation,
|
||||||
GetNumBlocksSinceSignatureConfirmation,
|
GetNumBlocksSinceSignatureConfirmation,
|
||||||
|
@ -41,6 +58,7 @@ impl RpcRequest {
|
||||||
RpcRequest::GetAccountInfo => "getAccountInfo",
|
RpcRequest::GetAccountInfo => "getAccountInfo",
|
||||||
RpcRequest::GetBalance => "getBalance",
|
RpcRequest::GetBalance => "getBalance",
|
||||||
RpcRequest::GetClusterNodes => "getClusterNodes",
|
RpcRequest::GetClusterNodes => "getClusterNodes",
|
||||||
|
RpcRequest::GetEpochInfo => "getEpochInfo",
|
||||||
RpcRequest::GetGenesisBlockhash => "getGenesisBlockhash",
|
RpcRequest::GetGenesisBlockhash => "getGenesisBlockhash",
|
||||||
RpcRequest::GetInflation => "getInflation",
|
RpcRequest::GetInflation => "getInflation",
|
||||||
RpcRequest::GetNumBlocksSinceSignatureConfirmation => {
|
RpcRequest::GetNumBlocksSinceSignatureConfirmation => {
|
||||||
|
@ -114,6 +132,10 @@ mod tests {
|
||||||
let request = test_request.build_request_json(1, Some(addr));
|
let request = test_request.build_request_json(1, Some(addr));
|
||||||
assert_eq!(request["method"], "getBalance");
|
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 test_request = RpcRequest::GetInflation;
|
||||||
let request = test_request.build_request_json(1, None);
|
let request = test_request.build_request_json(1, None);
|
||||||
assert_eq!(request["method"], "getInflation");
|
assert_eq!(request["method"], "getInflation");
|
||||||
|
|
|
@ -10,6 +10,7 @@ use crate::version::VERSION;
|
||||||
use bincode::{deserialize, serialize};
|
use bincode::{deserialize, serialize};
|
||||||
use jsonrpc_core::{Error, Metadata, Result};
|
use jsonrpc_core::{Error, Metadata, Result};
|
||||||
use jsonrpc_derive::rpc;
|
use jsonrpc_derive::rpc;
|
||||||
|
use solana_client::rpc_request::RpcEpochInfo;
|
||||||
use solana_drone::drone::request_airdrop_transaction;
|
use solana_drone::drone::request_airdrop_transaction;
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_sdk::account::Account;
|
use solana_sdk::account::Account;
|
||||||
|
@ -271,22 +272,6 @@ pub struct RpcVoteAccountInfo {
|
||||||
pub last_vote: u64,
|
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)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub struct RpcVersionInfo {
|
pub struct RpcVersionInfo {
|
||||||
|
|
Loading…
Reference in New Issue