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
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
extern crate flat_tree;

#[derive(Clone, Debug)]
pub struct Node {
    index: u64,
    parent: u64,
    hash: Vec<u8>,
    data: Option<Vec<u8>>,
    size: usize,
}

pub struct Generator {
    roots: Vec<Node>,
    blocks: u64,
    leaf: fn(&Node, &Vec<Node>) -> Vec<u8>,
    parent: fn(&Node, &Node) -> Vec<u8>,
}

impl Generator {
    pub fn new(leaf: fn(&Node, &Vec<Node>) -> Vec<u8>,
               parent: fn(&Node, &Node) -> Vec<u8>)
               -> Generator {
        Generator {
            roots: vec![],
            blocks: 0,
            leaf: leaf,
            parent: parent,
        }
    }

    pub fn next(&mut self, data: Vec<u8>) -> Vec<Node> {
        self.blocks += 1;
        let mut nodes = vec![];
        let index = 2 * self.blocks;
        let len = data.len();
        let mut leaf = Node {
            index: index,
            parent: flat_tree::parent(index),
            hash: vec![],
            data: Some(data),
            size: len,
        };
        let hash = (self.leaf)(&leaf, &self.roots);
        leaf.hash = hash;
        self.roots.push(leaf.clone());
        nodes.push(leaf.clone());

        while self.roots.len() > 1 {
            let ref left = self.roots[self.roots.len() - 2].clone();
            let ref right = self.roots[self.roots.len() - 1].clone();

            if left.parent != right.parent {
                break;
            }

            self.roots.pop();
            let leaf = Node {
                index: left.parent,
                parent: flat_tree::parent(left.parent),
                hash: (self.parent)(left, right),
                size: left.size + right.size,
                data: None,
            };
            let len = self.roots.len();
            self.roots[len - 1] = leaf.clone();
            nodes.push(leaf.clone());
        }

        nodes
    }
}

extern crate ring;

#[cfg(test)]
mod tests {
    use ring::digest;
    use super::{Generator, Node};

    #[test]
    fn it_works() {
        let mut gen = Generator::new(leaf, parent);
        let nodes = gen.next(b"Hello World".to_vec());
        println!("{:?}", nodes);
    }

    fn parent(a: &Node, b: &Node) -> Vec<u8> {
        let mut data = a.data.clone().unwrap();
        data.append(&mut b.data.clone().unwrap());

        digest::digest(&digest::SHA256, data.as_slice())
            .as_ref()
            .to_vec()
    }

    fn leaf(leaf: &Node, roots: &Vec<Node>) -> Vec<u8> {
        let data = leaf.data.clone().unwrap();
        digest::digest(&digest::SHA256, data.as_slice()).as_ref().to_vec()
    }
}