예제 #1
0
    async def _fetch_headers_chunks(self, chunks_at_time, local_best_header,
                                    network_best_header):
        """
        fetch chunks from local height to network best height, download <chunks_at_time> (>1 is unstable)
        """
        i = 0
        current_height = local_best_header and local_best_header[
            'block_height'] or 0
        saving_headers = []
        while 1:
            Logger.electrum.debug(
                '%s headers behind, downloading',
                network_best_header['block_height'] - current_height -
                len(saving_headers))
            local_best_height = local_best_header and local_best_header[
                'block_height'] or 0
            rewind_from = get_nearest_parent(local_best_height,
                                             2016) // 2016 + i
            _from = rewind_from
            _to = rewind_from + chunks_at_time
            if _from > (network_best_header['block_height'] // 2016):
                saved_headers = saving_headers and self.repo.save_headers(
                    saving_headers) or []
                saved_headers and self.set_last_processed_header(
                    saved_headers[-1])

                self.synced = True
                return
            res = await self.interface.get_headers_in_range_from_chunks(
                _from, _to, get_peer=True)
            peer, headers = res if res else (None, [])
            if not headers:
                raise exceptions.NoHeadersException
            if local_best_height:
                saving_headers = saving_headers + [
                    h for h in headers if h['block_height'] > local_best_height
                ]
            else:
                saving_headers = saving_headers + headers
            try:
                if not i % 5:
                    saved_headers = headers and self.repo.save_headers(
                        saving_headers) or []
                    saving_headers = []
                else:
                    saved_headers = []

            except exceptions.HeadersInconsistencyException:
                await peer.disconnect()
                raise
            Logger.electrum.debug('Fetched %s headers (chunk %s/%s), tot. %s',
                                  len(headers), _from, _to,
                                  len(saving_headers))
            if saved_headers:
                self.set_last_processed_header(saved_headers[-1])
                current_height = self._last_processed_header['block_height']
            elif saving_headers:
                self.set_last_processed_header(None)
            i += 1
예제 #2
0
 async def handle_headers_inconsistency(self):
     self.set_last_processed_header(None)
     local_best_header = self.repo.get_best_header()
     remove_headers_since = get_nearest_parent(
         local_best_header['block_height'], 2016)
     self.repo.remove_headers_after_height(remove_headers_since)
     Logger.electrum.warning(
         'Headers inconsistency found, removed headers since %s. Current local: %s',
         remove_headers_since, local_best_header['block_height'])
예제 #3
0
 async def _fetch_headers_chunks(self, chunks_at_time, local_best_header,
                                 network_best_header):
     """
     fetch chunks from local height to network best height, download <chunks_at_time> (>1 is unstable)
     """
     i = 0
     current_height = local_best_header and local_best_header[
         'block_height'] or 0
     while 1:
         Logger.electrum.debug(
             'Behind of %s blocks, fetching chunks',
             network_best_header['block_height'] - current_height)
         local_best_height = local_best_header and local_best_header[
             'block_height'] or 0
         rewind_from = get_nearest_parent(local_best_height,
                                          2016) // 2016 + i
         _from = rewind_from
         _to = rewind_from + chunks_at_time
         if _from > (network_best_header['block_height'] // 2016):
             # fixme, move the chunk stuff inside the electrod interface and
             # here just "fetch headers". stop.
             self.synced = True
             return
         res = await self.interface.get_headers_in_range_from_chunks(
             _from, _to, get_peer=True)
         peer, headers = res if res else (None, [])
         if not headers:
             raise exceptions.NoHeadersException
         if local_best_height:
             saving_headers = [
                 h for h in headers if h['block_height'] > local_best_height
             ]
         else:
             saving_headers = headers
         try:
             saved_headers = headers and self.repo.save_headers(
                 saving_headers)
         except exceptions.HeadersInconsistencyException:
             await peer.disconnect()
             raise
         Logger.electrum.debug(
             'Fetched %s headers (from chunk %s to chunk %s), saved %s headers of %s',
             len(headers), _from, _to, len(saved_headers),
             len(saving_headers))
         if saved_headers:
             self.set_last_processed_header(saved_headers[-1])
             current_height = self._last_processed_header['block_height']
         else:
             self.set_last_processed_header(None)
         i += 1