public async Task <IActionResult> AddAddressToBlacklist( BlacklistAddressRequest request) { var result = await _addressService.AddAddressToBlacklistAsync ( address : request.Address.ToLowerInvariant(), reason : request.BlacklistingReason ); switch (result) { case AddAddressResult.SuccessResult _: return(Ok()); case AddAddressResult.HasAlreadyBeenAddedError _: return(Conflict()); default: throw new NotSupportedException( $"{nameof(_addressService.AddAddressToBlacklistAsync)} returned unsupported result."); } }
public async Task <BuildTransactionResult> BuildTransactionAsync( Guid transactionId, string from, string fromContext, string to, BigInteger transferAmount, bool includeFee) { var transaction = await _transactionRepository.TryGetAsync(transactionId); if (transaction == null) { // Check address validity var addressValidationResult = await _addressService.ValidateAsync(to, false, false); if (addressValidationResult is AddressValidationResult.Error error) { _log.Info ( $"Failed to build transaction [{transactionId}]. Target address [{to}] is invalid. {error.Type.ToReason()}", new { transactionId, from, to } ); return(BuildTransactionResult.TargetAddressIsInvalid()); } // Calculate and validate required gas amount var gasAmountCalculationResult = await _calculateGasAmountStrategy.ExecuteAsync ( addressService : _addressService, blockchainService : _blockchainService, from : from, to : to, transferAmount : transferAmount ); if (gasAmountCalculationResult is GasAmountCalculationResult.ErrorResult) { _log.Info ( $"Failed to build transaction [{transactionId}]. Gas amount is invalid. {gasAmountCalculationResult}", new { transactionId, from, to } ); var isContract = await _blockchainService.IsContractAsync(to); if (isContract) { await _addressService.AddAddressToBlacklistAsync ( address : to, reason : gasAmountCalculationResult.ToString() ); } return(BuildTransactionResult.GasAmountIsInvalid()); } var gasAmount = (BigInteger)gasAmountCalculationResult; // Calculate and validate transaction amount var transactionAmountCalculationResult = await _calculateTransactionAmountStrategy.ExecuteAsync ( blockchainService : _blockchainService, from : from, transferAmount : transferAmount, gasAmount : gasAmount, includeFee : includeFee ); switch (transactionAmountCalculationResult) { case TransactionAmountCalculationResult.TransactionAmountIsTooSmallResult _: _log.Info ( $"Failed to build transaction [{transactionId}]: amount is too small.", new { transactionId, from, to } ); return(BuildTransactionResult.AmountIsTooSmall()); case TransactionAmountCalculationResult.BalanceIsNotEnoughResult _: _log.Info ( $"Failed to build transaction [{transactionId}]: balance is not enough.", new { transactionId, from, to } ); return(BuildTransactionResult.BalanceIsNotEnough()); } var transactionAmount = (BigInteger)transactionAmountCalculationResult; // Build transaction var transactionData = await _buildTransactionStrategy.ExecuteAsync ( transactionId : transactionId, from : from, to : to, transactionAmount : transactionAmount, gasAmount : gasAmount, includeFee : includeFee ); _log.Info ( $"Transaction [{transactionId}] has been built.", new { transactionId, from, to } ); return(BuildTransactionResult.Success(transactionData)); } else { switch (transaction.State) { case TransactionState.Built: return(BuildTransactionResult.Success(transaction.Data)); case TransactionState.InProgress: case TransactionState.Completed: case TransactionState.Failed: return(BuildTransactionResult.TransactionHasBeenBroadcasted()); case TransactionState.Deleted: return(BuildTransactionResult.TransactionHasBeenDeleted()); default: throw new ArgumentOutOfRangeException(); } } }
public async Task <bool> CheckAndUpdateStateAsync( TransactionMonitoringTask task) { try { var transaction = await _transactionRepository.TryGetAsync(task.TransactionId); if (transaction != null) { var transactionChanged = false; // ReSharper disable once ConvertIfStatementToSwitchStatement if (transaction.State == TransactionState.InProgress) { transactionChanged = await CheckTransactionCompletionStateAsync(transaction); } if (transaction.State == TransactionState.Completed || transaction.State == TransactionState.Failed) { transactionChanged = await CheckTransactionConfirmationStateAsync(transaction); } if (transaction.State == TransactionState.Failed && transaction.IsConfirmed) { var isContract = await _blockchainService.IsContractAsync(transaction.To); if (isContract) { await _addressService.AddAddressToBlacklistAsync ( address : transaction.To, reason : $"Transfer to contract failed in transaction [{transaction.TransactionId}]." ); } } if (transactionChanged) { await _transactionRepository.UpdateAsync(transaction); } // ReSharper disable once SwitchStatementMissingSomeCases switch (transaction.State) { case TransactionState.Built: return(true); case TransactionState.InProgress: return(false); case TransactionState.Completed: case TransactionState.Failed: return(transaction.IsConfirmed); case TransactionState.Deleted: return(true); default: throw new ArgumentException($"Transaction is in unknown state [{transaction.State}]."); } } else { _log.Warning($"Transaction [{task.TransactionId}] does not exist."); return(true); } } catch (Exception e) { _log.Warning($"Failed to check and update transaction [{task.TransactionId}] state.", e); return(false); } }