private Task AddOrUpdateAsync(DataDeliveryReceiptDetails receipt) { var rlp = _rlpDecoder.Encode(receipt); _database.Set(receipt.Id, rlp.Bytes); return(Task.CompletedTask); }
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 void SetLatestReceipt(DataDeliveryReceiptDetails receipt) { if (receipt is null) { return; } if (receipt.IsMerged) { Interlocked.Exchange(ref _latestMergedReceipt, receipt); Interlocked.Exchange(ref _latestReceipt, receipt); return; } Interlocked.Exchange(ref _latestReceipt, receipt); }
public async Task <IReadOnlyList <DataDeliveryReceiptDetails> > BrowseAsync(Keccak depositId = null, Keccak dataHeaderId = null, Keccak sessionId = null) { var receiptsBytes = _database.GetAll(); if (receiptsBytes.Length == 0) { return(Array.Empty <DataDeliveryReceiptDetails>()); } await Task.CompletedTask; var consumers = new DataDeliveryReceiptDetails[receiptsBytes.Length]; for (var i = 0; i < receiptsBytes.Length; i++) { consumers[i] = Decode(receiptsBytes[i]); } var filteredReceipts = consumers.AsEnumerable(); if (!(depositId is null)) { filteredReceipts = filteredReceipts.Where(c => c.DepositId == depositId); } if (!(dataHeaderId is null)) { filteredReceipts = filteredReceipts.Where(c => c.DataHeaderId == dataHeaderId); } if (!(sessionId is null)) { filteredReceipts = filteredReceipts.Where(c => c.SessionId == sessionId); } return(filteredReceipts.ToArray()); }
public Task UpdateAsync(DataDeliveryReceiptDetails receipt) => AddOrUpdateAsync(receipt);
public Task UpdateAsync(DataDeliveryReceiptDetails receipt) => Receipts.ReplaceOneAsync(r => r.DepositId == receipt.DepositId && r.Number == receipt.Number, receipt);
public Task AddAsync(DataDeliveryReceiptDetails receipt) => Receipts.InsertOneAsync(receipt);
public void AddReceipt(DataDeliveryReceiptDetails receipt) { _receipts.Push(receipt); SetLatestReceipt(receipt); }
private async Task <DataDeliveryReceiptDetails?> TryHandleReceiptAsync(ProviderSession session, Address consumer, INdmProviderPeer peer, DataDeliveryReceiptRequest request) { Keccak depositId = session.DepositId; IDepositNodesHandler?deposit = GetDepositNodesHandler(depositId); if (deposit == null) { throw new InvalidDataException($"Cannot resolve deposit handle for deposit ID: {depositId}"); } try { UnitsRange unitsRange = request.UnitsRange; if (_logger.IsInfo) { _logger.Info($"Sending data delivery receipt request ({request.Number}), deposit: '{depositId}', session: '{session.Id}', range: [{unitsRange.From}, {unitsRange.To}]."); } if (request.ReceiptsToMerge.Any()) { if (_logger.IsInfo) { _logger.Info($"Receipts to merge for deposit: '{depositId}': {string.Join(", ", request.ReceiptsToMerge.Select(r => $"[{r.UnitsRange.From}, {r.UnitsRange.To}]"))}"); } } (DataDeliveryReceipt receipt, RequestReceiptStatus status) = await TryHandleDeliveryReceipt(deposit, consumer, session, request, peer); Keccak id = Keccak.Compute(Rlp.Encode(Rlp.Encode(depositId), Rlp.Encode(request.Number)).Bytes); DataDeliveryReceiptDetails receiptDetails = new DataDeliveryReceiptDetails(id, session.Id, session.DataAssetId, peer.NodeId, request, receipt, _timestamper.UnixTime.Seconds, false); await _receiptRepository.AddAsync(receiptDetails); if (status != RequestReceiptStatus.Ok) { return(null); } UnitsRange range = request.UnitsRange; uint claimedUnits = range.To - range.From + 1; deposit.AddReceipt(receiptDetails); if (!request.ReceiptsToMerge.Any()) { deposit.SubtractUnpaidUnits(claimedUnits); } if (_logger.IsInfo) { _logger.Info($"Successfully processed receipt ({claimedUnits} units) for deposit: '{depositId}' with node: '{peer.NodeId}'."); } return(receiptDetails); } catch (Exception ex) { if (_logger.IsWarn) { _logger.Warn($"There was an error when processing a receipt for deposit: '{depositId}'. {ex}"); } session.SetDataAvailability(DataAvailability.DataDeliveryReceiptNotProvided); await _sessionRepository.UpdateAsync(session); peer.SendDataAvailability(depositId, DataAvailability.DataDeliveryReceiptInvalid); return(null); } }
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}'."); } }