Example #1
0
        public static async Task <bool> ExecuteTransaction(this TxProcessInfo processInfo, BitcornContext dbContext)
        {
            var sql = new StringBuilder();

            if (processInfo.WriteTransactionOutput(sql))
            {
                var rows = await DbOperations.ExecuteSqlRawAsync(dbContext, sql.ToString());

                if (rows > 0)
                {
                    await dbContext.SaveAsync();

                    try
                    {
                        await OnPostTransaction(processInfo, dbContext);
                    }
                    catch (Exception ex)
                    {
                        await BITCORNLogger.LogError(dbContext, ex, "failed to handle tx callback");
                    }
                }
                return(rows > 0);
            }
            return(false);
        }
Example #2
0
        public static async Task OnPostTransaction(TxProcessInfo processInfo, BitcornContext dbContext)
        {
            if (processInfo.Transactions != null)
            {
                decimal subtract       = 0;
                int     txCount        = 0;
                var     balanceUpdates = new List <object>();
                foreach (var txInfo in processInfo.Transactions)
                {
                    if (txInfo.To != null && txInfo.To.User != null && txInfo.Tx != null)
                    {
                        txCount++;
                        if (txInfo.To.User.IsSocketConnected)
                        {
                            var newBalance = txInfo.To.User.UserWallet.Balance + txInfo.Tx.Amount;
                            balanceUpdates.Add(new
                            {
                                auth0Id = txInfo.To.User.UserIdentity.Auth0Id,
                                balance = newBalance
                            });
                        }
                        subtract += txInfo.Tx.Amount.Value;
                    }
                }

                if (txCount > 0)
                {
                    if (processInfo.From != null && processInfo.From.IsSocketConnected)
                    {
                        balanceUpdates.Add(new
                        {
                            auth0Id = processInfo.From.UserIdentity.Auth0Id,
                            balance = processInfo.From.UserWallet.Balance - subtract
                        });
                    }
                }

                if (balanceUpdates.Count > 0)
                {
                    await WebSocketsController.TryBroadcastToBitcornfarms(dbContext, "update-balances", balanceUpdates);
                }
            }
        }
Example #3
0
        /// <summary>
        /// method to prepare a transaction, calling this method will not move fund immediately
        /// </summary>
        /// <param name="req">transaction request</param>
        /// <returns>transaction tracker output</returns>
        public static async Task <TxProcessInfo> ProcessRequest(ITxRequest req, BitcornContext dbContext)
        {
            if (req.Amount <= 0)
            {
                throw new ArgumentException("Amount");
            }
            //create tx process info that will be tracking this transaction
            var info = new TxProcessInfo();
            //create hashset of receivers
            var platformIds = new HashSet <PlatformId>();

            //set sender user
            info.From = req.FromUser;
            //array of recipient ids
            var toArray = req.To.ToArray();
            //calculate total amount of corn being sent
            var  totalAmountRequired = toArray.Length * req.Amount;
            bool canExecuteAll       = false;

            //check if sender has enough corn to execute all transactions
            if (info.From != null && info.From.UserWallet.Balance >= totalAmountRequired)
            {
                if (info.From.UserWallet.IsLocked != null && info.From.UserWallet.IsLocked == true)
                {
                    canExecuteAll = false;
                }
                else
                {
                    if (!(await ShouldLockWallet(dbContext, info.From, totalAmountRequired)))
                    {
                        canExecuteAll = true;
                    }
                }
            }

            //get platform ids of recipients
            foreach (var to in toArray)
            {
                var toPlatformId = BitcornUtils.GetPlatformId(to);
                if (!platformIds.Contains(toPlatformId))
                {
                    platformIds.Add(toPlatformId);
                }
            }
            var platformIdArray = platformIds.ToArray();
            //get recipients query
            var userQuery = BitcornUtils.GetUsersForPlatform(platformIdArray, dbContext).AsNoTracking();
            //convert into dictionary mapped by their platformid
            var users = await BitcornUtils.ToPlatformDictionary(platformIdArray, userQuery, dbContext);

            //create list for receipts
            var output = new List <TxReceipt>();
            //create group transaction id
            var txid = Guid.NewGuid().ToString();

            var sql = new StringBuilder();
            //get corn usdt price at this time
            var cornUsdtPrice = (await ProbitApi.GetCornPriceAsync(dbContext));

            foreach (var to in platformIdArray)
            {
                var receipt = new TxReceipt();
                //if sender is registered, assign it to the receipt
                if (info.From != null)
                {
                    receipt.From = new SelectableUser(info.From);
                }
                //if recipient is registered, assign it to the receipt
                if (users.TryGetValue(to.Id, out User user))
                {
                    receipt.To = new SelectableUser(user);
                    //if all transactions can be executed, attempt to validate this transaction
                    if (canExecuteAll)
                    {
                        //verifytx returns corntx if this transaction will be made
                        receipt.Tx = VerifyTx(info.From, user, cornUsdtPrice, req.Amount, req.Platform, req.TxType, txid);
                    }
                    //if this transaction will be made, log it into corntx table
                    if (receipt.Tx != null)
                    {
                        dbContext.CornTx.Add(receipt.Tx);
                    }
                }
                //add receipt to the output
                output.Add(receipt);
            }
            //set receipts to the transaction tracker
            info.Transactions = output.ToArray();
            return(info);
        }
Example #4
0
        public static async Task <TxProcessInfo> ProcessRequest(ITxRequest req, BitcornContext dbContext)
        {
            if (req.Amount <= 0)
            {
                throw new ArgumentException("Amount");
            }

            var info        = new TxProcessInfo();
            var platformIds = new HashSet <PlatformId>();

            var fromPlatformId = BitcornUtils.GetPlatformId(req.From);

            var fromUser = await BitcornUtils.GetUserForPlatform(fromPlatformId, dbContext).AsNoTracking().FirstOrDefaultAsync();

            info.From = fromUser;

            var toArray = req.To.ToArray();

            var  totalAmountRequired = toArray.Length * req.Amount;
            bool canExecuteAll       = false;

            if (fromUser != null && fromUser.UserWallet.Balance >= totalAmountRequired)
            {
                canExecuteAll = true;
            }

            foreach (var to in toArray)
            {
                var toPlatformId = BitcornUtils.GetPlatformId(to);
                if (!platformIds.Contains(toPlatformId))
                {
                    platformIds.Add(toPlatformId);
                }
            }
            var platformIdArray = platformIds.ToArray();
            var userQuery       = BitcornUtils.GetUsersForPlatform(platformIdArray, dbContext).AsNoTracking();
            var users           = await BitcornUtils.ToPlatformDictionary(platformIdArray, userQuery, dbContext);

            var output = new List <TxReceipt>();
            var txid   = Guid.NewGuid().ToString();
            var sql    = new StringBuilder();

            foreach (var to in platformIdArray)
            {
                var receipt = new TxReceipt();
                if (fromUser != null)
                {
                    receipt.From = new SelectableUser(fromUser);
                }

                if (users.TryGetValue(to.Id, out User user))
                {
                    receipt.To = new SelectableUser(user);
                    if (canExecuteAll)
                    {
                        receipt.Tx = VerifyTx(fromUser, user, req.Amount, req.Platform, req.TxType, txid);
                    }
                    if (receipt.Tx != null)
                    {
                        dbContext.CornTx.Add(receipt.Tx);
                    }
                }
                output.Add(receipt);
            }

            info.Transactions = output.ToArray();
            return(info);
        }