Add cluster-version subcommand to return entrypoint versions (#5464)
This commit is contained in:
parent
8c15214923
commit
4ae48b56f3
|
@ -94,6 +94,25 @@ impl RpcClient {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_version(&self) -> io::Result<String> {
|
||||||
|
let response = self
|
||||||
|
.client
|
||||||
|
.send(&RpcRequest::GetVersion, None, 0)
|
||||||
|
.map_err(|err| {
|
||||||
|
io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!("GetVersion request failure: {:?}", err),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
serde_json::to_string(&response).map_err(|err| {
|
||||||
|
io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!("GetVersion parse failure: {}", err),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn send_and_confirm_transaction<T: KeypairUtil>(
|
pub fn send_and_confirm_transaction<T: KeypairUtil>(
|
||||||
&self,
|
&self,
|
||||||
transaction: &mut Transaction,
|
transaction: &mut Transaction,
|
||||||
|
|
|
@ -9,18 +9,19 @@ pub enum RpcRequest {
|
||||||
GetAccountInfo,
|
GetAccountInfo,
|
||||||
GetBalance,
|
GetBalance,
|
||||||
GetClusterNodes,
|
GetClusterNodes,
|
||||||
|
GetEpochVoteAccounts,
|
||||||
GetNumBlocksSinceSignatureConfirmation,
|
GetNumBlocksSinceSignatureConfirmation,
|
||||||
GetProgramAccounts,
|
GetProgramAccounts,
|
||||||
GetRecentBlockhash,
|
GetRecentBlockhash,
|
||||||
GetSignatureStatus,
|
GetSignatureStatus,
|
||||||
GetSlot,
|
GetSlot,
|
||||||
GetSlotLeader,
|
GetSlotLeader,
|
||||||
GetEpochVoteAccounts,
|
|
||||||
GetStorageTurn,
|
GetStorageTurn,
|
||||||
GetStorageTurnRate,
|
GetStorageTurnRate,
|
||||||
GetSlotsPerSegment,
|
GetSlotsPerSegment,
|
||||||
GetStoragePubkeysForSlot,
|
GetStoragePubkeysForSlot,
|
||||||
GetTransactionCount,
|
GetTransactionCount,
|
||||||
|
GetVersion,
|
||||||
RegisterNode,
|
RegisterNode,
|
||||||
RequestAirdrop,
|
RequestAirdrop,
|
||||||
SendTransaction,
|
SendTransaction,
|
||||||
|
@ -37,6 +38,7 @@ impl RpcRequest {
|
||||||
RpcRequest::GetAccountInfo => "getAccountInfo",
|
RpcRequest::GetAccountInfo => "getAccountInfo",
|
||||||
RpcRequest::GetBalance => "getBalance",
|
RpcRequest::GetBalance => "getBalance",
|
||||||
RpcRequest::GetClusterNodes => "getClusterNodes",
|
RpcRequest::GetClusterNodes => "getClusterNodes",
|
||||||
|
RpcRequest::GetEpochVoteAccounts => "getEpochVoteAccounts",
|
||||||
RpcRequest::GetNumBlocksSinceSignatureConfirmation => {
|
RpcRequest::GetNumBlocksSinceSignatureConfirmation => {
|
||||||
"getNumBlocksSinceSignatureConfirmation"
|
"getNumBlocksSinceSignatureConfirmation"
|
||||||
}
|
}
|
||||||
|
@ -45,12 +47,12 @@ impl RpcRequest {
|
||||||
RpcRequest::GetSignatureStatus => "getSignatureStatus",
|
RpcRequest::GetSignatureStatus => "getSignatureStatus",
|
||||||
RpcRequest::GetSlot => "getSlot",
|
RpcRequest::GetSlot => "getSlot",
|
||||||
RpcRequest::GetSlotLeader => "getSlotLeader",
|
RpcRequest::GetSlotLeader => "getSlotLeader",
|
||||||
RpcRequest::GetEpochVoteAccounts => "getEpochVoteAccounts",
|
|
||||||
RpcRequest::GetStorageTurn => "getStorageTurn",
|
RpcRequest::GetStorageTurn => "getStorageTurn",
|
||||||
RpcRequest::GetStorageTurnRate => "getStorageTurnRate",
|
RpcRequest::GetStorageTurnRate => "getStorageTurnRate",
|
||||||
RpcRequest::GetSlotsPerSegment => "getSlotsPerSegment",
|
RpcRequest::GetSlotsPerSegment => "getSlotsPerSegment",
|
||||||
RpcRequest::GetStoragePubkeysForSlot => "getStoragePubkeysForSlot",
|
RpcRequest::GetStoragePubkeysForSlot => "getStoragePubkeysForSlot",
|
||||||
RpcRequest::GetTransactionCount => "getTransactionCount",
|
RpcRequest::GetTransactionCount => "getTransactionCount",
|
||||||
|
RpcRequest::GetVersion => "getVersion",
|
||||||
RpcRequest::RegisterNode => "registerNode",
|
RpcRequest::RegisterNode => "registerNode",
|
||||||
RpcRequest::RequestAirdrop => "requestAirdrop",
|
RpcRequest::RequestAirdrop => "requestAirdrop",
|
||||||
RpcRequest::SendTransaction => "sendTransaction",
|
RpcRequest::SendTransaction => "sendTransaction",
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
use console::style;
|
||||||
|
|
||||||
|
// Pretty print a "name value"
|
||||||
|
pub fn println_name_value(name: &str, value: &str) {
|
||||||
|
let styled_value = if value == "" {
|
||||||
|
style("(not set)").italic()
|
||||||
|
} else {
|
||||||
|
style(value)
|
||||||
|
};
|
||||||
|
println!("{} {}", style(name).bold(), styled_value);
|
||||||
|
}
|
|
@ -2,4 +2,5 @@
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
pub mod display;
|
||||||
pub mod wallet;
|
pub mod wallet;
|
||||||
|
|
|
@ -2,6 +2,7 @@ use clap::{crate_description, crate_name, crate_version, Arg, ArgGroup, ArgMatch
|
||||||
use console::style;
|
use console::style;
|
||||||
use solana_sdk::signature::{gen_keypair_file, read_keypair, KeypairUtil};
|
use solana_sdk::signature::{gen_keypair_file, read_keypair, KeypairUtil};
|
||||||
use solana_wallet::config::{self, Config};
|
use solana_wallet::config::{self, Config};
|
||||||
|
use solana_wallet::display::println_name_value;
|
||||||
use solana_wallet::wallet::{app, parse_command, process_command, WalletConfig, WalletError};
|
use solana_wallet::wallet::{app, parse_command, process_command, WalletConfig, WalletError};
|
||||||
use std::error;
|
use std::error;
|
||||||
|
|
||||||
|
@ -120,16 +121,6 @@ pub fn parse_args(matches: &ArgMatches<'_>) -> Result<WalletConfig, Box<dyn erro
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pretty print a "name value"
|
|
||||||
fn println_name_value(name: &str, value: &str) {
|
|
||||||
let styled_value = if value == "" {
|
|
||||||
style("(not set)").italic()
|
|
||||||
} else {
|
|
||||||
style(value)
|
|
||||||
};
|
|
||||||
println!("{} {}", style(name).bold(), styled_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return an error if a url cannot be parsed.
|
// Return an error if a url cannot be parsed.
|
||||||
fn is_url(string: String) -> Result<(), String> {
|
fn is_url(string: String) -> Result<(), String> {
|
||||||
match url::Url::parse(&string) {
|
match url::Url::parse(&string) {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
use crate::display::println_name_value;
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
|
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
|
||||||
|
use console::style;
|
||||||
use log::*;
|
use log::*;
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use serde_json::json;
|
use serde_json::{json, Value};
|
||||||
use solana_budget_api;
|
use solana_budget_api;
|
||||||
use solana_budget_api::budget_instruction;
|
use solana_budget_api::budget_instruction;
|
||||||
use solana_budget_api::budget_state::BudgetError;
|
use solana_budget_api::budget_state::BudgetError;
|
||||||
|
@ -63,6 +65,7 @@ pub enum WalletCommand {
|
||||||
Deploy(String),
|
Deploy(String),
|
||||||
GetSlot,
|
GetSlot,
|
||||||
GetTransactionCount,
|
GetTransactionCount,
|
||||||
|
GetVersion,
|
||||||
// Pay(lamports, to, timestamp, timestamp_pubkey, witness(es), cancelable)
|
// Pay(lamports, to, timestamp, timestamp_pubkey, witness(es), cancelable)
|
||||||
Pay(
|
Pay(
|
||||||
u64,
|
u64,
|
||||||
|
@ -362,6 +365,7 @@ pub fn parse_command(
|
||||||
};
|
};
|
||||||
Ok(WalletCommand::TimeElapsed(to, process_id, dt))
|
Ok(WalletCommand::TimeElapsed(to, process_id, dt))
|
||||||
}
|
}
|
||||||
|
("cluster-version", Some(_matches)) => Ok(WalletCommand::GetVersion),
|
||||||
("", None) => {
|
("", None) => {
|
||||||
eprintln!("{}", matches.usage());
|
eprintln!("{}", matches.usage());
|
||||||
Err(WalletError::CommandNotRecognized(
|
Err(WalletError::CommandNotRecognized(
|
||||||
|
@ -1040,6 +1044,23 @@ fn process_witness(
|
||||||
Ok(signature_str.to_string())
|
Ok(signature_str.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn process_get_version(rpc_client: &RpcClient, config: &WalletConfig) -> ProcessResult {
|
||||||
|
let remote_version: Value = serde_json::from_str(&rpc_client.get_version()?)?;
|
||||||
|
println!(
|
||||||
|
"{} {}",
|
||||||
|
style("Cluster versions from:").bold(),
|
||||||
|
config.json_rpc_url
|
||||||
|
);
|
||||||
|
if let Some(versions) = remote_version.as_object() {
|
||||||
|
for (key, value) in versions.iter() {
|
||||||
|
if let Some(value_string) = value.as_str() {
|
||||||
|
println_name_value(&format!("* {}:", key), &value_string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok("".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn process_command(config: &WalletConfig) -> ProcessResult {
|
pub fn process_command(config: &WalletConfig) -> ProcessResult {
|
||||||
if let WalletCommand::Address = config.command {
|
if let WalletCommand::Address = config.command {
|
||||||
// Get address of this client
|
// Get address of this client
|
||||||
|
@ -1220,6 +1241,9 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
|
||||||
WalletCommand::Witness(to, pubkey) => {
|
WalletCommand::Witness(to, pubkey) => {
|
||||||
process_witness(&rpc_client, config, drone_addr, &to, &pubkey)
|
process_witness(&rpc_client, config, drone_addr, &to, &pubkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return software version of wallet and cluster entrypoint node
|
||||||
|
WalletCommand::GetVersion => process_get_version(&rpc_client, config),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1795,6 +1819,10 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
|
||||||
.help("Optional arbitrary timestamp to apply"),
|
.help("Optional arbitrary timestamp to apply"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.subcommand(
|
||||||
|
SubCommand::with_name("cluster-version")
|
||||||
|
.about("Get the version of the cluster entrypoint"),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in New Issue