public async override Task <Result <ITxPoint> > GetInputAsync( string txId, uint inputNo, CancellationToken cancellationToken = default) { await RequestLimitControl .Wait(cancellationToken) .ConfigureAwait(false); var requestUri = $"api/tx/{txId}"; return(await HttpHelper.GetAsyncResult <ITxPoint>( baseUri : BaseUri, requestUri : requestUri, responseHandler : (response, content) => { var tx = JsonConvert.DeserializeObject <Tx>(content); var txIn = tx.Inputs[(int)inputNo]; var txInput = new BitcoinBasedTxPoint(new IndexedTxIn { TxIn = new TxIn(new OutPoint(new uint256(txIn.TxId), txIn.VOut), Script.FromHex(txIn.ScriptSig.Hex)), Index = txIn.N, //WitScript = null, }); return txInput; }, cancellationToken : cancellationToken) .ConfigureAwait(false)); }
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"); } }