def get_last_block_hash():
        """
        Gets the highest block's hash.

        Returns:
        string  -- hash of the highest block
        """
        block_dal = BlockServiceDal()
        max_height = block_dal.get_max_block_height()
        latest_blocks = block_dal.find_by_height(max_height)
        if len(latest_blocks) != 0:
            return latest_blocks[0]._hash
        else:
            return ''
    def remove_stale_blocks():
        """
        Removes stale, unused blocks.
        Blocks are removed if starting from the newest block, they do not appear when following the chain of previous blocks.
        ie.

        []<-[]<-[]<-[]<-[]<-[]<-[]<-[]<-[]<-[]
                    ^---[]<-[]<-[]<-[]<-[]

        In the above scenario, the bottom chain would be removed, moving all of those transactions back to the mempool.
        """
        block_dal = BlockServiceDal()
        current_height = block_dal.get_max_block_height()
        highest_blocks = block_dal.find_by_height(current_height)

        # if there is only 1 block at the greatest height, we can prune old blocks
        if len(highest_blocks) == 1:
            # get all block hashes
            all_block_hashes = block_dal.get_all_block_hashes()
            correct_block_hashes = set()
            block = highest_blocks[0]
            # add current highest block to the set of correct blocks
            correct_block_hashes.add(block._hash)
            # TODO while there is still a previous block
            while block.prev_block != 'GENESIS_BLOCK':
                block = block_dal.find_by_hash(block.prev_block)
                # add to list of correct blocks
                correct_block_hashes.add(block._hash)

            print("correct_block_hashes len: " +
                  str(len(correct_block_hashes)))
            print("\t" + str(correct_block_hashes))
            # get the difference between the two sets of blocks
            to_remove = set(all_block_hashes) - correct_block_hashes
            print("to_remove: " + str(to_remove))
            # remove each of the blocks
            for block_hash in to_remove:
                print("Removing block: " + block_hash)
                BlockService._remove_block_by_hash(block_hash)
 def get_max_height():
     """
     Method Comment
     """
     block_service_dal = BlockServiceDal()
     return block_service_dal.get_max_block_height()