Merge pull request #230 from garious/generalize-topackets

Benchmark the banking stage
This commit is contained in:
Greg Fitzgerald 2018-05-18 19:47:26 -07:00 committed by GitHub
commit 2786357082
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 103 additions and 43 deletions

View File

@ -251,3 +251,58 @@ impl BankingStage {
// println!("{} tps", tps);
// }
//}
#[cfg(all(feature = "unstable", test))]
mod bench {
extern crate test;
use self::test::Bencher;
use bank::*;
use banking_stage::BankingStage;
use event::Event;
use mint::Mint;
use packet::{to_packets, PacketRecycler};
use recorder::Signal;
use signature::{KeyPair, KeyPairUtil};
use std::iter;
use std::sync::Arc;
use std::sync::mpsc::channel;
#[bench]
fn stage_bench(bencher: &mut Bencher) {
let tx = 100_usize;
let mint = Mint::new(1_000_000_000);
let pubkey = KeyPair::new().pubkey();
let events: Vec<_> = (0..tx)
.map(|i| Event::new_transaction(&mint.keypair(), pubkey, i as i64, mint.last_id()))
.collect();
let (verified_sender, verified_receiver) = channel();
let (signal_sender, signal_receiver) = channel();
let packet_recycler = PacketRecycler::default();
let verified: Vec<_> = to_packets(&packet_recycler, events)
.into_iter()
.map(|x| {
let len = (*x).read().unwrap().packets.len();
(x, iter::repeat(1).take(len).collect())
})
.collect();
bencher.iter(move || {
let bank = Arc::new(Bank::new(&mint));
verified_sender.send(verified.clone()).unwrap();
BankingStage::process_packets(
bank.clone(),
&verified_receiver,
&signal_sender,
&packet_recycler,
).unwrap();
let signal = signal_receiver.recv().unwrap();
if let Signal::Events(ref events) = signal {
assert_eq!(events.len(), tx);
} else {
assert!(false);
}
});
}
}

View File

@ -8,7 +8,7 @@ extern crate untrusted;
use isatty::stdin_isatty;
use rayon::prelude::*;
use solana::bank::MAX_ENTRY_IDS;
use solana::entry::{create_entry, next_entry};
use solana::entry::{next_entry, Entry};
use solana::event::Event;
use solana::mint::MintDemo;
use solana::signature::{GenKeys, KeyPair, KeyPairUtil};
@ -61,7 +61,7 @@ fn main() {
}
eprintln!("Logging the creation of {} accounts...", num_accounts);
let entry = create_entry(&last_id, 0, events);
let entry = Entry::new(&last_id, 0, events);
println!("{}", serde_json::to_string(&entry).unwrap());
eprintln!("Creating {} empty entries...", MAX_ENTRY_IDS);

View File

@ -25,6 +25,25 @@ pub struct Entry {
}
impl Entry {
/// Creates the next Entry `num_hashes` after `start_hash`.
pub fn new(start_hash: &Hash, cur_hashes: u64, events: Vec<Event>) -> Self {
let num_hashes = cur_hashes + if events.is_empty() { 0 } else { 1 };
let id = next_hash(start_hash, 0, &events);
Entry {
num_hashes,
id,
events,
}
}
/// Creates the next Tick Entry `num_hashes` after `start_hash`.
pub fn new_mut(start_hash: &mut Hash, cur_hashes: &mut u64, events: Vec<Event>) -> Self {
let entry = Self::new(start_hash, *cur_hashes, events);
*start_hash = entry.id;
*cur_hashes = 0;
entry
}
/// Creates a Entry from the number of hashes `num_hashes` since the previous event
/// and that resulting `id`.
pub fn new_tick(num_hashes: u64, id: &Hash) -> Self {
@ -84,25 +103,6 @@ pub fn next_hash(start_hash: &Hash, num_hashes: u64, events: &[Event]) -> Hash {
}
}
/// Creates the next Entry `num_hashes` after `start_hash`.
pub fn create_entry(start_hash: &Hash, cur_hashes: u64, events: Vec<Event>) -> Entry {
let num_hashes = cur_hashes + if events.is_empty() { 0 } else { 1 };
let id = next_hash(start_hash, 0, &events);
Entry {
num_hashes,
id,
events,
}
}
/// Creates the next Tick Entry `num_hashes` after `start_hash`.
pub fn create_entry_mut(start_hash: &mut Hash, cur_hashes: &mut u64, events: Vec<Event>) -> Entry {
let entry = create_entry(start_hash, *cur_hashes, events);
*start_hash = entry.id;
*cur_hashes = 0;
entry
}
/// Creates the next Tick or Event Entry `num_hashes` after `start_hash`.
pub fn next_entry(start_hash: &Hash, num_hashes: u64, events: Vec<Event>) -> Entry {
Entry {
@ -116,11 +116,10 @@ pub fn next_entry(start_hash: &Hash, num_hashes: u64, events: Vec<Event>) -> Ent
mod tests {
use super::*;
use chrono::prelude::*;
use entry::create_entry;
use entry::Entry;
use event::Event;
use hash::hash;
use signature::{KeyPair, KeyPairUtil};
use transaction::Transaction;
#[test]
fn test_entry_verify() {
@ -138,9 +137,9 @@ mod tests {
// First, verify entries
let keypair = KeyPair::new();
let tr0 = Event::Transaction(Transaction::new(&keypair, keypair.pubkey(), 0, zero));
let tr1 = Event::Transaction(Transaction::new(&keypair, keypair.pubkey(), 1, zero));
let mut e0 = create_entry(&zero, 0, vec![tr0.clone(), tr1.clone()]);
let tr0 = Event::new_transaction(&keypair, keypair.pubkey(), 0, zero);
let tr1 = Event::new_transaction(&keypair, keypair.pubkey(), 1, zero);
let mut e0 = Entry::new(&zero, 0, vec![tr0.clone(), tr1.clone()]);
assert!(e0.verify(&zero));
// Next, swap two events and ensure verification fails.
@ -157,7 +156,7 @@ mod tests {
let keypair = KeyPair::new();
let tr0 = Event::new_timestamp(&keypair, Utc::now());
let tr1 = Event::new_signature(&keypair, Default::default());
let mut e0 = create_entry(&zero, 0, vec![tr0.clone(), tr1.clone()]);
let mut e0 = Entry::new(&zero, 0, vec![tr0.clone(), tr1.clone()]);
assert!(e0.verify(&zero));
// Next, swap two witness events and ensure verification fails.

View File

@ -3,6 +3,7 @@
use bincode::serialize;
use chrono::prelude::*;
use hash::Hash;
use signature::{KeyPair, KeyPairUtil, PublicKey, Signature, SignatureUtil};
use transaction::Transaction;
@ -22,6 +23,16 @@ pub enum Event {
}
impl Event {
pub fn new_transaction(
from_keypair: &KeyPair,
to: PublicKey,
tokens: i64,
last_id: Hash,
) -> Self {
let tr = Transaction::new(from_keypair, to, tokens, last_id);
Event::Transaction(tr)
}
/// Create and sign a new Witness Timestamp. Used for unit-testing.
pub fn new_timestamp(from: &KeyPair, dt: DateTime<Utc>) -> Self {
let sign_data = serialize(&dt).expect("serialize 'dt' in pub fn new_timestamp");

View File

@ -123,7 +123,6 @@ pub fn reconstruct_entries_from_blobs(blobs: &VecDeque<SharedBlob>) -> Vec<Entry
#[cfg(test)]
mod tests {
use super::*;
use entry;
use hash::hash;
use packet::BlobRecycler;
use signature::{KeyPair, KeyPairUtil};
@ -150,7 +149,7 @@ mod tests {
let keypair = KeyPair::new();
let tr0 = Event::Transaction(Transaction::new(&keypair, keypair.pubkey(), 1, one));
let events = vec![tr0.clone(); 10000];
let e0 = entry::create_entry(&zero, 0, events);
let e0 = Entry::new(&zero, 0, events);
let entry_list = vec![e0.clone(); 1];
let blob_recycler = BlobRecycler::default();

View File

@ -1,7 +1,6 @@
//! The `mint` module is a library for generating the chain's genesis block.
use entry::Entry;
use entry::create_entry;
use event::Event;
use hash::{hash, Hash};
use ring::rand::SystemRandom;
@ -55,8 +54,8 @@ impl Mint {
}
pub fn create_entries(&self) -> Vec<Entry> {
let e0 = create_entry(&self.seed(), 0, vec![]);
let e1 = create_entry(&e0.id, 0, self.create_events());
let e0 = Entry::new(&self.seed(), 0, vec![]);
let e1 = Entry::new(&e0.id, 0, self.create_events());
vec![e0, e1]
}
}

View File

@ -5,7 +5,7 @@
//! Event, the latest hash, and the number of hashes since the last event.
//! The resulting stream of entries represents ordered events in time.
use entry::{create_entry_mut, Entry};
use entry::Entry;
use event::Event;
use hash::{hash, Hash};
use std::sync::mpsc::{Receiver, Sender, TryRecvError};
@ -48,7 +48,7 @@ impl Recorder {
}
pub fn record_entry(&mut self, events: Vec<Event>) -> Result<(), ExitReason> {
let entry = create_entry_mut(&mut self.last_hash, &mut self.num_hashes, events);
let entry = Entry::new_mut(&mut self.last_hash, &mut self.num_hashes, events);
self.sender
.send(entry)
.or(Err(ExitReason::SendDisconnected))?;
@ -89,7 +89,6 @@ mod tests {
use super::*;
use signature::{KeyPair, KeyPairUtil};
use std::sync::mpsc::channel;
use transaction::Transaction;
#[test]
fn test_events() {
@ -99,8 +98,8 @@ mod tests {
let mut recorder = Recorder::new(signal_receiver, entry_sender, zero);
let alice_keypair = KeyPair::new();
let bob_pubkey = KeyPair::new().pubkey();
let event0 = Event::Transaction(Transaction::new(&alice_keypair, bob_pubkey, 1, zero));
let event1 = Event::Transaction(Transaction::new(&alice_keypair, bob_pubkey, 2, zero));
let event0 = Event::new_transaction(&alice_keypair, bob_pubkey, 1, zero);
let event1 = Event::new_transaction(&alice_keypair, bob_pubkey, 2, zero);
signal_sender
.send(Signal::Events(vec![event0, event1]))
.unwrap();

View File

@ -218,7 +218,7 @@ mod tests {
use bincode::serialize;
use chrono::prelude::*;
use crdt::Crdt;
use entry;
use entry::Entry;
use event::Event;
use hash::{hash, Hash};
use logger;
@ -231,7 +231,6 @@ mod tests {
use std::sync::{Arc, RwLock};
use std::time::Duration;
use streamer;
use transaction::Transaction;
use tvu::{test_node, Tvu};
/// Test that mesasge sent from leader to target1 and repliated to target2
@ -320,11 +319,11 @@ mod tests {
let bank = &tvu.bank;
let tr0 = Event::new_timestamp(&bob_keypair, Utc::now());
let entry0 = entry::create_entry(&cur_hash, i, vec![tr0]);
let entry0 = Entry::new(&cur_hash, i, vec![tr0]);
bank.register_entry_id(&cur_hash);
cur_hash = hash(&cur_hash);
let tr1 = Transaction::new(
let tr1 = Event::new_transaction(
&mint.keypair(),
bob_keypair.pubkey(),
transfer_amount,
@ -332,8 +331,7 @@ mod tests {
);
bank.register_entry_id(&cur_hash);
cur_hash = hash(&cur_hash);
let entry1 =
entry::create_entry(&cur_hash, i + num_blobs, vec![Event::Transaction(tr1)]);
let entry1 = Entry::new(&cur_hash, i + num_blobs, vec![tr1]);
bank.register_entry_id(&cur_hash);
cur_hash = hash(&cur_hash);