From c89cafe0225aadbd0bb75367c3f7f5b10a10bff7 Mon Sep 17 00:00:00 2001 From: Luke Murphy Date: Sun, 14 Jul 2019 13:14:02 +0200 Subject: [PATCH] Try to draw out the first API draft of the generator --- merkle_tree_stream/generator.py | 68 +++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 merkle_tree_stream/generator.py diff --git a/merkle_tree_stream/generator.py b/merkle_tree_stream/generator.py new file mode 100644 index 0000000..d29201b --- /dev/null +++ b/merkle_tree_stream/generator.py @@ -0,0 +1,68 @@ +"""The merkle tree stream generator.""" + +from typing import Any, Callable, List, Optional + +import attr +from flat_tree import FlatTreeAccessor + +__all__ = ['MerkleTreeGenerator', 'MerkleTreeNode'] + + +Hash = str + +flat_tree = FlatTreeAccessor() + + +@attr.s(auto_attribs=True) +class MerkleTreeNode: + """A node in a merkle tree. + + :param index: TODO + :param parent: TODO + :param size: TODO + :param data: TODO + :param hash: TODO + """ + + index: int + parent: Optional[int] + size: int + data: bytes + hash: Optional[str] = None + + def __attrs_post_init__(self) -> Any: + """Initialise the parent index.""" + self.parent = flat_tree.parent(self.index) + + +@attr.s(auto_attribs=True) +class MerkleTreeGenerator: + """A stream that generates a merkle tree based on the incoming data. + + :param leaf: TODO + :param parent: TODO + :param roots: TODO + :param blocks: TODO + """ + + leaf: Callable[[bytes], Hash] + parent: Callable[[bytes], Hash] + blocks: int + roots: Optional[List[MerkleTreeNode]] = attr.Factory(list) + + def next(self, data: bytes) -> List[MerkleTreeNode]: + """Further generate the treem based on the incoming data. + + :param data: Incoming data + """ + pass + + def __attrs_post_init__(self) -> Any: + """Initialise parent and block defaults.""" + for root in self.roots: + if not root.parent: + root.parent = flat_tree.parent(root.index) + + # https://github.com/mafintosh/merkle-tree-stream/blob/master/generator.js#L14 + # self.roots[self.roots.length] ... + # self.blocks = (1 + (flat_tree.right_span(...) / 2)) if self.roots else 0