Пример #1
0
        private async Task InternalBalanceCheck()
        {
            try
            {
                var balance = await _paymentService.GetMainAccountBalance();

                if (balance < _settings.MainAccountMinBalance)
                {
                    if ((DateTime.UtcNow - _lastWarningSentTime).TotalHours > 1)
                    {
                        string message = $"Main account {_settings.EthereumMainAccount} balance is less that {_settings.MainAccountMinBalance} ETH !";

                        await _logger.WriteWarningAsync("TransferContractPoolService", "InternalBalanceCheck", "", message);

                        await _slackNotifier.FinanceWarningAsync(message);

                        _lastWarningSentTime = DateTime.UtcNow;
                    }
                }
            }
            catch (Exception e)
            {
                await _logger.WriteErrorAsync("TransferContractPoolService", "InternalBalanceCheck", "", e);
            }
        }
Пример #2
0
        private async Task SendBalanceNotifications(string asset, string hotWallet, decimal minBalance)
        {
            string message = $"Offchain wallet {hotWallet} {asset} balance is less than {minBalance} {asset}!";
            await _logger.WriteWarningAsync("GenerateOffchainOutputsFunction", "SendBalanceNotifications", "", message);

            await _slackNotifier.FinanceWarningAsync(message);

            await _emailNotifier.WarningAsync("Bitcoin job", message);
        }
Пример #3
0
        public async Task FeeRateUpdate()
        {
            FeeResult feeRate = null;

            try
            {
                feeRate = await _feerateApiProvider.GetFee();
            }
            catch (TaskCanceledException)
            {
                //ignored
                return;
            }
            int newFeeRate;

            switch (_settings.FeeType)
            {
            case Core.Enums.FeeType21co.FastestFee:
                newFeeRate = feeRate.FastestFee;
                break;

            case Core.Enums.FeeType21co.HalfHourFee:
                newFeeRate = feeRate.HalfHourFee;
                break;

            case Core.Enums.FeeType21co.HourFee:
                newFeeRate = feeRate.HourFee;
                break;

            default:
                throw new Exception("unsupported fee type");
            }
            var maxFeeRate = await _settingsRepository.Get(Constants.MaxFeeRateSetting, DefaultMaxFeeRate);

            if (newFeeRate > maxFeeRate)
            {
                if (DateTime.UtcNow - _lastWarningSentTime > TimeSpan.FromHours(1))
                {
                    await _slackNotifier.FinanceWarningAsync($"Current fee rate={newFeeRate} is more than max fee rate={maxFeeRate}");

                    _lastWarningSentTime = DateTime.UtcNow;
                }
                newFeeRate = maxFeeRate;
            }
            await _feeRateRepository.UpdateFeeRate(newFeeRate);
        }
        private async Task GenerateFeeOutputs()
        {
            await _logger.WriteInfoAsync("GenerateOutputsFunction", "GenerateFeeOutputs", null, "Start process");

            var queue = _pregeneratedOutputsQueueFactory.CreateFeeQueue();

            try
            {
                while (await queue.Count() < _baseSettings.MinPregeneratedOutputsCount)
                {
                    var uncoloredOutputs = await _bitcoinOutputsService.GetUncoloredUnspentOutputs(_baseSettings.HotWalletForPregeneratedOutputs);

                    var outputs = uncoloredOutputs.ToList();

                    var totalRequiredAmount = Money.FromUnit(_baseSettings.GenerateOutputsBatchSize * _baseSettings.PregeneratedFeeAmount,
                                                             MoneyUnit.BTC); // Convert to satoshi

                    var feeAmount = new Money(_baseSettings.PregeneratedFeeAmount, MoneyUnit.BTC);

                    if (outputs.Sum(o => o.TxOut.Value) < totalRequiredAmount)
                    {
                        throw new BackendException($"The sum of total applicable outputs is less than the required: {totalRequiredAmount} satoshis.",
                                                   ErrorCode.NotEnoughBitcoinAvailable);
                    }

                    var hotWallet = new BitcoinPubKeyAddress(_baseSettings.HotWalletForPregeneratedOutputs, _connectionParams.Network);
                    var builder   = new TransactionBuilder();

                    builder.AddCoins(outputs);
                    builder.SetChange(hotWallet);

                    for (var i = 0; i < _baseSettings.GenerateOutputsBatchSize; i++)
                    {
                        builder.Send(new BitcoinPubKeyAddress(_baseSettings.FeeAddress, _connectionParams.Network), feeAmount);
                    }

                    builder.SendFees(await _feeProvider.CalcFeeForTransaction(builder));

                    var signedHex = await _signatureApiProvider.SignTransaction(builder.BuildTransaction(false).ToHex());

                    var signedTr = new Transaction(signedHex);

                    var transactionId = Guid.NewGuid();

                    await _bitcoinClient.BroadcastTransaction(signedTr, transactionId);

                    await queue.EnqueueOutputs(signedTr.Outputs.AsCoins().Where(o => o.TxOut.Value == feeAmount).ToArray());

                    await FinishOutputs(transactionId, signedTr, hotWallet);
                }
            }
            finally
            {
                if (await queue.Count() < _baseSettings.MinPregeneratedOutputsCount && (DateTime.UtcNow - _lastWarningFeeSentTime).TotalHours > 1)
                {
                    var message = $"Count of fee outputs is less than {_baseSettings.MinPregeneratedOutputsCount}";
                    await _slackNotifier.FinanceWarningAsync(message);

                    await _emailNotifier.WarningAsync("Bitcoin job", message);

                    _lastWarningFeeSentTime = DateTime.UtcNow;
                }
                await _logger.WriteInfoAsync("GenerateOutputsFunction", "GenerateFeeOutputs", null, "End process");
            }
        }