コード例 #1
0
        public async Task CheckCommitmentBroadcast()
        {
            using (OffchainMonitorContext context = new OffchainMonitorContext())
            {
                var commitmentsToSearchFor = (from c in context.Commitments
                                              where c.Punished == false
                                              select c).ToArray();

                if (commitmentsToSearchFor.Count() > 0)
                {
                    for (int i = 0; i < commitmentsToSearchFor.Count(); i++)
                    {
                        var  c     = commitmentsToSearchFor[i];
                        bool found = false;
                        try
                        {
                            await rpcBitcoinClient.GetTransactionHex(c.CommitmentTxId);

                            found = true;
                        }
                        catch (RPCException exp)
                        {
                            if (!exp.Message.Contains("No such mempool or blockchain transaction."))
                            {
                                throw exp;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        catch (Exception exp)
                        {
                            throw exp;
                        }

                        if (found)
                        {
                            try
                            {
                                await rpcBitcoinClient.BroadcastTransaction(new Transaction(c.Punishment), new Guid());

                                c.Punished = true;
                            }
                            catch (Exception exp)
                            {
                                throw exp;
                            }
                        }
                    }
                }

                await context.SaveChangesAsync();
            }
        }
コード例 #2
0
        private async Task Broadcast(Guid transactionId, Transaction tx, IPerformanceMonitor monitor, string hash, bool savePaidFees = true)
        {
            monitor?.Step("Broadcast transaction");
            try
            {
                await _rpcBitcoinClient.BroadcastTransaction(tx, transactionId);
            }
            catch (RPCException ex)
            {
                var builder = new StringBuilder();
                builder.AppendLine($"[{transactionId}], ");
                builder.AppendLine(ex.Message + ":");
                foreach (var input in tx.Inputs)
                {
                    builder.AppendLine(input.PrevOut.ToString());
                }
                await _logger.WriteWarningAsync(nameof(BitcoinBroadcastService), nameof(BroadcastTransaction), builder.ToString(), ex);

                throw;
            }
            monitor?.Step("Set transaction hash and add to monitoring");
            await Task.WhenAll(
                savePaidFees?_paidFeesTaskWriter.AddTask(hash, DateTime.UtcNow, null, null) : Task.CompletedTask,
                _broadcastedOutputRepository.SetTransactionHash(transactionId, hash),
                _monitoringWriter.AddToMonitoring(transactionId, hash)
                );
        }
コード例 #3
0
        public async Task <string> Broadcast(string transaction, Guid?trId)
        {
            trId = trId ?? Guid.NewGuid();
            var tr = new Transaction(transaction);
            await _rpcBitcoinClient.BroadcastTransaction(tr, trId.Value);

            await SaveSpentOutputs(trId.Value, tr);

            await _log.WriteInfoAsync(nameof(BccTransactionService), nameof(Broadcast), null,
                                      $"Broadcast BCC transaction {tr.GetHash()}");

            return(tr.GetHash().ToString());
        }
コード例 #4
0
        public async Task BroadcastTransaction(Guid transactionId, Transaction tx)
        {
            var hash = tx.GetHash().ToString();

            if (_settings.UseLykkeApi)
            {
                await _apiProvider.SendPreBroadcastNotification(new LykkeTransactionNotification(transactionId, hash));
            }

            await _rpcBitcoinClient.BroadcastTransaction(tx, transactionId);

            await _broadcastedOutputRepository.SetTransactionHash(transactionId, hash);

            if (_settings.UseLykkeApi)
            {
                await _apiProvider.SendPostBroadcastNotification(new LykkeTransactionNotification(transactionId, hash));
            }

            await _monitoringWriter.AddToMonitoring(transactionId, tx.GetHash().ToString());
        }
コード例 #5
0
        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");
            }
        }