Transactions now require a hash of the last entry they've seen

This ensures the transaction cannot be processed on a chain
that forked before that ID. It will also provide a basis for
expiration constraints. A client may want their transaction
to expire, and the generators may want to reject transactions
that have been floating in the ether for years.
This commit is contained in:
Greg Fitzgerald
2018-03-05 12:48:09 -07:00
parent d76ecbc9c9
commit 48c28c2267
10 changed files with 165 additions and 54 deletions

View File

@ -2,7 +2,7 @@
//! event log to record transactions. Its users can deposit funds and //! event log to record transactions. Its users can deposit funds and
//! transfer funds to other users. //! transfer funds to other users.
use log::{hash, Entry, Sha256Hash}; use log::Sha256Hash;
use event::{get_pubkey, sign_transaction_data, verify_event, Event, PublicKey, Signature}; use event::{get_pubkey, sign_transaction_data, verify_event, Event, PublicKey, Signature};
use genesis::Genesis; use genesis::Genesis;
use historian::{reserve_signature, Historian}; use historian::{reserve_signature, Historian};
@ -23,16 +23,18 @@ pub type Result<T> = result::Result<T, AccountingError>;
pub struct Accountant { pub struct Accountant {
pub historian: Historian<u64>, pub historian: Historian<u64>,
pub balances: HashMap<PublicKey, u64>, pub balances: HashMap<PublicKey, u64>,
pub first_id: Sha256Hash,
pub last_id: Sha256Hash, pub last_id: Sha256Hash,
} }
impl Accountant { impl Accountant {
pub fn new(gen: &Genesis, ms_per_tick: Option<u64>) -> Self { pub fn new(gen: &Genesis, ms_per_tick: Option<u64>) -> Self {
let start_hash = hash(&gen.pkcs8); let start_hash = gen.get_seed();
let hist = Historian::<u64>::new(&start_hash, ms_per_tick); let hist = Historian::<u64>::new(&start_hash, ms_per_tick);
let mut acc = Accountant { let mut acc = Accountant {
historian: hist, historian: hist,
balances: HashMap::new(), balances: HashMap::new(),
first_id: start_hash,
last_id: start_hash, last_id: start_hash,
}; };
for (i, event) in gen.create_events().iter().enumerate() { for (i, event) in gen.create_events().iter().enumerate() {
@ -41,17 +43,11 @@ impl Accountant {
acc acc
} }
pub fn sync(self: &mut Self) -> Vec<Entry<u64>> { pub fn sync(self: &mut Self) -> Sha256Hash {
let mut entries = vec![];
while let Ok(entry) = self.historian.receiver.try_recv() { while let Ok(entry) = self.historian.receiver.try_recv() {
entries.push(entry); self.last_id = entry.id;
} }
self.last_id
if let Some(last_entry) = entries.last() {
self.last_id = last_entry.id;
}
entries
} }
fn is_deposit(allow_deposits: bool, from: &PublicKey, to: &PublicKey) -> bool { fn is_deposit(allow_deposits: bool, from: &PublicKey, to: &PublicKey) -> bool {
@ -112,11 +108,13 @@ impl Accountant {
to: PublicKey, to: PublicKey,
) -> Result<Signature> { ) -> Result<Signature> {
let from = get_pubkey(keypair); let from = get_pubkey(keypair);
let sig = sign_transaction_data(&n, keypair, &to); let last_id = self.last_id;
let sig = sign_transaction_data(&n, keypair, &to, &last_id);
let event = Event::Transaction { let event = Event::Transaction {
from, from,
to, to,
data: n, data: n,
last_id,
sig, sig,
}; };
self.process_event(event).map(|_| sig) self.process_event(event).map(|_| sig)

View File

@ -6,7 +6,7 @@ use std::net::UdpSocket;
use bincode::{deserialize, serialize}; use bincode::{deserialize, serialize};
pub struct AccountantSkel { pub struct AccountantSkel {
pub obj: Accountant, pub acc: Accountant,
} }
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
@ -15,47 +15,67 @@ pub enum Request {
from: PublicKey, from: PublicKey,
to: PublicKey, to: PublicKey,
val: u64, val: u64,
last_id: Sha256Hash,
sig: Signature, sig: Signature,
}, },
GetBalance { GetBalance {
key: PublicKey, key: PublicKey,
}, },
GetEntries { GetEntries {
last_id: Option<Sha256Hash>, last_id: Sha256Hash,
},
GetId {
is_last: bool,
}, },
} }
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub enum Response { pub enum Response {
Balance { key: PublicKey, val: u64 }, Balance { key: PublicKey, val: u64 },
Confirmed { sig: Signature },
Entries { entries: Vec<Entry<u64>> }, Entries { entries: Vec<Entry<u64>> },
Id { id: Sha256Hash, is_last: bool },
} }
impl AccountantSkel { impl AccountantSkel {
pub fn new(obj: Accountant) -> Self { pub fn new(acc: Accountant) -> Self {
AccountantSkel { obj } AccountantSkel { acc }
} }
pub fn process_request(self: &mut Self, msg: Request) -> Option<Response> { pub fn process_request(self: &mut Self, msg: Request) -> Option<Response> {
match msg { match msg {
Request::Transfer { from, to, val, sig } => { Request::Transfer {
from,
to,
val,
last_id,
sig,
} => {
let event = Event::Transaction { let event = Event::Transaction {
from, from,
to, to,
data: val, data: val,
last_id,
sig, sig,
}; };
if let Err(err) = self.obj.process_event(event) { if let Err(err) = self.acc.process_event(event) {
println!("Transfer error: {:?}", err); println!("Transfer error: {:?}", err);
} }
None None
} }
Request::GetBalance { key } => { Request::GetBalance { key } => {
let val = self.obj.get_balance(&key).unwrap(); let val = self.acc.get_balance(&key).unwrap();
Some(Response::Balance { key, val }) Some(Response::Balance { key, val })
} }
Request::GetEntries { .. } => Some(Response::Entries { entries: vec![] }), Request::GetEntries { .. } => Some(Response::Entries { entries: vec![] }),
Request::GetId { is_last } => Some(Response::Id {
id: if is_last {
self.acc.sync();
self.acc.last_id
} else {
self.acc.first_id
},
is_last,
}),
} }
} }

View File

@ -30,9 +30,16 @@ impl AccountantStub {
from: PublicKey, from: PublicKey,
to: PublicKey, to: PublicKey,
val: u64, val: u64,
last_id: Sha256Hash,
sig: Signature, sig: Signature,
) -> io::Result<usize> { ) -> io::Result<usize> {
let req = Request::Transfer { from, to, val, sig }; let req = Request::Transfer {
from,
to,
val,
last_id,
sig,
};
let data = serialize(&req).unwrap(); let data = serialize(&req).unwrap();
self.socket.send_to(&data, &self.addr) self.socket.send_to(&data, &self.addr)
} }
@ -42,10 +49,12 @@ impl AccountantStub {
n: u64, n: u64,
keypair: &Ed25519KeyPair, keypair: &Ed25519KeyPair,
to: PublicKey, to: PublicKey,
last_id: &Sha256Hash,
) -> io::Result<Signature> { ) -> io::Result<Signature> {
let from = get_pubkey(keypair); let from = get_pubkey(keypair);
let sig = sign_transaction_data(&n, keypair, &to); let sig = sign_transaction_data(&n, keypair, &to, last_id);
self.transfer_signed(from, to, n, sig).map(|_| sig) self.transfer_signed(from, to, n, *last_id, sig)
.map(|_| sig)
} }
pub fn get_balance(&self, pubkey: &PublicKey) -> io::Result<u64> { pub fn get_balance(&self, pubkey: &PublicKey) -> io::Result<u64> {
@ -62,10 +71,34 @@ impl AccountantStub {
Ok(0) Ok(0)
} }
fn get_id(&self, is_last: bool) -> io::Result<Sha256Hash> {
let req = Request::GetId { is_last };
let data = serialize(&req).expect("serialize GetId");
self.socket.send_to(&data, &self.addr)?;
let mut buf = vec![0u8; 1024];
self.socket.recv_from(&mut buf)?;
let resp = deserialize(&buf).expect("deserialize Id");
if let Response::Id { id, .. } = resp {
return Ok(id);
}
Ok(Default::default())
}
pub fn get_last_id(&self) -> io::Result<Sha256Hash> {
self.get_id(true)
}
pub fn wait_on_signature(&mut self, wait_sig: &Signature) -> io::Result<()> { pub fn wait_on_signature(&mut self, wait_sig: &Signature) -> io::Result<()> {
let req = Request::GetEntries { let last_id = match self.last_id {
last_id: self.last_id, None => {
let first_id = self.get_id(false)?;
self.last_id = Some(first_id);
first_id
}
Some(last_id) => last_id,
}; };
let req = Request::GetEntries { last_id };
let data = serialize(&req).unwrap(); let data = serialize(&req).unwrap();
self.socket.send_to(&data, &self.addr).map(|_| ())?; self.socket.send_to(&data, &self.addr).map(|_| ())?;
@ -110,7 +143,9 @@ mod tests {
let socket = UdpSocket::bind(send_addr).unwrap(); let socket = UdpSocket::bind(send_addr).unwrap();
let mut acc = AccountantStub::new(addr, socket); let mut acc = AccountantStub::new(addr, socket);
let sig = acc.transfer(500, &alice.get_keypair(), bob_pubkey).unwrap(); let last_id = acc.get_last_id().unwrap();
let sig = acc.transfer(500, &alice.get_keypair(), bob_pubkey, &last_id)
.unwrap();
acc.wait_on_signature(&sig).unwrap(); acc.wait_on_signature(&sig).unwrap();
assert_eq!(acc.get_balance(&bob_pubkey).unwrap(), 1_500); assert_eq!(acc.get_balance(&bob_pubkey).unwrap(), 1_500);
} }

View File

@ -29,6 +29,7 @@ fn main() {
let socket = UdpSocket::bind(send_addr).unwrap(); let socket = UdpSocket::bind(send_addr).unwrap();
let mut acc = AccountantStub::new(addr, socket); let mut acc = AccountantStub::new(addr, socket);
let last_id = acc.get_last_id().unwrap();
let alice_pubkey = get_pubkey(&alice_keypair); let alice_pubkey = get_pubkey(&alice_keypair);
let one = 1; let one = 1;
println!("Signing transactions..."); println!("Signing transactions...");
@ -37,7 +38,7 @@ fn main() {
.map(|_| { .map(|_| {
let rando_keypair = generate_keypair(); let rando_keypair = generate_keypair();
let rando_pubkey = get_pubkey(&rando_keypair); let rando_pubkey = get_pubkey(&rando_keypair);
let sig = sign_transaction_data(&one, &alice_keypair, &rando_pubkey); let sig = sign_transaction_data(&one, &alice_keypair, &rando_pubkey, &last_id);
(rando_pubkey, sig) (rando_pubkey, sig)
}) })
.collect(); .collect();
@ -58,6 +59,7 @@ fn main() {
from: alice_pubkey, from: alice_pubkey,
to: k, to: k,
data: one, data: one,
last_id,
sig: s, sig: s,
}; };
assert!(verify_event(&e)); assert!(verify_event(&e));
@ -76,7 +78,8 @@ fn main() {
let now = Instant::now(); let now = Instant::now();
let mut sig = Default::default(); let mut sig = Default::default();
for (k, s) in sigs { for (k, s) in sigs {
acc.transfer_signed(alice_pubkey, k, one, s).unwrap(); acc.transfer_signed(alice_pubkey, k, one, last_id, s)
.unwrap();
sig = s; sig = s;
} }
println!("Waiting for last transaction to be confirmed...",); println!("Waiting for last transaction to be confirmed...",);

View File

@ -7,11 +7,19 @@ use std::thread::sleep;
use std::time::Duration; use std::time::Duration;
use std::sync::mpsc::SendError; use std::sync::mpsc::SendError;
fn create_log(hist: &Historian<Sha256Hash>) -> Result<(), SendError<Event<Sha256Hash>>> { fn create_log(
hist: &Historian<Sha256Hash>,
seed: &Sha256Hash,
) -> Result<(), SendError<Event<Sha256Hash>>> {
sleep(Duration::from_millis(15)); sleep(Duration::from_millis(15));
let data = Sha256Hash::default(); let data = 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),
data,
*seed,
sign_claim_data(&data, &keypair, seed),
);
hist.sender.send(event0)?; hist.sender.send(event0)?;
sleep(Duration::from_millis(10)); sleep(Duration::from_millis(10));
Ok(()) Ok(())
@ -20,7 +28,7 @@ fn create_log(hist: &Historian<Sha256Hash>) -> Result<(), SendError<Event<Sha256
fn main() { fn main() {
let seed = Sha256Hash::default(); let seed = Sha256Hash::default();
let hist = Historian::new(&seed, Some(10)); let hist = Historian::new(&seed, Some(10));
create_log(&hist).expect("send error"); create_log(&hist, &seed).expect("send error");
drop(hist.sender); drop(hist.sender);
let entries: Vec<Entry<Sha256Hash>> = hist.receiver.iter().collect(); let entries: Vec<Entry<Sha256Hash>> = hist.receiver.iter().collect();
for entry in &entries { for entry in &entries {

View File

@ -20,6 +20,7 @@ use ring::{rand, signature};
use untrusted; use untrusted;
use serde::Serialize; use serde::Serialize;
use bincode::serialize; use bincode::serialize;
use log::Sha256Hash;
pub type PublicKey = GenericArray<u8, U32>; pub type PublicKey = GenericArray<u8, U32>;
pub type Signature = GenericArray<u8, U64>; pub type Signature = GenericArray<u8, U64>;
@ -36,16 +37,18 @@ pub enum Event<T> {
from: PublicKey, from: PublicKey,
to: PublicKey, to: PublicKey,
data: T, data: T,
last_id: Sha256Hash,
sig: Signature, sig: Signature,
}, },
} }
impl<T> Event<T> { impl<T> Event<T> {
pub fn new_claim(to: PublicKey, data: T, sig: Signature) -> Self { pub fn new_claim(to: PublicKey, data: T, last_id: Sha256Hash, sig: Signature) -> Self {
Event::Transaction { Event::Transaction {
from: to, from: to,
to, to,
data, data,
last_id,
sig, sig,
} }
} }
@ -74,14 +77,19 @@ pub fn sign_transaction_data<T: Serialize>(
data: &T, data: &T,
keypair: &Ed25519KeyPair, keypair: &Ed25519KeyPair,
to: &PublicKey, to: &PublicKey,
last_id: &Sha256Hash,
) -> Signature { ) -> Signature {
let from = &get_pubkey(keypair); let from = &get_pubkey(keypair);
sign_serialized(&(from, to, data), keypair) sign_serialized(&(from, to, data, 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>(data: &T, keypair: &Ed25519KeyPair) -> Signature { pub fn sign_claim_data<T: Serialize>(
sign_transaction_data(data, keypair, &get_pubkey(keypair)) data: &T,
keypair: &Ed25519KeyPair,
last_id: &Sha256Hash,
) -> Signature {
sign_transaction_data(data, keypair, &get_pubkey(keypair), last_id)
} }
/// Verify a signed message with the given public key. /// Verify a signed message with the given public key.
@ -104,10 +112,11 @@ pub fn verify_event<T: Serialize>(event: &Event<T>) -> bool {
from, from,
to, to,
ref data, ref data,
last_id,
sig, sig,
} = *event } = *event
{ {
let sign_data = serialize(&(&from, &to, &data)).unwrap(); let sign_data = serialize(&(&from, &to, &data, &last_id)).unwrap();
if !verify_signature(&from, &sign_data, &sig) { if !verify_signature(&from, &sign_data, &sig) {
return false; return false;
} }
@ -122,7 +131,12 @@ mod tests {
#[test] #[test]
fn test_serialize_claim() { fn test_serialize_claim() {
let claim0 = Event::new_claim(Default::default(), 0u8, Default::default()); let claim0 = Event::new_claim(
Default::default(),
0u8,
Default::default(),
Default::default(),
);
let buf = serialize(&claim0).unwrap(); let buf = serialize(&claim0).unwrap();
let claim1: Event<u8> = deserialize(&buf).unwrap(); let claim1: Event<u8> = deserialize(&buf).unwrap();
assert_eq!(claim1, claim0); assert_eq!(claim1, claim0);

View File

@ -1,6 +1,7 @@
//! A library for generating the chain's genesis block. //! A library for generating the chain's genesis block.
use event::{generate_keypair, get_pubkey, sign_transaction_data, Event, PublicKey}; use event::{generate_keypair, get_pubkey, sign_transaction_data, Event, PublicKey};
use log::{hash, Sha256Hash};
use ring::rand::SystemRandom; use ring::rand::SystemRandom;
use ring::signature::Ed25519KeyPair; use ring::signature::Ed25519KeyPair;
use untrusted::Input; use untrusted::Input;
@ -38,6 +39,10 @@ impl Genesis {
} }
} }
pub fn get_seed(&self) -> Sha256Hash {
hash(&self.pkcs8)
}
pub fn get_keypair(&self) -> Ed25519KeyPair { pub fn get_keypair(&self) -> Ed25519KeyPair {
Ed25519KeyPair::from_pkcs8(Input::from(&self.pkcs8)).unwrap() Ed25519KeyPair::from_pkcs8(Input::from(&self.pkcs8)).unwrap()
} }
@ -47,12 +52,14 @@ impl Genesis {
} }
pub fn create_transaction(&self, data: u64, to: &PublicKey) -> Event<u64> { pub fn create_transaction(&self, data: u64, to: &PublicKey) -> Event<u64> {
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); let sig = sign_transaction_data(&data, &self.get_keypair(), to, &last_id);
Event::Transaction { Event::Transaction {
from, from,
to: *to, to: *to,
data, data,
last_id,
sig, sig,
} }
} }

View File

@ -114,8 +114,9 @@ mod tests {
let keypair = generate_keypair(); let keypair = generate_keypair();
let to = get_pubkey(&keypair); let to = get_pubkey(&keypair);
let data = b"hello, world"; let data = b"hello, world";
let sig = sign_claim_data(&data, &keypair); let zero = Sha256Hash::default();
let event0 = Event::new_claim(to, &data, sig); let sig = sign_claim_data(&data, &keypair, &zero);
let event0 = Event::new_claim(to, &data, zero, sig);
let mut sigs = HashSet::new(); let mut sigs = HashSet::new();
assert!(reserve_signature(&mut sigs, &event0)); assert!(reserve_signature(&mut sigs, &event0));
assert!(!reserve_signature(&mut sigs, &event0)); assert!(!reserve_signature(&mut sigs, &event0));

View File

@ -217,8 +217,18 @@ mod tests {
// First, verify entries // First, verify entries
let keypair = generate_keypair(); let keypair = generate_keypair();
let event0 = Event::new_claim(get_pubkey(&keypair), zero, sign_claim_data(&zero, &keypair)); let event0 = Event::new_claim(
let event1 = Event::new_claim(get_pubkey(&keypair), one, sign_claim_data(&one, &keypair)); get_pubkey(&keypair),
zero,
zero,
sign_claim_data(&zero, &keypair, &zero),
);
let event1 = Event::new_claim(
get_pubkey(&keypair),
one,
zero,
sign_claim_data(&one, &keypair, &zero),
);
let events = vec![event0, event1]; let events = vec![event0, event1];
let mut entries = create_entries(&zero, events); let mut entries = create_entries(&zero, events);
assert!(verify_slice(&entries, &zero)); assert!(verify_slice(&entries, &zero));
@ -235,8 +245,13 @@ mod tests {
fn test_claim() { fn test_claim() {
let keypair = generate_keypair(); let keypair = generate_keypair();
let data = hash(b"hello, world"); let data = hash(b"hello, world");
let event0 = Event::new_claim(get_pubkey(&keypair), data, sign_claim_data(&data, &keypair));
let zero = Sha256Hash::default(); let zero = Sha256Hash::default();
let event0 = Event::new_claim(
get_pubkey(&keypair),
data,
zero,
sign_claim_data(&data, &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));
} }
@ -244,18 +259,20 @@ mod tests {
#[test] #[test]
fn test_wrong_data_claim_attack() { fn test_wrong_data_claim_attack() {
let keypair = generate_keypair(); let keypair = generate_keypair();
let zero = Sha256Hash::default();
let event0 = Event::new_claim( let event0 = Event::new_claim(
get_pubkey(&keypair), get_pubkey(&keypair),
hash(b"goodbye cruel world"), hash(b"goodbye cruel world"),
sign_claim_data(&hash(b"hello, world"), &keypair), zero,
sign_claim_data(&hash(b"hello, world"), &keypair, &zero),
); );
let zero = Sha256Hash::default();
let entries = create_entries(&zero, vec![event0]); let entries = create_entries(&zero, vec![event0]);
assert!(!verify_slice(&entries, &zero)); assert!(!verify_slice(&entries, &zero));
} }
#[test] #[test]
fn test_transfer() { fn test_transfer() {
let zero = Sha256Hash::default();
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);
@ -264,9 +281,9 @@ mod tests {
from: get_pubkey(&keypair0), from: get_pubkey(&keypair0),
to: pubkey1, to: pubkey1,
data, data,
sig: sign_transaction_data(&data, &keypair0, &pubkey1), last_id: zero,
sig: sign_transaction_data(&data, &keypair0, &pubkey1, &zero),
}; };
let zero = Sha256Hash::default();
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 +294,14 @@ mod tests {
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 data = hash(b"hello, world");
let zero = Sha256Hash::default();
let event0 = Event::Transaction { let event0 = Event::Transaction {
from: get_pubkey(&keypair0), from: get_pubkey(&keypair0),
to: pubkey1, to: pubkey1,
data: hash(b"goodbye cruel world"), // <-- attack! data: hash(b"goodbye cruel world"), // <-- attack!
sig: sign_transaction_data(&data, &keypair0, &pubkey1), last_id: zero,
sig: sign_transaction_data(&data, &keypair0, &pubkey1, &zero),
}; };
let zero = Sha256Hash::default();
let entries = create_entries(&zero, vec![event0]); let entries = create_entries(&zero, vec![event0]);
assert!(!verify_slice(&entries, &zero)); assert!(!verify_slice(&entries, &zero));
} }
@ -295,13 +313,14 @@ mod tests {
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 data = hash(b"hello, world");
let zero = Sha256Hash::default();
let event0 = Event::Transaction { let event0 = Event::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"), data: hash(b"goodbye cruel world"),
sig: sign_transaction_data(&data, &keypair0, &pubkey1), last_id: zero,
sig: sign_transaction_data(&data, &keypair0, &pubkey1, &zero),
}; };
let zero = Sha256Hash::default();
let entries = create_entries(&zero, vec![event0]); let entries = create_entries(&zero, vec![event0]);
assert!(!verify_slice(&entries, &zero)); assert!(!verify_slice(&entries, &zero));
} }

View File

@ -83,16 +83,22 @@ mod tests {
#[test] #[test]
fn test_bad_event_signature() { fn test_bad_event_signature() {
let zero = Sha256Hash::default();
let keypair = generate_keypair(); let keypair = generate_keypair();
let sig = sign_claim_data(&hash(b"hello, world"), &keypair); let sig = sign_claim_data(&hash(b"hello, world"), &keypair, &zero);
let event0 = Event::new_claim(get_pubkey(&keypair), hash(b"goodbye cruel world"), sig); let event0 = Event::new_claim(
get_pubkey(&keypair),
hash(b"goodbye cruel world"),
zero,
sig,
);
assert!(!verify_event(&event0)); assert!(!verify_event(&event0));
} }
fn run_genesis(gen: Genesis) -> Vec<Entry<u64>> { fn run_genesis(gen: Genesis) -> Vec<Entry<u64>> {
let (sender, event_receiver) = sync_channel(100); let (sender, event_receiver) = sync_channel(100);
let (entry_sender, receiver) = sync_channel(100); let (entry_sender, receiver) = sync_channel(100);
let mut logger = Logger::new(event_receiver, entry_sender, hash(&gen.pkcs8)); let mut logger = Logger::new(event_receiver, entry_sender, gen.get_seed());
for tx in gen.create_events() { for tx in gen.create_events() {
sender.send(tx).unwrap(); sender.send(tx).unwrap();
} }