From 59424a3e735d0267d136acb195b67b280e73b70d Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Tue, 30 Jul 2019 00:34:12 -0300 Subject: [PATCH] add query to get tips summary for granular balances --- lbry/lbry/extras/daemon/Daemon.py | 25 +++++++++++-------- lbry/lbry/testcase.py | 1 + lbry/lbry/wallet/account.py | 3 +++ lbry/lbry/wallet/database.py | 11 ++++++++ .../integration/test_transaction_commands.py | 24 ++++++++++++++---- 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/lbry/lbry/extras/daemon/Daemon.py b/lbry/lbry/extras/daemon/Daemon.py index e12c9772d..07297f908 100644 --- a/lbry/lbry/extras/daemon/Daemon.py +++ b/lbry/lbry/extras/daemon/Daemon.py @@ -1033,6 +1033,7 @@ class Daemon(metaclass=JSONRPCServerType): Usage: account_balance [] [
| --address=
] + [ | --confirmations=] Options: --account_id= : (str) If provided only the balance for this @@ -1044,25 +1045,27 @@ class Daemon(metaclass=JSONRPCServerType): (decimal) amount of lbry credits in wallet """ account = self.get_account_or_default(account_id) - get_total_balance = partial(account.get_balance, confirmations=True, include_claims=True) + get_total_balance = partial(account.get_balance, confirmations=confirmations, include_claims=True) total = await get_total_balance() claims_balance = await get_total_balance(claim_type__or={'is_claim':True, 'is_update': True}) - supports_balance = await get_total_balance(is_support=True) - tips_received, tips_sent = 0, 0 - for transaction in await account.get_transactions(): - for support_output in transaction.my_support_outputs: - if all([not txi.is_my_account for txi in transaction.inputs]): - tips_received += support_output.amount - for support_output in transaction.other_support_outputs: - tips_sent += support_output.amount - unavailable = claims_balance + supports_balance + tips_received, tips_sent, tips_balance, supports_balance = 0, 0, 0, 0 + for amount, spent, from_me, to_me, height in await account.get_support_summary(): + tips_sent += amount if from_me and not to_me else 0 + tips_received += amount if to_me and not from_me else 0 + if confirmations > 0 and not 0 < height <= self.ledger.headers.height - (confirmations - 1): + continue + if not spent and to_me: + tips_balance += amount if not from_me else 0 + supports_balance += amount if from_me else 0 + unavailable = claims_balance + supports_balance + tips_balance return { 'total': dewies_to_lbc(total), 'available': dewies_to_lbc(total - unavailable), 'reserved': { 'total': dewies_to_lbc(unavailable), 'claims': dewies_to_lbc(claims_balance), - 'supports': dewies_to_lbc(supports_balance) + 'supports': dewies_to_lbc(supports_balance), + 'tips': dewies_to_lbc(tips_balance) }, 'tips_received': dewies_to_lbc(tips_received), 'tips_sent': dewies_to_lbc(tips_sent) diff --git a/lbry/lbry/testcase.py b/lbry/lbry/testcase.py index 6179bd681..9bf82cfe7 100644 --- a/lbry/lbry/testcase.py +++ b/lbry/lbry/testcase.py @@ -156,6 +156,7 @@ class CommandTestCase(IntegrationTestCase): await self.on_transaction_id(txid) await self.generate(1) await self.on_transaction_id(txid) + return txid async def on_transaction_dict(self, tx): await self.ledger.wait( diff --git a/lbry/lbry/wallet/account.py b/lbry/lbry/wallet/account.py index f29233ba5..899f19437 100644 --- a/lbry/lbry/wallet/account.py +++ b/lbry/lbry/wallet/account.py @@ -134,5 +134,8 @@ class Account(BaseAccount): def get_support_count(self, **constraints): return self.ledger.db.get_support_count(account=self, **constraints) + def get_support_summary(self): + return self.ledger.db.get_supports_summary(account_id=self.id) + async def release_all_outputs(self): await self.ledger.db.release_all_outputs(self) diff --git a/lbry/lbry/wallet/database.py b/lbry/lbry/wallet/database.py index 4de87d45b..24253aaa4 100644 --- a/lbry/lbry/wallet/database.py +++ b/lbry/lbry/wallet/database.py @@ -138,3 +138,14 @@ class WalletDatabase(BaseDatabase): " SELECT address from pubkey_address WHERE account = ?" " )", [account.public_key.address] ) + + def get_supports_summary(self, account_id): + return self.db.execute_fetchall(""" + select txo.amount, exists(select * from txi where txi.txoid=txo.txoid) as spent, + (txo.txid in + (select txi.txid from txi join pubkey_address a on txi.address = a.address + where a.account = ?)) as from_me, + (txo.address in (select address from pubkey_address where account=?)) as to_me, + tx.height + from txo join tx using (txid) where is_support=1 + """, (account_id, account_id)) diff --git a/lbry/tests/integration/test_transaction_commands.py b/lbry/tests/integration/test_transaction_commands.py index fafd0c722..f931e8018 100644 --- a/lbry/tests/integration/test_transaction_commands.py +++ b/lbry/tests/integration/test_transaction_commands.py @@ -44,7 +44,7 @@ class TransactionCommandsTestCase(CommandTestCase): 'tips_sent': '0.0', 'total': '10.0', 'available': '10.0', - 'reserved': {'total': '0.0', 'claims': '0.0', 'supports': '0.0'} + 'reserved': {'total': '0.0', 'claims': '0.0', 'supports': '0.0', 'tips': '0.0'} }, initial_balance) first_claim_id = self.get_claim_id(await self.stream_create('granularity', bid='3.0')) await self.stream_update(first_claim_id, data=b'news', bid='1.0') @@ -52,16 +52,30 @@ class TransactionCommandsTestCase(CommandTestCase): second_account_id = (await self.out(self.daemon.jsonrpc_account_create("Tip-er")))['id'] second_accound_address = await self.daemon.jsonrpc_address_unused(second_account_id) await self.confirm_tx((await self.daemon.jsonrpc_account_send('1.0', second_accound_address)).id) + self.assertEqual({ + 'tips_received': '0.0', + 'tips_sent': '0.0', + 'total': '8.97741', + 'available': '5.97741', + 'reserved': {'claims': '1.0', 'supports': '2.0', 'tips': '0.0', 'total': '3.0'} + }, await self.daemon.jsonrpc_account_balance()) second_claim_id = self.get_claim_id(await self.stream_create( name='granularity-is-cool', account_id=second_account_id, bid='0.1')) await self.daemon.jsonrpc_support_create(second_claim_id, '0.5', tip=True) - await self.confirm_tx((await self.daemon.jsonrpc_support_create( + first_account_tip_txid = await self.confirm_tx((await self.daemon.jsonrpc_support_create( first_claim_id, '0.3', tip=True, account_id=second_account_id)).id) - final_balance = await self.daemon.jsonrpc_account_balance() self.assertEqual({ 'tips_received': '0.3', 'tips_sent': '0.5', 'total': '8.777264', 'available': '5.477264', - 'reserved': {'claims': '1.0', 'supports': '2.3', 'total': '3.3'} - }, final_balance) + 'reserved': {'claims': '1.0', 'supports': '2.0', 'tips': '0.3', 'total': '3.3'} + }, await self.daemon.jsonrpc_account_balance()) + await self.confirm_tx((await self.daemon.jsonrpc_support_abandon(txid=first_account_tip_txid, nout=0)).id) + self.assertEqual({ + 'tips_received': '0.3', + 'tips_sent': '0.5', + 'total': '8.777157', + 'available': '5.777157', + 'reserved': {'claims': '1.0', 'supports': '2.0', 'tips': '0.0', 'total': '3.0'} + }, await self.daemon.jsonrpc_account_balance())