Skip to content

Commit

Permalink
Ver 1.0.5 - low hot wallet balance emails, plus fixes
Browse files Browse the repository at this point in the history
 - Add example env file with the most common env options
 - Added `notify_low_funds`, `funds_low` and `last_notified` to Coin model
 - Added new deposit status `mapped` - meaning we know the destination details
   but it has not been converted yet, and could still fail
 - Add email configuration to settings, with new env vars
 - Notify ADMINS if a deposit failed to convert due to low wallet balance
 - Refactored `convert_coins.py` to be two stages (so that low balance email
        can semi-accurately tell you how many deposits are stuck)

   - First stage, deposits are validated, e.g. do they have a valid deposit
   address, or a memo for us to map it to a conversion?
   - Second stage, validated deposits are converted, and conversion object created

 - Cache get_token request in `SteemEngineLoader` to prevent spamming API for
   same token for every single deposit.
 - Ignore deposits from `market` in `SteemEngineLoader`
 - Text after the destination address in a deposit memo should now be used for
   the destination memo
 - Clean up logging - commented out un-necessary debug logging, and don't use
   spammy `log.exception` when we know why the exception happened (e.g. coin daemon dead)
 - Probably various small fixes and comment cleanup
  • Loading branch information
Someguy123 committed Apr 1, 2019
1 parent 8e113e7 commit a7f08e6
Show file tree
Hide file tree
Showing 13 changed files with 499 additions and 67 deletions.
28 changes: 28 additions & 0 deletions env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
PLEASE_README=This is an EXAMPLE env file, and many of the settings specified in this file are OPTIONAL
PLEASE_README=You should read the documentation to see what is and isn't required, and their defaults.
PLEASE_README=You will also find information about each of these env vars in the folder steemengine/settings/

SECRET_KEY=SomeSecureRandomString
DEBUG=false

DB_BACKEND=postgresql
DB_USER=steemengine
DB_NAME=steemengine
DB_PASS=MyDatabasePassword
DB_HOST=localhost

ADMINS=John Doe:[email protected],Jane [email protected]
ALLOW_HOSTS=example.com,www.example.com
SITE_URL=https://www.example.com

[email protected]
EMAIL_HOST=smtp.emailprovider.com
EMAIL_USER=myemailuser
EMAIL_PASSWORD=somesecurepassword
EMAIL_PORT=587
EMAIL_TLS=true

UNLOCK=mybeempassword

EX_FEE=10
STEEM_RPC_NODES=https://steemd.privex.io,https://api.steemit.com
6 changes: 3 additions & 3 deletions payments/coin_handlers/Bitcoin/BitcoinMixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ def _prep_settings(self, reset: bool =False) -> Dict[str, dict]:
s = {} # Temporary settings dict

# Load handler settings from Coin objects, combine the JSON dict into our settings dict
log.debug('Loading Bitcoind handler settings from Coin objects')
# log.debug('Loading Bitcoind handler settings from Coin objects')
for sym, c in self.all_coins.items():
sc = c.settings # {host,port,user,password,json}
s[sym] = {k: v for k, v in sc.items() if k != 'json'} # Don't include the 'json' key
s[sym] = {**s[sym], **sc['json']} # Merge contents of 'json' into our settings

log.debug('Loading Bitcoind handler settings from settings.COIND_RPC (if it exists)')
# log.debug('Loading Bitcoind handler settings from settings.COIND_RPC (if it exists)')
# If COIND_RPC has been set in settings.py, they take precedence over database-level settings.
if hasattr(settings, 'COIND_RPC'):
for symbol, conn in settings.COIND_RPC.items():
Expand All @@ -117,7 +117,7 @@ def _clean_settings(self, d_settings: Dict[str, dict]) -> Dict[str, dict]:
defs = self._bc_defaults
# Loop over each symbol and settings dict we were passed
for sym, conn in d_settings.items(): # coin symbol : str, settings: dict
log.debug("Cleaning settings for symbol %s", sym)
# log.debug("Cleaning settings for symbol %s", sym)
z = d_settings[sym] # Pointer to the settings dict for this symbol
# Loop over our default settings, compare to the user's settings
for def_key, def_val in defs.items(): # settings key : str, settings value : any
Expand Down
6 changes: 4 additions & 2 deletions payments/coin_handlers/SteemEngine/SteemEngineLoader.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

from dateutil.parser import parse
from django.conf import settings
from django.core.cache import cache

from payments.coin_handlers.base.BaseLoader import BaseLoader
from privex.steemengine import SteemEngineToken
Expand Down Expand Up @@ -100,9 +101,10 @@ def clean_txs(self, account: str, symbol: str, transactions: Iterable[dict]) ->
"""
for tx in transactions:
try:
if tx['from'].lower() == 'tokens': continue # Ignore token issues
if tx['from'].lower() in ['tokens', 'market']: continue # Ignore token issues and market transactions
if tx['to'].lower() != account.lower(): continue # If we aren't the receiver, we don't need it.
token = self.eng_rpc.get_token(symbol)
# Cache the token for 5 mins, so we aren't spamming the token API
token = cache.get_or_set('stmeng:'+symbol, lambda: self.eng_rpc.get_token(symbol), 300)
q = tx['quantity']
if type(q) == float:
q = ('{0:.' + str(token['precision']) + 'f}').format(tx['quantity'])
Expand Down
5 changes: 3 additions & 2 deletions payments/coin_handlers/SteemEngine/SteemEngineManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,13 @@ def balance(self, address: str = None, memo: str = None, memo_case: bool = False
"""
Get token balance for a given Steem account, if memo is given - get total symbol amt received with this memo.
:param address: Steem account to get balance for
:param address: Steem account to get balance for, if not set, uses self.coin.our_account
:param memo: If not None, get total `self.symbol` received with this memo.
:param memo_case: Case sensitive memo search
:return: Decimal(balance)
"""

if address is None:
address = self.coin.our_account
address = address.lower()
if memo is not None:
memo = str(memo).strip()
Expand Down
3 changes: 3 additions & 0 deletions payments/coin_handlers/base/BatchLoader.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from payments.coin_handlers import BaseLoader
from payments.coin_handlers.base.decorators import retry_on_err
from payments.coin_handlers.base.exceptions import DeadAPIError
from payments.models import Coin
from steemengine.helpers import empty

Expand Down Expand Up @@ -126,6 +127,8 @@ def list_txs(self, batch=100) -> Generator[dict, None, None]:
try:
for tx in self._list_txs(coin=c, batch=batch):
yield tx
except DeadAPIError as e:
log.error('Skipping coin %s as API/Daemon is not responding: %s', c, str(e))
except:
log.exception('Something went wrong while loading transactions for coin %s. Skipping for now.', c)
continue
Expand Down
Loading

0 comments on commit a7f08e6

Please sign in to comment.