diff --git a/electrumx/lib/merkle.py b/electrumx/lib/merkle.py index 306c79a..731b8d0 100644 --- a/electrumx/lib/merkle.py +++ b/electrumx/lib/merkle.py @@ -53,7 +53,7 @@ class Merkle(object): raise ValueError('hash_count must be at least 1') return ceil(log(hash_count, 2)) - def branch(self, hashes, index, length=None): + def branch_and_root(self, hashes, index, length=None): '''Return a (merkle branch, merkle_root) pair given hashes, and the index of one of those hashes. ''' @@ -86,7 +86,7 @@ class Merkle(object): def root(self, hashes, length=None): '''Return the merkle root of a non-empty iterable of binary hashes.''' - branch, root = self.branch(hashes, 0, length) + branch, root = self.branch_and_root(hashes, 0, length) return root def root_from_proof(self, hash, branch, index): @@ -144,10 +144,10 @@ class Merkle(object): if not isinstance(leaf_hashes, list): raise TypeError("level must be a list") leaf_index = (index >> depth_higher) << depth_higher - leaf_branch, leaf_root = self.branch(leaf_hashes, index - leaf_index, - depth_higher) + leaf_branch, leaf_root = self.branch_and_root( + leaf_hashes, index - leaf_index, depth_higher) index >>= depth_higher - level_branch, root = self.branch(level, index) + level_branch, root = self.branch_and_root(level, index) # Check last so that we know index is in-range if leaf_root != level[index]: raise ValueError('leaf hashes inconsistent with level') diff --git a/electrumx/server/controller.py b/electrumx/server/controller.py index 5d26b21..cdd1981 100644 --- a/electrumx/server/controller.py +++ b/electrumx/server/controller.py @@ -20,7 +20,7 @@ from functools import partial import pylru from aiorpcx import RPCError, TaskSet, _version as aiorpcx_version -from electrumx.lib.hash import double_sha256, hash_to_str, hex_str_to_hash +from electrumx.lib.hash import double_sha256, hash_to_hex_str, hex_str_to_hash from electrumx.lib.hash import HASHX_LEN from electrumx.lib.merkle import Merkle from electrumx.lib.peer import Peer @@ -723,7 +723,7 @@ class Controller(ServerBase): async def confirmed_and_unconfirmed_history(self, hashX): # Note history is ordered but unconfirmed is unordered in e-s history = await self.get_history(hashX) - conf = [{'tx_hash': hash_to_str(tx_hash), 'height': height} + conf = [{'tx_hash': hash_to_hex_str(tx_hash), 'height': height} for tx_hash, height in history] return conf + await self.unconfirmed_history(hashX) @@ -785,7 +785,8 @@ class Controller(ServerBase): utxos.extend(self.mempool.get_utxos(hashX)) spends = await self.mempool.potential_spends(hashX) - return [{'tx_hash': hash_to_str(utxo.tx_hash), 'tx_pos': utxo.tx_pos, + return [{'tx_hash': hash_to_hex_str(utxo.tx_hash), + 'tx_pos': utxo.tx_pos, 'height': utxo.height, 'value': utxo.value} for utxo in utxos if (utxo.tx_hash, utxo.tx_pos) not in spends] @@ -862,6 +863,7 @@ class Controller(ServerBase): f'block {block_hash} at height {height:,d}') hashes = [hex_str_to_hash(hash) for hash in tx_hashes] - branch = [hash_to_str(hash) for hash in merkle.branch(hashes, pos)] + branch, root = merkle.branch_and_root(hashes, pos) + branch = [hash_to_hex_str(hash) for hash in branch] return {"block_height": height, "merkle": branch, "pos": pos} diff --git a/tests/lib/test_merkle.py b/tests/lib/test_merkle.py index 2cd3623..2d8e4e5 100644 --- a/tests/lib/test_merkle.py +++ b/tests/lib/test_merkle.py @@ -55,7 +55,7 @@ def test_root_bad(): def test_branch_and_root_from_proof(): for n in range(len(hashes)): for m in range(n + 1): - branch, root = Merkle.branch(hashes[:n + 1], m) + branch, root = Merkle.branch_and_root(hashes[:n + 1], m) assert root == roots[n] root = Merkle.root_from_proof(hashes[m], branch, m) assert root == roots[n] @@ -63,20 +63,20 @@ def test_branch_and_root_from_proof(): def test_branch_bad(): with pytest.raises(TypeError): - Merkle.branch(0, 0) + Merkle.branch_and_root(0, 0) with pytest.raises(ValueError): - Merkle.branch([], 0) + Merkle.branch_and_root([], 0) with pytest.raises(TypeError): - Merkle.branch(hashes, 0.0) + Merkle.branch_and_root(hashes, 0.0) with pytest.raises(ValueError): - Merkle.branch(hashes[:2], -1) + Merkle.branch_and_root(hashes[:2], -1) with pytest.raises(ValueError): - Merkle.branch(hashes[:2], 2) - Merkle.branch(hashes, 0, 3) + Merkle.branch_and_root(hashes[:2], 2) + Merkle.branch_and_root(hashes, 0, 3) with pytest.raises(TypeError): - Merkle.branch(hashes, 0, 3.0) + Merkle.branch_and_root(hashes, 0, 3.0) with pytest.raises(ValueError): - Merkle.branch(hashes, 0, 2) + Merkle.branch_and_root(hashes, 0, 2) def test_root_from_proof_bad(): @@ -115,7 +115,7 @@ def test_branch_from_level(): leaf_index = (index >> depth_higher) << depth_higher leaf_hashes = part[leaf_index: leaf_index + (1 << depth_higher)] - branch = Merkle.branch(part, index) + branch = Merkle.branch_and_root(part, index) branch2 = Merkle.branch_from_level(level, leaf_hashes, index, depth_higher) assert branch == branch2