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