diff --git a/src/banking_stage.rs b/src/banking_stage.rs index cf72430c0a6040..606ee42f47b205 100644 --- a/src/banking_stage.rs +++ b/src/banking_stage.rs @@ -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); + } + }); + } +} diff --git a/src/bin/genesis-demo.rs b/src/bin/genesis-demo.rs index 0e408c11ec36b6..32873247933273 100644 --- a/src/bin/genesis-demo.rs +++ b/src/bin/genesis-demo.rs @@ -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); diff --git a/src/entry.rs b/src/entry.rs index 555cb5bbd4bd56..295fbc442839f6 100644 --- a/src/entry.rs +++ b/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) -> 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) -> 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) -> 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) -> 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) -> Entry { Entry { @@ -116,11 +116,10 @@ pub fn next_entry(start_hash: &Hash, num_hashes: u64, events: Vec) -> 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. diff --git a/src/event.rs b/src/event.rs index b3a317e1990918..f657f5c3f09154 100644 --- a/src/event.rs +++ b/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) -> Self { let sign_data = serialize(&dt).expect("serialize 'dt' in pub fn new_timestamp"); diff --git a/src/ledger.rs b/src/ledger.rs index 1b1895d4c1a520..f63846e008d1e5 100644 --- a/src/ledger.rs +++ b/src/ledger.rs @@ -123,7 +123,6 @@ pub fn reconstruct_entries_from_blobs(blobs: &VecDeque) -> Vec Vec { - 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] } } diff --git a/src/recorder.rs b/src/recorder.rs index 3866747fa2ba1b..09e0d471e7e20f 100644 --- a/src/recorder.rs +++ b/src/recorder.rs @@ -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) -> 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(); diff --git a/src/tvu.rs b/src/tvu.rs index 3a87a6dab4ef44..f0ec2ccac6f402 100644 --- a/src/tvu.rs +++ b/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);