Move smart contract fields into their own struct

This commit is contained in:
Greg Fitzgerald 2018-03-10 16:55:39 -07:00
parent 1e07014f86
commit 7a0bc7d888
3 changed files with 38 additions and 23 deletions

View File

@ -109,12 +109,12 @@ impl Accountant {
/// Commit funds to the 'to' party.
fn complete_transaction(self: &mut Self, tr: &Transaction<i64>) {
if self.balances.contains_key(&tr.to) {
if let Some(x) = self.balances.get_mut(&tr.to) {
if self.balances.contains_key(&tr.plan.to) {
if let Some(x) = self.balances.get_mut(&tr.plan.to) {
*x += tr.asset;
}
} else {
self.balances.insert(tr.to, tr.asset);
self.balances.insert(tr.plan.to, tr.asset);
}
}
@ -149,17 +149,17 @@ impl Accountant {
return Err(AccountingError::InvalidTransferSignature);
}
if !tr.unless_any.is_empty() {
if !tr.plan.unless_any.is_empty() {
// TODO: Check to see if the transaction is expired.
}
if !Self::is_deposit(allow_deposits, &tr.from, &tr.to) {
if !Self::is_deposit(allow_deposits, &tr.from, &tr.plan.to) {
if let Some(x) = self.balances.get_mut(&tr.from) {
*x -= tr.asset;
}
}
if !self.all_satisfied(&tr.if_all) {
if !self.all_satisfied(&tr.plan.if_all) {
self.pending.insert(tr.sig, tr.clone());
return Ok(());
}
@ -175,7 +175,7 @@ impl Accountant {
// if Signature(from) is in unless_any, return funds to tx.from, and remove the tx from this map.
// TODO: Use find().
for cond in &tr.unless_any {
for cond in &tr.plan.unless_any {
if let Condition::Signature(pubkey) = *cond {
if from == pubkey {
cancel = true;
@ -220,17 +220,17 @@ impl Accountant {
// Check to see if any timelocked transactions can be completed.
let mut completed = vec![];
for (key, tr) in &self.pending {
for cond in &tr.if_all {
for cond in &tr.plan.if_all {
if let Condition::Timestamp(dt) = *cond {
if self.last_time >= dt {
if tr.if_all.len() == 1 {
if tr.plan.if_all.len() == 1 {
completed.push(*key);
}
}
}
}
// TODO: Add this in once we start removing constraints
//if tr.if_all.is_empty() {
//if tr.plan.if_all.is_empty() {
// // TODO: Remove tr from pending
// self.complete_transaction(tr);
//}

View File

@ -63,7 +63,7 @@ mod tests {
fn test_create_events() {
let mut events = Mint::new(100).create_events().into_iter();
if let Event::Transaction(tr) = events.next().unwrap() {
assert_eq!(tr.from, tr.to);
assert_eq!(tr.from, tr.plan.to);
}
assert_eq!(events.next(), None);
}

View File

@ -13,11 +13,16 @@ pub enum Condition {
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Transaction<T> {
pub from: PublicKey,
pub struct SpendingPlan {
pub to: PublicKey,
pub if_all: Vec<Condition>,
pub unless_any: Vec<Condition>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Transaction<T> {
pub from: PublicKey,
pub plan: SpendingPlan,
pub asset: T,
pub last_id: Hash,
pub sig: Signature,
@ -25,11 +30,14 @@ pub struct Transaction<T> {
impl<T: Serialize> Transaction<T> {
pub fn new(from_keypair: &KeyPair, to: PublicKey, asset: T, last_id: Hash) -> Self {
let mut tr = Transaction {
from: from_keypair.pubkey(),
let plan = SpendingPlan {
to,
if_all: vec![],
unless_any: vec![],
};
let mut tr = Transaction {
from: from_keypair.pubkey(),
plan,
asset,
last_id,
sig: Signature::default(),
@ -46,11 +54,14 @@ impl<T: Serialize> Transaction<T> {
last_id: Hash,
) -> Self {
let from = from_keypair.pubkey();
let mut tr = Transaction {
from,
let plan = SpendingPlan {
to,
if_all: vec![Condition::Timestamp(dt)],
unless_any: vec![Condition::Signature(from)],
};
let mut tr = Transaction {
from,
plan,
asset,
last_id,
sig: Signature::default(),
@ -60,11 +71,12 @@ impl<T: Serialize> Transaction<T> {
}
fn get_sign_data(&self) -> Vec<u8> {
let plan = &self.plan;
serialize(&(
&self.from,
&self.to,
&self.if_all,
&self.unless_any,
&plan.to,
&plan.if_all,
&plan.unless_any,
&self.asset,
&self.last_id,
)).unwrap()
@ -108,11 +120,14 @@ mod tests {
#[test]
fn test_serialize_claim() {
let claim0 = Transaction {
from: Default::default(),
let plan = SpendingPlan {
to: Default::default(),
if_all: Default::default(),
unless_any: Default::default(),
};
let claim0 = Transaction {
from: Default::default(),
plan,
asset: 0u8,
last_id: Default::default(),
sig: Default::default(),
@ -142,7 +157,7 @@ mod tests {
let zero = Hash::default();
let mut tr = Transaction::new(&keypair0, pubkey1, hash(b"hello, world"), zero);
tr.sign(&keypair0);
tr.to = thief_keypair.pubkey(); // <-- attack!
tr.plan.to = thief_keypair.pubkey(); // <-- attack!
assert!(!tr.verify());
}
}