datrs / merkle-tree-stream

A stream that generates a merkle tree based on the incoming data.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add finalize like method

drbh opened this issue · comments

commented

This is an awesome library! Great work.

In my use case - I'd like to produce a single root regardless of the input size (similar to the Bitcoin implementation)

Looking at the JS library, it seems like there was a PR open to add this exact functionality https://github.com/mafintosh/merkle-tree-stream/pull/4/files

I've forked the repo but am having trouble translating the code. Would you be able to either help me implement this feature or implement it yourself?

The logic doesn't seem too complicated - I am just get hung up on creating the correct struct to append on the root vector.

Here is the start of my attempt

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

    if left.parent() != right.parent() {
      if (!merge) {
        break;
      }

      let partial_n = match &leaf.data() {
        NodeKind::Parent => PartialNode {
          index: flat::sibling(right.index()),
          parent: right.parent(),
          length: right.len(),
          data: NodeKind::Leaf(data.to_vec()),
        },
        NodeKind::Leaf(data) => PartialNode {
          index: flat::sibling(right.index()),
          parent: right.parent(),
          length: right.len(),
          data: NodeKind::Leaf(data.to_vec()),
        },
      };

      H::Node::from(NodeParts {
        node: partial_n,
        hash: hash, // Problem cloning hash??
      });
    }

    let hash = self.handler.parent(left, right);
    let partial = PartialNode {
      index: left.parent(),
      parent: flat::parent(left.parent()) as u64,
      length: left.len() + right.len(),
      data: NodeKind::Parent,
    };

    H::Node::from(NodeParts {
      node: partial,
      hash,
    })
  };

Thanks again!