asset -> tokens
This commit is contained in:
parent
4f09e5d04c
commit
265f41887f
|
@ -97,7 +97,7 @@ impl Accountant {
|
|||
return Err(AccountingError::InvalidTransfer);
|
||||
}
|
||||
|
||||
if self.get_balance(&tr.from).unwrap_or(0) < tr.asset {
|
||||
if self.get_balance(&tr.from).unwrap_or(0) < tr.tokens {
|
||||
return Err(AccountingError::InsufficientFunds);
|
||||
}
|
||||
|
||||
|
@ -117,10 +117,10 @@ impl Accountant {
|
|||
if let Plan::Action(Action::Pay(ref payment)) = *plan {
|
||||
if self.balances.contains_key(&payment.to) {
|
||||
if let Some(x) = self.balances.get_mut(&payment.to) {
|
||||
*x += payment.asset;
|
||||
*x += payment.tokens;
|
||||
}
|
||||
} else {
|
||||
self.balances.insert(payment.to, payment.asset);
|
||||
self.balances.insert(payment.to, payment.tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ impl Accountant {
|
|||
|
||||
if !Self::is_deposit(allow_deposits, &tr.from, &tr.plan) {
|
||||
if let Some(x) = self.balances.get_mut(&tr.from) {
|
||||
*x -= tr.asset;
|
||||
*x -= tr.tokens;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,16 +289,16 @@ mod tests {
|
|||
let bob_pubkey = KeyPair::new().pubkey();
|
||||
let mut tr = Transaction::new(&alice.keypair(), bob_pubkey, 1, alice.seed());
|
||||
if let Plan::Action(Action::Pay(ref mut payment)) = tr.plan {
|
||||
payment.asset = 2; // <-- attack!
|
||||
payment.tokens = 2; // <-- attack!
|
||||
}
|
||||
assert_eq!(
|
||||
acc.process_transaction(tr.clone()),
|
||||
Err(AccountingError::InvalidTransfer)
|
||||
);
|
||||
|
||||
// Also, ensure all branchs of the plan spend all assets
|
||||
// Also, ensure all branchs of the plan spend all tokens
|
||||
if let Plan::Action(Action::Pay(ref mut payment)) = tr.plan {
|
||||
payment.asset = 0; // <-- whoops!
|
||||
payment.tokens = 0; // <-- whoops!
|
||||
}
|
||||
assert_eq!(
|
||||
acc.process_transaction(tr.clone()),
|
||||
|
|
36
src/plan.rs
36
src/plan.rs
|
@ -35,14 +35,14 @@ pub enum Action {
|
|||
impl Action {
|
||||
pub fn spendable(&self) -> i64 {
|
||||
match *self {
|
||||
Action::Pay(ref payment) => payment.asset,
|
||||
Action::Pay(ref payment) => payment.tokens,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Payment {
|
||||
pub asset: i64,
|
||||
pub tokens: i64,
|
||||
pub to: PublicKey,
|
||||
}
|
||||
|
||||
|
@ -54,42 +54,48 @@ pub enum Plan {
|
|||
}
|
||||
|
||||
impl Plan {
|
||||
pub fn new_payment(asset: i64, to: PublicKey) -> Self {
|
||||
Plan::Action(Action::Pay(Payment { asset, to }))
|
||||
pub fn new_payment(tokens: i64, to: PublicKey) -> Self {
|
||||
Plan::Action(Action::Pay(Payment { tokens, to }))
|
||||
}
|
||||
|
||||
pub fn new_authorized_payment(from: PublicKey, asset: i64, to: PublicKey) -> Self {
|
||||
pub fn new_authorized_payment(from: PublicKey, tokens: i64, to: PublicKey) -> Self {
|
||||
Plan::After(
|
||||
Condition::Signature(from),
|
||||
Action::Pay(Payment { asset, to }),
|
||||
Action::Pay(Payment { tokens, to }),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_future_payment(dt: DateTime<Utc>, asset: i64, to: PublicKey) -> Self {
|
||||
Plan::After(Condition::Timestamp(dt), Action::Pay(Payment { asset, to }))
|
||||
pub fn new_future_payment(dt: DateTime<Utc>, tokens: i64, to: PublicKey) -> Self {
|
||||
Plan::After(
|
||||
Condition::Timestamp(dt),
|
||||
Action::Pay(Payment { tokens, to }),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_cancelable_future_payment(
|
||||
dt: DateTime<Utc>,
|
||||
from: PublicKey,
|
||||
asset: i64,
|
||||
tokens: i64,
|
||||
to: PublicKey,
|
||||
) -> Self {
|
||||
Plan::Race(
|
||||
(Condition::Timestamp(dt), Action::Pay(Payment { asset, to })),
|
||||
(
|
||||
Condition::Timestamp(dt),
|
||||
Action::Pay(Payment { tokens, to }),
|
||||
),
|
||||
(
|
||||
Condition::Signature(from),
|
||||
Action::Pay(Payment { asset, to: from }),
|
||||
Action::Pay(Payment { tokens, to: from }),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn verify(&self, spendable_assets: i64) -> bool {
|
||||
pub fn verify(&self, spendable_tokens: i64) -> bool {
|
||||
match *self {
|
||||
Plan::Action(ref action) => action.spendable() == spendable_assets,
|
||||
Plan::After(_, ref action) => action.spendable() == spendable_assets,
|
||||
Plan::Action(ref action) => action.spendable() == spendable_tokens,
|
||||
Plan::After(_, ref action) => action.spendable() == spendable_tokens,
|
||||
Plan::Race(ref a, ref b) => {
|
||||
a.1.spendable() == spendable_assets && b.1.spendable() == spendable_assets
|
||||
a.1.spendable() == spendable_tokens && b.1.spendable() == spendable_tokens
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,19 +10,19 @@ use plan::{Action, Condition, Payment, Plan};
|
|||
pub struct Transaction {
|
||||
pub from: PublicKey,
|
||||
pub plan: Plan,
|
||||
pub asset: i64,
|
||||
pub tokens: i64,
|
||||
pub last_id: Hash,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
impl Transaction {
|
||||
pub fn new(from_keypair: &KeyPair, to: PublicKey, asset: i64, last_id: Hash) -> Self {
|
||||
pub fn new(from_keypair: &KeyPair, to: PublicKey, tokens: i64, last_id: Hash) -> Self {
|
||||
let from = from_keypair.pubkey();
|
||||
let plan = Plan::Action(Action::Pay(Payment { asset, to }));
|
||||
let plan = Plan::Action(Action::Pay(Payment { tokens, to }));
|
||||
let mut tr = Transaction {
|
||||
from,
|
||||
plan,
|
||||
asset,
|
||||
tokens,
|
||||
last_id,
|
||||
sig: Signature::default(),
|
||||
};
|
||||
|
@ -34,21 +34,24 @@ impl Transaction {
|
|||
from_keypair: &KeyPair,
|
||||
to: PublicKey,
|
||||
dt: DateTime<Utc>,
|
||||
asset: i64,
|
||||
tokens: i64,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
let from = from_keypair.pubkey();
|
||||
let plan = Plan::Race(
|
||||
(Condition::Timestamp(dt), Action::Pay(Payment { asset, to })),
|
||||
(
|
||||
Condition::Timestamp(dt),
|
||||
Action::Pay(Payment { tokens, to }),
|
||||
),
|
||||
(
|
||||
Condition::Signature(from),
|
||||
Action::Pay(Payment { asset, to: from }),
|
||||
Action::Pay(Payment { tokens, to: from }),
|
||||
),
|
||||
);
|
||||
let mut tr = Transaction {
|
||||
from,
|
||||
plan,
|
||||
asset,
|
||||
tokens,
|
||||
last_id,
|
||||
sig: Signature::default(),
|
||||
};
|
||||
|
@ -57,7 +60,7 @@ impl Transaction {
|
|||
}
|
||||
|
||||
fn get_sign_data(&self) -> Vec<u8> {
|
||||
serialize(&(&self.from, &self.plan, &self.asset, &self.last_id)).unwrap()
|
||||
serialize(&(&self.from, &self.plan, &self.tokens, &self.last_id)).unwrap()
|
||||
}
|
||||
|
||||
pub fn sign(&mut self, keypair: &KeyPair) {
|
||||
|
@ -66,7 +69,7 @@ impl Transaction {
|
|||
}
|
||||
|
||||
pub fn verify(&self) -> bool {
|
||||
self.sig.verify(&self.from, &self.get_sign_data()) && self.plan.verify(self.asset)
|
||||
self.sig.verify(&self.from, &self.get_sign_data()) && self.plan.verify(self.tokens)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,13 +99,13 @@ mod tests {
|
|||
#[test]
|
||||
fn test_serialize_claim() {
|
||||
let plan = Plan::Action(Action::Pay(Payment {
|
||||
asset: 0,
|
||||
tokens: 0,
|
||||
to: Default::default(),
|
||||
}));
|
||||
let claim0 = Transaction {
|
||||
from: Default::default(),
|
||||
plan,
|
||||
asset: 0,
|
||||
tokens: 0,
|
||||
last_id: Default::default(),
|
||||
sig: Default::default(),
|
||||
};
|
||||
|
@ -118,7 +121,7 @@ mod tests {
|
|||
let pubkey = keypair.pubkey();
|
||||
let mut tr = Transaction::new(&keypair, pubkey, 42, zero);
|
||||
tr.sign(&keypair);
|
||||
tr.asset = 1_000_000; // <-- attack!
|
||||
tr.tokens = 1_000_000; // <-- attack!
|
||||
assert!(!tr.verify());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue