split claim_abandon into stream_abandon and channel_abandon

This commit is contained in:
Lex Berezhny 2019-03-29 21:41:24 -04:00
parent 4230812f82
commit 83411acfbd
4 changed files with 121 additions and 64 deletions

View file

@ -1616,7 +1616,7 @@ class Daemon(metaclass=JSONRPCServerType):
return result return result
CLAIM_DOC = """ CLAIM_DOC = """
List, search and abandon all types of claims. List and search all types of claims.
""" """
@requires(WALLET_COMPONENT) @requires(WALLET_COMPONENT)
@ -1694,55 +1694,8 @@ class Daemon(metaclass=JSONRPCServerType):
sort_claim_results(claims) sort_claim_results(claims)
return {"items": claims, "total_pages": 1, "page": 1, "page_size": len(claims)} return {"items": claims, "total_pages": 1, "page": 1, "page_size": len(claims)}
@requires(WALLET_COMPONENT, conditions=[WALLET_IS_UNLOCKED])
async def jsonrpc_claim_abandon(
self, claim_id=None, txid=None, nout=None, account_id=None,
preview=False, blocking=True):
"""
Abandon one of my channel or stream claims.
Usage:
claim_abandon [<claim_id> | --claim_id=<claim_id>]
[<txid> | --txid=<txid>] [<nout> | --nout=<nout>]
[--account_id=<account_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
--preview : (bool) do not broadcast the transaction
--blocking : (bool) wait until abandon is in mempool
"""
account = self.get_account_or_default(account_id)
if txid is not None and nout is not None:
claims = await account.get_claims(**{'txo.txid': txid, 'txo.position': nout})
elif claim_id is not None:
claims = await account.get_claims(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 account.ledger.broadcast(tx)
await self.analytics_manager.send_claim_action('abandon')
if blocking:
await account.ledger.wait(tx)
else:
await account.ledger.release_tx(tx)
return tx
CHANNEL_DOC = """ CHANNEL_DOC = """
Create, update and list your channel claims. Create, update, abandon and list your channel claims.
""" """
@deprecated('channel_create') @deprecated('channel_create')
@ -1977,6 +1930,53 @@ class Daemon(metaclass=JSONRPCServerType):
return tx return tx
@requires(WALLET_COMPONENT, conditions=[WALLET_IS_UNLOCKED])
async def jsonrpc_channel_abandon(
self, claim_id=None, txid=None, nout=None, account_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>]
[--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
--preview : (bool) do not broadcast the transaction
--blocking : (bool) wait until abandon is in mempool
"""
account = self.get_account_or_default(account_id)
if txid is not None and nout is not None:
claims = await account.get_claims(**{'txo.txid': txid, 'txo.position': nout})
elif claim_id is not None:
claims = await account.get_claims(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 account.ledger.broadcast(tx)
await self.analytics_manager.send_claim_action('abandon')
if blocking:
await account.ledger.wait(tx)
else:
await account.ledger.release_tx(tx)
return tx
@requires(WALLET_COMPONENT) @requires(WALLET_COMPONENT)
def jsonrpc_channel_list(self, account_id=None, page=None, page_size=None): def jsonrpc_channel_list(self, account_id=None, page=None, page_size=None):
""" """
@ -2037,7 +2037,7 @@ class Daemon(metaclass=JSONRPCServerType):
return await self.wallet_manager.import_certificate_info(serialized_certificate_info) return await self.wallet_manager.import_certificate_info(serialized_certificate_info)
STREAM_DOC = """ STREAM_DOC = """
Create, update, list and inspect your stream claims. Create, update, abandon, list and inspect your stream claims.
""" """
@requires(WALLET_COMPONENT, STREAM_MANAGER_COMPONENT, BLOB_COMPONENT, DATABASE_COMPONENT, @requires(WALLET_COMPONENT, STREAM_MANAGER_COMPONENT, BLOB_COMPONENT, DATABASE_COMPONENT,
@ -2466,6 +2466,53 @@ class Daemon(metaclass=JSONRPCServerType):
return tx return tx
@requires(WALLET_COMPONENT, conditions=[WALLET_IS_UNLOCKED])
async def jsonrpc_stream_abandon(
self, claim_id=None, txid=None, nout=None, account_id=None,
preview=False, blocking=True):
"""
Abandon one of my stream claims.
Usage:
stream_abandon [<claim_id> | --claim_id=<claim_id>]
[<txid> | --txid=<txid>] [<nout> | --nout=<nout>]
[--account_id=<account_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
--preview : (bool) do not broadcast the transaction
--blocking : (bool) wait until abandon is in mempool
"""
account = self.get_account_or_default(account_id)
if txid is not None and nout is not None:
claims = await account.get_claims(**{'txo.txid': txid, 'txo.position': nout})
elif claim_id is not None:
claims = await account.get_claims(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 account.ledger.broadcast(tx)
await self.analytics_manager.send_claim_action('abandon')
if blocking:
await account.ledger.wait(tx)
else:
await account.ledger.release_tx(tx)
return tx
@requires(WALLET_COMPONENT) @requires(WALLET_COMPONENT)
def jsonrpc_stream_list(self, account_id=None, page=None, page_size=None): def jsonrpc_stream_list(self, account_id=None, page=None, page_size=None):
""" """

View file

@ -81,7 +81,7 @@ class EpicAdventuresOfChris45(CommandTestCase):
# After some soul searching Chris decides that his story needs more # After some soul searching Chris decides that his story needs more
# heart and a better ending. He takes down the story and begins the rewrite. # heart and a better ending. He takes down the story and begins the rewrite.
abandon = await self.out(self.daemon.jsonrpc_claim_abandon(claim_id, blocking=False)) abandon = await self.out(self.daemon.jsonrpc_stream_abandon(claim_id, blocking=False))
self.assertEqual(abandon['inputs'][0]['claim_id'], claim_id) self.assertEqual(abandon['inputs'][0]['claim_id'], claim_id)
await self.confirm_tx(abandon['txid']) await self.confirm_tx(abandon['txid'])
@ -183,7 +183,7 @@ class EpicAdventuresOfChris45(CommandTestCase):
# But sadly Ramsey wasn't so pleased. It was hard for him to tell Chris... # But sadly Ramsey wasn't so pleased. It was hard for him to tell Chris...
# Chris, though a bit heartbroken, abandoned the claim for now, but instantly started working on new hit lyrics # Chris, though a bit heartbroken, abandoned the claim for now, but instantly started working on new hit lyrics
abandon = await self.out(self.daemon.jsonrpc_claim_abandon(txid=tx['txid'], nout=0, blocking=False)) abandon = await self.out(self.daemon.jsonrpc_stream_abandon(txid=tx['txid'], nout=0, blocking=False))
self.assertTrue(abandon['inputs'][0]['txid'], tx['txid']) self.assertTrue(abandon['inputs'][0]['txid'], tx['txid'])
await self.confirm_tx(abandon['txid']) await self.confirm_tx(abandon['txid'])

View file

@ -379,7 +379,7 @@ class StreamCommands(CommandTestCase):
self.assertEqual(txs[0]['fee'], '-0.000184') self.assertEqual(txs[0]['fee'], '-0.000184')
await self.assertBalance(self.account, '8.979709') await self.assertBalance(self.account, '8.979709')
await self.claim_abandon(claim_id) await self.stream_abandon(claim_id)
txs = await self.out(self.daemon.jsonrpc_transaction_list()) txs = await self.out(self.daemon.jsonrpc_transaction_list())
self.assertEqual(len(txs[0]['abandon_info']), 1) self.assertEqual(len(txs[0]['abandon_info']), 1)
self.assertEqual(txs[0]['abandon_info'][0]['balance_delta'], '1.0') self.assertEqual(txs[0]['abandon_info'][0]['balance_delta'], '1.0')
@ -392,7 +392,7 @@ class StreamCommands(CommandTestCase):
await self.assertBalance(self.account, '10.0') await self.assertBalance(self.account, '10.0')
tx = await self.stream_create(bid='0.0001') tx = await self.stream_create(bid='0.0001')
await self.assertBalance(self.account, '9.979793') await self.assertBalance(self.account, '9.979793')
await self.claim_abandon(tx['outputs'][0]['claim_id']) await self.stream_abandon(tx['outputs'][0]['claim_id'])
await self.assertBalance(self.account, '9.97968399') await self.assertBalance(self.account, '9.97968399')
async def test_publish(self): async def test_publish(self):
@ -422,8 +422,8 @@ class StreamCommands(CommandTestCase):
with self.assertRaisesRegex(Exception, "There are 2 claims for 'foo'"): with self.assertRaisesRegex(Exception, "There are 2 claims for 'foo'"):
await self.daemon.jsonrpc_publish('foo') await self.daemon.jsonrpc_publish('foo')
# abandon duplicate channel # abandon duplicate stream
await self.claim_abandon(tx3['outputs'][0]['claim_id']) await self.stream_abandon(tx3['outputs'][0]['claim_id'])
# publish to a channel # publish to a channel
await self.channel_create('@abc') await self.channel_create('@abc')
@ -458,7 +458,7 @@ class StreamCommands(CommandTestCase):
claims = await self.claim_search(claim_id=channel_id) claims = await self.claim_search(claim_id=channel_id)
self.assertEqual(claims[0]['value'], value) self.assertEqual(claims[0]['value'], value)
await self.claim_abandon(txid=txid, nout=0) await self.channel_abandon(txid=txid, nout=0)
self.assertEqual(len(await self.claim_search(txid=txid, nout=0)), 0) self.assertEqual(len(await self.claim_search(txid=txid, nout=0)), 0)
# search stream claims # search stream claims
@ -481,9 +481,9 @@ class StreamCommands(CommandTestCase):
claims = await self.claim_search(channel_id=channel_id) claims = await self.claim_search(channel_id=channel_id)
self.assertEqual(len(claims), 3) self.assertEqual(len(claims), 3)
await self.claim_abandon(claim_id=claims[0]['claim_id']) await self.stream_abandon(claim_id=claims[0]['claim_id'])
await self.claim_abandon(claim_id=claims[1]['claim_id']) await self.stream_abandon(claim_id=claims[1]['claim_id'])
await self.claim_abandon(claim_id=claims[2]['claim_id']) await self.stream_abandon(claim_id=claims[2]['claim_id'])
claims = await self.claim_search(channel_id=channel_id) claims = await self.claim_search(channel_id=channel_id)
self.assertEqual(len(claims), 0) self.assertEqual(len(claims), 0)
@ -518,7 +518,7 @@ class StreamCommands(CommandTestCase):
async def test_abandoned_channel_with_signed_claims(self): async def test_abandoned_channel_with_signed_claims(self):
channel = (await self.channel_create('@abc', '1.0'))['outputs'][0] channel = (await self.channel_create('@abc', '1.0'))['outputs'][0]
orphan_claim = await self.stream_create('on-channel-claim', '0.0001', channel_id=channel['claim_id']) orphan_claim = await self.stream_create('on-channel-claim', '0.0001', channel_id=channel['claim_id'])
await self.claim_abandon(txid=channel['txid'], nout=0) await self.channel_abandon(txid=channel['txid'], nout=0)
channel = (await self.channel_create('@abc', '1.0'))['outputs'][0] channel = (await self.channel_create('@abc', '1.0'))['outputs'][0]
orphan_claim_id = orphan_claim['outputs'][0]['claim_id'] orphan_claim_id = orphan_claim['outputs'][0]['claim_id']
@ -531,7 +531,7 @@ class StreamCommands(CommandTestCase):
direct_uri = 'lbry://on-channel-claim#' + orphan_claim_id direct_uri = 'lbry://on-channel-claim#' + orphan_claim_id
response = await self.resolve(direct_uri) response = await self.resolve(direct_uri)
self.assertFalse(response[direct_uri]['claim']['signature_is_valid']) self.assertFalse(response[direct_uri]['claim']['signature_is_valid'])
await self.claim_abandon(claim_id=orphan_claim_id) await self.stream_abandon(claim_id=orphan_claim_id)
uri = 'lbry://@abc/on-channel-claim' uri = 'lbry://@abc/on-channel-claim'
# now, claim something on this channel (it will update the invalid claim, but we save and forcefully restore) # now, claim something on this channel (it will update the invalid claim, but we save and forcefully restore)

View file

@ -186,6 +186,16 @@ class CommandTestCase(IntegrationTestCase):
await self.on_transaction_dict(claim) await self.on_transaction_dict(claim)
return claim return claim
async def stream_abandon(self, *args, confirm=True, **kwargs):
if 'blocking' not in kwargs:
kwargs['blocking'] = False
tx = await self.out(self.daemon.jsonrpc_stream_abandon(*args, **kwargs))
if confirm:
await self.on_transaction_dict(tx)
await self.generate(1)
await self.on_transaction_dict(tx)
return tx
async def publish(self, name, *args, confirm=True, **kwargs): async def publish(self, name, *args, confirm=True, **kwargs):
claim = await self.out(self.daemon.jsonrpc_publish(name, *args, **kwargs)) claim = await self.out(self.daemon.jsonrpc_publish(name, *args, **kwargs))
self.assertEqual(claim['outputs'][0]['name'], name) self.assertEqual(claim['outputs'][0]['name'], name)
@ -213,10 +223,10 @@ class CommandTestCase(IntegrationTestCase):
await self.on_transaction_dict(channel) await self.on_transaction_dict(channel)
return channel return channel
async def claim_abandon(self, *args, confirm=True, **kwargs): async def channel_abandon(self, *args, confirm=True, **kwargs):
if 'blocking' not in kwargs: if 'blocking' not in kwargs:
kwargs['blocking'] = False kwargs['blocking'] = False
tx = await self.out(self.daemon.jsonrpc_claim_abandon(*args, **kwargs)) tx = await self.out(self.daemon.jsonrpc_channel_abandon(*args, **kwargs))
if confirm: if confirm:
await self.on_transaction_dict(tx) await self.on_transaction_dict(tx)
await self.generate(1) await self.generate(1)