예제 #1
0
    async def request_header_blocks(
        self, request: peer_protocol.RequestHeaderBlocks
    ) -> OutboundMessageGenerator:
        """
        A peer requests a list of header blocks, by height. Used for syncing or light clients.
        """
        start = time.time()
        if len(request.heights) > self.config["max_headers_to_send"]:
            raise errors.TooManyheadersRequested(
                f"The max number of headers is {self.config['max_headers_to_send']},\
                                                but requested {len(request.heights)}"
            )

        try:
            headers: List[
                HeaderBlock] = self.blockchain.get_header_blocks_by_height(
                    request.heights, request.tip_header_hash)
            log.info(f"Got header blocks by height {time.time() - start}")
        except KeyError:
            return
        except BlockNotInBlockchain as e:
            log.info(f"{e}")
            return

        response = peer_protocol.HeaderBlocks(request.tip_header_hash, headers)
        yield OutboundMessage(NodeType.FULL_NODE,
                              Message("header_blocks", response),
                              Delivery.RESPOND)
예제 #2
0
 async def request_sync_blocks(
     self, request: peer_protocol.RequestSyncBlocks
 ) -> OutboundMessageGenerator:
     """
     Responds to a peers request for syncing blocks.
     """
     blocks: List[FullBlock] = []
     async with self.store.lock:
         tip_block: Optional[FullBlock] = await self.store.get_block(
             request.tip_header_hash
         )
     if tip_block is not None:
         if len(request.heights) > self.config["max_blocks_to_send"]:
             raise errors.TooManyheadersRequested(
                 f"The max number of blocks is "
                 f"{self.config['max_blocks_to_send']},"
                 f"but requested {len(request.heights)}"
             )
         try:
             header_hashes: List[
                 HeaderBlock
             ] = self.blockchain.get_header_hashes_by_height(
                 request.heights, request.tip_header_hash
             )
             header_blocks: List[
                 HeaderBlock
             ] = await self.store.get_header_blocks_by_hash(header_hashes)
             for header_block in header_blocks:
                 fetched = await self.store.get_block(header_block.header.get_hash())
                 assert fetched
                 blocks.append(fetched)
         except KeyError:
             log.info("Do not have required blocks")
             return
         except BlockNotInBlockchain as e:
             log.info(f"{e}")
             return
     else:
         # We don't have the blocks that the client is looking for
         log.info(f"Peer requested tip {request.tip_header_hash} that we don't have")
         return
     response = Message(
         "sync_blocks", peer_protocol.SyncBlocks(request.tip_header_hash, blocks)
     )
     yield OutboundMessage(NodeType.FULL_NODE, response, Delivery.RESPOND)