diff --git a/torba/torba/client/baseledger.py b/torba/torba/client/baseledger.py index 6be7b883b..7f55cf88f 100644 --- a/torba/torba/client/baseledger.py +++ b/torba/torba/client/baseledger.py @@ -1,3 +1,4 @@ +import base64 import os import asyncio import logging @@ -308,12 +309,12 @@ class BaseLedger(metaclass=LedgerRegistry): async def initial_headers_sync(self): target = self.network.remote_height current = len(self.headers) - get_chunk = partial(self.network.retriable_call, self.network.get_headers, count=2000) - chunks = [asyncio.ensure_future(get_chunk(height)) for height in range(current, target, 2000)] + get_chunk = partial(self.network.retriable_call, self.network.get_headers, count=2016, b64=True) + chunks = [asyncio.ensure_future(get_chunk(height)) for height in range(current, target, 2016)] async with self.headers.checkpointed_connector() as connector: for chunk in chunks: headers = await chunk - connector.connect(len(self.headers), unhexlify(headers['hex'])) + connector.connect(len(self.headers), base64.b64decode(headers['base64'])) log.info("Headers sync: %s / %s", connector.tell() // self.headers.header_size, target) async def update_headers(self, height=None, headers=None, subscription_update=False): diff --git a/torba/torba/client/basenetwork.py b/torba/torba/client/basenetwork.py index cdf33dab2..b2a5b6878 100644 --- a/torba/torba/client/basenetwork.py +++ b/torba/torba/client/basenetwork.py @@ -239,9 +239,9 @@ class BaseNetwork: restricted = 0 > height > self.remote_height - 10 return self.rpc('blockchain.transaction.get_merkle', [tx_hash, height], restricted) - def get_headers(self, height, count=10000): + def get_headers(self, height, count=10000, b64=False): restricted = height >= self.remote_height - 100 - return self.rpc('blockchain.block.headers', [height, count], restricted) + return self.rpc('blockchain.block.headers', [height, count, 0, b64], restricted) # --- Subscribes, history and broadcasts are always aimed towards the master client directly def get_history(self, address): diff --git a/torba/torba/server/session.py b/torba/torba/server/session.py index 6f92e894a..a45f7ede1 100644 --- a/torba/torba/server/session.py +++ b/torba/torba/server/session.py @@ -6,6 +6,7 @@ # and warranty status of this software. """Classes for local RPC server and remote client TCP/SSL servers.""" +import base64 import collections import asyncio import codecs @@ -1007,7 +1008,7 @@ class ElectrumX(SessionBase): height: the header's height""" return await self.block_header(height) - async def block_headers(self, start_height, count, cp_height=0): + async def block_headers(self, start_height, count, cp_height=0, b64=False): """Return count concatenated block headers as hex for the main chain; starting at start_height. @@ -1021,15 +1022,16 @@ class ElectrumX(SessionBase): max_size = self.MAX_CHUNK_SIZE count = min(count, max_size) headers, count = await self.db.read_headers(start_height, count) - result = {'hex': headers.hex(), 'count': count, 'max': max_size} + result = { + 'base64' if b64 else 'hex': base64.b64encode(headers).decode() if b64 else headers.hex(), + 'count': count, + 'max': max_size + } if count and cp_height: last_height = start_height + count - 1 result.update(await self._merkle_proof(cp_height, last_height)) return result - async def block_headers_12(self, start_height, count): - return await self.block_headers(start_height, count) - async def block_get_chunk(self, index): """Return a chunk of block headers as a hexadecimal string. @@ -1270,7 +1272,7 @@ class ElectrumX(SessionBase): handlers.update({ 'mempool.get_fee_histogram': self.mempool.compact_fee_histogram, - 'blockchain.block.headers': self.block_headers_12, + 'blockchain.block.headers': self.block_headers, 'server.ping': self.ping, })