예제 #1
0
        /// <summary>
        /// Created Address with optimistic lock
        /// </summary>
        /// <param name="repoQuery"></param>
        /// <param name="rpcClass"></param>
        /// <param name="walletId"></param>
        /// <param name="other"></param>
        /// <typeparam name="TBlockchainAddress"></typeparam>
        /// <returns></returns>
        public virtual async Task <ReturnObject> CreateAddressAsync <TBlockchainAddress>(
            IAddressRepository <TBlockchainAddress> repoQuery, IBlockchainRpc rpcClass, string walletId,
            string other = "") where TBlockchainAddress : BlockchainAddress
        {
            try
            {
                using (var walletRepository = VakapayRepositoryFactory.GetWalletRepository(DbConnection))
                {
                    var walletCheck = walletRepository.FindById(walletId);

                    if (walletCheck == null)
                    {
                        return new ReturnObject
                               {
                                   Status  = Status.STATUS_ERROR,
                                   Message = "Wallet Not Found"
                               }
                    }
                    ;
                }
                var resultsRPC = rpcClass.CreateNewAddress(other);
                if (resultsRPC.Status == Status.STATUS_ERROR)
                {
                    return(resultsRPC);
                }

                var address = resultsRPC.Data;

                //	TBlockchainAddress _newAddress = new TBlockchainAddress();

                var resultDB = await repoQuery.InsertAddress(address, walletId, other);

                //
                //if (result.Status == Status.StatusError)
                //{
                //	return new ReturnObject
                //	{
                //		Status = Status.StatusSuccess,
                //		Message = "Cannot Insert Address"
                //	};
                //}

                //update address into wallet db
                //wallet.WalletBusiness(VakapayRepositoryFactory);

                return(new ReturnObject
                {
                    Status = resultDB.Status,
                    Message = resultDB.Message
                });
            }
            catch (Exception e)
            {
                return(new ReturnObject
                {
                    Status = Status.STATUS_ERROR,
                    Message = e.Message
                });
            }
        }
        /// <summary>
        /// Created Address with optimistic lock
        /// </summary>
        /// <param name="rpcClass"></param>
        /// <param name="walletId"></param>
        /// <param name="other"></param>
        /// <returns></returns>
        public virtual ReturnObject CreateAddress(IBlockchainRpc rpcClass, string userId,
                                                  string other = "")
        {
            try
            {
                using (var dbConnection = SmartContractRepositoryFactory.GetDbConnection())
                {
                    if (dbConnection.State != ConnectionState.Open)
                    {
                        dbConnection.Open();
                    }

                    var userRepository = SmartContractRepositoryFactory.GetUserRepository(dbConnection);

                    var userCheck = userRepository.FindByIdUser(userId);

                    if (userCheck == null)
                    {
                        return new ReturnObject
                               {
                                   Status  = Status.STATUS_ERROR,
                                   Message = "User Not Found"
                               }
                    }
                    ;

                    var resultsRPC = rpcClass.CreateNewAddress(other);
                    if (resultsRPC.Status == Status.STATUS_ERROR)
                    {
                        return(resultsRPC);
                    }

                    var address = resultsRPC.Data;

                    return(new ReturnObject
                    {
                        Status = Status.STATUS_SUCCESS,
                        Data = address,
                        Message = "Can't update wallet " + userCheck.mem_id
                    });
                }
            }
            catch (Exception e)
            {
                return(new ReturnObject
                {
                    Status = Status.STATUS_ERROR,
                    Message = e.Message
                });
            }
        }
예제 #3
0
        /// <summary>
        /// Created Address with optimistic lock
        /// </summary>
        /// <param name="repoQuery"></param>
        /// <param name="rpcClass"></param>
        /// <param name="walletId"></param>
        /// <param name="other"></param>
        /// <typeparam name="TBlockchainAddress"></typeparam>
        /// <returns></returns>
        public override async Task <ReturnObject> CreateAddressAsync <TBlockchainAddress>(
            IAddressRepository <TBlockchainAddress> repoQuery,
            IBlockchainRpc rpcClass, string walletId, string other = "")
        {
            //return base.CreateAddressAsync(wallet, repoQuery, rpcClass, walletId, other);

            try
            {
                using (var walletRepository = VakapayRepositoryFactory.GetWalletRepository(DbConnection))
                {
                    var walletCheck = walletRepository.FindById(walletId);

                    if (walletCheck == null)
                    {
                        return new ReturnObject
                               {
                                   Status  = Status.STATUS_ERROR,
                                   Message = "Wallet Not Found"
                               }
                    }
                    ;

                    VakacoinRpcObj = rpcClass as VakacoinRpc;

                    var results =
                        CreateNewAccount(walletId); // Create account and add account name to VakacoinAccount table

                    if (results.Status == Status.STATUS_ERROR)
                    {
                        return(results);
                    }

                    return(new ReturnObject
                    {
                        Status = Status.STATUS_SUCCESS,
                        Message = "Create vakacoin account success!"
                    });
                }
            }
            catch (Exception e)
            {
                return(new ReturnObject
                {
                    Status = Status.STATUS_ERROR,
                    Message = e.Message
                });
            }
        }
예제 #4
0
        /// <summary>
        /// Created Address with optimistic lock
        /// </summary>
        /// <param name="repoQuery"></param>
        /// <param name="rpcClass"></param>
        /// <param name="walletId"></param>
        /// <param name="other"></param>
        /// <typeparam name="TBlockchainAddress"></typeparam>
        /// <returns></returns>
        public virtual async Task <ReturnObject> CreateAddressAsync <TBlockchainAddress>(
            IAddressRepository <TBlockchainAddress> repoQuery, IBlockchainRpc rpcClass, string userId,
            string other = "") where TBlockchainAddress : BlockchainAddress
        {
            try
            {
                using (var userRepository = SmartContractRepositoryFactory.GetUserRepository(DbConnection))
                {
                    var walletCheck = userRepository.FindById(userId);

                    if (walletCheck == null)
                    {
                        return new ReturnObject
                               {
                                   Status  = Status.STATUS_ERROR,
                                   Message = "Wallet Not Found"
                               }
                    }
                    ;
                }

                var resultsRPC = rpcClass.CreateNewAddress(other);
                if (resultsRPC.Status == Status.STATUS_ERROR)
                {
                    return(resultsRPC);
                }

                var address = resultsRPC.Data;


                var resultDB = await repoQuery.InsertAddress(address, userId, other);


                return(new ReturnObject
                {
                    Status = resultDB.Status,
                    Message = resultDB.Message
                });
            }
            catch (Exception e)
            {
                return(new ReturnObject
                {
                    Status = Status.STATUS_ERROR,
                    Message = e.Message
                });
            }
        }
예제 #5
0
        /// <summary>
        /// Send Transaction with optimistic lock
        /// Send with multiple thread
        /// </summary>
        /// <param name="repoQuery"></param>
        /// <param name="rpcClass"></param>
        /// <param name="privateKey"></param>
        /// <typeparam name="TBlockchainTransaction"></typeparam>
        /// <returns></returns>
        public virtual async Task <ReturnObject> SendTransactionAsync <TBlockchainTransaction>(
            IRepositoryBlockchainTransaction <TBlockchainTransaction> repoQuery, IBlockchainRpc rpcClass,
            string privateKey = "") where TBlockchainTransaction : BlockchainTransaction
        {
            /*
             * 1. Query Transaction Withdraw pending
             * 2. Update Processing = 1, version = version + 1
             * 3. Commit Transaction
             * 4. Call RPC send transaction
             * 5. Update Transaction Status
             */
            // find transaction pending
            //            var pendingTransaction = repoQuery.FindTransactionPending();
            var pendingTransaction = repoQuery.FindRowPending();

            if (pendingTransaction?.Id == null)
            {
                //if (!CacheHelper.HaveKey("cache"))
                //{
                //	long numberOfTicks = (DateTime.Now.Ticks - startTime);

                //	TimeSpan ts = TimeSpan.FromTicks(numberOfTicks);
                //	double minutesFromTs = ts.TotalMinutes;
                //	CacheHelper.SetCacheString("cache", minutesFromTs.ToString());

                //}
                //Console.WriteLine("END TIME " + CacheHelper.GetCacheString("cache"));
                return(new ReturnObject
                {
                    Status = Status.STATUS_SUCCESS,
                    Message = "Not found Transaction"
                });
            }

            if (DbConnection.State != ConnectionState.Open)
            {
                //Console.WriteLine(DbConnection.State);
                DbConnection.Open();
            }


            //begin first transaction
            var transactionScope = DbConnection.BeginTransaction();

            try
            {
                //lock transaction for process
                var resultLock = await repoQuery.LockForProcess(pendingTransaction);

                if (resultLock.Status == Status.STATUS_ERROR)
                {
                    transactionScope.Rollback();
                    return(new ReturnObject
                    {
                        Status = Status.STATUS_SUCCESS,
                        Message = "Cannot Lock For Process"
                    });
                }

                //commit transaction
                transactionScope.Commit();
            }
            catch (Exception e)
            {
                transactionScope.Rollback();
                return(new ReturnObject
                {
                    Status = Status.STATUS_ERROR,
                    Message = e.ToString()
                });
            }

            //Update Version to Model
            pendingTransaction.Version += 1;

            //start send and update

            var transactionDbSend = DbConnection.BeginTransaction();

            try
            {
                //Call RPC Transaction
                //TODO EDIT RPC Class
                var sendTransaction = await rpcClass.SendTransactionAsync(pendingTransaction);

                pendingTransaction.Status       = sendTransaction.Status;
                pendingTransaction.IsProcessing = 0;
                //                pendingTransaction.UpdatedAt = (int) CommonHelper.GetUnixTimestamp(); // set in SafeUpdate
                pendingTransaction.Hash = sendTransaction.Data;

                //create database email when send success
                if (sendTransaction.Status == Status.STATUS_COMPLETED)
                {
                    var email = GetEmailByTransaction(pendingTransaction);
                    if (email != null)
                    {
                        //                        await CreateDataEmail("Notify send " + pendingTransaction.NetworkName(),
                        //                            email, pendingTransaction.Amount,
                        //                            Constants.TEMPLATE_EMAIL_SENT, pendingTransaction.NetworkName(),Constants.TYPE_SEND);
                        await SendMailBusiness.SendMailBusiness.CreateDataEmail("Notify send " + pendingTransaction.NetworkName(),
                                                                                email, pendingTransaction.Amount, pendingTransaction.Id,
                                                                                EmailTemplate.Sent, pendingTransaction.NetworkName(), VakapayRepositoryFactory, false);
                    }
                }

                var result = await repoQuery.SafeUpdate(pendingTransaction);

                if (result.Status == Status.STATUS_ERROR)
                {
                    transactionDbSend.Rollback();
                    return(new ReturnObject
                    {
                        Status = Status.STATUS_ERROR,
                        Message = "Cannot Save Transaction Status"
                    });
                }

                transactionDbSend.Commit();
                return(new ReturnObject
                {
                    Status = sendTransaction.Status,
                    Message = sendTransaction.Message,
                    Data = sendTransaction.Data
                });
            }
            catch (Exception e)
            {
                //release lock
                transactionDbSend.Rollback();
                var resultRelease = repoQuery.ReleaseLock(pendingTransaction);
                Console.WriteLine(JsonHelper.SerializeObject(resultRelease));
                throw e;
            }
        }
예제 #6
0
        public virtual async Task <ReturnObject> ScanBlockAsync <TWithDraw, TDeposit, TBlockResponse, TTransaction>(
            string networkName,
            IWalletBusiness wallet,
            IRepositoryBlockchainTransaction <TWithDraw> withdrawRepoQuery,
            IRepositoryBlockchainTransaction <TDeposit> depositRepoQuery,
            IBlockchainRpc rpcClass)
            where TWithDraw : BlockchainTransaction
            where TDeposit : BlockchainTransaction
            where TBlockResponse : EthereumBlockResponse
            where TTransaction : EthereumTransactionResponse
        {
            try
            {
                int lastBlock   = -1;
                int blockNumber = -1;
                //Get lastBlock from last time
                int.TryParse(
                    CacheHelper.GetCacheString(String.Format(RedisCacheKey.KEY_SCANBLOCK_LASTSCANBLOCK,
                                                             networkName)), out lastBlock);
                if (lastBlock < 0)
                {
                    lastBlock = 0;
                }

                //get blockNumber:
                var _result = rpcClass.GetBlockNumber();
                if (_result.Status == Status.STATUS_ERROR)
                {
                    throw new Exception("Cant GetBlockNumber");
                }

                if (!int.TryParse(_result.Data.ToString(), out blockNumber))
                {
                    throw new Exception("Cant parse block number");
                }

                //Get list of new block that have transactions
                if (lastBlock >= blockNumber)
                {
                    lastBlock = blockNumber;
                }
                Console.WriteLine("SCAN FROM " + lastBlock + "___" + blockNumber);
                List <TBlockResponse> blocks = new List <TBlockResponse>();
                for (int i = lastBlock; i <= blockNumber; i++)
                {
                    if (i < 0)
                    {
                        continue;
                    }
                    _result = rpcClass.GetBlockByNumber(i);
                    if (_result.Status == Status.STATUS_ERROR)
                    {
                        return(_result);
                    }

                    if (_result.Data == null)
                    {
                        continue;
                    }
                    TBlockResponse _block = JsonHelper.DeserializeObject <TBlockResponse>(_result.Data.ToString());
                    if (_block.TransactionsResponse.Length > 0)
                    {
                        blocks.Add(_block);
                    }
                }

                CacheHelper.SetCacheString(String.Format(RedisCacheKey.KEY_SCANBLOCK_LASTSCANBLOCK, networkName),
                                           blockNumber.ToString());
                if (blocks.Count <= 0)
                {
                    throw new Exception("no blocks have transaction");
                }
                //Get done,List<> blocks now contains all block that have transaction
                //check Transaction and update:
                //Search transactions which need to scan:

                var withdrawPendingTransactions = withdrawRepoQuery.FindTransactionsNotCompleteOnNet();
                //Scan all block and check Withdraw transaction:
                Console.WriteLine("Scan withdrawPendingTransactions");
                if (withdrawPendingTransactions.Count > 0)
                {
                    foreach (TBlockResponse _block in blocks)
                    {
                        if (withdrawPendingTransactions.Count <= 0)
                        {
                            //SCAN DONE:
                            break;
                        }

                        for (int i = withdrawPendingTransactions.Count - 1; i >= 0; i--)
                        {
                            BlockchainTransaction       _currentPending = withdrawPendingTransactions[i];
                            EthereumTransactionResponse _trans          =
                                _block.TransactionsResponse.SingleOrDefault(x => x.Hash.Equals(_currentPending.Hash));
                            int _blockNumber = -1;
                            int _fee         = 0;

                            if (_trans != null)
                            {
                                _trans.BlockNumber.HexToInt(out _blockNumber);
                                if (_trans.Fee != null)
                                {
                                    _trans.Fee.HexToInt(out _fee);
                                }
                                Console.WriteLine("HELLO " + _currentPending.Hash);
                                _currentPending.BlockNumber = _blockNumber;
                                _currentPending.Fee         = _fee;
                                _currentPending.UpdatedAt   = (int)CommonHelper.GetUnixTimestamp();
                                //	_currentPending.Status = Status.StatusCompleted;
                                //	_currentPending.InProcess = 0;
                                Console.WriteLine("CaLL UPDATE");

                                portfolioHistoryBusiness.InsertWithPrice(_currentPending.UserId);
                                withdrawRepoQuery.Update((TWithDraw)_currentPending);
                                withdrawPendingTransactions.RemoveAt(i);
                            }
                        }
                    }
                }

                Console.WriteLine("Scan withdrawPendingTransactions Done");
                //check wallet balance and update
                foreach (TBlockResponse _block in blocks)
                {
                    foreach (EthereumTransactionResponse _trans in _block.TransactionsResponse)
                    {
                        string _toAddress   = _trans.To;
                        string _fromAddress = _trans.From;
                        if (!wallet.CheckExistedAddress(_toAddress, networkName))
                        {
                            //logger.Info(to + " is not exist in Wallet!!!");
                            continue;
                        }
                        else
                        {
                            //Console.WriteLine("value" + _trans.value);
                            int _transaValue = 0;
                            if (_trans.Value.HexToInt(out _transaValue))
                            {
                                var userID = "";
                                //  portfolioHistoryBusiness.InsertWithPrice(_trans.i);
                                wallet.UpdateBalanceDeposit(_toAddress, (Decimal)_transaValue, networkName);
                            }
                        }
                    }
                }


                return(new ReturnObject
                {
                    Status = Status.STATUS_COMPLETED,
                    Message = "Scan done"
                });
            }
            catch (Exception e)
            {
                return(new ReturnObject
                {
                    Status = Status.STATUS_ERROR,
                    Message = e.Message
                });
            }
        }
예제 #7
0
        /// <summary>
        /// Send Transaction with optimistic lock
        /// Send with multiple thread
        /// </summary>
        /// <param name="repoQuery"></param>
        /// <param name="rpcClass"></param>
        /// <param name="privateKey"></param>
        /// <typeparam name="TBlockchainTransaction"></typeparam>
        /// <returns></returns>
        public virtual async Task <ReturnObject> SendTransactionAsync <TBlockchainTransaction>(
            IRepositoryBlockchainTransaction <TBlockchainTransaction> repoQuery, IBlockchainRpc rpcClass,
            string privateKey = "") where TBlockchainTransaction : BlockchainTransaction
        {
            /*
             * 1. Query Transaction Withdraw pending
             * 2. Update Processing = 1, version = version + 1
             * 3. Commit Transaction
             * 4. Call RPC send transaction
             * 5. Update Transaction Status
             */

            var pendingTransaction = repoQuery.FindRowPending();

            if (pendingTransaction?.Id == null)
            {
                //Console.WriteLine("END TIME " + CacheHelper.GetCacheString("cache"));
                return(new ReturnObject
                {
                    Status = Status.STATUS_SUCCESS,
                    Message = "Not found Transaction"
                });
            }

            if (DbConnection.State != ConnectionState.Open)
            {
                //Console.WriteLine(DbConnection.State);
                DbConnection.Open();
            }


            //begin first transaction
            var transactionScope = DbConnection.BeginTransaction();

            try
            {
                //lock transaction for process
                var resultLock = await repoQuery.LockForProcess(pendingTransaction);

                if (resultLock.Status == Status.STATUS_ERROR)
                {
                    transactionScope.Rollback();
                    return(new ReturnObject
                    {
                        Status = Status.STATUS_SUCCESS,
                        Message = "Cannot Lock For Process"
                    });
                }

                //commit transaction
                transactionScope.Commit();
            }
            catch (Exception e)
            {
                transactionScope.Rollback();
                return(new ReturnObject
                {
                    Status = Status.STATUS_ERROR,
                    Message = e.ToString()
                });
            }

            //Update Version to Model
            pendingTransaction.Version += 1;

            //start send and update

            var transactionDbSend = DbConnection.BeginTransaction();

            try
            {
                //Call RPC Transaction
                //TODO EDIT RPC Class
                var sendTransaction = await rpcClass.SendTransactionAsync1(pendingTransaction);

                pendingTransaction.Status       = sendTransaction.Status;
                pendingTransaction.IsProcessing = 0;

                pendingTransaction.Hash = sendTransaction.Data;

                //create database email when send success
                if (sendTransaction.Status == Status.STATUS_COMPLETED)
                {
//                    var email = GetEmailByTransaction(pendingTransaction);
//                    if (email != null)
//                    {
//
//                        await SendMailBusiness.SendMailBusiness.CreateDataEmail(
//                            "Notify send " + pendingTransaction.NetworkName(),
//                            email, pendingTransaction.Amount, pendingTransaction.Id,
//                            EmailTemplate.Sent, pendingTransaction.NetworkName(), SmartContractRepositoryFactory,
//                            false);
//                    }
                }

                var result = await repoQuery.SafeUpdate(pendingTransaction);

                if (result.Status == Status.STATUS_ERROR)
                {
                    transactionDbSend.Rollback();
                    return(new ReturnObject
                    {
                        Status = Status.STATUS_ERROR,
                        Message = "Cannot Save Transaction Status"
                    });
                }

                transactionDbSend.Commit();
                return(new ReturnObject
                {
                    Status = sendTransaction.Status,
                    Message = sendTransaction.Message,
                    Data = sendTransaction.Data
                });
            }
            catch (Exception e)
            {
                //release lock
                Console.WriteLine(e.Message);
                transactionDbSend.Rollback();
                var resultRelease = repoQuery.ReleaseLock(pendingTransaction);
                Console.WriteLine(JsonHelper.SerializeObject(resultRelease));
                throw e;
            }
        }