Move verify into methods

A little overly-coupled to Serialize, but makes the code a lot tighter
This commit is contained in:
Greg Fitzgerald 2018-03-06 12:26:39 -07:00
parent 4fcd9e3bd6
commit b019416518
7 changed files with 30 additions and 32 deletions

View File

@ -4,8 +4,7 @@
use log::{Entry, Sha256Hash}; use log::{Entry, Sha256Hash};
use event::Event; use event::Event;
use transaction::{get_pubkey, sign_transaction_data, verify_transaction, PublicKey, Signature, use transaction::{get_pubkey, sign_transaction_data, PublicKey, Signature, Transaction};
Transaction};
use genesis::Genesis; use genesis::Genesis;
use historian::{reserve_signature, Historian}; use historian::{reserve_signature, Historian};
use ring::signature::Ed25519KeyPair; use ring::signature::Ed25519KeyPair;
@ -78,7 +77,7 @@ impl Accountant {
} }
pub fn process_transaction(self: &mut Self, tr: Transaction<i64>) -> Result<()> { pub fn process_transaction(self: &mut Self, tr: Transaction<i64>) -> Result<()> {
if !verify_transaction(&tr) { if !tr.verify() {
return Err(AccountingError::InvalidTransfer); return Err(AccountingError::InvalidTransfer);
} }

View File

@ -5,7 +5,6 @@
use std::net::UdpSocket; use std::net::UdpSocket;
use std::io; use std::io;
use bincode::{deserialize, serialize}; use bincode::{deserialize, serialize};
use event::get_signature;
use transaction::{get_pubkey, sign_transaction_data, PublicKey, Signature, Transaction}; use transaction::{get_pubkey, sign_transaction_data, PublicKey, Signature, Transaction};
use log::{Entry, Sha256Hash}; use log::{Entry, Sha256Hash};
use ring::signature::Ed25519KeyPair; use ring::signature::Ed25519KeyPair;
@ -109,7 +108,7 @@ impl AccountantStub {
if let Response::Entries { entries } = resp { if let Response::Entries { entries } = resp {
for Entry { id, event, .. } in entries { for Entry { id, event, .. } in entries {
self.last_id = Some(id); self.last_id = Some(id);
if let Some(sig) = get_signature(&event) { if let Some(sig) = event.get_signature() {
if sig == *wait_sig { if sig == *wait_sig {
return Ok(()); return Ok(());
} }

View File

@ -2,7 +2,7 @@ extern crate serde_json;
extern crate silk; extern crate silk;
use silk::accountant_stub::AccountantStub; use silk::accountant_stub::AccountantStub;
use silk::event::{verify_event, Event}; use silk::event::Event;
use silk::transaction::{generate_keypair, get_pubkey, sign_transaction_data, Transaction}; use silk::transaction::{generate_keypair, get_pubkey, sign_transaction_data, Transaction};
use silk::genesis::Genesis; use silk::genesis::Genesis;
use std::time::Instant; use std::time::Instant;
@ -55,7 +55,7 @@ fn main() {
last_id, last_id,
sig: s, sig: s,
}); });
assert!(verify_event(&e)); assert!(e.verify());
} }
let duration = now.elapsed(); let duration = now.elapsed();
let ns = duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64; let ns = duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64;

View File

@ -1,6 +1,6 @@
//! The `event` crate provides the data structures for log events. //! The `event` crate provides the data structures for log events.
use transaction::{verify_transaction, PublicKey, Signature, Transaction}; use transaction::{PublicKey, Signature, Transaction};
use serde::Serialize; use serde::Serialize;
use log::Sha256Hash; use log::Sha256Hash;
@ -15,22 +15,22 @@ pub enum Event<T> {
Transaction(Transaction<T>), Transaction(Transaction<T>),
} }
impl<T> 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, data: T, last_id: Sha256Hash, sig: Signature) -> Self {
Event::Transaction(Transaction::new_claim(to, data, last_id, sig)) Event::Transaction(Transaction::new_claim(to, data, last_id, sig))
} }
}
pub fn get_signature<T>(event: &Event<T>) -> Option<Signature> { pub fn get_signature(&self) -> Option<Signature> {
match *event { match *self {
Event::Tick => None, Event::Tick => None,
Event::Transaction(ref tr) => Some(tr.sig), Event::Transaction(ref tr) => Some(tr.sig),
} }
} }
pub fn verify_event<T: Serialize>(event: &Event<T>) -> bool { pub fn verify(&self) -> bool {
match *event { match *self {
Event::Tick => true, Event::Tick => true,
Event::Transaction(ref tr) => verify_transaction(tr), Event::Transaction(ref tr) => tr.verify(),
}
} }
} }

View File

@ -16,7 +16,7 @@
use generic_array::GenericArray; use generic_array::GenericArray;
use generic_array::typenum::U32; use generic_array::typenum::U32;
use serde::Serialize; use serde::Serialize;
use event::{get_signature, verify_event, Event}; use event::Event;
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
use rayon::prelude::*; use rayon::prelude::*;
@ -64,7 +64,7 @@ pub fn next_hash<T: Serialize>(
event: &Event<T>, event: &Event<T>,
) -> Sha256Hash { ) -> Sha256Hash {
let mut id = *start_hash; let mut id = *start_hash;
let sig = get_signature(event); let sig = event.get_signature();
let start_index = if sig.is_some() { 1 } else { 0 }; let start_index = if sig.is_some() { 1 } else { 0 };
for _ in start_index..num_hashes { for _ in start_index..num_hashes {
id = hash(&id); id = hash(&id);
@ -81,7 +81,7 @@ pub fn create_entry<T: Serialize>(
cur_hashes: u64, cur_hashes: u64,
event: Event<T>, event: Event<T>,
) -> Entry<T> { ) -> Entry<T> {
let sig = get_signature(&event); let sig = event.get_signature();
let num_hashes = cur_hashes + if sig.is_some() { 1 } else { 0 }; let num_hashes = cur_hashes + if sig.is_some() { 1 } else { 0 };
let id = next_hash(start_hash, 0, &event); let id = next_hash(start_hash, 0, &event);
Entry { Entry {
@ -116,7 +116,7 @@ pub fn next_tick<T: Serialize>(start_hash: &Sha256Hash, num_hashes: u64) -> Entr
/// Verifies self.id is the result of hashing a 'start_hash' 'self.num_hashes' times. /// Verifies self.id is the result of hashing a 'start_hash' 'self.num_hashes' times.
/// If the event is not a Tick, then hash that as well. /// If the event is not a Tick, then hash that as well.
pub fn verify_entry<T: Serialize>(entry: &Entry<T>, start_hash: &Sha256Hash) -> bool { pub fn verify_entry<T: Serialize>(entry: &Entry<T>, start_hash: &Sha256Hash) -> bool {
if !verify_event(&entry.event) { if !entry.event.verify() {
return false; return false;
} }
entry.id == next_hash(start_hash, entry.num_hashes, &entry.event) entry.id == next_hash(start_hash, entry.num_hashes, &entry.event)

View File

@ -93,6 +93,6 @@ mod tests {
zero, zero,
sig, sig,
); );
assert!(!verify_event(&event0)); assert!(!event0.verify());
} }
} }

View File

@ -21,7 +21,7 @@ pub struct Transaction<T> {
pub sig: Signature, pub sig: Signature,
} }
impl<T> 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, data: T, last_id: Sha256Hash, sig: Signature) -> Self {
Transaction { Transaction {
from: to, from: to,
@ -31,6 +31,11 @@ impl<T> Transaction<T> {
sig, sig,
} }
} }
pub fn verify(&self) -> bool {
let sign_data = serialize(&(&self.from, &self.to, &self.data, &self.last_id)).unwrap();
verify_signature(&self.from, &sign_data, &self.sig)
}
} }
/// Return a new ED25519 keypair /// Return a new ED25519 keypair
@ -79,11 +84,6 @@ pub fn verify_signature(peer_public_key_bytes: &[u8], msg_bytes: &[u8], sig_byte
signature::verify(&signature::ED25519, peer_public_key, msg, sig).is_ok() signature::verify(&signature::ED25519, peer_public_key, msg, sig).is_ok()
} }
pub fn verify_transaction<T: Serialize>(tr: &Transaction<T>) -> bool {
let sign_data = serialize(&(&tr.from, &tr.to, &tr.data, &tr.last_id)).unwrap();
verify_signature(&tr.from, &sign_data, &tr.sig)
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;