<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def end_block(self, request_end_block):
 """Calculate block hash using transaction ids and previous block hash to be stored in the next block. Args: height (int):
 new height of the chain. """


        self.abort_if_abci_chain_is_not_synced()

        chain_shift = 0 if self.chain is None else self.chain['height']

        height = request_end_block.height + chain_shift
        self.new_height = height

        # store pre-commit state to recover in case there is a crash during
        # `end_block` or `commit`
        logger.debug(f'Updating pre-commit state: {self.new_height}')
        pre_commit_state = dict(height=self.new_height,
                                transactions=self.block_txn_ids)
        self.bigchaindb.store_pre_commit_state(pre_commit_state)

        block_txn_hash = calculate_hash(self.block_txn_ids)
        block = self.bigchaindb.get_latest_block()

        if self.block_txn_ids:
            self.block_txn_hash = calculate_hash([block['app_hash'], block_txn_hash])
        else:
            self.block_txn_hash = block['app_hash']

        validator_update = Election.process_block(self.bigchaindb,
                                                  self.new_height,
                                                  self.block_transactions)

        return ResponseEndBlock(validator_updates=validator_update)