Skip to content

Commit 30be689

Browse files
committed
Fix taproot hash and tests
1 parent a3e57c3 commit 30be689

1 file changed

Lines changed: 25 additions & 16 deletions

File tree

bitcoinutils/utils.py

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def __init__(self, pubkey: PublicKey, scripts: None | list[list[Script]], index:
8989
"""
9090
self.pubkey = pubkey
9191
self.scripts = scripts
92-
self.merkle_path = b"".join(_generate_merkle_path(scripts, index))
92+
self.merkle_path = _generate_merkle_path(scripts, index)
9393
self.is_odd = is_odd
9494

9595
def to_bytes(self) -> bytes:
@@ -101,7 +101,8 @@ def to_bytes(self) -> bytes:
101101
def to_hex(self):
102102
"""Converts object to hexadecimal string"""
103103
return b_to_h(self.to_bytes())
104-
104+
105+
105106
def _generate_merkle_path(all_leafs, target_leaf_index):
106107
"""Generate the merkle path for spending a taproot path.
107108
@@ -117,25 +118,33 @@ def _generate_merkle_path(all_leafs, target_leaf_index):
117118
merkle_path : list
118119
List of tagged hashes representing the merkle path.
119120
"""
120-
merkle_path = []
121121
traversed = 0
122-
122+
123123
def traverse_level(level):
124124
nonlocal traversed
125-
for leaf in level:
126-
if isinstance(leaf, list):
127-
traverse_level(leaf)
128-
else:
129-
if traversed == target_leaf_index:
130-
traversed += 1
131-
continue
132-
tagged_hash = tapleaf_tagged_hash(leaf)
133-
merkle_path.append(tagged_hash)
125+
if isinstance(level, list):
126+
if len(level) == 1:
127+
return traverse_level(level[0])
128+
if len(level) == 2:
129+
a, a1 = traverse_level(level[0])
130+
b, b1 = traverse_level(level[1])
131+
if a1:
132+
return (a + b), True
133+
if b1:
134+
return (b + a), True
135+
return tapbranch_tagged_hash(a, b), False
136+
raise ValueError("Invalid Merkle branch: List cannot have more than 2 branches.")
137+
else:
138+
if traversed == target_leaf_index:
134139
traversed += 1
140+
return b"", True
141+
traversed += 1
142+
return tapleaf_tagged_hash(level), False
143+
144+
merkle_path = traverse_level(all_leafs)
135145

136-
traverse_level(all_leafs)
137-
138-
return merkle_path
146+
return merkle_path[0]
147+
139148

140149
def get_tag_hashed_merkle_root(
141150
scripts: None | Script | list[Script] | list[list[Script]],

0 commit comments

Comments
 (0)