diff --git a/electrumx/server/session.py b/electrumx/server/session.py index 6174cc2..9780bdc 100644 --- a/electrumx/server/session.py +++ b/electrumx/server/session.py @@ -70,11 +70,14 @@ def assert_boolean(value): def assert_tx_hash(value): - '''Raise an RPCError if the value is not a valid transaction - hash.''' + '''Raise an RPCError if the value is not a valid hexadecimal transaction hash. + + If it is valid, return it as 32-byte binary hash. + ''' try: - if len(util.hex_to_bytes(value)) == 32: - return + raw_hash = hex_str_to_hash(value) + if len(raw_hash) == 32: + return raw_hash except (ValueError, TypeError): pass raise RPCError(BAD_REQUEST, f'{value} should be a transaction hash') @@ -1155,28 +1158,25 @@ class ElectrumX(SessionBase): '''Returns a pair (block_hash, tx_hashes) for the main chain block at the given height. - x_hashes is an ordered list of hexadecimal strings. + Returns an ordered list of binary hashes. ''' height = non_negative_integer(height) try: tx_hashes = await self.db.tx_hashes_at_blockheight(height) except self.db.DBError as e: raise RPCError(BAD_REQUEST, f'db error: {e!r}') - tx_hashes = [hash_to_hex_str(hash) for hash in tx_hashes] # Aim is to cost 3.0 for a 1MB block of 2,500 txs self.bump_cost(0.5 + len(tx_hashes) / 2500) return tx_hashes def _get_merkle_branch(self, tx_hashes, tx_pos): - '''Return a merkle branch to a transaction. + '''Return a merkle branch to a transaction as a list of hexadecimal strings. - tx_hashes: ordered list of hex strings of tx hashes in a block + tx_hashes: ordered list of binary tx hashes in a block tx_pos: index of transaction in tx_hashes to create branch for ''' - hashes = [hex_str_to_hash(hash) for hash in tx_hashes] - branch, _root = self.db.merkle.branch_and_root(hashes, tx_pos) - branch = [hash_to_hex_str(hash) for hash in branch] - return branch + branch, _root = self.db.merkle.branch_and_root(tx_hashes, tx_pos) + return [hash_to_hex_str(hash) for hash in branch] async def transaction_merkle(self, tx_hash, height): '''Return the merkle branch to a confirmed transaction given its hash @@ -1185,10 +1185,10 @@ class ElectrumX(SessionBase): tx_hash: the transaction hash as a hexadecimal string height: the height of the block it is in ''' - assert_tx_hash(tx_hash) + tx_hash_bytes = assert_tx_hash(tx_hash) tx_hashes = await self._tx_hashes_at_blockheight(height) try: - pos = tx_hashes.index(tx_hash) + pos = tx_hashes.index(tx_hash_bytes) except ValueError: raise RPCError(BAD_REQUEST, f'tx {tx_hash} not in block at height {height:,d}') branch = self._get_merkle_branch(tx_hashes, pos) @@ -1209,6 +1209,7 @@ class ElectrumX(SessionBase): raise RPCError(BAD_REQUEST, f'no tx at position {tx_pos:,d} in block at height {height:,d}') + tx_hash = hash_to_hex_str(tx_hash) if merkle: branch = self._get_merkle_branch(tx_hashes, tx_pos) return {"tx_hash": tx_hash, "merkle": branch}