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); } }
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); }
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"); } }