2022-12-16 18:35:49 -08:00
|
|
|
use std::{
|
|
|
|
collections::HashMap,
|
|
|
|
sync::Arc,
|
|
|
|
time::{Duration, Instant},
|
|
|
|
};
|
2022-12-10 09:31:37 -08:00
|
|
|
|
2022-12-16 18:35:49 -08:00
|
|
|
use bench_utils::{
|
2022-12-28 05:01:04 -08:00
|
|
|
helpers::BenchHelper,
|
2022-12-10 09:31:37 -08:00
|
|
|
metrics::{AvgMetric, Metric},
|
|
|
|
};
|
2023-01-02 05:38:59 -08:00
|
|
|
use lite_rpc::DEFAULT_LITE_RPC_ADDR;
|
2022-12-10 09:31:37 -08:00
|
|
|
use log::info;
|
|
|
|
use solana_client::{nonblocking::rpc_client::RpcClient, rpc_client::SerializableTransaction};
|
2022-12-28 05:01:04 -08:00
|
|
|
use solana_sdk::{
|
|
|
|
commitment_config::CommitmentConfig, native_token::LAMPORTS_PER_SOL, signature::Signature,
|
|
|
|
};
|
2022-12-10 09:31:37 -08:00
|
|
|
|
|
|
|
use simplelog::*;
|
|
|
|
|
2022-12-16 18:35:49 -08:00
|
|
|
const NUM_OF_TXS: usize = 20_000;
|
2022-12-28 05:01:04 -08:00
|
|
|
const NUM_OF_RUNS: usize = 1;
|
2022-12-10 09:31:37 -08:00
|
|
|
const CSV_FILE_NAME: &str = "metrics.csv";
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
async fn main() {
|
|
|
|
TermLogger::init(
|
|
|
|
LevelFilter::Info,
|
|
|
|
Config::default(),
|
|
|
|
TerminalMode::Mixed,
|
|
|
|
ColorChoice::Auto,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
2023-01-02 05:38:59 -08:00
|
|
|
let rpc_client = Arc::new(RpcClient::new_with_commitment(
|
|
|
|
DEFAULT_LITE_RPC_ADDR.to_string(),
|
2022-12-27 03:14:25 -08:00
|
|
|
CommitmentConfig::confirmed(),
|
2023-01-02 05:38:59 -08:00
|
|
|
));
|
2022-12-27 03:14:25 -08:00
|
|
|
|
2023-01-02 05:38:59 -08:00
|
|
|
info!("Connecting to {DEFAULT_LITE_RPC_ADDR}");
|
|
|
|
|
|
|
|
let bench_helper = BenchHelper { rpc_client };
|
2022-12-28 05:01:04 -08:00
|
|
|
|
2022-12-10 09:31:37 -08:00
|
|
|
let mut csv_writer = csv::Writer::from_path(CSV_FILE_NAME).unwrap();
|
|
|
|
|
|
|
|
let mut avg_metric = AvgMetric::default();
|
|
|
|
|
|
|
|
for run_num in 0..NUM_OF_RUNS {
|
2022-12-28 05:01:04 -08:00
|
|
|
let metric = bench(&bench_helper).await;
|
2023-01-02 05:38:59 -08:00
|
|
|
info!("Run {run_num}: Sent and Confirmed {NUM_OF_TXS} tx(s) in {metric:?} with",);
|
2022-12-10 09:31:37 -08:00
|
|
|
avg_metric += &metric;
|
|
|
|
csv_writer.serialize(metric).unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
let avg_metric = Metric::from(avg_metric);
|
|
|
|
|
|
|
|
info!("Avg Metric {avg_metric:?}",);
|
|
|
|
csv_writer.serialize(avg_metric).unwrap();
|
|
|
|
|
|
|
|
csv_writer.flush().unwrap();
|
|
|
|
}
|
|
|
|
|
2022-12-28 05:01:04 -08:00
|
|
|
async fn bench(bench_helper: &BenchHelper) -> Metric {
|
|
|
|
let funded_payer = bench_helper
|
|
|
|
.new_funded_payer(LAMPORTS_PER_SOL * 2000)
|
2022-12-10 09:31:37 -08:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
2022-12-28 05:01:04 -08:00
|
|
|
let txs = bench_helper
|
|
|
|
.generate_txs(NUM_OF_TXS, &funded_payer)
|
2022-12-10 09:31:37 -08:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
2022-12-28 05:01:04 -08:00
|
|
|
let mut un_confirmed_txs: HashMap<Signature, Option<Instant>> =
|
|
|
|
HashMap::with_capacity(txs.len());
|
2022-12-10 09:31:37 -08:00
|
|
|
|
|
|
|
for tx in &txs {
|
2022-12-28 05:01:04 -08:00
|
|
|
un_confirmed_txs.insert(*tx.get_signature(), None);
|
2022-12-10 09:31:37 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
let start_time = Instant::now();
|
|
|
|
|
2023-01-02 05:38:59 -08:00
|
|
|
info!("Sending and Confirming {NUM_OF_TXS} tx(s)",);
|
2022-12-28 05:01:04 -08:00
|
|
|
|
2023-01-02 05:38:59 -08:00
|
|
|
let lite_client = bench_helper.rpc_client.clone();
|
2022-12-10 09:31:37 -08:00
|
|
|
|
|
|
|
let send_fut = {
|
|
|
|
let lite_client = lite_client.clone();
|
2022-12-21 05:31:43 -08:00
|
|
|
|
2022-12-10 09:31:37 -08:00
|
|
|
tokio::spawn(async move {
|
|
|
|
for tx in txs {
|
|
|
|
lite_client.send_transaction(&tx).await.unwrap();
|
|
|
|
info!("Tx {}", &tx.signatures[0]);
|
|
|
|
}
|
|
|
|
info!("Sent {NUM_OF_TXS} tx(s)");
|
2022-12-21 05:31:43 -08:00
|
|
|
|
|
|
|
start_time.elapsed()
|
2022-12-10 09:31:37 -08:00
|
|
|
})
|
|
|
|
};
|
|
|
|
|
|
|
|
let confirm_fut = tokio::spawn(async move {
|
|
|
|
let mut metrics = Metric::default();
|
|
|
|
|
|
|
|
while !un_confirmed_txs.is_empty() {
|
|
|
|
let mut to_remove_txs = Vec::new();
|
|
|
|
|
|
|
|
for (sig, time_elapsed_since_last_confirmed) in un_confirmed_txs.iter_mut() {
|
2022-12-28 05:01:04 -08:00
|
|
|
let sig = *sig;
|
|
|
|
|
2022-12-10 09:31:37 -08:00
|
|
|
if time_elapsed_since_last_confirmed.is_none() {
|
|
|
|
*time_elapsed_since_last_confirmed = Some(Instant::now())
|
|
|
|
}
|
|
|
|
|
2023-01-02 05:38:59 -08:00
|
|
|
if lite_client.confirm_transaction(&sig).await.unwrap() {
|
2022-12-10 09:31:37 -08:00
|
|
|
metrics.txs_confirmed += 1;
|
2022-12-28 05:01:04 -08:00
|
|
|
to_remove_txs.push(sig);
|
2022-12-10 09:31:37 -08:00
|
|
|
} else if time_elapsed_since_last_confirmed.unwrap().elapsed()
|
|
|
|
> Duration::from_secs(3)
|
|
|
|
{
|
|
|
|
metrics.txs_un_confirmed += 1;
|
2022-12-28 05:01:04 -08:00
|
|
|
to_remove_txs.push(sig);
|
2022-12-10 09:31:37 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for to_remove_tx in to_remove_txs {
|
|
|
|
un_confirmed_txs.remove(&to_remove_tx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-21 05:31:43 -08:00
|
|
|
metrics.total_time_elapsed_sec = start_time.elapsed().as_secs_f64();
|
2022-12-10 09:31:37 -08:00
|
|
|
metrics.txs_sent = NUM_OF_TXS as u64;
|
|
|
|
|
2022-12-21 05:31:43 -08:00
|
|
|
metrics
|
2022-12-10 09:31:37 -08:00
|
|
|
});
|
|
|
|
|
2022-12-21 05:31:43 -08:00
|
|
|
let (send_fut, confirm_fut) = tokio::join!(send_fut, confirm_fut);
|
|
|
|
let time_to_send_txs = send_fut.unwrap();
|
|
|
|
let mut metrics = confirm_fut.unwrap();
|
|
|
|
metrics.time_to_send_txs = time_to_send_txs.as_secs_f64();
|
|
|
|
metrics.calc_tps();
|
2022-12-10 09:31:37 -08:00
|
|
|
|
2022-12-21 05:31:43 -08:00
|
|
|
metrics
|
2022-12-10 09:31:37 -08:00
|
|
|
}
|