2018-08-22 07:57:07 -07:00
|
|
|
#![feature(test)]
|
2018-07-10 19:33:16 -07:00
|
|
|
extern crate bincode;
|
|
|
|
extern crate rayon;
|
|
|
|
extern crate solana;
|
2018-08-22 07:57:07 -07:00
|
|
|
extern crate test;
|
2018-07-10 19:33:16 -07:00
|
|
|
|
|
|
|
use rayon::prelude::*;
|
|
|
|
use solana::bank::Bank;
|
|
|
|
use solana::banking_stage::BankingStage;
|
2018-09-24 10:40:42 -07:00
|
|
|
use solana::entry::Entry;
|
2018-07-10 19:33:16 -07:00
|
|
|
use solana::mint::Mint;
|
|
|
|
use solana::packet::{to_packets_chunked, PacketRecycler};
|
2018-09-24 10:40:42 -07:00
|
|
|
use solana::poh_service::PohService;
|
2018-08-09 07:56:04 -07:00
|
|
|
use solana::signature::{Keypair, KeypairUtil};
|
2018-07-10 19:33:16 -07:00
|
|
|
use solana::transaction::Transaction;
|
|
|
|
use std::iter;
|
|
|
|
use std::sync::mpsc::{channel, Receiver};
|
|
|
|
use std::sync::Arc;
|
2018-09-24 10:40:42 -07:00
|
|
|
use std::time::Duration;
|
2018-08-22 07:57:07 -07:00
|
|
|
use test::Bencher;
|
2018-07-10 19:33:16 -07:00
|
|
|
|
|
|
|
// use self::test::Bencher;
|
|
|
|
// use bank::{Bank, MAX_ENTRY_IDS};
|
|
|
|
// use bincode::serialize;
|
|
|
|
// use hash::hash;
|
|
|
|
// use mint::Mint;
|
|
|
|
// use rayon::prelude::*;
|
2018-08-09 07:56:04 -07:00
|
|
|
// use signature::{Keypair, KeypairUtil};
|
2018-07-10 19:33:16 -07:00
|
|
|
// use std::collections::HashSet;
|
|
|
|
// use std::time::Instant;
|
|
|
|
// use transaction::Transaction;
|
|
|
|
//
|
|
|
|
// fn bench_process_transactions(_bencher: &mut Bencher) {
|
|
|
|
// let mint = Mint::new(100_000_000);
|
|
|
|
// let bank = Bank::new(&mint);
|
|
|
|
// // Create transactions between unrelated parties.
|
|
|
|
// let txs = 100_000;
|
|
|
|
// let last_ids: Mutex<HashSet<Hash>> = Mutex::new(HashSet::new());
|
|
|
|
// let transactions: Vec<_> = (0..txs)
|
|
|
|
// .into_par_iter()
|
|
|
|
// .map(|i| {
|
|
|
|
// // Seed the 'to' account and a cell for its signature.
|
|
|
|
// let dummy_id = i % (MAX_ENTRY_IDS as i32);
|
|
|
|
// let last_id = hash(&serialize(&dummy_id).unwrap()); // Semi-unique hash
|
|
|
|
// {
|
|
|
|
// let mut last_ids = last_ids.lock().unwrap();
|
|
|
|
// if !last_ids.contains(&last_id) {
|
|
|
|
// last_ids.insert(last_id);
|
|
|
|
// bank.register_entry_id(&last_id);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// // Seed the 'from' account.
|
2018-08-09 07:56:04 -07:00
|
|
|
// let rando0 = Keypair::new();
|
2018-07-10 19:33:16 -07:00
|
|
|
// let tx = Transaction::new(&mint.keypair(), rando0.pubkey(), 1_000, last_id);
|
|
|
|
// bank.process_transaction(&tx).unwrap();
|
|
|
|
//
|
2018-08-09 07:56:04 -07:00
|
|
|
// let rando1 = Keypair::new();
|
2018-07-10 19:33:16 -07:00
|
|
|
// let tx = Transaction::new(&rando0, rando1.pubkey(), 2, last_id);
|
|
|
|
// bank.process_transaction(&tx).unwrap();
|
|
|
|
//
|
|
|
|
// // Finally, return a transaction that's unique
|
|
|
|
// Transaction::new(&rando0, rando1.pubkey(), 1, last_id)
|
|
|
|
// })
|
|
|
|
// .collect();
|
|
|
|
//
|
|
|
|
// let banking_stage = EventProcessor::new(bank, &mint.last_id(), None);
|
|
|
|
//
|
|
|
|
// let now = Instant::now();
|
|
|
|
// assert!(banking_stage.process_transactions(transactions).is_ok());
|
|
|
|
// let duration = now.elapsed();
|
|
|
|
// let sec = duration.as_secs() as f64 + duration.subsec_nanos() as f64 / 1_000_000_000.0;
|
|
|
|
// let tps = txs as f64 / sec;
|
|
|
|
//
|
|
|
|
// // Ensure that all transactions were successfully logged.
|
|
|
|
// drop(banking_stage.historian_input);
|
|
|
|
// let entries: Vec<Entry> = banking_stage.output.lock().unwrap().iter().collect();
|
|
|
|
// assert_eq!(entries.len(), 1);
|
|
|
|
// assert_eq!(entries[0].transactions.len(), txs as usize);
|
|
|
|
//
|
|
|
|
// println!("{} tps", tps);
|
|
|
|
// }
|
|
|
|
|
2018-09-24 10:40:42 -07:00
|
|
|
fn check_txs(receiver: &Receiver<Vec<Entry>>, ref_tx_count: usize) {
|
2018-07-10 19:33:16 -07:00
|
|
|
let mut total = 0;
|
2018-08-12 10:04:21 -07:00
|
|
|
loop {
|
2018-09-24 10:40:42 -07:00
|
|
|
let entries = receiver.recv_timeout(Duration::new(1, 0));
|
|
|
|
if let Ok(entries) = entries {
|
|
|
|
for entry in &entries {
|
|
|
|
total += entry.transactions.len();
|
2018-08-07 10:29:57 -07:00
|
|
|
}
|
2018-07-10 19:33:16 -07:00
|
|
|
} else {
|
2018-09-24 10:40:42 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if total >= ref_tx_count {
|
|
|
|
break;
|
2018-07-10 19:33:16 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
assert_eq!(total, ref_tx_count);
|
|
|
|
}
|
|
|
|
|
2018-08-22 07:57:07 -07:00
|
|
|
#[bench]
|
2018-07-10 19:33:16 -07:00
|
|
|
fn bench_banking_stage_multi_accounts(bencher: &mut Bencher) {
|
2018-07-11 09:57:32 -07:00
|
|
|
let tx = 10_000_usize;
|
2018-07-10 19:33:16 -07:00
|
|
|
let mint_total = 1_000_000_000_000;
|
|
|
|
let mint = Mint::new(mint_total);
|
|
|
|
let num_dst_accounts = 8 * 1024;
|
|
|
|
let num_src_accounts = 8 * 1024;
|
|
|
|
|
2018-08-09 07:56:04 -07:00
|
|
|
let srckeys: Vec<_> = (0..num_src_accounts).map(|_| Keypair::new()).collect();
|
2018-07-10 19:33:16 -07:00
|
|
|
let dstkeys: Vec<_> = (0..num_dst_accounts)
|
2018-08-09 07:56:04 -07:00
|
|
|
.map(|_| Keypair::new().pubkey())
|
2018-07-10 19:33:16 -07:00
|
|
|
.collect();
|
|
|
|
|
|
|
|
let transactions: Vec<_> = (0..tx)
|
|
|
|
.map(|i| {
|
|
|
|
Transaction::new(
|
|
|
|
&srckeys[i % num_src_accounts],
|
|
|
|
dstkeys[i % num_dst_accounts],
|
|
|
|
i as i64,
|
|
|
|
mint.last_id(),
|
|
|
|
)
|
2018-09-14 16:25:14 -07:00
|
|
|
}).collect();
|
2018-07-10 19:33:16 -07:00
|
|
|
|
|
|
|
let (verified_sender, verified_receiver) = channel();
|
2018-09-24 10:40:42 -07:00
|
|
|
let (entry_sender, entry_receiver) = channel();
|
2018-07-10 19:33:16 -07:00
|
|
|
let packet_recycler = PacketRecycler::default();
|
|
|
|
|
|
|
|
let setup_transactions: Vec<_> = (0..num_src_accounts)
|
|
|
|
.map(|i| {
|
|
|
|
Transaction::new(
|
|
|
|
&mint.keypair(),
|
|
|
|
srckeys[i].pubkey(),
|
|
|
|
mint_total / num_src_accounts as i64,
|
|
|
|
mint.last_id(),
|
|
|
|
)
|
2018-09-14 16:25:14 -07:00
|
|
|
}).collect();
|
2018-07-10 19:33:16 -07:00
|
|
|
|
|
|
|
bencher.iter(move || {
|
|
|
|
let bank = Arc::new(Bank::new(&mint));
|
|
|
|
|
2018-09-24 10:40:42 -07:00
|
|
|
let (hash_sender, hash_receiver) = channel();
|
|
|
|
let (_poh_service, poh_receiver) = PohService::new(bank.last_id(), hash_receiver, None);
|
|
|
|
|
2018-07-10 19:33:16 -07:00
|
|
|
let verified_setup: Vec<_> =
|
2018-07-11 13:40:46 -07:00
|
|
|
to_packets_chunked(&packet_recycler, &setup_transactions.clone(), tx)
|
2018-07-10 19:33:16 -07:00
|
|
|
.into_iter()
|
|
|
|
.map(|x| {
|
2018-09-24 10:40:42 -07:00
|
|
|
let len = (x).read().packets.len();
|
2018-07-10 19:33:16 -07:00
|
|
|
(x, iter::repeat(1).take(len).collect())
|
2018-09-14 16:25:14 -07:00
|
|
|
}).collect();
|
2018-07-10 19:33:16 -07:00
|
|
|
|
|
|
|
verified_sender.send(verified_setup).unwrap();
|
2018-09-24 10:40:42 -07:00
|
|
|
BankingStage::process_packets(
|
|
|
|
&bank,
|
|
|
|
&hash_sender,
|
|
|
|
&poh_receiver,
|
|
|
|
&verified_receiver,
|
|
|
|
&entry_sender,
|
|
|
|
).unwrap();
|
2018-07-10 19:33:16 -07:00
|
|
|
|
2018-09-24 10:40:42 -07:00
|
|
|
check_txs(&entry_receiver, num_src_accounts);
|
2018-07-10 19:33:16 -07:00
|
|
|
|
2018-07-11 13:40:46 -07:00
|
|
|
let verified: Vec<_> = to_packets_chunked(&packet_recycler, &transactions.clone(), 192)
|
2018-07-10 19:33:16 -07:00
|
|
|
.into_iter()
|
|
|
|
.map(|x| {
|
2018-09-24 10:40:42 -07:00
|
|
|
let len = (x).read().packets.len();
|
2018-07-10 19:33:16 -07:00
|
|
|
(x, iter::repeat(1).take(len).collect())
|
2018-09-14 16:25:14 -07:00
|
|
|
}).collect();
|
2018-07-10 19:33:16 -07:00
|
|
|
|
|
|
|
verified_sender.send(verified).unwrap();
|
2018-09-24 10:40:42 -07:00
|
|
|
BankingStage::process_packets(
|
|
|
|
&bank,
|
|
|
|
&hash_sender,
|
|
|
|
&poh_receiver,
|
|
|
|
&verified_receiver,
|
|
|
|
&entry_sender,
|
|
|
|
).unwrap();
|
|
|
|
|
|
|
|
check_txs(&entry_receiver, tx);
|
2018-07-10 19:33:16 -07:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-08-22 07:57:07 -07:00
|
|
|
#[bench]
|
2018-07-10 19:33:16 -07:00
|
|
|
fn bench_banking_stage_single_from(bencher: &mut Bencher) {
|
2018-07-11 09:57:32 -07:00
|
|
|
let tx = 10_000_usize;
|
2018-07-10 19:33:16 -07:00
|
|
|
let mint = Mint::new(1_000_000_000_000);
|
|
|
|
let mut pubkeys = Vec::new();
|
|
|
|
let num_keys = 8;
|
|
|
|
for _ in 0..num_keys {
|
2018-08-09 07:56:04 -07:00
|
|
|
pubkeys.push(Keypair::new().pubkey());
|
2018-07-10 19:33:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
let transactions: Vec<_> = (0..tx)
|
|
|
|
.into_par_iter()
|
|
|
|
.map(|i| {
|
|
|
|
Transaction::new(
|
|
|
|
&mint.keypair(),
|
|
|
|
pubkeys[i % num_keys],
|
|
|
|
i as i64,
|
|
|
|
mint.last_id(),
|
|
|
|
)
|
2018-09-14 16:25:14 -07:00
|
|
|
}).collect();
|
2018-07-10 19:33:16 -07:00
|
|
|
|
|
|
|
let (verified_sender, verified_receiver) = channel();
|
2018-09-24 10:40:42 -07:00
|
|
|
let (entry_sender, entry_receiver) = channel();
|
2018-07-10 19:33:16 -07:00
|
|
|
let packet_recycler = PacketRecycler::default();
|
|
|
|
|
|
|
|
bencher.iter(move || {
|
|
|
|
let bank = Arc::new(Bank::new(&mint));
|
2018-09-24 10:40:42 -07:00
|
|
|
|
|
|
|
let (hash_sender, hash_receiver) = channel();
|
|
|
|
let (_poh_service, poh_receiver) = PohService::new(bank.last_id(), hash_receiver, None);
|
|
|
|
|
2018-07-11 13:40:46 -07:00
|
|
|
let verified: Vec<_> = to_packets_chunked(&packet_recycler, &transactions.clone(), tx)
|
2018-07-10 19:33:16 -07:00
|
|
|
.into_iter()
|
|
|
|
.map(|x| {
|
2018-09-24 10:40:42 -07:00
|
|
|
let len = (x).read().packets.len();
|
2018-07-10 19:33:16 -07:00
|
|
|
(x, iter::repeat(1).take(len).collect())
|
2018-09-14 16:25:14 -07:00
|
|
|
}).collect();
|
2018-07-10 19:33:16 -07:00
|
|
|
verified_sender.send(verified).unwrap();
|
2018-09-24 10:40:42 -07:00
|
|
|
BankingStage::process_packets(
|
|
|
|
&bank,
|
|
|
|
&hash_sender,
|
|
|
|
&poh_receiver,
|
|
|
|
&verified_receiver,
|
|
|
|
&entry_sender,
|
|
|
|
).unwrap();
|
|
|
|
|
|
|
|
check_txs(&entry_receiver, tx);
|
2018-07-10 19:33:16 -07:00
|
|
|
});
|
|
|
|
}
|