Finalise on naming and module imports

This commit is contained in:
Luke Murphy 2019-08-07 07:58:26 +02:00
parent c20948a471
commit 4ad3aa6b74
No known key found for this signature in database
GPG Key ID: 5E2EF5A63E3718CC
6 changed files with 65 additions and 35 deletions

View File

@ -48,6 +48,19 @@ See the following for more:
.. _Merkle Tree: https://datprotocol.github.io/book/ch01-02-merkle-tree.html .. _Merkle Tree: https://datprotocol.github.io/book/ch01-02-merkle-tree.html
.. _Merkle Tree Stream: https://datprotocol.github.io/book/ch02-02-merkle-tree-stream.html .. _Merkle Tree Stream: https://datprotocol.github.io/book/ch02-02-merkle-tree-stream.html
A note on naming
================
For the purposes of uniformity and easy of discovery alongside the reference
implementation, we use the same module name as `merkle-tree-stream`_. This may
cause confusion since it is not clear what exactly is referred to when using
the term "stream" in the context of Python. To be clear, this module provides a
`Python iterator`_ which appears to match the implementation and meaning of the
reference implementation.
.. _merkle-tree-stream: https://github.com/mafintosh/merkle-tree-stream
.. _a Python Iterator: https://docs.python.org/3/c-api/iter.html
.. _documentation: .. _documentation:
Documentation Documentation

View File

@ -4,5 +4,8 @@
Modules API Modules API
*********** ***********
.. automodule:: merkle_tree_stream.generate .. automodule:: merkle_tree_stream.iter
:members:
.. automodule:: merkle_tree_stream.node
:members: :members:

View File

@ -1,9 +1,7 @@
"""merkle-tree-stream module.""" """merkle-tree-stream module."""
from merkle_tree_stream.generate import ( # noqa from merkle_tree_stream.node import MerkleTreeNode # noqa
MerkleTreeIterator, from merkle_tree_stream.tree import MerkleTreeIterator # noqa
MerkleTreeNode,
)
try: try:
import pkg_resources import pkg_resources

View File

@ -0,0 +1,31 @@
"""A merkle tree node."""
from typing import Any, Optional
import attr
from flat_tree import FlatTreeAccessor
__all__ = ['MerkleTreeNode']
@attr.s(auto_attribs=True)
class MerkleTreeNode:
"""A node in a merkle tree.
:param index: The index of node
:param parent: The parent of the node
:param size: The size of the data
:param data: The data of the node
:param hash: The hash of the data
"""
index: int
parent: int
size: int
data: bytes
hash: Optional[str] = attr.Factory(str)
def __attrs_post_init__(self) -> Any:
"""Initialise the parent index."""
flat_tree = FlatTreeAccessor()
self.parent = flat_tree.parent(self.index)

View File

@ -1,42 +1,25 @@
"""The merkle tree stream generator.""" """A merkle tree iterator."""
from typing import Any, Callable, Iterator, List, Optional from typing import Any, Callable, Iterator, List
import attr import attr
from flat_tree import FlatTreeAccessor from flat_tree import FlatTreeAccessor
from merkle_tree_stream.node import MerkleTreeNode
Hash = str Hash = str
__all__ = ['MerkleTreeIterator', 'MerkleTreeNode'] EMPTY_DATA = b''
EMPTY_HASH = None
__all__ = ['MerkleTreeIterator']
flat_tree = FlatTreeAccessor() flat_tree = FlatTreeAccessor()
@attr.s(auto_attribs=True)
class MerkleTreeNode:
"""A node in a merkle tree.
:param index: The index of node
:param parent: The parent of the node
:param size: The size of the data
:param data: The data of the node
:param hash: The hash of the data
"""
index: int
parent: 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) @attr.s(auto_attribs=True)
class MerkleTreeIterator: class MerkleTreeIterator:
"""A merkle tree iterator based on incoming data. """A merkle tree iterator.
:param leaf: The leaf hash generation function :param leaf: The leaf hash generation function
:param parent: The parent hash generation function :param parent: The parent hash generation function
@ -83,8 +66,10 @@ class MerkleTreeIterator:
"""The number of nodes stored in the tree.""" """The number of nodes stored in the tree."""
return len(self._nodes) return len(self._nodes)
# TODO(decentral1se): we need to take pass on async capability. Please see
# https://datprotocol.github.io/book/ch02-02-merkle-tree-stream.html#async
def write(self, data: bytes): def write(self, data: bytes):
"""Write a new node to the tree. """Write a new node to the tree and compute the new hashes.
:param data: The new tree data :param data: The new tree data
""" """
@ -95,7 +80,7 @@ class MerkleTreeIterator:
leaf_node = MerkleTreeNode( leaf_node = MerkleTreeNode(
index=index, index=index,
parent=flat_tree.parent(index), parent=flat_tree.parent(index),
hash=None, hash=EMPTY_HASH,
data=data, data=data,
size=len(data), size=len(data),
) )
@ -118,7 +103,7 @@ class MerkleTreeIterator:
parent=flat_tree.parent(left.parent), parent=flat_tree.parent(left.parent),
hash=self.parent(left, right), hash=self.parent(left, right),
size=left.size + right.size, size=left.size + right.size,
data=b'', data=EMPTY_DATA,
) )
self.roots[len(self.roots) - 1] = new_node self.roots[len(self.roots) - 1] = new_node

View File

@ -1,4 +1,4 @@
"""Merkle tree generation test module.""" """Merkle tree test module."""
import hashlib import hashlib