From 572475ce14e2e7f649e0655bf36d420c29184929 Mon Sep 17 00:00:00 2001 From: Greg Fitzgerald Date: Sun, 4 Mar 2018 00:13:40 -0700 Subject: [PATCH] Load the genesis block --- src/accountant.rs | 72 +++++++++++++++------------------------- src/accountant_stub.rs | 17 ++++------ src/bin/client-demo.rs | 9 +++-- src/bin/genesis-block.rs | 1 - src/bin/testnode.rs | 8 +++-- src/genesis.rs | 61 +++++++++++++++++++--------------- 6 files changed, 76 insertions(+), 92 deletions(-) diff --git a/src/accountant.rs b/src/accountant.rs index 303561517..25a18dc9e 100644 --- a/src/accountant.rs +++ b/src/accountant.rs @@ -2,8 +2,9 @@ //! event log to record transactions. Its users can deposit funds and //! transfer funds to other users. -use log::{Entry, Sha256Hash}; +use log::{hash, Entry, Sha256Hash}; use event::{Event, PublicKey, Signature}; +use genesis::Genesis; use historian::Historian; use ring::signature::Ed25519KeyPair; use std::sync::mpsc::SendError; @@ -26,13 +27,18 @@ pub struct Accountant { } impl Accountant { - pub fn new(start_hash: &Sha256Hash, ms_per_tick: Option) -> Self { - let hist = Historian::::new(start_hash, ms_per_tick); - Accountant { + pub fn new(gen: &Genesis, ms_per_tick: Option) -> Self { + let start_hash = hash(&gen.pkcs8); + let hist = Historian::::new(&start_hash, ms_per_tick); + let mut acc = Accountant { historian: hist, balances: HashMap::new(), - end_hash: *start_hash, + end_hash: start_hash, + }; + for (i, event) in gen.create_events().into_iter().enumerate() { + acc.process_verified_event(event, i < 2).unwrap(); } + acc } pub fn sync(self: &mut Self) -> Vec> { @@ -151,19 +157,16 @@ mod tests { use super::*; use event::{generate_keypair, get_pubkey}; use logger::ExitReason; + use genesis::Creator; #[test] fn test_accountant() { - let zero = Sha256Hash::default(); - let mut acc = Accountant::new(&zero, Some(2)); - let alice_keypair = generate_keypair(); - let bob_keypair = generate_keypair(); - acc.deposit(10_000, &alice_keypair).unwrap(); - let sig = acc.deposit(1_000, &bob_keypair).unwrap(); - acc.wait_on_signature(&sig); + let bob = Creator::new("Bob", 1_000); + let bob_pubkey = bob.pubkey; + let alice = Genesis::new(10_000, vec![bob]); + let mut acc = Accountant::new(&alice, Some(2)); - let bob_pubkey = get_pubkey(&bob_keypair); - let sig = acc.transfer(500, &alice_keypair, bob_pubkey).unwrap(); + let sig = acc.transfer(500, &alice.get_keypair(), bob_pubkey).unwrap(); acc.wait_on_signature(&sig); assert_eq!(acc.get_balance(&bob_pubkey).unwrap(), 1_500); @@ -179,22 +182,18 @@ mod tests { fn test_invalid_transfer() { use std::thread::sleep; use std::time::Duration; - let zero = Sha256Hash::default(); - let mut acc = Accountant::new(&zero, Some(2)); - let alice_keypair = generate_keypair(); - let bob_keypair = generate_keypair(); - acc.deposit(10_000, &alice_keypair).unwrap(); - let sig = acc.deposit(1_000, &bob_keypair).unwrap(); - acc.wait_on_signature(&sig); + let bob = Creator::new("Bob", 1_000); + let bob_pubkey = bob.pubkey; + let alice = Genesis::new(11_000, vec![bob]); + let mut acc = Accountant::new(&alice, Some(2)); - let bob_pubkey = get_pubkey(&bob_keypair); assert_eq!( - acc.transfer(10_001, &alice_keypair, bob_pubkey), + acc.transfer(10_001, &alice.get_keypair(), bob_pubkey), Err(AccountingError::InsufficientFunds) ); sleep(Duration::from_millis(30)); - let alice_pubkey = get_pubkey(&alice_keypair); + let alice_pubkey = get_pubkey(&alice.get_keypair()); assert_eq!(acc.get_balance(&alice_pubkey).unwrap(), 10_000); assert_eq!(acc.get_balance(&bob_pubkey).unwrap(), 1_000); @@ -205,30 +204,11 @@ mod tests { ); } - #[test] - fn test_multiple_claims() { - let zero = Sha256Hash::default(); - let mut acc = Accountant::new(&zero, Some(2)); - let keypair = generate_keypair(); - acc.deposit(1, &keypair).unwrap(); - let sig = acc.deposit(2, &keypair).unwrap(); - acc.wait_on_signature(&sig); - - let pubkey = get_pubkey(&keypair); - assert_eq!(acc.get_balance(&pubkey).unwrap(), 3); - - drop(acc.historian.sender); - assert_eq!( - acc.historian.thread_hdl.join().unwrap().1, - ExitReason::RecvDisconnected - ); - } - #[test] fn test_transfer_to_newb() { - let zero = Sha256Hash::default(); - let mut acc = Accountant::new(&zero, Some(2)); - let alice_keypair = generate_keypair(); + let alice = Genesis::new(10_000, vec![]); + let mut acc = Accountant::new(&alice, Some(2)); + let alice_keypair = alice.get_keypair(); let bob_keypair = generate_keypair(); let sig = acc.deposit(10_000, &alice_keypair).unwrap(); acc.wait_on_signature(&sig); diff --git a/src/accountant_stub.rs b/src/accountant_stub.rs index 9b4285b6f..9b38e751b 100644 --- a/src/accountant_stub.rs +++ b/src/accountant_stub.rs @@ -82,27 +82,22 @@ mod tests { use accountant_skel::AccountantSkel; use std::thread::{sleep, spawn}; use std::time::Duration; - use log::Sha256Hash; - use event::{generate_keypair, get_pubkey}; + use genesis::{Creator, Genesis}; #[test] fn test_accountant_stub() { let addr = "127.0.0.1:9000"; let send_addr = "127.0.0.1:9001"; - let zero = Sha256Hash::default(); - let alice_keypair = generate_keypair(); - let bob_keypair = generate_keypair(); - let mut acc = Accountant::new(&zero, None); - acc.deposit(10_000, &alice_keypair).unwrap(); - let sig = acc.deposit(1_000, &bob_keypair).unwrap(); - acc.wait_on_signature(&sig); + let bob = Creator::new("Bob", 1_000); + let bob_pubkey = bob.pubkey; + let alice = Genesis::new(10_000, vec![bob]); + let acc = Accountant::new(&alice, None); spawn(move || AccountantSkel::new(acc).serve(addr).unwrap()); sleep(Duration::from_millis(30)); let socket = UdpSocket::bind(send_addr).unwrap(); let acc = AccountantStub::new(addr, socket); - let bob_pubkey = get_pubkey(&bob_keypair); - let sig = acc.transfer(500, &alice_keypair, bob_pubkey).unwrap(); + let sig = acc.transfer(500, &alice.get_keypair(), bob_pubkey).unwrap(); acc.wait_on_signature(&sig).unwrap(); assert_eq!(acc.get_balance(&bob_pubkey).unwrap(), 1_500); } diff --git a/src/bin/client-demo.rs b/src/bin/client-demo.rs index 73b200728..43cee19af 100644 --- a/src/bin/client-demo.rs +++ b/src/bin/client-demo.rs @@ -5,6 +5,7 @@ fn main() { use silk::accountant_skel::AccountantSkel; use silk::accountant::Accountant; use silk::event::{generate_keypair, get_pubkey, sign_transaction_data}; + use silk::genesis::Genesis; use std::time::Instant; use std::net::UdpSocket; use std::thread::{sleep, spawn}; @@ -13,12 +14,10 @@ fn main() { let addr = "127.0.0.1:8000"; let send_addr = "127.0.0.1:8001"; - let zero = Default::default(); - let alice_keypair = generate_keypair(); - let mut acc = Accountant::new(&zero, None); let txs = 200; - let sig = acc.deposit(txs, &alice_keypair).unwrap(); - acc.wait_on_signature(&sig); + let gen = Genesis::new(txs, vec![]); + let alice_keypair = generate_keypair(); + let acc = Accountant::new(&gen, None); spawn(move || AccountantSkel::new(acc).serve(addr).unwrap()); sleep(Duration::from_millis(30)); diff --git a/src/bin/genesis-block.rs b/src/bin/genesis-block.rs index 7ec47888e..eeb7c1730 100644 --- a/src/bin/genesis-block.rs +++ b/src/bin/genesis-block.rs @@ -1,7 +1,6 @@ //! A command-line executable for generating the chain's genesis block. extern crate ring; -extern crate serde; extern crate serde_json; extern crate silk; diff --git a/src/bin/testnode.rs b/src/bin/testnode.rs index 4231eda35..141fffb90 100644 --- a/src/bin/testnode.rs +++ b/src/bin/testnode.rs @@ -1,13 +1,15 @@ +extern crate serde_json; extern crate silk; use silk::accountant_skel::AccountantSkel; use silk::accountant::Accountant; -use silk::log::Sha256Hash; +use silk::genesis::Genesis; +use std::io::stdin; fn main() { let addr = "127.0.0.1:8000"; - let zero = Sha256Hash::default(); - let acc = Accountant::new(&zero, Some(1000)); + let gen: Genesis = serde_json::from_reader(stdin()).unwrap(); + let acc = Accountant::new(&gen, Some(1000)); let mut skel = AccountantSkel::new(acc); println!("Listening on {}", addr); skel.serve(addr).unwrap(); diff --git a/src/genesis.rs b/src/genesis.rs index ceea9393a..bb466677e 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -20,19 +20,6 @@ impl Creator { tokens, } } - - pub fn create_transaction(&self, keypair: &Ed25519KeyPair) -> Event { - let from = get_pubkey(keypair); - let to = self.pubkey; - let data = self.tokens; - let sig = sign_transaction_data(&data, keypair, &to); - Event::Transaction { - from, - to, - data, - sig, - } - } } #[derive(Serialize, Deserialize, Debug)] @@ -53,15 +40,33 @@ impl Genesis { } } + pub fn get_keypair(&self) -> Ed25519KeyPair { + Ed25519KeyPair::from_pkcs8(Input::from(&self.pkcs8)).unwrap() + } + + pub fn get_pubkey(&self) -> PublicKey { + get_pubkey(&self.get_keypair()) + } + + pub fn create_transaction(&self, data: u64, to: &PublicKey) -> Event { + let from = self.get_pubkey(); + let sig = sign_transaction_data(&data, &self.get_keypair(), to); + Event::Transaction { + from, + to: *to, + data, + sig, + } + } + pub fn create_events(&self) -> Vec> { - let org_keypair = Ed25519KeyPair::from_pkcs8(Input::from(&self.pkcs8)).unwrap(); + let pubkey = self.get_pubkey(); let event0 = Event::Tick; - let treasury = Creator::new("Treasury", self.tokens); - let event1 = treasury.create_transaction(&org_keypair); + let event1 = self.create_transaction(self.tokens, &pubkey); let mut events = vec![event0, event1]; - for creator in &self.creators { - let tx = creator.create_transaction(&org_keypair); + for x in &self.creators { + let tx = self.create_transaction(x.tokens, &x.pubkey); events.push(tx); } @@ -72,17 +77,21 @@ impl Genesis { #[cfg(test)] mod tests { use super::*; - use event::verify_event; - - #[test] - fn test_creator_transaction() { - assert!(verify_event(&Creator::new("Satoshi", 42) - .create_transaction(&generate_keypair()))); - } #[test] fn test_create_events() { - assert_eq!(Genesis::new(100, vec![]).create_events().len(), 2); + let mut events = Genesis::new(100, vec![]).create_events().into_iter(); + assert_eq!(events.next().unwrap(), Event::Tick); + if let Event::Transaction { from, to, .. } = events.next().unwrap() { + assert_eq!(from, to); + } else { + assert!(false); + } + assert_eq!(events.next(), None); + } + + #[test] + fn test_create_creator() { assert_eq!( Genesis::new(100, vec![Creator::new("Satoshi", 42)]) .create_events()