예제 #1
0
        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));
        }
예제 #2
0
        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");
            }
        }