示例#1
0
        private Task AddOrUpdateAsync(DataDeliveryReceiptDetails receipt)
        {
            var rlp = _rlpDecoder.Encode(receipt);

            _database.Set(receipt.Id, rlp.Bytes);

            return(Task.CompletedTask);
        }
示例#2
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);
        }
        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());
        }
示例#5
0
 public Task UpdateAsync(DataDeliveryReceiptDetails receipt) => AddOrUpdateAsync(receipt);
示例#6
0
 public Task UpdateAsync(DataDeliveryReceiptDetails receipt)
 => Receipts.ReplaceOneAsync(r => r.DepositId == receipt.DepositId && r.Number == receipt.Number, receipt);
示例#7
0
 public Task AddAsync(DataDeliveryReceiptDetails receipt)
 => Receipts.InsertOneAsync(receipt);
 public void AddReceipt(DataDeliveryReceiptDetails receipt)
 {
     _receipts.Push(receipt);
     SetLatestReceipt(receipt);
 }
示例#9
0
        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);
            }
        }
示例#10
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}'.");
            }
        }