# Buggy code
async def jsonrpc_channel_abandon(
    self,
    claim_id=None,
    txid=None,
    nout=None,
    account_id=None,
    wallet_id=None,
    preview=False,
    blocking=True,
):
    """
    Abandon one of my channel claims.

    Usage:
        channel_abandon [<claim_id> | --claim_id=<claim_id>]
                        [<txid> | --txid=<txid>] [<nout> | --nout=<nout>]
                        [--account_id=<account_id>] [--wallet_id=<wallet_id>]
                        [--preview] [--blocking]

    Options:
        --claim_id=<claim_id>     : (str) claim_id of the claim to abandon
        --txid=<txid>             : (str) txid of the claim to abandon
        --nout=<nout>             : (int) nout of the claim to abandon
        --account_id=<account_id> : (str) id of the account to use
        --wallet_id=<wallet_id>   : (str) restrict operation to specific wallet
        --preview                 : (bool) do not broadcast the transaction
        --blocking                : (bool) wait until abandon is in mempool

    Returns: {Transaction}
    """
    wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
    assert not wallet.is_locked, "Cannot spend funds with locked wallet, unlock first."
    if account_id:
        account = wallet.get_account_or_error(account_id)
        accounts = [account]
    else:
        account = wallet.default_account
        accounts = wallet.accounts

    if txid is not None and nout is not None:
        claims = await self.ledger.get_claims(
            wallet=wallet, accounts=accounts, **{"txo.txid": txid, "txo.position": nout}
        )
    elif claim_id is not None:
        claims = await self.ledger.get_claims(
            wallet=wallet, accounts=accounts, claim_id=claim_id
        )
    else:
        raise Exception("Must specify claim_id, or txid and nout")

    if not claims:
        raise Exception("No claim found for the specified claim_id or txid:nout")

    tx = await Transaction.create(
        [Input.spend(txo) for txo in claims], [], [account], account
    )

    if not preview:
        await self.broadcast_or_release(tx, blocking)
        await self.analytics_manager.send_claim_action("abandon")
    else:
        await account.ledger.release_tx(tx)

    return tx


# Traceback (AttributeError)
2019-08-01 18:18:06,916 INFO     lbry.stream.reflector.client:119: Sent reflector blob e5828b7e
2019-08-01 18:18:29,221 INFO     lbry.stream.reflector.client:119: Sent reflector blob 867d1a2c
2019-08-01 18:18:51,545 INFO     lbry.stream.reflector.client:119: Sent reflector blob 6e365367
2019-08-01 18:18:58,400 INFO     lbry.extras.daemon.Daemon:2330: publishing: name: xxxx params: {'title': 'xxxx', 'description': 'xxxxxx', 'bid': '0.10000000', 'languages': ['en'], 'tags': ['xxxxx'], 'thumbnail_url': 'https://spee.ch/8/xxxxxxxxx', 'license': 'All rights reserved   Published With Permission', 'release_time': 1564696220, 'channel_id': 'xxxxxxxxxxxx', 'fee_currency': 'LBC', 'fee_amount': '1.00000000', 'file_path': 'C:\\Users\\David T\\Desktop\\GMCZ0549_VID_1280x720x1500kbs_HCVC549.mp4'}
2019-08-01 18:19:22,348 ERROR    lbry.extras.daemon.Daemon:586: error handling api request
Traceback (most recent call last):
File "lbry\extras\daemon\Daemon.py", line 580, in _process_rpc_call
File "lbry\extras\daemon\Daemon.py", line 2342, in jsonrpc_publish
File "lbry\extras\daemon\Daemon.py", line 2659, in jsonrpc_stream_update
File "lbry\stream\stream_manager.py", line 232, in delete_stream
AttributeError: 'NoneType' object has no attribute 'stop_tasks'
2019-08-01 18:19:37,886 INFO     lbry.stream.reflector.client:119: Sent reflector blob f5b10e7b
2019-08-01 18:20:00,717 INFO     lbry.stream.reflector.client:119: Sent reflector blob d5ffe375

# Fixed code
async def jsonrpc_channel_abandon(
    self,
    claim_id=None,
    txid=None,
    nout=None,
    account_id=None,
    wallet_id=None,
    preview=False,
    blocking=True,
):
    """
    Abandon one of my channel claims.

    Usage:
        channel_abandon [<claim_id> | --claim_id=<claim_id>]
                        [<txid> | --txid=<txid>] [<nout> | --nout=<nout>]
                        [--account_id=<account_id>] [--wallet_id=<wallet_id>]
                        [--preview] [--blocking]

    Options:
        --claim_id=<claim_id>     : (str) claim_id of the claim to abandon
        --txid=<txid>             : (str) txid of the claim to abandon
        --nout=<nout>             : (int) nout of the claim to abandon
        --account_id=<account_id> : (str) id of the account to use
        --wallet_id=<wallet_id>   : (str) restrict operation to specific wallet
        --preview                 : (bool) do not broadcast the transaction
        --blocking                : (bool) wait until abandon is in mempool

    Returns: {Transaction}
    """
    wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
    assert not wallet.is_locked, "Cannot spend funds with locked wallet, unlock first."
    if account_id:
        account = wallet.get_account_or_error(account_id)
        accounts = [account]
    else:
        account = wallet.default_account
        accounts = wallet.accounts

    if txid is not None and nout is not None:
        claims = await self.ledger.get_claims(
            wallet=wallet, accounts=accounts, **{"txo.txid": txid, "txo.position": nout}
        )
    elif claim_id is not None:
        claims = await self.ledger.get_claims(
            wallet=wallet, accounts=accounts, claim_id=claim_id
        )
    else:
        raise Exception("Must specify claim_id, or txid and nout")

    if not claims:
        raise Exception("No claim found for the specified claim_id or txid:nout")

    tx = await Transaction.create(
        [Input.spend(txo) for txo in claims], [], [account], account
    )

    if not preview:
        await self.broadcast_or_release(tx, blocking)
        self.component_manager.loop.create_task(
            self.analytics_manager.send_claim_action("abandon")
        )
    else:
        await account.ledger.release_tx(tx)

    return tx