Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
352a7d3697 | |||
4b47706883 | |||
15cac7d390 | |||
c470b70722 | |||
9a651a9d3d | |||
a293d4bada |
@ -1,3 +1,21 @@
|
||||
Merkle_Tree_Stream 0.0.1a4 (2019-11-03)
|
||||
=======================================
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- New Sphinx theme. Improved clarity with documentation.
|
||||
|
||||
|
||||
Merkle_Tree_Stream 0.0.1a3 (2019-10-08)
|
||||
=======================================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- MerkleTreeIterator -> MerkleTreeGenerator
|
||||
|
||||
|
||||
Merkle_Tree_Stream 0.0.1a2 (2019-10-06)
|
||||
=======================================
|
||||
|
||||
|
@ -1,28 +1,28 @@
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The DatPy community is committed to providing an inclusive,
|
||||
safe, and collaborative environment for all participants, regardless of their
|
||||
gender, gender expression, race, ethnicity, religion, sexual orientation,
|
||||
sexual characteristics, physical appearance, disability, or age. We encourage
|
||||
every participant to be themselves, and must respect the rights of others. The
|
||||
code of conduct is a set of guidelines that establishes shared values and
|
||||
ensures that behaviors that may harm participants are avoided.
|
||||
The DatPy community is committed to providing an inclusive, safe, and
|
||||
collaborative environment for all participants, regardless of their gender,
|
||||
gender expression, race, ethnicity, religion, sexual orientation, sexual
|
||||
characteristics, physical appearance, disability, or age. We encourage every
|
||||
participant to be themselves, and must respect the rights of others. The code
|
||||
of conduct is a set of guidelines that establishes shared values and ensures
|
||||
that behaviors that may harm participants are avoided.
|
||||
|
||||
The values of the DatPy community are focused on developing
|
||||
both our individual and collective potential, supporting and empowering the
|
||||
most marginalized, mutual respect, and an anti-violence approach that favors
|
||||
support and collaboration among participants and the resolution of conflicts. A
|
||||
code of conduct helps us co-exist in a more positive way and provides
|
||||
individuals who are victims of negative behaviors with confidence that they
|
||||
will be supported by the organization and the DatPy
|
||||
community, who respects and stands behind the code of conduct.
|
||||
The values of the DatPy community are focused on developing both our individual
|
||||
and collective potential, supporting and empowering the most marginalized,
|
||||
mutual respect, and an anti-violence approach that favors support and
|
||||
collaboration among participants and the resolution of conflicts. A code of
|
||||
conduct helps us co-exist in a more positive way and provides individuals who
|
||||
are victims of negative behaviors with confidence that they will be supported
|
||||
by the organization and the DatPy community, who respects and stands behind the
|
||||
code of conduct.
|
||||
|
||||
The DatPy community works towards providing a welcoming
|
||||
environment where participants are treated with dignity and respect and are
|
||||
free to be themselves. We encourage all participants to approach the
|
||||
Librehosters network with an open and positive attitude, engaging
|
||||
constructively with others at all times.
|
||||
The DatPy community works towards providing a welcoming environment where
|
||||
participants are treated with dignity and respect and are free to be
|
||||
themselves. We encourage all participants to approach the Librehosters network
|
||||
with an open and positive attitude, engaging constructively with others at all
|
||||
times.
|
||||
|
||||
Respect for Diversity & Inclusion
|
||||
---------------------------------
|
||||
@ -92,9 +92,9 @@ Enforcement
|
||||
Overseeing the code of conduct
|
||||
==============================
|
||||
|
||||
The DatPy community, composed of volunteers, oversees the
|
||||
code of conduct, including addressing all incident reports. Breaking the code
|
||||
of conduct may result in immediate expulsion from the Librehosters network.
|
||||
The DatPy community, composed of volunteers, oversees the code of conduct,
|
||||
including addressing all incident reports. Breaking the code of conduct may
|
||||
result in immediate expulsion from the Librehosters network.
|
||||
|
||||
How to Report an Incident
|
||||
=========================
|
||||
|
@ -33,8 +33,36 @@ Type check source
|
||||
|
||||
tox -e type
|
||||
|
||||
Release Process
|
||||
---------------
|
||||
Build the documentation
|
||||
-----------------------
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ tox -e docs
|
||||
$ tox -e docs-livereload
|
||||
|
||||
Make a new release
|
||||
------------------
|
||||
|
||||
Ensure metadata for packaging is correct.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ tox -e metadata-release
|
||||
|
||||
Generate the changelog with the next target version.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ export VERSION=1.0.1 tox -e changelog
|
||||
|
||||
Make a new Git tag.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ git tag -a 1.0.1
|
||||
|
||||
And finally, make a new release.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
|
46
README.rst
46
README.rst
@ -48,40 +48,21 @@ See the following for more:
|
||||
.. _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
|
||||
|
||||
Part of the `Datpy`_ project.
|
||||
|
||||
.. _Datpy: https://datpy.decentral1.se/
|
||||
|
||||
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.
|
||||
implementation, we use the same module name as `merkle-tree-stream`_. However,
|
||||
there is currently no stream implemented, only a generator is available. This
|
||||
is because the reference implementation of Hypercore 7 makes use of the
|
||||
generator only. A `stream`_ implementation may follow.
|
||||
|
||||
.. _merkle-tree-stream: https://github.com/mafintosh/merkle-tree-stream
|
||||
.. _Python iterator: https://docs.python.org/3/c-api/iter.html
|
||||
|
||||
.. _example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from hashlib import sha256
|
||||
from merkle_tree_stream import MerkleTreeIterator
|
||||
|
||||
|
||||
def leaf(node, roots=None):
|
||||
return sha256(node.data).digest()
|
||||
|
||||
def parent(first, second):
|
||||
sha256 = hashlib.sha256()
|
||||
sha256.update(first.data)
|
||||
sha256.update(second.data)
|
||||
return sha256.digest()
|
||||
|
||||
merkle_iter = MerkleTreeIterator(leaf=leaf, parent=parent)
|
||||
merkle_iter.write('hello')
|
||||
merkle_iter.write('hashed')
|
||||
merkle_iter.write('world')
|
||||
.. _stream: https://docs.python.org/3/library/asyncio-stream.html
|
||||
|
||||
.. _documentation:
|
||||
|
||||
@ -91,12 +72,3 @@ Documentation
|
||||
* `merkle-tree-stream.readthedocs.io`_
|
||||
|
||||
.. _merkle-tree-stream.readthedocs.io: https://merkle-tree-stream.readthedocs.io/
|
||||
|
||||
Mirroring
|
||||
*********
|
||||
|
||||
* `hack.decentral1.se/datpy/merkle-tree-stream`_
|
||||
* `github.com/datpy/merkle-tree-stream`_
|
||||
|
||||
.. _hack.decentral1.se/datpy/merkle-tree-stream: https://hack.decentral1.se/datpy/merkle-tree-stream
|
||||
.. _github.com/datpy/merkle-tree-stream: https://github.com/datpy/merkle-tree-stream
|
||||
|
@ -1,7 +1,7 @@
|
||||
author = 'decentral1se'
|
||||
copyright = '2019, decentral1se'
|
||||
html_static_path = ['_static']
|
||||
html_theme = 'alabaster'
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
master_doc = 'index'
|
||||
project = 'merkle-tree-stream'
|
||||
templates_path = ['_templates']
|
||||
|
24
documentation/source/example.rst
Normal file
24
documentation/source/example.rst
Normal file
@ -0,0 +1,24 @@
|
||||
.. _example:
|
||||
|
||||
*******
|
||||
Example
|
||||
*******
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from hashlib import sha256
|
||||
from merkle_tree_stream import MerkleTreeGenerator
|
||||
|
||||
def leaf(node, roots=None):
|
||||
return sha256(node.data).digest()
|
||||
|
||||
def parent(first, second):
|
||||
sha256 = hashlib.sha256()
|
||||
sha256.update(first.data)
|
||||
sha256.update(second.data)
|
||||
return sha256.digest()
|
||||
|
||||
merkle = MerkleTreeGenerator(leaf=leaf, parent=parent)
|
||||
merkle.write('hello')
|
||||
merkle.write('hashed')
|
||||
merkle.write('world')
|
@ -1,12 +1,13 @@
|
||||
.. include:: ../../README.rst
|
||||
:end-before: _documentation
|
||||
|
||||
Table of Contents
|
||||
*****************
|
||||
:end-before: _documentation
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:hidden:
|
||||
|
||||
install
|
||||
upgrade
|
||||
example
|
||||
modules-api
|
||||
other-impls
|
||||
contribute
|
||||
|
@ -3,6 +3,10 @@
|
||||
Other Implementations
|
||||
*********************
|
||||
|
||||
* https://github.com/mafintosh/merkle-tree-stream
|
||||
* https://github.com/datrs/merkle-tree-stream
|
||||
* https://github.com/datcxx/merkle-tree-stream
|
||||
* `mafintosh/merkle-tree-stream`_
|
||||
* `datrs/merkle-tree-stream`_
|
||||
* `datcxx/merkle-tree-stream`_
|
||||
|
||||
.. _mafintosh/merkle-tree-stream: https://github.com/mafintosh/merkle-tree-stream
|
||||
.. _datrs/merkle-tree-stream: https://github.com/datrs/merkle-tree-stream
|
||||
.. _datcxx/merkle-tree-stream: https://github.com/datcxx/merkle-tree-stream
|
||||
|
7
documentation/source/upgrade.rst
Normal file
7
documentation/source/upgrade.rst
Normal file
@ -0,0 +1,7 @@
|
||||
*******
|
||||
Upgrade
|
||||
*******
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pip install --upgrade merkle-tree-stream
|
@ -1,7 +1,7 @@
|
||||
"""merkle-tree-stream module."""
|
||||
|
||||
from merkle_tree_stream.node import MerkleTreeNode # noqa
|
||||
from merkle_tree_stream.tree import MerkleTreeIterator # noqa
|
||||
from merkle_tree_stream.tree import MerkleTreeGenerator # noqa
|
||||
|
||||
try:
|
||||
import pkg_resources
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""A merkle tree iterator."""
|
||||
"""A merkle tree generator."""
|
||||
|
||||
from typing import Any, Callable, Iterator, List
|
||||
|
||||
@ -10,14 +10,14 @@ from merkle_tree_stream.node import MerkleTreeNode
|
||||
EMPTY_DATA = b''
|
||||
EMPTY_HASH = None
|
||||
|
||||
__all__ = ['MerkleTreeIterator']
|
||||
__all__ = ['MerkleTreeGenerator']
|
||||
|
||||
flat_tree = FlatTreeAccessor()
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True)
|
||||
class MerkleTreeIterator:
|
||||
"""A merkle tree iterator.
|
||||
class MerkleTreeGenerator:
|
||||
"""A merkle tree generator.
|
||||
|
||||
:param leaf: The leaf hash generation function
|
||||
:param parent: The parent hash generation function
|
||||
|
@ -61,6 +61,7 @@ warning-is-error = True
|
||||
[options.extras_require]
|
||||
docs =
|
||||
sphinx
|
||||
sphinx_rtd_theme
|
||||
sphinx-autodoc-typehints >= 1.6.0, < 2.0
|
||||
changelog =
|
||||
towncrier <= 19.2.0, < 20.0
|
||||
|
@ -4,53 +4,53 @@ import hashlib
|
||||
|
||||
import pytest
|
||||
|
||||
from merkle_tree_stream import MerkleTreeIterator, MerkleTreeNode
|
||||
from merkle_tree_stream import MerkleTreeGenerator, MerkleTreeNode
|
||||
|
||||
|
||||
def test_hashes(leaf, parent):
|
||||
merkle_iter = MerkleTreeIterator(leaf=leaf, parent=parent)
|
||||
merkle = MerkleTreeGenerator(leaf=leaf, parent=parent)
|
||||
|
||||
merkle_iter.write(b'a')
|
||||
merkle_iter.write(b'b')
|
||||
merkle.write(b'a')
|
||||
merkle.write(b'b')
|
||||
|
||||
expected_count = 2 + 1 # nodes plus parent
|
||||
assert len(merkle_iter) == expected_count
|
||||
assert len(merkle) == expected_count
|
||||
|
||||
assert next(merkle_iter) == MerkleTreeNode(
|
||||
assert next(merkle) == MerkleTreeNode(
|
||||
index=0, parent=1, hash=hashlib.sha256(b'a').digest(), size=1, data=b'a'
|
||||
)
|
||||
|
||||
assert next(merkle_iter) == MerkleTreeNode(
|
||||
assert next(merkle) == MerkleTreeNode(
|
||||
index=2, parent=1, hash=hashlib.sha256(b'b').digest(), size=1, data=b'b'
|
||||
)
|
||||
|
||||
hashed = hashlib.sha256(b'a')
|
||||
hashed.update(b'b')
|
||||
|
||||
assert next(merkle_iter) == MerkleTreeNode(
|
||||
assert next(merkle) == MerkleTreeNode(
|
||||
index=1, parent=3, hash=hashed.digest(), size=2, data=b''
|
||||
)
|
||||
|
||||
with pytest.raises(StopIteration):
|
||||
next(merkle_iter)
|
||||
next(merkle)
|
||||
|
||||
|
||||
def test_single_root(leaf, parent):
|
||||
merkle_iter = MerkleTreeIterator(leaf=leaf, parent=parent)
|
||||
merkle = MerkleTreeGenerator(leaf=leaf, parent=parent)
|
||||
|
||||
merkle_iter.write(b'a')
|
||||
merkle_iter.write(b'b')
|
||||
merkle_iter.write(b'c')
|
||||
merkle_iter.write(b'd')
|
||||
merkle.write(b'a')
|
||||
merkle.write(b'b')
|
||||
merkle.write(b'c')
|
||||
merkle.write(b'd')
|
||||
|
||||
assert len(merkle_iter.roots) == 1
|
||||
assert len(merkle.roots) == 1
|
||||
|
||||
|
||||
def multiple_roots(leaf, parent):
|
||||
merkle_iter = MerkleTreeIterator(leaf=leaf, parent=parent)
|
||||
merkle = MerkleTreeGenerator(leaf=leaf, parent=parent)
|
||||
|
||||
merkle_iter.write(b'a')
|
||||
merkle_iter.write(b'b')
|
||||
merkle_iter.write(b'c')
|
||||
merkle.write(b'a')
|
||||
merkle.write(b'b')
|
||||
merkle.write(b'c')
|
||||
|
||||
assert len(merkle_iter.roots) > 1
|
||||
assert len(merkle.roots) > 1
|
||||
|
23
tox.ini
23
tox.ini
@ -34,13 +34,11 @@ commands = isort {posargs:-rc -c} -sp setup.cfg merkle_tree_stream/ test/
|
||||
[testenv:format]
|
||||
description = format the source
|
||||
skipdist = True
|
||||
basepython = python3.6
|
||||
deps = black
|
||||
commands = black {posargs:--check} merkle_tree_stream/ test/
|
||||
|
||||
[testenv:type]
|
||||
description = type check the source
|
||||
basepython = python3.7
|
||||
skipdist = True
|
||||
deps = mypy
|
||||
commands = mypy merkle_tree_stream/ test/
|
||||
@ -52,19 +50,30 @@ extras = docs
|
||||
commands = python -m setup build_sphinx
|
||||
|
||||
[testenv:changelog]
|
||||
description = draft the changelog
|
||||
description = draw up the new changelog
|
||||
skipdist = True
|
||||
extras = changelog
|
||||
commands = towncrier --draft
|
||||
passenv = VERSION
|
||||
deps = towncrier
|
||||
commands = towncrier --version={env:VERSION} {posargs}
|
||||
|
||||
[testenv:metadata-release]
|
||||
description = validate the package metadata
|
||||
deps = twine
|
||||
commands = twine check {toxworkdir}/dist/*
|
||||
commands =
|
||||
rm -rf {toxworkdir}/dist
|
||||
python -m setup sdist --dist-dir {toxworkdir}/dist bdist_wheel
|
||||
python -m setup sdist --dist-dir {toxworkdir}/dist bdist_egg
|
||||
twine check {toxworkdir}/dist/*
|
||||
whitelist_externals =
|
||||
rm
|
||||
|
||||
[testenv:release]
|
||||
description = make a release
|
||||
deps = {[testenv:metadata-release]deps}
|
||||
commands =
|
||||
python -m setup sdist bdist_wheel
|
||||
rm -rf {toxworkdir}/dist
|
||||
python -m setup sdist --dist-dir {toxworkdir}/dist bdist_wheel
|
||||
python -m setup sdist --dist-dir {toxworkdir}/dist bdist_egg
|
||||
twine upload {toxworkdir}/dist/*
|
||||
whitelist_externals =
|
||||
rm
|
||||
|
Reference in New Issue
Block a user