Merge pull request #48 from garious/add-transaction-struct
data -> asset
This commit is contained in:
commit
cb436250da
|
@ -19,9 +19,9 @@ use std::sync::mpsc::SendError;
|
||||||
|
|
||||||
fn create_log(hist: &Historian<Sha256Hash>) -> Result<(), SendError<Event<Sha256Hash>>> {
|
fn create_log(hist: &Historian<Sha256Hash>) -> Result<(), SendError<Event<Sha256Hash>>> {
|
||||||
sleep(Duration::from_millis(15));
|
sleep(Duration::from_millis(15));
|
||||||
let data = Sha256Hash::default();
|
let asset = Sha256Hash::default();
|
||||||
let keypair = generate_keypair();
|
let keypair = generate_keypair();
|
||||||
let event0 = Event::new_claim(get_pubkey(&keypair), data, sign_claim_data(&data, &keypair));
|
let event0 = Event::new_claim(get_pubkey(&keypair), asset, sign_claim_data(&asset, &keypair));
|
||||||
hist.sender.send(event0)?;
|
hist.sender.send(event0)?;
|
||||||
sleep(Duration::from_millis(10));
|
sleep(Duration::from_millis(10));
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -46,7 +46,7 @@ Running the program should produce a log similar to:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
Entry { num_hashes: 0, id: [0, ...], event: Tick }
|
Entry { num_hashes: 0, id: [0, ...], event: Tick }
|
||||||
Entry { num_hashes: 3, id: [67, ...], event: Transaction { data: [37, ...] } }
|
Entry { num_hashes: 3, id: [67, ...], event: Transaction { asset: [37, ...] } }
|
||||||
Entry { num_hashes: 3, id: [123, ...], event: Tick }
|
Entry { num_hashes: 3, id: [123, ...], event: Tick }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ impl Accountant {
|
||||||
return Err(AccountingError::InvalidTransfer);
|
return Err(AccountingError::InvalidTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.get_balance(&tr.from).unwrap_or(0) < tr.data {
|
if self.get_balance(&tr.from).unwrap_or(0) < tr.asset {
|
||||||
return Err(AccountingError::InsufficientFunds);
|
return Err(AccountingError::InsufficientFunds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,16 +105,16 @@ impl Accountant {
|
||||||
|
|
||||||
if !Self::is_deposit(allow_deposits, &tr.from, &tr.to) {
|
if !Self::is_deposit(allow_deposits, &tr.from, &tr.to) {
|
||||||
if let Some(x) = self.balances.get_mut(&tr.from) {
|
if let Some(x) = self.balances.get_mut(&tr.from) {
|
||||||
*x -= tr.data;
|
*x -= tr.asset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.balances.contains_key(&tr.to) {
|
if self.balances.contains_key(&tr.to) {
|
||||||
if let Some(x) = self.balances.get_mut(&tr.to) {
|
if let Some(x) = self.balances.get_mut(&tr.to) {
|
||||||
*x += tr.data;
|
*x += tr.asset;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.balances.insert(tr.to, tr.data);
|
self.balances.insert(tr.to, tr.asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -143,7 +143,7 @@ impl Accountant {
|
||||||
let tr = Transaction {
|
let tr = Transaction {
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
data: n,
|
asset: n,
|
||||||
last_id,
|
last_id,
|
||||||
sig,
|
sig,
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl AccountantStub {
|
||||||
let req = Request::Transaction(Transaction {
|
let req = Request::Transaction(Transaction {
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
data: val,
|
asset: val,
|
||||||
last_id,
|
last_id,
|
||||||
sig,
|
sig,
|
||||||
});
|
});
|
||||||
|
|
|
@ -52,7 +52,7 @@ fn main() {
|
||||||
let e = Event::Transaction(Transaction {
|
let e = Event::Transaction(Transaction {
|
||||||
from: alice_pubkey,
|
from: alice_pubkey,
|
||||||
to: k,
|
to: k,
|
||||||
data: one,
|
asset: one,
|
||||||
last_id,
|
last_id,
|
||||||
sig: s,
|
sig: s,
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,13 +14,13 @@ fn create_log(
|
||||||
seed: &Sha256Hash,
|
seed: &Sha256Hash,
|
||||||
) -> Result<(), SendError<Event<Sha256Hash>>> {
|
) -> Result<(), SendError<Event<Sha256Hash>>> {
|
||||||
sleep(Duration::from_millis(15));
|
sleep(Duration::from_millis(15));
|
||||||
let data = Sha256Hash::default();
|
let asset = Sha256Hash::default();
|
||||||
let keypair = generate_keypair();
|
let keypair = generate_keypair();
|
||||||
let event0 = Event::new_claim(
|
let event0 = Event::new_claim(
|
||||||
get_pubkey(&keypair),
|
get_pubkey(&keypair),
|
||||||
data,
|
asset,
|
||||||
*seed,
|
*seed,
|
||||||
sign_claim_data(&data, &keypair, seed),
|
sign_claim_data(&asset, &keypair, seed),
|
||||||
);
|
);
|
||||||
hist.sender.send(event0)?;
|
hist.sender.send(event0)?;
|
||||||
sleep(Duration::from_millis(10));
|
sleep(Duration::from_millis(10));
|
||||||
|
|
|
@ -17,8 +17,8 @@ pub enum Event<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Serialize> Event<T> {
|
impl<T: Serialize> Event<T> {
|
||||||
pub fn new_claim(to: PublicKey, data: T, last_id: Sha256Hash, sig: Signature) -> Self {
|
pub fn new_claim(to: PublicKey, asset: T, last_id: Sha256Hash, sig: Signature) -> Self {
|
||||||
Event::Transaction(Transaction::new_claim(to, data, last_id, sig))
|
Event::Transaction(Transaction::new_claim(to, asset, last_id, sig))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_signature(&self) -> Option<Signature> {
|
pub fn get_signature(&self) -> Option<Signature> {
|
||||||
|
|
|
@ -54,14 +54,14 @@ impl Genesis {
|
||||||
get_pubkey(&self.get_keypair())
|
get_pubkey(&self.get_keypair())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_transaction(&self, data: i64, to: &PublicKey) -> Event<i64> {
|
pub fn create_transaction(&self, asset: i64, to: &PublicKey) -> Event<i64> {
|
||||||
let last_id = self.get_seed();
|
let last_id = self.get_seed();
|
||||||
let from = self.get_pubkey();
|
let from = self.get_pubkey();
|
||||||
let sig = sign_transaction_data(&data, &self.get_keypair(), to, &last_id);
|
let sig = sign_transaction_data(&asset, &self.get_keypair(), to, &last_id);
|
||||||
Event::Transaction(Transaction {
|
Event::Transaction(Transaction {
|
||||||
from,
|
from,
|
||||||
to: *to,
|
to: *to,
|
||||||
data,
|
asset,
|
||||||
last_id,
|
last_id,
|
||||||
sig,
|
sig,
|
||||||
})
|
})
|
||||||
|
|
24
src/log.rs
24
src/log.rs
|
@ -245,13 +245,13 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_claim() {
|
fn test_claim() {
|
||||||
let keypair = generate_keypair();
|
let keypair = generate_keypair();
|
||||||
let data = hash(b"hello, world");
|
let asset = hash(b"hello, world");
|
||||||
let zero = Sha256Hash::default();
|
let zero = Sha256Hash::default();
|
||||||
let event0 = Event::new_claim(
|
let event0 = Event::new_claim(
|
||||||
get_pubkey(&keypair),
|
get_pubkey(&keypair),
|
||||||
data,
|
asset,
|
||||||
zero,
|
zero,
|
||||||
sign_claim_data(&data, &keypair, &zero),
|
sign_claim_data(&asset, &keypair, &zero),
|
||||||
);
|
);
|
||||||
let entries = create_entries(&zero, vec![event0]);
|
let entries = create_entries(&zero, vec![event0]);
|
||||||
assert!(verify_slice(&entries, &zero));
|
assert!(verify_slice(&entries, &zero));
|
||||||
|
@ -277,13 +277,13 @@ mod tests {
|
||||||
let keypair0 = generate_keypair();
|
let keypair0 = generate_keypair();
|
||||||
let keypair1 = generate_keypair();
|
let keypair1 = generate_keypair();
|
||||||
let pubkey1 = get_pubkey(&keypair1);
|
let pubkey1 = get_pubkey(&keypair1);
|
||||||
let data = hash(b"hello, world");
|
let asset = hash(b"hello, world");
|
||||||
let event0 = Event::Transaction(Transaction {
|
let event0 = Event::Transaction(Transaction {
|
||||||
from: get_pubkey(&keypair0),
|
from: get_pubkey(&keypair0),
|
||||||
to: pubkey1,
|
to: pubkey1,
|
||||||
data,
|
asset,
|
||||||
last_id: zero,
|
last_id: zero,
|
||||||
sig: sign_transaction_data(&data, &keypair0, &pubkey1, &zero),
|
sig: sign_transaction_data(&asset, &keypair0, &pubkey1, &zero),
|
||||||
});
|
});
|
||||||
let entries = create_entries(&zero, vec![event0]);
|
let entries = create_entries(&zero, vec![event0]);
|
||||||
assert!(verify_slice(&entries, &zero));
|
assert!(verify_slice(&entries, &zero));
|
||||||
|
@ -294,14 +294,14 @@ mod tests {
|
||||||
let keypair0 = generate_keypair();
|
let keypair0 = generate_keypair();
|
||||||
let keypair1 = generate_keypair();
|
let keypair1 = generate_keypair();
|
||||||
let pubkey1 = get_pubkey(&keypair1);
|
let pubkey1 = get_pubkey(&keypair1);
|
||||||
let data = hash(b"hello, world");
|
let asset = hash(b"hello, world");
|
||||||
let zero = Sha256Hash::default();
|
let zero = Sha256Hash::default();
|
||||||
let event0 = Event::Transaction(Transaction {
|
let event0 = Event::Transaction(Transaction {
|
||||||
from: get_pubkey(&keypair0),
|
from: get_pubkey(&keypair0),
|
||||||
to: pubkey1,
|
to: pubkey1,
|
||||||
data: hash(b"goodbye cruel world"), // <-- attack!
|
asset: hash(b"goodbye cruel world"), // <-- attack!
|
||||||
last_id: zero,
|
last_id: zero,
|
||||||
sig: sign_transaction_data(&data, &keypair0, &pubkey1, &zero),
|
sig: sign_transaction_data(&asset, &keypair0, &pubkey1, &zero),
|
||||||
});
|
});
|
||||||
let entries = create_entries(&zero, vec![event0]);
|
let entries = create_entries(&zero, vec![event0]);
|
||||||
assert!(!verify_slice(&entries, &zero));
|
assert!(!verify_slice(&entries, &zero));
|
||||||
|
@ -313,14 +313,14 @@ mod tests {
|
||||||
let keypair1 = generate_keypair();
|
let keypair1 = generate_keypair();
|
||||||
let thief_keypair = generate_keypair();
|
let thief_keypair = generate_keypair();
|
||||||
let pubkey1 = get_pubkey(&keypair1);
|
let pubkey1 = get_pubkey(&keypair1);
|
||||||
let data = hash(b"hello, world");
|
let asset = hash(b"hello, world");
|
||||||
let zero = Sha256Hash::default();
|
let zero = Sha256Hash::default();
|
||||||
let event0 = Event::Transaction(Transaction {
|
let event0 = Event::Transaction(Transaction {
|
||||||
from: get_pubkey(&keypair0),
|
from: get_pubkey(&keypair0),
|
||||||
to: get_pubkey(&thief_keypair), // <-- attack!
|
to: get_pubkey(&thief_keypair), // <-- attack!
|
||||||
data: hash(b"goodbye cruel world"),
|
asset: hash(b"goodbye cruel world"),
|
||||||
last_id: zero,
|
last_id: zero,
|
||||||
sig: sign_transaction_data(&data, &keypair0, &pubkey1, &zero),
|
sig: sign_transaction_data(&asset, &keypair0, &pubkey1, &zero),
|
||||||
});
|
});
|
||||||
let entries = create_entries(&zero, vec![event0]);
|
let entries = create_entries(&zero, vec![event0]);
|
||||||
assert!(!verify_slice(&entries, &zero));
|
assert!(!verify_slice(&entries, &zero));
|
||||||
|
|
|
@ -10,51 +10,51 @@ use log::Sha256Hash;
|
||||||
pub struct Transaction<T> {
|
pub struct Transaction<T> {
|
||||||
pub from: PublicKey,
|
pub from: PublicKey,
|
||||||
pub to: PublicKey,
|
pub to: PublicKey,
|
||||||
pub data: T,
|
pub asset: T,
|
||||||
pub last_id: Sha256Hash,
|
pub last_id: Sha256Hash,
|
||||||
pub sig: Signature,
|
pub sig: Signature,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Serialize> Transaction<T> {
|
impl<T: Serialize> Transaction<T> {
|
||||||
pub fn new_claim(to: PublicKey, data: T, last_id: Sha256Hash, sig: Signature) -> Self {
|
pub fn new_claim(to: PublicKey, asset: T, last_id: Sha256Hash, sig: Signature) -> Self {
|
||||||
Transaction {
|
Transaction {
|
||||||
from: to,
|
from: to,
|
||||||
to,
|
to,
|
||||||
data,
|
asset,
|
||||||
last_id,
|
last_id,
|
||||||
sig,
|
sig,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify(&self) -> bool {
|
pub fn verify(&self) -> bool {
|
||||||
let sign_data = serialize(&(&self.from, &self.to, &self.data, &self.last_id)).unwrap();
|
let sign_data = serialize(&(&self.from, &self.to, &self.asset, &self.last_id)).unwrap();
|
||||||
verify_signature(&self.from, &sign_data, &self.sig)
|
verify_signature(&self.from, &sign_data, &self.sig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_serialized<T: Serialize>(data: &T, keypair: &Ed25519KeyPair) -> Signature {
|
fn sign_serialized<T: Serialize>(asset: &T, keypair: &Ed25519KeyPair) -> Signature {
|
||||||
let serialized = serialize(data).unwrap();
|
let serialized = serialize(asset).unwrap();
|
||||||
Signature::clone_from_slice(keypair.sign(&serialized).as_ref())
|
Signature::clone_from_slice(keypair.sign(&serialized).as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a signature for the given transaction data using the private key from the given keypair.
|
/// Return a signature for the given transaction data using the private key from the given keypair.
|
||||||
pub fn sign_transaction_data<T: Serialize>(
|
pub fn sign_transaction_data<T: Serialize>(
|
||||||
data: &T,
|
asset: &T,
|
||||||
keypair: &Ed25519KeyPair,
|
keypair: &Ed25519KeyPair,
|
||||||
to: &PublicKey,
|
to: &PublicKey,
|
||||||
last_id: &Sha256Hash,
|
last_id: &Sha256Hash,
|
||||||
) -> Signature {
|
) -> Signature {
|
||||||
let from = &get_pubkey(keypair);
|
let from = &get_pubkey(keypair);
|
||||||
sign_serialized(&(from, to, data, last_id), keypair)
|
sign_serialized(&(from, to, asset, last_id), keypair)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a signature for the given data using the private key from the given keypair.
|
/// Return a signature for the given data using the private key from the given keypair.
|
||||||
pub fn sign_claim_data<T: Serialize>(
|
pub fn sign_claim_data<T: Serialize>(
|
||||||
data: &T,
|
asset: &T,
|
||||||
keypair: &Ed25519KeyPair,
|
keypair: &Ed25519KeyPair,
|
||||||
last_id: &Sha256Hash,
|
last_id: &Sha256Hash,
|
||||||
) -> Signature {
|
) -> Signature {
|
||||||
sign_transaction_data(data, keypair, &get_pubkey(keypair), last_id)
|
sign_transaction_data(asset, keypair, &get_pubkey(keypair), last_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in New Issue