/// <summary> /// Broadcasts a signed transaction to the Decred network /// </summary> /// <param name="operationId"></param> /// <param name="hexTransaction"></param> /// <returns></returns> /// <exception cref="TransactionBroadcastException"></exception> public async Task Broadcast(Guid operationId, string hexTransaction) { if (operationId == Guid.Empty) { throw new BusinessException(ErrorReason.BadRequest, "Operation id is invalid"); } if (string.IsNullOrWhiteSpace(hexTransaction)) { throw new BusinessException(ErrorReason.BadRequest, "SignedTransaction is invalid"); } var txBytes = HexUtil.ToByteArray(hexTransaction); var msgTx = new MsgTx(); msgTx.Decode(txBytes); // If the operation exists in the cache, throw exception var cachedResult = await _broadcastTxRepo.GetAsync(operationId.ToString()); if (cachedResult != null) { throw new BusinessException(ErrorReason.DuplicateRecord, "Operation already broadcast"); } var txHash = HexUtil.FromByteArray(msgTx.GetHash().Reverse().ToArray()); var txWasMined = await _txRepo.GetTxInfoByHash(txHash, long.MaxValue) != null; if (txWasMined) { await SaveBroadcastedTransaction(new BroadcastedTransaction { OperationId = operationId, Hash = txHash, EncodedTransaction = hexTransaction }); throw new BusinessException(ErrorReason.DuplicateRecord, "Operation already broadcast"); } // Submit the transaction to the network via dcrd var result = await _dcrdClient.SendRawTransactionAsync(hexTransaction); if (result.Error != null) { throw new TransactionBroadcastException($"[{result.Error.Code}] {result.Error.Message}"); } await SaveBroadcastedTransaction(new BroadcastedTransaction { OperationId = operationId, Hash = txHash, EncodedTransaction = hexTransaction }); }
public async Task <BuildTransactionResponse> BuildSingleTransactionAsync(BuildSingleTransactionRequest request, decimal feeFactor) { if (request.OperationId == Guid.Empty) { throw new BusinessException(ErrorReason.BadRequest, "Operation id is invalid"); } // Check to see if already broadcasted. var cachedResult = await _broadcastTxRepo.GetAsync(request.OperationId.ToString()); if (cachedResult != null) { throw new BusinessException(ErrorReason.DuplicateRecord, "Operation already broadcast"); } var unsignedTx = await _unsignedTxRepo.GetAsync(request.OperationId.ToString()); if (unsignedTx?.ResponseJson != null) { return(JsonConvert.DeserializeObject <BuildTransactionResponse>(unsignedTx.ResponseJson)); } var response = await _builder.BuildSingleTransactionAsync(request, feeFactor); var entity = new UnsignedTransactionEntity( request.OperationId, JsonConvert.SerializeObject(request), JsonConvert.SerializeObject(response) ); await _unsignedTxRepo.InsertAsync(entity); return(response); }
public async Task <(DateTime updated, IEnumerable <HealthIssue> issues)> GetHealthStatusAsync() { var result = (await _healthStatusRepo.GetAsync(HealthStatusEntity.RowKeyDefaultValue)); if (result != null) { return(updated : result.Timestamp.UtcDateTime, result.HealthIssues.Select(p => HealthIssue.Create(p.Type, p.Value))); } return(DateTime.MinValue, Enumerable.Empty <HealthIssue>()); }
private async Task <bool> IsBroadcastedUtxo(Transaction.OutPoint outpoint) { return(await _broadcastedOutpointRepo.GetAsync(outpoint.ToString()) != null); }