Esempio n. 1
0
        private void AddReciptsToMerge(TestConsumer consumer, IDepositNodesHandler depositHandler)
        {
            DataDeliveryReceiptRequest request = new DataDeliveryReceiptRequest(1, consumer.DepositId, new UnitsRange(0, 5), false, new List <DataDeliveryReceiptToMerge> {
                new DataDeliveryReceiptToMerge(new UnitsRange(0, 1), new Signature(1, 2, 37))
            });
            DataDeliveryReceipt        receipt        = new DataDeliveryReceipt(StatusCodes.Ok, 50, 0, new Signature(1, 2, 37));
            DataDeliveryReceiptDetails receiptDetails = new DataDeliveryReceiptDetails(Keccak.OfAnEmptyString, consumer.Sessions.First().Id, consumer.DataAsset.Id, null, request, receipt, 10, true);

            depositHandler.AddReceipt(receiptDetails);

            DataDeliveryReceiptRequest request2        = new DataDeliveryReceiptRequest(1, consumer.DepositId, new UnitsRange(6, 49));
            DataDeliveryReceipt        receipt2        = new DataDeliveryReceipt(StatusCodes.Ok, 50, 0, new Signature(1, 2, 37));
            DataDeliveryReceiptDetails receiptDetails2 = new DataDeliveryReceiptDetails(Keccak.OfAnEmptyString, consumer.Sessions.First().Id, consumer.DataAsset.Id, null, request2, receipt2, 10, false);

            depositHandler.AddReceipt(receiptDetails2);
        }
Esempio n. 2
0
        private async Task ClaimPaymentAsync(IDepositNodesHandler deposit)
        {
            if (deposit.LatestPaymentClaim?.UnitsRange.To == deposit.PurchasedUnits - 1)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"Last receipt request for deposit: '{deposit.DepositId}' was already claimed.");
                }
                return;
            }

            var claimableReceipts = deposit.Receipts
                                    .Where(r => !r.IsClaimed)
                                    .OrderBy(r => r.Timestamp)
                                    .ThenBy(r => r.Request.UnitsRange.To)
                                    .ToArray();

            DataDeliveryReceiptDetails latestClaimableReceipt = claimableReceipts.LastOrDefault(r => r.IsMerged) ??
                                                                claimableReceipts.FirstOrDefault(r =>
                                                                                                 r.Request.UnitsRange.To == deposit.PurchasedUnits - 1);

            if (latestClaimableReceipt is null)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Cannot claim a payment for deposit: '{deposit.DepositId}' - claimable receipt was not found.");
                }
                return;
            }

            if (latestClaimableReceipt.IsClaimed)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Cannot claim a payment for deposit: '{deposit.DepositId}' - receipt was already claimed, timestamp: {latestClaimableReceipt.Timestamp}.");
                }
                return;
            }

            DataDeliveryReceiptDetails?receipt = await _receiptRepository.GetAsync(latestClaimableReceipt.Id);

            if (receipt == null)
            {
                throw new InvalidDataException($"Unable to make a claim for the receipt with ID: {latestClaimableReceipt.Id} - receipt missing");
            }

            receipt.Claim();
            await _receiptRepository.UpdateAsync(receipt);

            PaymentClaim?paymentClaim = await _paymentClaimProcessor.ProcessAsync(latestClaimableReceipt.Request,
                                                                                  latestClaimableReceipt.Receipt.Signature);

            if (paymentClaim is null)
            {
                throw new InvalidDataException($"Unable to make a claim for the receipt with ID: {latestClaimableReceipt.Id} - claim processing failure");
            }

            latestClaimableReceipt.Claim();
            deposit.AddReceipt(latestClaimableReceipt); // so the receipt become LatestReceipt
            deposit.ClearReceipts();
            deposit.SetLatestPaymentClaim(paymentClaim);
            uint claimedUnits = deposit.UnclaimedUnits < paymentClaim.ClaimedUnits
                ? deposit.UnclaimedUnits
                : paymentClaim.ClaimedUnits;

            deposit.SubtractUnclaimedUnits(claimedUnits);
            if (_logger.IsInfo)
            {
                _logger.Info($"Successfully claimed payment ({claimedUnits} units) for deposit: '{deposit.DepositId}'.");
            }
        }
Esempio n. 3
0
        private async Task TryMergeReceiptsAsync(IDepositNodesHandler deposit)
        {
            Keccak depositId = deposit.DepositId;

            if (deposit.HasSentLastMergedReceipt)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"Last receipt request for deposit: '{depositId}' was already sent.");
                }
                return;
            }

            if (deposit.HasClaimedAllUnits)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"Last receipt request for deposit: '{depositId}' was already claimed.");
                }
                return;
            }

            DataDeliveryReceiptDetails?latestReceipt = deposit.LatestMergedReceipt;

            if (latestReceipt?.Request.UnitsRange.To == deposit.PurchasedUnits)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"Last receipt request for deposit: '{depositId}' was already merged.");
                }
                return;
            }

            var consumerNodes = _sessionManager.GetConsumerNodes(depositId);

            foreach (ConsumerNode node in consumerNodes)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"Trying to merge receipts for deposit: '{depositId}' with node: '{node.Peer.NodeId}'.");
                }
                try
                {
                    ProviderSession?session = node.GetSession(depositId);
                    if (session is null)
                    {
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Session was not found for deposit: '{depositId}', node: '{node.Peer.NodeId}'.");
                        }
                        continue;
                    }

                    DataDeliveryReceiptRequest?request = CreateMergedRequest(deposit);
                    if (request is null)
                    {
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Merged receipt for deposit: '{depositId}' couldn't be created.");
                        }
                        return;
                    }

                    if (latestReceipt?.Request.UnitsRange.Equals(request.UnitsRange) == true)
                    {
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Merged receipt request for deposit: '{depositId}' would be the same as a previous one (already sent).");
                        }
                        continue;
                    }

                    uint previouslyMergedUnits = latestReceipt?.Request.UnitsRange.To + 1 ?? 0;
                    DataDeliveryReceiptDetails?receiptDetails = await TryHandleReceiptAsync(session, deposit.Consumer, node.Peer, request);

                    if (receiptDetails is null)
                    {
                        if (_logger.IsWarn)
                        {
                            _logger.Warn($"Couldn't merge receipts for deposit: '{depositId}' with node: '{node.Peer.NodeId}'.");
                        }
                        continue;
                    }

                    deposit.AddReceipt(receiptDetails);
                    UnitsRange range    = receiptDetails.Request.UnitsRange;
                    uint       mergedTo = range.To + 1;
                    if (mergedTo <= previouslyMergedUnits)
                    {
                        return;
                    }

                    uint mergedUnits = mergedTo - previouslyMergedUnits;
                    mergedUnits = deposit.UnmergedUnits < mergedUnits ? deposit.UnmergedUnits : mergedUnits;
                    deposit.SubtractUnmergedUnits(mergedUnits);
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Successfully merged receipts ({mergedUnits} units) for deposit: '{depositId}' with node: '{node.Peer.NodeId}'.");
                    }
                    break;
                }
                catch (Exception ex)
                {
                    if (_logger.IsWarn)
                    {
                        _logger.Warn($"There was an error when merging receipt requests for deposit: '{deposit.DepositId}'. {ex}");
                    }
                }
            }
        }