public async Task given_receipt_request_range_0_to_19_payment_claim_range_should_be_0_to_19() { var unitsRange = new UnitsRange(0, 19); var consumer = CreateConsumer(); _consumerRepository.GetAsync(Arg.Any <Keccak>()).Returns(consumer); _paymentService.ClaimPaymentAsync(Arg.Any <PaymentClaim>(), _coldWalletAddress, _gasPrice) .Returns(_transaction.Hash); var receiptRequest = new DataDeliveryReceiptRequest(1, Keccak.Zero, unitsRange); var paymentClaim = await _processor.ProcessAsync(receiptRequest, null); paymentClaim.ClaimedUnits.Should().Be(20); paymentClaim.UnitsRange.Should().Be(unitsRange); }
private void ConfigureMocks(TestConsumer consumer) { var depositId = consumer.DepositId; _consumerRepository.GetAsync(depositId).Returns(consumer.Consumer); _paymentClaimRepository.BrowseAsync(Arg.Any <GetPaymentClaims>()) .Returns(PagedResult <PaymentClaim> .Empty); _sessionRepository.BrowseAsync(new GetProviderSessions { DepositId = depositId }) .Returns(PagedResult <ProviderSession> .Create(new List <ProviderSession>(consumer.Sessions), 1, 1, 1, 1)); _receiptsPolicies.CanRequestReceipts(Arg.Any <long>(), Arg.Any <UInt256>()).Returns(true); _sessionManager.GetConsumerNodes(depositId).Returns(consumer.Nodes.Select(n => n.Node).ToArray()); _receiptProcessor.TryProcessAsync(Arg.Any <ProviderSession>(), _consumer, Arg.Any <INdmProviderPeer>(), Arg.Any <DataDeliveryReceiptRequest>(), Arg.Any <DataDeliveryReceipt>()).Returns(true); }
public async Task <PaymentClaim?> ProcessAsync(DataDeliveryReceiptRequest receiptRequest, Signature signature) { Keccak depositId = receiptRequest.DepositId; Consumer?consumer = await _consumerRepository.GetAsync(depositId); if (consumer is null) { if (_logger.IsError) { _logger.Error($"Could not find any consumers for deposit {depositId} in the repository."); } return(null); } DataRequest dataRequest = consumer.DataRequest; UnitsRange range = receiptRequest.UnitsRange; uint claimedUnits = range.Units; BigInteger claimedValue = claimedUnits * (BigInteger)consumer.DataRequest.Value / consumer.DataRequest.Units; ulong timestamp = _timestamper.UnixTime.Seconds; Rlp unitsRangeRlp = _unitsRangeRlpDecoder.Encode(range); Keccak id = Keccak.Compute(Rlp.Encode(Rlp.Encode(depositId), Rlp.Encode(timestamp), unitsRangeRlp).Bytes); PaymentClaim paymentClaim = new PaymentClaim(id, consumer.DepositId, consumer.DataAsset.Id, consumer.DataAsset.Name, dataRequest.Units, claimedUnits, range, dataRequest.Value, (UInt256)claimedValue, dataRequest.ExpiryTime, dataRequest.Pepper, dataRequest.Provider, dataRequest.Consumer, signature, timestamp, Array.Empty <TransactionInfo>(), PaymentClaimStatus.Unknown); await _paymentClaimRepository.AddAsync(paymentClaim); if (_logger.IsInfo) { _logger.Info($"Claiming a payment (id: '{paymentClaim.Id}') for deposit: '{depositId}', range: [{range.From}, {range.To}], units: {claimedUnits}."); } UInt256 gasPrice = await _gasPriceService.GetCurrentPaymentClaimGasPriceAsync(); Keccak?transactionHash = null; if (_disableSendingPaymentClaimTransaction) { if (_logger.IsWarn) { _logger.Warn("*** NDM provider sending payment claim transaction is disabled ***"); } } else { transactionHash = await SendTransactionAsync(paymentClaim, gasPrice); if (transactionHash is null) { if (_logger.IsInfo) { _logger.Info($"Payment claim (id: {paymentClaim.Id}) for deposit: '{paymentClaim.DepositId}' did not receive a transaction hash."); } return(paymentClaim); } } if (_logger.IsInfo) { _logger.Info($"Payment claim (id: {paymentClaim.Id}) for deposit: '{paymentClaim.DepositId}' received a transaction hash: '{transactionHash}'."); } paymentClaim.AddTransaction(TransactionInfo.Default(transactionHash, 0, gasPrice, _paymentService.GasLimit, timestamp)); paymentClaim.SetStatus(PaymentClaimStatus.Sent); await _paymentClaimRepository.UpdateAsync(paymentClaim); string claimedEth = ((decimal)claimedValue / Eth).ToString("0.0000"); if (_logger.IsInfo) { _logger.Info($"Sent a payment claim (id: '{paymentClaim.Id}') for deposit: '{depositId}', range: [{range.From}, {range.To}], units: {claimedUnits}, units: {claimedUnits}, value: {claimedValue} wei ({claimedEth} ETH, transaction hash: '{transactionHash}'."); } return(paymentClaim); }
public async Task <IDepositNodesHandler> InitAsync(Keccak depositId, uint unpaidSessionUnits = 0) { if (_logger.IsInfo) { _logger.Info($"Initializing deposit: '{depositId}'."); } Consumer?consumer = await _consumerRepository.GetAsync(depositId); if (consumer is null) { if (_logger.IsInfo) { _logger.Info($"Consumer has not been found for deposit: '{depositId}'."); } return(null); } if (_depositNodesHandlers.TryGetValue(depositId, out IDepositNodesHandler? deposit)) { deposit.AddUnpaidUnits(unpaidSessionUnits); deposit.AddUnmergedUnits(unpaidSessionUnits); deposit.AddUnclaimedUnits(unpaidSessionUnits); if (_logger.IsInfo) { _logger.Info($"Updated deposit: '{depositId}'."); } if (_logger.IsInfo) { _logger.Info($"Deposit: '{depositId}' has {deposit.UnpaidUnits} unpaid units, unmerged: {deposit.UnmergedUnits}, unclaimed: {deposit.UnclaimedUnits}, grace: {deposit.GraceUnits}."); } return(deposit); } else { uint purchasedUnits = consumer.DataRequest.Units; UInt256 unitPrice = consumer.DataAsset.UnitPrice; var sessions = await _sessionRepository.BrowseAsync(new GetProviderSessions { DepositId = depositId, Results = int.MaxValue }); var depositReceipts = await _receiptRepository.BrowseAsync(depositId); var receipts = depositReceipts.OrderBy(r => r.Timestamp) .ThenBy(r => r.Request.UnitsRange.To) .ThenByDescending(r => r.Request.UnitsRange.From) .ToArray(); uint consumedUnits = (uint)sessions.Items.Sum(s => s.ConsumedUnits); uint graceUnits = (uint)sessions.Items.Sum(s => s.GraceUnits); uint unpaidUnits = (uint)(sessions.Items.Sum(s => s.UnpaidUnits) - sessions.Items.Sum(s => s.SettledUnits)); ulong latestMergedReceiptTimestamp = receipts.LastOrDefault(r => r.IsMerged)?.Timestamp ?? 0; uint unmergedUnits = (uint)receipts.Where(r => !r.IsClaimed && !r.IsMerged && r.Timestamp >= latestMergedReceiptTimestamp) .Sum(r => r.Request.UnitsRange.To - r.Request.UnitsRange.From + 1); ulong latestClaimedReceiptTimestamp = receipts.LastOrDefault(r => r.IsClaimed)?.Timestamp ?? 0; uint unclaimedUnits = (uint)receipts.Where(r => !r.IsClaimed && !r.IsMerged && r.Timestamp >= latestClaimedReceiptTimestamp) .Sum(r => r.Request.UnitsRange.To - r.Request.UnitsRange.From + 1); var latestReceipts = receipts.Where(r => r.Timestamp >= latestClaimedReceiptTimestamp); uint latestReceiptRequestNumber = receipts.Any() ? receipts.Max(r => r.Number) : 0; var paymentClaimsResult = await _paymentClaimRepository.BrowseAsync(new GetPaymentClaims { DepositId = depositId, Page = 1, Results = int.MaxValue }); PaymentClaim latestPaymentClaim = paymentClaimsResult.Items.OrderBy(c => c.Timestamp) .ThenBy(c => c.UnitsRange.To).LastOrDefault(); deposit = _depositNodesHandlerFactory.CreateInMemory(depositId, consumer.DataRequest.Consumer, consumer.DataAsset.UnitType, consumer.VerificationTimestamp, purchasedUnits, unitPrice, consumedUnits, unpaidUnits, unmergedUnits, unclaimedUnits, graceUnits, consumer.DataRequest.ExpiryTime, latestPaymentClaim, latestReceipts, latestReceiptRequestNumber); _depositNodesHandlers.TryAdd(depositId, deposit); if (_logger.IsInfo) { _logger.Info($"Initialized deposit: '{depositId}'."); } if (_logger.IsInfo) { _logger.Info($"Deposit: '{depositId}' has {deposit.UnpaidUnits} unpaid units, unmerged: {deposit.UnmergedUnits}, unclaimed: {deposit.UnclaimedUnits}, grace: {deposit.GraceUnits}."); } return(deposit); } }