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) ); }
private async Task AddBroadcastedOutputs(List <ICoin> coins, string walletAddress, int confirmationsCount, IPerformanceMonitor monitor) { //get unique saved coins if (confirmationsCount == 0) { var set = new HashSet <OutPoint>(coins.Select(x => x.Outpoint)); monitor?.Step("Get broadcasted outputs"); var internalSavedOutputs = (await _broadcastedOutputRepository.GetOutputs(walletAddress)) .Where(o => !set.Contains(new OutPoint(uint256.Parse(o.TransactionHash), o.N))); coins.AddRange(internalSavedOutputs.Select(o => { var coin = new Coin(new OutPoint(uint256.Parse(o.TransactionHash), o.N), new TxOut(new Money(o.Amount, MoneyUnit.Satoshi), o.ScriptPubKey.ToScript())); if (o.AssetId != null) { return ((ICoin) coin.ToColoredCoin(new BitcoinAssetId(o.AssetId, _connectionParams.Network).AssetId, (ulong)o.Quantity)); } return(coin); })); } }
public async Task BroadcastTransaction(Guid transactionId, List <Guid> notificationIds, Transaction tx, IPerformanceMonitor monitor = null, bool useHandlers = true) { var hash = tx.GetHash().ToString(); if (_settings.UseLykkeApi && useHandlers) { monitor?.Step("Send prebroadcast multi notification"); await _apiProvider.SendPreBroadcastMultiNotification(new LykkeTransactionMultiNotification(notificationIds, hash)); } await Broadcast(transactionId, tx, monitor, hash); if (_settings.UseLykkeApi && useHandlers) { monitor?.Step("Send postbroadcast multi notification"); await _apiProvider.SendPostBroadcastMultiNotification(new LykkeTransactionMultiNotification(notificationIds, hash)); } }
private async Task <List <ICoin> > FilterCoins(List <ICoin> coins, bool useInternalSpentOutputs, IPerformanceMonitor monitor) { monitor?.Step("Get unspent outputs"); var unspentOutputs = await _spentOutputRepository.GetUnspentOutputs(coins.Select(o => new Output(o.Outpoint))); var unspentSet = new HashSet <OutPoint>(unspentOutputs.Select(x => new OutPoint(uint256.Parse(x.TransactionHash), x.N))); if (useInternalSpentOutputs) { monitor?.Step("Get internal spent outputs"); var internalSpentOuputs = new HashSet <OutPoint>( (await _internalSpentOutputRepository.GetInternalSpentOutputs()).Select(x => new OutPoint(uint256.Parse(x.TransactionHash), x.N))); unspentSet.ExceptWith(internalSpentOuputs); } monitor?.Step("Filter ouputs"); return(coins.Where(o => unspentSet.Contains(o.Outpoint)).ToList()); }
public async Task BroadcastTransaction(Guid transactionId, Transaction tx, IPerformanceMonitor monitor = null, bool useHandlers = true, Guid?notifyTxId = null, bool savePaidFees = true) { var hash = tx.GetHash().ToString(); if (_settings.UseLykkeApi && useHandlers) { monitor?.Step("Send prebroadcast notification"); await _apiProvider.SendPreBroadcastNotification(new LykkeTransactionNotification(notifyTxId ?? transactionId, hash)); } await Broadcast(transactionId, tx, monitor, hash, savePaidFees); }
public async Task <IEnumerable <ICoin> > GetUnspentOutputs(string walletAddress, int confirmationsCount = 0, bool useInternalSpentOutputs = true, IPerformanceMonitor monitor = null) { monitor?.Step("Get address balance"); var outputResponse = await _qBitNinjaApiCaller.GetAddressBalance(walletAddress); var coins = outputResponse.Operations .Where(x => x.Confirmations >= Math.Max(1, confirmationsCount)) .SelectMany(o => o.ReceivedCoins).ToList(); await AddBroadcastedOutputs(coins, walletAddress, confirmationsCount, monitor); coins = await FilterCoins(coins, useInternalSpentOutputs, monitor); return(await ToScriptCoins(walletAddress, coins)); }