@api_request
@reply_type([ProtocolMessageTypes.respond_blocks, ProtocolMessageTypes.reject_blocks])
async def request_blocks(self, request: full_node_protocol.RequestBlocks) -> Optional[Message]:
    if ((request.end_height < request.start_height) or ((request.end_height - request.start_height) > 32)):
        reject = RejectBlocks(request.start_height, request.end_height)
        msg: Message = make_msg(ProtocolMessageTypes.reject_blocks, reject)
        return msg
    for i in range(request.start_height, (request.end_height + 1)):
        if (not self.full_node.blockchain.contains_height(uint32(i))):
            reject = RejectBlocks(request.start_height, request.end_height)
            msg = make_msg(ProtocolMessageTypes.reject_blocks, reject)
            return msg
    if (not request.include_transaction_block):
        blocks: List[FullBlock] = []
        for i in range(request.start_height, (request.end_height + 1)):
            header_hash_i: Optional[bytes32] = self.full_node.blockchain.height_to_hash(uint32(i))
            if (header_hash_i is None):
                reject = RejectBlocks(request.start_height, request.end_height)
                return make_msg(ProtocolMessageTypes.reject_blocks, reject)
            block: Optional[FullBlock] = (await self.full_node.block_store.get_full_block(header_hash_i))
            if (block is None):
                reject = RejectBlocks(request.start_height, request.end_height)
                return make_msg(ProtocolMessageTypes.reject_blocks, reject)
            block = dataclasses.replace(block, transactions_generator=None)
            blocks.append(block)
        msg = make_msg(ProtocolMessageTypes.respond_blocks, full_node_protocol.RespondBlocks(request.start_height, request.end_height, blocks))
    else:
        blocks_bytes: List[bytes] = []
        for i in range(request.start_height, (request.end_height + 1)):
            header_hash_i = self.full_node.blockchain.height_to_hash(uint32(i))
            if (header_hash_i is None):
                reject = RejectBlocks(request.start_height, request.end_height)
                return make_msg(ProtocolMessageTypes.reject_blocks, reject)
            block_bytes: Optional[bytes] = (await self.full_node.block_store.get_full_block_bytes(header_hash_i))
            if (block_bytes is None):
                reject = RejectBlocks(request.start_height, request.end_height)
                msg = make_msg(ProtocolMessageTypes.reject_blocks, reject)
                return msg
            blocks_bytes.append(block_bytes)
        respond_blocks_manually_streamed: bytes = ((bytes(uint32(request.start_height)) + bytes(uint32(request.end_height))) + len(blocks_bytes).to_bytes(4, 'big', signed=False))
        for block_bytes in blocks_bytes:
            respond_blocks_manually_streamed += block_bytes
        msg = make_msg(ProtocolMessageTypes.respond_blocks, respond_blocks_manually_streamed)
    return msg
@api_request
@reply_type([ProtocolMessageTypes.respond_blocks, ProtocolMessageTypes.reject_blocks])
async def request_blocks(self, request: full_node_protocol.RequestBlocks) -> Optional[Message]:
    if ((request.end_height < request.start_height) or ((request.end_height - request.start_height) > 32)):
        reject = RejectBlocks(request.start_height, request.end_height)
        msg: Message = make_msg(ProtocolMessageTypes.reject_blocks, reject)
        return msg
    for i in range(request.start_height, (request.end_height + 1)):
        if (not self.full_node.blockchain.contains_height(uint32(i))):
            reject = RejectBlocks(request.start_height, request.end_height)
            msg = make_msg(ProtocolMessageTypes.reject_blocks, reject)
            return msg
    if (not request.include_transaction_block):
        blocks: List[FullBlock] = []
        for i in range(request.start_height, (request.end_height + 1)):
            header_hash_i: Optional[bytes32] = self.full_node.blockchain.height_to_hash(uint32(i))
            if (header_hash_i is None):
                reject = RejectBlocks(request.start_height, request.end_height)
                return make_msg(ProtocolMessageTypes.reject_blocks, reject)
            block: Optional[FullBlock] = (await self.full_node.block_store.get_full_block(header_hash_i))
            if (block is None):
                reject = RejectBlocks(request.start_height, request.end_height)
                return make_msg(ProtocolMessageTypes.reject_blocks, reject)
            block = dataclasses.replace(block, transactions_generator=None)
            blocks.append(block)
        msg = make_msg(ProtocolMessageTypes.respond_blocks, full_node_protocol.RespondBlocks(request.start_height, request.end_height, blocks))
    else:
        blocks_bytes: List[bytes] = []
        for i in range(request.start_height, (request.end_height + 1)):
            header_hash_i = self.full_node.blockchain.height_to_hash(uint32(i))
            if (header_hash_i is None):
                reject = RejectBlocks(request.start_height, request.end_height)
                return make_msg(ProtocolMessageTypes.reject_blocks, reject)
            block_bytes: Optional[bytes] = (await self.full_node.block_store.get_full_block_bytes(header_hash_i))
            if (block_bytes is None):
                reject = RejectBlocks(request.start_height, request.end_height)
                msg = make_msg(ProtocolMessageTypes.reject_blocks, reject)
                return msg
            blocks_bytes.append(block_bytes)
        respond_blocks_manually_streamed: bytes = ((bytes(uint32(request.start_height)) + bytes(uint32(request.end_height))) + len(blocks_bytes).to_bytes(4, 'big', signed=False))
        for block_bytes in blocks_bytes:
            respond_blocks_manually_streamed += block_bytes
        msg = make_msg(ProtocolMessageTypes.respond_blocks, respond_blocks_manually_streamed)
    return msg