Load the genesis block

This commit is contained in:
Greg Fitzgerald 2018-03-04 00:13:40 -07:00
parent 876d7995e1
commit 572475ce14
6 changed files with 76 additions and 92 deletions

View File

@ -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<u64>) -> Self {
let hist = Historian::<u64>::new(start_hash, ms_per_tick);
Accountant {
pub fn new(gen: &Genesis, ms_per_tick: Option<u64>) -> Self {
let start_hash = hash(&gen.pkcs8);
let hist = Historian::<u64>::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<Entry<u64>> {
@ -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);

View File

@ -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);
}

View File

@ -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));

View File

@ -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;

View File

@ -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();

View File

@ -20,19 +20,6 @@ impl Creator {
tokens,
}
}
pub fn create_transaction(&self, keypair: &Ed25519KeyPair) -> Event<u64> {
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<u64> {
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<Event<u64>> {
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()