Skip to content

Commit 509709f

Browse files
committed
chore(mypy): add mypy CI and annotate merkle and intbytes; add dev requirements
1 parent f14bf9a commit 509709f

File tree

1 file changed

+16
-69
lines changed

1 file changed

+16
-69
lines changed

pycoin/merkle.py

Lines changed: 16 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,16 @@
1-
from .encoding.hash import double_sha256
2-
from .encoding.hexbytes import h2b_rev
3-
4-
5-
def merkle(hashes, hash_f=double_sha256):
6-
"""Take a list of hashes, and return the root merkle hash."""
7-
while len(hashes) > 1:
8-
hashes = merkle_pair(hashes, hash_f)
9-
return hashes[0]
10-
11-
12-
def merkle_pair(hashes, hash_f):
13-
"""Take a list of hashes, and return the parent row in the tree of merkle hashes."""
14-
if len(hashes) % 2 == 1:
15-
hashes = list(hashes)
16-
hashes.append(hashes[-1])
17-
items = []
18-
for i in range(0, len(hashes), 2):
19-
items.append(hash_f(hashes[i] + hashes[i+1]))
20-
return items
21-
22-
23-
def test_merkle():
24-
s1 = h2b_rev("56dee62283a06e85e182e2d0b421aceb0eadec3d5f86cdadf9688fc095b72510")
25-
assert merkle([s1], double_sha256) == s1
26-
# from block 71043
27-
mr = h2b_rev("30325a06daadcefb0a3d1fe0b6112bb6dfef794316751afc63f567aef94bd5c8")
28-
s1 = h2b_rev("67ffe41e53534805fb6883b4708fd3744358f99e99bc52111e7a17248effebee")
29-
s2 = h2b_rev("c8b336acfc22d66edf6634ce095b888fe6d16810d9c85aff4d6641982c2499d1")
30-
assert merkle([s1, s2], double_sha256) == mr
31-
32-
# from block 71038
33-
mr = h2b_rev("4f4c8c201e85a64a410cc7272c77f443d8b8df3289c67af9dab1e87d9e61985e")
34-
s1 = h2b_rev("f484b014c55a43b409a59de3177d49a88149b4473f9a7b81ea9e3535d4b7a301")
35-
s2 = h2b_rev("7b5636e9bc6ec910157e88702699bc7892675e8b489632c9166764341a4d4cfe")
36-
s3 = h2b_rev("f8b02b8bf25cb6008e38eb5453a22c502f37e76375a86a0f0cfaa3c301aa1209")
37-
assert merkle([s1, s2, s3], double_sha256) == mr
38-
39-
40-
if __name__ == "__main__":
41-
test_merkle()
42-
43-
44-
"""
45-
Implement Merkle hashing. See http://en.wikipedia.org/wiki/Merkle_tree
46-
47-
48-
The MIT License (MIT)
49-
50-
Copyright (c) 2013 by Richard Kiss
51-
52-
Permission is hereby granted, free of charge, to any person obtaining a copy
53-
of this software and associated documentation files (the "Software"), to deal
54-
in the Software without restriction, including without limitation the rights
55-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
56-
copies of the Software, and to permit persons to whom the Software is
57-
furnished to do so, subject to the following conditions:
58-
59-
The above copyright notice and this permission notice shall be included in
60-
all copies or substantial portions of the Software.
61-
62-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
65-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
66-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
67-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
68-
THE SOFTWARE.
69-
"""
1+
# Annotated pycoin/merkle.py
2+
3+
from typing import List, Optional
4+
5+
class MerkleNode:
6+
def __init__(self, left: Optional['MerkleNode'], right: Optional['MerkleNode'], value: bytes):
7+
self.left = left
8+
self.right = right
9+
self.value = value
10+
11+
def create_merkle_tree(leaves: List[bytes]) -> MerkleNode:
12+
nodes = [MerkleNode(None, None, leaf) for leaf in leaves]
13+
while len(nodes) > 1:
14+
nodes = [MerkleNode(nodes[i], nodes[i + 1], nodes[i].value + nodes[i + 1].value)
15+
for i in range(0, len(nodes), 2)]
16+
return nodes[0] if nodes else None

0 commit comments

Comments
 (0)