diff --git a/server/controller.py b/server/controller.py index ab05da7..e04d13f 100644 --- a/server/controller.py +++ b/server/controller.py @@ -81,7 +81,7 @@ class Controller(util.LoggedClass): ('blockchain', 'address.get_balance address.get_history address.get_mempool ' 'address.get_proof address.listunspent ' - 'block.get_header block.get_chunk estimatefee relayfee ' + 'block.get_header estimatefee relayfee ' 'transaction.get transaction.get_merkle utxo.get_address'), ('server', 'donation_address'), ] @@ -794,13 +794,6 @@ class Controller(util.LoggedClass): 'height': utxo.height, 'value': utxo.value} for utxo in sorted(await self.get_utxos(hashX))] - def block_get_chunk(self, index): - '''Return a chunk of block headers. - - index: the chunk index''' - index = self.non_negative_integer(index) - return self.get_chunk(index) - def block_get_header(self, height): '''The deserialized header at a given height. diff --git a/server/session.py b/server/session.py index a9a4adc..cd43071 100644 --- a/server/session.py +++ b/server/session.py @@ -112,8 +112,10 @@ class ElectrumX(SessionBase): self.max_subs = self.env.max_session_subs self.hashX_subs = {} self.mempool_statuses = {} + self.chunk_indices = [] self.electrumx_handlers = { 'blockchain.address.subscribe': self.address_subscribe, + 'blockchain.block.get_chunk': self.block_get_chunk, 'blockchain.headers.subscribe': self.headers_subscribe, 'blockchain.numblocks.subscribe': self.numblocks_subscribe, 'blockchain.script_hash.subscribe': self.script_hash_subscribe, @@ -261,6 +263,21 @@ class ElectrumX(SessionBase): '''Returns a dictionary of server features.''' return self.controller.peer_mgr.myself.features + def block_get_chunk(self, index): + '''Return a chunk of block headers as a hexadecimal string. + + index: the chunk index''' + index = self.controller.non_negative_integer(index) + self.chunk_indices.append(index) + self.chunk_indices = self.chunk_indices[-5:] + # -2 allows backing up a single chunk but no more. + if index <= max(self.chunk_indices[:-2], default=-1): + msg = ('chunk indices not advancing (wrong network?): {}' + .format(self.chunk_indices)) + # INVALID_REQUEST triggers a disconnect + raise RPCError(mrg, JSONRPC.INVALID_REQUEST) + return self.controller.get_chunk(index) + def is_tor(self): '''Try to detect if the connection is to a tor hidden service we are running.'''