Refactor to support loading an existing ledger
This commit is contained in:
@ -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> {
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user