<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def commit_token_operation(self, token_op, current_block_number):
 """ Commit a token operation that debits one account and credits another Returns the new canonicalized record (with all compatibility quirks preserved) DO NOT CALL THIS DIRECTLY """

        # have to have read-write disposition 
        if self.disposition != DISPOSITION_RW:
            log.error("FATAL: borrowing violation: not a read-write connection")
            traceback.print_stack()
            os.abort()

        cur = self.db.cursor()
        opcode = token_op.get('opcode', None)
        clean_token_op = self.sanitize_op(token_op)
       
        try:
            assert token_operation_is_valid(token_op), 'Invalid token operation'
            assert opcode is not None, 'No opcode given'
            assert 'txid' in token_op, 'No txid'
            assert 'vtxindex' in token_op, 'No vtxindex'
        except Exception as e:
            log.exception(e)
            log.error('FATAL: failed to commit token operation')
            self.db.rollback()
            os.abort()

        table = token_operation_get_table(token_op)
        account_payment_info = token_operation_get_account_payment_info(token_op)
        account_credit_info = token_operation_get_account_credit_info(token_op)

        # fields must be set
        try:
            for key in account_payment_info:
                assert account_payment_info[key] is not None, 'BUG: payment info key {} is None'.format(key)

            for key in account_credit_info:
                assert account_credit_info[key] is not None, 'BUG: credit info key {} is not None'.format(key)

            # NOTE: do not check token amount and type, since in the future we want to support converting
            # between tokens
        except Exception as e:
            log.exception(e)
            log.error("FATAL: invalid token debit or credit info")
            os.abort()
        
        self.log_accept(current_block_number, token_op['vtxindex'], token_op['op'], token_op)
        
        # NOTE: this code is single-threaded, but this code must be atomic
        self.commit_account_debit(token_op, account_payment_info, current_block_number, token_op['vtxindex'], token_op['txid'])
        self.commit_account_credit(token_op, account_credit_info, current_block_number, token_op['vtxindex'], token_op['txid'])

        namedb_history_save(cur, opcode, token_op['address'], None, None, current_block_number, token_op['vtxindex'], token_op['txid'], clean_token_op)
        return clean_token_op