From 958c345f0c840b69458290625ff5f4a86716894a Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Fri, 9 Aug 2019 22:48:57 -0700 Subject: [PATCH] Add show-account command (#5485) --- Cargo.lock | 7 +++++ wallet/Cargo.toml | 1 + wallet/src/wallet.rs | 65 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 492ee60a92..2ed1f238e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2238,6 +2238,11 @@ dependencies = [ "treeline 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pretty-hex" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "pretty_env_logger" version = "0.2.5" @@ -3842,6 +3847,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "pretty-hex 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5400,6 +5406,7 @@ dependencies = [ "checksum predicates 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "53e09015b0d3f5a0ec2d4428f7559bb7b3fff341b4e159fedd1d57fac8b939ff" "checksum predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06075c3a3e92559ff8929e7a280684489ea27fe44805174c3ebd9328dcb37178" "checksum predicates-tree 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e63c4859013b38a76eca2414c64911fba30def9e3202ac461a2d22831220124" +"checksum pretty-hex 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "119929a2a3b731bb3d888f7a1b5dc3c1db28b6c134def5d99f7e16e2da16b8f7" "checksum pretty_env_logger 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8d1e63042e889b85228620629b51c011d380eed2c7e0015f8a644def280c28" "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" "checksum proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "982a35d1194084ba319d65c4a68d24ca28f5fdb5b8bc20899e4eef8641ea5178" diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index 3014eb02b2..09292cc403 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -18,6 +18,7 @@ dirs = "2.0.2" lazy_static = "1.3.0" log = "0.4.8" num-traits = "0.2" +pretty-hex = "0.1.0" serde = "1.0.98" serde_derive = "1.0.98" serde_json = "1.0.40" diff --git a/wallet/src/wallet.rs b/wallet/src/wallet.rs index 48dfefff40..2fd6f1a6df 100644 --- a/wallet/src/wallet.rs +++ b/wallet/src/wallet.rs @@ -34,7 +34,7 @@ use solana_storage_api::storage_instruction; use solana_vote_api::vote_instruction; use solana_vote_api::vote_state::VoteState; use std::fs::File; -use std::io::Read; +use std::io::{Read, Write}; use std::net::{IpAddr, SocketAddr}; use std::thread::sleep; use std::time::Duration; @@ -53,6 +53,7 @@ pub enum WalletCommand { Confirm(Signature), AuthorizeVoter(Pubkey, Keypair, Pubkey), CreateVoteAccount(Pubkey, Pubkey, u8, u64), + ShowAccount(Pubkey, Option), ShowVoteAccount(Pubkey), DelegateStake(Keypair, Pubkey, u64, bool), WithdrawStake(Keypair, Pubkey, u64), @@ -244,6 +245,14 @@ pub fn parse_command( new_authorized_voter_pubkey, )) } + ("show-account", Some(matches)) => { + let account_pubkey = pubkey_of(matches, "account_pubkey").unwrap(); + let output_file = matches.value_of("output_file"); + Ok(WalletCommand::ShowAccount( + account_pubkey, + output_file.map(ToString::to_string), + )) + } ("show-vote-account", Some(matches)) => { let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap(); Ok(WalletCommand::ShowVoteAccount(vote_account_pubkey)) @@ -553,6 +562,33 @@ fn process_authorize_voter( Ok(signature_str.to_string()) } +fn process_show_account( + rpc_client: &RpcClient, + _config: &WalletConfig, + account_pubkey: &Pubkey, + output_file: &Option, +) -> ProcessResult { + let account = rpc_client.get_account(account_pubkey)?; + + println!(); + println!("Public Key: {}", account_pubkey); + println!("Lamports: {}", account.lamports); + println!("Owner: {}", account.owner); + println!("Executable: {}", account.executable); + + if let Some(output_file) = output_file { + let mut f = File::create(output_file)?; + f.write_all(&account.data)?; + println!(); + println!("Wrote account data to {}", output_file); + } else { + use pretty_hex::*; + println!("{:?}", account.data.hex_dump()); + } + + Ok("".to_string()) +} + fn process_show_vote_account( rpc_client: &RpcClient, _config: &WalletConfig, @@ -1179,7 +1215,11 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult { &authorized_voter_keypair, &new_authorized_voter_pubkey, ), - // Show a vote account + + WalletCommand::ShowAccount(account_pubkey, output_file) => { + process_show_account(&rpc_client, config, &account_pubkey, &output_file) + } + WalletCommand::ShowVoteAccount(vote_account_pubkey) => { process_show_vote_account(&rpc_client, config, &vote_account_pubkey) } @@ -1535,6 +1575,27 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, ' .help("The commission taken on reward redemption (0-255), default: 0"), ), ) + .subcommand( + SubCommand::with_name("show-account") + .about("Show the contents of an account") + .arg( + Arg::with_name("account_pubkey") + .index(1) + .value_name("ACCOUNT PUBKEY") + .takes_value(true) + .required(true) + .validator(is_pubkey_or_keypair) + .help("Account pubkey"), + ) + .arg( + Arg::with_name("output_file") + .long("output") + .short("o") + .value_name("FILE") + .takes_value(true) + .help("Write the account data to this file"), + ) + ) .subcommand( SubCommand::with_name("show-vote-account") .about("Show the contents of a vote account")