Ejemplo n.º 1
0
        /// <summary>	Updates this object. </summary>
        ///
        /// <remarks>	Paul, 05/02/2015. </remarks>
        async public override void Update()
        {
            try
            {
                //
                // don't process transactions if the network is in danger
                //

                GetInfoResponse info = m_bitshares.GetInfo();
                m_suspended = info.blockchain_average_delegate_participation < kMinDelegateParticipation;
                if (!m_suspended)
                {
                    Dictionary <string, MarketRow> allMarkets = GetAllMarkets().ToDictionary(m => m.symbol_pair);
                    m_allCurrencies = m_dataAccess.GetAllCurrencies();

                    // create any handlers we need for new markets
                    CheckMarketHandlers(allMarkets);

                    // get all markets
                    RecomputeTransactionLimitsAndPrices(allMarkets);

                    //
                    // handle bitshares->bitcoin
                    //

                    Dictionary <string, BitsharesLedgerEntry> bitsharesDeposits = HandleBitsharesDesposits();

                    //
                    // handle bitcoin->bitshares
                    //

                    List <TransactionSinceBlock> bitcoinDeposits = HandleBitcoinDeposits();

                    //
                    // process bitshares deposits
                    //

                    uint siteLastTid = m_dataAccess.GetSiteLastTransactionUid();

                    foreach (KeyValuePair <string, BitsharesLedgerEntry> kvpDeposit in bitsharesDeposits)
                    {
                        // figure out which market each deposit belongs to
                        foreach (KeyValuePair <string, MarketBase> kvpHandler in m_marketHandlers)
                        {
                            BitsharesLedgerEntry l            = kvpDeposit.Value;
                            MarketRow            m            = allMarkets[kvpHandler.Key];
                            BitsharesAsset       depositAsset = m_allBitsharesAssets[l.amount.asset_id];

                            if (!HandleCommand(l, kvpHandler.Value, m, kvpDeposit.Key))
                            {
                                if (IsDepositForMarket(l.memo, m.symbol_pair))
                                {
                                    // make sure the deposit is for this market!
                                    if (kvpHandler.Value.CanDepositAsset(CurrencyHelpers.FromBitsharesSymbol(depositAsset.symbol, m_allCurrencies, depositAsset.IsUia())))
                                    {
                                        kvpHandler.Value.HandleBitsharesDeposit(kvpDeposit);
                                    }
                                }
                            }
                        }

                        // this needs to happen for every transaction
                        RecomputeTransactionLimitsAndPrices(allMarkets);
                    }

                    //
                    // process bitcoin deposits
                    //

                    List <TransactionsRow> pendingTransactions = m_dataAccess.GetAllPendingTransactions();

                    foreach (TransactionSinceBlock deposit in bitcoinDeposits)
                    {
                        // figure out which market each deposit belongs to
                        foreach (KeyValuePair <string, MarketBase> kvpHandler in m_marketHandlers)
                        {
                            if (IsDepositForMarket(deposit.Address, allMarkets[kvpHandler.Key].symbol_pair))
                            {
                                kvpHandler.Value.HandleBitcoinDeposit(deposit);
                            }
                        }

                        // this needs to happen for every transaction
                        RecomputeTransactionLimitsAndPrices(allMarkets);
                    }

                    //
                    // handle changes in transaction status
                    //

                    List <TransactionsRow> updatedTrans = new List <TransactionsRow>();
                    foreach (TransactionsRow pending in pendingTransactions)
                    {
                        TransactionsRow updated = m_dataAccess.GetTransaction(pending.received_txid);
                        if (updated.status != MetaOrderStatus.pending)
                        {
                            updatedTrans.Add(updated);
                        }
                    }

                    //
                    // push any new transactions, make sure site acknowledges receipt
                    //

                    uint latestTid = m_dataAccess.GetLastTransactionUid();
                    if (latestTid > siteLastTid || updatedTrans.Count > 0)
                    {
                        List <TransactionsRow> newTrans = m_dataAccess.GetAllTransactionsSince(siteLastTid);

                        // lump them together
                        newTrans.AddRange(updatedTrans);

                        // send 'em all
                        string result = await ApiPush <List <TransactionsRow> >(Routes.kPushTransactions, newTrans);

                        if (bool.Parse(result))
                        {
                            m_dataAccess.UpdateSiteLastTransactionUid(latestTid);
                        }
                        else
                        {
                            throw new Exception("API push response unknown! " + result);
                        }
                    }

                    //
                    // push market updates
                    //

                    foreach (KeyValuePair <string, MarketBase> kvpHandler in m_marketHandlers)
                    {
                        if (kvpHandler.Value.m_IsDirty)
                        {
                            m_dataAccess.UpdateMarketInDatabase(kvpHandler.Value.m_Market);

                                                        #pragma warning disable 4014
                            ApiPush <MarketRow>(Routes.kPushMarket, kvpHandler.Value.m_Market);
                                                        #pragma warning restore 4014

                            kvpHandler.Value.m_IsDirty = false;
                        }
                    }

                    //
                    // push fee collections
                    //

                    if (m_bitcoinFeeAddress != null && m_bitshaaresFeeAccount != null)
                    {
                        uint lastFeeId = m_dataAccess.GetSiteLastFeeUid();

                        // collect our fees
                        foreach (KeyValuePair <string, MarketBase> kvpHandler in m_marketHandlers)
                        {
                            kvpHandler.Value.CollectFees(m_bitcoinFeeAddress, m_bitshaaresFeeAccount);
                        }

                        // keep the site up to date, make sure it acknowledges receipt
                        uint latestFeeId = m_dataAccess.GetLastFeeCollectionUid();
                        if (latestFeeId > lastFeeId)
                        {
                            List <FeeCollectionRow> fees = m_dataAccess.GetFeeCollectionsSince(lastFeeId);
                            string result = await ApiPush <List <FeeCollectionRow> >(Routes.kPushFees, fees);

                            if (bool.Parse(result))
                            {
                                m_dataAccess.UpdateSiteLastFeeUid(latestFeeId);
                            }
                            else
                            {
                                throw new Exception("API push response unknown! " + result);
                            }
                        }
                    }
                }

                //
                // wait for a stop command to exit gracefully
                //

                if (m_lastCommand == null)
                {
                    m_lastCommand = ReadConsoleAsync();

                    string command = await m_lastCommand;

                    // remember we never get here unless a command was entered

                    Console.WriteLine("got command: " + command);

                    if (command == "stop")
                    {
                        m_scheduler.Dispose();
                    }

                    m_lastCommand = null;
                }
            }
            catch (UnsupportedTransactionException ute)
            {
                // ignore so we can move on!
                m_dataAccess.IgnoreTransaction(ute.m_trxId);

                // log it
                LogGeneralException(ute.ToString());
            }
            catch (Exception e)
            {
                LogGeneralException(e.ToString());
            }
        }