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 UpdateHealthStatus() { var result = new List <HealthIssue>(); try { result.AddRange(await GetDcrdHealthIssues()); result.AddRange(await GetDcrdataHealthIssues()); } catch (Exception e) { _log.Error(e); result.Add(HealthIssue.Create("UnknownHealthIssue", e.Message)); } await _healthStatusRepo.InsertAsync(new HealthStatusEntity { HealthIssues = result.Select(p => new HealthStatusEntity.HealthIssue { Type = p.Type, Value = p.Value }).ToArray() }); }
/// <summary> /// Adds the given address to the observation repository. /// /// If the address is already in the repository, a BusinessException is thrown. /// </summary> /// <param name="address"></param> /// <returns></returns> public async Task SubscribeAsync(string address) { if (!_addressValidator.IsValid(address)) { throw new BusinessException(ErrorReason.InvalidAddress, "Address is invalid"); } await _observableWalletRepository.InsertAsync(new ObservableWalletEntity { Address = address }, false); }
/// <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"); } // 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}"); } // Flag the consumed outpoints as spent. var outpoints = GetOutpointKeysForRawTransaction(txBytes); foreach (var outpoint in outpoints) { _broadcastedOutpointRepo.InsertAsync(new BroadcastedOutpoint { Value = outpoint }); } var txHash = HexUtil.FromByteArray(msgTx.GetHash().Reverse().ToArray()); await SaveBroadcastedTransaction(new BroadcastedTransaction { OperationId = operationId, Hash = txHash, EncodedTransaction = hexTransaction }); }
private async Task SaveBroadcastedTransaction(BroadcastedTransaction broadcastedTx) { // Store tx Hash to OperationId lookup await _broadcastTxHashRepo.InsertAsync( new BroadcastedTransactionByHash { Hash = broadcastedTx.Hash, OperationId = broadcastedTx.OperationId } ); // Store operation await _broadcastTxRepo.InsertAsync(broadcastedTx); }
/// <summary> /// Observe receiving transactions for this address. /// Only need this to return expected errors. /// </summary> /// <param name="address"></param> /// <returns></returns> public async Task SubscribeAddressFrom(string address) { _addressValidator.AssertValid(address); var entity = new ObservableAddressEntity(address, TxDirection.Outgoing); await _operationRepo.InsertAsync(entity); }