def txs(): page = request.args.get('p', 1, int) txs_q = session.query(ExchangeTx).order_by(desc(ExchangeTx.id)) last_txs = session.query(LastSeenTransaction).order_by( desc(LastSeenTransaction.id)).limit(5).all() txs_count = txs_q.count() return render_template_string(TX_TEMPLATE, txs=txs_q.offset( (page - 1) * 20).limit(20).all(), txs_count=txs_count, pages_count=math.ceil(txs_count / 20), current_page=page, last_txs=last_txs)
def rates(): if request.method == 'POST': er = ExchangeRate(platform=request.form.get('platform'), value=float(request.form.get('value'))) session.add(er) session.commit() return redirect('/exchange-rates') rates = session.query(ExchangeRate).order_by(desc(ExchangeRate.id)).all() return render_template_string(RATES_TEMPLATE, rates=rates)
def get_actual_exchange_rate(platform): """ Actual exchange rate for platform. :param platform: Platform name :type platform: str :return: Actual exchange rate :rtype: ExchangeRate """ assert platform in [PLATFORM_WAVES, PLATFORM_ETHEREUM] return session.query(ExchangeRate).filter(ExchangeRate.platform == platform) \ .order_by(desc(ExchangeRate.id)) \ .limit(1) \ .one()
def load_txs(fnc, address): logging.getLogger('data_loading').info( 'Trying to get transactions for "%s" with "%s"', address, fnc.__name__) # get data from transactions from the blockchain txs = fnc(address) # let remember about last seen transaction last_tx_id = session.query(LastSeenTransaction.tx_id) \ .filter(LastSeenTransaction.address == address) \ .order_by(desc(LastSeenTransaction.id)) \ .limit(1)\ .scalar() logging.getLogger('data_loading').debug('Last seen transaction id "%s"', last_tx_id) new_last_tx_id = None for tx in txs: # if transaction without receiver data it is string value, not object tx_id = tx.income_tx_id if isinstance(tx, ExchangeTx) else tx logging.getLogger('data_loading').info( 'Processing transaction blockchain id "%s"', tx_id) logging.getLogger('data_loading').debug( 'Processing transaction dump: %s', tx) # there is no new data for us if processed transaction id same with id of last seen transaction in blockchain if tx_id == last_tx_id: logging.getLogger('data_loading').info( 'Current transaction already processed. Finishing processing') break if new_last_tx_id is None: # if last seen transaction not defined, this will be as last seen logging.getLogger('data_loading').debug( 'New last seen transaction id "%s"', tx_id) new_last_tx_id = tx_id # we do not interesting in information without receiver data and we do not save any data from it if not isinstance(tx, ExchangeTx): continue # save transaction session.add(tx) session.commit() # here we save data without "batch saving" logging.getLogger('data_loading').info( 'Transaction created and saved with id %d', tx.id) else: logging.getLogger('data_loading').info( 'There is no new data. Finishing processing') # saving new last seen transaction id if it calculated if new_last_tx_id: new_last_tx = LastSeenTransaction(tx_id=new_last_tx_id, address=address) session.add(new_last_tx) session.flush()
def exchange_txs(): """ Transactions processing. """ # get all transactions with status "new" txs = session.query(ExchangeTx).filter( ExchangeTx.status == ExchangeTx.STATUS_NEW).all() # type: list[ExchangeTx] for tx in txs: logging.getLogger('tx_processing').info('Working with %s', tx) # currency exchange rate for incoming and outcome currencies try: income_exchange_rate = get_actual_exchange_rate( tx.income_platform).value outcome_exchange_rate = get_actual_exchange_rate( tx.outcome_platform).value except NoResultFound: # if suddenly we could not get exchange rates logging.getLogger('tx_processing').critical( 'Missed exchange rate for one of platforms %s', [tx.income_platform, tx.outcome_platform]) continue tx.income_exchange_rate = income_exchange_rate tx.outcome_exchange_rate = outcome_exchange_rate tx.outcome_amount = int(tx.income_amount * income_exchange_rate / outcome_exchange_rate) logging.getLogger('tx_processing').debug( 'Calculating outcome amount %s', { 'income_amount': tx.income_amount, 'income_exchange_rate': income_exchange_rate, 'outcome_exchange_rate': outcome_exchange_rate }) # let send reverse transaction try: logging.getLogger('tx_processing').info( 'Creating exchange transaction') if tx.outcome_platform == PLATFORM_ETHEREUM: outcome_tx_id = send_ethereum_tx( tx, os.getenv('ETHEREUM_WALLET_ADDRESS')) elif tx.outcome_platform == PLATFORM_WAVES: outcome_tx_id = send_waves_tx( tx, os.getenv('WAVES_WALLET_ADDRESS'), os.getenv('WAVES_WALLET_PRIVATE_KEY')) else: raise ValueError('Unknown platform "{}"' % tx.outcome_platform) except Exception as e: tx.status = ExchangeTx.STATUS_FAILED tx.status_data = str(e) logging.getLogger('tx_processing').exception( 'Failed to create exchange transaction "%s"', str(e), exc_info=False) else: # marking transaction as "done" if we will not check transaction state in future tx.status = ExchangeTx.STATUS_DONE if os.getenv('DISABLE_TRANSACTION_CHECK', True) \ else ExchangeTx.STATUS_AWAITING_PROCESSING tx.outcome_tx_id = outcome_tx_id logging.getLogger('tx_processing').info( 'Exchange transaction has been created successfully') session.commit()