Exemplo n.º 1
0
        public async Task SetUnitsAsync(Keccak depositId, uint consumedUnitsFromProvider)
        {
            var(session, deposit) = await TryGetSessionAndDepositAsync(depositId);

            if (session is null || deposit is null)
            {
                return;
            }

            session.SetConsumedUnitsFromProvider(consumedUnitsFromProvider);
            switch (deposit.DataAsset.UnitType)
            {
            case DataAssetUnitType.Time:
                var now = (uint)_timestamper.EpochSeconds;
                var currentlyConsumedUnits = now - deposit.ConfirmationTimestamp;
                var currentlyUnpaidUnits   = currentlyConsumedUnits > session.PaidUnits
                        ? currentlyConsumedUnits - session.PaidUnits
                        : 0;
                session.SetConsumedUnits((uint)(now - session.StartTimestamp));
                session.SetUnpaidUnits(currentlyUnpaidUnits);
                break;

            case DataAssetUnitType.Unit:
                session.IncrementConsumedUnits();
                session.IncrementUnpaidUnits();
                Metrics.ConsumedUnits++;
                break;
            }

            var consumedUnits = session.ConsumedUnits;
            var unpaidUnits   = session.UnpaidUnits;

            if (_logger.IsTrace)
            {
                _logger.Trace($"Setting units, consumed: [provider: {consumedUnitsFromProvider}, consumer: {consumedUnits}], unpaid: {unpaidUnits}, paid: {session.PaidUnits}, for deposit: '{depositId}', session: '{session.Id}'.");
            }
            if (consumedUnitsFromProvider > consumedUnits)
            {
                var unitsDifference = consumedUnitsFromProvider - consumedUnits;
                if (_logger.IsTrace)
                {
                    _logger.Trace($"Provider has counted more consumed units ({unitsDifference}) for deposit: '{depositId}', session: '{session.Id}'");
                }
            }
            else if (consumedUnitsFromProvider < consumedUnits)
            {
                var unitsDifference = consumedUnits - consumedUnitsFromProvider;
                if (_logger.IsTrace)
                {
                    _logger.Trace($"Provider has counted less consumed units ({unitsDifference}) for deposit: '{depositId}', session: '{session.Id}'.");
                }

                //Adjust units?
//                session.SubtractUnpaidUnits(unpaidUnits);
//                session.SubtractUnpaidUnits(unitsDifference);
            }


            await _sessionRepository.UpdateAsync(session);
        }
Exemplo n.º 2
0
        public async Task SetEnabledDataStreamAsync(Keccak depositId, string client, string[] args)
        {
            ConsumerSession?session = _sessionService.GetActive(depositId);

            if (session is null)
            {
                return;
            }

            session.EnableStream(client, args);
            await _sessionRepository.UpdateAsync(session);

            await _consumerNotifier.SendDataStreamEnabledAsync(depositId, session.Id);

            if (_logger.IsInfo)
            {
                _logger.Info($"Enabled data stream for deposit: '{depositId}', client: '{client}', session: '{session.Id}'.'");
            }
        }
Exemplo n.º 3
0
        public async Task FinishSessionAsync(Session session, INdmPeer provider, bool removePeer = true)
        {
            if (removePeer)
            {
                _providerService.Remove(provider.NodeId);
            }

            if (provider.ProviderAddress is null)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Provider node: '{provider.NodeId}' has no address assigned.");
                }
                return;
            }

            var depositId       = session.DepositId;
            var consumerSession = GetActive(depositId);

            if (consumerSession is null)
            {
                return;
            }

            _sessions.TryRemove(session.DepositId, out _);
            var timestamp = session.FinishTimestamp;

            consumerSession.Finish(session.State, timestamp);
            await _sessionRepository.UpdateAsync(consumerSession);

            await _consumerNotifier.SendSessionFinishedAsync(session.DepositId, session.Id);

            if (_logger.IsInfo)
            {
                _logger.Info($"Finished a session: '{session.Id}' for deposit: '{depositId}', provider: '{provider.ProviderAddress}', state: '{session.State}', timestamp: {timestamp}.");
            }
        }
Exemplo n.º 4
0
        public async Task SendAsync(DataDeliveryReceiptRequest request, int fetchSessionRetries = 3,
                                    int fetchSessionRetryDelayMilliseconds = 3000)
        {
            var depositId = request.DepositId;

            var(deposit, session) = await TryGetDepositAndSessionAsync(depositId,
                                                                       fetchSessionRetries, fetchSessionRetryDelayMilliseconds);

            if (deposit is null || session is null)
            {
                return;
            }

            var providerAddress = deposit.DataAsset.Provider.Address;
            var providerPeer    = _providerService.GetPeer(providerAddress);

            if (providerPeer is null)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Provider: '{providerAddress}' was not found.");
                }

                return;
            }

            var receiptId = Keccak.Compute(Rlp.Encode(Rlp.Encode(depositId), Rlp.Encode(request.Number),
                                                      Rlp.Encode(_timestamper.EpochSeconds)));

            if (!_receiptRequestValidator.IsValid(request, session.UnpaidUnits, session.ConsumedUnits,
                                                  deposit.Deposit.Units))
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Provider: '{providerPeer.NodeId}' sent an invalid data delivery receipt request.");
                }
                var receipt = new DataDeliveryReceipt(StatusCodes.InvalidReceiptRequestRange,
                                                      session.ConsumedUnits, session.UnpaidUnits, new Signature(1, 1, 27));
                await _receiptRepository.AddAsync(new DataDeliveryReceiptDetails(receiptId, session.Id,
                                                                                 session.DataAssetId, _nodePublicKey, request, receipt, _timestamper.EpochSeconds, false));

                await _sessionRepository.UpdateAsync(session);

                providerPeer.SendDataDeliveryReceipt(depositId, receipt);
                return;
            }

            var abiHash = _abiEncoder.Encode(AbiEncodingStyle.Packed, _dataDeliveryReceiptAbiSig,
                                             depositId.Bytes, new[] { request.UnitsRange.From, request.UnitsRange.To });
            var receiptHash      = Keccak.Compute(abiHash);
            var signature        = _wallet.Sign(receiptHash, deposit.Consumer);
            var recoveredAddress = _ecdsa.RecoverPublicKey(signature, receiptHash)?.Address;

            if (deposit.Consumer != recoveredAddress)
            {
                if (_logger.IsError)
                {
                    _logger.Error($"Signature failure when signing the receipt from provider: '{providerPeer.NodeId}', invalid recovered address.");
                }
                var receipt = new DataDeliveryReceipt(StatusCodes.InvalidReceiptAddress,
                                                      session.ConsumedUnits, session.UnpaidUnits, new Signature(1, 1, 27));
                await _receiptRepository.AddAsync(new DataDeliveryReceiptDetails(receiptId, session.Id,
                                                                                 session.DataAssetId, _nodePublicKey, request, receipt, _timestamper.EpochSeconds, false));

                await _sessionRepository.UpdateAsync(session);

                providerPeer.SendDataDeliveryReceipt(depositId, receipt);
                return;
            }

            if (_logger.IsInfo)
            {
                _logger.Info($"Provider: '{providerPeer.NodeId}' sent a valid data delivery receipt request.");
            }
            if (request.ReceiptsToMerge.Any())
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"Processing a merged receipt request for deposit: {session.DepositId}, session: '{session.Id} - units will not be updated.");
                }
            }
            else
            {
                var paidUnits   = request.UnitsRange.To - request.UnitsRange.From + 1;
                var unpaidUnits = session.UnpaidUnits > paidUnits ? session.UnpaidUnits - paidUnits : 0;
                session.SetUnpaidUnits(unpaidUnits);
                session.AddPaidUnits(paidUnits);
                if (request.IsSettlement)
                {
                    session.SetPaidUnits(paidUnits);
                    session.SettleUnits(paidUnits);
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Settled {paidUnits} units for deposit: '{session.DepositId}', session: '{session.Id}'.");
                    }
                }

                await _sessionRepository.UpdateAsync(session);
            }

            if (_logger.IsInfo)
            {
                _logger.Info($"Sending data delivery receipt for deposit: '{depositId}', range: [{request.UnitsRange.From}, {request.UnitsRange.To}].");
            }
            var deliveryReceipt = new DataDeliveryReceipt(StatusCodes.Ok, session.ConsumedUnits,
                                                          session.UnpaidUnits, signature);
            await _receiptRepository.AddAsync(new DataDeliveryReceiptDetails(receiptId, session.Id,
                                                                             session.DataAssetId, _nodePublicKey, request, deliveryReceipt, _timestamper.EpochSeconds, false));

            providerPeer.SendDataDeliveryReceipt(depositId, deliveryReceipt);
            if (_logger.IsInfo)
            {
                _logger.Info($"Sent data delivery receipt for deposit: '{depositId}', range: [{request.UnitsRange.From}, {request.UnitsRange.To}].");
            }
        }