Refactor to support loading an existing ledger

This commit is contained in:
Greg Fitzgerald
2018-03-03 22:25:37 -07:00
parent b8655e30d4
commit 876d7995e1
2 changed files with 61 additions and 69 deletions

View File

@ -48,70 +48,62 @@ impl Accountant {
entries 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<Signature> { pub fn deposit(self: &mut Self, n: u64, keypair: &Ed25519KeyPair) -> Result<Signature> {
use event::{get_pubkey, sign_claim_data}; use event::{get_pubkey, sign_claim_data};
let key = get_pubkey(keypair); let to = get_pubkey(keypair);
let sig = sign_claim_data(&n, keypair); let sig = sign_claim_data(&n, keypair);
self.deposit_signed(key, n, sig).map(|_| sig) let event = Event::new_claim(to, n, 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,
};
if !self.historian.verify_event(&event) { if !self.historian.verify_event(&event) {
return Err(AccountingError::InvalidEvent); return Err(AccountingError::InvalidEvent);
} }
if let Err(SendError(_)) = self.historian.sender.send(event) { self.process_verified_event(event, true).map(|_| sig)
return Err(AccountingError::SendError); }
}
if let Some(x) = self.balances.get_mut(&from) { fn is_deposit(allow_deposits: bool, from: &PublicKey, to: &PublicKey) -> bool {
*x -= data; allow_deposits && from == to
} }
if self.balances.contains_key(&to) { pub fn process_event(self: &mut Self, event: Event<u64>) -> Result<()> {
if let Some(x) = self.balances.get_mut(&to) { if !self.historian.verify_event(&event) {
*x += data; return Err(AccountingError::InvalidEvent);
}
self.process_verified_event(event, false)
}
fn process_verified_event(
self: &mut Self,
event: Event<u64>,
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( pub fn transfer(
@ -123,7 +115,13 @@ impl Accountant {
use event::{get_pubkey, sign_transaction_data}; use event::{get_pubkey, sign_transaction_data};
let from = get_pubkey(keypair); let from = get_pubkey(keypair);
let sig = sign_transaction_data(&n, keypair, &to); 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<u64> { pub fn get_balance(self: &Self, pubkey: &PublicKey) -> Option<u64> {

View File

@ -1,7 +1,6 @@
use std::io; use std::io;
use accountant::Accountant; use accountant::Accountant;
use event::{PublicKey, Signature}; use event::{Event, PublicKey, Signature};
//use serde::Serialize;
pub struct AccountantSkel { pub struct AccountantSkel {
pub obj: Accountant, pub obj: Accountant,
@ -9,11 +8,6 @@ pub struct AccountantSkel {
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub enum Request { pub enum Request {
Deposit {
key: PublicKey,
val: u64,
sig: Signature,
},
Transfer { Transfer {
from: PublicKey, from: PublicKey,
to: PublicKey, to: PublicKey,
@ -41,14 +35,14 @@ impl AccountantSkel {
pub fn process_request(self: &mut Self, msg: Request) -> Option<Response> { pub fn process_request(self: &mut Self, msg: Request) -> Option<Response> {
match msg { 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 } => { 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); println!("Transfer error: {:?}", err);
} }
None None