Refactor balance retrieval to suite multi-token environment.

This commit is contained in:
PhilipWafula 2021-11-22 13:16:01 +03:00
parent 2c8acce80d
commit eff588ad9e
Signed by untrusted user: mango-habanero
GPG Key ID: B00CE9034DA19FB7

View File

@ -2,7 +2,7 @@
import json import json
import logging import logging
from typing import Optional from typing import Union, Optional
# third-party imports # third-party imports
from cic_eth.api import Api from cic_eth.api import Api
@ -14,7 +14,7 @@ from cic_ussd.account.transaction import from_wei
from cic_ussd.cache import cache_data_key, get_cached_data from cic_ussd.cache import cache_data_key, get_cached_data
from cic_ussd.error import CachedDataNotFoundError from cic_ussd.error import CachedDataNotFoundError
logg = logging.getLogger() logg = logging.getLogger(__file__)
def get_balances(address: str, def get_balances(address: str,
@ -43,7 +43,7 @@ def get_balances(address: str,
:return: A list containing balance data if called synchronously. | None :return: A list containing balance data if called synchronously. | None
:rtype: list | None :rtype: list | None
""" """
logg.debug(f'retrieving balance for address: {address}') logg.debug(f'retrieving {token_symbol} balance for address: {address}')
if asynchronous: if asynchronous:
cic_eth_api = Api( cic_eth_api = Api(
chain_str=chain_str, chain_str=chain_str,
@ -60,11 +60,13 @@ def get_balances(address: str,
return balance_request_task.get() return balance_request_task.get()
def calculate_available_balance(balances: dict) -> float: def calculate_available_balance(balances: dict, decimals: int) -> float:
"""This function calculates an account's balance at a specific point in time by computing the difference from the """This function calculates an account's balance at a specific point in time by computing the difference from the
outgoing balance and the sum of the incoming and network balances. outgoing balance and the sum of the incoming and network balances.
:param balances: incoming, network and outgoing balances. :param balances: incoming, network and outgoing balances.
:type balances: dict :type balances: dict
:param decimals:
:type decimals: int
:return: Token value of the available balance. :return: Token value of the available balance.
:rtype: float :rtype: float
""" """
@ -73,7 +75,7 @@ def calculate_available_balance(balances: dict) -> float:
network_balance = balances.get('balance_network') network_balance = balances.get('balance_network')
available_balance = (network_balance + incoming_balance) - outgoing_balance available_balance = (network_balance + incoming_balance) - outgoing_balance
return from_wei(value=available_balance) return from_wei(decimals=decimals, value=available_balance)
def get_adjusted_balance(balance: int, chain_str: str, timestamp: int, token_symbol: str): def get_adjusted_balance(balance: int, chain_str: str, timestamp: int, token_symbol: str):
@ -94,24 +96,25 @@ def get_adjusted_balance(balance: int, chain_str: str, timestamp: int, token_sym
return demurrage_api.get_adjusted_balance(token_symbol, balance, timestamp).result return demurrage_api.get_adjusted_balance(token_symbol, balance, timestamp).result
def get_cached_available_balance(blockchain_address: str) -> float: def get_cached_available_balance(decimals: int, identifier: Union[list, bytes]) -> float:
"""This function attempts to retrieve balance data from the redis cache. """This function attempts to retrieve balance data from the redis cache.
:param blockchain_address: Ethereum address of an account. :param decimals:
:type blockchain_address: str :type decimals: int
:param identifier: An identifier needed to create a unique pointer to a balances resource.
:type identifier: bytes | list
:raises CachedDataNotFoundError: No cached balance data could be found. :raises CachedDataNotFoundError: No cached balance data could be found.
:return: Operational balance of an account. :return: Operational balance of an account.
:rtype: float :rtype: float
""" """
identifier = bytes.fromhex(blockchain_address) key = cache_data_key(identifier=identifier, salt=MetadataPointer.BALANCES)
key = cache_data_key(identifier, salt=MetadataPointer.BALANCES)
cached_balances = get_cached_data(key=key) cached_balances = get_cached_data(key=key)
if cached_balances: if cached_balances:
return calculate_available_balance(json.loads(cached_balances)) return calculate_available_balance(balances=json.loads(cached_balances), decimals=decimals)
else: else:
raise CachedDataNotFoundError(f'No cached available balance for address: {blockchain_address}') raise CachedDataNotFoundError(f'No cached available balance at {key}')
def get_cached_adjusted_balance(identifier: bytes): def get_cached_adjusted_balance(identifier: Union[list, bytes]):
""" """
:param identifier: :param identifier:
:type identifier: :type identifier:
@ -120,3 +123,22 @@ def get_cached_adjusted_balance(identifier: bytes):
""" """
key = cache_data_key(identifier, MetadataPointer.BALANCES_ADJUSTED) key = cache_data_key(identifier, MetadataPointer.BALANCES_ADJUSTED)
return get_cached_data(key) return get_cached_data(key)
def get_account_tokens_balance(blockchain_address: str, chain_str: str, token_symbols_list: list):
"""
:param blockchain_address:
:type blockchain_address:
:param chain_str:
:type chain_str:
:param token_symbols_list:
:type token_symbols_list:
:return:
:rtype:
"""
for token_symbol in token_symbols_list:
get_balances(address=blockchain_address,
chain_str=chain_str,
token_symbol=token_symbol,
asynchronous=True,
callback_param=f'{blockchain_address},{token_symbol}')