示例#1
0
        private async Task <string> SendTransaction(PrizePayment prizePayment)
        {
            try
            {
                var connector = new WalletConnector
                                (
                    prizePayment.Host,
                    prizePayment.UserName,
                    prizePayment.Password
                                );
                var result = await connector.SendToAddressAsync(prizePayment.Destination, decimal.Parse(prizePayment.Amount));

                return(result.Txid);
            }
            catch (Exception ex)
            {
                Log.Exception("Failed to send transaction.", ex);
                return(null);
            }
        }
        private async Task PerformWalletTransactionsAndUpdateDepositsWithIds(List <string> transactionIds, IExchangeDataContext context)
        {
            Log.Message(LogLevel.Info, "PerformWalletTransactionsAndUpdateDepositsWithIds entered.");

            // send transactions to the wallets for System_User cefs payments and update the deposits with the real txId.
            var cefsDeposits = await context.Deposit.Where(x => transactionIds.Contains(x.Txid)).ToListAsync().ConfigureAwait(false);

            foreach (var txId in transactionIds)
            {
                try
                {
                    var deposit  = cefsDeposits.FirstOrDefault(x => x.Txid == txId);
                    var currency = await context.Currency.FirstOrDefaultAsync(c => c.Id == deposit.CurrencyId).ConfigureAwait(false);

                    var currencyAddress = await context.Address.FirstOrDefaultAsync(a => a.UserId == Constant.SYSTEM_USER_STAGING && a.CurrencyId == deposit.CurrencyId).ConfigureAwait(false);

                    if (currencyAddress == null)
                    {
                        Log.Message(LogLevel.Error, $"No address exists for currency {currency.Symbol}. Unable to process CEF deposit.");
                        continue;
                    }

                    var connector = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass, WALLET_TIMEOUT);
                    var result    = await connector.SendToAddressAsync(currencyAddress.AddressHash, deposit.Amount);

                    if (result != null)
                    {
                        deposit.Txid = result.Txid;
                        await context.SaveChangesAsync();
                    }
                }
                catch (Exception ex)
                {
                    Log.Message(LogLevel.Error, $"Wallet Transaction blew up.\r\n{ex.Message}");
                }
            }

            Log.Message(LogLevel.Info, "PerformWalletTransactionsAndUpdateDepositsWithIds exited.");
        }
        /// <summary>
        /// Processes the withrawals.
        /// </summary>
        /// <returns></returns>
        private async Task ProcessWithrawals()
        {
            using (var dataAccess = new MsSqlDataAccess())
                using (var balanceRepo = new Repository <Balance>())
                    using (var currencyRepo = new Repository <Currency>())
                    {
                        var start = DateTime.Now;
                        Log.Message(LogLevel.Info, "[ProcessWithrawals] - Processing pending withdrawals...");
                        var pendingWithdraws = GetPendingWithdraws();
                        if (!pendingWithdraws.Any())
                        {
                            Log.Message(LogLevel.Info, "[ProcessWithrawals] - No pending withdraws found.");
                            return;
                        }

                        Log.Message(LogLevel.Info, "[ProcessWithrawals] - {0} pending withdraws found, Processing...", pendingWithdraws.Count);
                        foreach (var currency in await currencyRepo.GetAllAsync(x => x.IsEnabled))
                        {
                            if (!_isEnabled)
                            {
                                return;
                            }

                            try
                            {
                                Log.Message(LogLevel.Info, "[ProcessWithrawals] - Processing pending withdraws for {0}...", currency.Symbol);
                                if (!IsWalletOnline(currency.Status))
                                {
                                    Log.Message(LogLevel.Info, "[ProcessWithrawals] - {0} wallet current status is '{1}', skipping.", currency.Symbol,
                                                currency.Status);
                                    continue;
                                }

                                var wallet    = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass, 60000 * 4);
                                var withdraws = pendingWithdraws.Where(x => x.CurrencyId == currency.Id);
                                if (withdraws.IsNullOrEmpty())
                                {
                                    Log.Message(LogLevel.Info, "[ProcessWithrawals] - No pending withdraws found for {0}...", currency.Symbol);
                                    continue;                     // next coin
                                }

                                foreach (var withdraw in withdraws)
                                {
                                    Log.Message(LogLevel.Info, "[ProcessWithrawals] - Processing withdraw #{0}...", withdraw.Id);
                                    try
                                    {
                                        //await SendNotification(withdraw.UserId, "Processing {0} withdraw #{1}, {2}{0}", currency.Symbol, withdraw.Id, withdraw.Amount.ToString("F8"));
                                        //Run a balance order to ensure we have the correct balance information
                                        if (!await AuditUserBalance(dataAccess, withdraw.UserId, withdraw.CurrencyId))
                                        {
                                            continue;
                                        }

                                        // get the users balance information has enough in locked in pending
                                        var balance = await balanceRepo.GetOrDefaultAsync(x => x.UserId == withdraw.UserId && x.CurrencyId == withdraw.CurrencyId);

                                        if (balance == null || balance.Total <= 0)
                                        {
                                            //await SendErrorNotification(withdraw.UserId, "{0} withdraw #{1}, Insufficient funds.", currency.Symbol, withdraw.Id);
                                            LogError("ProcessWithrawals", "Withdraw Failed, {0} withdraw #{1}, Insufficient funds.", currency.Symbol, withdraw.Id);
                                            continue;
                                        }
                                        if (balance.Total < withdraw.Amount || balance.PendingWithdraw < withdraw.Amount || balance.PendingWithdraw > balance.Total)
                                        {
                                            //await SendErrorNotification(withdraw.UserId, "{0} withdraw #{1}, Insufficient funds.", currency.Symbol, withdraw.Id);
                                            LogError("ProcessWithrawals", "Withdraw Failed, {0} withdraw #{1}, Insufficient funds.", currency.Symbol, withdraw.Id);
                                            continue;
                                        }

                                        // again check if its a valid address
                                        if (!await wallet.ValidateAddressAsync(withdraw.Address))
                                        {
                                            LogError("ProcessWithrawals", "Withdraw Failed, Invalid {0} address, WithdrawId: {1}", currency.Symbol, withdraw.Id);
                                            continue;
                                        }


                                        //decimal amountExcludingFees = currency.WithdrawFeeType == WithdrawFeeType.Normal
                                        //	? withdraw.Amount - currency.WithdrawFee
                                        //	: withdraw.Amount - ((withdraw.Amount / 100m) * currency.WithdrawFee);
                                        decimal withdrawFee         = GetWithdrawFee(wallet, currency, withdraw.Amount);
                                        decimal amountExcludingFees = withdraw.Amount - withdrawFee;
                                        var     withdrawResult      = await wallet.SendToAddressAsync(withdraw.Address, amountExcludingFees);

                                        if (withdrawResult == null || string.IsNullOrEmpty(withdrawResult.Txid))
                                        {
                                            LogError("ProcessWithrawals", "Withdraw Failed, Failed to send {0} transaction, WithdrawId: {1}", currency.Symbol, withdraw.Id);
                                            continue;
                                        }

                                        // Update the withdraw with the txid and set to completed
                                        if (await dataAccess.ExecuteAsync("WalletSetWithdrawTxId", new { WithdrawId = withdraw.Id, TxId = withdrawResult.Txid }, CommandType.StoredProcedure) <= 0)
                                        {
                                            LogError("ProcessWithrawals", "Withdraw Failed, Failed to update {0} withdraw transaction id, WithdrawId: {1}, TxId: {2}", currency.Symbol, withdraw.Id, withdrawResult.Txid);
                                            continue;
                                        }

                                        //Run a balance audit to ensure we have the correct balance information
                                        if (!await AuditUserBalance(dataAccess, withdraw.UserId, withdraw.CurrencyId))
                                        {
                                            continue;
                                        }

                                        //await SendNotification(withdraw.UserId, "{0} withdrawal #{1} successfully processed.", currency.Symbol, withdraw.Id);
                                        //await SendBalanceNotification(withdraw.UserId, currency.Id, currency.Symbol);
                                    }
                                    catch (Exception ex)
                                    {
                                        LogError(ex, "ProcessWithrawals", "An exception occured processing Currency: {0}, WithdrawId: {1}", ex, currency.Symbol, withdraw.Id);
                                        continue;
                                    }
                                    Log.Message(LogLevel.Info, "[ProcessWithrawals] - Processing withdraw #{0} complete.", withdraw.Id);
                                }
                            }
                            catch (Exception ex)
                            {
                                LogError(ex, "ProcessWithrawals", "An exception occured processing Currency: {0}", ex, currency.Symbol);
                                continue;
                            }
                            Log.Message(LogLevel.Info, "[ProcessWithrawals] - Processing pending withdraws for {0} complete.", currency.Symbol);
                        }
                        Log.Message(LogLevel.Info, "[ProcessWithrawals] - Processing pending withdrawals complete. Elapsed: {0}", DateTime.Now - start);
                    }
        }
示例#4
0
        private async Task ProcessTransactions()
        {
            Log.Message(LogLevel.Info, "[ProcessNZDT] - Processing NZDT Transactions...");

            List <NzdtTransaction> nzdtTransactions;

            using (var context = ExchangeDataContextFactory.CreateContext())
            {
                nzdtTransactions = await context.NzdtTransaction
                                   .Where(x => x.TransactionStatus == NzdtTransactionStatus.ReadyForProcessing)
                                   .Where(x => DbFunctions.AddHours(x.CreatedOn, 1) <= DateTime.UtcNow)
                                   .ToListNoLockAsync();

                Log.Message(LogLevel.Info, $"[ProcessNZDT] - {nzdtTransactions.Count()} transactions found, processing...");

                foreach (var transaction in nzdtTransactions)
                {
                    transaction.TransactionStatus = NzdtTransactionStatus.Processed;
                }

                await context.SaveChangesAsync();
            }

            var wallet = new WalletConnector(_nzdtAssetWalletIp, _nzdtAssetWalletPort, _nzdtAssetWalletUserName, _nzdtAssetWalletPassword, 30000);

            foreach (var transaction in nzdtTransactions)
            {
                try
                {
                    var sendResult = await wallet.SendToAddressAsync(Constant.NzdtBaseExchangeAddress, transaction.Amount);

                    using (var context = ExchangeDataContextFactory.CreateContext())
                    {
                        var deposit = new Deposit
                        {
                            Txid          = string.IsNullOrEmpty(sendResult?.Txid) ? $"{transaction.Id}" : sendResult.Txid,
                            Amount        = transaction.Amount,
                            TimeStamp     = DateTime.UtcNow,
                            CurrencyId    = Constant.NZDT_ID,
                            Status        = DepositStatus.Confirmed,
                            Confirmations = 20,
                            UserId        = transaction.UserId.Value,
                            Type          = DepositType.Normal
                        };

                        var tx = await context.NzdtTransaction.FirstNoLockAsync(x => x.Id == transaction.Id);

                        tx.Deposit = deposit;

                        await context.SaveChangesAsync();

                        await context.AuditUserBalance(transaction.UserId.Value, Constant.NZDT_ID);

                        await context.SaveChangesAsync();
                    }
                }
                catch (Exception ex)
                {
                    Log.Exception($"[ProcessNZDT] Insert Deposit failed for transaction {transaction.Id}", ex);
                }
            }

            Log.Message(LogLevel.Info, $"[ProcessNZDT] - Processing NZDT Transactions complete.");
        }
示例#5
0
        private async Task SendWithdrawals(IDataContext context, Currency currency)
        {
            try
            {
                Log.Message(LogLevel.Info, "Sending pending {0} withdrawals...", currency.Symbol);
                if (currency.Status == CurrencyStatus.Maintenance || currency.Status == CurrencyStatus.Offline)
                {
                    return;                     // currency is skipped
                }
                var connector        = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass);
                var pendingWithdraws = await context.Withdraw.Where(x => x.CurrencyId == currency.Id && x.WithdrawStatus == WithdrawStatus.Pending && x.User.IsWithdrawEnabled).ToListAsync();

                foreach (var pendingWithdraw in pendingWithdraws)
                {
                    pendingWithdraw.WithdrawStatus = WithdrawStatus.Processing;
                }
                await context.SaveChangesAsync();

                if (!pendingWithdraws.Any())
                {
                    Log.Message(LogLevel.Info, "No pending {0} withdrawals found.", currency.Symbol);
                    return;
                }

                foreach (var pendingWithdraw in pendingWithdraws)
                {
                    try
                    {
                        Log.Message(LogLevel.Info, "Processing pending withdrawal. Currency: {0}, Amount: {1}, Address: {2}", currency.Symbol, pendingWithdraw.Amount, pendingWithdraw.Address);
                        var auditResult = await AuditUser(context, pendingWithdraw.CurrencyId, pendingWithdraw.UserId);

                        if (!auditResult.Success)
                        {
                            Log.Message(LogLevel.Error, "Failed to audit user balance. Currency: {0}, User: {1}", currency.Symbol, pendingWithdraw.UserId);
                            continue;
                        }

                        if (auditResult.Total <= 0 || auditResult.Total < pendingWithdraw.Amount || auditResult.PendingWithdraw < pendingWithdraw.Amount || auditResult.PendingWithdraw > auditResult.Total)
                        {
                            Log.Message(LogLevel.Error, "User has insufficiant funds for withdraw: Currency:{0}, User: {1}", currency.Symbol, pendingWithdraw.UserId);
                            continue;
                        }

                        decimal withdrawFee         = GetWithdrawFee(currency, pendingWithdraw.Amount);
                        decimal amountExcludingFees = pendingWithdraw.Amount - withdrawFee;
                        Log.Message(LogLevel.Info, "Sending wallet transaction. Currency: {0}, Host: {1}, Port: {2}", currency.Symbol, currency.WalletHost, currency.WalletPort);
                        var withdrawResult = await connector.SendToAddressAsync(pendingWithdraw.Address, amountExcludingFees);

                        if (withdrawResult == null || string.IsNullOrEmpty(withdrawResult.Txid))
                        {
                            Log.Message(LogLevel.Error, "Received no response from wallet, CAUTION: Withdraw status unknown!");
                            continue;
                        }

                        // Update the withdraw with the txid and set to completed
                        pendingWithdraw.Txid           = withdrawResult.Txid;
                        pendingWithdraw.WithdrawStatus = WithdrawStatus.Complete;
                        await context.SaveChangesAsync();

                        Log.Message(LogLevel.Info, "Sending wallet transaction complete. Currency: {0}, TransactionId: {1}", currency.Symbol, withdrawResult.Txid);

                        auditResult = await AuditUser(context, pendingWithdraw.CurrencyId, pendingWithdraw.UserId);

                        await NotificationService.SendBalanceUpdate(GetBalanceNotification(auditResult));
                    }
                    catch (Exception ex)
                    {
                        Log.Exception("An exception occured sending withdraw", ex);
                    }
                }
                Log.Message(LogLevel.Info, "Sending pending {0} withdrawals complete.", currency.Symbol);
            }
            catch (Exception ex)
            {
                Log.Exception("An exception occured sending withdrawals", ex);
            }
        }