async def cmd_hashrate(command_str, discord_message, apis): if apis.token.estimated_hashrate_since_readjustment == None: return ":shrug:" fmt_str = "Estimated hashrate: **{}** over the last {}, and **{}** over the last 24 hours." result = fmt_str.format(to_readable_thousands(apis.token.estimated_hashrate_since_readjustment, unit_type="hashrate", decimals=2), seconds_to_time(apis.token.seconds_since_readjustment, granularity=2), to_readable_thousands(apis.token.estimated_hashrate_24h, unit_type="hashrate", decimals=2)) return result
async def cmd_hashrate(command_str, discord_message, apis): if apis.token.estimated_hashrate_since_readjustment is None: result = ":shrug:" # check if the 24h hashrate estimate was not calculated # # unfortunately infura v3 removed the functions necessary to calculate it, and # we store 'None' in that case. If they ever being back support it should be # populated again and just work elif apis.token.estimated_hashrate_24h is None: fmt_str = "Estimated hashrate: **{}** over the last {}." result = fmt_str.format(to_readable_thousands(apis.token.estimated_hashrate_since_readjustment, unit_type="hashrate", decimals=2), seconds_to_time(apis.token.seconds_since_readjustment, granularity=2)) else: fmt_str = "Estimated hashrate: **{}** over the last {}, and **{}** over the last 24 hours." result = fmt_str.format(to_readable_thousands(apis.token.estimated_hashrate_since_readjustment, unit_type="hashrate", decimals=2), seconds_to_time(apis.token.seconds_since_readjustment, granularity=2), to_readable_thousands(apis.token.estimated_hashrate_24h, unit_type="hashrate", decimals=2)) return result
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_difficulty(command_str, discord_message, apis): if apis.token.difficulty == None: return ":shrug:" if apis.token.seconds_until_readjustment == float('inf'): retarget_str = '' else: retarget_str = " ({} until next retarget)".format(seconds_to_time(apis.token.seconds_until_readjustment)) fmt_str = "Current difficulty: **{}** {}" result = fmt_str.format(to_readable_thousands(apis.token.difficulty, unit_type='long'), retarget_str) 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))
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 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')