コード例 #1
0
        /// <summary>	Sell bit asset. </summary>
        ///
        /// <remarks>	Paul, 16/02/2015. </remarks>
        ///
        /// <param name="l">		The BitsharesLedgerEntry to process. </param>
        /// <param name="s2d">      The 2D. </param>
        /// <param name="trxId">	Identifier for the trx. </param>
        protected virtual void SellBitAsset(BitsharesLedgerEntry l, SenderToDepositRow s2d, string trxId)
        {
            decimal oldBid = m_market.bid;

            try
            {
                if (m_market.price_discovery)
                {
                    //
                    // adjust prices based on order
                    //

                    decimal informed = m_asset.GetAmountFromLarimers(l.amount.amount) / m_market.bid_max;
                    m_market.bid = m_prices.GetBidForSell(informed);
                }

                string btcAddress = s2d.receiving_address;
                SendBitcoinsToDepositor(btcAddress, trxId, l.amount.amount, m_asset, s2d.deposit_address, MetaOrderType.sell, m_currency.uia);

                if (m_market.price_discovery)
                {
                    // update database with new prices
                    m_isDirty = true;
                }
            }
            catch (Exception e)
            {
                // also lets now ignore this transaction so we don't keep failing
                RefundBitsharesDeposit(l.from_account, l.amount.amount, trxId, e.Message, m_asset, s2d.deposit_address, MetaOrderType.sell);

                // restore this
                m_market.bid = oldBid;
            }
        }
コード例 #2
0
        /// <summary>	Handles the command. </summary>
        ///
        /// <remarks>	Paul, 26/02/2015. </remarks>
        ///
        /// <param name="l">	    The BitsharesLedgerEntry to process. </param>
        /// <param name="handler">	The handler. </param>
        /// <param name="market">   The market. </param>
        ///
        /// <returns>	true if it succeeds, false if it fails. </returns>
        public bool HandleCommand(BitsharesLedgerEntry l, MarketBase handler, MarketRow market, string trxid)
        {
            if (m_adminUsernames.Contains(l.from_account))
            {
                try
                {
                    string[] parts = l.memo.Split(' ');

                    if (l.memo.StartsWith(kSetPricesMemoStart))
                    {
                        HandlePriceSetting(parts, l, handler, market);
                        return(true);
                    }
                    else if (l.memo.StartsWith(kWithdrawMemo))
                    {
                        // process withdrawal
                        if (parts[0] == kWithdrawMemo)
                        {
                            // make sure we didn't already process this transaction!
                            if (!m_dataAccess.IsWithdrawalProcessed(trxid))
                            {
                                decimal       amount = decimal.Parse(parts[1]);
                                CurrenciesRow type   = CurrencyHelpers.FromSymbol(parts[2], m_allCurrencies);
                                string        to;

                                string txid;
                                if (!CurrencyHelpers.IsBitsharesAsset(type))
                                {
                                    to = m_dataAccess.GetStats().bitcoin_withdraw_address;
                                    Debug.Assert(to != null);

                                    txid = m_bitcoin.SendToAddress(to, amount);
                                }
                                else
                                {
                                    to = l.from_account;
                                    BitsharesTransactionResponse response = m_bitshares.WalletTransfer(amount, CurrencyHelpers.ToBitsharesSymbol(type), m_bitsharesAccount, to);
                                    txid = response.record_id;
                                }

                                // log in DB
                                m_dataAccess.InsertWithdrawal(trxid, txid, type.ToString(), amount, to, DateTime.UtcNow);
                            }

                            return(true);
                        }
                    }
                }
                catch (Exception e)
                {
                    LogGeneralException(e.ToString());
                }
            }

            return(false);
        }
コード例 #3
0
        /// <summary>	Handles the bitshares deposit described by kvp. </summary>
        ///
        /// <remarks>	Paul, 05/02/2015. </remarks>
        ///
        /// <param name="kvp">	The kvp. </param>
        public override void HandleBitsharesDeposit(KeyValuePair <string, BitsharesLedgerEntry> kvp)
        {
            // get the btc address
            BitsharesLedgerEntry l = kvp.Value;
            string trxId           = kvp.Key;

            SenderToDepositRow s2d = BitsharesTransactionToBitcoinAddress(l);

            SellBitAsset(l, s2d, trxId);
        }
コード例 #4
0
ファイル: DaemonBase.cs プロジェクト: wildbunny/metaexchange
        /// <summary>	Handles the bitshares desposits. </summary>
        ///
        /// <remarks>	Paul, 16/12/2014. </remarks>
        ///
        /// <exception cref="UnsupportedTransactionException">	Thrown when an Unsupported Transaction
        ///                                                     error condition occurs. </exception>
        protected virtual Dictionary <string, BitsharesLedgerEntry> HandleBitsharesDesposits()
        {
            Dictionary <string, BitsharesLedgerEntry> results = new Dictionary <string, BitsharesLedgerEntry>();

            // which block do we start from
            uint lastBlockBitshares = GetLastBitsharesBlock();

            // which block do we end on
            GetInfoResponse info = m_bitshares.GetInfo();

            if (lastBlockBitshares == 0)
            {
                // default to current block
                lastBlockBitshares = info.blockchain_head_block_num;
            }

            // get all relevant bitshares deposits
            List <BitsharesWalletTransaction> assetTransactions = m_bitshares.WalletAccountTransactionHistory(m_bitsharesAccount,
                                                                                                              null,
                                                                                                              0,
                                                                                                              lastBlockBitshares,
                                                                                                              info.blockchain_head_block_num);

            IEnumerable <BitsharesWalletTransaction> assetDeposits = assetTransactions.Where(t => t.is_confirmed &&
                                                                                             t.ledger_entries.Any(l => l.to_account == m_bitsharesAccount &&
                                                                                                                  l.from_account != l.to_account &&
                                                                                                                  l.memo != kFundingMemo &&
                                                                                                                  l.from_account != BitsharesWallet.kNetworkAccount));

            foreach (BitsharesWalletTransaction t in assetDeposits)
            {
                // make sure we didn't already send bitcoins for this deposit
                if (!HasDepositBeenCredited(t.trx_id) && !IsTransactionIgnored(t.trx_id))
                {
                    IEnumerable <BitsharesLedgerEntry> deposits = t.ledger_entries.Where(l => l.to_account == m_bitsharesAccount);

                    if (deposits.Count() == 1)
                    {
                        BitsharesLedgerEntry l = deposits.First();
                        results[t.trx_id] = l;
                    }
                    else
                    {
                        // fail with unhandled case
                        throw new UnsupportedTransactionException(t.trx_id);
                    }
                }
            }

            UpdateBitsharesBlock(info.blockchain_head_block_num);

            return(results);
        }
コード例 #5
0
ファイル: DaemonBase.cs プロジェクト: wildbunny/metaexchange
        /// <summary>	This is virtual because implementors might like a different way  </summary>
        ///
        /// <remarks>	Paul, 16/12/2014. </remarks>
        ///
        /// <param name="account">	The account. </param>
        ///
        /// <returns>	A string. </returns>

        /*protected virtual string BitsharesTransactionToBitcoinAddress(BitsharesLedgerEntry l)
         * {
         *      // THIS CANNOT WORK DUE TO MEMO SIZE = 19 bytes!!!!!!!
         *
         *
         *      // expect the BTC address to be inside the memo somewhere
         *      string[] memo = l.memo.Split(' ');
         *      AddressBase address = null;
         *      foreach (string s in memo)
         *      {
         *              try
         *              {
         *                      address = new AddressBase(s);
         *                      break;
         *              }
         *              catch (ArgumentException){}
         *      }
         *
         *      if (address == null)
         *      {
         *              throw new RefundBitsharesException("Unable to find desired bitcoin address in transction memo!");
         *      }
         *
         *      return address.AddressBase58;
         * }*/

        /// <summary>	Bitshares transaction to bitcoin address. </summary>
        ///
        /// <remarks>	Paul, 25/01/2015. </remarks>
        ///
        /// <exception cref="RefundBitsharesException">	Thrown when a Refund Bitshares error condition
        ///                                             occurs. </exception>
        ///
        /// <param name="l">	The BitsharesLedgerEntry to process. </param>
        /// <param name="t">	The TransactionSinceBlock to process. </param>
        ///
        /// <returns>	A string. </returns>
        protected virtual string BitsharesTransactionToBitcoinAddress(BitsharesLedgerEntry l, BitsharesTransaction t)
        {
            try
            {
                // get the public key of the sender
                BitsharesAccount account = GetAccountFromLedger(l.from_account);

                // turn into into a bitshares address
                return(BitsharesAccountToBitcoinAddress(account));
            }
            catch (BitsharesRpcException)
            {
                throw new RefundBitsharesException("Unregistered acct!");
            }
        }
コード例 #6
0
        /// <summary>	Bitshares transaction to bitcoin address. </summary>
        ///
        /// <remarks>	Paul, 31/01/2015. </remarks>
        ///
        /// <param name="l">	The BitsharesLedgerEntry to process. </param>
        /// <param name="t">	The TransactionSinceBlock to process. </param>
        ///
        /// <returns>	A string. </returns>

        /*protected override string BitsharesTransactionToBitcoinAddress(BitsharesLedgerEntry l, BitsharesTransaction t)
         * {
         *      // look up the BTS address this transaction was sent to
         *      BitsharesOperation op = t.trx.operations.First(o => o.type == BitsharesTransactionOp.deposit_op_type);
         *
         *      string depositAddress = op.data.condition.data.owner;
         *
         *      // look that address up in our map of sender->deposit address
         *      SenderToDepositRow senderToDeposit = GetSenderDepositFromDeposit(depositAddress);
         *      if (senderToDeposit != null)
         *      {
         *              return senderToDeposit.sender;
         *      }
         *      else
         *      {
         *              return null;
         *      }
         * }*/

        /// <summary>	Bitshares transaction to bitcoin address. </summary>
        ///
        /// <remarks>	Paul, 31/01/2015. </remarks>
        ///
        /// <param name="l">	The BitsharesLedgerEntry to process. </param>
        /// <param name="t">	The TransactionSinceBlock to process. </param>
        ///
        /// <returns>	A string. </returns>
        protected override string BitsharesTransactionToBitcoinAddress(BitsharesLedgerEntry l, BitsharesTransaction t)
        {
            // look up the BTS address this transaction was sent to

            // look that address up in our map of sender->deposit address
            SenderToDepositRow senderToDeposit = GetSenderDepositFromDeposit(l.memo);

            if (senderToDeposit != null)
            {
                return(senderToDeposit.receiving_address);
            }
            else
            {
                throw new RefundBitsharesException("Missing memo!");
            }
        }
コード例 #7
0
        /// <summary>	Handles the price setting. </summary>
        ///
        /// <remarks>	Paul, 14/02/2015. </remarks>
        ///
        /// <param name="l">	    The BitsharesLedgerEntry to process. </param>
        /// <param name="handler">	The handler. </param>
        /// <param name="market">   The market. </param>
        void HandlePriceSetting(string[] parts, BitsharesLedgerEntry l, MarketBase handler, MarketRow market)
        {
            // parse

            if (parts[0] == kSetPricesMemoStart)
            {
                if (parts[1] == market.symbol_pair)
                {
                    // setting is for this market!
                    decimal basePrice  = decimal.Parse(parts[2]);
                    decimal quotePrice = decimal.Parse(parts[3]);

                    // go do it!
                    handler.SetPricesFromSingleUnitQuantities(basePrice, quotePrice, market.flipped, market);
                }
            }
        }
コード例 #8
0
ファイル: MarketBase.cs プロジェクト: wildbunny/metaexchange
        /// <summary>	Bitshares transaction to bitcoin address. </summary>
        ///
        /// <remarks>	Paul, 05/02/2015. </remarks>
        ///
        /// <exception cref="RefundBitsharesException">	Thrown when a Refund Bitshares error condition
        ///                                             occurs. </exception>
        ///
        /// <param name="l">	The BitsharesLedgerEntry to process. </param>
        ///
        /// <returns>	A string. </returns>
        protected SenderToDepositRow BitsharesTransactionToBitcoinAddress(BitsharesLedgerEntry l)
        {
            // look up the BTS address this transaction was sent to

            // look that address up in our map of sender->deposit address

            // pull the market uid out of the memo
            string symbolPair;
            uint   referralUser;

            MemoExtract(l.memo, out symbolPair, out referralUser);

            SenderToDepositRow senderToDeposit = m_daemon.GetSenderDepositFromDeposit(l.memo, symbolPair, referralUser);

            if (senderToDeposit != null)
            {
                return(senderToDeposit);
            }
            else
            {
                throw new RefundBitsharesException("Missing/bad memo!");
            }
        }
コード例 #9
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());
            }
        }
コード例 #10
0
ファイル: DaemonApi.cs プロジェクト: sfinder/metaexchange
        /// <summary>	Bitshares transaction to bitcoin address. </summary>
        ///
        /// <remarks>	Paul, 31/01/2015. </remarks>
        ///
        /// <param name="l">	The BitsharesLedgerEntry to process. </param>
        /// <param name="t">	The TransactionSinceBlock to process. </param>
        ///
        /// <returns>	A string. </returns>
        /*protected override string BitsharesTransactionToBitcoinAddress(BitsharesLedgerEntry l, BitsharesTransaction t)
        {
            // look up the BTS address this transaction was sent to
            BitsharesOperation op = t.trx.operations.First(o => o.type == BitsharesTransactionOp.deposit_op_type);

            string depositAddress = op.data.condition.data.owner;

            // look that address up in our map of sender->deposit address
            SenderToDepositRow senderToDeposit = GetSenderDepositFromDeposit(depositAddress);
            if (senderToDeposit != null)
            {
                return senderToDeposit.sender;
            }
            else
            {
                return null;
            }
        }*/
        /// <summary>	Bitshares transaction to bitcoin address. </summary>
        ///
        /// <remarks>	Paul, 31/01/2015. </remarks>
        ///
        /// <param name="l">	The BitsharesLedgerEntry to process. </param>
        /// <param name="t">	The TransactionSinceBlock to process. </param>
        ///
        /// <returns>	A string. </returns>
        protected override string BitsharesTransactionToBitcoinAddress(BitsharesLedgerEntry l, BitsharesTransaction t)
        {
            // look up the BTS address this transaction was sent to

            // look that address up in our map of sender->deposit address
            SenderToDepositRow senderToDeposit = GetSenderDepositFromDeposit(l.memo);
            if (senderToDeposit != null)
            {
                return senderToDeposit.receiving_address;
            }
            else
            {
                throw new RefundBitsharesException("Missing memo!");
            }
        }
コード例 #11
0
ファイル: MetaDaemonApi.cs プロジェクト: sfinder/metaexchange
		/// <summary>	Handles the command. </summary>
		///
		/// <remarks>	Paul, 26/02/2015. </remarks>
		///
		/// <param name="l">	  	The BitsharesLedgerEntry to process. </param>
		/// <param name="handler">	The handler. </param>
		/// <param name="market"> 	The market. </param>
		///
		/// <returns>	true if it succeeds, false if it fails. </returns>
		public bool HandleCommand(BitsharesLedgerEntry l, MarketBase handler, MarketRow market, string trxid)
		{
			if (m_adminUsernames.Contains(l.from_account))
			{
				try
				{
					string[] parts = l.memo.Split(' ');

					if (l.memo.StartsWith(kSetPricesMemoStart))
					{
						HandlePriceSetting(parts, l, handler, market);
						return true;
					}
					else if (l.memo.StartsWith(kWithdrawMemo))
					{
						// process withdrawal
						if (parts[0] == kWithdrawMemo)
						{
							// make sure we didn't already process this transaction!
							if (!m_dataAccess.IsWithdrawalProcessed(trxid))
							{
								decimal amount = decimal.Parse(parts[1]);
								CurrenciesRow type = CurrencyHelpers.FromSymbol(parts[2], m_allCurrencies);
								string to;

								string txid;
								if ( !CurrencyHelpers.IsBitsharesAsset(type) )
								{
									to = m_dataAccess.GetStats().bitcoin_withdraw_address;
									Debug.Assert(to != null);

									txid = m_bitcoin.SendToAddress(to, amount);
								}
								else
								{
									to = l.from_account;
									BitsharesTransactionResponse response = m_bitshares.WalletTransfer(amount, CurrencyHelpers.ToBitsharesSymbol(type), m_bitsharesAccount, to);
									txid = response.record_id;
								}

								// log in DB
								m_dataAccess.InsertWithdrawal(trxid, txid, type.ToString(), amount, to, DateTime.UtcNow);
							}

							return true;
						}
					}
				}
				catch (Exception e)
				{
					LogGeneralException(e.ToString());
				}
			}

			return false;
		}
コード例 #12
0
ファイル: MetaDaemonApi.cs プロジェクト: sfinder/metaexchange
		/// <summary>	Handles the price setting. </summary>
		///
		/// <remarks>	Paul, 14/02/2015. </remarks>
		///
		/// <param name="l">	  	The BitsharesLedgerEntry to process. </param>
		/// <param name="handler">	The handler. </param>
		/// <param name="market"> 	The market. </param>
		void HandlePriceSetting(string[] parts, BitsharesLedgerEntry l, MarketBase handler, MarketRow market)
		{
			// parse
			
			if (parts[0] == kSetPricesMemoStart)
			{
				if (parts[1] == market.symbol_pair)
				{
					// setting is for this market!
					decimal basePrice = decimal.Parse(parts[2]);
					decimal quotePrice = decimal.Parse(parts[3]);

					// go do it!
					handler.SetPricesFromSingleUnitQuantities(basePrice, quotePrice, market.flipped, market);
				}
			}
		}
コード例 #13
0
ファイル: DaemonBase.cs プロジェクト: wildbunny/metaexchange
        /// <summary>	Handles the bitshares desposits. </summary>
        ///
        /// <remarks>	Paul, 16/12/2014. </remarks>
        ///
        /// <exception cref="UnsupportedTransactionException">	Thrown when an Unsupported Transaction
        ///                                                     error condition occurs. </exception>
        protected virtual void HandleBitsharesDesposits()
        {
            // which block do we start from
            uint lastBlockBitshares = GetLastBitsharesBlock();

            // which block do we end on
            GetInfoResponse info = m_bitshares.GetInfo();

            if (lastBlockBitshares == 0)
            {
                // default to current block
                lastBlockBitshares = info.blockchain_head_block_num;
            }

            // get all relevant bitshares deposits
            List <BitsharesWalletTransaction> assetTransactions = m_bitshares.WalletAccountTransactionHistory(m_bitsharesAccount,
                                                                                                              m_bitsharesAsset,
                                                                                                              0,
                                                                                                              lastBlockBitshares,
                                                                                                              info.blockchain_head_block_num);

            IEnumerable <BitsharesWalletTransaction> assetDeposits = assetTransactions.Where(t => t.is_confirmed &&
                                                                                             t.ledger_entries.Any(l => l.to_account == m_bitsharesAccount &&
                                                                                                                  l.from_account != l.to_account &&
                                                                                                                  l.memo != kFundingMemo &&
                                                                                                                  l.from_account != BitsharesWallet.kNetworkAccount));

            foreach (BitsharesWalletTransaction t in assetDeposits)
            {
                IEnumerable <BitsharesLedgerEntry> deposits = t.ledger_entries.Where(l => l.to_account == m_bitsharesAccount);

                if (deposits.Count() == 1)
                {
                    BitsharesLedgerEntry l = deposits.First();

                    // make sure we didn't already send bitcoins for this deposit
                    if (!HasBitsharesDepositBeenCredited(t.trx_id) && !IsTransactionIgnored(t.trx_id))
                    {
                        try
                        {
                            ///
                            /// STILL NEED A WAY TO GET SENDER BITCOIN ADDRESS FOR UNREGISTERED ACCOUNTS
                            ///
                            // look up the transaction proper
                            BitsharesTransaction fullT = m_bitshares.BlockchainGetTransaction(t.trx_id);

                            // get the btc address
                            string btcAddress = BitsharesTransactionToBitcoinAddress(l, fullT);

                            try
                            {
                                SendBitcoinsToDepositor(btcAddress, t.trx_id, l.amount.amount);
                            }
                            catch (Exception e)
                            {
                                // problem sending bitcoins, lets log it
                                LogException(t.trx_id, e.Message, DateTime.UtcNow, DaemonTransactionType.bitsharesDeposit);

                                // also lets now ignore this transaction so we don't keep failing
                                RefundBitsharesDeposit(l.from_account, l.amount.amount, t.trx_id, e.Message);
                            }
                        }
                        catch (RefundBitsharesException r)
                        {
                            // were unable to get a bitcoin address from the bitshares account, so refund the transaction
                            RefundBitsharesDeposit(l.from_account, l.amount.amount, t.trx_id, r.Message);
                        }
                    }
                }
                else
                {
                    // fail with unhandled case
                    throw new UnsupportedTransactionException(t.trx_id);
                }
            }

            UpdateBitsharesBlock(info.blockchain_head_block_num);
        }
コード例 #14
0
ファイル: DaemonBase.cs プロジェクト: sfinder/metaexchange
        /// <summary>	This is virtual because implementors might like a different way  </summary>
        ///
        /// <remarks>	Paul, 16/12/2014. </remarks>
        ///
        /// <param name="account">	The account. </param>
        ///
        /// <returns>	A string. </returns>
        /*protected virtual string BitsharesTransactionToBitcoinAddress(BitsharesLedgerEntry l)
        {
            // THIS CANNOT WORK DUE TO MEMO SIZE = 19 bytes!!!!!!!

            // expect the BTC address to be inside the memo somewhere
            string[] memo = l.memo.Split(' ');
            AddressBase address = null;
            foreach (string s in memo)
            {
                try
                {
                    address = new AddressBase(s);
                    break;
                }
                catch (ArgumentException){}
            }

            if (address == null)
            {
                throw new RefundBitsharesException("Unable to find desired bitcoin address in transction memo!");
            }

            return address.AddressBase58;
        }*/
        /// <summary>	Bitshares transaction to bitcoin address. </summary>
        ///
        /// <remarks>	Paul, 25/01/2015. </remarks>
        ///
        /// <exception cref="RefundBitsharesException">	Thrown when a Refund Bitshares error condition
        /// 											occurs. </exception>
        ///
        /// <param name="l">	The BitsharesLedgerEntry to process. </param>
        /// <param name="t">	The TransactionSinceBlock to process. </param>
        ///
        /// <returns>	A string. </returns>
        protected virtual string BitsharesTransactionToBitcoinAddress(BitsharesLedgerEntry l, BitsharesTransaction t)
        {
            try
            {
                // get the public key of the sender
                BitsharesAccount account = GetAccountFromLedger(l.from_account);

                // turn into into a bitshares address
                return BitsharesAccountToBitcoinAddress(account);
            }
            catch (BitsharesRpcException)
            {
                throw new RefundBitsharesException("Unregistered acct!");
            }
        }
コード例 #15
0
ファイル: MarketBase.cs プロジェクト: sfinder/metaexchange
        /// <summary>	Bitshares transaction to bitcoin address. </summary>
        ///
        /// <remarks>	Paul, 05/02/2015. </remarks>
        ///
        /// <exception cref="RefundBitsharesException">	Thrown when a Refund Bitshares error condition
        /// 											occurs. </exception>
        ///
        /// <param name="l">	The BitsharesLedgerEntry to process. </param>
        ///
        /// <returns>	A string. </returns>
        protected SenderToDepositRow BitsharesTransactionToBitcoinAddress(BitsharesLedgerEntry l)
        {
            // look up the BTS address this transaction was sent to

            // look that address up in our map of sender->deposit address

            // pull the market uid out of the memo
            string symbolPair;
            uint referralUser;
            MemoExtract(l.memo, out symbolPair, out referralUser);

            SenderToDepositRow senderToDeposit = m_daemon.GetSenderDepositFromDeposit(l.memo, symbolPair, referralUser);
            if (senderToDeposit != null)
            {
                return senderToDeposit;
            }
            else
            {
                throw new RefundBitsharesException("Missing/bad memo!");
            }
        }