15
15
validate_leafs ,
16
16
)
17
17
18
-
19
18
class MerkleTree :
20
19
"""
21
20
# 🌳 Merkle Tree implementation
22
21
23
22
## Args:
24
- - leafs: List of raw data
25
- - hash_function (Callable[[str], str], optional): Function that hashes the data.
26
- * Defaults to `keccak` if not provided. It must have the signature (data: str) -> str.
27
-
23
+ - leaves: List of raw data
24
+ - hash_function (Callable[[bytes, bytes], bytes], optional): Function that hashes the data.
25
+ * Defaults to `keccak` if not provided
28
26
"""
29
27
30
28
def __init__ (
31
29
self ,
32
- leafs : List [str ],
30
+ leaves : List [str ],
33
31
hash_function : Callable [[bytes , bytes ], bytes ] = lambda x , y : keccak (x + y ),
34
32
) -> None :
35
- validate_leafs (leafs )
33
+ validate_leafs (leaves )
36
34
validate_hash_function (hash_function )
37
35
self .hash_function : Callable [[bytes , bytes ], bytes ] = hash_function
38
- self .raw_leafs : List [str ] = leafs
39
- self .leafs : List [str ] = self .__hash_leafs ( leafs )
40
- self .short_leafs : List [str ] = self .short (self .leafs )
36
+ self .raw_leaves : List [str ] = leaves
37
+ self .leaves : List [str ] = self .__hash_leaves ( leaves )
38
+ self .short_leaves : List [str ] = self .short (self .leaves )
41
39
42
- def __hash_leafs (self , leafs : List [str ]) -> List [str ]:
43
- return list (map (lambda x : self .hash_function (x .encode (), bytes ()), leafs ))
40
+ def __hash_leaves (self , leaves : List [str ]) -> List [str ]:
41
+ return list (map (lambda x : self .hash_function (x .encode (), bytes ()), leaves ))
44
42
45
43
def __repr__ (self ) -> str :
46
- return f"""MerkleTree(\n raw_leafs : { self .raw_leafs } \n leafs : { self .leafs } \n short_leafs : { self .short (self .leafs )} )"""
44
+ return f"""MerkleTree(\n raw_leaves : { self .raw_leaves } \n leaves : { self .leaves } \n short_leaves : { self .short (self .leaves )} )"""
47
45
48
46
def short (self , data : List [str ]) -> List [str ]:
49
47
return [x [:2 ] for x in data ]
50
48
51
49
@property
52
50
def root (self ) -> bytes :
53
- return self .make_root (self .leafs )
51
+ return self .make_root (self .leaves )
54
52
55
53
def proof (self , raw_leaf : str ) -> List [Node ]:
56
54
return self .make_proof (
57
- self .leafs , [], self .hash_function (raw_leaf .encode (), bytes ())
55
+ self .leaves , [], self .hash_function (raw_leaf .encode (), bytes ())
58
56
)
59
57
60
58
def verify (self , proof : List [bytes ], raw_leaf : str ) -> bool :
@@ -80,31 +78,31 @@ def concat_nodes(left: Node, right: Node) -> Node:
80
78
81
79
return reduce (concat_nodes , full_proof ).data == self .root
82
80
83
- def make_root (self , leafs : List [bytes ]) -> List [ str ] :
84
- while len (leafs ) > 1 :
81
+ def make_root (self , leaves : List [bytes ]) -> bytes :
82
+ while len (leaves ) > 1 :
85
83
next_level = []
86
- for i in range (0 , len (leafs ) - 1 , 2 ):
87
- next_level .append (self .hash_function (leafs [i ], leafs [i + 1 ]))
84
+ for i in range (0 , len (leaves ) - 1 , 2 ):
85
+ next_level .append (self .hash_function (leaves [i ], leaves [i + 1 ]))
88
86
89
- if len (leafs ) % 2 == 1 :
90
- next_level .append (leafs [- 1 ])
87
+ if len (leaves ) % 2 == 1 :
88
+ next_level .append (leaves [- 1 ])
91
89
92
- leafs = next_level
90
+ leaves = next_level
93
91
94
- return leafs [0 ]
92
+ return leaves [0 ]
95
93
96
94
def make_proof (
97
- self , leafs : List [bytes ], proof : List [Node ], leaf : bytes
95
+ self , leaves : List [bytes ], proof : List [Node ], leaf : bytes
98
96
) -> List [Node ]:
99
97
"""
100
98
# Make a proof
101
99
102
100
## Dev:
103
- - if the `leaf` index is less than half the size of the `leafs `
101
+ - if the `leaf` index is less than half the size of the `leaves `
104
102
list then the right side must reach root and vice versa
105
103
106
104
## Args:
107
- - leafs : List of leafs
105
+ - leaves : List of leaves
108
106
- proof: Accumulated proof
109
107
- leaf: Leaf for which to create the proof
110
108
@@ -113,25 +111,25 @@ def make_proof(
113
111
"""
114
112
115
113
try :
116
- index = leafs .index (leaf )
114
+ index = leaves .index (leaf )
117
115
except ValueError as err :
118
- msg = f"Leaf: { leaf } does not exist in the tree: { leafs } "
116
+ msg = f"Leaf: { leaf } does not exist in the tree: { leaves } "
119
117
raise ValueError (msg ) from err
120
118
121
- if is_power_2 (len (leafs )) is False :
122
- return self .mix_tree (leafs , [], index )
119
+ if is_power_2 (len (leaves )) is False :
120
+ return self .mix_tree (leaves , [], index )
123
121
124
- if len (leafs ) == 2 :
122
+ if len (leaves ) == 2 :
125
123
if index == 1 :
126
- proof .append (Node (data = leafs [0 ], side = Side .LEFT ))
124
+ proof .append (Node (data = leaves [0 ], side = Side .LEFT ))
127
125
else :
128
- proof .append (Node (data = leafs [1 ], side = Side .RIGHT ))
126
+ proof .append (Node (data = leaves [1 ], side = Side .RIGHT ))
129
127
proof .reverse ()
130
128
return proof
131
129
132
- left , right = half (leafs )
130
+ left , right = half (leaves )
133
131
134
- if index < len (leafs ) / 2 :
132
+ if index < len (leaves ) / 2 :
135
133
proof .append (Node (data = self .make_root (right ), side = Side .RIGHT ))
136
134
return self .make_proof (left , proof , leaf )
137
135
else :
0 commit comments