2019-07-31 16:10:55 -07:00
|
|
|
#[cfg(test)]
|
|
|
|
#[macro_use]
|
|
|
|
extern crate solana_move_loader_program;
|
|
|
|
|
2018-12-12 11:27:21 -08:00
|
|
|
mod bench;
|
|
|
|
mod cli;
|
2018-11-16 08:45:59 -08:00
|
|
|
|
2019-06-11 18:47:35 -07:00
|
|
|
use crate::bench::{
|
|
|
|
do_bench_tps, generate_and_fund_keypairs, generate_keypairs, Config, NUM_LAMPORTS_PER_ACCOUNT,
|
|
|
|
};
|
2019-05-27 20:54:44 -07:00
|
|
|
use solana::gossip_service::{discover_cluster, get_multi_client};
|
2019-06-18 14:44:53 -07:00
|
|
|
use solana_sdk::fee_calculator::FeeCalculator;
|
2019-07-23 17:46:33 -07:00
|
|
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
2019-06-11 18:47:35 -07:00
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::fs::File;
|
|
|
|
use std::io::prelude::*;
|
|
|
|
use std::path::Path;
|
2019-04-19 14:04:36 -07:00
|
|
|
use std::process::exit;
|
2018-03-04 00:21:40 -08:00
|
|
|
|
2019-06-18 14:44:53 -07:00
|
|
|
/// Number of signatures for all transactions in ~1 week at ~100K TPS
|
|
|
|
pub const NUM_SIGNATURES_FOR_TXS: u64 = 100_000 * 60 * 60 * 24 * 7;
|
|
|
|
|
2018-02-28 09:07:54 -08:00
|
|
|
fn main() {
|
2019-07-31 20:00:52 -07:00
|
|
|
solana_logger::setup_with_filter("solana=info");
|
2018-11-16 08:45:59 -08:00
|
|
|
solana_metrics::set_panic_hook("bench-tps");
|
2018-03-03 20:15:42 -08:00
|
|
|
|
2018-12-12 11:27:21 -08:00
|
|
|
let matches = cli::build_args().get_matches();
|
2019-04-19 14:04:36 -07:00
|
|
|
let cli_config = cli::extract_args(&matches);
|
2018-12-12 11:27:21 -08:00
|
|
|
|
2019-04-19 14:04:36 -07:00
|
|
|
let cli::Config {
|
2019-05-03 15:00:19 -07:00
|
|
|
entrypoint_addr,
|
2019-04-19 14:04:36 -07:00
|
|
|
drone_addr,
|
|
|
|
id,
|
|
|
|
threads,
|
|
|
|
num_nodes,
|
|
|
|
duration,
|
|
|
|
tx_count,
|
|
|
|
thread_batch_sleep_ms,
|
|
|
|
sustained,
|
2019-06-11 18:47:35 -07:00
|
|
|
client_ids_and_stake_file,
|
|
|
|
write_to_client_file,
|
|
|
|
read_from_client_file,
|
2019-06-18 14:44:53 -07:00
|
|
|
target_lamports_per_signature,
|
2019-07-28 10:43:42 -07:00
|
|
|
use_move,
|
2019-04-19 14:04:36 -07:00
|
|
|
} = cli_config;
|
2018-12-12 11:27:21 -08:00
|
|
|
|
2019-06-11 18:47:35 -07:00
|
|
|
if write_to_client_file {
|
2019-07-31 11:15:14 -07:00
|
|
|
let (keypairs, _) = generate_keypairs(&id, tx_count as u64 * 2);
|
2019-06-18 14:44:53 -07:00
|
|
|
let num_accounts = keypairs.len() as u64;
|
|
|
|
let max_fee = FeeCalculator::new(target_lamports_per_signature).max_lamports_per_signature;
|
|
|
|
let num_lamports_per_account = (num_accounts - 1 + NUM_SIGNATURES_FOR_TXS * max_fee)
|
|
|
|
/ num_accounts
|
|
|
|
+ NUM_LAMPORTS_PER_ACCOUNT;
|
2019-06-11 18:47:35 -07:00
|
|
|
let mut accounts = HashMap::new();
|
|
|
|
keypairs.iter().for_each(|keypair| {
|
|
|
|
accounts.insert(
|
|
|
|
serde_json::to_string(&keypair.to_bytes().to_vec()).unwrap(),
|
2019-06-18 14:44:53 -07:00
|
|
|
num_lamports_per_account,
|
2019-06-11 18:47:35 -07:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
let serialized = serde_yaml::to_string(&accounts).unwrap();
|
|
|
|
let path = Path::new(&client_ids_and_stake_file);
|
|
|
|
let mut file = File::create(path).unwrap();
|
|
|
|
file.write_all(&serialized.into_bytes()).unwrap();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-19 14:04:36 -07:00
|
|
|
println!("Connecting to the cluster");
|
2019-05-16 07:14:58 -07:00
|
|
|
let (nodes, _replicators) =
|
|
|
|
discover_cluster(&entrypoint_addr, num_nodes).unwrap_or_else(|err| {
|
|
|
|
eprintln!("Failed to discover {} nodes: {:?}", num_nodes, err);
|
|
|
|
exit(1);
|
|
|
|
});
|
2019-05-27 20:54:44 -07:00
|
|
|
|
|
|
|
let (client, num_clients) = get_multi_client(&nodes);
|
|
|
|
|
|
|
|
if nodes.len() < num_clients {
|
2019-04-19 14:04:36 -07:00
|
|
|
eprintln!(
|
|
|
|
"Error: Insufficient nodes discovered. Expecting {} or more",
|
|
|
|
num_nodes
|
|
|
|
);
|
|
|
|
exit(1);
|
|
|
|
}
|
2019-05-01 17:14:01 -07:00
|
|
|
|
2019-07-31 16:10:55 -07:00
|
|
|
let (keypairs, move_keypairs, keypair_balance) = if read_from_client_file && !use_move {
|
2019-06-11 18:47:35 -07:00
|
|
|
let path = Path::new(&client_ids_and_stake_file);
|
|
|
|
let file = File::open(path).unwrap();
|
|
|
|
|
|
|
|
let accounts: HashMap<String, u64> = serde_yaml::from_reader(file).unwrap();
|
|
|
|
let mut keypairs = vec![];
|
|
|
|
let mut last_balance = 0;
|
|
|
|
|
|
|
|
accounts.into_iter().for_each(|(keypair, balance)| {
|
|
|
|
let bytes: Vec<u8> = serde_json::from_str(keypair.as_str()).unwrap();
|
|
|
|
keypairs.push(Keypair::from_bytes(&bytes).unwrap());
|
|
|
|
last_balance = balance;
|
|
|
|
});
|
2019-07-23 17:46:33 -07:00
|
|
|
// Sort keypairs so that do_bench_tps() uses the same subset of accounts for each run.
|
|
|
|
// This prevents the amount of storage needed for bench-tps accounts from creeping up
|
|
|
|
// across multiple runs.
|
|
|
|
keypairs.sort_by(|x, y| x.pubkey().to_string().cmp(&y.pubkey().to_string()));
|
2019-07-31 11:15:14 -07:00
|
|
|
(keypairs, None, last_balance)
|
2019-06-11 18:47:35 -07:00
|
|
|
} else {
|
|
|
|
generate_and_fund_keypairs(
|
|
|
|
&client,
|
|
|
|
Some(drone_addr),
|
|
|
|
&id,
|
|
|
|
tx_count,
|
|
|
|
NUM_LAMPORTS_PER_ACCOUNT,
|
2019-07-31 16:10:55 -07:00
|
|
|
use_move,
|
2019-06-11 18:47:35 -07:00
|
|
|
)
|
2019-06-12 15:01:59 -07:00
|
|
|
.unwrap_or_else(|e| {
|
|
|
|
eprintln!("Error could not fund keys: {:?}", e);
|
|
|
|
exit(1);
|
|
|
|
})
|
2019-06-11 18:47:35 -07:00
|
|
|
};
|
2019-04-19 14:04:36 -07:00
|
|
|
|
|
|
|
let config = Config {
|
|
|
|
id,
|
|
|
|
threads,
|
|
|
|
thread_batch_sleep_ms,
|
|
|
|
duration,
|
|
|
|
tx_count,
|
|
|
|
sustained,
|
2019-07-28 10:43:42 -07:00
|
|
|
use_move,
|
2019-04-19 14:04:36 -07:00
|
|
|
};
|
|
|
|
|
2019-07-31 16:10:55 -07:00
|
|
|
do_bench_tps(
|
|
|
|
vec![client],
|
|
|
|
config,
|
|
|
|
keypairs,
|
|
|
|
keypair_balance,
|
|
|
|
move_keypairs,
|
|
|
|
);
|
2018-09-06 14:20:01 -07:00
|
|
|
}
|