fixed wallet balance for multiple accounts

This commit is contained in:
Lex Berezhny 2019-11-05 09:31:33 -05:00
parent 25a0e67841
commit 2d7038dc18
3 changed files with 46 additions and 23 deletions

View file

@ -34,9 +34,12 @@ def dewies_to_lbc(dewies) -> str:
def dict_values_to_lbc(d): def dict_values_to_lbc(d):
lbc_dict = {}
for key, value in d.items(): for key, value in d.items():
if isinstance(value, int): if isinstance(value, int):
d[key] = dewies_to_lbc(value) lbc_dict[key] = dewies_to_lbc(value)
elif isinstance(value, dict): elif isinstance(value, dict):
dict_values_to_lbc(value) lbc_dict[key] = dict_values_to_lbc(value)
return d else:
lbc_dict[key] = value
return lbc_dict

View file

@ -300,21 +300,27 @@ class MainNetLedger(BaseLedger):
return self.db.get_transaction_count(**constraints) return self.db.get_transaction_count(**constraints)
async def get_detailed_balance(self, accounts, confirmations=0): async def get_detailed_balance(self, accounts, confirmations=0):
result = {} result = {
'total': 0,
'available': 0,
'reserved': 0,
'reserved_subtotals': {
'claims': 0,
'supports': 0,
'tips': 0
}
}
for account in accounts: for account in accounts:
balance = self._balance_cache.get(account.id) balance = self._balance_cache.get(account.id)
if not balance: if not balance:
balance = self._balance_cache[account.id] =\ balance = self._balance_cache[account.id] =\
await account.get_detailed_balance(confirmations, reserved_subtotals=True) await account.get_detailed_balance(confirmations, reserved_subtotals=True)
if result: for key, value in balance.items():
for key, value in balance.items(): if key == 'reserved_subtotals':
if key == 'reserved_subtotals': for subkey, subvalue in value.items():
for subkey, subvalue in value.items(): result['reserved_subtotals'][subkey] += subvalue
result['reserved_subtotals'][subkey] += subvalue else:
else: result[key] += value
result[key] += value
else:
result = balance
return result return result

View file

@ -1,7 +1,9 @@
import asyncio import asyncio
import json import json
from lbry.testcase import CommandTestCase
from torba.client.wallet import ENCRYPT_ON_DISK from torba.client.wallet import ENCRYPT_ON_DISK
from lbry.testcase import CommandTestCase
from lbry.wallet.dewies import dict_values_to_lbc
class WalletCommands(CommandTestCase): class WalletCommands(CommandTestCase):
@ -17,40 +19,52 @@ class WalletCommands(CommandTestCase):
self.assertEqual(len(session.hashX_subs), 28) self.assertEqual(len(session.hashX_subs), 28)
async def test_balance_caching(self): async def test_balance_caching(self):
self.merchant_address = await self.blockchain.get_raw_change_address() account2 = await self.daemon.jsonrpc_account_create("Tip-er")
address2 = await self.daemon.jsonrpc_address_unused(account2.id)
sendtxid = await self.blockchain.send_to_address(address2, 10)
await self.confirm_tx(sendtxid)
await self.generate(1)
wallet_balance = self.daemon.jsonrpc_wallet_balance wallet_balance = self.daemon.jsonrpc_wallet_balance
ledger = self.ledger ledger = self.ledger
query_count = self.ledger.db.db.query_count query_count = self.ledger.db.db.query_count
expected = { expected = {
'total': '10.0', 'total': '20.0',
'available': '10.0', 'available': '20.0',
'reserved': '0.0', 'reserved': '0.0',
'reserved_subtotals': {'claims': '0.0', 'supports': '0.0', 'tips': '0.0'} 'reserved_subtotals': {'claims': '0.0', 'supports': '0.0', 'tips': '0.0'}
} }
self.assertIsNone(ledger._balance_cache.get(self.account.id)) self.assertIsNone(ledger._balance_cache.get(self.account.id))
query_count += 3 query_count += 6
self.assertEqual(await wallet_balance(), expected) self.assertEqual(await wallet_balance(), expected)
self.assertEqual(self.ledger.db.db.query_count, query_count) self.assertEqual(self.ledger.db.db.query_count, query_count)
self.assertEqual(ledger._balance_cache.get(self.account.id), expected) self.assertEqual(dict_values_to_lbc(ledger._balance_cache.get(self.account.id))['total'], '10.0')
self.assertEqual(dict_values_to_lbc(ledger._balance_cache.get(account2.id))['total'], '10.0')
# calling again uses cache # calling again uses cache
self.assertEqual(await wallet_balance(), expected) self.assertEqual(await wallet_balance(), expected)
self.assertEqual(self.ledger.db.db.query_count, query_count) self.assertEqual(self.ledger.db.db.query_count, query_count)
self.assertEqual(ledger._balance_cache.get(self.account.id), expected) self.assertEqual(dict_values_to_lbc(ledger._balance_cache.get(self.account.id))['total'], '10.0')
self.assertEqual(dict_values_to_lbc(ledger._balance_cache.get(account2.id))['total'], '10.0')
await self.stream_create() await self.stream_create()
await self.generate(1)
expected = { expected = {
'total': '9.979893', 'total': '19.979893',
'available': '8.979893', 'available': '18.979893',
'reserved': '1.0', 'reserved': '1.0',
'reserved_subtotals': {'claims': '1.0', 'supports': '0.0', 'tips': '0.0'} 'reserved_subtotals': {'claims': '1.0', 'supports': '0.0', 'tips': '0.0'}
} }
# on_transaction event reset balance cache # on_transaction event reset balance cache
query_count = self.ledger.db.db.query_count
self.assertEqual(await wallet_balance(), expected) self.assertEqual(await wallet_balance(), expected)
self.assertEqual(ledger._balance_cache.get(self.account.id), expected) query_count += 3 # only one of the accounts changed
self.assertEqual(dict_values_to_lbc(ledger._balance_cache.get(self.account.id))['total'], '9.979893')
self.assertEqual(dict_values_to_lbc(ledger._balance_cache.get(account2.id))['total'], '10.0')
self.assertEqual(self.ledger.db.db.query_count, query_count)
async def test_granular_balances(self): async def test_granular_balances(self):
account2 = await self.daemon.jsonrpc_account_create("Tip-er") account2 = await self.daemon.jsonrpc_account_create("Tip-er")