def receive_advertise_block():
    jsn = request.get_json()
    if "block_id" not in jsn or "peer" not in jsn:
        return "Invalid request", 404

    block_id = jsn.get('block_id')
    if block_id <= blockchain.last_block.index:
        return json.dumps({"error ": "error"})

    if block_id not in blockchain.received_block_advertises:
        data = {"block_id": block_id, "peer": "http://localhost:" + str(PORT)}
        headers = {'Content-Type': "application/json"}

        requested_block = requests.post(jsn["peer"] + '/request_block',
                                        data=json.dumps(data),
                                        headers=headers).json()
        block = Block(
            index=requested_block['index'],
            transactions=requested_block['transactions'],
            proof_of_verification=requested_block['proof_of_verification'],
            timestamp=requested_block['timestamp'],
            previous_hash=requested_block['previous_hash'])
        block.hash = requested_block['hash']
        verified = utils.is_valid_block(block.__dict__)
        if not verified:
            return json.dumps({"error ": "error"})

        for transaction in block.transactions:
            if transaction in blockchain.transactions:
                del blockchain.transactions[transaction]

        assert (requested_block["index"] == block_id)
        blockchain.pending_blocks[block_id] = block
        blockchain.pending_blocks_counts[block_id] = 1
        blockchain.received_block_advertises.add(block_id)
        for peer in blockchain.peers:
            requests.post(peer + '/receive_adv_block',
                          data=json.dumps(data),
                          headers=headers)

    else:
        blockchain.pending_blocks_counts[block_id] += 1

    if (blockchain.pending_blocks_counts[block_id] >=
        (len(blockchain.peers) + 1) // 2):
        if block_id in blockchain.pending_blocks:
            blockchain.add_block(blockchain.pending_blocks[block_id])
            del blockchain.pending_blocks[block_id]
            return str(block_id)
        else:
            return json.dumps({"error ": "error"})
    else:
        return json.dumps({"error ": "error"})
def create_chain_from_dump(chain_dump):
    blockchain = Blockchain(PORT)
    for idx, block_data in enumerate(chain_dump):
        block = Block(
            block_data["index"],
            block_data["transactions"],
            block_data["proof_of_verification"],
            block_data["timestamp"],
            block_data["previous_hash"],
        )
        block.hash = block_data["hash"]
        if idx > 0:
            verified = utils.is_valid_block(block.__dict__)
            added = blockchain.add_block(block, clone_mode=True)
            if not added:
                raise Exception("The chain dump is tampered!!")
        else:  # the block is a genesis block, no verification needed
            blockchain.chain.append(block)
    return blockchain
    def add_block(self, block, clone_mode=False):
        if (block.previous_hash != self.last_block.hash):
            return False

        if not utils.is_valid_block(block.__dict__):
            return False

        if block.index <= self.last_block.index:
            return True

        self.chain.append(block)
        if clone_mode:
            return True

        next_index = block.index + 1

        while next_index in self.pending_blocks_counts:
            if (self.pending_blocks_counts[next_index] >=
                (len(self.peers) + 1) // 2):
                self.chain.append(block)
                next_index += 1
            else:
                break
        return True