1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//! A library for generating the chain's genesis block.

use event::Event;
use transaction::Transaction;
use signature::{KeyPair, KeyPairUtil, PublicKey};
use entry::Entry;
use log::create_entries;
use hash::{hash, Hash};
use ring::rand::SystemRandom;
use untrusted::Input;

#[derive(Serialize, Deserialize, Debug)]
pub struct Mint {
    pub pkcs8: Vec<u8>,
    pubkey: PublicKey,
    pub tokens: i64,
}

impl Mint {
    pub fn new(tokens: i64) -> Self {
        let rnd = SystemRandom::new();
        let pkcs8 = KeyPair::generate_pkcs8(&rnd).unwrap().to_vec();
        let keypair = KeyPair::from_pkcs8(Input::from(&pkcs8)).unwrap();
        let pubkey = keypair.pubkey();
        Mint {
            pkcs8,
            pubkey,
            tokens,
        }
    }

    pub fn seed(&self) -> Hash {
        hash(&self.pkcs8)
    }

    pub fn keypair(&self) -> KeyPair {
        KeyPair::from_pkcs8(Input::from(&self.pkcs8)).unwrap()
    }

    pub fn pubkey(&self) -> PublicKey {
        self.pubkey
    }

    pub fn create_events(&self) -> Vec<Event> {
        let keypair = self.keypair();
        let tr = Transaction::new(&keypair, self.pubkey(), self.tokens, self.seed());
        vec![Event::Tick, Event::Transaction(tr)]
    }

    pub fn create_entries(&self) -> Vec<Entry> {
        create_entries(&self.seed(), self.create_events())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use log::verify_slice;

    #[test]
    fn test_create_events() {
        let mut events = Mint::new(100).create_events().into_iter();
        assert_eq!(events.next().unwrap(), Event::Tick);
        if let Event::Transaction(tr) = events.next().unwrap() {
            assert_eq!(tr.from, tr.to);
        } else {
            assert!(false);
        }
        assert_eq!(events.next(), None);
    }

    #[test]
    fn test_verify_entries() {
        let entries = Mint::new(100).create_entries();
        assert!(verify_slice(&entries, &entries[0].id));
    }
}