| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- use clap::{crate_description, crate_name, crate_version, App, Arg, ArgMatches};
- use solana_drone::drone::DRONE_PORT;
- use solana_sdk::fee_calculator::FeeCalculator;
- use solana_sdk::signature::{read_keypair_file, Keypair, KeypairUtil};
- use std::{net::SocketAddr, process::exit, time::Duration};
- const NUM_LAMPORTS_PER_ACCOUNT_DEFAULT: u64 = solana_sdk::native_token::SOL_LAMPORTS;
- /// Holds the configuration for a single run of the benchmark
- pub struct Config {
- pub entrypoint_addr: SocketAddr,
- pub drone_addr: SocketAddr,
- pub id: Keypair,
- pub threads: usize,
- pub num_nodes: usize,
- pub duration: Duration,
- pub tx_count: usize,
- pub thread_batch_sleep_ms: usize,
- pub sustained: bool,
- pub client_ids_and_stake_file: String,
- pub write_to_client_file: bool,
- pub read_from_client_file: bool,
- pub target_lamports_per_signature: u64,
- pub multi_client: bool,
- pub use_move: bool,
- pub num_lamports_per_account: u64,
- }
- impl Default for Config {
- fn default() -> Config {
- Config {
- entrypoint_addr: SocketAddr::from(([127, 0, 0, 1], 8001)),
- drone_addr: SocketAddr::from(([127, 0, 0, 1], DRONE_PORT)),
- id: Keypair::new(),
- threads: 4,
- num_nodes: 1,
- duration: Duration::new(std::u64::MAX, 0),
- tx_count: 50_000,
- thread_batch_sleep_ms: 1000,
- sustained: false,
- client_ids_and_stake_file: String::new(),
- write_to_client_file: false,
- read_from_client_file: false,
- target_lamports_per_signature: FeeCalculator::default().target_lamports_per_signature,
- multi_client: true,
- use_move: false,
- num_lamports_per_account: NUM_LAMPORTS_PER_ACCOUNT_DEFAULT,
- }
- }
- }
- /// Defines and builds the CLI args for a run of the benchmark
- pub fn build_args<'a, 'b>() -> App<'a, 'b> {
- App::new(crate_name!()).about(crate_description!())
- .version(crate_version!())
- .arg(
- Arg::with_name("entrypoint")
- .short("n")
- .long("entrypoint")
- .value_name("HOST:PORT")
- .takes_value(true)
- .help("Rendezvous with the cluster at this entry point; defaults to 127.0.0.1:8001"),
- )
- .arg(
- Arg::with_name("drone")
- .short("d")
- .long("drone")
- .value_name("HOST:PORT")
- .takes_value(true)
- .help("Location of the drone; defaults to entrypoint:DRONE_PORT"),
- )
- .arg(
- Arg::with_name("identity")
- .short("i")
- .long("identity")
- .value_name("PATH")
- .takes_value(true)
- .help("File containing a client identity (keypair)"),
- )
- .arg(
- Arg::with_name("num-nodes")
- .short("N")
- .long("num-nodes")
- .value_name("NUM")
- .takes_value(true)
- .help("Wait for NUM nodes to converge"),
- )
- .arg(
- Arg::with_name("threads")
- .short("t")
- .long("threads")
- .value_name("NUM")
- .takes_value(true)
- .help("Number of threads"),
- )
- .arg(
- Arg::with_name("duration")
- .long("duration")
- .value_name("SECS")
- .takes_value(true)
- .help("Seconds to run benchmark, then exit; default is forever"),
- )
- .arg(
- Arg::with_name("sustained")
- .long("sustained")
- .help("Use sustained performance mode vs. peak mode. This overlaps the tx generation with transfers."),
- )
- .arg(
- Arg::with_name("use-move")
- .long("use-move")
- .help("Use Move language transactions to perform transfers."),
- )
- .arg(
- Arg::with_name("no-multi-client")
- .long("no-multi-client")
- .help("Disable multi-client support, only transact with the entrypoint."),
- )
- .arg(
- Arg::with_name("tx_count")
- .long("tx_count")
- .value_name("NUM")
- .takes_value(true)
- .help("Number of transactions to send per batch")
- )
- .arg(
- Arg::with_name("thread-batch-sleep-ms")
- .short("z")
- .long("thread-batch-sleep-ms")
- .value_name("NUM")
- .takes_value(true)
- .help("Per-thread-per-iteration sleep in ms"),
- )
- .arg(
- Arg::with_name("write-client-keys")
- .long("write-client-keys")
- .value_name("FILENAME")
- .takes_value(true)
- .help("Generate client keys and stakes and write the list to YAML file"),
- )
- .arg(
- Arg::with_name("read-client-keys")
- .long("read-client-keys")
- .value_name("FILENAME")
- .takes_value(true)
- .help("Read client keys and stakes from the YAML file"),
- )
- .arg(
- Arg::with_name("target_lamports_per_signature")
- .long("target-lamports-per-signature")
- .value_name("LAMPORTS")
- .takes_value(true)
- .help(
- "The cost in lamports that the cluster will charge for signature \
- verification when the cluster is operating at target-signatures-per-slot",
- ),
- )
- .arg(
- Arg::with_name("num_lamports_per_account")
- .long("num-lamports-per-account")
- .value_name("LAMPORTS")
- .takes_value(true)
- .help(
- "Number of lamports per account.",
- ),
- )
- }
- /// Parses a clap `ArgMatches` structure into a `Config`
- /// # Arguments
- /// * `matches` - command line arguments parsed by clap
- /// # Panics
- /// Panics if there is trouble parsing any of the arguments
- pub fn extract_args<'a>(matches: &ArgMatches<'a>) -> Config {
- let mut args = Config::default();
- if let Some(addr) = matches.value_of("entrypoint") {
- args.entrypoint_addr = solana_net_utils::parse_host_port(addr).unwrap_or_else(|e| {
- eprintln!("failed to parse entrypoint address: {}", e);
- exit(1)
- });
- }
- if let Some(addr) = matches.value_of("drone") {
- args.drone_addr = solana_net_utils::parse_host_port(addr).unwrap_or_else(|e| {
- eprintln!("failed to parse drone address: {}", e);
- exit(1)
- });
- }
- if matches.is_present("identity") {
- args.id = read_keypair_file(matches.value_of("identity").unwrap())
- .expect("can't read client identity");
- }
- if let Some(t) = matches.value_of("threads") {
- args.threads = t.to_string().parse().expect("can't parse threads");
- }
- if let Some(n) = matches.value_of("num-nodes") {
- args.num_nodes = n.to_string().parse().expect("can't parse num-nodes");
- }
- if let Some(duration) = matches.value_of("duration") {
- args.duration = Duration::new(
- duration.to_string().parse().expect("can't parse duration"),
- 0,
- );
- }
- if let Some(s) = matches.value_of("tx_count") {
- args.tx_count = s.to_string().parse().expect("can't parse tx_account");
- }
- if let Some(t) = matches.value_of("thread-batch-sleep-ms") {
- args.thread_batch_sleep_ms = t
- .to_string()
- .parse()
- .expect("can't parse thread-batch-sleep-ms");
- }
- args.sustained = matches.is_present("sustained");
- if let Some(s) = matches.value_of("write-client-keys") {
- args.write_to_client_file = true;
- args.client_ids_and_stake_file = s.to_string();
- }
- if let Some(s) = matches.value_of("read-client-keys") {
- assert!(!args.write_to_client_file);
- args.read_from_client_file = true;
- args.client_ids_and_stake_file = s.to_string();
- }
- if let Some(v) = matches.value_of("target_lamports_per_signature") {
- args.target_lamports_per_signature = v.to_string().parse().expect("can't parse lamports");
- }
- args.use_move = matches.is_present("use-move");
- args.multi_client = !matches.is_present("no-multi-client");
- if let Some(v) = matches.value_of("num_lamports_per_account") {
- args.num_lamports_per_account = v.to_string().parse().expect("can't parse lamports");
- }
- args
- }
|