Merge pull request #230 from garious/generalize-topackets
Benchmark the banking stage
This commit is contained in:
commit
2786357082
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
49
src/entry.rs
49
src/entry.rs
|
@ -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.
|
||||
|
|
11
src/event.rs
11
src/event.rs
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
10
src/tvu.rs
10
src/tvu.rs
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue