updating/abanding streams/channels works across all accounts

This commit is contained in:
Lex Berezhny 2019-10-03 23:14:09 -04:00
parent 9e873f77f9
commit 56df145052
2 changed files with 80 additions and 16 deletions

View file

@ -2248,7 +2248,7 @@ class Daemon(metaclass=JSONRPCServerType):
--clear_locations : (bool) clear existing locations (prior to adding new ones) --clear_locations : (bool) clear existing locations (prior to adding new ones)
--thumbnail_url=<thumbnail_url>: (str) thumbnail url --thumbnail_url=<thumbnail_url>: (str) thumbnail url
--cover_url=<cover_url> : (str) url of cover image --cover_url=<cover_url> : (str) url of cover image
--account_id=<account_id> : (str) account to use for holding the transaction --account_id=<account_id> : (str) account in which to look for channel (default: all)
--wallet_id=<wallet_id> : (str) restrict operation to specific wallet --wallet_id=<wallet_id> : (str) restrict operation to specific wallet
--funding_account_ids=<funding_account_ids>: (list) ids of accounts to fund this transaction --funding_account_ids=<funding_account_ids>: (list) ids of accounts to fund this transaction
--claim_address=<claim_address>: (str) address where the channel is sent --claim_address=<claim_address>: (str) address where the channel is sent
@ -2263,15 +2263,21 @@ class Daemon(metaclass=JSONRPCServerType):
Returns: {Transaction} Returns: {Transaction}
""" """
wallet = self.wallet_manager.get_wallet_or_default(wallet_id) wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
account = wallet.get_account_or_default(account_id)
funding_accounts = wallet.get_accounts_or_all(funding_account_ids) funding_accounts = wallet.get_accounts_or_all(funding_account_ids)
if account_id:
account = wallet.get_account_or_error(account_id)
accounts = [account]
else:
account = wallet.default_account
accounts = wallet.accounts
existing_channels = await self.ledger.get_claims( existing_channels = await self.ledger.get_claims(
wallet=wallet, accounts=[account] if account_id else wallet.accounts, claim_id=claim_id wallet=wallet, accounts=accounts, claim_id=claim_id
) )
if len(existing_channels) != 1: if len(existing_channels) != 1:
account_ids = ', '.join(f"'{account.id}'" for account in accounts)
raise Exception( raise Exception(
f"Can't find the channel '{claim_id}' in account '{account.id}'." f"Can't find the channel '{claim_id}' in account(s) {account_ids}."
) )
old_txo = existing_channels[0] old_txo = existing_channels[0]
if not old_txo.claim.is_channel: if not old_txo.claim.is_channel:
@ -2346,12 +2352,21 @@ class Daemon(metaclass=JSONRPCServerType):
Returns: {Transaction} Returns: {Transaction}
""" """
wallet = self.wallet_manager.get_wallet_or_default(wallet_id) wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
account = wallet.get_account_or_default(account_id) 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: if txid is not None and nout is not None:
claims = await account.get_claims(**{'txo.txid': txid, 'txo.position': nout}) claims = await self.ledger.get_claims(
wallet=wallet, accounts=accounts, **{'txo.txid': txid, 'txo.position': nout}
)
elif claim_id is not None: elif claim_id is not None:
claims = await account.get_claims(claim_id=claim_id) claims = await self.ledger.get_claims(
wallet=wallet, accounts=accounts, claim_id=claim_id
)
else: else:
raise Exception('Must specify claim_id, or txid and nout') raise Exception('Must specify claim_id, or txid and nout')
@ -2854,7 +2869,7 @@ class Daemon(metaclass=JSONRPCServerType):
--clear_channel : (bool) remove channel signature --clear_channel : (bool) remove channel signature
--channel_account_id=<channel_account_id>: (str) one or more account ids for accounts to look in --channel_account_id=<channel_account_id>: (str) one or more account ids for accounts to look in
for channel certificates, defaults to all accounts. for channel certificates, defaults to all accounts.
--account_id=<account_id> : (str) account to use for holding the transaction --account_id=<account_id> : (str) account in which to look for stream (default: all)
--wallet_id=<wallet_id> : (str) restrict operation to specific wallet --wallet_id=<wallet_id> : (str) restrict operation to specific wallet
--funding_account_ids=<funding_account_ids>: (list) ids of accounts to fund this transaction --funding_account_ids=<funding_account_ids>: (list) ids of accounts to fund this transaction
--claim_address=<claim_address>: (str) address where the claim is sent to, if not specified --claim_address=<claim_address>: (str) address where the claim is sent to, if not specified
@ -2869,13 +2884,21 @@ class Daemon(metaclass=JSONRPCServerType):
Returns: {Transaction} Returns: {Transaction}
""" """
wallet = self.wallet_manager.get_wallet_or_default(wallet_id) wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
account = wallet.get_account_or_default(account_id)
funding_accounts = wallet.get_accounts_or_all(funding_account_ids) funding_accounts = wallet.get_accounts_or_all(funding_account_ids)
if account_id:
account = wallet.get_account_or_error(account_id)
accounts = [account]
else:
account = wallet.default_account
accounts = wallet.accounts
existing_claims = await account.get_claims(claim_id=claim_id) existing_claims = await self.ledger.get_claims(
wallet=wallet, accounts=accounts, claim_id=claim_id
)
if len(existing_claims) != 1: if len(existing_claims) != 1:
account_ids = ', '.join(f"'{account.id}'" for account in accounts)
raise Exception( raise Exception(
f"Can't find the claim '{claim_id}' in account '{account.id}'." f"Can't find the stream '{claim_id}' in account(s) {account_ids}."
) )
old_txo = existing_claims[0] old_txo = existing_claims[0]
if not old_txo.claim.is_stream: if not old_txo.claim.is_stream:
@ -2979,12 +3002,21 @@ class Daemon(metaclass=JSONRPCServerType):
Returns: {Transaction} Returns: {Transaction}
""" """
wallet = self.wallet_manager.get_wallet_or_default(wallet_id) wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
account = wallet.get_account_or_default(account_id) 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: if txid is not None and nout is not None:
claims = await account.get_claims(**{'txo.txid': txid, 'txo.position': nout}) claims = await self.ledger.get_claims(
wallet=wallet, accounts=accounts, **{'txo.txid': txid, 'txo.position': nout}
)
elif claim_id is not None: elif claim_id is not None:
claims = await account.get_claims(claim_id=claim_id) claims = await self.ledger.get_claims(
wallet=wallet, accounts=accounts, claim_id=claim_id
)
else: else:
raise Exception('Must specify claim_id, or txid and nout') raise Exception('Must specify claim_id, or txid and nout')
@ -2992,14 +3024,14 @@ class Daemon(metaclass=JSONRPCServerType):
raise Exception('No claim found for the specified claim_id or txid:nout') raise Exception('No claim found for the specified claim_id or txid:nout')
tx = await Transaction.create( tx = await Transaction.create(
[Input.spend(txo) for txo in claims], [], [account], account [Input.spend(txo) for txo in claims], [], accounts, account
) )
if not preview: if not preview:
await self.broadcast_or_release(tx, blocking) await self.broadcast_or_release(tx, blocking)
await self.analytics_manager.send_claim_action('abandon') await self.analytics_manager.send_claim_action('abandon')
else: else:
await account.ledger.release_tx(tx) await self.ledger.release_tx(tx)
return tx return tx

View file

@ -507,6 +507,22 @@ class ChannelCommands(CommandTestCase):
# second wallet should be able to update now # second wallet should be able to update now
await daemon2.jsonrpc_channel_update(claim_id, bid='0.5') await daemon2.jsonrpc_channel_update(claim_id, bid='0.5')
async def test_channel_update_across_accounts(self):
account2 = await self.daemon.jsonrpc_account_create('second account')
channel = await self.out(self.channel_create('@spam', '1.0', account_id=account2.id))
# channel not in account1
with self.assertRaisesRegex(Exception, "Can't find the channel"):
await self.channel_update(self.get_claim_id(channel), bid='2.0', account_id=self.account.id)
# channel is in account2
await self.channel_update(self.get_claim_id(channel), bid='2.0', account_id=account2.id)
result = await self.out(self.daemon.jsonrpc_channel_list())
self.assertEqual(result[0]['amount'], '2.0')
# check all accounts for channel
await self.channel_update(self.get_claim_id(channel), bid='3.0')
result = await self.out(self.daemon.jsonrpc_channel_list())
self.assertEqual(result[0]['amount'], '3.0')
await self.channel_abandon(self.get_claim_id(channel))
class StreamCommands(ClaimTestCase): class StreamCommands(ClaimTestCase):
@ -564,6 +580,22 @@ class StreamCommands(ClaimTestCase):
self.assertEqual(len(tx['outputs']), 1) # no change self.assertEqual(len(tx['outputs']), 1) # no change
self.assertEqual(len(await self.daemon.jsonrpc_claim_list()), 2) self.assertEqual(len(await self.daemon.jsonrpc_claim_list()), 2)
async def test_stream_update_and_abandon_across_accounts(self):
account2 = await self.daemon.jsonrpc_account_create('second account')
stream = await self.out(self.stream_create('spam', '1.0', account_id=account2.id))
# stream not in account1
with self.assertRaisesRegex(Exception, "Can't find the stream"):
await self.stream_update(self.get_claim_id(stream), bid='2.0', account_id=self.account.id)
# stream is in account2
await self.stream_update(self.get_claim_id(stream), bid='2.0', account_id=account2.id)
result = await self.out(self.daemon.jsonrpc_stream_list())
self.assertEqual(result[0]['amount'], '2.0')
# check all accounts for stream
await self.stream_update(self.get_claim_id(stream), bid='3.0')
result = await self.out(self.daemon.jsonrpc_stream_list())
self.assertEqual(result[0]['amount'], '3.0')
await self.stream_abandon(self.get_claim_id(stream))
async def test_publishing_checks_all_accounts_for_channel(self): async def test_publishing_checks_all_accounts_for_channel(self):
account1_id, account1 = self.account.id, self.account account1_id, account1 = self.account.id, self.account
new_account = await self.out(self.daemon.jsonrpc_account_create('second account')) new_account = await self.out(self.daemon.jsonrpc_account_create('second account'))