public async Task TestTransferTokens()
        {
            var colorCoin = await _coinRepository.GetCoinByAddress(_tokenAdapterAddress);

            var toAddress = _settings.EthereumMainAccount;

            await CashinTokens(_externalTokenAddress, _clientTokenTransferAddress, new BigInteger(100), _tokenAdapterAddress, _clientA);

            var transferUser = await _transferContractService.GetTransferAddressUser(colorCoin.AdapterAddress, _clientTokenTransferAddress);

            var currentBalance = await _transferContractService.GetBalanceOnAdapter(colorCoin.AdapterAddress, _clientA);

            Assert.AreEqual(transferUser, _clientA.ToLower());

            var guid = Guid.NewGuid();

            EthUtils.GuidToBigInteger(guid);
            var externalSign = await _exchangeService.GetSign(guid, _tokenAdapterAddress, _clientA, toAddress, currentBalance);

            var transferHash = await _exchangeService.Transfer(guid, _tokenAdapterAddress, _clientA, toAddress,
                                                               currentBalance, externalSign);

            while (await _transactionService.GetTransactionReceipt(transferHash) == null)
            {
                await Task.Delay(100);
            }

            var currentBalanceOnAdapter = await _transferContractService.GetBalanceOnAdapter(colorCoin.AdapterAddress, _clientA);

            var newBalance = await _transferContractService.GetBalanceOnAdapter(colorCoin.AdapterAddress, toAddress);

            Assert.IsTrue(await _transactionService.IsTransactionExecuted(transferHash, Constants.GasForCoinTransaction));
            Assert.IsTrue(currentBalanceOnAdapter == 0);
            Assert.IsTrue(currentBalance <= newBalance);
        }
        private static void OperationCheck()
        {
            try
            {
                var list = new List <string>();
                Console.WriteLine("CheckingOperation");
                IEthereumTransactionService coinTransactionService = ServiceProvider.GetService <IEthereumTransactionService>();
                var operationToHashMatchRepository = ServiceProvider.GetService <IOperationToHashMatchRepository>();
                operationToHashMatchRepository.ProcessAllAsync((items) =>
                {
                    foreach (var item in items)
                    {
                        if (string.IsNullOrEmpty(item.TransactionHash) || !coinTransactionService.IsTransactionExecuted(item.TransactionHash, Constants.GasForCoinTransaction).Result)
                        {
                            Console.WriteLine($"Operation is dead {item.OperationId}");
                            list.Add(item.OperationId);
                        }
                    }
                    return(Task.FromResult(0));
                }).Wait();

                File.WriteAllText("reportOperations.txt", Newtonsoft.Json.JsonConvert.SerializeObject(list));
                Console.WriteLine("Report completed");
            }
            catch (Exception e)
            {
                Console.WriteLine($"{e.Message}, {e.StackTrace}");
            }
            Console.WriteLine();
        }
        public async Task <ICoinTransaction> ProcessTransaction(CoinTransactionMessage transaction)
        {
            var receipt = await _transactionService.GetTransactionReceipt(transaction.TransactionHash);

            if (receipt == null)
            {
                return(null);
            }

            ICoinTransaction coinDbTransaction = await _coinTransactionRepository.GetTransaction(transaction.TransactionHash)
                                                 ?? new CoinTransaction()
            {
                ConfirmationLevel = 0,
                TransactionHash   = transaction.TransactionHash
            };
            bool error = coinDbTransaction?.Error == true || !await _transactionService.IsTransactionExecuted(transaction.TransactionHash);

            var confimations = await _contractService.GetCurrentBlock() - receipt.BlockNumber;

            var coinTransaction = new CoinTransaction
            {
                TransactionHash   = transaction.TransactionHash,
                Error             = error,
                ConfirmationLevel = GetTransactionConfirmationLevel(confimations)
            };

            await _coinTransactionRepository.InsertOrReplaceAsync(coinTransaction);

            return(coinTransaction);
        }
Exemple #4
0
        public async Task AddOwners(IEnumerable <IOwner> owners)
        {
            string transactionHash = await _ownerBlockchainService.AddOwnersToMainExchangeAsync(owners);

            while (!await _ethereumTransactionService.IsTransactionExecuted(transactionHash, Constants.GasForCoinTransaction))
            {
                await Task.Delay(300);
            }

            List <Task> wait = new List <Task>(owners.Count());

            foreach (var owner in owners)
            {
                var task = _ownerRepository.SaveAsync(owner);
                wait.Add(task);
            }

            await Task.WhenAll(wait);
        }
        private static void OperationResubmit()
        {
            try
            {
                Console.WriteLine("Are you sure?: Y/N");
                var input = Console.ReadLine();
                if (input.ToLower() != "y")
                {
                    Console.WriteLine("Cancel Resubmit");
                    return;
                }

                var queueFactory = ServiceProvider.GetService <IQueueFactory>();
                IEthereumTransactionService coinTransactionService = ServiceProvider.GetService <IEthereumTransactionService>();
                var queue = queueFactory.Build(Constants.PendingOperationsQueue);
                var operationToHashMatchRepository = ServiceProvider.GetService <IOperationToHashMatchRepository>();
                operationToHashMatchRepository.ProcessAllAsync((items) =>
                {
                    foreach (var item in items)
                    {
                        if (string.IsNullOrEmpty(item.TransactionHash) || !coinTransactionService.IsTransactionExecuted(item.TransactionHash, Constants.GasForCoinTransaction).Result)
                        {
                            Console.WriteLine($"Resubmitting {item.OperationId}");
                            queue.PutRawMessageAsync(Newtonsoft.Json.JsonConvert.SerializeObject(new OperationHashMatchMessage()
                            {
                                OperationId = item.OperationId
                            })).Wait();
                        }
                    }
                    return(Task.FromResult(0));
                }).Wait();

                Console.WriteLine("Resubmitted");
            }
            catch (Exception e)
            {
                Console.WriteLine($"{e.Message}, {e.StackTrace}");
            }
            Console.WriteLine();
        }
        //return whether we have sent to rabbit or not
        private async Task <bool> SendCompletedCoinEvent(string transactionHash, string operationId, bool success, QueueTriggeringContext context, CoinTransactionMessage transaction)
        {
            try
            {
                ICoinEvent coinEvent = await GetCoinEvent(transactionHash, operationId, success);

                switch (coinEvent.CoinEventType)
                {
                case CoinEventType.CashinStarted:
                    ICashinEvent cashinEvent = await _transactionEventsService.GetCashinEvent(transactionHash);

                    if (cashinEvent == null)
                    {
                        await _transactionEventsService.IndexEventsForTransaction(coinEvent.ContractAddress, transactionHash);

                        SendMessageToTheQueueEnd(context, transaction, 100);

                        return(false);
                    }

                    //transferContract - userAddress
                    await UpdateUserTransferWallet(coinEvent.FromAddress, coinEvent.ToAddress.ToLower());

                    coinEvent.Amount = cashinEvent.Amount;
                    coinEvent.CoinEventType++;
                    break;

                case CoinEventType.CashoutStarted:
                case CoinEventType.TransferStarted:
                    //Say that Event Is completed
                    coinEvent.CoinEventType++;
                    break;

                default: break;
                }

                #region FailedCashout

                if (coinEvent.CoinEventType == CoinEventType.CashoutCompleted && !success)
                {
                    coinEvent.CoinEventType = CoinEventType.CashoutFailed;
                    await _coinEventService.InsertAsync(coinEvent);

                    SendMessageToTheQueueEnd(context, transaction, 200, "Put Failed cashout in the end of the queue");

                    return(false);
                }

                if (coinEvent.CoinEventType == CoinEventType.CashoutFailed && !success)
                {
                    var historycal = await _pendingOperationService.GetHistoricalAsync(operationId);

                    if (historycal != null)
                    {
                        foreach (var match in historycal)
                        {
                            if (!string.IsNullOrEmpty(match.TransactionHash) &&
                                await _ethereumTransactionService.IsTransactionExecuted(match.TransactionHash, Constants.GasForCoinTransaction))
                            {
                                var @event = await _coinEventService.GetCoinEvent(match.TransactionHash);

                                if (@event != null && @event.TransactionHash.ToLower() == match.TransactionHash.ToLower())
                                {
                                    await _slackNotifier.ErrorAsync($"EthereumCoreService: Transaction with hash {coinEvent.TransactionHash} [{coinEvent.OperationId}]" +
                                                                    $" ({coinEvent.CoinEventType}). Previously was successfully transfered");

                                    return(false);
                                }
                            }
                        }
                    }
                }

                #endregion

                await _coinEventService.PublishEvent(coinEvent, putInProcessingQueue : false);

                await _pendingTransactionsRepository.Delete(transactionHash);

                await _pendingOperationService.MatchHashToOpId(transactionHash, coinEvent.OperationId);

                return(true);
            }
            catch (Exception e)
            {
                await _log.WriteErrorAsync("MonitoringCoinTransactionJob", "SendCompletedCoinEvent", $"trHash: {transactionHash}", e, DateTime.UtcNow);

                SendMessageToTheQueueEnd(context, transaction, 100);

                return(false);
            }
        }
        public async Task Execute(OperationHashMatchMessage opMessage, QueueTriggeringContext context)
        {
            try
            {
                string operatioId = opMessage.OperationId;
                IOperationResubmitt opResubmitCounter = await _operationResubmittRepository.GetAsync(operatioId);

                if (opResubmitCounter == null)
                {
                    opResubmitCounter = new OperationResubmitt()
                    {
                        OperationId    = operatioId,
                        ResubmittCount = 0
                    };
                }
                if (opResubmitCounter.ResubmittCount > 2)
                {
                    await _log.WriteWarningAsync("CoinEventResubmittJob", "Execute", "", $"Message put to poison {opMessage.OperationId}");

                    context.MoveMessageToPoison(opMessage.ToJson());

                    return;
                }

                var historicalMessages = await _pendingOperationService.GetHistoricalAsync(opMessage.OperationId);

                if (historicalMessages == null || historicalMessages.Count() == 0)
                {
                    //Process cashin operations
                    var coinEvent = await _coinEventService.GetCoinEventById(opMessage.OperationId);

                    if (coinEvent != null &&
                        await _ethereumTransactionService.IsTransactionExecuted(coinEvent.TransactionHash, Constants.GasForCoinTransaction))
                    {
                        await ResubmittTransactionAsync(coinEvent.TransactionHash, operatioId, opResubmitCounter);

                        return;
                    }
                    else
                    {
                        context.MoveMessageToPoison(opMessage.ToJson());
                        await _slackNotifier.ErrorAsync($"Moved message {opMessage.OperationId} to poison: no corresponding coinEvent");
                    }
                }
                else
                {
                    //Process transfer/cashout operations
                    foreach (var match in historicalMessages)
                    {
                        if (!string.IsNullOrEmpty(match.TransactionHash) &&
                            await _ethereumTransactionService.IsTransactionExecuted(match.TransactionHash, Constants.GasForCoinTransaction))
                        {
                            var coinEvent = await _coinEventService.GetCoinEventById(match.OperationId);

                            if (coinEvent != null && coinEvent.TransactionHash.ToLower() == match.TransactionHash.ToLower())
                            {
                                await ResubmittTransactionAsync(match.TransactionHash, operatioId, opResubmitCounter);

                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (opMessage.DequeueCount > 100000)
                {
                    context.MoveMessageToPoison(opMessage.ToJson());
                    await _slackNotifier.ErrorAsync($"Moved message {opMessage.OperationId} to poison: dequeue count is {opMessage.DequeueCount }" +
                                                    $" error is {ex.Message}");

                    return;
                }
                opMessage.LastError = ex.Message;
                opMessage.DequeueCount++;
                context.MoveMessageToEnd(opMessage.ToJson());

                await _log.WriteErrorAsync("MonitoringOperationJob", "Execute", "", ex);

                return;
            }

            if (opMessage.DequeueCount > 100000)
            {
                context.MoveMessageToPoison(opMessage.ToJson());
                await _slackNotifier.ErrorAsync($"Moved message {opMessage.OperationId} to poison: dequeue count is {opMessage.DequeueCount }");
            }
            else
            {
                opMessage.DequeueCount++;
                context.MoveMessageToEnd(opMessage.ToJson());
            }
        }