diff --git a/src/accountant.rs b/src/accountant.rs index 0718ef63e6..3035615175 100644 --- a/src/accountant.rs +++ b/src/accountant.rs @@ -48,70 +48,62 @@ impl Accountant { entries } - pub fn deposit_signed(self: &mut Self, to: PublicKey, data: u64, sig: Signature) -> Result<()> { - let event = Event::new_claim(to, data, sig); - if !self.historian.verify_event(&event) { - return Err(AccountingError::InvalidEvent); - } - if let Err(SendError(_)) = self.historian.sender.send(event) { - return Err(AccountingError::SendError); - } - - if self.balances.contains_key(&to) { - if let Some(x) = self.balances.get_mut(&to) { - *x += data; - } - } else { - self.balances.insert(to, data); - } - - Ok(()) - } - pub fn deposit(self: &mut Self, n: u64, keypair: &Ed25519KeyPair) -> Result { use event::{get_pubkey, sign_claim_data}; - let key = get_pubkey(keypair); + let to = get_pubkey(keypair); let sig = sign_claim_data(&n, keypair); - self.deposit_signed(key, n, sig).map(|_| sig) - } - - pub fn transfer_signed( - self: &mut Self, - from: PublicKey, - to: PublicKey, - data: u64, - sig: Signature, - ) -> Result<()> { - if self.get_balance(&from).unwrap_or(0) < data { - return Err(AccountingError::InsufficientFunds); - } - - let event = Event::Transaction { - from, - to, - data, - sig, - }; + let event = Event::new_claim(to, n, sig); if !self.historian.verify_event(&event) { return Err(AccountingError::InvalidEvent); } - if let Err(SendError(_)) = self.historian.sender.send(event) { - return Err(AccountingError::SendError); - } + self.process_verified_event(event, true).map(|_| sig) + } - if let Some(x) = self.balances.get_mut(&from) { - *x -= data; - } + fn is_deposit(allow_deposits: bool, from: &PublicKey, to: &PublicKey) -> bool { + allow_deposits && from == to + } - if self.balances.contains_key(&to) { - if let Some(x) = self.balances.get_mut(&to) { - *x += data; + pub fn process_event(self: &mut Self, event: Event) -> Result<()> { + if !self.historian.verify_event(&event) { + return Err(AccountingError::InvalidEvent); + } + self.process_verified_event(event, false) + } + + fn process_verified_event( + self: &mut Self, + event: Event, + allow_deposits: bool, + ) -> Result<()> { + match event { + Event::Tick => Ok(()), + Event::Transaction { from, to, data, .. } => { + if !Self::is_deposit(allow_deposits, &from, &to) { + if self.get_balance(&from).unwrap_or(0) < data { + return Err(AccountingError::InsufficientFunds); + } + } + + if let Err(SendError(_)) = self.historian.sender.send(event) { + return Err(AccountingError::SendError); + } + + if !Self::is_deposit(allow_deposits, &from, &to) { + if let Some(x) = self.balances.get_mut(&from) { + *x -= data; + } + } + + if self.balances.contains_key(&to) { + if let Some(x) = self.balances.get_mut(&to) { + *x += data; + } + } else { + self.balances.insert(to, data); + } + Ok(()) } - } else { - self.balances.insert(to, data); } - - Ok(()) } pub fn transfer( @@ -123,7 +115,13 @@ impl Accountant { use event::{get_pubkey, sign_transaction_data}; let from = get_pubkey(keypair); let sig = sign_transaction_data(&n, keypair, &to); - self.transfer_signed(from, to, n, sig).map(|_| sig) + let event = Event::Transaction { + from, + to, + data: n, + sig, + }; + self.process_event(event).map(|_| sig) } pub fn get_balance(self: &Self, pubkey: &PublicKey) -> Option { diff --git a/src/accountant_skel.rs b/src/accountant_skel.rs index 2aaefde117..7164e690e3 100644 --- a/src/accountant_skel.rs +++ b/src/accountant_skel.rs @@ -1,7 +1,6 @@ use std::io; use accountant::Accountant; -use event::{PublicKey, Signature}; -//use serde::Serialize; +use event::{Event, PublicKey, Signature}; pub struct AccountantSkel { pub obj: Accountant, @@ -9,11 +8,6 @@ pub struct AccountantSkel { #[derive(Serialize, Deserialize, Debug)] pub enum Request { - Deposit { - key: PublicKey, - val: u64, - sig: Signature, - }, Transfer { from: PublicKey, to: PublicKey, @@ -41,14 +35,14 @@ impl AccountantSkel { pub fn process_request(self: &mut Self, msg: Request) -> Option { match msg { - Request::Deposit { key, val, sig } => { - if let Err(err) = self.obj.deposit_signed(key, val, sig) { - println!("Deposit error: {:?}", err); - } - None - } Request::Transfer { from, to, val, sig } => { - if let Err(err) = self.obj.transfer_signed(from, to, val, sig) { + let event = Event::Transaction { + from, + to, + data: val, + sig, + }; + if let Err(err) = self.obj.process_event(event) { println!("Transfer error: {:?}", err); } None