Applies the transaction to the current tip block.

        WARNING: Receipt and Transaction trie generation is computationally
        heavy and incurs significant performance overhead.

def apply_transaction(self,
                          transaction: BaseTransaction
                          ) -> Tuple[BaseBlock, Receipt, BaseComputation]:
        """
        Applies the transaction to the current tip block.

        WARNING: Receipt and Transaction trie generation is computationally
        heavy and incurs significant performance overhead.
        """
        vm = self.get_vm(self.header)
        base_block = vm.block

        receipt, computation = vm.apply_transaction(base_block.header, transaction)
        header_with_receipt = vm.add_receipt_to_header(base_block.header, receipt)

        # since we are building the block locally, we have to persist all the incremental state
        vm.state.persist()
        new_header = header_with_receipt.copy(state_root=vm.state.state_root)

        transactions = base_block.transactions + (transaction, )
        receipts = base_block.get_receipts(self.chaindb) + (receipt, )

        new_block = vm.set_block_transactions(base_block, new_header, transactions, receipts)

        self.header = new_block.header

        return new_block, receipt, computation