Merge pull request #100 from garious/rollback
Cleanup use of event signatures and entry hashing
This commit is contained in:
commit
95749ed0e3
|
@ -3,12 +3,13 @@
|
|||
//! in flux. Clients should use AccountantStub to interact with it.
|
||||
|
||||
use accountant::Accountant;
|
||||
use historian::Historian;
|
||||
use recorder::Signal;
|
||||
use bincode::{deserialize, serialize};
|
||||
use entry::Entry;
|
||||
use event::Event;
|
||||
use hash::Hash;
|
||||
use historian::Historian;
|
||||
use rayon::prelude::*;
|
||||
use recorder::Signal;
|
||||
use result::Result;
|
||||
use serde_json;
|
||||
use signature::PublicKey;
|
||||
|
@ -22,7 +23,6 @@ use std::thread::{spawn, JoinHandle};
|
|||
use std::time::Duration;
|
||||
use streamer;
|
||||
use transaction::Transaction;
|
||||
use rayon::prelude::*;
|
||||
|
||||
pub struct AccountantSkel<W: Write + Send + 'static> {
|
||||
acc: Accountant,
|
||||
|
|
|
@ -87,8 +87,8 @@ impl AccountantStub {
|
|||
mod tests {
|
||||
use super::*;
|
||||
use accountant::Accountant;
|
||||
use historian::Historian;
|
||||
use accountant_skel::AccountantSkel;
|
||||
use historian::Historian;
|
||||
use mint::Mint;
|
||||
use signature::{KeyPair, KeyPairUtil};
|
||||
use std::io::sink;
|
||||
|
|
|
@ -2,15 +2,15 @@ extern crate rayon;
|
|||
extern crate serde_json;
|
||||
extern crate solana;
|
||||
|
||||
use rayon::prelude::*;
|
||||
use solana::accountant_stub::AccountantStub;
|
||||
use solana::mint::Mint;
|
||||
use solana::signature::{KeyPair, KeyPairUtil};
|
||||
use solana::transaction::Transaction;
|
||||
use std::io::stdin;
|
||||
use std::net::UdpSocket;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::thread::sleep;
|
||||
use rayon::prelude::*;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
fn main() {
|
||||
let addr = "127.0.0.1:8000";
|
||||
|
|
|
@ -2,10 +2,10 @@ extern crate serde_json;
|
|||
extern crate solana;
|
||||
|
||||
use solana::accountant::Accountant;
|
||||
use solana::event::Event;
|
||||
use solana::entry::Entry;
|
||||
use solana::historian::Historian;
|
||||
use solana::accountant_skel::AccountantSkel;
|
||||
use solana::entry::Entry;
|
||||
use solana::event::Event;
|
||||
use solana::historian::Historian;
|
||||
use std::io::{self, stdout, BufRead};
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
|
40
src/entry.rs
40
src/entry.rs
|
@ -43,6 +43,23 @@ impl Entry {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_event_data(hash_data: &mut Vec<u8>, event: &Event) {
|
||||
match *event {
|
||||
Event::Transaction(ref tr) => {
|
||||
hash_data.push(0u8);
|
||||
hash_data.extend_from_slice(&tr.sig);
|
||||
}
|
||||
Event::Signature { ref sig, .. } => {
|
||||
hash_data.push(1u8);
|
||||
hash_data.extend_from_slice(sig);
|
||||
}
|
||||
Event::Timestamp { ref sig, .. } => {
|
||||
hash_data.push(2u8);
|
||||
hash_data.extend_from_slice(sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates the hash `num_hashes` after `start_hash`. If the event contains
|
||||
/// signature, the final hash will be a hash of both the previous ID and
|
||||
/// the signature.
|
||||
|
@ -55,10 +72,7 @@ pub fn next_hash(start_hash: &Hash, num_hashes: u64, events: &[Event]) -> Hash {
|
|||
// Hash all the event data
|
||||
let mut hash_data = vec![];
|
||||
for event in events {
|
||||
let sig = event.get_signature();
|
||||
if let Some(sig) = sig {
|
||||
hash_data.extend_from_slice(&sig);
|
||||
}
|
||||
add_event_data(&mut hash_data, event);
|
||||
}
|
||||
|
||||
if !hash_data.is_empty() {
|
||||
|
@ -99,6 +113,7 @@ pub fn next_tick(start_hash: &Hash, num_hashes: u64) -> Entry {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use chrono::prelude::*;
|
||||
use entry::create_entry;
|
||||
use event::Event;
|
||||
use hash::hash;
|
||||
|
@ -132,6 +147,23 @@ mod tests {
|
|||
assert!(!e0.verify(&zero));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_witness_reorder_attack() {
|
||||
let zero = Hash::default();
|
||||
|
||||
// First, verify entries
|
||||
let keypair = KeyPair::new();
|
||||
let tr0 = Event::new_timestamp(&keypair, Utc::now());
|
||||
let tr1 = Event::new_signature(&keypair, Default::default());
|
||||
let mut e0 = create_entry(&zero, 0, vec![tr0.clone(), tr1.clone()]);
|
||||
assert!(e0.verify(&zero));
|
||||
|
||||
// Next, swap two witness events and ensure verification fails.
|
||||
e0.events[0] = tr1; // <-- attack
|
||||
e0.events[1] = tr0;
|
||||
assert!(!e0.verify(&zero));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_next_tick() {
|
||||
let zero = Hash::default();
|
||||
|
|
25
src/event.rs
25
src/event.rs
|
@ -33,12 +33,13 @@ impl Event {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Rename this to transaction_signature().
|
||||
/// If the Event is a Transaction, return its Signature.
|
||||
pub fn get_signature(&self) -> Option<Signature> {
|
||||
match *self {
|
||||
Event::Transaction(ref tr) => Some(tr.sig),
|
||||
Event::Signature { .. } | Event::Timestamp { .. } => None,
|
||||
/// Create and sign a new Witness Signature. Used for unit-testing.
|
||||
pub fn new_signature(from: &KeyPair, tx_sig: Signature) -> Self {
|
||||
let sig = Signature::clone_from_slice(from.sign(&tx_sig).as_ref());
|
||||
Event::Signature {
|
||||
from: from.pubkey(),
|
||||
tx_sig,
|
||||
sig,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,3 +53,15 @@ impl Event {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use signature::{KeyPair, KeyPairUtil};
|
||||
|
||||
#[test]
|
||||
fn test_event_verify() {
|
||||
assert!(Event::new_timestamp(&KeyPair::new(), Utc::now()).verify());
|
||||
assert!(Event::new_signature(&KeyPair::new(), Signature::default()).verify());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
use bincode::serialize;
|
||||
use chrono::prelude::*;
|
||||
use rayon::prelude::*;
|
||||
use hash::Hash;
|
||||
use plan::{Condition, Payment, Plan};
|
||||
use rayon::prelude::*;
|
||||
use signature::{KeyPair, KeyPairUtil, PublicKey, Signature, SignatureUtil};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
|
@ -57,7 +57,7 @@ impl Transaction {
|
|||
}
|
||||
|
||||
fn get_sign_data(&self) -> Vec<u8> {
|
||||
serialize(&(&self.from, &self.plan, &self.tokens, &self.last_id)).unwrap()
|
||||
serialize(&(&self.plan, &self.tokens, &self.last_id)).unwrap()
|
||||
}
|
||||
|
||||
/// Sign this transaction.
|
||||
|
|
Loading…
Reference in New Issue