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); }
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}'."); } }
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}"); } } } }