Merge pull request #93 from garious/par-req-processing

Better benchmark, fix logging
This commit is contained in:
Greg Fitzgerald
2018-03-29 14:02:40 -06:00
committed by GitHub
3 changed files with 29 additions and 22 deletions

View File

@ -94,12 +94,8 @@ impl Accountant {
} }
} }
/// Verify and process the given Transaction. /// Process and log the given Transaction.
pub fn process_transaction(self: &mut Self, tr: Transaction) -> Result<()> { pub fn log_verified_transaction(&mut self, tr: Transaction) -> Result<()> {
if !tr.verify() {
return Err(AccountingError::InvalidTransfer);
}
if self.get_balance(&tr.from).unwrap_or(0) < tr.tokens { if self.get_balance(&tr.from).unwrap_or(0) < tr.tokens {
return Err(AccountingError::InsufficientFunds); return Err(AccountingError::InsufficientFunds);
} }
@ -115,8 +111,17 @@ impl Accountant {
Ok(()) Ok(())
} }
/// Verify and process the given Transaction.
pub fn log_transaction(&mut self, tr: Transaction) -> Result<()> {
if !tr.verify() {
return Err(AccountingError::InvalidTransfer);
}
self.log_verified_transaction(tr)
}
/// Process a Transaction that has already been verified. /// Process a Transaction that has already been verified.
pub fn process_verified_transaction( fn process_verified_transaction(
self: &mut Self, self: &mut Self,
tr: &Transaction, tr: &Transaction,
allow_deposits: bool, allow_deposits: bool,
@ -209,7 +214,7 @@ impl Accountant {
) -> Result<Signature> { ) -> Result<Signature> {
let tr = Transaction::new(keypair, to, n, last_id); let tr = Transaction::new(keypair, to, n, last_id);
let sig = tr.sig; let sig = tr.sig;
self.process_transaction(tr).map(|_| sig) self.log_transaction(tr).map(|_| sig)
} }
/// Create, sign, and process a postdated Transaction from `keypair` /// Create, sign, and process a postdated Transaction from `keypair`
@ -225,7 +230,7 @@ impl Accountant {
) -> Result<Signature> { ) -> Result<Signature> {
let tr = Transaction::new_on_date(keypair, to, dt, n, last_id); let tr = Transaction::new_on_date(keypair, to, dt, n, last_id);
let sig = tr.sig; let sig = tr.sig;
self.process_transaction(tr).map(|_| sig) self.log_transaction(tr).map(|_| sig)
} }
pub fn get_balance(self: &Self, pubkey: &PublicKey) -> Option<i64> { pub fn get_balance(self: &Self, pubkey: &PublicKey) -> Option<i64> {
@ -292,7 +297,7 @@ mod tests {
payment.tokens = 2; // <-- attack! payment.tokens = 2; // <-- attack!
} }
assert_eq!( assert_eq!(
acc.process_transaction(tr.clone()), acc.log_transaction(tr.clone()),
Err(AccountingError::InvalidTransfer) Err(AccountingError::InvalidTransfer)
); );
@ -301,7 +306,7 @@ mod tests {
payment.tokens = 0; // <-- whoops! payment.tokens = 0; // <-- whoops!
} }
assert_eq!( assert_eq!(
acc.process_transaction(tr.clone()), acc.log_transaction(tr.clone()),
Err(AccountingError::InvalidTransfer) Err(AccountingError::InvalidTransfer)
); );
} }

View File

@ -78,10 +78,10 @@ impl<W: Write + Send + 'static> AccountantSkel<W> {
} }
/// Process Request items sent by clients. /// Process Request items sent by clients.
pub fn process_verified_request(self: &mut Self, msg: Request) -> Option<Response> { pub fn log_verified_request(&mut self, msg: Request) -> Option<Response> {
match msg { match msg {
Request::Transaction(tr) => { Request::Transaction(tr) => {
if let Err(err) = self.acc.process_verified_transaction(&tr, false) { if let Err(err) = self.acc.log_verified_transaction(tr) {
eprintln!("Transaction error: {:?}", err); eprintln!("Transaction error: {:?}", err);
} }
None None
@ -126,7 +126,7 @@ impl<W: Write + Send + 'static> AccountantSkel<W> {
let mut num = 0; let mut num = 0;
let mut ursps = rsps.write().unwrap(); let mut ursps = rsps.write().unwrap();
for (req, rsp_addr) in reqs { for (req, rsp_addr) in reqs {
if let Some(resp) = obj.lock().unwrap().process_verified_request(req) { if let Some(resp) = obj.lock().unwrap().log_verified_request(req) {
if ursps.responses.len() <= num { if ursps.responses.len() <= num {
ursps ursps
.responses .responses

View File

@ -8,7 +8,8 @@ use solana::signature::{KeyPair, KeyPairUtil};
use solana::transaction::Transaction; use solana::transaction::Transaction;
use std::io::stdin; use std::io::stdin;
use std::net::UdpSocket; use std::net::UdpSocket;
use std::time::Instant; use std::time::{Duration, Instant};
use std::thread::sleep;
use rayon::prelude::*; use rayon::prelude::*;
fn main() { fn main() {
@ -27,7 +28,7 @@ fn main() {
println!("Mint's Initial Balance {}", mint_balance); println!("Mint's Initial Balance {}", mint_balance);
println!("Signing transactions..."); println!("Signing transactions...");
let txs = 10_000; let txs = 100_000;
let now = Instant::now(); let now = Instant::now();
let transactions: Vec<_> = (0..txs) let transactions: Vec<_> = (0..txs)
.into_par_iter() .into_par_iter()
@ -55,17 +56,18 @@ fn main() {
} }
println!("Waiting for last transaction to be confirmed...",); println!("Waiting for last transaction to be confirmed...",);
let mut val = mint_balance; let mut val = mint_balance;
while val > mint_balance - txs { let mut prev = 0;
while val != prev {
sleep(Duration::from_millis(20));
prev = val;
val = acc.get_balance(&mint_pubkey).unwrap().unwrap(); val = acc.get_balance(&mint_pubkey).unwrap().unwrap();
} }
println!("Mint's Final Balance {}", val);
let txs = mint_balance - val;
println!("Successful transactions {}", txs);
let duration = now.elapsed(); let duration = now.elapsed();
let ns = duration.as_secs() * 1_000_000_000 + u64::from(duration.subsec_nanos()); let ns = duration.as_secs() * 1_000_000_000 + u64::from(duration.subsec_nanos());
let tps = (txs * 1_000_000_000) as f64 / ns as f64; let tps = (txs * 1_000_000_000) as f64 / ns as f64;
println!("Done. {} tps!", tps); println!("Done. {} tps!", tps);
println!("Mint's Final Balance {}", val);
assert_eq!(val, mint_balance - txs);
// Force the ledger to print on the server.
acc.get_last_id().unwrap();
} }