Esempio n. 1
0
 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);
        }
Esempio n. 3
0
        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");
            }
        }
Esempio n. 6
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");
            }
        }