private async Task HandleInitiateAsync(ClientSwap swap, ClientSwap clientSwap) { if (swap.SecretHash != null) { if (!swap.SecretHash.SequenceEqual(clientSwap.SecretHash)) { throw new InternalException( code: Errors.InvalidSecretHash, description: $"Secret hash does not match the one already received for swap {swap.Id}"); } return; } if (clientSwap.SecretHash == null || clientSwap.SecretHash.Length != CurrencySwap.DefaultSecretHashSize) { throw new InternalException( code: Errors.InvalidSecretHash, description: $"Incorrect secret hash length for swap {swap.Id}"); } Log.Debug("Secret hash {@hash} successfully received", clientSwap.SecretHash.ToHexString()); swap.SecretHash = clientSwap.SecretHash; RaiseSwapUpdated(swap, SwapStateFlags.HasSecretHash); // check party requisites if (clientSwap.PartyAddress == null) { throw new InternalException( code: Errors.InvalidWallets, description: $"Incorrect party address for swap {swap.Id}"); } //if (IsCriminal(clientSwap.PartyAddress)) // throw new InternalException( // code: Errors.IsCriminalWallet, // description: $"Party wallet is criminal for swap {swap.Id}"); if (clientSwap.RewardForRedeem < 0) { throw new InternalException( code: Errors.InvalidRewardForRedeem, description: $"Incorrect reward for redeem for swap {swap.Id}"); } swap.PartyAddress = clientSwap.PartyAddress; swap.PartyRewardForRedeem = clientSwap.PartyRewardForRedeem; // create self requisites swap.ToAddress = (await _account .GetRedeemAddressAsync(swap.PurchasedCurrency) .ConfigureAwait(false)) .Address; var purchasedCurrencyBalance = await _account .GetBalanceAsync(swap.PurchasedCurrency) .ConfigureAwait(false); swap.RewardForRedeem = purchasedCurrencyBalance.Available < swap.PurchasedCurrency.GetDefaultRedeemFee() && !(swap.PurchasedCurrency is BitcoinBasedCurrency) ? swap.PurchasedCurrency.GetDefaultRedeemFee() * 2 : 0; RaiseSwapUpdated(swap, SwapStateFlags.Empty); // send "accept" to other side _swapClient.SwapAcceptAsync(swap); await GetCurrencySwap(swap.PurchasedCurrency) .PrepareToReceiveAsync(swap) .ConfigureAwait(false); }
private async Task <Error> HandleInitiateAsync( Swap swap, Swap receivedSwap, CancellationToken cancellationToken = default) { if (DateTime.UtcNow > swap.TimeStamp.ToUniversalTime() + DefaultCredentialsExchangeTimeout) { Log.Error("Handle initiate after swap {@swap} timeout", swap.Id); swap.StateFlags |= SwapStateFlags.IsCanceled; await UpdateSwapAsync(swap, SwapStateFlags.IsCanceled, cancellationToken) .ConfigureAwait(false); return(null); // no error } // check secret hash if (swap.SecretHash != null && !swap.SecretHash.SequenceEqual(receivedSwap.SecretHash)) { return(new Error(Errors.InvalidSecretHash, $"Secret hash does not match the one already received for swap {swap.Id}")); } if (receivedSwap.SecretHash == null || receivedSwap.SecretHash.Length != CurrencySwap.DefaultSecretHashSize) { return(new Error(Errors.InvalidSecretHash, $"Incorrect secret hash length for swap {swap.Id}")); } Log.Debug("Secret hash {@hash} successfully received", receivedSwap.SecretHash.ToHexString()); swap.SecretHash = receivedSwap.SecretHash; await UpdateSwapAsync(swap, SwapStateFlags.HasSecretHash, cancellationToken) .ConfigureAwait(false); // check party address if (receivedSwap.PartyAddress == null) { return(new Error(Errors.InvalidWallets, $"Incorrect party address for swap {swap.Id}")); } // check party reward for redeem if (receivedSwap.RewardForRedeem < 0) { return(new Error(Errors.InvalidRewardForRedeem, $"Incorrect reward for redeem for swap {swap.Id}")); } if (swap.PartyAddress == null) { swap.PartyAddress = receivedSwap.PartyAddress; } if (swap.PartyRewardForRedeem == 0 && receivedSwap.PartyRewardForRedeem > 0) { swap.PartyRewardForRedeem = receivedSwap.PartyRewardForRedeem; } if (swap.PartyRefundAddress == null) { swap.PartyRefundAddress = receivedSwap.PartyRefundAddress; } var redeemFromWalletAddress = swap.RedeemFromAddress != null ? await _account .GetAddressAsync(swap.PurchasedCurrency, swap.RedeemFromAddress, cancellationToken) .ConfigureAwait(false) : null; var purchasedCurrency = _account.Currencies.GetByName(swap.PurchasedCurrency); swap.RewardForRedeem = await RewardForRedeemHelper .EstimateAsync( account : _account, quotesProvider : _quotesProvider, feeCurrencyQuotesProvider : symbol => _marketDataRepository ?.OrderBookBySymbol(symbol) ?.TopOfBook(), redeemableCurrency : purchasedCurrency, redeemFromAddress : redeemFromWalletAddress, cancellationToken : cancellationToken) .ConfigureAwait(false); var soldCurrency = _account.Currencies.GetByName(swap.SoldCurrency); // select refund address for bitcoin based currency if (soldCurrency is BitcoinBasedConfig && swap.RefundAddress == null) { swap.RefundAddress = (await _account .GetCurrencyAccount <BitcoinBasedAccount>(soldCurrency.Name) .GetRefundAddressAsync(cancellationToken) .ConfigureAwait(false)) ?.Address; } await UpdateSwapAsync(swap, SwapStateFlags.Empty, cancellationToken) .ConfigureAwait(false); // send "accept" to other side _swapClient.SwapAcceptAsync(swap); await GetCurrencySwap(swap.PurchasedCurrency) .StartPartyPaymentControlAsync(swap, cancellationToken) .ConfigureAwait(false); return(null); // no error }
private async Task HandleInitiateAsync(Swap swap, Swap receivedSwap) { if (DateTime.UtcNow > swap.TimeStamp.ToUniversalTime() + DefaultCredentialsExchangeTimeout) { Log.Error("Handle initiate after swap {@swap} timeout", swap.Id); swap.Cancel(); RaiseSwapUpdated(swap, SwapStateFlags.IsCanceled); return; } if (swap.SecretHash != null) { if (!swap.SecretHash.SequenceEqual(receivedSwap.SecretHash)) { throw new InternalException( code: Errors.InvalidSecretHash, description: $"Secret hash does not match the one already received for swap {swap.Id}"); } return; } if (receivedSwap.SecretHash == null || receivedSwap.SecretHash.Length != CurrencySwap.DefaultSecretHashSize) { throw new InternalException( code: Errors.InvalidSecretHash, description: $"Incorrect secret hash length for swap {swap.Id}"); } Log.Debug("Secret hash {@hash} successfully received", receivedSwap.SecretHash.ToHexString()); swap.SecretHash = receivedSwap.SecretHash; RaiseSwapUpdated(swap, SwapStateFlags.HasSecretHash); // check party requisites if (receivedSwap.PartyAddress == null) { throw new InternalException( code: Errors.InvalidWallets, description: $"Incorrect party address for swap {swap.Id}"); } //if (IsCriminal(clientSwap.PartyAddress)) // throw new InternalException( // code: Errors.IsCriminalWallet, // description: $"Party wallet is criminal for swap {swap.Id}"); if (receivedSwap.RewardForRedeem < 0) { throw new InternalException( code: Errors.InvalidRewardForRedeem, description: $"Incorrect reward for redeem for swap {swap.Id}"); } swap.PartyAddress = receivedSwap.PartyAddress; swap.PartyRewardForRedeem = receivedSwap.PartyRewardForRedeem; // create self requisites var walletToAddress = (await _account .GetRedeemAddressAsync(swap.PurchasedCurrency) .ConfigureAwait(false)); swap.ToAddress = walletToAddress.Address; swap.RewardForRedeem = await GetRewardForRedeemAsync(walletToAddress) .ConfigureAwait(false); RaiseSwapUpdated(swap, SwapStateFlags.Empty); // send "accept" to other side _swapClient.SwapAcceptAsync(swap); await GetCurrencySwap(swap.PurchasedCurrency) .StartPartyPaymentControlAsync(swap) .ConfigureAwait(false); }