commit
5c672adc21
|
@ -17,7 +17,6 @@ use transaction::Transaction;
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum AccountingError {
|
pub enum AccountingError {
|
||||||
InsufficientFunds,
|
InsufficientFunds,
|
||||||
InvalidTransfer,
|
|
||||||
InvalidTransferSignature,
|
InvalidTransferSignature,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,15 +58,6 @@ impl Accountant {
|
||||||
Self::new_from_deposit(&deposit)
|
Self::new_from_deposit(&deposit)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verify and process the given Transaction.
|
|
||||||
pub fn process_transaction(&mut self, tr: Transaction) -> Result<()> {
|
|
||||||
if !tr.verify() {
|
|
||||||
return Err(AccountingError::InvalidTransfer);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.process_verified_transaction(&tr)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reserve_signature(&mut self, sig: &Signature) -> bool {
|
fn reserve_signature(&mut self, sig: &Signature) -> bool {
|
||||||
if self.signatures.contains(sig) {
|
if self.signatures.contains(sig) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -168,7 +158,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.process_verified_transaction(&tr).map(|_| sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create, sign, and process a postdated Transaction from `keypair`
|
/// Create, sign, and process a postdated Transaction from `keypair`
|
||||||
|
@ -184,7 +174,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.process_verified_transaction(&tr).map(|_| sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_balance(&self, pubkey: &PublicKey) -> Option<i64> {
|
pub fn get_balance(&self, pubkey: &PublicKey) -> Option<i64> {
|
||||||
|
@ -228,30 +218,6 @@ mod tests {
|
||||||
assert_eq!(acc.get_balance(&bob_pubkey).unwrap(), 1_000);
|
assert_eq!(acc.get_balance(&bob_pubkey).unwrap(), 1_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_overspend_attack() {
|
|
||||||
let alice = Mint::new(1);
|
|
||||||
let mut acc = Accountant::new(&alice);
|
|
||||||
let bob_pubkey = KeyPair::new().pubkey();
|
|
||||||
let mut tr = Transaction::new(&alice.keypair(), bob_pubkey, 1, alice.last_id());
|
|
||||||
if let Plan::Pay(ref mut payment) = tr.plan {
|
|
||||||
payment.tokens = 2; // <-- attack!
|
|
||||||
}
|
|
||||||
assert_eq!(
|
|
||||||
acc.process_transaction(tr.clone()),
|
|
||||||
Err(AccountingError::InvalidTransfer)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Also, ensure all branchs of the plan spend all tokens
|
|
||||||
if let Plan::Pay(ref mut payment) = tr.plan {
|
|
||||||
payment.tokens = 0; // <-- whoops!
|
|
||||||
}
|
|
||||||
assert_eq!(
|
|
||||||
acc.process_transaction(tr.clone()),
|
|
||||||
Err(AccountingError::InvalidTransfer)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_transfer_to_newb() {
|
fn test_transfer_to_newb() {
|
||||||
let alice = Mint::new(10_000);
|
let alice = Mint::new(10_000);
|
||||||
|
|
|
@ -154,6 +154,24 @@ mod tests {
|
||||||
assert!(!tr.verify());
|
assert!(!tr.verify());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_overspend_attack() {
|
||||||
|
let keypair0 = KeyPair::new();
|
||||||
|
let keypair1 = KeyPair::new();
|
||||||
|
let zero = Hash::default();
|
||||||
|
let mut tr = Transaction::new(&keypair0, keypair1.pubkey(), 1, zero);
|
||||||
|
if let Plan::Pay(ref mut payment) = tr.plan {
|
||||||
|
payment.tokens = 2; // <-- attack!
|
||||||
|
}
|
||||||
|
assert!(!tr.verify());
|
||||||
|
|
||||||
|
// Also, ensure all branchs of the plan spend all tokens
|
||||||
|
if let Plan::Pay(ref mut payment) = tr.plan {
|
||||||
|
payment.tokens = 0; // <-- whoops!
|
||||||
|
}
|
||||||
|
assert!(!tr.verify());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_verify_transactions() {
|
fn test_verify_transactions() {
|
||||||
let alice_keypair = KeyPair::new();
|
let alice_keypair = KeyPair::new();
|
||||||
|
|
Loading…
Reference in New Issue