async def cmd_tokens_minted(command_str, discord_message, apis):
    if apis.token.tokens_minted == None:
        return ":shrug:"

    fmt_str = "Tokens in circulation: **{}** / {} {}"
    result = fmt_str.format(prettify_decimals(apis.token.tokens_minted), 
                            prettify_decimals(apis.token.total_supply),
                            apis.token.symbol)
    return result
Ejemplo n.º 2
0
def run_function_and_time_it(function_name, iterations):
    import timeit
    timer = timeit.Timer(
        "{}()".format(function_name),
        "gc.enable(); from main import {}".format(function_name))
    speed = min(timer.repeat(repeat=3, number=iterations))
    time_per_run = speed / iterations
    messages_per_sec = 1 / (speed / iterations)
    fmt_str = "{:>23}:{:>12} seconds per call{:>12} runs per sec"
    logging.info(
        fmt_str.format(function_name,
                       formatting_helpers.prettify_decimals(time_per_run),
                       formatting_helpers.prettify_decimals(messages_per_sec)))
def parse_mining_results(apis, nonce, digest, save_high_score=False, author_name=None, author_id=None):
    resulting_difficulty = apis.token.max_target / Web3.toInt(digest)
    percent_of_the_way_to_full_target = apis.token.mining_target / Web3.toInt(digest)
    fmt_str = "Nonce `0x{}...` -> Digest `0x{}...`\nDiff: {} ({}% of the way to a full solution)"
    result = fmt_str.format(nonce[:5].hex(),
                            digest[:5].hex(),
                            prettify_decimals(resulting_difficulty), 
                            prettify_decimals(percent_of_the_way_to_full_target * 100.0))
    if save_high_score:
        result += check_and_set_top_share(apis,
                                          resulting_difficulty, 
                                          author_name,
                                          author_id,
                                          digest)
    return result
async def cmd_marketcap(command_str, discord_message, apis):
    if apis.exchanges.last_updated_time() == 0:
        return "not sure yet... waiting on my APIs :sob: [<{}>]".format(apis.exchanges.short_url())

    token_price = apis.exchanges.price_eth(config.TOKEN_SYMBOL) * apis.exchanges.eth_price_usd()
    marketcap = apis.token.tokens_minted * token_price

    if marketcap == 0:
        return ":shrug:"

    fmt_str = "Marketcap: **${}** (Price: ${} Circulating Supply: {})"
    result = fmt_str.format(prettify_decimals(marketcap),
                            prettify_decimals(token_price),
                            prettify_decimals(apis.token.tokens_minted))
    return result
Ejemplo n.º 5
0
def run_command_fuzzer():
    import logging
    import asyncio
    import time
    from main import apis, manual_api_update
    from formatting_helpers import prettify_decimals
    commands_per_log_message = 150000  # about 1 hour on a 4th gen i7

    logging.info(
        "Starting fuzz test. Ctrl+C to exit. Errors are logged to console.")

    asyncio.get_event_loop().run_until_complete(manual_api_update())
    time_last = time.time()

    # no seed; each run should be unique
    for idx, command_str in enumerate(get_fuzzing_iterator()):
        run_and_log_command(apis, command_str)

        if idx != 0 and idx % commands_per_log_message == 0:

            time_now = time.time()
            time_delta = time_now - time_last
            time_per_command = time_delta / commands_per_log_message
            commands_per_second = 1 / time_per_command
            time_last = time_now

            fmt_str = "{:>14} commands {:>14} cmds/sec"
            logging.info(
                fmt_str.format(idx, prettify_decimals(commands_per_second)))
async def cmd_all_time_high(command_str, discord_message, apis):
    time_eth = unix_timestamp_to_readable_date(apis.storage.all_time_high_eth_timestamp.get())
    time_usd = unix_timestamp_to_readable_date(apis.storage.all_time_high_usd_timestamp.get())

    if time_eth == time_usd:
        fmt_str = "All time high: **{}Ξ** **${}** ({})"
        result = fmt_str.format(prettify_decimals(apis.storage.all_time_high_eth_price.get()),
                                prettify_decimals(apis.storage.all_time_high_usd_price.get()),
                                time_usd)
    else:
        fmt_str = "All time high: \n**{}Ξ** ({})  **${}** ({})"
        result = fmt_str.format(prettify_decimals(apis.storage.all_time_high_eth_price.get()),
                                time_eth,
                                prettify_decimals(apis.storage.all_time_high_usd_price.get()),
                                time_usd)
    return result
async def cmd_income(command_str, discord_message, apis):
    if apis.token.difficulty is None:
        return "not sure yet... waiting on my APIs :sob:"

    try:
        command, hashrate = command_str.split(maxsplit=1)
    except:
        return "Bad hashrate; try `!income 5`, `!income 300mh`, or `!income 2.8gh`"

    multipliers = (
        ('k', 1e3),
        ('m', 1e6),
        ('g', 1e9),
        ('t', 1e12),
        ('p', 1e15),
        ('e', 1e18),
        ('z', 1e21),
        ('y', 1e24))
    selected_multiplier = 1e9
    for char, mult in multipliers:
        if char in hashrate:
            selected_multiplier = mult

    match = re.match("([<\d.,]+)", hashrate)
    if not match:
        return "Bad hashrate; try `!income 5`, `!income 300mh`, or `!income 2.8gh`"
    try:
        hashrate = string_to_float(match.group(1)) * selected_multiplier
    except ValueError:
        return "Bad hashrate; try `!income 5`, `!income 300mh`, or `!income 2.8gh`"

    if hashrate == 0:
        return "Bad hashrate; try `!income 5`, `!income 300mh`, or `!income 2.8gh`"

    tokens_per_day = 0.8 * 86400 * apis.token.reward * hashrate / ((2**22) * apis.token.difficulty)
    seconds_per_block = 1.2 * ((2**22) * apis.token.difficulty) / hashrate

    if tokens_per_day > 1:
        tokens_over_time_str = "**{}** tokens/day".format(prettify_decimals(tokens_per_day))
    else:
        tokens_over_time_str = "**{}** tokens/week".format(prettify_decimals(tokens_per_day*7))

    fmt_str = "Income for {}: {}; **{}** per block solo"
    return fmt_str.format(to_readable_thousands(hashrate, unit_type='hashrate'),
                          tokens_over_time_str,
                          seconds_to_time(seconds_per_block))
Ejemplo n.º 8
0
 def test_fuzzing_prettify_decimals(self):
     from formatting_helpers import prettify_decimals
     import random
     iterations = 100000  # 4 seconds on an i7-5700HQ
     min_value, max_value = -1e30, 1e30
     # fixed seed so randomness is repeatable
     myrandom = random.Random("myseed")
     # test formatting integers
     for _ in range(iterations):
         number = myrandom.randint(min_value, max_value)
         with self.subTest(number=number):
             formatted = prettify_decimals(number)
             self.assertTrue(isinstance(formatted, str))
             self.assertTrue(len(formatted) <= 16)
     # test formatting floats
     for _ in range(iterations):
         number = myrandom.uniform(min_value, max_value)
         with self.subTest(number=number):
             formatted = prettify_decimals(number)
             self.assertTrue(isinstance(formatted, str))
             self.assertTrue(len(formatted) <= 16)
Ejemplo n.º 9
0
async def check_update_all_time_high(apis):
    price_eth = apis.exchanges.price_eth(config.TOKEN_SYMBOL)
    price_usd = apis.exchanges.price_eth(
        config.TOKEN_SYMBOL) * apis.exchanges.eth_price_usd()
    if (price_eth > 100 * apis.storage.all_time_high_eth_price.get()
            or price_usd > 100 * apis.storage.all_time_high_usd_price.get()):
        # check for prices so high they are likely bugs
        logging.warning(
            f"Prevented ATH announcement due to price too high ({price_eth} eth {price_usd} usd)"
        )
        return

    try:
        if (price_usd > apis.storage.all_time_high_usd_price.get()
                and formatting_helpers.prettify_decimals(price_usd) !=
                formatting_helpers.prettify_decimals(
                    apis.storage.all_time_high_usd_price.get())):
            msg = 'New USD all-time-high **${}**'.format(
                formatting_helpers.prettify_decimals(price_usd))
            await send_all_time_high_announcement(apis, msg)
            apis.storage.all_time_high_usd_price.set(price_usd)
            apis.storage.all_time_high_usd_timestamp.set(time.time())
        if (price_eth > apis.storage.all_time_high_eth_price.get()
                and formatting_helpers.prettify_decimals(price_eth) !=
                formatting_helpers.prettify_decimals(
                    apis.storage.all_time_high_eth_price.get())):
            msg = 'New Ethereum all-time-high **{}Ξ**'.format(
                formatting_helpers.prettify_decimals(price_eth))
            await send_all_time_high_announcement(apis, msg)
            apis.storage.all_time_high_eth_price.set(price_eth)
            apis.storage.all_time_high_eth_timestamp.set(time.time())
    except Exception as e:
        logging.exception(f"Failed to compare and/or save ATH data: {str(e)}")
Ejemplo n.º 10
0
async def check_update_all_time_high(apis):
    try:
        price_eth = apis.exchanges.price_eth(config.TOKEN_SYMBOL)
        price_usd = apis.exchanges.price_eth(
            config.TOKEN_SYMBOL) * apis.exchanges.eth_price_usd()
        if (price_usd > apis.storage.all_time_high_usd_price.get()
                and formatting_helpers.prettify_decimals(price_usd) !=
                formatting_helpers.prettify_decimals(
                    apis.storage.all_time_high_usd_price.get())):
            msg = 'New USD all-time-high **${}**'.format(
                formatting_helpers.prettify_decimals(price_usd))
            await send_all_time_high_announcement(apis, msg)
            apis.storage.all_time_high_usd_price.set(price_usd)
            apis.storage.all_time_high_usd_timestamp.set(time.time())
        if (price_eth > apis.storage.all_time_high_eth_price.get()
                and formatting_helpers.prettify_decimals(price_eth) !=
                formatting_helpers.prettify_decimals(
                    apis.storage.all_time_high_eth_price.get())):
            msg = 'New Ethereum all-time-high **{}Ξ**'.format(
                formatting_helpers.prettify_decimals(price_eth))
            await send_all_time_high_announcement(apis, msg)
            apis.storage.all_time_high_eth_price.set(price_eth)
            apis.storage.all_time_high_eth_timestamp.set(time.time())
    except:
        logging.exception('Failed to save ATH data')
async def cmd_compare_price_vs(apis, item_name="lambo", item_price=200000):
    if apis.exchanges.last_updated_time() == 0:
        return ":shrug:"

    token_price_usd = apis.exchanges.price_eth(config.TOKEN_SYMBOL) * apis.exchanges.eth_price_usd()

    if token_price_usd == 0:
        return ":shrug:"

    return "1 {} = **{}** {} (${})".format(item_name, 
                                           prettify_decimals(item_price / token_price_usd),
                                           config.TOKEN_SYMBOL,
                                           to_readable_thousands(item_price))
async def cmd_balance_of(command_str, discord_message, apis):
    if apis.token.estimated_hashrate_since_readjustment == None:
        return ":shrug:"

    try:
        address = command_str.split()[-1:][0]
        address = Web3.toChecksumAddress(address)
    except:
        return "Bad address, try `!balance of 0x0000000000000000000000000000000000000000`"

    try:
        fmt_str = "0xBitcoin balance: **{}** 0xBTC."
        result = fmt_str.format(prettify_decimals(apis.token.balance_of(address)))
    except:
        logging.exception('exception in token.balance_of')
        return ":shrug:"
    else:
        return result
def check_and_set_top_share(apis, resulting_difficulty, author_name, author_id, digest):
    result = ""
    if resulting_difficulty > apis.storage.top_miner_difficulty.get():
        fmt_str = "\nNew best share! Previous was `0x{}...` (Difficulty: {}) by {}"
        result += fmt_str.format(apis.storage.top_miner_digest.get()[:5].hex(),
                                 prettify_decimals(apis.storage.top_miner_difficulty.get()),
                                 apis.storage.top_miner_name.get())

        apis.storage.top_miner_difficulty.set(resulting_difficulty)
        apis.storage.top_miner_name.set(author_name)
        apis.storage.top_miner_id.set(author_id)
        apis.storage.top_miner_digest.set(digest)
    # in case someone solves a block... never going to happen but why not?
    if Web3.toInt(digest) <= apis.token.mining_target:
        result += "\n~~~~~"
        result += "\n:money_mouth: You seem to have solved a block!? Try your luck here [<https://etherscan.io/address/0xb6ed7644c69416d67b522e20bc294a9a9b405b31#writeContract>]"
        result += "\nMake sure you log into metamask using the public address you have set here, and type these values into the mint() function:"
        result += "\n  nonce=`{}`".format(Web3.toHex(nonce))
        result += "\n  challenge_digest=`{}`".format(Web3.toHex(digest))
        result += "\n~~~~~"
    return result
async def cmd_volume(command_str, discord_message, apis):
    if apis.exchanges.last_updated_time() == 0:
        return "not sure yet... waiting on my APIs :sob: [<{}>]".format(apis.exchanges.short_url())

    total_eth_volume = 0
    total_btc_volume = 0
    response = ""

    for api in sorted(apis.exchanges.alive_exchanges, key=lambda a: a.exchange_name):
        # skip CMC and apis not directly tracking main currency
        if api.currency_symbol != config.TOKEN_SYMBOL or api.exchange_name == "Coin Market Cap":
            continue

        volume_eth = apis.exchanges.volume_eth(config.TOKEN_SYMBOL, exchange_name=api.exchange_name)
        volume_btc = apis.exchanges.volume_btc(config.TOKEN_SYMBOL, exchange_name=api.exchange_name)
        if volume_eth == 0 and volume_btc == 0:
            continue

        total_eth_volume += volume_eth
        total_btc_volume += volume_btc
        if apis.exchanges.eth_price_usd() == 0:
            response += "{}: **{}Ξ** ".format(api.exchange_name, prettify_decimals(volume_eth))
        else:
            response += "{}: $**{}**({}Ξ) ".format(api.exchange_name, prettify_decimals(volume_eth * apis.exchanges.eth_price_usd()), prettify_decimals(volume_eth))
        if volume_btc != 0:
            if apis.exchanges.btc_price_usd() == 0:
                response += "+ **{}₿** ".format(prettify_decimals(volume_btc))
            else:
                response += "+ $**{}**({}₿) ".format(prettify_decimals(volume_btc * apis.exchanges.btc_price_usd()), prettify_decimals(volume_btc))

    response += "\n"

    if apis.exchanges.eth_price_usd() == 0 or apis.exchanges.btc_price_usd() == 0:
        response += "Total: {}Ξ + {}₿".format(prettify_decimals(total_eth_volume), prettify_decimals(total_btc_volume))
    else:
        response += "Total: $**{}**({}Ξ+{}₿)".format(prettify_decimals((total_eth_volume * apis.exchanges.eth_price_usd()) + (total_btc_volume * apis.exchanges.btc_price_usd())), prettify_decimals(total_eth_volume), prettify_decimals(total_btc_volume))

    if "better" in command_str:
        # !bettervolume
        return ':star2:'*10 + '\n' + response + '\n' + ':star2:'*10
    else:
        return response
def convert(amount, src, dest, apis):
    src = src.lower()
    dest = dest.lower()
    amount = string_to_float(amount)

    usd_value, result = None, None

    token_price_usd = apis.exchanges.price_eth(config.TOKEN_SYMBOL) * apis.exchanges.eth_price_usd()

    if config.TOKEN_SYMBOL != "0xBTC":
        logging.warning("unknown currency {}; !convert command assumes 0xBTC".format(config.TOKEN_SYMBOL))

    if src in ['0xbtc', '0xbitcoins', '0xbitcoin']:
        usd_value = token_price_usd * amount
    elif src in ['m0xbtc', 'milli0xbtc', 'milli0xbitcoin', 'milli0xbitcoins']:
        usd_value = token_price_usd * amount / 1000.0
    elif src in ['0xsatoshis', '0xsatoshi', 'satoastis', 'satoasti', 'crumbs', 'crumb']:
        usd_value = token_price_usd * amount / 10**8
    elif src in ['eth', 'ethereum', 'ether']:
        usd_value = apis.exchanges.eth_price_usd() * amount
    elif src == 'wei':
        usd_value = apis.exchanges.eth_price_usd() * amount / 10**18
    elif src in ['btc', 'bitcoins', 'bitcoin']:
        usd_value = apis.exchanges.btc_price_usd() * amount
    elif src in ['mbtc', 'millibtc', 'millibitcoins', 'millibitcoin']:
        usd_value = apis.exchanges.btc_price_usd() * amount / 1000.0
    elif src in ['satoshis', 'satoshi']:
        usd_value = apis.exchanges.btc_price_usd() * amount / 10**8
    elif src in ['usd', 'dollars', 'dollar', 'ddollar', 'bucks', 'buck']:
        usd_value = amount
    elif src in ['cents', 'cent']:
        usd_value = amount / 100.0
    else:
        for price, names in config.EXPENSIVE_STUFF:
            if util.string_contains_any(src, names, exhaustive_search=True, require_cmd_char=False):
                src = names[0]  # replace name with the non-typo'd version
                usd_value = amount * price
                break

    if usd_value == None:
        return "Bad currency ({}). 0xbtc, 0xsatoshis, eth, wei, btc, mbtc, satoshis, and usd are supported.".format(src)

    if dest in ['0xbtc', '0xbitcoins', '0xbitcoin']:
        result = usd_value / token_price_usd
    elif dest in ['m0xbtc', 'milli0xbtc', 'milli0xbitcoin', 'milli0xbitcoins']:
        result = 1000.0 * usd_value / token_price_usd
    elif dest in ['0xsatoshis', '0xsatoshi', 'satoastis', 'satoasti', 'crumbs', 'crumb']:
        result = 10**8 * usd_value / token_price_usd
    elif dest in ['eth', 'ethereum', 'ether']:
        result = usd_value / apis.exchanges.eth_price_usd()
    elif dest == 'wei':
        result = 10**18 * usd_value / apis.exchanges.eth_price_usd()
    elif dest in ['btc', 'bitcoins', 'bitcoin']:
        result = usd_value / apis.exchanges.btc_price_usd()
    elif dest in ['mbtc', 'millibtc', 'millibitcoins', 'millibitcoin']:
        result = usd_value * 1000.0 / apis.exchanges.btc_price_usd()
    elif dest in ['satoshis', 'satoshi']:
        result = 10**8 * usd_value / apis.exchanges.btc_price_usd()
    elif dest in ['usd', 'dollars', 'dollar', 'ddollar', 'bucks', 'buck']:
        result = usd_value
    elif dest in ['cents', 'cent']:
        result = usd_value * 100.0
    else:
        for price, names in config.EXPENSIVE_STUFF:
            if util.string_contains_any(dest, names, exhaustive_search=True, require_cmd_char=False):
                dest = names[0]  # replaces provided name with the non-typo'd version
                result = usd_value / price
                break

    if result == None:
        return "Bad currency ({}). 0xbtc, 0xsatoshis, eth, wei, btc, mbtc, satoshis, and usd are supported.".format(dest)

    amount = prettify_decimals(amount)
    result = prettify_decimals(result)

    return "{} {} = **{}** {}".format(amount, src, result, dest)
Ejemplo n.º 16
0
async def background_update():
    try:
        await apis.gas_price_api.update()
    except RuntimeError as e:
        logging.warning('Failed to update gas price: {}'.format(str(e)))
    except:
        logging.exception('Failed to update gas price')

    # TODO: time this. even better: time each exchange
    try:
        await apis.exchanges.update()
    except RuntimeError as e:
        logging.warning('Failed to update exchange APIs: {}'.format(str(e)))
    except:
        logging.exception('Failed to update exchange APIs')

    try:
        apis.token.update()
    except RuntimeError as e:
        logging.warning('Failed to update contract info: {}'.format(str(e)))
    except:
        logging.exception('Failed to update contract info')

    # removed holders chart updates until etherscan.py works again
    #
    # if (time.time() - apis.storage.last_holders_update_timestamp.get()) / 3600.0 > config.TOKEN_HOLDER_UPDATE_RATE_HOURS:
    #     try:
    #         etherscan.update_saved_holders_chart(config.TOKEN_NAME,
    #                                              config.TOKEN_ETH_ADDRESS,
    #                                              apis.token.tokens_minted)
    #         apis.storage.last_holders_update_timestamp.set(time.time())
    #     except TimeoutError:
    #         logging.warning('Failed to update token holders chart')
    #     except:
    #         logging.exception('Failed to update token holders chart')
    #     else:
    #         logging.info('Updated token holders chart')

    try:
        await check_update_all_time_high(apis)
    except:
        logging.exception('Failed to check all time high')

    try:
        price_eth = apis.exchanges.price_eth(config.TOKEN_SYMBOL)
        price_usd = apis.exchanges.price_eth(
            config.TOKEN_SYMBOL) * apis.exchanges.eth_price_usd()
        # usd price is hidden if it is 0 (an error)
        usd_str = "" if price_usd == 0 else "${:.2f}  |  ".format(price_usd)

        # show hashrate if available, otherwise show 'time since last update'
        if apis.token.estimated_hashrate_since_readjustment is not None and apis.token.estimated_hashrate_since_readjustment > 0:
            end_of_status = formatting_helpers.to_readable_thousands(
                apis.token.estimated_hashrate_since_readjustment,
                unit_type='short_hashrate')
        else:
            end_of_status = formatting_helpers.seconds_to_n_time_ago(
                time.time() - apis.exchanges.last_updated_time())

        # wait until at least one successful update to show status
        if apis.exchanges.last_updated_time() != 0:
            fmt_str = "{}{} Ξ ({})"
            await update_status(
                client,
                fmt_str.format(usd_str,
                               formatting_helpers.prettify_decimals(price_eth),
                               end_of_status))
    except (websockets.exceptions.ConnectionClosed, RuntimeError) as e:
        logging.warning('Falied to change status: {}'.format(str(e)))
    except:
        logging.exception('Failed to change status')
async def cmd_bestshare(command_str, discord_message, apis):
    fmt_str = "Best share digest: `0x{}...` (Difficulty: {}) by {}"
    result = fmt_str.format(apis.storage.top_miner_digest.get()[:16].hex(),
                            prettify_decimals(apis.storage.top_miner_difficulty.get()),
                            apis.storage.top_miner_name.get())
    return result
Ejemplo n.º 18
0
    def test_prettify_decimals(self):
        from formatting_helpers import prettify_decimals
        self.assertEqual(prettify_decimals(0), '0')
        self.assertEqual(prettify_decimals(0.0032), '0.0032')
        self.assertEqual(prettify_decimals(0.00160), '0.0016')

        self.assertEqual(prettify_decimals(0.00000000000000123456), '1.23e-15')
        self.assertEqual(prettify_decimals(0.0000000000000123456), '1.23e-14')
        self.assertEqual(prettify_decimals(0.000000000000123456), '1.23e-13')
        self.assertEqual(prettify_decimals(0.00000000000123456),
                         '0.00000000000123')
        self.assertEqual(prettify_decimals(0.0000000000123456),
                         '0.0000000000123')
        self.assertEqual(prettify_decimals(0.000000000123456),
                         '0.000000000123')
        self.assertEqual(prettify_decimals(0.00000000123456), '0.00000000123')
        self.assertEqual(prettify_decimals(0.0000000123456), '0.0000000123')
        self.assertEqual(prettify_decimals(0.000000123456), '0.000000123')
        self.assertEqual(prettify_decimals(0.00000123456), '0.00000123')
        self.assertEqual(prettify_decimals(0.0000123456), '0.0000123')
        self.assertEqual(prettify_decimals(0.000123456), '0.000123')
        self.assertEqual(prettify_decimals(0.00123456), '0.00123')
        self.assertEqual(prettify_decimals(0.012345678), '0.0123')
        self.assertEqual(prettify_decimals(0.12345678), '0.123')
        self.assertEqual(prettify_decimals(1.2345678), '1.235')
        self.assertEqual(prettify_decimals(12.345678), '12.35')
        self.assertEqual(prettify_decimals(123.45678), '123.46')
        self.assertEqual(prettify_decimals(1234.5678), '1234.57')
        self.assertEqual(prettify_decimals(12345.6789), '12,346')
        self.assertEqual(prettify_decimals(12345), '12,345')
        self.assertEqual(prettify_decimals(123456789), '123,456,789')
        self.assertEqual(prettify_decimals(1234567890), '1.2 billion')
        self.assertEqual(prettify_decimals(12345678901), '12.3 billion')
        self.assertEqual(prettify_decimals(123456789012), '123.5 billion')
        self.assertEqual(prettify_decimals(12345678901234), '12.3 trillion')
        self.assertEqual(prettify_decimals(123456789012345), '123.5 trillion')
        self.assertEqual(prettify_decimals(1234567890123456), '1.23e15')
        self.assertEqual(prettify_decimals(12345678901234567), '1.23e16')
        self.assertEqual(prettify_decimals(123456789012345678), '1.23e17')
Ejemplo n.º 19
0
async def background_update():
    await client.wait_until_ready()
    while not client.is_closed:
        try:
            await apis.exchanges.update()
        except RuntimeError as e:
            logging.warning('Failed to update exchange APIs: {}'.format(
                str(e)))
        except:
            logging.exception('Failed to update exchange APIs')

        try:
            apis.token.update()
        except RuntimeError as e:
            logging.warning('Failed to update contract info: {}'.format(
                str(e)))
        except:
            logging.exception('Failed to update contract info')

        if (time.time() - apis.storage.last_holders_update_timestamp.get()
            ) / 3600.0 > config.TOKEN_HOLDER_UPDATE_RATE_HOURS:
            try:
                etherscan.update_saved_holders_chart(config.TOKEN_NAME,
                                                     config.TOKEN_ETH_ADDRESS,
                                                     apis.token.tokens_minted)
                apis.storage.last_holders_update_timestamp.set(time.time())
            except TimeoutError:
                logging.warning('Failed to update token holders chart')
            except:
                logging.exception('Failed to update token holders chart')
            else:
                logging.info('Updated token holders chart')

        await check_update_all_time_high(apis)

        try:
            price_eth = apis.exchanges.price_eth(config.TOKEN_SYMBOL)
            price_usd = apis.exchanges.price_eth(
                config.TOKEN_SYMBOL) * apis.exchanges.eth_price_usd()
            # usd price is hidden if it is 0 (an error)
            usd_str = "" if price_usd == 0 else "${:.2f}  |  ".format(
                price_usd)

            # show hashrate if available, otherwise show 'time since last update'
            if apis.token.estimated_hashrate_since_readjustment is not None and apis.token.estimated_hashrate_since_readjustment > 0:
                end_of_status = formatting_helpers.to_readable_thousands(
                    apis.token.estimated_hashrate_since_readjustment,
                    unit_type='short_hashrate')
            else:
                end_of_status = formatting_helpers.seconds_to_n_time_ago(
                    time.time() - apis.exchanges.last_updated_time())

            # wait until at least one successful update to show status
            if apis.exchanges.last_updated_time() != 0:
                fmt_str = "{}{} Ξ ({})"
                await update_status(
                    client,
                    fmt_str.format(
                        usd_str,
                        formatting_helpers.prettify_decimals(price_eth),
                        end_of_status))
        except (websockets.exceptions.ConnectionClosed, RuntimeError) as e:
            logging.warning('Falied to change status: {}'.format(str(e)))
        except:
            logging.exception('Failed to change status')

        await asyncio.sleep(config.UPDATE_RATE)

    # this throws an exception which causes the program to restart
    # in normal operation we should never reach this
    raise RuntimeError('background_update loop stopped - something is wrong')