public BitcoinBasedTxOutput( ICoin coin, ITxPoint spentTxPoint) { Coin = coin; SpentTxPoint = spentTxPoint; }
private async Task GetSecretAsync(ClientSwap swap, ITxPoint spentPoint) { Log.Debug("Try to get CounterParty's payment spent output {@hash}:{@no} for swap {@swapId}", spentPoint.Hash, spentPoint.Index, swap.Id); var soldCurrency = swap.SoldCurrency; var swapInput = await((IInOutBlockchainApi)soldCurrency.BlockchainApi) .GetInputAsync(spentPoint.Hash, spentPoint.Index) .ConfigureAwait(false); var secret = swapInput.ExtractSecret(); var secretHash = CreateSwapSecretHash(secret); if (!secretHash.SequenceEqual(swap.SecretHash)) { throw new InternalException( code: Errors.InvalidSecretHash, description: "Invalid secret hash"); } swap.Secret = secret; RaiseSwapUpdated(swap, SwapStateFlags.HasSecret); }
public static byte[] ExtractSecret(this ITxPoint input) { if (input is BitcoinBasedTxPoint bitcoinBaseInput) { return(bitcoinBaseInput.ExtractSecret()); } throw new NotSupportedException("Input not supported"); }
public override async Task <bool> CheckCompletion() { var spentPoint = await((IInOutBlockchainApi)Currency.BlockchainApi) .IsTransactionOutputSpent(OutputHash, OutputIndex) .ConfigureAwait(false); if (spentPoint == null) { return(false); } SpentPoint = spentPoint; CompleteHandler(this); return(true); }
private async void PaymentSpentEventHandler(ClientSwap swap, ITxPoint spentPoint) { try { if (spentPoint == null) { throw new InternalException( code: Errors.InvalidSpentPoint, description: "Invalid spent point"); } // extract secret await GetSecretAsync(swap, spentPoint) .ConfigureAwait(false); RaiseAcceptorPaymentSpent(swap); } catch (Exception e) { Log.Error(e, "Error while handle payment tx spent event"); } }
private async void PaymentSpentEventHandler( Swap swap, ITxPoint spentPoint, CancellationToken cancellationToken = default) { Log.Debug("Handle payment spent event for swap {@swapId}", swap.Id); try { var soldCurrency = Currencies.GetByName(swap.SoldCurrency); BitcoinBasedTxPoint spentTxInput = null; var attempts = 0; while (attempts < MaxInputGettingAttemps) { attempts++; var inputResult = await((IInOutBlockchainApi)soldCurrency.BlockchainApi) .TryGetInputAsync(spentPoint.Hash, spentPoint.Index, cancellationToken: cancellationToken) .ConfigureAwait(false); if (inputResult == null || (inputResult.HasError && inputResult.Error?.Code == Errors.RequestError)) { await Task.Delay(TimeSpan.FromSeconds(InputGettingIntervalInSec), cancellationToken) .ConfigureAwait(false); continue; } if (inputResult.HasError) { throw new InternalException(inputResult.Error.Code, inputResult.Error.Description); } spentTxInput = inputResult.Value as BitcoinBasedTxPoint; if (spentTxInput == null) { throw new InternalException(Errors.InvalidSpentPoint, "Spent point is not bitcoin based tx point"); } break; } var secret = spentTxInput .ExtractAllPushData() .FirstOrDefault(d => d.Length == DefaultSecretSize && CreateSwapSecretHash(d).SequenceEqual(swap.SecretHash)); if (secret != null) { swap.Secret = secret; RaiseSwapUpdated(swap, SwapStateFlags.HasSecret); if (swap.IsAcceptor) { RaiseAcceptorPaymentSpent(swap); } } else if (spentTxInput.IsRefund()) { RefundConfirmedEventHandler(swap, null, cancellationToken); } else { throw new InternalException( Errors.InvalidSpentPoint, $"Unknown redeem or refund script for output {spentPoint.Hash}:{spentPoint.Index}"); } } catch (Exception e) { Log.Error(e, "Error while handle payment tx spent event"); } }