diff --git a/electrumx/server/chain_state.py b/electrumx/server/chain_state.py index 4704fbf..58534db 100644 --- a/electrumx/server/chain_state.py +++ b/electrumx/server/chain_state.py @@ -48,7 +48,7 @@ class ChainState(object): def header_branch_and_root(self, length, height): return self._bp.header_mc.branch_and_root(length, height) - def raw_header(self, height): + async def raw_header(self, height): '''Return the binary header at the given height.''' header, n = self._bp.read_headers(height, 1) if n != 1: diff --git a/electrumx/server/peers.py b/electrumx/server/peers.py index 955d0e6..0c7ba1c 100644 --- a/electrumx/server/peers.py +++ b/electrumx/server/peers.py @@ -315,7 +315,7 @@ class PeerManager(object): # Check prior header too in case of hard fork. check_height = min(our_height, their_height) - raw_header = self.chain_state.raw_header(check_height) + raw_header = await self.chain_state.raw_header(check_height) if ptuple >= (1, 4): ours = raw_header.hex() message = 'blockchain.block.header' diff --git a/electrumx/server/session.py b/electrumx/server/session.py index e450108..33e6cea 100644 --- a/electrumx/server/session.py +++ b/electrumx/server/session.py @@ -61,6 +61,13 @@ def non_negative_integer(value): f'{value} should be a non-negative integer') +def assert_boolean(value): + '''Return param value it is boolean otherwise raise an RPCError.''' + if value in (False, True): + return value + raise RPCError(BAD_REQUEST, f'{value} should be a boolean value') + + def assert_tx_hash(value): '''Raise an RPCError if the value is not a valid transaction hash.''' @@ -712,7 +719,7 @@ class ElectrumX(SessionBase): if height_changed: self.notified_height = height if self.subscribe_headers: - args = (self.subscribe_headers_result(height), ) + args = (await self.subscribe_headers_result(height), ) await self.send_notification('blockchain.headers.subscribe', args) @@ -720,49 +727,44 @@ class ElectrumX(SessionBase): if touched or (height_changed and self.mempool_statuses): await self.notify_touched(touched) - def assert_boolean(self, value): - '''Return param value it is boolean otherwise raise an RPCError.''' - if value in (False, True): - return value - raise RPCError(BAD_REQUEST, f'{value} should be a boolean value') - - def raw_header(self, height): + async def raw_header(self, height): '''Return the binary header at the given height.''' try: - return self.chain_state.raw_header(height) + return await self.chain_state.raw_header(height) except IndexError: - raise RPCError(BAD_REQUEST, f'height {height:,d} out of range') + raise RPCError(BAD_REQUEST, f'height {height:,d} ' + 'out of range') from None - def electrum_header(self, height): + async def electrum_header(self, height): '''Return the deserialized header at the given height.''' - raw_header = self.raw_header(height) + raw_header = await self.raw_header(height) return self.coin.electrum_header(raw_header, height) - def subscribe_headers_result(self, height): + async def subscribe_headers_result(self, height): '''The result of a header subscription for the given height.''' if self.subscribe_headers_raw: - raw_header = self.raw_header(height) + raw_header = await self.raw_header(height) return {'hex': raw_header.hex(), 'height': height} - return self.electrum_header(height) + return await self.electrum_header(height) - def _headers_subscribe(self, raw): + async def _headers_subscribe(self, raw): '''Subscribe to get headers of new blocks.''' self.subscribe_headers = True - self.subscribe_headers_raw = self.assert_boolean(raw) + self.subscribe_headers_raw = assert_boolean(raw) self.notified_height = self.db_height() - return self.subscribe_headers_result(self.notified_height) + return await self.subscribe_headers_result(self.notified_height) async def headers_subscribe(self): '''Subscribe to get raw headers of new blocks.''' - return self._headers_subscribe(True) + return await self._headers_subscribe(True) async def headers_subscribe_True(self, raw=True): '''Subscribe to get headers of new blocks.''' - return self._headers_subscribe(raw) + return await self._headers_subscribe(raw) async def headers_subscribe_False(self, raw=False): '''Subscribe to get headers of new blocks.''' - return self._headers_subscribe(raw) + return await self._headers_subscribe(raw) async def add_peer(self, features): '''Add a peer (but only if the peer resolves to the source).''' @@ -925,7 +927,7 @@ class ElectrumX(SessionBase): dictionary with a merkle proof.''' height = non_negative_integer(height) cp_height = non_negative_integer(cp_height) - raw_header_hex = self.raw_header(height).hex() + raw_header_hex = (await self.raw_header(height)).hex() if cp_height == 0: return raw_header_hex result = {'header': raw_header_hex} @@ -976,7 +978,7 @@ class ElectrumX(SessionBase): height: the header's height''' height = non_negative_integer(height) - return self.electrum_header(height) + return await self.electrum_header(height) def is_tor(self): '''Try to detect if the connection is to a tor hidden service we are