Port solana-client-demo to clap crate for CLI arguments
This commit is contained in:
committed by
Greg Fitzgerald
parent
37dd511356
commit
4d05b74314
@ -1,14 +1,12 @@
|
|||||||
extern crate atty;
|
|
||||||
extern crate bincode;
|
extern crate bincode;
|
||||||
|
extern crate clap;
|
||||||
extern crate env_logger;
|
extern crate env_logger;
|
||||||
extern crate getopts;
|
|
||||||
extern crate rayon;
|
extern crate rayon;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate solana;
|
extern crate solana;
|
||||||
|
|
||||||
use atty::{is, Stream};
|
|
||||||
use bincode::serialize;
|
use bincode::serialize;
|
||||||
use getopts::Options;
|
use clap::{App, Arg};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use solana::crdt::{Crdt, ReplicatedData};
|
use solana::crdt::{Crdt, ReplicatedData};
|
||||||
use solana::drone::DroneRequest;
|
use solana::drone::DroneRequest;
|
||||||
@ -22,10 +20,9 @@ use solana::streamer::default_window;
|
|||||||
use solana::thin_client::ThinClient;
|
use solana::thin_client::ThinClient;
|
||||||
use solana::timing::{duration_as_ms, duration_as_s};
|
use solana::timing::{duration_as_ms, duration_as_s};
|
||||||
use solana::transaction::Transaction;
|
use solana::transaction::Transaction;
|
||||||
use std::env;
|
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{stdin, Read, Write};
|
use std::io::Write;
|
||||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream, UdpSocket};
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream, UdpSocket};
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
@ -36,15 +33,6 @@ use std::thread::JoinHandle;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
fn print_usage(program: &str, opts: Options) {
|
|
||||||
let mut brief = format!("Usage: cat <mint.json> | {} [options]\n\n", program);
|
|
||||||
brief += " Solana client demo creates a number of transactions and\n";
|
|
||||||
brief += " sends them to a target node.";
|
|
||||||
brief += " Takes json formatted mint file to stdin.";
|
|
||||||
|
|
||||||
print!("{}", opts.usage(&brief));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sample_tx_count(
|
fn sample_tx_count(
|
||||||
exit: Arc<AtomicBool>,
|
exit: Arc<AtomicBool>,
|
||||||
maxes: Arc<RwLock<Vec<(f64, u64)>>>,
|
maxes: Arc<RwLock<Vec<(f64, u64)>>>,
|
||||||
@ -153,53 +141,77 @@ fn main() {
|
|||||||
let mut num_nodes = 1usize;
|
let mut num_nodes = 1usize;
|
||||||
let mut time_sec = 60;
|
let mut time_sec = 60;
|
||||||
|
|
||||||
let mut opts = Options::new();
|
let matches = App::new("solana-client-demo")
|
||||||
opts.optopt("l", "", "leader", "leader.json");
|
.arg(
|
||||||
opts.optopt("t", "", "number of threads", &format!("{}", threads));
|
Arg::with_name("leader")
|
||||||
opts.optopt(
|
.short("l")
|
||||||
"s",
|
.long("leader")
|
||||||
"",
|
.value_name("PATH")
|
||||||
"send transactions for this many seconds",
|
.takes_value(true)
|
||||||
&format!("{}", time_sec),
|
.help("/path/to/leader.json"),
|
||||||
);
|
)
|
||||||
opts.optopt(
|
.arg(
|
||||||
"n",
|
Arg::with_name("mint")
|
||||||
"",
|
.short("m")
|
||||||
"number of nodes to converge to",
|
.long("mint")
|
||||||
&format!("{}", num_nodes),
|
.value_name("PATH")
|
||||||
);
|
.takes_value(true)
|
||||||
opts.optflag("h", "help", "print help");
|
.help("/path/to/mint.json"),
|
||||||
let args: Vec<String> = env::args().collect();
|
)
|
||||||
let matches = match opts.parse(&args[1..]) {
|
.arg(
|
||||||
Ok(m) => m,
|
Arg::with_name("num_nodes")
|
||||||
Err(e) => {
|
.short("n")
|
||||||
eprintln!("{}", e);
|
.long("nodes")
|
||||||
exit(1);
|
.value_name("NUMBER")
|
||||||
}
|
.takes_value(true)
|
||||||
};
|
.help("number of nodes to converge to"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("threads")
|
||||||
|
.short("t")
|
||||||
|
.long("threads")
|
||||||
|
.value_name("NUMBER")
|
||||||
|
.takes_value(true)
|
||||||
|
.help("number of threads"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("seconds")
|
||||||
|
.short("s")
|
||||||
|
.long("sec")
|
||||||
|
.value_name("NUMBER")
|
||||||
|
.takes_value(true)
|
||||||
|
.help("send transactions for this many seconds"),
|
||||||
|
)
|
||||||
|
.get_matches();
|
||||||
|
|
||||||
if matches.opt_present("h") {
|
let leader: ReplicatedData;
|
||||||
let program = args[0].clone();
|
if let Some(l) = matches.value_of("leader") {
|
||||||
print_usage(&program, opts);
|
leader = read_leader(l.to_string());
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if matches.opt_present("t") {
|
|
||||||
threads = matches.opt_str("t").unwrap().parse().expect("integer");
|
|
||||||
}
|
|
||||||
if matches.opt_present("n") {
|
|
||||||
num_nodes = matches.opt_str("n").unwrap().parse().expect("integer");
|
|
||||||
}
|
|
||||||
if matches.opt_present("s") {
|
|
||||||
time_sec = matches.opt_str("s").unwrap().parse().expect("integer");
|
|
||||||
}
|
|
||||||
|
|
||||||
let leader = if matches.opt_present("l") {
|
|
||||||
read_leader(matches.opt_str("l").unwrap())
|
|
||||||
} else {
|
} else {
|
||||||
let server_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 8000);
|
let server_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 8000);
|
||||||
ReplicatedData::new_leader(&server_addr)
|
leader = ReplicatedData::new_leader(&server_addr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let id: Mint;
|
||||||
|
if let Some(m) = matches.value_of("mint") {
|
||||||
|
id = read_mint(m.to_string()).expect("client mint");
|
||||||
|
} else {
|
||||||
|
eprintln!("No mint found!");
|
||||||
|
exit(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(t) = matches.value_of("threads") {
|
||||||
|
threads = t.to_string().parse().expect("integer");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(n) = matches.value_of("nodes") {
|
||||||
|
num_nodes = n.to_string().parse().expect("integer");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(s) = matches.value_of("seconds") {
|
||||||
|
time_sec = s.to_string().parse().expect("integer");
|
||||||
|
}
|
||||||
|
|
||||||
let mut drone_addr = leader.transactions_addr.clone();
|
let mut drone_addr = leader.transactions_addr.clone();
|
||||||
drone_addr.set_port(9900);
|
drone_addr.set_port(9900);
|
||||||
|
|
||||||
@ -208,23 +220,23 @@ fn main() {
|
|||||||
let validators = converge(&leader, signal.clone(), num_nodes, &mut c_threads);
|
let validators = converge(&leader, signal.clone(), num_nodes, &mut c_threads);
|
||||||
assert_eq!(validators.len(), num_nodes);
|
assert_eq!(validators.len(), num_nodes);
|
||||||
|
|
||||||
if is(Stream::Stdin) {
|
// if is(Stream::Stdin) {
|
||||||
eprintln!("nothing found on stdin, expected a json file");
|
// eprintln!("nothing found on stdin, expected a json file");
|
||||||
exit(1);
|
// exit(1);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
let mut buffer = String::new();
|
// let mut buffer = String::new();
|
||||||
let num_bytes = stdin().read_to_string(&mut buffer).unwrap();
|
// let num_bytes = stdin().read_to_string(&mut buffer).unwrap();
|
||||||
if num_bytes == 0 {
|
// if num_bytes == 0 {
|
||||||
eprintln!("empty file on stdin, expected a json file");
|
// eprintln!("empty file on stdin, expected a json file");
|
||||||
exit(1);
|
// exit(1);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
println!("Parsing stdin...");
|
// println!("Parsing stdin...");
|
||||||
let id: Mint = serde_json::from_str(&buffer).unwrap_or_else(|e| {
|
// let id: Mint = serde_json::from_str(&buffer).unwrap_or_else(|e| {
|
||||||
eprintln!("failed to parse json: {}", e);
|
// eprintln!("failed to parse json: {}", e);
|
||||||
exit(1);
|
// exit(1);
|
||||||
});
|
// });
|
||||||
let mut client = mk_client(&leader);
|
let mut client = mk_client(&leader);
|
||||||
|
|
||||||
let starting_balance = client.poll_get_balance(&id.pubkey()).unwrap();
|
let starting_balance = client.poll_get_balance(&id.pubkey()).unwrap();
|
||||||
@ -405,6 +417,12 @@ fn read_leader(path: String) -> ReplicatedData {
|
|||||||
serde_json::from_reader(file).expect(&format!("failed to parse {}", path))
|
serde_json::from_reader(file).expect(&format!("failed to parse {}", path))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_mint(path: String) -> Result<Mint, Box<error::Error>> {
|
||||||
|
let file = File::open(path.clone())?;
|
||||||
|
let mint = serde_json::from_reader(file)?;
|
||||||
|
Ok(mint)
|
||||||
|
}
|
||||||
|
|
||||||
fn request_airdrop(
|
fn request_airdrop(
|
||||||
drone_addr: &SocketAddr,
|
drone_addr: &SocketAddr,
|
||||||
id: &Mint,
|
id: &Mint,
|
||||||
|
Reference in New Issue
Block a user